summaryrefslogtreecommitdiffstats
path: root/src/libs/7zip/win/CPP/Windows/FileFind.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/7zip/win/CPP/Windows/FileFind.cpp')
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileFind.cpp605
1 files changed, 361 insertions, 244 deletions
diff --git a/src/libs/7zip/win/CPP/Windows/FileFind.cpp b/src/libs/7zip/win/CPP/Windows/FileFind.cpp
index e3358f905..7f58288fe 100644
--- a/src/libs/7zip/win/CPP/Windows/FileFind.cpp
+++ b/src/libs/7zip/win/CPP/Windows/FileFind.cpp
@@ -4,6 +4,7 @@
#include "FileFind.h"
#include "FileIO.h"
+#include "FileName.h"
#ifndef _UNICODE
#include "../Common/StringConvert.h"
#endif
@@ -12,45 +13,55 @@
extern bool g_IsNT;
#endif
-namespace NWindows {
-namespace NFile {
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
-#ifdef SUPPORT_DEVICE_FILE
-bool IsDeviceName(LPCTSTR n);
-#ifndef _UNICODE
-bool IsDeviceName(LPCWSTR n);
-#endif
-#endif
+#if defined(_WIN32) && !defined(UNDER_CE)
-#if defined(WIN_LONG_PATH) && defined(_UNICODE)
-#define WIN_LONG_PATH2
-#endif
+EXTERN_C_BEGIN
+
+typedef enum
+{
+ My_FindStreamInfoStandard,
+ My_FindStreamInfoMaxInfoLevel
+} MY_STREAM_INFO_LEVELS;
+
+typedef struct
+{
+ LARGE_INTEGER StreamSize;
+ WCHAR cStreamName[MAX_PATH + 36];
+} MY_WIN32_FIND_STREAM_DATA, *MY_PWIN32_FIND_STREAM_DATA;
-bool GetLongPath(LPCWSTR fileName, UString &res);
+typedef WINBASEAPI HANDLE (WINAPI *FindFirstStreamW_Ptr)(LPCWSTR fileName, MY_STREAM_INFO_LEVELS infoLevel,
+ LPVOID findStreamData, DWORD flags);
-namespace NFind {
+typedef WINBASEAPI BOOL (APIENTRY *FindNextStreamW_Ptr)(HANDLE findStream, LPVOID findStreamData);
-static const TCHAR kDot = TEXT('.');
+EXTERN_C_END
-bool CFileInfo::IsDots() const
+#endif
+
+namespace NWindows {
+namespace NFile {
+
+#ifdef SUPPORT_DEVICE_FILE
+namespace NSystem
{
- if (!IsDir() || Name.IsEmpty())
- return false;
- if (Name[0] != kDot)
- return false;
- return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
+bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize);
}
+#endif
-#ifndef _UNICODE
-bool CFileInfoW::IsDots() const
+namespace NFind {
+
+bool CFileInfo::IsDots() const throw()
{
if (!IsDir() || Name.IsEmpty())
return false;
- if (Name[0] != kDot)
+ if (Name[0] != FTEXT('.'))
return false;
- return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
+ return Name.Len() == 1 || (Name.Len() == 2 && Name[1] == FTEXT('.'));
}
-#endif
#define WIN_FD_TO_MY_FI(fi, fd) \
fi.Attrib = fd.dwFileAttributes; \
@@ -58,6 +69,7 @@ bool CFileInfoW::IsDots() const
fi.ATime = fd.ftLastAccessTime; \
fi.MTime = fd.ftLastWriteTime; \
fi.Size = (((UInt64)fd.nFileSizeHigh) << 32) + fd.nFileSizeLow; \
+ fi.IsAltStream = false; \
fi.IsDevice = false;
/*
@@ -68,33 +80,31 @@ bool CFileInfoW::IsDots() const
#endif
*/
-static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATA &fd, CFileInfo &fi)
+static void Convert_WIN32_FIND_DATA_to_FileInfo(const WIN32_FIND_DATAW &fd, CFileInfo &fi)
{
WIN_FD_TO_MY_FI(fi, fd);
- fi.Name = fd.cFileName;
+ fi.Name = us2fs(fd.cFileName);
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ // fi.ShortName = us2fs(fd.cAlternateFileName);
+ #endif
}
#ifndef _UNICODE
-static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
-
-static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATAW &fd, CFileInfoW &fi)
-{
- WIN_FD_TO_MY_FI(fi, fd);
- fi.Name = fd.cFileName;
-}
-
-static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATA &fd, CFileInfoW &fi)
+static void Convert_WIN32_FIND_DATA_to_FileInfo(const WIN32_FIND_DATA &fd, CFileInfo &fi)
{
WIN_FD_TO_MY_FI(fi, fd);
- fi.Name = GetUnicodeString(fd.cFileName, GetCurrentCodePage());
+ fi.Name = fas2fs(fd.cFileName);
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ // fi.ShortName = fas2fs(fd.cAlternateFileName);
+ #endif
}
#endif
-
+
////////////////////////////////
// CFindFile
-bool CFindFile::Close()
+bool CFindFileBase::Close() throw()
{
if (_handle == INVALID_HANDLE_VALUE)
return true;
@@ -104,183 +114,344 @@ bool CFindFile::Close()
return true;
}
-
-bool CFindFile::FindFirst(LPCTSTR wildcard, CFileInfo &fi)
+bool CFindFile::FindFirst(CFSTR path, CFileInfo &fi)
{
if (!Close())
return false;
- WIN32_FIND_DATA fd;
- _handle = ::FindFirstFile(wildcard, &fd);
- #ifdef WIN_LONG_PATH2
- if (_handle == INVALID_HANDLE_VALUE)
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- UString longPath;
- if (GetLongPath(wildcard, longPath))
- _handle = ::FindFirstFileW(longPath, &fd);
+ WIN32_FIND_DATAA fd;
+ _handle = ::FindFirstFileA(fs2fas(path), &fd);
+ if (_handle == INVALID_HANDLE_VALUE)
+ return false;
+ Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi);
}
+ else
#endif
- if (_handle == INVALID_HANDLE_VALUE)
- return false;
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
- return true;
-}
-
-#ifndef _UNICODE
-bool CFindFile::FindFirst(LPCWSTR wildcard, CFileInfoW &fi)
-{
- if (!Close())
- return false;
- if (g_IsNT)
{
WIN32_FIND_DATAW fd;
- _handle = ::FindFirstFileW(wildcard, &fd);
+
+ IF_USE_MAIN_PATH
+ _handle = ::FindFirstFileW(fs2us(path), &fd);
#ifdef WIN_LONG_PATH
- if (_handle == INVALID_HANDLE_VALUE)
+ if (_handle == INVALID_HANDLE_VALUE && USE_SUPER_PATH)
{
UString longPath;
- if (GetLongPath(wildcard, longPath))
+ if (GetSuperPath(path, longPath, USE_MAIN_PATH))
_handle = ::FindFirstFileW(longPath, &fd);
}
#endif
- if (_handle != INVALID_HANDLE_VALUE)
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
+ if (_handle == INVALID_HANDLE_VALUE)
+ return false;
+ Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi);
}
- else
+ return true;
+}
+
+bool CFindFile::FindNext(CFileInfo &fi)
+{
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
WIN32_FIND_DATAA fd;
- _handle = ::FindFirstFileA(UnicodeStringToMultiByte(wildcard,
- GetCurrentCodePage()), &fd);
- if (_handle != INVALID_HANDLE_VALUE)
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
+ if (!::FindNextFileA(_handle, &fd))
+ return false;
+ Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi);
}
- return (_handle != INVALID_HANDLE_VALUE);
+ else
+ #endif
+ {
+ WIN32_FIND_DATAW fd;
+ if (!::FindNextFileW(_handle, &fd))
+ return false;
+ Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi);
+ }
+ return true;
}
-#endif
-bool CFindFile::FindNext(CFileInfo &fi)
+#if defined(_WIN32) && !defined(UNDER_CE)
+
+////////////////////////////////
+// AltStreams
+
+static FindFirstStreamW_Ptr g_FindFirstStreamW;
+static FindNextStreamW_Ptr g_FindNextStreamW;
+
+struct CFindStreamLoader
{
- WIN32_FIND_DATA fd;
- bool result = BOOLToBool(::FindNextFile(_handle, &fd));
- if (result)
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
- return result;
+ CFindStreamLoader()
+ {
+ g_FindFirstStreamW = (FindFirstStreamW_Ptr)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "FindFirstStreamW");
+ g_FindNextStreamW = (FindNextStreamW_Ptr)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "FindNextStreamW");
+ }
+} g_FindStreamLoader;
+
+bool CStreamInfo::IsMainStream() const throw()
+{
+ return Name == L"::$DATA";
+};
+
+UString CStreamInfo::GetReducedName() const
+{
+ UString s = Name;
+ if (s.Len() >= 6)
+ if (wcscmp(s.RightPtr(6), L":$DATA") == 0)
+ s.DeleteFrom(s.Len() - 6);
+ return s;
}
-#ifndef _UNICODE
-bool CFindFile::FindNext(CFileInfoW &fi)
+static void Convert_WIN32_FIND_STREAM_DATA_to_StreamInfo(const MY_WIN32_FIND_STREAM_DATA &sd, CStreamInfo &si)
+{
+ si.Size = sd.StreamSize.QuadPart;
+ si.Name = sd.cStreamName;
+}
+
+bool CFindStream::FindFirst(CFSTR path, CStreamInfo &si)
{
- if (g_IsNT)
+ if (!Close())
+ return false;
+ if (!g_FindFirstStreamW)
{
- WIN32_FIND_DATAW fd;
- if (!::FindNextFileW(_handle, &fd))
+ ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return false;
+ }
+ {
+ MY_WIN32_FIND_STREAM_DATA sd;
+ IF_USE_MAIN_PATH
+ _handle = g_FindFirstStreamW(fs2us(path), My_FindStreamInfoStandard, &sd, 0);
+ if (_handle == INVALID_HANDLE_VALUE)
+ {
+ if (::GetLastError() == ERROR_HANDLE_EOF)
+ return false;
+ // long name can be tricky for path like ".\dirName".
+ #ifdef WIN_LONG_PATH
+ if (USE_SUPER_PATH)
+ {
+ UString longPath;
+ if (GetSuperPath(path, longPath, USE_MAIN_PATH))
+ _handle = g_FindFirstStreamW(longPath, My_FindStreamInfoStandard, &sd, 0);
+ }
+ #endif
+ }
+ if (_handle == INVALID_HANDLE_VALUE)
return false;
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
+ Convert_WIN32_FIND_STREAM_DATA_to_StreamInfo(sd, si);
}
- else
+ return true;
+}
+
+bool CFindStream::FindNext(CStreamInfo &si)
+{
+ if (!g_FindNextStreamW)
{
- WIN32_FIND_DATAA fd;
- if (!::FindNextFileA(_handle, &fd))
+ ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return false;
+ }
+ {
+ MY_WIN32_FIND_STREAM_DATA sd;
+ if (!g_FindNextStreamW(_handle, &sd))
return false;
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
+ Convert_WIN32_FIND_STREAM_DATA_to_StreamInfo(sd, si);
}
return true;
}
+
+bool CStreamEnumerator::Next(CStreamInfo &si, bool &found)
+{
+ bool res;
+ if (_find.IsHandleAllocated())
+ res = _find.FindNext(si);
+ else
+ res = _find.FindFirst(_filePath, si);
+ if (res)
+ {
+ found = true;
+ return true;
+ }
+ found = false;
+ return (::GetLastError() == ERROR_HANDLE_EOF);
+}
+
#endif
+
#define MY_CLEAR_FILETIME(ft) ft.dwLowDateTime = ft.dwHighDateTime = 0;
-void CFileInfoBase::Clear()
+void CFileInfoBase::Clear() throw()
{
Size = 0;
MY_CLEAR_FILETIME(CTime);
MY_CLEAR_FILETIME(ATime);
MY_CLEAR_FILETIME(MTime);
Attrib = 0;
+ IsAltStream = false;
+ IsDevice = false;
}
-
-bool CFileInfo::Find(LPCTSTR wildcard)
+
+#if defined(_WIN32) && !defined(UNDER_CE)
+
+static int FindAltStreamColon(CFSTR path)
{
- #ifdef SUPPORT_DEVICE_FILE
- if (IsDeviceName(wildcard))
+ for (int i = 0;; i++)
{
- Clear();
- IsDevice = true;
- NIO::CInFile inFile;
- if (!inFile.Open(wildcard))
- return false;
- Name = wildcard + 4;
- if (inFile.LengthDefined)
- Size = inFile.Length;
- return true;
+ FChar c = path[i];
+ if (c == 0)
+ return -1;
+ if (c == ':')
+ {
+ if (path[i + 1] == '\\')
+ if (i == 1 || (i > 1 && path[i - 2] == '\\'))
+ {
+ wchar_t c0 = path[i - 1];
+ if (c0 >= 'a' && c0 <= 'z' ||
+ c0 >= 'A' && c0 <= 'Z')
+ continue;
+ }
+ return i;
+ }
}
- #endif
- CFindFile finder;
- return finder.FindFirst(wildcard, *this);
}
+#endif
-#ifndef _UNICODE
-bool CFileInfoW::Find(LPCWSTR wildcard)
+bool CFileInfo::Find(CFSTR path)
{
#ifdef SUPPORT_DEVICE_FILE
- if (IsDeviceName(wildcard))
+ if (IsDevicePath(path))
{
Clear();
+ Name = path + 4;
+
IsDevice = true;
+ if (/* path[0] == '\\' && path[1] == '\\' && path[2] == '.' && path[3] == '\\' && */
+ path[5] == ':' && path[6] == 0)
+ {
+ FChar drive[4] = { path[4], ':', '\\', 0 };
+ UInt64 clusterSize, totalSize, freeSize;
+ if (NSystem::MyGetDiskFreeSpace(drive, clusterSize, totalSize, freeSize))
+ {
+ Size = totalSize;
+ return true;
+ }
+ }
+
NIO::CInFile inFile;
- if (!inFile.Open(wildcard))
+ // ::OutputDebugStringW(path);
+ if (!inFile.Open(path))
return false;
- Name = wildcard + 4;
- if (inFile.LengthDefined)
- Size = inFile.Length;
+ // ::OutputDebugStringW(L"---");
+ if (inFile.SizeDefined)
+ Size = inFile.Size;
return true;
}
#endif
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+
+ int colonPos = FindAltStreamColon(path);
+ if (colonPos >= 0)
+ {
+ UString streamName = fs2us(path + (unsigned)colonPos);
+ FString filePath = path;
+ filePath.DeleteFrom(colonPos);
+ streamName += L":$DATA"; // change it!!!!
+ if (Find(filePath))
+ {
+ // if (IsDir())
+ Attrib &= ~FILE_ATTRIBUTE_DIRECTORY;
+ Size = 0;
+ CStreamEnumerator enumerator(filePath);
+ for (;;)
+ {
+ CStreamInfo si;
+ bool found;
+ if (!enumerator.Next(si, found))
+ return false;
+ if (!found)
+ {
+ ::SetLastError(ERROR_FILE_NOT_FOUND);
+ return false;
+ }
+ if (si.Name.IsEqualToNoCase(streamName))
+ {
+ Name += us2fs(si.Name);
+ Name.DeleteFrom(Name.Len() - 6);
+ Size = si.Size;
+ IsAltStream = true;
+ return true;
+ }
+ }
+ }
+ }
+
+ #endif
+
CFindFile finder;
- return finder.FindFirst(wildcard, *this);
+ if (finder.FindFirst(path, *this))
+ return true;
+ #ifdef _WIN32
+ {
+ DWORD lastError = GetLastError();
+ if (lastError == ERROR_BAD_NETPATH ||
+ lastError == ERROR_FILE_NOT_FOUND ||
+ lastError == ERROR_INVALID_NAME // for "\\SERVER\shared" paths that are translated to "\\?\UNC\SERVER\shared"
+ )
+ {
+ unsigned len = MyStringLen(path);
+ if (len > 2 && path[0] == '\\' && path[1] == '\\')
+ {
+ int startPos = 2;
+ if (len > kSuperUncPathPrefixSize && IsSuperUncPath(path))
+ startPos = kSuperUncPathPrefixSize;
+ int pos = FindCharPosInString(path + startPos, FTEXT('\\'));
+ if (pos >= 0)
+ {
+ pos += startPos + 1;
+ len -= pos;
+ int pos2 = FindCharPosInString(path + pos, FTEXT('\\'));
+ if (pos2 < 0 || pos2 == (int)len - 1)
+ {
+ FString s = path;
+ if (pos2 < 0)
+ {
+ pos2 = len;
+ s += FTEXT('\\');
+ }
+ s += FCHAR_ANY_MASK;
+ if (finder.FindFirst(s, *this))
+ if (Name == FTEXT("."))
+ {
+ Name.SetFrom(s.Ptr(pos), pos2);
+ return true;
+ }
+ ::SetLastError(lastError);
+ }
+ }
+ }
+ }
+ }
+ #endif
+ return false;
}
-#endif
-bool DoesFileExist(LPCTSTR name)
+bool DoesFileExist(CFSTR name)
{
CFileInfo fi;
return fi.Find(name) && !fi.IsDir();
}
-bool DoesDirExist(LPCTSTR name)
+bool DoesDirExist(CFSTR name)
{
CFileInfo fi;
return fi.Find(name) && fi.IsDir();
}
-
-bool DoesFileOrDirExist(LPCTSTR name)
+bool DoesFileOrDirExist(CFSTR name)
{
CFileInfo fi;
return fi.Find(name);
}
-#ifndef _UNICODE
-bool DoesFileExist(LPCWSTR name)
-{
- CFileInfoW fi;
- return fi.Find(name) && !fi.IsDir();
-}
-
-bool DoesDirExist(LPCWSTR name)
-{
- CFileInfoW fi;
- return fi.Find(name) && fi.IsDir();
-}
-bool DoesFileOrDirExist(LPCWSTR name)
-{
- CFileInfoW fi;
- return fi.Find(name);
-}
-#endif
-
-/////////////////////////////////////
-// CEnumerator
-
bool CEnumerator::NextAny(CFileInfo &fi)
{
if (_findFile.IsHandleAllocated())
@@ -311,44 +482,11 @@ bool CEnumerator::Next(CFileInfo &fi, bool &found)
return (::GetLastError() == ERROR_NO_MORE_FILES);
}
-#ifndef _UNICODE
-bool CEnumeratorW::NextAny(CFileInfoW &fi)
-{
- if (_findFile.IsHandleAllocated())
- return _findFile.FindNext(fi);
- else
- return _findFile.FindFirst(_wildcard, fi);
-}
-
-bool CEnumeratorW::Next(CFileInfoW &fi)
-{
- for (;;)
- {
- if (!NextAny(fi))
- return false;
- if (!fi.IsDots())
- return true;
- }
-}
-
-bool CEnumeratorW::Next(CFileInfoW &fi, bool &found)
-{
- if (Next(fi))
- {
- found = true;
- return true;
- }
- found = false;
- return (::GetLastError() == ERROR_NO_MORE_FILES);
-}
-
-#endif
-
////////////////////////////////
// CFindChangeNotification
// FindFirstChangeNotification can return 0. MSDN doesn't tell about it.
-bool CFindChangeNotification::Close()
+bool CFindChangeNotification::Close() throw()
{
if (!IsHandleAllocated())
return true;
@@ -357,105 +495,84 @@ bool CFindChangeNotification::Close()
_handle = INVALID_HANDLE_VALUE;
return true;
}
-
-HANDLE CFindChangeNotification::FindFirst(LPCTSTR pathName, bool watchSubtree, DWORD notifyFilter)
-{
- _handle = ::FindFirstChangeNotification(pathName, BoolToBOOL(watchSubtree), notifyFilter);
- #ifdef WIN_LONG_PATH2
- if (!IsHandleAllocated())
- {
- UString longPath;
- if (GetLongPath(pathName, longPath))
- _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
- }
- #endif
- return _handle;
-}
-#ifndef _UNICODE
-HANDLE CFindChangeNotification::FindFirst(LPCWSTR pathName, bool watchSubtree, DWORD notifyFilter)
+HANDLE CFindChangeNotification::FindFirst(CFSTR path, bool watchSubtree, DWORD notifyFilter)
{
+ #ifndef _UNICODE
if (!g_IsNT)
- return FindFirst(UnicodeStringToMultiByte(pathName, GetCurrentCodePage()), watchSubtree, notifyFilter);
- _handle = ::FindFirstChangeNotificationW(pathName, BoolToBOOL(watchSubtree), notifyFilter);
- #ifdef WIN_LONG_PATH
- if (!IsHandleAllocated())
+ _handle = ::FindFirstChangeNotification(fs2fas(path), BoolToBOOL(watchSubtree), notifyFilter);
+ else
+ #endif
{
- UString longPath;
- if (GetLongPath(pathName, longPath))
- _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
+ IF_USE_MAIN_PATH
+ _handle = ::FindFirstChangeNotificationW(fs2us(path), BoolToBOOL(watchSubtree), notifyFilter);
+ #ifdef WIN_LONG_PATH
+ if (!IsHandleAllocated())
+ {
+ UString longPath;
+ if (GetSuperPath(path, longPath, USE_MAIN_PATH))
+ _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
+ }
+ #endif
}
- #endif
return _handle;
}
-#endif
#ifndef UNDER_CE
-bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings)
+
+bool MyGetLogicalDriveStrings(CObjectVector<FString> &driveStrings)
{
driveStrings.Clear();
- UINT32 size = GetLogicalDriveStrings(0, NULL);
- if (size == 0)
- return false;
- CSysString buffer;
- UINT32 newSize = GetLogicalDriveStrings(size, buffer.GetBuffer(size));
- if (newSize == 0)
- return false;
- if (newSize > size)
- return false;
- CSysString string;
- for (UINT32 i = 0; i < newSize; i++)
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- TCHAR c = buffer[i];
- if (c == TEXT('\0'))
+ driveStrings.Clear();
+ UINT32 size = GetLogicalDriveStrings(0, NULL);
+ if (size == 0)
+ return false;
+ AString buf;
+ UINT32 newSize = GetLogicalDriveStrings(size, buf.GetBuffer(size));
+ if (newSize == 0 || newSize > size)
+ return false;
+ AString s;
+ for (UINT32 i = 0; i < newSize; i++)
{
- driveStrings.Add(string);
- string.Empty();
+ char c = buf[i];
+ if (c == '\0')
+ {
+ driveStrings.Add(fas2fs(s));
+ s.Empty();
+ }
+ else
+ s += c;
}
- else
- string += c;
+ return s.IsEmpty();
}
- if (!string.IsEmpty())
- return false;
- return true;
-}
-
-#ifndef _UNICODE
-bool MyGetLogicalDriveStrings(UStringVector &driveStrings)
-{
- driveStrings.Clear();
- if (g_IsNT)
+ else
+ #endif
{
UINT32 size = GetLogicalDriveStringsW(0, NULL);
if (size == 0)
return false;
- UString buffer;
- UINT32 newSize = GetLogicalDriveStringsW(size, buffer.GetBuffer(size));
- if (newSize == 0)
- return false;
- if (newSize > size)
+ UString buf;
+ UINT32 newSize = GetLogicalDriveStringsW(size, buf.GetBuffer(size));
+ if (newSize == 0 || newSize > size)
return false;
- UString string;
+ UString s;
for (UINT32 i = 0; i < newSize; i++)
{
- WCHAR c = buffer[i];
+ WCHAR c = buf[i];
if (c == L'\0')
{
- driveStrings.Add(string);
- string.Empty();
+ driveStrings.Add(us2fs(s));
+ s.Empty();
}
else
- string += c;
+ s += c;
}
- return string.IsEmpty();
+ return s.IsEmpty();
}
- CSysStringVector driveStringsA;
- bool res = MyGetLogicalDriveStrings(driveStringsA);
- for (int i = 0; i < driveStringsA.Size(); i++)
- driveStrings.Add(GetUnicodeString(driveStringsA[i]));
- return res;
}
-#endif
#endif