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