other-licenses/7zstub/src/Windows/FileFind.cpp

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

michael@0 1 // Windows/FileFind.cpp
michael@0 2
michael@0 3 #include "StdAfx.h"
michael@0 4
michael@0 5 #include "FileFind.h"
michael@0 6 #ifndef _UNICODE
michael@0 7 #include "../Common/StringConvert.h"
michael@0 8 #endif
michael@0 9
michael@0 10 #ifndef _UNICODE
michael@0 11 extern bool g_IsNT;
michael@0 12 #endif
michael@0 13
michael@0 14 namespace NWindows {
michael@0 15 namespace NFile {
michael@0 16 namespace NFind {
michael@0 17
michael@0 18 static const TCHAR kDot = TEXT('.');
michael@0 19
michael@0 20 bool CFileInfo::IsDots() const
michael@0 21 {
michael@0 22 if (!IsDirectory() || Name.IsEmpty())
michael@0 23 return false;
michael@0 24 if (Name[0] != kDot)
michael@0 25 return false;
michael@0 26 return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
michael@0 27 }
michael@0 28
michael@0 29 #ifndef _UNICODE
michael@0 30 bool CFileInfoW::IsDots() const
michael@0 31 {
michael@0 32 if (!IsDirectory() || Name.IsEmpty())
michael@0 33 return false;
michael@0 34 if (Name[0] != kDot)
michael@0 35 return false;
michael@0 36 return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
michael@0 37 }
michael@0 38 #endif
michael@0 39
michael@0 40 static void ConvertWIN32_FIND_DATA_To_FileInfo(
michael@0 41 const WIN32_FIND_DATA &findData,
michael@0 42 CFileInfo &fileInfo)
michael@0 43 {
michael@0 44 fileInfo.Attributes = findData.dwFileAttributes;
michael@0 45 fileInfo.CreationTime = findData.ftCreationTime;
michael@0 46 fileInfo.LastAccessTime = findData.ftLastAccessTime;
michael@0 47 fileInfo.LastWriteTime = findData.ftLastWriteTime;
michael@0 48 fileInfo.Size = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
michael@0 49 fileInfo.Name = findData.cFileName;
michael@0 50 #ifndef _WIN32_WCE
michael@0 51 fileInfo.ReparseTag = findData.dwReserved0;
michael@0 52 #else
michael@0 53 fileInfo.ObjectID = findData.dwOID;
michael@0 54 #endif
michael@0 55 }
michael@0 56
michael@0 57 #ifndef _UNICODE
michael@0 58
michael@0 59 static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
michael@0 60
michael@0 61 static void ConvertWIN32_FIND_DATA_To_FileInfo(
michael@0 62 const WIN32_FIND_DATAW &findData,
michael@0 63 CFileInfoW &fileInfo)
michael@0 64 {
michael@0 65 fileInfo.Attributes = findData.dwFileAttributes;
michael@0 66 fileInfo.CreationTime = findData.ftCreationTime;
michael@0 67 fileInfo.LastAccessTime = findData.ftLastAccessTime;
michael@0 68 fileInfo.LastWriteTime = findData.ftLastWriteTime;
michael@0 69 fileInfo.Size = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
michael@0 70 fileInfo.Name = findData.cFileName;
michael@0 71 #ifndef _WIN32_WCE
michael@0 72 fileInfo.ReparseTag = findData.dwReserved0;
michael@0 73 #else
michael@0 74 fileInfo.ObjectID = findData.dwOID;
michael@0 75 #endif
michael@0 76 }
michael@0 77
michael@0 78 static void ConvertWIN32_FIND_DATA_To_FileInfo(
michael@0 79 const WIN32_FIND_DATA &findData,
michael@0 80 CFileInfoW &fileInfo)
michael@0 81 {
michael@0 82 fileInfo.Attributes = findData.dwFileAttributes;
michael@0 83 fileInfo.CreationTime = findData.ftCreationTime;
michael@0 84 fileInfo.LastAccessTime = findData.ftLastAccessTime;
michael@0 85 fileInfo.LastWriteTime = findData.ftLastWriteTime;
michael@0 86 fileInfo.Size = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
michael@0 87 fileInfo.Name = GetUnicodeString(findData.cFileName, GetCurrentCodePage());
michael@0 88 #ifndef _WIN32_WCE
michael@0 89 fileInfo.ReparseTag = findData.dwReserved0;
michael@0 90 #else
michael@0 91 fileInfo.ObjectID = findData.dwOID;
michael@0 92 #endif
michael@0 93 }
michael@0 94 #endif
michael@0 95
michael@0 96 ////////////////////////////////
michael@0 97 // CFindFile
michael@0 98
michael@0 99 bool CFindFile::Close()
michael@0 100 {
michael@0 101 if(!_handleAllocated)
michael@0 102 return true;
michael@0 103 bool result = BOOLToBool(::FindClose(_handle));
michael@0 104 _handleAllocated = !result;
michael@0 105 return result;
michael@0 106 }
michael@0 107
michael@0 108 bool CFindFile::FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo)
michael@0 109 {
michael@0 110 Close();
michael@0 111 WIN32_FIND_DATA findData;
michael@0 112 _handle = ::FindFirstFile(wildcard, &findData);
michael@0 113 if (_handleAllocated = (_handle != INVALID_HANDLE_VALUE))
michael@0 114 ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
michael@0 115 return _handleAllocated;
michael@0 116 }
michael@0 117
michael@0 118 #ifndef _UNICODE
michael@0 119 bool CFindFile::FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo)
michael@0 120 {
michael@0 121 Close();
michael@0 122 if (g_IsNT)
michael@0 123 {
michael@0 124 WIN32_FIND_DATAW findData;
michael@0 125 _handle = ::FindFirstFileW(wildcard, &findData);
michael@0 126 if (_handleAllocated = (_handle != INVALID_HANDLE_VALUE))
michael@0 127 ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
michael@0 128 }
michael@0 129 else
michael@0 130 {
michael@0 131 WIN32_FIND_DATAA findData;
michael@0 132 _handle = ::FindFirstFileA(UnicodeStringToMultiByte(wildcard,
michael@0 133 GetCurrentCodePage()), &findData);
michael@0 134 if (_handleAllocated = (_handle != INVALID_HANDLE_VALUE))
michael@0 135 ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
michael@0 136 }
michael@0 137 return _handleAllocated;
michael@0 138 }
michael@0 139 #endif
michael@0 140
michael@0 141 bool CFindFile::FindNext(CFileInfo &fileInfo)
michael@0 142 {
michael@0 143 WIN32_FIND_DATA findData;
michael@0 144 bool result = BOOLToBool(::FindNextFile(_handle, &findData));
michael@0 145 if (result)
michael@0 146 ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
michael@0 147 return result;
michael@0 148 }
michael@0 149
michael@0 150 #ifndef _UNICODE
michael@0 151 bool CFindFile::FindNext(CFileInfoW &fileInfo)
michael@0 152 {
michael@0 153 if (g_IsNT)
michael@0 154 {
michael@0 155 WIN32_FIND_DATAW findData;
michael@0 156 if (!::FindNextFileW(_handle, &findData))
michael@0 157 return false;
michael@0 158 ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
michael@0 159 }
michael@0 160 else
michael@0 161 {
michael@0 162 WIN32_FIND_DATAA findData;
michael@0 163 if (!::FindNextFileA(_handle, &findData))
michael@0 164 return false;
michael@0 165 ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
michael@0 166 }
michael@0 167 return true;
michael@0 168 }
michael@0 169 #endif
michael@0 170
michael@0 171 bool FindFile(LPCTSTR wildcard, CFileInfo &fileInfo)
michael@0 172 {
michael@0 173 CFindFile finder;
michael@0 174 return finder.FindFirst(wildcard, fileInfo);
michael@0 175 }
michael@0 176
michael@0 177 #ifndef _UNICODE
michael@0 178 bool FindFile(LPCWSTR wildcard, CFileInfoW &fileInfo)
michael@0 179 {
michael@0 180 CFindFile finder;
michael@0 181 return finder.FindFirst(wildcard, fileInfo);
michael@0 182 }
michael@0 183 #endif
michael@0 184
michael@0 185 bool DoesFileExist(LPCTSTR name)
michael@0 186 {
michael@0 187 CFileInfo fileInfo;
michael@0 188 return FindFile(name, fileInfo);
michael@0 189 }
michael@0 190
michael@0 191 #ifndef _UNICODE
michael@0 192 bool DoesFileExist(LPCWSTR name)
michael@0 193 {
michael@0 194 CFileInfoW fileInfo;
michael@0 195 return FindFile(name, fileInfo);
michael@0 196 }
michael@0 197 #endif
michael@0 198
michael@0 199 /////////////////////////////////////
michael@0 200 // CEnumerator
michael@0 201
michael@0 202 bool CEnumerator::NextAny(CFileInfo &fileInfo)
michael@0 203 {
michael@0 204 if(_findFile.IsHandleAllocated())
michael@0 205 return _findFile.FindNext(fileInfo);
michael@0 206 else
michael@0 207 return _findFile.FindFirst(_wildcard, fileInfo);
michael@0 208 }
michael@0 209
michael@0 210 bool CEnumerator::Next(CFileInfo &fileInfo)
michael@0 211 {
michael@0 212 while(true)
michael@0 213 {
michael@0 214 if(!NextAny(fileInfo))
michael@0 215 return false;
michael@0 216 if(!fileInfo.IsDots())
michael@0 217 return true;
michael@0 218 }
michael@0 219 }
michael@0 220
michael@0 221 bool CEnumerator::Next(CFileInfo &fileInfo, bool &found)
michael@0 222 {
michael@0 223 if (Next(fileInfo))
michael@0 224 {
michael@0 225 found = true;
michael@0 226 return true;
michael@0 227 }
michael@0 228 found = false;
michael@0 229 return (::GetLastError() == ERROR_NO_MORE_FILES);
michael@0 230 }
michael@0 231
michael@0 232 #ifndef _UNICODE
michael@0 233 bool CEnumeratorW::NextAny(CFileInfoW &fileInfo)
michael@0 234 {
michael@0 235 if(_findFile.IsHandleAllocated())
michael@0 236 return _findFile.FindNext(fileInfo);
michael@0 237 else
michael@0 238 return _findFile.FindFirst(_wildcard, fileInfo);
michael@0 239 }
michael@0 240
michael@0 241 bool CEnumeratorW::Next(CFileInfoW &fileInfo)
michael@0 242 {
michael@0 243 while(true)
michael@0 244 {
michael@0 245 if(!NextAny(fileInfo))
michael@0 246 return false;
michael@0 247 if(!fileInfo.IsDots())
michael@0 248 return true;
michael@0 249 }
michael@0 250 }
michael@0 251
michael@0 252 bool CEnumeratorW::Next(CFileInfoW &fileInfo, bool &found)
michael@0 253 {
michael@0 254 if (Next(fileInfo))
michael@0 255 {
michael@0 256 found = true;
michael@0 257 return true;
michael@0 258 }
michael@0 259 found = false;
michael@0 260 return (::GetLastError() == ERROR_NO_MORE_FILES);
michael@0 261 }
michael@0 262
michael@0 263 #endif
michael@0 264
michael@0 265 ////////////////////////////////
michael@0 266 // CFindChangeNotification
michael@0 267
michael@0 268 bool CFindChangeNotification::Close()
michael@0 269 {
michael@0 270 if(_handle == INVALID_HANDLE_VALUE || _handle == 0)
michael@0 271 return true;
michael@0 272 bool result = BOOLToBool(::FindCloseChangeNotification(_handle));
michael@0 273 if (result)
michael@0 274 _handle = INVALID_HANDLE_VALUE;
michael@0 275 return result;
michael@0 276 }
michael@0 277
michael@0 278 HANDLE CFindChangeNotification::FindFirst(LPCTSTR pathName, bool watchSubtree,
michael@0 279 DWORD notifyFilter)
michael@0 280 {
michael@0 281 _handle = ::FindFirstChangeNotification(pathName,
michael@0 282 BoolToBOOL(watchSubtree), notifyFilter);
michael@0 283 return _handle;
michael@0 284 }
michael@0 285
michael@0 286 #ifndef _UNICODE
michael@0 287 HANDLE CFindChangeNotification::FindFirst(LPCWSTR pathName, bool watchSubtree,
michael@0 288 DWORD notifyFilter)
michael@0 289 {
michael@0 290 if (g_IsNT)
michael@0 291 return (_handle = ::FindFirstChangeNotificationW(pathName, BoolToBOOL(watchSubtree), notifyFilter));
michael@0 292 return FindFirst(UnicodeStringToMultiByte(pathName, GetCurrentCodePage()), watchSubtree, notifyFilter);
michael@0 293 }
michael@0 294 #endif
michael@0 295
michael@0 296 #ifndef _WIN32_WCE
michael@0 297 bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings)
michael@0 298 {
michael@0 299 driveStrings.Clear();
michael@0 300 UINT32 size = GetLogicalDriveStrings(0, NULL);
michael@0 301 if(size == 0)
michael@0 302 return false;
michael@0 303 CSysString buffer;
michael@0 304 UINT32 newSize = GetLogicalDriveStrings(size, buffer.GetBuffer(size));
michael@0 305 if(newSize == 0)
michael@0 306 return false;
michael@0 307 if(newSize > size)
michael@0 308 return false;
michael@0 309 CSysString string;
michael@0 310 for(UINT32 i = 0; i < newSize; i++)
michael@0 311 {
michael@0 312 TCHAR c = buffer[i];
michael@0 313 if(c == TEXT('\0'))
michael@0 314 {
michael@0 315 driveStrings.Add(string);
michael@0 316 string.Empty();
michael@0 317 }
michael@0 318 else
michael@0 319 string += c;
michael@0 320 }
michael@0 321 if(!string.IsEmpty())
michael@0 322 return false;
michael@0 323 return true;
michael@0 324 }
michael@0 325
michael@0 326 #ifndef _UNICODE
michael@0 327 bool MyGetLogicalDriveStrings(UStringVector &driveStrings)
michael@0 328 {
michael@0 329 driveStrings.Clear();
michael@0 330 if (g_IsNT)
michael@0 331 {
michael@0 332 UINT32 size = GetLogicalDriveStringsW(0, NULL);
michael@0 333 if (size == 0)
michael@0 334 return false;
michael@0 335 UString buffer;
michael@0 336 UINT32 newSize = GetLogicalDriveStringsW(size, buffer.GetBuffer(size));
michael@0 337 if(newSize == 0)
michael@0 338 return false;
michael@0 339 if(newSize > size)
michael@0 340 return false;
michael@0 341 UString string;
michael@0 342 for(UINT32 i = 0; i < newSize; i++)
michael@0 343 {
michael@0 344 WCHAR c = buffer[i];
michael@0 345 if(c == L'\0')
michael@0 346 {
michael@0 347 driveStrings.Add(string);
michael@0 348 string.Empty();
michael@0 349 }
michael@0 350 else
michael@0 351 string += c;
michael@0 352 }
michael@0 353 return string.IsEmpty();
michael@0 354 }
michael@0 355 CSysStringVector driveStringsA;
michael@0 356 bool res = MyGetLogicalDriveStrings(driveStringsA);
michael@0 357 for (int i = 0; i < driveStringsA.Size(); i++)
michael@0 358 driveStrings.Add(GetUnicodeString(driveStringsA[i]));
michael@0 359 return res;
michael@0 360 }
michael@0 361 #endif
michael@0 362
michael@0 363 #endif
michael@0 364
michael@0 365 }}}

mercurial