other-licenses/7zstub/src/Windows/FileDir.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 // Windows/FileDir.cpp
     3 #include "StdAfx.h"
     5 #include "FileDir.h"
     6 #include "FileName.h"
     7 #include "FileFind.h"
     8 #include "Defs.h"
     9 #ifndef _UNICODE
    10 #include "../Common/StringConvert.h"
    11 #endif
    13 #ifndef _UNICODE
    14 extern bool g_IsNT;
    15 #endif
    17 namespace NWindows {
    18 namespace NFile {
    19 namespace NDirectory {
    21 #ifndef _UNICODE
    22 static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } 
    23 static UString GetUnicodePath(const CSysString &sysPath)
    24   { return MultiByteToUnicodeString(sysPath, GetCurrentCodePage()); }
    25 static CSysString GetSysPath(LPCWSTR sysPath)
    26   { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); }
    27 #endif
    29 bool MyGetWindowsDirectory(CSysString &path)
    30 {
    31   UINT needLength = ::GetWindowsDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
    32   path.ReleaseBuffer();
    33   return (needLength > 0 && needLength <= MAX_PATH);
    34 }
    36 bool MyGetSystemDirectory(CSysString &path)
    37 {
    38   UINT needLength = ::GetSystemDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
    39   path.ReleaseBuffer();
    40   return (needLength > 0 && needLength <= MAX_PATH);
    41 }
    43 #ifndef _UNICODE
    44 bool MyGetWindowsDirectory(UString &path)
    45 {
    46   if (g_IsNT)
    47   {
    48     UINT needLength = ::GetWindowsDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
    49     path.ReleaseBuffer();
    50     return (needLength > 0 && needLength <= MAX_PATH);
    51   }
    52   CSysString sysPath;
    53   if (!MyGetWindowsDirectory(sysPath))
    54     return false;
    55   path = GetUnicodePath(sysPath);
    56   return true;
    57 }
    59 bool MyGetSystemDirectory(UString &path)
    60 {
    61   if (g_IsNT)
    62   {
    63     UINT needLength = ::GetSystemDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
    64     path.ReleaseBuffer();
    65     return (needLength > 0 && needLength <= MAX_PATH);
    66   }
    67   CSysString sysPath;
    68   if (!MyGetSystemDirectory(sysPath))
    69     return false;
    70   path = GetUnicodePath(sysPath);
    71   return true;
    72 }
    73 #endif
    75 #ifndef _UNICODE
    76 bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes)
    77 {  
    78   if (g_IsNT)
    79     return BOOLToBool(::SetFileAttributesW(fileName, fileAttributes));
    80   return MySetFileAttributes(GetSysPath(fileName), fileAttributes);
    81 }
    83 bool MyRemoveDirectory(LPCWSTR pathName)
    84 {  
    85   if (g_IsNT)
    86     return BOOLToBool(::RemoveDirectoryW(pathName));
    87   return MyRemoveDirectory(GetSysPath(pathName));
    88 }
    90 bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName)
    91 {  
    92   if (g_IsNT)
    93     return BOOLToBool(::MoveFileW(existFileName, newFileName));
    94   return MyMoveFile(GetSysPath(existFileName), GetSysPath(newFileName));
    95 }
    96 #endif
    98 bool MyCreateDirectory(LPCTSTR pathName) { return BOOLToBool(::CreateDirectory(pathName, NULL)); }
   100 #ifndef _UNICODE
   101 bool MyCreateDirectory(LPCWSTR pathName)
   102 {  
   103   if (g_IsNT)
   104     return BOOLToBool(::CreateDirectoryW(pathName, NULL));
   105   return MyCreateDirectory(GetSysPath(pathName));
   106 }
   107 #endif
   109 /*
   110 bool CreateComplexDirectory(LPCTSTR pathName)
   111 {
   112   NName::CParsedPath path;
   113   path.ParsePath(pathName);
   114   CSysString fullPath = path.Prefix;
   115   DWORD errorCode = ERROR_SUCCESS;
   116   for(int i = 0; i < path.PathParts.Size(); i++)
   117   {
   118     const CSysString &string = path.PathParts[i];
   119     if(string.IsEmpty())
   120     {
   121       if(i != path.PathParts.Size() - 1)
   122         return false;
   123       return true;
   124     }
   125     fullPath += path.PathParts[i];
   126     if(!MyCreateDirectory(fullPath))
   127     {
   128       DWORD errorCode = GetLastError();
   129       if(errorCode != ERROR_ALREADY_EXISTS)
   130         return false;
   131     }
   132     fullPath += NName::kDirDelimiter;
   133   }
   134   return true;
   135 }
   136 */
   138 bool CreateComplexDirectory(LPCTSTR _aPathName)
   139 {
   140   CSysString pathName = _aPathName;
   141   int pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
   142   if (pos > 0 && pos == pathName.Length() - 1)
   143   {
   144     if (pathName.Length() == 3 && pathName[1] == ':')
   145       return true; // Disk folder;
   146     pathName.Delete(pos);
   147   }
   148   CSysString pathName2 = pathName;
   149   pos = pathName.Length();
   150   while(true)
   151   {
   152     if(MyCreateDirectory(pathName))
   153       break;
   154     if(::GetLastError() == ERROR_ALREADY_EXISTS)
   155     {
   156       NFind::CFileInfo fileInfo;
   157       if (!NFind::FindFile(pathName, fileInfo)) // For network folders
   158         return true;
   159       if (!fileInfo.IsDirectory())
   160         return false;
   161       break;
   162     }
   163     pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
   164     if (pos < 0 || pos == 0)
   165       return false;
   166     if (pathName[pos - 1] == ':')
   167       return false;
   168     pathName = pathName.Left(pos);
   169   }
   170   pathName = pathName2;
   171   while(pos < pathName.Length())
   172   {
   173     pos = pathName.Find(TEXT(CHAR_PATH_SEPARATOR), pos + 1);
   174     if (pos < 0)
   175       pos = pathName.Length();
   176     if(!MyCreateDirectory(pathName.Left(pos)))
   177       return false;
   178   }
   179   return true;
   180 }
   182 #ifndef _UNICODE
   184 bool CreateComplexDirectory(LPCWSTR _aPathName)
   185 {
   186   UString pathName = _aPathName;
   187   int pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
   188   if (pos > 0 && pos == pathName.Length() - 1)
   189   {
   190     if (pathName.Length() == 3 && pathName[1] == L':')
   191       return true; // Disk folder;
   192     pathName.Delete(pos);
   193   }
   194   UString pathName2 = pathName;
   195   pos = pathName.Length();
   196   while(true)
   197   {
   198     if(MyCreateDirectory(pathName))
   199       break;
   200     if(::GetLastError() == ERROR_ALREADY_EXISTS)
   201     {
   202       NFind::CFileInfoW fileInfo;
   203       if (!NFind::FindFile(pathName, fileInfo)) // For network folders
   204         return true;
   205       if (!fileInfo.IsDirectory())
   206         return false;
   207       break;
   208     }
   209     pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
   210     if (pos < 0 || pos == 0)
   211       return false;
   212     if (pathName[pos - 1] == L':')
   213       return false;
   214     pathName = pathName.Left(pos);
   215   }
   216   pathName = pathName2;
   217   while(pos < pathName.Length())
   218   {
   219     pos = pathName.Find(WCHAR_PATH_SEPARATOR, pos + 1);
   220     if (pos < 0)
   221       pos = pathName.Length();
   222     if(!MyCreateDirectory(pathName.Left(pos)))
   223       return false;
   224   }
   225   return true;
   226 }
   228 #endif
   230 bool DeleteFileAlways(LPCTSTR name)
   231 {
   232   if(!::SetFileAttributes(name, 0))
   233     return false;
   234   return BOOLToBool(::DeleteFile(name));
   235 }
   237 #ifndef _UNICODE
   238 bool DeleteFileAlways(LPCWSTR name)
   239 {  
   240   if (g_IsNT)
   241   {
   242     if(!MySetFileAttributes(name, 0))
   243       return false;
   244     return BOOLToBool(::DeleteFileW(name));
   245   }
   246   return DeleteFileAlways(GetSysPath(name));
   247 }
   248 #endif
   250 static bool RemoveDirectorySubItems2(const CSysString pathPrefix, const NFind::CFileInfo &fileInfo)
   251 {
   252   if(fileInfo.IsDirectory())
   253     return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
   254   else
   255     return DeleteFileAlways(pathPrefix + fileInfo.Name);
   256 }
   258 bool RemoveDirectoryWithSubItems(const CSysString &path)
   259 {
   260   NFind::CFileInfo fileInfo;
   261   CSysString pathPrefix = path + NName::kDirDelimiter;
   262   {
   263     NFind::CEnumerator enumerator(pathPrefix + TCHAR(NName::kAnyStringWildcard));
   264     while(enumerator.Next(fileInfo))
   265       if(!RemoveDirectorySubItems2(pathPrefix, fileInfo))
   266         return false;
   267   }
   268   if(!BOOLToBool(::SetFileAttributes(path, 0)))
   269     return false;
   270   return BOOLToBool(::RemoveDirectory(path));
   271 }
   273 #ifndef _UNICODE
   274 static bool RemoveDirectorySubItems2(const UString pathPrefix, const NFind::CFileInfoW &fileInfo)
   275 {
   276   if(fileInfo.IsDirectory())
   277     return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
   278   else
   279     return DeleteFileAlways(pathPrefix + fileInfo.Name);
   280 }
   281 bool RemoveDirectoryWithSubItems(const UString &path)
   282 {
   283   NFind::CFileInfoW fileInfo;
   284   UString pathPrefix = path + UString(NName::kDirDelimiter);
   285   {
   286     NFind::CEnumeratorW enumerator(pathPrefix + UString(NName::kAnyStringWildcard));
   287     while(enumerator.Next(fileInfo))
   288       if(!RemoveDirectorySubItems2(pathPrefix, fileInfo))
   289         return false;
   290   }
   291   if(!MySetFileAttributes(path, 0))
   292     return false;
   293   return MyRemoveDirectory(path);
   294 }
   295 #endif
   297 #ifndef _WIN32_WCE
   299 bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath)
   300 {
   301   DWORD needLength = ::GetShortPathName(longPath, shortPath.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
   302   shortPath.ReleaseBuffer();
   303   return (needLength > 0 && needLength < MAX_PATH);
   304 }
   306 bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex)
   307 {
   308   resultPath.Empty();
   309   LPTSTR fileNamePointer = 0;
   310   LPTSTR buffer = resultPath.GetBuffer(MAX_PATH);
   311   DWORD needLength = ::GetFullPathName(fileName, MAX_PATH + 1, buffer, &fileNamePointer);
   312   resultPath.ReleaseBuffer();
   313   if (needLength == 0 || needLength >= MAX_PATH)
   314     return false;
   315   if (fileNamePointer == 0)
   316     fileNamePartStartIndex = lstrlen(fileName);
   317   else
   318     fileNamePartStartIndex = (int)(fileNamePointer - buffer);
   319   return true;
   320 }
   322 #ifndef _UNICODE
   323 bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex)
   324 {
   325   resultPath.Empty();
   326   if (g_IsNT)
   327   {
   328     LPWSTR fileNamePointer = 0;
   329     LPWSTR buffer = resultPath.GetBuffer(MAX_PATH);
   330     DWORD needLength = ::GetFullPathNameW(fileName, MAX_PATH + 1, buffer, &fileNamePointer);
   331     resultPath.ReleaseBuffer();
   332     if (needLength == 0 || needLength >= MAX_PATH)
   333       return false;
   334     if (fileNamePointer == 0)
   335       fileNamePartStartIndex = MyStringLen(fileName);
   336     else
   337       fileNamePartStartIndex = (int)(fileNamePointer - buffer);
   338   }
   339   else
   340   {
   341     CSysString sysPath;
   342     if (!MyGetFullPathName(GetSysPath(fileName), sysPath, fileNamePartStartIndex))
   343       return false;
   344     UString resultPath1 = GetUnicodePath(sysPath.Left(fileNamePartStartIndex));
   345     UString resultPath2 = GetUnicodePath(sysPath.Mid(fileNamePartStartIndex));
   346     fileNamePartStartIndex = resultPath1.Length();
   347     resultPath = resultPath1 + resultPath2;
   348   }
   349   return true;
   350 }
   351 #endif
   354 bool MyGetFullPathName(LPCTSTR fileName, CSysString &path)
   355 {
   356   int index;
   357   return MyGetFullPathName(fileName, path, index);
   358 }
   360 #ifndef _UNICODE
   361 bool MyGetFullPathName(LPCWSTR fileName, UString &path)
   362 {
   363   int index;
   364   return MyGetFullPathName(fileName, path, index);
   365 }
   366 #endif
   368 bool GetOnlyName(LPCTSTR fileName, CSysString &resultName)
   369 {
   370   int index;
   371   if (!MyGetFullPathName(fileName, resultName, index))
   372     return false;
   373   resultName = resultName.Mid(index);
   374   return true;
   375 }
   377 #ifndef _UNICODE
   378 bool GetOnlyName(LPCWSTR fileName, UString &resultName)
   379 {
   380   int index;
   381   if (!MyGetFullPathName(fileName, resultName, index))
   382     return false;
   383   resultName = resultName.Mid(index);
   384   return true;
   385 }
   386 #endif
   388 bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName)
   389 {
   390   int index;
   391   if (!MyGetFullPathName(fileName, resultName, index))
   392     return false;
   393   resultName = resultName.Left(index);
   394   return true;
   395 }
   397 #ifndef _UNICODE
   398 bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName)
   399 {
   400   int index;
   401   if (!MyGetFullPathName(fileName, resultName, index))
   402     return false;
   403   resultName = resultName.Left(index);
   404   return true;
   405 }
   406 #endif
   408 bool MyGetCurrentDirectory(CSysString &path)
   409 {
   410   DWORD needLength = ::GetCurrentDirectory(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
   411   path.ReleaseBuffer();
   412   return (needLength > 0 && needLength <= MAX_PATH);
   413 }
   415 #ifndef _UNICODE
   416 bool MySetCurrentDirectory(LPCWSTR path)
   417 {
   418   if (g_IsNT)
   419     return BOOLToBool(::SetCurrentDirectoryW(path));
   420   return MySetCurrentDirectory(GetSysPath(path));
   421 }
   422 bool MyGetCurrentDirectory(UString &path)
   423 {
   424   if (g_IsNT)
   425   {
   426     DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
   427     path.ReleaseBuffer();
   428     return (needLength > 0 && needLength <= MAX_PATH);
   429   }
   430   CSysString sysPath;
   431   if (!MyGetCurrentDirectory(sysPath))
   432     return false;
   433   path = GetUnicodePath(sysPath);
   434   return true;
   435 }
   436 #endif
   437 #endif
   439 bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension, 
   440   CSysString &resultPath, UINT32 &filePart)
   441 {
   442   LPTSTR filePartPointer;
   443   DWORD value = ::SearchPath(path, fileName, extension, 
   444     MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);
   445   filePart = (UINT32)(filePartPointer - (LPCTSTR)resultPath);
   446   resultPath.ReleaseBuffer();
   447   return (value > 0 && value <= MAX_PATH);
   448 }
   450 #ifndef _UNICODE
   451 bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, 
   452   UString &resultPath, UINT32 &filePart)
   453 {
   454   if (g_IsNT)
   455   {
   456     LPWSTR filePartPointer = 0;
   457     DWORD value = ::SearchPathW(path, fileName, extension, 
   458         MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);
   459     filePart = (UINT32)(filePartPointer - (LPCWSTR)resultPath);
   460     resultPath.ReleaseBuffer();
   461     return (value > 0 && value <= MAX_PATH);
   462   }
   464   CSysString sysPath;
   465   if (!MySearchPath(
   466       path != 0 ? (LPCTSTR)GetSysPath(path): 0,
   467       fileName != 0 ? (LPCTSTR)GetSysPath(fileName): 0,
   468       extension != 0 ? (LPCTSTR)GetSysPath(extension): 0,
   469       sysPath, filePart))
   470     return false;
   471   UString resultPath1 = GetUnicodePath(sysPath.Left(filePart));
   472   UString resultPath2 = GetUnicodePath(sysPath.Mid(filePart));
   473   filePart = resultPath1.Length();
   474   resultPath = resultPath1 + resultPath2;
   475   return true;
   476 }
   477 #endif
   479 bool MyGetTempPath(CSysString &path)
   480 {
   481   DWORD needLength = ::GetTempPath(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
   482   path.ReleaseBuffer();
   483   return (needLength > 0 && needLength <= MAX_PATH);
   484 }
   486 #ifndef _UNICODE
   487 bool MyGetTempPath(UString &path)
   488 {
   489   path.Empty();
   490   if (g_IsNT)
   491   {
   492     DWORD needLength = ::GetTempPathW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
   493     path.ReleaseBuffer();
   494     return (needLength > 0 && needLength <= MAX_PATH);
   495   }
   496   CSysString sysPath;
   497   if (!MyGetTempPath(sysPath))
   498     return false;
   499   path = GetUnicodePath(sysPath);
   500   return true;
   501 }
   502 #endif
   504 UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &path)
   505 {
   506   UINT number = ::GetTempFileName(dirPath, prefix, 0, path.GetBuffer(MAX_PATH + 1));
   507   path.ReleaseBuffer();
   508   return number;
   509 }
   511 #ifndef _UNICODE
   512 UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &path)
   513 {
   514   if (g_IsNT)
   515   {
   516     UINT number = ::GetTempFileNameW(dirPath, prefix, 0, path.GetBuffer(MAX_PATH));
   517     path.ReleaseBuffer();
   518     return number;
   519   }
   520   CSysString sysPath;
   521   UINT number = MyGetTempFileName(
   522       dirPath ? (LPCTSTR)GetSysPath(dirPath): 0, 
   523       prefix ? (LPCTSTR)GetSysPath(prefix): 0, 
   524       sysPath);
   525   path = GetUnicodePath(sysPath);
   526   return number;
   527 }
   528 #endif
   530 UINT CTempFile::Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath)
   531 {
   532   Remove();
   533   UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
   534   if(number != 0)
   535   {
   536     _fileName = resultPath;
   537     _mustBeDeleted = true;
   538   }
   539   return number;
   540 }
   542 bool CTempFile::Create(LPCTSTR prefix, CSysString &resultPath)
   543 {
   544   CSysString tempPath;
   545   if(!MyGetTempPath(tempPath))
   546     return false;
   547   if (Create(tempPath, prefix, resultPath) != 0)
   548     return true;
   549   if(!MyGetWindowsDirectory(tempPath))
   550     return false;
   551   return (Create(tempPath, prefix, resultPath) != 0);
   552 }
   554 bool CTempFile::Remove()
   555 {
   556   if (!_mustBeDeleted)
   557     return true;
   558   _mustBeDeleted = !DeleteFileAlways(_fileName);
   559   return !_mustBeDeleted;
   560 }
   562 #ifndef _UNICODE
   564 UINT CTempFileW::Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath)
   565 {
   566   Remove();
   567   UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
   568   if(number != 0)
   569   {
   570     _fileName = resultPath;
   571     _mustBeDeleted = true;
   572   }
   573   return number;
   574 }
   576 bool CTempFileW::Create(LPCWSTR prefix, UString &resultPath)
   577 {
   578   UString tempPath;
   579   if(!MyGetTempPath(tempPath))
   580     return false;
   581   if (Create(tempPath, prefix, resultPath) != 0)
   582     return true;
   583   if(!MyGetWindowsDirectory(tempPath))
   584     return false;
   585   return (Create(tempPath, prefix, resultPath) != 0);
   586 }
   588 bool CTempFileW::Remove()
   589 {
   590   if (!_mustBeDeleted)
   591     return true;
   592   _mustBeDeleted = !DeleteFileAlways(_fileName);
   593   return !_mustBeDeleted;
   594 }
   596 #endif
   598 bool CreateTempDirectory(LPCTSTR prefix, CSysString &dirName)
   599 {
   600   /*
   601   CSysString prefix = tempPath + prefixChars;
   602   CRandom random;
   603   random.Init();
   604   */
   605   while(true)
   606   {
   607     CTempFile tempFile;
   608     if (!tempFile.Create(prefix, dirName))
   609       return false;
   610     if (!::DeleteFile(dirName))
   611       return false;
   612     /*
   613     UINT32 randomNumber = random.Generate();
   614     TCHAR randomNumberString[32];
   615     _stprintf(randomNumberString, _T("%04X"), randomNumber);
   616     dirName = prefix + randomNumberString;
   617     */
   618     if(NFind::DoesFileExist(dirName))
   619       continue;
   620     if (MyCreateDirectory(dirName))
   621       return true;
   622     if (::GetLastError() != ERROR_ALREADY_EXISTS)
   623       return false;
   624   }
   625 }
   627 bool CTempDirectory::Create(LPCTSTR prefix)
   628 { 
   629   Remove();
   630   return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir)); 
   631 }
   633 #ifndef _UNICODE
   635 bool CreateTempDirectory(LPCWSTR prefix, UString &dirName)
   636 {
   637   /*
   638   CSysString prefix = tempPath + prefixChars;
   639   CRandom random;
   640   random.Init();
   641   */
   642   while(true)
   643   {
   644     CTempFileW tempFile;
   645     if (!tempFile.Create(prefix, dirName))
   646       return false;
   647     if (!DeleteFileAlways(dirName))
   648       return false;
   649     /*
   650     UINT32 randomNumber = random.Generate();
   651     TCHAR randomNumberString[32];
   652     _stprintf(randomNumberString, _T("%04X"), randomNumber);
   653     dirName = prefix + randomNumberString;
   654     */
   655     if(NFind::DoesFileExist(dirName))
   656       continue;
   657     if (MyCreateDirectory(dirName))
   658       return true;
   659     if (::GetLastError() != ERROR_ALREADY_EXISTS)
   660       return false;
   661   }
   662 }
   664 bool CTempDirectoryW::Create(LPCWSTR prefix)
   665 { 
   666   Remove();
   667   return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir)); 
   668 }
   670 #endif
   672 }}}

mercurial