00001
00002
00003
00004
00005 #include "StdAfx.h"
00006
00007 #include "FileDir.h"
00008 #include "FileName.h"
00009 #include "FileFind.h"
00010 #include "Defs.h"
00011 #ifndef _UNICODE
00012 #include "../Common/StringConvert.h"
00013 #endif
00014
00015 #ifndef _UNICODE
00016 extern bool g_IsNT;
00017 #endif
00018
00019 namespace NWindows {
00020 namespace NFile {
00021 namespace NDirectory {
00022
00023 #ifndef _UNICODE
00024 static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
00025 static UString GetUnicodePath(const CSysString &sysPath)
00026 { return MultiByteToUnicodeString(sysPath, GetCurrentCodePage()); }
00027 static CSysString GetSysPath(LPCWSTR sysPath)
00028 { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); }
00029 #endif
00030
00031 bool MyGetWindowsDirectory(CSysString &path)
00032 {
00033 UINT needLength = ::GetWindowsDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
00034 path.ReleaseBuffer();
00035 return (needLength > 0 && needLength <= MAX_PATH);
00036 }
00037
00038 bool MyGetSystemDirectory(CSysString &path)
00039 {
00040 UINT needLength = ::GetSystemDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
00041 path.ReleaseBuffer();
00042 return (needLength > 0 && needLength <= MAX_PATH);
00043 }
00044
00045 #ifndef _UNICODE
00046 bool MyGetWindowsDirectory(UString &path)
00047 {
00048 if (g_IsNT)
00049 {
00050 UINT needLength = ::GetWindowsDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
00051 path.ReleaseBuffer();
00052 return (needLength > 0 && needLength <= MAX_PATH);
00053 }
00054 CSysString sysPath;
00055 if (!MyGetWindowsDirectory(sysPath))
00056 return false;
00057 path = GetUnicodePath(sysPath);
00058 return true;
00059 }
00060
00061 bool MyGetSystemDirectory(UString &path)
00062 {
00063 if (g_IsNT)
00064 {
00065 UINT needLength = ::GetSystemDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
00066 path.ReleaseBuffer();
00067 return (needLength > 0 && needLength <= MAX_PATH);
00068 }
00069 CSysString sysPath;
00070 if (!MyGetSystemDirectory(sysPath))
00071 return false;
00072 path = GetUnicodePath(sysPath);
00073 return true;
00074 }
00075 #endif
00076
00077 #ifndef _UNICODE
00078 bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes)
00079 {
00080 if (g_IsNT)
00081 return BOOLToBool(::SetFileAttributesW(fileName, fileAttributes));
00082 return MySetFileAttributes(GetSysPath(fileName), fileAttributes);
00083 }
00084
00085 bool MyRemoveDirectory(LPCWSTR pathName)
00086 {
00087 if (g_IsNT)
00088 return BOOLToBool(::RemoveDirectoryW(pathName));
00089 return MyRemoveDirectory(GetSysPath(pathName));
00090 }
00091
00092 bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName)
00093 {
00094 if (g_IsNT)
00095 return BOOLToBool(::MoveFileW(existFileName, newFileName));
00096 return MyMoveFile(GetSysPath(existFileName), GetSysPath(newFileName));
00097 }
00098 #endif
00099
00100 bool MyCreateDirectory(LPCTSTR pathName) { return BOOLToBool(::CreateDirectory(pathName, NULL)); }
00101
00102 #ifndef _UNICODE
00103 bool MyCreateDirectory(LPCWSTR pathName)
00104 {
00105 if (g_IsNT)
00106 return BOOLToBool(::CreateDirectoryW(pathName, NULL));
00107 return MyCreateDirectory(GetSysPath(pathName));
00108 }
00109 #endif
00110
00111 bool CreateComplexDirectory(LPCTSTR _aPathName)
00112 {
00113 CSysString pathName = _aPathName;
00114 int pos = pathName.ReverseFind(TEXT('\\'));
00115 if (pos > 0 && pos == pathName.Length() - 1)
00116 {
00117 if (pathName.Length() == 3 && pathName[1] == ':')
00118 return true;
00119 pathName.Delete(pos);
00120 }
00121 CSysString pathName2 = pathName;
00122 pos = pathName.Length();
00123 while(true)
00124 {
00125 if(MyCreateDirectory(pathName))
00126 break;
00127 if(::GetLastError() == ERROR_ALREADY_EXISTS)
00128 {
00129 NFind::CFileInfo fileInfo;
00130 if (!NFind::FindFile(pathName, fileInfo))
00131 return true;
00132 if (!fileInfo.IsDirectory())
00133 return false;
00134 break;
00135 }
00136 pos = pathName.ReverseFind(TEXT('\\'));
00137 if (pos < 0 || pos == 0)
00138 return false;
00139 if (pathName[pos - 1] == ':')
00140 return false;
00141 pathName = pathName.Left(pos);
00142 }
00143 pathName = pathName2;
00144 while(pos < pathName.Length())
00145 {
00146 pos = pathName.Find(TEXT('\\'), pos + 1);
00147 if (pos < 0)
00148 pos = pathName.Length();
00149 if(!MyCreateDirectory(pathName.Left(pos)))
00150 return false;
00151 }
00152 return true;
00153 }
00154
00155 #ifndef _UNICODE
00156
00157 bool CreateComplexDirectory(LPCWSTR _aPathName)
00158 {
00159 UString pathName = _aPathName;
00160 int pos = pathName.ReverseFind(L'\\');
00161 if (pos > 0 && pos == pathName.Length() - 1)
00162 {
00163 if (pathName.Length() == 3 && pathName[1] == L':')
00164 return true;
00165 pathName.Delete(pos);
00166 }
00167 UString pathName2 = pathName;
00168 pos = pathName.Length();
00169 while(true)
00170 {
00171 if(MyCreateDirectory(pathName))
00172 break;
00173 if(::GetLastError() == ERROR_ALREADY_EXISTS)
00174 {
00175 NFind::CFileInfoW fileInfo;
00176 if (!NFind::FindFile(pathName, fileInfo))
00177 return true;
00178 if (!fileInfo.IsDirectory())
00179 return false;
00180 break;
00181 }
00182 pos = pathName.ReverseFind(L'\\');
00183 if (pos < 0 || pos == 0)
00184 return false;
00185 if (pathName[pos - 1] == L':')
00186 return false;
00187 pathName = pathName.Left(pos);
00188 }
00189 pathName = pathName2;
00190 while(pos < pathName.Length())
00191 {
00192 pos = pathName.Find(L'\\', pos + 1);
00193 if (pos < 0)
00194 pos = pathName.Length();
00195 if(!MyCreateDirectory(pathName.Left(pos)))
00196 return false;
00197 }
00198 return true;
00199 }
00200
00201 #endif
00202
00203 bool DeleteFileAlways(LPCTSTR name)
00204 {
00205 if(!::SetFileAttributes(name, 0))
00206 return false;
00207 return BOOLToBool(::DeleteFile(name));
00208 }
00209
00210 #ifndef _UNICODE
00211 bool DeleteFileAlways(LPCWSTR name)
00212 {
00213 if (g_IsNT)
00214 {
00215 if(!MySetFileAttributes(name, 0))
00216 return false;
00217 return BOOLToBool(::DeleteFileW(name));
00218 }
00219 return DeleteFileAlways(GetSysPath(name));
00220 }
00221 #endif
00222
00223 static bool RemoveDirectorySubItems2(const CSysString pathPrefix, const NFind::CFileInfo &fileInfo)
00224 {
00225 if(fileInfo.IsDirectory())
00226 return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
00227 else
00228 return DeleteFileAlways(pathPrefix + fileInfo.Name);
00229 }
00230
00231 bool RemoveDirectoryWithSubItems(const CSysString &path)
00232 {
00233 NFind::CFileInfo fileInfo;
00234 CSysString pathPrefix = path + NName::kDirDelimiter;
00235 {
00236 NFind::CEnumerator enumerator(pathPrefix + TCHAR(NName::kAnyStringWildcard));
00237 while(enumerator.Next(fileInfo))
00238 if(!RemoveDirectorySubItems2(pathPrefix, fileInfo))
00239 return false;
00240 }
00241 if(!BOOLToBool(::SetFileAttributes(path, 0)))
00242 return false;
00243 return BOOLToBool(::RemoveDirectory(path));
00244 }
00245
00246 #ifndef _UNICODE
00247 static bool RemoveDirectorySubItems2(const UString pathPrefix, const NFind::CFileInfoW &fileInfo)
00248 {
00249 if(fileInfo.IsDirectory())
00250 return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
00251 else
00252 return DeleteFileAlways(pathPrefix + fileInfo.Name);
00253 }
00254 bool RemoveDirectoryWithSubItems(const UString &path)
00255 {
00256 NFind::CFileInfoW fileInfo;
00257 UString pathPrefix = path + UString(NName::kDirDelimiter);
00258 {
00259 NFind::CEnumeratorW enumerator(pathPrefix + UString(NName::kAnyStringWildcard));
00260 while(enumerator.Next(fileInfo))
00261 if(!RemoveDirectorySubItems2(pathPrefix, fileInfo))
00262 return false;
00263 }
00264 if(!MySetFileAttributes(path, 0))
00265 return false;
00266 return MyRemoveDirectory(path);
00267 }
00268 #endif
00269
00270 #ifndef _WIN32_WCE
00271
00272 bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath)
00273 {
00274 DWORD needLength = ::GetShortPathName(longPath, shortPath.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
00275 shortPath.ReleaseBuffer();
00276 return (needLength > 0 && needLength < MAX_PATH);
00277 }
00278
00279 bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex)
00280 {
00281 resultPath.Empty();
00282 LPTSTR fileNamePointer = 0;
00283 LPTSTR buffer = resultPath.GetBuffer(MAX_PATH);
00284 DWORD needLength = ::GetFullPathName(fileName, MAX_PATH + 1, buffer, &fileNamePointer);
00285 resultPath.ReleaseBuffer();
00286 if (needLength == 0 || needLength >= MAX_PATH)
00287 return false;
00288 if (fileNamePointer == 0)
00289 fileNamePartStartIndex = lstrlen(fileName);
00290 else
00291 fileNamePartStartIndex = (int)(fileNamePointer - buffer);
00292 return true;
00293 }
00294
00295 #ifndef _UNICODE
00296 bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex)
00297 {
00298 resultPath.Empty();
00299 if (g_IsNT)
00300 {
00301 LPWSTR fileNamePointer = 0;
00302 LPWSTR buffer = resultPath.GetBuffer(MAX_PATH);
00303 DWORD needLength = ::GetFullPathNameW(fileName, MAX_PATH + 1, buffer, &fileNamePointer);
00304 resultPath.ReleaseBuffer();
00305 if (needLength == 0 || needLength >= MAX_PATH)
00306 return false;
00307 if (fileNamePointer == 0)
00308 fileNamePartStartIndex = MyStringLen(fileName);
00309 else
00310 fileNamePartStartIndex = (int)(fileNamePointer - buffer);
00311 }
00312 else
00313 {
00314 CSysString sysPath;
00315 if (!MyGetFullPathName(GetSysPath(fileName), sysPath, fileNamePartStartIndex))
00316 return false;
00317 UString resultPath1 = GetUnicodePath(sysPath.Left(fileNamePartStartIndex));
00318 UString resultPath2 = GetUnicodePath(sysPath.Mid(fileNamePartStartIndex));
00319 fileNamePartStartIndex = resultPath1.Length();
00320 resultPath = resultPath1 + resultPath2;
00321 }
00322 return true;
00323 }
00324 #endif
00325
00326 bool MyGetFullPathName(LPCTSTR fileName, CSysString &path)
00327 {
00328 int index;
00329 return MyGetFullPathName(fileName, path, index);
00330 }
00331
00332 #ifndef _UNICODE
00333 bool MyGetFullPathName(LPCWSTR fileName, UString &path)
00334 {
00335 int index;
00336 return MyGetFullPathName(fileName, path, index);
00337 }
00338 #endif
00339
00340 bool GetOnlyName(LPCTSTR fileName, CSysString &resultName)
00341 {
00342 int index;
00343 if (!MyGetFullPathName(fileName, resultName, index))
00344 return false;
00345 resultName = resultName.Mid(index);
00346 return true;
00347 }
00348
00349 #ifndef _UNICODE
00350 bool GetOnlyName(LPCWSTR fileName, UString &resultName)
00351 {
00352 int index;
00353 if (!MyGetFullPathName(fileName, resultName, index))
00354 return false;
00355 resultName = resultName.Mid(index);
00356 return true;
00357 }
00358 #endif
00359
00360 bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName)
00361 {
00362 int index;
00363 if (!MyGetFullPathName(fileName, resultName, index))
00364 return false;
00365 resultName = resultName.Left(index);
00366 return true;
00367 }
00368
00369 #ifndef _UNICODE
00370 bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName)
00371 {
00372 int index;
00373 if (!MyGetFullPathName(fileName, resultName, index))
00374 return false;
00375 resultName = resultName.Left(index);
00376 return true;
00377 }
00378 #endif
00379
00380 bool MyGetCurrentDirectory(CSysString &path)
00381 {
00382 DWORD needLength = ::GetCurrentDirectory(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
00383 path.ReleaseBuffer();
00384 return (needLength > 0 && needLength <= MAX_PATH);
00385 }
00386
00387 #ifndef _UNICODE
00388 bool MySetCurrentDirectory(LPCWSTR path)
00389 {
00390 if (g_IsNT)
00391 return BOOLToBool(::SetCurrentDirectoryW(path));
00392 return MySetCurrentDirectory(GetSysPath(path));
00393 }
00394 bool MyGetCurrentDirectory(UString &path)
00395 {
00396 if (g_IsNT)
00397 {
00398 DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
00399 path.ReleaseBuffer();
00400 return (needLength > 0 && needLength <= MAX_PATH);
00401 }
00402 CSysString sysPath;
00403 if (!MyGetCurrentDirectory(sysPath))
00404 return false;
00405 path = GetUnicodePath(sysPath);
00406 return true;
00407 }
00408 #endif
00409 #endif
00410
00411 bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension,
00412 CSysString &resultPath, UINT32 &filePart)
00413 {
00414 LPTSTR filePartPointer;
00415 DWORD value = ::SearchPath(path, fileName, extension,
00416 MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);
00417 filePart = (UINT32)(filePartPointer - (LPCTSTR)resultPath);
00418 resultPath.ReleaseBuffer();
00419 return (value > 0 && value <= MAX_PATH);
00420 }
00421
00422 #ifndef _UNICODE
00423 bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension,
00424 UString &resultPath, UINT32 &filePart)
00425 {
00426 if (g_IsNT)
00427 {
00428 LPWSTR filePartPointer = 0;
00429 DWORD value = ::SearchPathW(path, fileName, extension,
00430 MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);
00431 filePart = (UINT32)(filePartPointer - (LPCWSTR)resultPath);
00432 resultPath.ReleaseBuffer();
00433 return (value > 0 && value <= MAX_PATH);
00434 }
00435
00436 CSysString sysPath;
00437 if (!MySearchPath(
00438 path != 0 ? (LPCTSTR)GetSysPath(path): 0,
00439 fileName != 0 ? (LPCTSTR)GetSysPath(fileName): 0,
00440 extension != 0 ? (LPCTSTR)GetSysPath(extension): 0,
00441 sysPath, filePart))
00442 return false;
00443 UString resultPath1 = GetUnicodePath(sysPath.Left(filePart));
00444 UString resultPath2 = GetUnicodePath(sysPath.Mid(filePart));
00445 filePart = resultPath1.Length();
00446 resultPath = resultPath1 + resultPath2;
00447 return true;
00448 }
00449 #endif
00450
00451 bool MyGetTempPath(CSysString &path)
00452 {
00453 DWORD needLength = ::GetTempPath(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
00454 path.ReleaseBuffer();
00455 return (needLength > 0 && needLength <= MAX_PATH);
00456 }
00457
00458 #ifndef _UNICODE
00459 bool MyGetTempPath(UString &path)
00460 {
00461 path.Empty();
00462 if (g_IsNT)
00463 {
00464 DWORD needLength = ::GetTempPathW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
00465 path.ReleaseBuffer();
00466 return (needLength > 0 && needLength <= MAX_PATH);
00467 }
00468 CSysString sysPath;
00469 if (!MyGetTempPath(sysPath))
00470 return false;
00471 path = GetUnicodePath(sysPath);
00472 return true;
00473 }
00474 #endif
00475
00476 UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &path)
00477 {
00478 UINT number = ::GetTempFileName(dirPath, prefix, 0, path.GetBuffer(MAX_PATH + 1));
00479 path.ReleaseBuffer();
00480 return number;
00481 }
00482
00483 #ifndef _UNICODE
00484 UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &path)
00485 {
00486 if (g_IsNT)
00487 {
00488 UINT number = ::GetTempFileNameW(dirPath, prefix, 0, path.GetBuffer(MAX_PATH));
00489 path.ReleaseBuffer();
00490 return number;
00491 }
00492 CSysString sysPath;
00493 UINT number = MyGetTempFileName(
00494 dirPath ? (LPCTSTR)GetSysPath(dirPath): 0,
00495 prefix ? (LPCTSTR)GetSysPath(prefix): 0,
00496 sysPath);
00497 path = GetUnicodePath(sysPath);
00498 return number;
00499 }
00500 #endif
00501
00502 UINT CTempFile::Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath)
00503 {
00504 Remove();
00505 UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
00506 if(number != 0)
00507 {
00508 _fileName = resultPath;
00509 _mustBeDeleted = true;
00510 }
00511 return number;
00512 }
00513
00514 bool CTempFile::Create(LPCTSTR prefix, CSysString &resultPath)
00515 {
00516 CSysString tempPath;
00517 if(!MyGetTempPath(tempPath))
00518 return false;
00519 if (Create(tempPath, prefix, resultPath) != 0)
00520 return true;
00521 if(!MyGetWindowsDirectory(tempPath))
00522 return false;
00523 return (Create(tempPath, prefix, resultPath) != 0);
00524 }
00525
00526 bool CTempFile::Remove()
00527 {
00528 if (!_mustBeDeleted)
00529 return true;
00530 _mustBeDeleted = !DeleteFileAlways(_fileName);
00531 return !_mustBeDeleted;
00532 }
00533
00534 #ifndef _UNICODE
00535
00536 UINT CTempFileW::Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath)
00537 {
00538 Remove();
00539 UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
00540 if(number != 0)
00541 {
00542 _fileName = resultPath;
00543 _mustBeDeleted = true;
00544 }
00545 return number;
00546 }
00547
00548 bool CTempFileW::Create(LPCWSTR prefix, UString &resultPath)
00549 {
00550 UString tempPath;
00551 if(!MyGetTempPath(tempPath))
00552 return false;
00553 if (Create(tempPath, prefix, resultPath) != 0)
00554 return true;
00555 if(!MyGetWindowsDirectory(tempPath))
00556 return false;
00557 return (Create(tempPath, prefix, resultPath) != 0);
00558 }
00559
00560 bool CTempFileW::Remove()
00561 {
00562 if (!_mustBeDeleted)
00563 return true;
00564 _mustBeDeleted = !DeleteFileAlways(_fileName);
00565 return !_mustBeDeleted;
00566 }
00567
00568 #endif
00569
00570 bool CreateTempDirectory(LPCTSTR prefix, CSysString &dirName)
00571 {
00572
00573 while(true)
00574 {
00575 CTempFile tempFile;
00576 if (!tempFile.Create(prefix, dirName))
00577 return false;
00578 if (!::DeleteFile(dirName))
00579 return false;
00580
00581 if(NFind::DoesFileExist(dirName))
00582 continue;
00583 if (MyCreateDirectory(dirName))
00584 return true;
00585 if (::GetLastError() != ERROR_ALREADY_EXISTS)
00586 return false;
00587 }
00588 }
00589
00590 bool CTempDirectory::Create(LPCTSTR prefix)
00591 {
00592 Remove();
00593 return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
00594 }
00595
00596 #ifndef _UNICODE
00597
00598 bool CreateTempDirectory(LPCWSTR prefix, UString &dirName)
00599 {
00600
00601 while(true)
00602 {
00603 CTempFileW tempFile;
00604 if (!tempFile.Create(prefix, dirName))
00605 return false;
00606 if (!DeleteFileAlways(dirName))
00607 return false;
00608
00609 if(NFind::DoesFileExist(dirName))
00610 continue;
00611 if (MyCreateDirectory(dirName))
00612 return true;
00613 if (::GetLastError() != ERROR_ALREADY_EXISTS)
00614 return false;
00615 }
00616 }
00617
00618 bool CTempDirectoryW::Create(LPCWSTR prefix)
00619 {
00620 Remove();
00621 return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
00622 }
00623
00624 #endif
00625
00626 }}}