summaryrefslogtreecommitdiffstats
path: root/other-licenses/7zstub/src/Windows/FileFind.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'other-licenses/7zstub/src/Windows/FileFind.cpp')
-rw-r--r--other-licenses/7zstub/src/Windows/FileFind.cpp365
1 files changed, 365 insertions, 0 deletions
diff --git a/other-licenses/7zstub/src/Windows/FileFind.cpp b/other-licenses/7zstub/src/Windows/FileFind.cpp
new file mode 100644
index 000000000..298df4644
--- /dev/null
+++ b/other-licenses/7zstub/src/Windows/FileFind.cpp
@@ -0,0 +1,365 @@
+// 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 {
+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(!_handleAllocated)
+ return true;
+ bool result = BOOLToBool(::FindClose(_handle));
+ _handleAllocated = !result;
+ return result;
+}
+
+bool CFindFile::FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo)
+{
+ Close();
+ WIN32_FIND_DATA findData;
+ _handle = ::FindFirstFile(wildcard, &findData);
+ if (_handleAllocated = (_handle != INVALID_HANDLE_VALUE))
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ return _handleAllocated;
+}
+
+#ifndef _UNICODE
+bool CFindFile::FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo)
+{
+ Close();
+ if (g_IsNT)
+ {
+ WIN32_FIND_DATAW findData;
+ _handle = ::FindFirstFileW(wildcard, &findData);
+ if (_handleAllocated = (_handle != INVALID_HANDLE_VALUE))
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ }
+ else
+ {
+ WIN32_FIND_DATAA findData;
+ _handle = ::FindFirstFileA(UnicodeStringToMultiByte(wildcard,
+ GetCurrentCodePage()), &findData);
+ if (_handleAllocated = (_handle != INVALID_HANDLE_VALUE))
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ }
+ return _handleAllocated;
+}
+#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)
+{
+ while(true)
+ {
+ 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)
+{
+ while(true)
+ {
+ 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
+
+bool CFindChangeNotification::Close()
+{
+ if(_handle == INVALID_HANDLE_VALUE || _handle == 0)
+ return true;
+ bool result = BOOLToBool(::FindCloseChangeNotification(_handle));
+ if (result)
+ _handle = INVALID_HANDLE_VALUE;
+ return result;
+}
+
+HANDLE CFindChangeNotification::FindFirst(LPCTSTR pathName, bool watchSubtree,
+ DWORD notifyFilter)
+{
+ _handle = ::FindFirstChangeNotification(pathName,
+ BoolToBOOL(watchSubtree), notifyFilter);
+ return _handle;
+}
+
+#ifndef _UNICODE
+HANDLE CFindChangeNotification::FindFirst(LPCWSTR pathName, bool watchSubtree,
+ DWORD notifyFilter)
+{
+ if (g_IsNT)
+ return (_handle = ::FindFirstChangeNotificationW(pathName, BoolToBOOL(watchSubtree), notifyFilter));
+ return FindFirst(UnicodeStringToMultiByte(pathName, GetCurrentCodePage()), watchSubtree, notifyFilter);
+}
+#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
+
+}}}