| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 |
- // Windows/FileFind.cpp
- #include "StdAfx.h"
- #include "FileFind.h"
- #ifndef _UNICODE
- #include "../Common/StringConvert.h"
- #endif
- #ifndef _UNICODE
- extern bool g_IsNT;
- #endif
- namespace NWindows {
- namespace NFile {
- #if defined(WIN_LONG_PATH) && defined(_UNICODE)
- #define WIN_LONG_PATH2
- #endif
- bool GetLongPath(LPCWSTR fileName, UString &res);
- namespace NFind {
- static const TCHAR kDot = TEXT('.');
- bool CFileInfo::IsDots() const
- {
- if (!IsDirectory() || Name.IsEmpty())
- return false;
- if (Name[0] != kDot)
- return false;
- return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
- }
- #ifndef _UNICODE
- bool CFileInfoW::IsDots() const
- {
- if (!IsDirectory() || Name.IsEmpty())
- return false;
- if (Name[0] != kDot)
- return false;
- return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
- }
- #endif
- static void ConvertWIN32_FIND_DATA_To_FileInfo(
- const WIN32_FIND_DATA &findData,
- CFileInfo &fileInfo)
- {
- fileInfo.Attributes = findData.dwFileAttributes;
- fileInfo.CreationTime = findData.ftCreationTime;
- fileInfo.LastAccessTime = findData.ftLastAccessTime;
- fileInfo.LastWriteTime = findData.ftLastWriteTime;
- fileInfo.Size = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
- fileInfo.Name = findData.cFileName;
- #ifndef _WIN32_WCE
- fileInfo.ReparseTag = findData.dwReserved0;
- #else
- fileInfo.ObjectID = findData.dwOID;
- #endif
- }
- #ifndef _UNICODE
- static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
- static void ConvertWIN32_FIND_DATA_To_FileInfo(
- const WIN32_FIND_DATAW &findData,
- CFileInfoW &fileInfo)
- {
- fileInfo.Attributes = findData.dwFileAttributes;
- fileInfo.CreationTime = findData.ftCreationTime;
- fileInfo.LastAccessTime = findData.ftLastAccessTime;
- fileInfo.LastWriteTime = findData.ftLastWriteTime;
- fileInfo.Size = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
- fileInfo.Name = findData.cFileName;
- #ifndef _WIN32_WCE
- fileInfo.ReparseTag = findData.dwReserved0;
- #else
- fileInfo.ObjectID = findData.dwOID;
- #endif
- }
- static void ConvertWIN32_FIND_DATA_To_FileInfo(
- const WIN32_FIND_DATA &findData,
- CFileInfoW &fileInfo)
- {
- fileInfo.Attributes = findData.dwFileAttributes;
- fileInfo.CreationTime = findData.ftCreationTime;
- fileInfo.LastAccessTime = findData.ftLastAccessTime;
- fileInfo.LastWriteTime = findData.ftLastWriteTime;
- fileInfo.Size = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
- fileInfo.Name = GetUnicodeString(findData.cFileName, GetCurrentCodePage());
- #ifndef _WIN32_WCE
- fileInfo.ReparseTag = findData.dwReserved0;
- #else
- fileInfo.ObjectID = findData.dwOID;
- #endif
- }
- #endif
-
- ////////////////////////////////
- // CFindFile
- bool CFindFile::Close()
- {
- if (_handle == INVALID_HANDLE_VALUE)
- return true;
- if (!::FindClose(_handle))
- return false;
- _handle = INVALID_HANDLE_VALUE;
- return true;
- }
-
- bool CFindFile::FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo)
- {
- if (!Close())
- return false;
- WIN32_FIND_DATA findData;
- _handle = ::FindFirstFile(wildcard, &findData);
- #ifdef WIN_LONG_PATH2
- if (_handle == INVALID_HANDLE_VALUE)
- {
- UString longPath;
- if (GetLongPath(wildcard, longPath))
- _handle = ::FindFirstFileW(longPath, &findData);
- }
- #endif
- if (_handle == INVALID_HANDLE_VALUE)
- return false;
- ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
- return true;
- }
- #ifndef _UNICODE
- bool CFindFile::FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo)
- {
- if (!Close())
- return false;
- if (g_IsNT)
- {
- WIN32_FIND_DATAW findData;
- _handle = ::FindFirstFileW(wildcard, &findData);
- #ifdef WIN_LONG_PATH
- if (_handle == INVALID_HANDLE_VALUE)
- {
- UString longPath;
- if (GetLongPath(wildcard, longPath))
- _handle = ::FindFirstFileW(longPath, &findData);
- }
- #endif
- if (_handle != INVALID_HANDLE_VALUE)
- ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
- }
- else
- {
- WIN32_FIND_DATAA findData;
- _handle = ::FindFirstFileA(UnicodeStringToMultiByte(wildcard,
- GetCurrentCodePage()), &findData);
- if (_handle != INVALID_HANDLE_VALUE)
- ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
- }
- return (_handle != INVALID_HANDLE_VALUE);
- }
- #endif
- bool CFindFile::FindNext(CFileInfo &fileInfo)
- {
- WIN32_FIND_DATA findData;
- bool result = BOOLToBool(::FindNextFile(_handle, &findData));
- if (result)
- ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
- return result;
- }
- #ifndef _UNICODE
- bool CFindFile::FindNext(CFileInfoW &fileInfo)
- {
- if (g_IsNT)
- {
- WIN32_FIND_DATAW findData;
- if (!::FindNextFileW(_handle, &findData))
- return false;
- ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
- }
- else
- {
- WIN32_FIND_DATAA findData;
- if (!::FindNextFileA(_handle, &findData))
- return false;
- ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
- }
- return true;
- }
- #endif
- bool FindFile(LPCTSTR wildcard, CFileInfo &fileInfo)
- {
- CFindFile finder;
- return finder.FindFirst(wildcard, fileInfo);
- }
- #ifndef _UNICODE
- bool FindFile(LPCWSTR wildcard, CFileInfoW &fileInfo)
- {
- CFindFile finder;
- return finder.FindFirst(wildcard, fileInfo);
- }
- #endif
- bool DoesFileExist(LPCTSTR name)
- {
- CFileInfo fileInfo;
- return FindFile(name, fileInfo);
- }
- #ifndef _UNICODE
- bool DoesFileExist(LPCWSTR name)
- {
- CFileInfoW fileInfo;
- return FindFile(name, fileInfo);
- }
- #endif
- /////////////////////////////////////
- // CEnumerator
- bool CEnumerator::NextAny(CFileInfo &fileInfo)
- {
- if (_findFile.IsHandleAllocated())
- return _findFile.FindNext(fileInfo);
- else
- return _findFile.FindFirst(_wildcard, fileInfo);
- }
- bool CEnumerator::Next(CFileInfo &fileInfo)
- {
- for (;;)
- {
- if (!NextAny(fileInfo))
- return false;
- if (!fileInfo.IsDots())
- return true;
- }
- }
- bool CEnumerator::Next(CFileInfo &fileInfo, bool &found)
- {
- if (Next(fileInfo))
- {
- found = true;
- return true;
- }
- found = false;
- return (::GetLastError() == ERROR_NO_MORE_FILES);
- }
- #ifndef _UNICODE
- bool CEnumeratorW::NextAny(CFileInfoW &fileInfo)
- {
- if (_findFile.IsHandleAllocated())
- return _findFile.FindNext(fileInfo);
- else
- return _findFile.FindFirst(_wildcard, fileInfo);
- }
- bool CEnumeratorW::Next(CFileInfoW &fileInfo)
- {
- for (;;)
- {
- if (!NextAny(fileInfo))
- return false;
- if (!fileInfo.IsDots())
- return true;
- }
- }
- bool CEnumeratorW::Next(CFileInfoW &fileInfo, bool &found)
- {
- if (Next(fileInfo))
- {
- 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()
- {
- if (!IsHandleAllocated())
- return true;
- if (!::FindCloseChangeNotification(_handle))
- return false;
- _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)
- {
- if (!g_IsNT)
- return FindFirst(UnicodeStringToMultiByte(pathName, GetCurrentCodePage()), watchSubtree, notifyFilter);
- _handle = ::FindFirstChangeNotificationW(pathName, BoolToBOOL(watchSubtree), notifyFilter);
- #ifdef WIN_LONG_PATH
- if (!IsHandleAllocated())
- {
- UString longPath;
- if (GetLongPath(pathName, longPath))
- _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
- }
- #endif
- return _handle;
- }
- #endif
- #ifndef _WIN32_WCE
- bool MyGetLogicalDriveStrings(CSysStringVector &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++)
- {
- TCHAR c = buffer[i];
- if (c == TEXT('\0'))
- {
- driveStrings.Add(string);
- string.Empty();
- }
- else
- string += c;
- }
- if (!string.IsEmpty())
- return false;
- return true;
- }
- #ifndef _UNICODE
- bool MyGetLogicalDriveStrings(UStringVector &driveStrings)
- {
- driveStrings.Clear();
- if (g_IsNT)
- {
- 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)
- return false;
- UString string;
- for(UINT32 i = 0; i < newSize; i++)
- {
- WCHAR c = buffer[i];
- if (c == L'\0')
- {
- driveStrings.Add(string);
- string.Empty();
- }
- else
- string += c;
- }
- return string.IsEmpty();
- }
- CSysStringVector driveStringsA;
- bool res = MyGetLogicalDriveStrings(driveStringsA);
- for (int i = 0; i < driveStringsA.Size(); i++)
- driveStrings.Add(GetUnicodeString(driveStringsA[i]));
- return res;
- }
- #endif
- #endif
- }}}
|