michael@0: // Windows/FileDir.cpp michael@0: michael@0: #include "StdAfx.h" michael@0: michael@0: #include "FileDir.h" michael@0: #include "FileName.h" michael@0: #include "FileFind.h" michael@0: #include "Defs.h" michael@0: #ifndef _UNICODE michael@0: #include "../Common/StringConvert.h" michael@0: #endif michael@0: michael@0: #ifndef _UNICODE michael@0: extern bool g_IsNT; michael@0: #endif michael@0: michael@0: namespace NWindows { michael@0: namespace NFile { michael@0: namespace NDirectory { michael@0: michael@0: #ifndef _UNICODE michael@0: static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } michael@0: static UString GetUnicodePath(const CSysString &sysPath) michael@0: { return MultiByteToUnicodeString(sysPath, GetCurrentCodePage()); } michael@0: static CSysString GetSysPath(LPCWSTR sysPath) michael@0: { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); } michael@0: #endif michael@0: michael@0: bool MyGetWindowsDirectory(CSysString &path) michael@0: { michael@0: UINT needLength = ::GetWindowsDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1); michael@0: path.ReleaseBuffer(); michael@0: return (needLength > 0 && needLength <= MAX_PATH); michael@0: } michael@0: michael@0: bool MyGetSystemDirectory(CSysString &path) michael@0: { michael@0: UINT needLength = ::GetSystemDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1); michael@0: path.ReleaseBuffer(); michael@0: return (needLength > 0 && needLength <= MAX_PATH); michael@0: } michael@0: michael@0: #ifndef _UNICODE michael@0: bool MyGetWindowsDirectory(UString &path) michael@0: { michael@0: if (g_IsNT) michael@0: { michael@0: UINT needLength = ::GetWindowsDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1); michael@0: path.ReleaseBuffer(); michael@0: return (needLength > 0 && needLength <= MAX_PATH); michael@0: } michael@0: CSysString sysPath; michael@0: if (!MyGetWindowsDirectory(sysPath)) michael@0: return false; michael@0: path = GetUnicodePath(sysPath); michael@0: return true; michael@0: } michael@0: michael@0: bool MyGetSystemDirectory(UString &path) michael@0: { michael@0: if (g_IsNT) michael@0: { michael@0: UINT needLength = ::GetSystemDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1); michael@0: path.ReleaseBuffer(); michael@0: return (needLength > 0 && needLength <= MAX_PATH); michael@0: } michael@0: CSysString sysPath; michael@0: if (!MyGetSystemDirectory(sysPath)) michael@0: return false; michael@0: path = GetUnicodePath(sysPath); michael@0: return true; michael@0: } michael@0: #endif michael@0: michael@0: #ifndef _UNICODE michael@0: bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes) michael@0: { michael@0: if (g_IsNT) michael@0: return BOOLToBool(::SetFileAttributesW(fileName, fileAttributes)); michael@0: return MySetFileAttributes(GetSysPath(fileName), fileAttributes); michael@0: } michael@0: michael@0: bool MyRemoveDirectory(LPCWSTR pathName) michael@0: { michael@0: if (g_IsNT) michael@0: return BOOLToBool(::RemoveDirectoryW(pathName)); michael@0: return MyRemoveDirectory(GetSysPath(pathName)); michael@0: } michael@0: michael@0: bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName) michael@0: { michael@0: if (g_IsNT) michael@0: return BOOLToBool(::MoveFileW(existFileName, newFileName)); michael@0: return MyMoveFile(GetSysPath(existFileName), GetSysPath(newFileName)); michael@0: } michael@0: #endif michael@0: michael@0: bool MyCreateDirectory(LPCTSTR pathName) { return BOOLToBool(::CreateDirectory(pathName, NULL)); } michael@0: michael@0: #ifndef _UNICODE michael@0: bool MyCreateDirectory(LPCWSTR pathName) michael@0: { michael@0: if (g_IsNT) michael@0: return BOOLToBool(::CreateDirectoryW(pathName, NULL)); michael@0: return MyCreateDirectory(GetSysPath(pathName)); michael@0: } michael@0: #endif michael@0: michael@0: /* michael@0: bool CreateComplexDirectory(LPCTSTR pathName) michael@0: { michael@0: NName::CParsedPath path; michael@0: path.ParsePath(pathName); michael@0: CSysString fullPath = path.Prefix; michael@0: DWORD errorCode = ERROR_SUCCESS; michael@0: for(int i = 0; i < path.PathParts.Size(); i++) michael@0: { michael@0: const CSysString &string = path.PathParts[i]; michael@0: if(string.IsEmpty()) michael@0: { michael@0: if(i != path.PathParts.Size() - 1) michael@0: return false; michael@0: return true; michael@0: } michael@0: fullPath += path.PathParts[i]; michael@0: if(!MyCreateDirectory(fullPath)) michael@0: { michael@0: DWORD errorCode = GetLastError(); michael@0: if(errorCode != ERROR_ALREADY_EXISTS) michael@0: return false; michael@0: } michael@0: fullPath += NName::kDirDelimiter; michael@0: } michael@0: return true; michael@0: } michael@0: */ michael@0: michael@0: bool CreateComplexDirectory(LPCTSTR _aPathName) michael@0: { michael@0: CSysString pathName = _aPathName; michael@0: int pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR)); michael@0: if (pos > 0 && pos == pathName.Length() - 1) michael@0: { michael@0: if (pathName.Length() == 3 && pathName[1] == ':') michael@0: return true; // Disk folder; michael@0: pathName.Delete(pos); michael@0: } michael@0: CSysString pathName2 = pathName; michael@0: pos = pathName.Length(); michael@0: while(true) michael@0: { michael@0: if(MyCreateDirectory(pathName)) michael@0: break; michael@0: if(::GetLastError() == ERROR_ALREADY_EXISTS) michael@0: { michael@0: NFind::CFileInfo fileInfo; michael@0: if (!NFind::FindFile(pathName, fileInfo)) // For network folders michael@0: return true; michael@0: if (!fileInfo.IsDirectory()) michael@0: return false; michael@0: break; michael@0: } michael@0: pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR)); michael@0: if (pos < 0 || pos == 0) michael@0: return false; michael@0: if (pathName[pos - 1] == ':') michael@0: return false; michael@0: pathName = pathName.Left(pos); michael@0: } michael@0: pathName = pathName2; michael@0: while(pos < pathName.Length()) michael@0: { michael@0: pos = pathName.Find(TEXT(CHAR_PATH_SEPARATOR), pos + 1); michael@0: if (pos < 0) michael@0: pos = pathName.Length(); michael@0: if(!MyCreateDirectory(pathName.Left(pos))) michael@0: return false; michael@0: } michael@0: return true; michael@0: } michael@0: michael@0: #ifndef _UNICODE michael@0: michael@0: bool CreateComplexDirectory(LPCWSTR _aPathName) michael@0: { michael@0: UString pathName = _aPathName; michael@0: int pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR); michael@0: if (pos > 0 && pos == pathName.Length() - 1) michael@0: { michael@0: if (pathName.Length() == 3 && pathName[1] == L':') michael@0: return true; // Disk folder; michael@0: pathName.Delete(pos); michael@0: } michael@0: UString pathName2 = pathName; michael@0: pos = pathName.Length(); michael@0: while(true) michael@0: { michael@0: if(MyCreateDirectory(pathName)) michael@0: break; michael@0: if(::GetLastError() == ERROR_ALREADY_EXISTS) michael@0: { michael@0: NFind::CFileInfoW fileInfo; michael@0: if (!NFind::FindFile(pathName, fileInfo)) // For network folders michael@0: return true; michael@0: if (!fileInfo.IsDirectory()) michael@0: return false; michael@0: break; michael@0: } michael@0: pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR); michael@0: if (pos < 0 || pos == 0) michael@0: return false; michael@0: if (pathName[pos - 1] == L':') michael@0: return false; michael@0: pathName = pathName.Left(pos); michael@0: } michael@0: pathName = pathName2; michael@0: while(pos < pathName.Length()) michael@0: { michael@0: pos = pathName.Find(WCHAR_PATH_SEPARATOR, pos + 1); michael@0: if (pos < 0) michael@0: pos = pathName.Length(); michael@0: if(!MyCreateDirectory(pathName.Left(pos))) michael@0: return false; michael@0: } michael@0: return true; michael@0: } michael@0: michael@0: #endif michael@0: michael@0: bool DeleteFileAlways(LPCTSTR name) michael@0: { michael@0: if(!::SetFileAttributes(name, 0)) michael@0: return false; michael@0: return BOOLToBool(::DeleteFile(name)); michael@0: } michael@0: michael@0: #ifndef _UNICODE michael@0: bool DeleteFileAlways(LPCWSTR name) michael@0: { michael@0: if (g_IsNT) michael@0: { michael@0: if(!MySetFileAttributes(name, 0)) michael@0: return false; michael@0: return BOOLToBool(::DeleteFileW(name)); michael@0: } michael@0: return DeleteFileAlways(GetSysPath(name)); michael@0: } michael@0: #endif michael@0: michael@0: static bool RemoveDirectorySubItems2(const CSysString pathPrefix, const NFind::CFileInfo &fileInfo) michael@0: { michael@0: if(fileInfo.IsDirectory()) michael@0: return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name); michael@0: else michael@0: return DeleteFileAlways(pathPrefix + fileInfo.Name); michael@0: } michael@0: michael@0: bool RemoveDirectoryWithSubItems(const CSysString &path) michael@0: { michael@0: NFind::CFileInfo fileInfo; michael@0: CSysString pathPrefix = path + NName::kDirDelimiter; michael@0: { michael@0: NFind::CEnumerator enumerator(pathPrefix + TCHAR(NName::kAnyStringWildcard)); michael@0: while(enumerator.Next(fileInfo)) michael@0: if(!RemoveDirectorySubItems2(pathPrefix, fileInfo)) michael@0: return false; michael@0: } michael@0: if(!BOOLToBool(::SetFileAttributes(path, 0))) michael@0: return false; michael@0: return BOOLToBool(::RemoveDirectory(path)); michael@0: } michael@0: michael@0: #ifndef _UNICODE michael@0: static bool RemoveDirectorySubItems2(const UString pathPrefix, const NFind::CFileInfoW &fileInfo) michael@0: { michael@0: if(fileInfo.IsDirectory()) michael@0: return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name); michael@0: else michael@0: return DeleteFileAlways(pathPrefix + fileInfo.Name); michael@0: } michael@0: bool RemoveDirectoryWithSubItems(const UString &path) michael@0: { michael@0: NFind::CFileInfoW fileInfo; michael@0: UString pathPrefix = path + UString(NName::kDirDelimiter); michael@0: { michael@0: NFind::CEnumeratorW enumerator(pathPrefix + UString(NName::kAnyStringWildcard)); michael@0: while(enumerator.Next(fileInfo)) michael@0: if(!RemoveDirectorySubItems2(pathPrefix, fileInfo)) michael@0: return false; michael@0: } michael@0: if(!MySetFileAttributes(path, 0)) michael@0: return false; michael@0: return MyRemoveDirectory(path); michael@0: } michael@0: #endif michael@0: michael@0: #ifndef _WIN32_WCE michael@0: michael@0: bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath) michael@0: { michael@0: DWORD needLength = ::GetShortPathName(longPath, shortPath.GetBuffer(MAX_PATH + 1), MAX_PATH + 1); michael@0: shortPath.ReleaseBuffer(); michael@0: return (needLength > 0 && needLength < MAX_PATH); michael@0: } michael@0: michael@0: bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex) michael@0: { michael@0: resultPath.Empty(); michael@0: LPTSTR fileNamePointer = 0; michael@0: LPTSTR buffer = resultPath.GetBuffer(MAX_PATH); michael@0: DWORD needLength = ::GetFullPathName(fileName, MAX_PATH + 1, buffer, &fileNamePointer); michael@0: resultPath.ReleaseBuffer(); michael@0: if (needLength == 0 || needLength >= MAX_PATH) michael@0: return false; michael@0: if (fileNamePointer == 0) michael@0: fileNamePartStartIndex = lstrlen(fileName); michael@0: else michael@0: fileNamePartStartIndex = (int)(fileNamePointer - buffer); michael@0: return true; michael@0: } michael@0: michael@0: #ifndef _UNICODE michael@0: bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex) michael@0: { michael@0: resultPath.Empty(); michael@0: if (g_IsNT) michael@0: { michael@0: LPWSTR fileNamePointer = 0; michael@0: LPWSTR buffer = resultPath.GetBuffer(MAX_PATH); michael@0: DWORD needLength = ::GetFullPathNameW(fileName, MAX_PATH + 1, buffer, &fileNamePointer); michael@0: resultPath.ReleaseBuffer(); michael@0: if (needLength == 0 || needLength >= MAX_PATH) michael@0: return false; michael@0: if (fileNamePointer == 0) michael@0: fileNamePartStartIndex = MyStringLen(fileName); michael@0: else michael@0: fileNamePartStartIndex = (int)(fileNamePointer - buffer); michael@0: } michael@0: else michael@0: { michael@0: CSysString sysPath; michael@0: if (!MyGetFullPathName(GetSysPath(fileName), sysPath, fileNamePartStartIndex)) michael@0: return false; michael@0: UString resultPath1 = GetUnicodePath(sysPath.Left(fileNamePartStartIndex)); michael@0: UString resultPath2 = GetUnicodePath(sysPath.Mid(fileNamePartStartIndex)); michael@0: fileNamePartStartIndex = resultPath1.Length(); michael@0: resultPath = resultPath1 + resultPath2; michael@0: } michael@0: return true; michael@0: } michael@0: #endif michael@0: michael@0: michael@0: bool MyGetFullPathName(LPCTSTR fileName, CSysString &path) michael@0: { michael@0: int index; michael@0: return MyGetFullPathName(fileName, path, index); michael@0: } michael@0: michael@0: #ifndef _UNICODE michael@0: bool MyGetFullPathName(LPCWSTR fileName, UString &path) michael@0: { michael@0: int index; michael@0: return MyGetFullPathName(fileName, path, index); michael@0: } michael@0: #endif michael@0: michael@0: bool GetOnlyName(LPCTSTR fileName, CSysString &resultName) michael@0: { michael@0: int index; michael@0: if (!MyGetFullPathName(fileName, resultName, index)) michael@0: return false; michael@0: resultName = resultName.Mid(index); michael@0: return true; michael@0: } michael@0: michael@0: #ifndef _UNICODE michael@0: bool GetOnlyName(LPCWSTR fileName, UString &resultName) michael@0: { michael@0: int index; michael@0: if (!MyGetFullPathName(fileName, resultName, index)) michael@0: return false; michael@0: resultName = resultName.Mid(index); michael@0: return true; michael@0: } michael@0: #endif michael@0: michael@0: bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName) michael@0: { michael@0: int index; michael@0: if (!MyGetFullPathName(fileName, resultName, index)) michael@0: return false; michael@0: resultName = resultName.Left(index); michael@0: return true; michael@0: } michael@0: michael@0: #ifndef _UNICODE michael@0: bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName) michael@0: { michael@0: int index; michael@0: if (!MyGetFullPathName(fileName, resultName, index)) michael@0: return false; michael@0: resultName = resultName.Left(index); michael@0: return true; michael@0: } michael@0: #endif michael@0: michael@0: bool MyGetCurrentDirectory(CSysString &path) michael@0: { michael@0: DWORD needLength = ::GetCurrentDirectory(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1)); michael@0: path.ReleaseBuffer(); michael@0: return (needLength > 0 && needLength <= MAX_PATH); michael@0: } michael@0: michael@0: #ifndef _UNICODE michael@0: bool MySetCurrentDirectory(LPCWSTR path) michael@0: { michael@0: if (g_IsNT) michael@0: return BOOLToBool(::SetCurrentDirectoryW(path)); michael@0: return MySetCurrentDirectory(GetSysPath(path)); michael@0: } michael@0: bool MyGetCurrentDirectory(UString &path) michael@0: { michael@0: if (g_IsNT) michael@0: { michael@0: DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1)); michael@0: path.ReleaseBuffer(); michael@0: return (needLength > 0 && needLength <= MAX_PATH); michael@0: } michael@0: CSysString sysPath; michael@0: if (!MyGetCurrentDirectory(sysPath)) michael@0: return false; michael@0: path = GetUnicodePath(sysPath); michael@0: return true; michael@0: } michael@0: #endif michael@0: #endif michael@0: michael@0: bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension, michael@0: CSysString &resultPath, UINT32 &filePart) michael@0: { michael@0: LPTSTR filePartPointer; michael@0: DWORD value = ::SearchPath(path, fileName, extension, michael@0: MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer); michael@0: filePart = (UINT32)(filePartPointer - (LPCTSTR)resultPath); michael@0: resultPath.ReleaseBuffer(); michael@0: return (value > 0 && value <= MAX_PATH); michael@0: } michael@0: michael@0: #ifndef _UNICODE michael@0: bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, michael@0: UString &resultPath, UINT32 &filePart) michael@0: { michael@0: if (g_IsNT) michael@0: { michael@0: LPWSTR filePartPointer = 0; michael@0: DWORD value = ::SearchPathW(path, fileName, extension, michael@0: MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer); michael@0: filePart = (UINT32)(filePartPointer - (LPCWSTR)resultPath); michael@0: resultPath.ReleaseBuffer(); michael@0: return (value > 0 && value <= MAX_PATH); michael@0: } michael@0: michael@0: CSysString sysPath; michael@0: if (!MySearchPath( michael@0: path != 0 ? (LPCTSTR)GetSysPath(path): 0, michael@0: fileName != 0 ? (LPCTSTR)GetSysPath(fileName): 0, michael@0: extension != 0 ? (LPCTSTR)GetSysPath(extension): 0, michael@0: sysPath, filePart)) michael@0: return false; michael@0: UString resultPath1 = GetUnicodePath(sysPath.Left(filePart)); michael@0: UString resultPath2 = GetUnicodePath(sysPath.Mid(filePart)); michael@0: filePart = resultPath1.Length(); michael@0: resultPath = resultPath1 + resultPath2; michael@0: return true; michael@0: } michael@0: #endif michael@0: michael@0: bool MyGetTempPath(CSysString &path) michael@0: { michael@0: DWORD needLength = ::GetTempPath(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1)); michael@0: path.ReleaseBuffer(); michael@0: return (needLength > 0 && needLength <= MAX_PATH); michael@0: } michael@0: michael@0: #ifndef _UNICODE michael@0: bool MyGetTempPath(UString &path) michael@0: { michael@0: path.Empty(); michael@0: if (g_IsNT) michael@0: { michael@0: DWORD needLength = ::GetTempPathW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1)); michael@0: path.ReleaseBuffer(); michael@0: return (needLength > 0 && needLength <= MAX_PATH); michael@0: } michael@0: CSysString sysPath; michael@0: if (!MyGetTempPath(sysPath)) michael@0: return false; michael@0: path = GetUnicodePath(sysPath); michael@0: return true; michael@0: } michael@0: #endif michael@0: michael@0: UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &path) michael@0: { michael@0: UINT number = ::GetTempFileName(dirPath, prefix, 0, path.GetBuffer(MAX_PATH + 1)); michael@0: path.ReleaseBuffer(); michael@0: return number; michael@0: } michael@0: michael@0: #ifndef _UNICODE michael@0: UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &path) michael@0: { michael@0: if (g_IsNT) michael@0: { michael@0: UINT number = ::GetTempFileNameW(dirPath, prefix, 0, path.GetBuffer(MAX_PATH)); michael@0: path.ReleaseBuffer(); michael@0: return number; michael@0: } michael@0: CSysString sysPath; michael@0: UINT number = MyGetTempFileName( michael@0: dirPath ? (LPCTSTR)GetSysPath(dirPath): 0, michael@0: prefix ? (LPCTSTR)GetSysPath(prefix): 0, michael@0: sysPath); michael@0: path = GetUnicodePath(sysPath); michael@0: return number; michael@0: } michael@0: #endif michael@0: michael@0: UINT CTempFile::Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath) michael@0: { michael@0: Remove(); michael@0: UINT number = MyGetTempFileName(dirPath, prefix, resultPath); michael@0: if(number != 0) michael@0: { michael@0: _fileName = resultPath; michael@0: _mustBeDeleted = true; michael@0: } michael@0: return number; michael@0: } michael@0: michael@0: bool CTempFile::Create(LPCTSTR prefix, CSysString &resultPath) michael@0: { michael@0: CSysString tempPath; michael@0: if(!MyGetTempPath(tempPath)) michael@0: return false; michael@0: if (Create(tempPath, prefix, resultPath) != 0) michael@0: return true; michael@0: if(!MyGetWindowsDirectory(tempPath)) michael@0: return false; michael@0: return (Create(tempPath, prefix, resultPath) != 0); michael@0: } michael@0: michael@0: bool CTempFile::Remove() michael@0: { michael@0: if (!_mustBeDeleted) michael@0: return true; michael@0: _mustBeDeleted = !DeleteFileAlways(_fileName); michael@0: return !_mustBeDeleted; michael@0: } michael@0: michael@0: #ifndef _UNICODE michael@0: michael@0: UINT CTempFileW::Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath) michael@0: { michael@0: Remove(); michael@0: UINT number = MyGetTempFileName(dirPath, prefix, resultPath); michael@0: if(number != 0) michael@0: { michael@0: _fileName = resultPath; michael@0: _mustBeDeleted = true; michael@0: } michael@0: return number; michael@0: } michael@0: michael@0: bool CTempFileW::Create(LPCWSTR prefix, UString &resultPath) michael@0: { michael@0: UString tempPath; michael@0: if(!MyGetTempPath(tempPath)) michael@0: return false; michael@0: if (Create(tempPath, prefix, resultPath) != 0) michael@0: return true; michael@0: if(!MyGetWindowsDirectory(tempPath)) michael@0: return false; michael@0: return (Create(tempPath, prefix, resultPath) != 0); michael@0: } michael@0: michael@0: bool CTempFileW::Remove() michael@0: { michael@0: if (!_mustBeDeleted) michael@0: return true; michael@0: _mustBeDeleted = !DeleteFileAlways(_fileName); michael@0: return !_mustBeDeleted; michael@0: } michael@0: michael@0: #endif michael@0: michael@0: bool CreateTempDirectory(LPCTSTR prefix, CSysString &dirName) michael@0: { michael@0: /* michael@0: CSysString prefix = tempPath + prefixChars; michael@0: CRandom random; michael@0: random.Init(); michael@0: */ michael@0: while(true) michael@0: { michael@0: CTempFile tempFile; michael@0: if (!tempFile.Create(prefix, dirName)) michael@0: return false; michael@0: if (!::DeleteFile(dirName)) michael@0: return false; michael@0: /* michael@0: UINT32 randomNumber = random.Generate(); michael@0: TCHAR randomNumberString[32]; michael@0: _stprintf(randomNumberString, _T("%04X"), randomNumber); michael@0: dirName = prefix + randomNumberString; michael@0: */ michael@0: if(NFind::DoesFileExist(dirName)) michael@0: continue; michael@0: if (MyCreateDirectory(dirName)) michael@0: return true; michael@0: if (::GetLastError() != ERROR_ALREADY_EXISTS) michael@0: return false; michael@0: } michael@0: } michael@0: michael@0: bool CTempDirectory::Create(LPCTSTR prefix) michael@0: { michael@0: Remove(); michael@0: return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir)); michael@0: } michael@0: michael@0: #ifndef _UNICODE michael@0: michael@0: bool CreateTempDirectory(LPCWSTR prefix, UString &dirName) michael@0: { michael@0: /* michael@0: CSysString prefix = tempPath + prefixChars; michael@0: CRandom random; michael@0: random.Init(); michael@0: */ michael@0: while(true) michael@0: { michael@0: CTempFileW tempFile; michael@0: if (!tempFile.Create(prefix, dirName)) michael@0: return false; michael@0: if (!DeleteFileAlways(dirName)) michael@0: return false; michael@0: /* michael@0: UINT32 randomNumber = random.Generate(); michael@0: TCHAR randomNumberString[32]; michael@0: _stprintf(randomNumberString, _T("%04X"), randomNumber); michael@0: dirName = prefix + randomNumberString; michael@0: */ michael@0: if(NFind::DoesFileExist(dirName)) michael@0: continue; michael@0: if (MyCreateDirectory(dirName)) michael@0: return true; michael@0: if (::GetLastError() != ERROR_ALREADY_EXISTS) michael@0: return false; michael@0: } michael@0: } michael@0: michael@0: bool CTempDirectoryW::Create(LPCWSTR prefix) michael@0: { michael@0: Remove(); michael@0: return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir)); michael@0: } michael@0: michael@0: #endif michael@0: michael@0: }}}