00001 // $Id: fileutil.cpp 1482 2006-07-20 10:23:23Z luke $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 // FileUtil - WinOil level file manipulation library (implementation code) 00099 00100 #include "camtypes.h" 00101 #include "fileutil.h" 00102 00103 #include "camelot.h" 00104 //#include "pathname.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00105 #include "sgliboil.h" 00106 00107 // Place any IMPLEMENT type statements here 00108 CC_IMPLEMENT_MEMDUMP(FindFiles, CC_CLASS_MEMDUMP); 00109 00110 #define new CAM_DEBUG_NEW 00111 00112 BOOL FileUtil::SearchActive = FALSE; 00113 bool FileUtil::s_fStarted = false; 00114 String_256 FileUtil::SearchPath = TEXT(""); 00115 wxDir FileUtil::s_dirSearch; 00116 00117 PORTNOTE("other", "Removed lots of Windows'isms" ) 00118 #if !defined(EXCLUDE_FROM_XARALX) 00119 00120 /****************************************************************************** 00121 00122 > static BOOL FileUtil::FindResourceFile(TCHAR* SearchFile, TCHAR* FoundFile) 00123 00124 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00125 Created: 8/5/96 00126 Inputs: SearchFile = the name of the file to search for 00127 Outputs: FoundFile = the pathname of the first file to match SearchFile. 00128 Returns: TRUE if the file has been found 00129 FALSE if not 00130 Purpose: The function searches for a matching file in the following directories 00131 in the following sequence: 00132 1. The directory from which the application loaded. 00133 2. The current directory. 00134 3. Windows 95: The Windows system directory. 00135 Windows NT: The 32-bit Windows system directory. 00136 4. Windows NT only: The 16-bit Windows system directory. 00137 5. The Windows directory. 00138 6. The directories that are listed in the PATH environment variable. 00139 00140 ******************************************************************************/ 00141 00142 BOOL FileUtil::FindResourceFile(TCHAR* SearchFile, TCHAR* FoundFile) 00143 { 00144 // Try to find the printer.cms file 00145 BOOL Found = FALSE; 00146 00147 #if WIN16 00148 00149 // 16 bit Windows - look in the PATH variable and current 00150 // directory using _searchenv. 00151 _tsearchenv((char*)SearchFile, "PATH", (char*)FoundFile); 00152 Found = (FoundFile[0] != '\0'); 00153 00154 #else 00155 00156 // 32-bit Windows - use Win32 API SearchPath, which will look in all kinds 00157 // of places, and hopefully should find the 16-bit Windows directory if it's 00158 // on the user's path, and use the ini file in there. 00159 LPTSTR FirstChar; 00160 DWORD BytesRead = ::SearchPath(NULL, // Use default search paths (see help file) 00161 SearchFile, 00162 NULL, // Filename already has an extension 00163 _MAX_PATH - 1, // Destination buffer size 00164 FoundFile, // Destination buffer 00165 &FirstChar); 00166 00167 Found = (BytesRead > 0) && (BytesRead < _MAX_PATH); 00168 00169 #endif 00170 00171 return Found; 00172 } 00173 00174 #endif 00175 00176 /******************************************************************************************** 00177 00178 > static BOOL FileUtil::StartFindingFiles(String_256 *FileSpecifier) 00179 00180 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00181 Created: 12/9/96 00182 00183 Inputs: FileSpecifier - A full pathname specifying the file(s) to search for. 00184 You may include ? and * wildcards 00185 00186 For example, 00187 c:\Files\Drawings\Blobby.xar one specific file 00188 c:\Files\Drawings\*.txt all .txt files 00189 c:\Files\Drawings\*.* all files 00190 00191 Returns: TRUE if the scan was successfully started, FALSE otherwise 00192 00193 Purpose: Scans a given directory for files matching a particular name. 00194 00195 To find files, do something like the following 00196 00197 PathName SearchPath("c:\\Directory\\*.*") 00198 if (FileUtil::StartFindingFiles(&SearchPath)) 00199 { 00200 String_256 LeafName; 00201 while (TRUE) 00202 { 00203 if (!FileUtil::FindNextFile(&LeafName)) 00204 break; 00205 00206 // Do something with file "LeafName" 00207 String_256 FullPathName = "c:\\Directory\"; 00208 FullPathName += LeafName; 00209 TRACE( _T("Full file path name is %s\n"), (TCHAR *)FullPathName); 00210 } 00211 FileUtil::StopFindingFiles(); 00212 } 00213 00214 Notes: This search is non-"re-entrant". Between calls to Start & Stop, any calls 00215 to start another search will give an Error3 and return failure. 00216 00217 SeeAlso: FileUtil::FindNextFile; FileUtil::StopFindingFiles 00218 00219 ********************************************************************************************/ 00220 00221 BOOL FileUtil::StartFindingFiles(String_256 *FileSpecifier) 00222 { 00223 ERROR3IF(FileSpecifier == NULL, "Duff FileSpecifier param"); 00224 00225 if (SearchActive) 00226 { 00227 ERROR3("StartFindingFiles called while already finding files! Call returns failure"); 00228 return(FALSE); 00229 } 00230 00231 SearchActive = TRUE; 00232 s_fStarted = false; 00233 SearchPath = *FileSpecifier; 00234 00235 return(TRUE); 00236 } 00237 00238 00239 00240 /******************************************************************************************** 00241 00242 > static BOOL FileUtil::FindNextFile(String_256 *FoundFile) 00243 00244 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00245 Created: 12/9/96 00246 00247 Outputs: If return value is TRUE, FoundFile will be filled in with 00248 the LEAF filename ("bob.xar") of a found file - else, it will be 00249 set to an empty string. 00250 00251 (I was going to return a PathName - it seemed logical - but.... 00252 An attempt to set 00253 the location/path ("c:\directory") followed by the leaf-name ("bob.xar") 00254 resulted in a PathName of "bob.xar.xar" as opposed to "c:\directory\bob.xar". 00255 00256 Returns: TRUE if it found a(nother) file matching the filespec. 00257 FALSE if there are no (more) matching files 00258 00259 Purpose: Finds the next file, if any. 00260 See StartFindingFiles for example search code 00261 00262 Notes: ** Note that this will not return system/hidden files or directories ** 00263 00264 SeeAlso: FileUtil::StartFindingFiles; FileUtil::StopFindingFiles 00265 00266 ********************************************************************************************/ 00267 00268 BOOL FileUtil::FindNextFile(String_256 *FoundFile) 00269 { 00270 ERROR3IF(FoundFile == NULL, "Illegal NULL param"); 00271 00272 if (!SearchActive) 00273 { 00274 ERROR3("FindNextFile called when StartFindingFiles not called/failed"); 00275 return(FALSE); 00276 } 00277 00278 BOOL result = TRUE; 00279 00280 while (result) 00281 { 00282 wxString strFileName; 00283 00284 if( !s_fStarted ) 00285 { 00286 // find first 00287 PathName path( SearchPath ); 00288 result = wxDir::Exists( path.GetLocation() ); 00289 result = result && s_dirSearch.Open( path.GetLocation() ); 00290 result = result && s_dirSearch.GetFirst( &strFileName, (PCTSTR)path.GetFileName(), wxDIR_FILES ); 00291 s_fStarted = result; 00292 } 00293 else 00294 { 00295 // find next 00296 result = s_dirSearch.GetNext( &strFileName ); 00297 } 00298 00299 if (result) 00300 { 00301 PORTNOTE("other", "This is part of initial GetFirst" ) 00302 #if !defined(EXCLUDE_FROM_XARALX) 00303 // Only return "files" which are not system or hidden, and which aren't directories! 00304 const DWORD AttrMask = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM; 00305 00306 if ((SearchData.dwFileAttributes & AttrMask) == 0) 00307 #endif 00308 { 00309 // OK, it's a safe file to return, so return it 00310 *FoundFile = (PCTSTR)strFileName; 00311 return(TRUE); 00312 } 00313 } 00314 } 00315 00316 *FoundFile = TEXT(""); 00317 return(FALSE); 00318 } 00319 00320 00321 00322 /******************************************************************************************** 00323 00324 > static void FileUtil::StopFindingFiles(void) 00325 00326 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00327 Created: 12/9/96 00328 00329 Purpose: Stops a directory scan 00330 00331 To find files, do something like the following 00332 See StartFindingFiles for example search code 00333 00334 Notes: This code is non-re-entrant. Between calls to Start & Stop, any calls 00335 to start another search will give an Error3 and return failure. 00336 00337 DO NOT CALL THIS FUNCTION if StartFindingFiles failed. 00338 Call this function exactly once for each call to StartFindingFiles. 00339 00340 SeeAlso: FileUtil::StartFindingFiles; FileUtil::FindNextFile 00341 00342 ********************************************************************************************/ 00343 00344 void FileUtil::StopFindingFiles(void) 00345 { 00346 ERROR3IF(!SearchActive, "StopFindingFiles called when StartFindingFiles not called/failed"); 00347 00348 s_fStarted = false; 00349 SearchActive = FALSE; 00350 } 00351 00352 PORTNOTE("other", "Removed lots of Windows'isms" ) 00353 #if !defined(EXCLUDE_FROM_XARALX) 00354 00355 00356 /******************************************************************************************** 00357 > static BOOL FileUtil::GetLongFileName(LPTSTR lpszPath, LPTSTR lpszOutput, size_t cchMaxOutLen) 00358 00359 Author: Richard_Millican (Xara Group Ltd) <camelotdev@xara.com> 00360 Created: 7/8/96 00361 Inputs: lpszPath the full pathname of the file (short, or long) 00362 cchMaxLen the size of the output buffer (if not big enough, we WILL 00363 fail and return FALSE) 00364 Outputs: lpszOutput contains the full, long, filename of the file 00365 Returns: TRUE if successful, FALSE otherwise. 00366 Purpose: Given a full 8.3 pathname, extract the full filename. 00367 Errors: - 00368 SeeAlso: MakeShortPath (which is currently in helpuser.cpp for some bizarre reason...) 00369 ********************************************************************************************/ 00370 00371 BOOL FileUtil::GetLongFileName(LPTSTR lpszPath, LPTSTR lpszOutput, size_t cchMaxOutLen) 00372 { 00373 if(lpszPath == NULL || lpszOutput == NULL || cchMaxOutLen < 1) 00374 { 00375 ERROR3("FileUtil::GetLongFileName given dodgy params - come on, play the game..."); 00376 return FALSE; 00377 } 00378 00379 WIN32_FIND_DATA FileData; 00380 00381 // Perform a search for the specified file 00382 HANDLE hSearch = ::FindFirstFile(lpszPath, &FileData); 00383 if (hSearch == INVALID_HANDLE_VALUE) 00384 { 00385 //ERROR3_PF(("FileUtil::GetLongFileName Corresponding long filename version of %s not found", lpszPath)); 00386 return FALSE; 00387 } 00388 00389 // The find_data structure will hopefully now contain the long filename for the file 00390 if(camStrlen(FileData.cFileName) < (INT32)cchMaxOutLen) 00391 { 00392 camStrcpy(lpszOutput, FileData.cFileName); 00393 return TRUE; 00394 } 00395 00396 return FALSE; 00397 } 00398 00399 #endif 00400 00401 00402 /******************************************************************************************** 00403 > static PathName FileUtil::GetTemporaryFile() 00404 00405 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00406 Created: 2/5/97 00407 Inputs: - 00408 Outputs: - 00409 Returns: A path to a new temporary file 00410 00411 Purpose: Simplified interface to GetTempFileName(). 00412 00413 Call this function when you want to create a new temporary file 00414 and want a pathname for it. 00415 00416 The pathname that this function returns will be unique (i.e. will 00417 not point to an existing file), will begin with 'xar' and will 00418 be in the system's temporary directory. 00419 00420 Errors: - 00421 SeeAlso: - 00422 ********************************************************************************************/ 00423 PathName FileUtil::GetTemporaryPathName() 00424 { 00425 //First get the directory in which to put our temporary files 00426 TCHAR pcPath[MAX_PATH] = _T(""); 00427 00428 PORTNOTE("other", "This call is not needed, wxFileName::CreateTempFileName does the right thing" ) 00429 // FileUtil::GetTemporaryPath(MAX_PATH, pcPath); 00430 00431 //Now get a temporary file name 00432 TCHAR pcFileName[MAX_PATH]; 00433 00434 FileUtil::GetTemporaryFileName(pcPath, _T("xar"), 0, pcFileName); 00435 00436 //And convert the file name into a PathName 00437 String_256 strFileName=pcFileName; 00438 PathName pthFileName(strFileName); 00439 00440 //And return it 00441 return pthFileName; 00442 00443 } 00444 00445 00446 /******************************************************************************************** 00447 > BOOL FileUtil::GetTemporaryPathName(const TCHAR *pExt, PathName *pTempPath) 00448 00449 Author: Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> 00450 Created: 30/6/97 00451 Inputs: pExt - pointer to the extension for the new file 00452 Outputs: pTempPath - a path for a new temporary file 00453 Returns: TRUE, if successful, FALSE otherwise 00454 Purpose: Simplified interface to GetTempFileName(). 00455 Call this function when you want to create a new temporary file 00456 with a particular extension. 00457 Errors: - 00458 SeeAlso: - GetTemporaryPathName() 00459 ********************************************************************************************/ 00460 BOOL FileUtil::GetTemporaryPathName(const TCHAR *pExt, PathName *pTempPath) 00461 { 00462 ERROR3IF((pTempPath == NULL) || (pExt == NULL), "NULL param passed to FileUtil::GetTemporaryPathName"); 00463 if ((pTempPath == NULL) || (pExt == NULL)) 00464 return FALSE; 00465 00466 // create a new temp file 00467 *pTempPath = FileUtil::GetTemporaryPathName(); 00468 00469 // if tmp extension is asked - call the relevant function 00470 if (camStricmp(pExt, (const TCHAR *)"tmp") == 0) 00471 return TRUE; 00472 00473 // remember the current name 00474 String_256 pInFile = pTempPath->GetPath(); 00475 00476 // change the extension 00477 pTempPath->SetType(pExt); 00478 00479 // check if the file exists 00480 if (SGLibOil::FileExists(pTempPath)) 00481 { 00482 // make a recursive call 00483 BOOL ok = GetTemporaryPathName(pExt, pTempPath); 00484 00485 // remove our .tmp file 00486 wxRemoveFile( (PCTSTR)pInFile ); 00487 00488 return ok; 00489 } 00490 00491 // try to rename the file 00492 wxString path = (PCTSTR)pTempPath->GetPath(); 00493 return wxRenameFile( (PCTSTR)pInFile, path ); 00494 } 00495 00496 00497 /******************************************************************************************** 00498 > static UINT32 FileUtil::GetTempFileName(TCHAR *PathName, const TCHAR *Prefix, UINT32 Unique, 00499 TCHAR *FileName) 00500 00501 Author: Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> 00502 Created: 2/5/97 00503 Inputs: pPathName address of directory name for temporary file 00504 Prefix address of filename prefix 00505 Unique number used to create temporary filename 00506 Outputs: FileName address of buffer that receives the new filename 00507 Returns: The unique numeric value used in the temporary filenamem, or 0 if unsuccessful. 00508 Purpose: Creates a unique file name to be used as temporary file. The format of the file 00509 name is path\preuuuu.TMP, where 'path' is specified by PathName, 'pre' are the 00510 first three characters pointed by Prefix, 'uuuu' is the hexadecimal Unique 00511 parameter. Pass 0 for Unique to be certain the temp file name is really unique. 00512 Errors: - 00513 SeeAlso: FileUtil::GetTemporaryDir 00514 ********************************************************************************************/ 00515 UINT32 FileUtil::GetTemporaryFileName(const TCHAR *PathName, const TCHAR *Prefix, UINT32 Unique, TCHAR *FileName) 00516 { 00517 if(PathName == NULL || Prefix == NULL || FileName == NULL) 00518 { 00519 ERROR3("FileUtil::GetTempFileName given dodgy params - come on, play the game..."); 00520 return FALSE; 00521 } 00522 00523 wxString str( PathName ); 00524 // str += Prefix; 00525 00526 str = wxFileName::CreateTempFileName( str ); 00527 camStrcpy( FileName, str.c_str() ); 00528 return Unique != 0 ? Unique : 0xD7334; // Random non-zero value 00529 } 00530 00531 00532 PORTNOTE("other", "Removed lots of Windows'isms" ) 00533 #if !defined(EXCLUDE_FROM_XARALX) 00534 00535 /******************************************************************************************** 00536 > static INT32 FileUtil::GetTempPath(UINT32 BufferLength, TCHAR *Buffer) 00537 00538 Author: Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> 00539 Created: 2/5/97 00540 Inputs: BufferLength the lenght of the buffer addressed by the second parameter 00541 Outputs: Buffer points to a character buffer, to receive the directory name 00542 Returns: The actual length of the returned string 00543 Purpose: Gets the temporary directory 00544 Errors: - 00545 SeeAlso: FileUtil::GetTemporaryFileName 00546 ********************************************************************************************/ 00547 DWORD FileUtil::GetTemporaryPath(UINT32 BufferLength, TCHAR *Buffer) 00548 { 00549 if(Buffer == NULL || BufferLength == 0) 00550 { 00551 ERROR3("FileUtil::GetTempPath given dodgy params - come on, play the game..."); 00552 return FALSE; 00553 } 00554 00555 return ::GetTempPath(BufferLength, Buffer); 00556 } 00557 00558 #endif 00559 00560 00561 /******************************************************************************************* 00562 00563 > static BOOL FileUtil::DeleteFile(PathName *FileToRemove) 00564 00565 Author: Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> (based on code by Neville Humphrys) 00566 Created: 11/4/97 00567 Inputs: FileToRemove - the path name of the file to be removed. 00568 Returns: TRUE if succesful, FALSE otherwise 00569 Purpose: Removes a file 00570 00571 *******************************************************************************************/ 00572 00573 BOOL FileUtil::DeleteFile(PathName *FileToRemove) 00574 { 00575 if (FileToRemove == NULL) 00576 return FALSE; 00577 00578 BOOL Exists = TRUE; 00579 BOOL status = TRUE; 00580 00581 // check if the file exists 00582 Exists = SGLibOil::FileExists(FileToRemove); 00583 00584 // remove it 00585 if (Exists) 00586 status = wxRemoveFile( FileToRemove->GetPath() ); 00587 00588 return !status; 00589 } 00590 00591 00592 /******************************************************************************************* 00593 00594 > static BOOL FileUtil::RecursiveCreateDirectory(const String_256& strDirPath) 00595 00596 Author: Luke_Hart (Xara Group Ltd) <lukeh@xara.com> 00597 Created: 18/07/2006 00598 Inputs: strDirPath - the path to verify and create 00599 Returns: TRUE if succesful, FALSE otherwise 00600 Purpose: Recursivly create directory path 00601 00602 *******************************************************************************************/ 00603 00604 BOOL FileUtil::RecursiveCreateDirectory( const String_256& strDirPath ) 00605 { 00606 // Go down path making sure each directory exists (and creating if needed), we 00607 // start from the second character becuase we don't want to deal with '/' 00608 UINT32 ord = 1; 00609 while( _T('\0') != strDirPath[ord] ) 00610 { 00611 if( _T('/') == strDirPath[ord] ) 00612 { 00613 String_256 strPath; 00614 strDirPath.Left( &strPath, ord ); 00615 if( !wxDir::Exists( (PCTSTR)strPath ) ) 00616 wxMkdir( (PCTSTR)strPath ); 00617 } 00618 00619 ++ord; 00620 } 00621 00622 // Make sure the path as a whole exists 00623 if( !wxDir::Exists( (PCTSTR)strDirPath ) ) 00624 wxMkdir( (PCTSTR)strDirPath ); 00625 00626 return TRUE; 00627 } 00628 00629 00630 PORTNOTE("other", "Removed lots of Windows'isms" ) 00631 #if !defined(EXCLUDE_FROM_XARALX) 00632 00633 /******************************************************************************************* 00634 00635 > static BOOL FileUtil::SetCurrentDirectory(const PathName& NewCurrentPath) 00636 00637 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00638 Created: 31/10/97 00639 Inputs: NewCurrentPath - the new current path to be used. 00640 Returns: TRUE if succesful, FALSE otherwise 00641 Purpose: Set up the operating system current directory 00642 00643 *******************************************************************************************/ 00644 00645 BOOL FileUtil::GetCurrentDirectory(String_256 * pCurrentPath) 00646 { 00647 ERROR2IF(pCurrentPath == NULL,FALSE,"FileUtil::GetCurrentDirectory Bad params"); 00648 00649 // Call the OS to get the new current directory 00650 // DWORD nBufferLength size, in characters, of directory buffer 00651 // LPTSTR lpBuffer address of buffer for current directory 00652 // If the function succeeds, the return value specifies the number of characters 00653 // written to the buffer, not including the terminating null character. 00654 // If the function fails, the return value is zero. 00655 const INT32 MaxSize = 256; 00656 TCHAR Buffer[MaxSize]; 00657 DWORD chars = ::GetCurrentDirectory( MaxSize, Buffer); 00658 if (chars > 0) 00659 { 00660 *pCurrentPath = Buffer; 00661 } 00662 else 00663 pCurrentPath->Empty(); 00664 00665 return (chars > 0); 00666 } 00667 00668 /******************************************************************************************* 00669 00670 > static BOOL FileUtil::SetCurrentDirectory(const PathName& NewCurrentPath) 00671 00672 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00673 Created: 31/10/97 00674 Inputs: NewCurrentPath - the new current path to be used. 00675 Returns: TRUE if succesful, FALSE otherwise 00676 Purpose: Set up the operating system current directory 00677 00678 *******************************************************************************************/ 00679 00680 BOOL FileUtil::SetCurrentDirectory(const PathName& NewCurrentPath) 00681 { 00682 String_256 CurrentPath = NewCurrentPath.GetPath(); 00683 00684 // Call the OS to set the new current directory 00685 BOOL ok = ::SetCurrentDirectory( (TCHAR *)CurrentPath ); 00686 return ok; 00687 } 00688 00689 /******************************************************************************************* 00690 00691 > static BOOL FileUtil::SetCurrentDirectory(const String_256& NewCurrentPath) 00692 00693 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00694 Created: 31/10/97 00695 Inputs: NewCurrentPath - the new current path to be used. 00696 Returns: TRUE if succesful, FALSE otherwise 00697 Purpose: Set up the operating system current directory 00698 00699 *******************************************************************************************/ 00700 00701 BOOL FileUtil::SetCurrentDirectory(const String_256& NewCurrentPath) 00702 { 00703 // Call the OS to set the new current directory 00704 String_256 CurrentPath = NewCurrentPath; 00705 BOOL ok = ::SetCurrentDirectory( (TCHAR *)CurrentPath ); 00706 return ok; 00707 } 00708 00709 00710 /******************************************************************************************** 00711 // FindFiles class 00712 ********************************************************************************************/ 00713 00714 /******************************************************************************************** 00715 00716 > BOOL FindFiles::StartFindingFiles(String_256 *FileSpecifier) 00717 00718 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> based on Jason code. 00719 Created: 9/1/97 00720 Inputs: FileSpecifier - A full pathname specifying the file(s) to search for. 00721 You may include ? and * wildcards 00722 00723 For example, 00724 c:\Files\Drawings\Blobby.xar one specific file 00725 c:\Files\Drawings\*.txt all .txt files 00726 c:\Files\Drawings\*.* all files 00727 00728 Returns: TRUE if the scan was successfully started, FALSE otherwise 00729 Purpose: Scans a given directory for files matching a particular name. 00730 Same as FileUtil::StartFindingFiles but being a class is re-entrant 00731 and returns directories so that you can do recursive searches. 00732 00733 SeeAlso: FindFiles::FindNextFile; FindFiles::StopFindingFiles 00734 SeeAlso: FileUtil::StartFindingFiles FileUtil::FindNextFile; FileUtil::StopFindingFiles 00735 00736 ********************************************************************************************/ 00737 00738 BOOL FindFiles::StartFindingFiles(String_256 *FileSpecifier) 00739 { 00740 ERROR3IF(FileSpecifier == NULL, "Duff FileSpecifier param"); 00741 00742 m_SearchHandle = INVALID_HANDLE_VALUE; 00743 m_SearchPath = *FileSpecifier; 00744 00745 return(TRUE); 00746 } 00747 00748 /******************************************************************************************** 00749 00750 > BOOL FindFiles::FindNextFile(String_256 *FoundFile) 00751 00752 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> based on Jason code. 00753 Created: 12/9/96 00754 Outputs: if return value is TRUE 00755 FoundFile will be filled in with the LEAF filename ("bob.xar") of a found 00756 IsDirectory will be TRUE if the file is a directory, else FALSE, 00757 if return value is FALSE 00758 FoundFile will be set to an empty string. 00759 IsDirectory will be FALSE. 00760 Returns: TRUE if it found a(nother) file matching the filespec. 00761 FALSE if there are no (more) matching files 00762 Purpose: Finds the next file, if any. 00763 See StartFindingFiles for example search code 00764 Notes: ** Note that this will not return system/hidden files ** 00765 00766 SeeAlso: FindFiles::StartFindingFiles; FindFiles::StopFindingFiles 00767 SeeAlso: FileUtil::StartFindingFiles FileUtil::FindNextFile; FileUtil::StopFindingFiles 00768 00769 ********************************************************************************************/ 00770 00771 BOOL FindFiles::FindNextFile(String_256 *FoundFile, BOOL *IsDirectory) 00772 { 00773 ERROR3IF(FoundFile == NULL || IsDirectory == NULL, "Illegal NULL param"); 00774 00775 BOOL result = TRUE; 00776 00777 while (result) 00778 { 00779 if (m_SearchHandle == INVALID_HANDLE_VALUE) 00780 { 00781 // find first 00782 m_SearchHandle = ::FindFirstFile((TCHAR *)m_SearchPath, &m_SearchData); 00783 result = (m_SearchHandle != INVALID_HANDLE_VALUE); 00784 } 00785 else 00786 { 00787 // find next 00788 result = ::FindNextFile(m_SearchHandle, &m_SearchData); 00789 } 00790 00791 if (result) 00792 { 00793 // Only return "files" which are not system or hidden 00794 const DWORD AttrMask = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM; 00795 const DWORD AttrDirMask = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM; 00796 TCHAR * ThisDir = "."; 00797 TCHAR * ParentDir = ".."; 00798 INT32 len = camStrclen(m_SearchData.cFileName); 00799 if ((m_SearchData.dwFileAttributes & AttrMask) == 0) 00800 { 00801 // OK, it's a safe file to return, so return it 00802 *FoundFile = m_SearchData.cFileName; 00803 *IsDirectory = FALSE; 00804 return TRUE; 00805 } 00806 else if (((m_SearchData.dwFileAttributes & AttrDirMask) == 0) && 00807 // (cc_lstrncmp(m_SearchData.cFileName, ThisDir, len) != 0) && 00808 // (cc_lstrncmp(m_SearchData.cFileName, ParentDir, len) != 0)) 00809 (camStrncmp(m_SearchData.cFileName, ThisDir, len) != 0) && 00810 (camStrncmp(m_SearchData.cFileName, ParentDir, len) != 0)) 00811 { 00812 // OK, it's a safe directory to return, so return it 00813 *FoundFile = m_SearchData.cFileName; 00814 *IsDirectory = TRUE; 00815 return TRUE; 00816 } 00817 } 00818 } 00819 00820 *FoundFile = TEXT(""); 00821 *IsDirectory = FALSE; 00822 return FALSE; 00823 } 00824 00825 /******************************************************************************************** 00826 00827 > BOOL FindFiles::StopFindingFiles() 00828 00829 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> based on Jason code. 00830 Created: 12/9/96 00831 Returns: True if completed ok, False otherwise. 00832 Purpose: Stops a directory scan 00833 To find files, do something like the following 00834 See StartFindingFiles for example search code 00835 DO NOT CALL THIS FUNCTION if StartFindingFiles failed. 00836 Call this function exactly once for each call to StartFindingFiles. 00837 00838 SeeAlso: FindFiles::StartFindingFiles; FindFiles::FindNextFile 00839 SeeAlso: FileUtil::StartFindingFiles FileUtil::FindNextFile; FileUtil::StopFindingFiles 00840 00841 ********************************************************************************************/ 00842 00843 BOOL FindFiles::StopFindingFiles() 00844 { 00845 if (m_SearchHandle != NULL) 00846 ::FindClose(m_SearchHandle); 00847 00848 m_SearchHandle = INVALID_HANDLE_VALUE; 00849 00850 return TRUE; 00851 } 00852 00853 #endif