Mercurial > vba-clojure
diff src/win32/7zip/7z/CPP/Windows/FileFind.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/win32/7zip/7z/CPP/Windows/FileFind.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,402 @@ 1.4 +// Windows/FileFind.cpp 1.5 + 1.6 +#include "StdAfx.h" 1.7 + 1.8 +#include "FileFind.h" 1.9 +#ifndef _UNICODE 1.10 +#include "../Common/StringConvert.h" 1.11 +#endif 1.12 + 1.13 +#ifndef _UNICODE 1.14 +extern bool g_IsNT; 1.15 +#endif 1.16 + 1.17 +namespace NWindows { 1.18 +namespace NFile { 1.19 + 1.20 +#if defined(WIN_LONG_PATH) && defined(_UNICODE) 1.21 +#define WIN_LONG_PATH2 1.22 +#endif 1.23 + 1.24 +bool GetLongPath(LPCWSTR fileName, UString &res); 1.25 + 1.26 +namespace NFind { 1.27 + 1.28 +static const TCHAR kDot = TEXT('.'); 1.29 + 1.30 +bool CFileInfo::IsDots() const 1.31 +{ 1.32 + if (!IsDir() || Name.IsEmpty()) 1.33 + return false; 1.34 + if (Name[0] != kDot) 1.35 + return false; 1.36 + return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2); 1.37 +} 1.38 + 1.39 +#ifndef _UNICODE 1.40 +bool CFileInfoW::IsDots() const 1.41 +{ 1.42 + if (!IsDir() || Name.IsEmpty()) 1.43 + return false; 1.44 + if (Name[0] != kDot) 1.45 + return false; 1.46 + return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2); 1.47 +} 1.48 +#endif 1.49 + 1.50 +static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATA &fd, CFileInfo &fi) 1.51 +{ 1.52 + fi.Attrib = fd.dwFileAttributes; 1.53 + fi.CTime = fd.ftCreationTime; 1.54 + fi.ATime = fd.ftLastAccessTime; 1.55 + fi.MTime = fd.ftLastWriteTime; 1.56 + fi.Size = (((UInt64)fd.nFileSizeHigh) << 32) + fd.nFileSizeLow; 1.57 + fi.Name = fd.cFileName; 1.58 + #ifndef _WIN32_WCE 1.59 + fi.ReparseTag = fd.dwReserved0; 1.60 + #else 1.61 + fi.ObjectID = fd.dwOID; 1.62 + #endif 1.63 +} 1.64 + 1.65 +#ifndef _UNICODE 1.66 + 1.67 +static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } 1.68 + 1.69 +static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATAW &fd, CFileInfoW &fi) 1.70 +{ 1.71 + fi.Attrib = fd.dwFileAttributes; 1.72 + fi.CTime = fd.ftCreationTime; 1.73 + fi.ATime = fd.ftLastAccessTime; 1.74 + fi.MTime = fd.ftLastWriteTime; 1.75 + fi.Size = (((UInt64)fd.nFileSizeHigh) << 32) + fd.nFileSizeLow; 1.76 + fi.Name = fd.cFileName; 1.77 + #ifndef _WIN32_WCE 1.78 + fi.ReparseTag = fd.dwReserved0; 1.79 + #else 1.80 + fi.ObjectID = fd.dwOID; 1.81 + #endif 1.82 +} 1.83 + 1.84 +static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATA &fd, CFileInfoW &fi) 1.85 +{ 1.86 + fi.Attrib = fd.dwFileAttributes; 1.87 + fi.CTime = fd.ftCreationTime; 1.88 + fi.ATime = fd.ftLastAccessTime; 1.89 + fi.MTime = fd.ftLastWriteTime; 1.90 + fi.Size = (((UInt64)fd.nFileSizeHigh) << 32) + fd.nFileSizeLow; 1.91 + fi.Name = GetUnicodeString(fd.cFileName, GetCurrentCodePage()); 1.92 + #ifndef _WIN32_WCE 1.93 + fi.ReparseTag = fd.dwReserved0; 1.94 + #else 1.95 + fi.ObjectID = fd.dwOID; 1.96 + #endif 1.97 +} 1.98 +#endif 1.99 + 1.100 +//////////////////////////////// 1.101 +// CFindFile 1.102 + 1.103 +bool CFindFile::Close() 1.104 +{ 1.105 + if (_handle == INVALID_HANDLE_VALUE) 1.106 + return true; 1.107 + if (!::FindClose(_handle)) 1.108 + return false; 1.109 + _handle = INVALID_HANDLE_VALUE; 1.110 + return true; 1.111 +} 1.112 + 1.113 + 1.114 +bool CFindFile::FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo) 1.115 +{ 1.116 + if (!Close()) 1.117 + return false; 1.118 + WIN32_FIND_DATA fd; 1.119 + _handle = ::FindFirstFile(wildcard, &fd); 1.120 + #ifdef WIN_LONG_PATH2 1.121 + if (_handle == INVALID_HANDLE_VALUE) 1.122 + { 1.123 + UString longPath; 1.124 + if (GetLongPath(wildcard, longPath)) 1.125 + _handle = ::FindFirstFileW(longPath, &fd); 1.126 + } 1.127 + #endif 1.128 + if (_handle == INVALID_HANDLE_VALUE) 1.129 + return false; 1.130 + ConvertWIN32_FIND_DATA_To_FileInfo(fd, fileInfo); 1.131 + return true; 1.132 +} 1.133 + 1.134 +#ifndef _UNICODE 1.135 +bool CFindFile::FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo) 1.136 +{ 1.137 + if (!Close()) 1.138 + return false; 1.139 + if (g_IsNT) 1.140 + { 1.141 + WIN32_FIND_DATAW fd; 1.142 + _handle = ::FindFirstFileW(wildcard, &fd); 1.143 + #ifdef WIN_LONG_PATH 1.144 + if (_handle == INVALID_HANDLE_VALUE) 1.145 + { 1.146 + UString longPath; 1.147 + if (GetLongPath(wildcard, longPath)) 1.148 + _handle = ::FindFirstFileW(longPath, &fd); 1.149 + } 1.150 + #endif 1.151 + if (_handle != INVALID_HANDLE_VALUE) 1.152 + ConvertWIN32_FIND_DATA_To_FileInfo(fd, fileInfo); 1.153 + } 1.154 + else 1.155 + { 1.156 + WIN32_FIND_DATAA fd; 1.157 + _handle = ::FindFirstFileA(UnicodeStringToMultiByte(wildcard, 1.158 + GetCurrentCodePage()), &fd); 1.159 + if (_handle != INVALID_HANDLE_VALUE) 1.160 + ConvertWIN32_FIND_DATA_To_FileInfo(fd, fileInfo); 1.161 + } 1.162 + return (_handle != INVALID_HANDLE_VALUE); 1.163 +} 1.164 +#endif 1.165 + 1.166 +bool CFindFile::FindNext(CFileInfo &fileInfo) 1.167 +{ 1.168 + WIN32_FIND_DATA fd; 1.169 + bool result = BOOLToBool(::FindNextFile(_handle, &fd)); 1.170 + if (result) 1.171 + ConvertWIN32_FIND_DATA_To_FileInfo(fd, fileInfo); 1.172 + return result; 1.173 +} 1.174 + 1.175 +#ifndef _UNICODE 1.176 +bool CFindFile::FindNext(CFileInfoW &fileInfo) 1.177 +{ 1.178 + if (g_IsNT) 1.179 + { 1.180 + WIN32_FIND_DATAW fd; 1.181 + if (!::FindNextFileW(_handle, &fd)) 1.182 + return false; 1.183 + ConvertWIN32_FIND_DATA_To_FileInfo(fd, fileInfo); 1.184 + } 1.185 + else 1.186 + { 1.187 + WIN32_FIND_DATAA fd; 1.188 + if (!::FindNextFileA(_handle, &fd)) 1.189 + return false; 1.190 + ConvertWIN32_FIND_DATA_To_FileInfo(fd, fileInfo); 1.191 + } 1.192 + return true; 1.193 +} 1.194 +#endif 1.195 + 1.196 +bool FindFile(LPCTSTR wildcard, CFileInfo &fileInfo) 1.197 +{ 1.198 + CFindFile finder; 1.199 + return finder.FindFirst(wildcard, fileInfo); 1.200 +} 1.201 + 1.202 +#ifndef _UNICODE 1.203 +bool FindFile(LPCWSTR wildcard, CFileInfoW &fileInfo) 1.204 +{ 1.205 + CFindFile finder; 1.206 + return finder.FindFirst(wildcard, fileInfo); 1.207 +} 1.208 +#endif 1.209 + 1.210 +bool DoesFileExist(LPCTSTR name) 1.211 +{ 1.212 + CFileInfo fileInfo; 1.213 + return FindFile(name, fileInfo); 1.214 +} 1.215 + 1.216 +#ifndef _UNICODE 1.217 +bool DoesFileExist(LPCWSTR name) 1.218 +{ 1.219 + CFileInfoW fileInfo; 1.220 + return FindFile(name, fileInfo); 1.221 +} 1.222 +#endif 1.223 + 1.224 +///////////////////////////////////// 1.225 +// CEnumerator 1.226 + 1.227 +bool CEnumerator::NextAny(CFileInfo &fileInfo) 1.228 +{ 1.229 + if (_findFile.IsHandleAllocated()) 1.230 + return _findFile.FindNext(fileInfo); 1.231 + else 1.232 + return _findFile.FindFirst(_wildcard, fileInfo); 1.233 +} 1.234 + 1.235 +bool CEnumerator::Next(CFileInfo &fileInfo) 1.236 +{ 1.237 + for (;;) 1.238 + { 1.239 + if (!NextAny(fileInfo)) 1.240 + return false; 1.241 + if (!fileInfo.IsDots()) 1.242 + return true; 1.243 + } 1.244 +} 1.245 + 1.246 +bool CEnumerator::Next(CFileInfo &fileInfo, bool &found) 1.247 +{ 1.248 + if (Next(fileInfo)) 1.249 + { 1.250 + found = true; 1.251 + return true; 1.252 + } 1.253 + found = false; 1.254 + return (::GetLastError() == ERROR_NO_MORE_FILES); 1.255 +} 1.256 + 1.257 +#ifndef _UNICODE 1.258 +bool CEnumeratorW::NextAny(CFileInfoW &fileInfo) 1.259 +{ 1.260 + if (_findFile.IsHandleAllocated()) 1.261 + return _findFile.FindNext(fileInfo); 1.262 + else 1.263 + return _findFile.FindFirst(_wildcard, fileInfo); 1.264 +} 1.265 + 1.266 +bool CEnumeratorW::Next(CFileInfoW &fileInfo) 1.267 +{ 1.268 + for (;;) 1.269 + { 1.270 + if (!NextAny(fileInfo)) 1.271 + return false; 1.272 + if (!fileInfo.IsDots()) 1.273 + return true; 1.274 + } 1.275 +} 1.276 + 1.277 +bool CEnumeratorW::Next(CFileInfoW &fileInfo, bool &found) 1.278 +{ 1.279 + if (Next(fileInfo)) 1.280 + { 1.281 + found = true; 1.282 + return true; 1.283 + } 1.284 + found = false; 1.285 + return (::GetLastError() == ERROR_NO_MORE_FILES); 1.286 +} 1.287 + 1.288 +#endif 1.289 + 1.290 +//////////////////////////////// 1.291 +// CFindChangeNotification 1.292 +// FindFirstChangeNotification can return 0. MSDN doesn't tell about it. 1.293 + 1.294 +bool CFindChangeNotification::Close() 1.295 +{ 1.296 + if (!IsHandleAllocated()) 1.297 + return true; 1.298 + if (!::FindCloseChangeNotification(_handle)) 1.299 + return false; 1.300 + _handle = INVALID_HANDLE_VALUE; 1.301 + return true; 1.302 +} 1.303 + 1.304 +HANDLE CFindChangeNotification::FindFirst(LPCTSTR pathName, bool watchSubtree, DWORD notifyFilter) 1.305 +{ 1.306 + _handle = ::FindFirstChangeNotification(pathName, BoolToBOOL(watchSubtree), notifyFilter); 1.307 + #ifdef WIN_LONG_PATH2 1.308 + if (!IsHandleAllocated()) 1.309 + { 1.310 + UString longPath; 1.311 + if (GetLongPath(pathName, longPath)) 1.312 + _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter); 1.313 + } 1.314 + #endif 1.315 + return _handle; 1.316 +} 1.317 + 1.318 +#ifndef _UNICODE 1.319 +HANDLE CFindChangeNotification::FindFirst(LPCWSTR pathName, bool watchSubtree, DWORD notifyFilter) 1.320 +{ 1.321 + if (!g_IsNT) 1.322 + return FindFirst(UnicodeStringToMultiByte(pathName, GetCurrentCodePage()), watchSubtree, notifyFilter); 1.323 + _handle = ::FindFirstChangeNotificationW(pathName, BoolToBOOL(watchSubtree), notifyFilter); 1.324 + #ifdef WIN_LONG_PATH 1.325 + if (!IsHandleAllocated()) 1.326 + { 1.327 + UString longPath; 1.328 + if (GetLongPath(pathName, longPath)) 1.329 + _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter); 1.330 + } 1.331 + #endif 1.332 + return _handle; 1.333 +} 1.334 +#endif 1.335 + 1.336 +#ifndef _WIN32_WCE 1.337 +bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings) 1.338 +{ 1.339 + driveStrings.Clear(); 1.340 + UINT32 size = GetLogicalDriveStrings(0, NULL); 1.341 + if (size == 0) 1.342 + return false; 1.343 + CSysString buffer; 1.344 + UINT32 newSize = GetLogicalDriveStrings(size, buffer.GetBuffer(size)); 1.345 + if (newSize == 0) 1.346 + return false; 1.347 + if (newSize > size) 1.348 + return false; 1.349 + CSysString string; 1.350 + for (UINT32 i = 0; i < newSize; i++) 1.351 + { 1.352 + TCHAR c = buffer[i]; 1.353 + if (c == TEXT('\0')) 1.354 + { 1.355 + driveStrings.Add(string); 1.356 + string.Empty(); 1.357 + } 1.358 + else 1.359 + string += c; 1.360 + } 1.361 + if (!string.IsEmpty()) 1.362 + return false; 1.363 + return true; 1.364 +} 1.365 + 1.366 +#ifndef _UNICODE 1.367 +bool MyGetLogicalDriveStrings(UStringVector &driveStrings) 1.368 +{ 1.369 + driveStrings.Clear(); 1.370 + if (g_IsNT) 1.371 + { 1.372 + UINT32 size = GetLogicalDriveStringsW(0, NULL); 1.373 + if (size == 0) 1.374 + return false; 1.375 + UString buffer; 1.376 + UINT32 newSize = GetLogicalDriveStringsW(size, buffer.GetBuffer(size)); 1.377 + if (newSize == 0) 1.378 + return false; 1.379 + if (newSize > size) 1.380 + return false; 1.381 + UString string; 1.382 + for (UINT32 i = 0; i < newSize; i++) 1.383 + { 1.384 + WCHAR c = buffer[i]; 1.385 + if (c == L'\0') 1.386 + { 1.387 + driveStrings.Add(string); 1.388 + string.Empty(); 1.389 + } 1.390 + else 1.391 + string += c; 1.392 + } 1.393 + return string.IsEmpty(); 1.394 + } 1.395 + CSysStringVector driveStringsA; 1.396 + bool res = MyGetLogicalDriveStrings(driveStringsA); 1.397 + for (int i = 0; i < driveStringsA.Size(); i++) 1.398 + driveStrings.Add(GetUnicodeString(driveStringsA[i])); 1.399 + return res; 1.400 +} 1.401 +#endif 1.402 + 1.403 +#endif 1.404 + 1.405 +}}}