00001
00002
00003
00004
00005 #include "StdAfx.h"
00006
00007 #include "FileFind.h"
00008 #ifndef _UNICODE
00009 #include "StringConvert.h"
00010 #endif
00011
00012 #ifndef _UNICODE
00013 extern bool g_IsNT;
00014 #endif
00015
00016 namespace NWindows {
00017 namespace NFile {
00018 namespace NFind {
00019
00020 static const TCHAR kDot = TEXT('.');
00021
00022 bool CFileInfo::IsDots() const
00023 {
00024 if (!IsDirectory() || Name.IsEmpty())
00025 return false;
00026 if (Name[0] != kDot)
00027 return false;
00028 return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
00029 }
00030
00031 #ifndef _UNICODE
00032 bool CFileInfoW::IsDots() const
00033 {
00034 if (!IsDirectory() || Name.IsEmpty())
00035 return false;
00036 if (Name[0] != kDot)
00037 return false;
00038 return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
00039 }
00040 #endif
00041
00042 static void ConvertWIN32_FIND_DATA_To_FileInfo(
00043 const WIN32_FIND_DATA &findData,
00044 CFileInfo &fileInfo)
00045 {
00046 fileInfo.Attributes = findData.dwFileAttributes;
00047 fileInfo.CreationTime = findData.ftCreationTime;
00048 fileInfo.LastAccessTime = findData.ftLastAccessTime;
00049 fileInfo.LastWriteTime = findData.ftLastWriteTime;
00050 fileInfo.Size = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
00051 fileInfo.Name = findData.cFileName;
00052 #ifndef _WIN32_WCE
00053 fileInfo.ReparseTag = findData.dwReserved0;
00054 #else
00055 fileInfo.ObjectID = findData.dwOID;
00056 #endif
00057 }
00058
00059 #ifndef _UNICODE
00060
00061 static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
00062
00063 static void ConvertWIN32_FIND_DATA_To_FileInfo(
00064 const WIN32_FIND_DATAW &findData,
00065 CFileInfoW &fileInfo)
00066 {
00067 fileInfo.Attributes = findData.dwFileAttributes;
00068 fileInfo.CreationTime = findData.ftCreationTime;
00069 fileInfo.LastAccessTime = findData.ftLastAccessTime;
00070 fileInfo.LastWriteTime = findData.ftLastWriteTime;
00071 fileInfo.Size = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
00072 fileInfo.Name = findData.cFileName;
00073 #ifndef _WIN32_WCE
00074 fileInfo.ReparseTag = findData.dwReserved0;
00075 #else
00076 fileInfo.ObjectID = findData.dwOID;
00077 #endif
00078 }
00079
00080 static void ConvertWIN32_FIND_DATA_To_FileInfo(
00081 const WIN32_FIND_DATA &findData,
00082 CFileInfoW &fileInfo)
00083 {
00084 fileInfo.Attributes = findData.dwFileAttributes;
00085 fileInfo.CreationTime = findData.ftCreationTime;
00086 fileInfo.LastAccessTime = findData.ftLastAccessTime;
00087 fileInfo.LastWriteTime = findData.ftLastWriteTime;
00088 fileInfo.Size = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
00089 fileInfo.Name = GetUnicodeString(findData.cFileName, GetCurrentCodePage());
00090 #ifndef _WIN32_WCE
00091 fileInfo.ReparseTag = findData.dwReserved0;
00092 #else
00093 fileInfo.ObjectID = findData.dwOID;
00094 #endif
00095 }
00096 #endif
00097
00098
00099 bool CFindFile::Close()
00100 {
00101 if(!_handleAllocated)
00102 return true;
00103 bool result = BOOLToBool(::FindClose(_handle));
00104 _handleAllocated = !result;
00105 return result;
00106 }
00107
00108 bool CFindFile::FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo)
00109 {
00110 Close();
00111 WIN32_FIND_DATA findData;
00112 _handle = ::FindFirstFile(wildcard, &findData);
00113 if (_handleAllocated = (_handle != INVALID_HANDLE_VALUE))
00114 ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
00115 return _handleAllocated;
00116 }
00117
00118 #ifndef _UNICODE
00119 bool CFindFile::FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo)
00120 {
00121 Close();
00122 if (g_IsNT)
00123 {
00124 WIN32_FIND_DATAW findData;
00125 _handle = ::FindFirstFileW(wildcard, &findData);
00126 if (_handleAllocated = (_handle != INVALID_HANDLE_VALUE))
00127 ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
00128 }
00129 else
00130 {
00131 WIN32_FIND_DATAA findData;
00132 _handle = ::FindFirstFileA(UnicodeStringToMultiByte(wildcard,
00133 GetCurrentCodePage()), &findData);
00134 if (_handleAllocated = (_handle != INVALID_HANDLE_VALUE))
00135 ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
00136 }
00137 return _handleAllocated;
00138 }
00139 #endif
00140
00141 bool CFindFile::FindNext(CFileInfo &fileInfo)
00142 {
00143 WIN32_FIND_DATA findData;
00144 bool result = BOOLToBool(::FindNextFile(_handle, &findData));
00145 if (result)
00146 ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
00147 return result;
00148 }
00149
00150 #ifndef _UNICODE
00151 bool CFindFile::FindNext(CFileInfoW &fileInfo)
00152 {
00153 if (g_IsNT)
00154 {
00155 WIN32_FIND_DATAW findData;
00156 if (!::FindNextFileW(_handle, &findData))
00157 return false;
00158 ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
00159 }
00160 else
00161 {
00162 WIN32_FIND_DATAA findData;
00163 if (!::FindNextFileA(_handle, &findData))
00164 return false;
00165 ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
00166 }
00167 return true;
00168 }
00169 #endif
00170
00171 bool FindFile(LPCTSTR wildcard, CFileInfo &fileInfo)
00172 {
00173 CFindFile finder;
00174 return finder.FindFirst(wildcard, fileInfo);
00175 }
00176
00177 #ifndef _UNICODE
00178 bool FindFile(LPCWSTR wildcard, CFileInfoW &fileInfo)
00179 {
00180 CFindFile finder;
00181 return finder.FindFirst(wildcard, fileInfo);
00182 }
00183 #endif
00184
00185 bool DoesFileExist(LPCTSTR name)
00186 {
00187 CFileInfo fileInfo;
00188 return FindFile(name, fileInfo);
00189 }
00190
00191 #ifndef _UNICODE
00192 bool DoesFileExist(LPCWSTR name)
00193 {
00194 CFileInfoW fileInfo;
00195 return FindFile(name, fileInfo);
00196 }
00197 #endif
00198
00199 bool CEnumerator::NextAny(CFileInfo &fileInfo)
00200 {
00201 if(_findFile.IsHandleAllocated())
00202 return _findFile.FindNext(fileInfo);
00203 else
00204 return _findFile.FindFirst(_wildcard, fileInfo);
00205 }
00206
00207 bool CEnumerator::Next(CFileInfo &fileInfo)
00208 {
00209 while(true)
00210 {
00211 if(!NextAny(fileInfo))
00212 return false;
00213 if(!fileInfo.IsDots())
00214 return true;
00215 }
00216 }
00217
00218 bool CEnumerator::Next(CFileInfo &fileInfo, bool &found)
00219 {
00220 if (Next(fileInfo))
00221 {
00222 found = true;
00223 return true;
00224 }
00225 found = false;
00226 return (::GetLastError() == ERROR_NO_MORE_FILES);
00227 }
00228
00229 #ifndef _UNICODE
00230 bool CEnumeratorW::NextAny(CFileInfoW &fileInfo)
00231 {
00232 if(_findFile.IsHandleAllocated())
00233 return _findFile.FindNext(fileInfo);
00234 else
00235 return _findFile.FindFirst(_wildcard, fileInfo);
00236 }
00237
00238 bool CEnumeratorW::Next(CFileInfoW &fileInfo)
00239 {
00240 while(true)
00241 {
00242 if(!NextAny(fileInfo))
00243 return false;
00244 if(!fileInfo.IsDots())
00245 return true;
00246 }
00247 }
00248
00249 bool CEnumeratorW::Next(CFileInfoW &fileInfo, bool &found)
00250 {
00251 if (Next(fileInfo))
00252 {
00253 found = true;
00254 return true;
00255 }
00256 found = false;
00257 return (::GetLastError() == ERROR_NO_MORE_FILES);
00258 }
00259
00260 #endif
00261
00262 bool CFindChangeNotification::Close()
00263 {
00264 if(_handle == INVALID_HANDLE_VALUE || _handle == 0)
00265 return true;
00266 bool result = BOOLToBool(::FindCloseChangeNotification(_handle));
00267 if (result)
00268 _handle = INVALID_HANDLE_VALUE;
00269 return result;
00270 }
00271
00272 HANDLE CFindChangeNotification::FindFirst(LPCTSTR pathName, bool watchSubtree,
00273 DWORD notifyFilter)
00274 {
00275 _handle = ::FindFirstChangeNotification(pathName,
00276 BoolToBOOL(watchSubtree), notifyFilter);
00277 return _handle;
00278 }
00279
00280 #ifndef _UNICODE
00281 HANDLE CFindChangeNotification::FindFirst(LPCWSTR pathName, bool watchSubtree,
00282 DWORD notifyFilter)
00283 {
00284 if (g_IsNT)
00285 return (_handle = ::FindFirstChangeNotificationW(pathName, BoolToBOOL(watchSubtree), notifyFilter));
00286 return FindFirst(UnicodeStringToMultiByte(pathName, GetCurrentCodePage()), watchSubtree, notifyFilter);
00287 }
00288 #endif
00289
00290 #ifndef _WIN32_WCE
00291 bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings)
00292 {
00293 driveStrings.Clear();
00294 UINT32 size = GetLogicalDriveStrings(0, NULL);
00295 if(size == 0)
00296 return false;
00297 CSysString buffer;
00298 UINT32 newSize = GetLogicalDriveStrings(size, buffer.GetBuffer(size));
00299 if(newSize == 0)
00300 return false;
00301 if(newSize > size)
00302 return false;
00303 CSysString string;
00304 for(UINT32 i = 0; i < newSize; i++)
00305 {
00306 TCHAR c = buffer[i];
00307 if(c == TEXT('\0'))
00308 {
00309 driveStrings.Add(string);
00310 string.Empty();
00311 }
00312 else
00313 string += c;
00314 }
00315 if(!string.IsEmpty())
00316 return false;
00317 return true;
00318 }
00319
00320 #ifndef _UNICODE
00321 bool MyGetLogicalDriveStrings(UStringVector &driveStrings)
00322 {
00323 driveStrings.Clear();
00324 if (g_IsNT)
00325 {
00326 UINT32 size = GetLogicalDriveStringsW(0, NULL);
00327 if (size == 0)
00328 return false;
00329 UString buffer;
00330 UINT32 newSize = GetLogicalDriveStringsW(size, buffer.GetBuffer(size));
00331 if(newSize == 0)
00332 return false;
00333 if(newSize > size)
00334 return false;
00335 UString string;
00336 for(UINT32 i = 0; i < newSize; i++)
00337 {
00338 WCHAR c = buffer[i];
00339 if(c == L'\0')
00340 {
00341 driveStrings.Add(string);
00342 string.Empty();
00343 }
00344 else
00345 string += c;
00346 }
00347 return string.IsEmpty();
00348 }
00349 CSysStringVector driveStringsA;
00350 bool res = MyGetLogicalDriveStrings(driveStringsA);
00351 for (int i = 0; i < driveStringsA.Size(); i++)
00352 driveStrings.Add(GetUnicodeString(driveStringsA[i]));
00353 return res;
00354 }
00355 #endif
00356
00357 #endif
00358
00359 }}}