Mercurial > vba-clojure
comparison src/win32/7zip/7z/CPP/Windows/FileDir.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/FileDir.cpp | |
2 | |
3 #include "StdAfx.h" | |
4 | |
5 #include "FileDir.h" | |
6 #include "FileName.h" | |
7 #include "FileFind.h" | |
8 #include "Defs.h" | |
9 #ifndef _UNICODE | |
10 #include "../Common/StringConvert.h" | |
11 #endif | |
12 | |
13 #ifndef _UNICODE | |
14 extern bool g_IsNT; | |
15 #endif | |
16 | |
17 namespace NWindows { | |
18 namespace NFile { | |
19 | |
20 #if defined(WIN_LONG_PATH) && defined(_UNICODE) | |
21 #define WIN_LONG_PATH2 | |
22 #endif | |
23 | |
24 // SetCurrentDirectory doesn't support \\?\ prefix | |
25 | |
26 #ifdef WIN_LONG_PATH | |
27 bool GetLongPathBase(LPCWSTR fileName, UString &res); | |
28 bool GetLongPath(LPCWSTR fileName, UString &res); | |
29 #endif | |
30 | |
31 namespace NDirectory { | |
32 | |
33 #ifndef _UNICODE | |
34 static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } | |
35 static UString GetUnicodePath(const CSysString &sysPath) | |
36 { return MultiByteToUnicodeString(sysPath, GetCurrentCodePage()); } | |
37 static CSysString GetSysPath(LPCWSTR sysPath) | |
38 { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); } | |
39 #endif | |
40 | |
41 bool MyGetWindowsDirectory(CSysString &path) | |
42 { | |
43 UINT needLength = ::GetWindowsDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1); | |
44 path.ReleaseBuffer(); | |
45 return (needLength > 0 && needLength <= MAX_PATH); | |
46 } | |
47 | |
48 bool MyGetSystemDirectory(CSysString &path) | |
49 { | |
50 UINT needLength = ::GetSystemDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1); | |
51 path.ReleaseBuffer(); | |
52 return (needLength > 0 && needLength <= MAX_PATH); | |
53 } | |
54 | |
55 #ifndef _UNICODE | |
56 bool MyGetWindowsDirectory(UString &path) | |
57 { | |
58 if (g_IsNT) | |
59 { | |
60 UINT needLength = ::GetWindowsDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1); | |
61 path.ReleaseBuffer(); | |
62 return (needLength > 0 && needLength <= MAX_PATH); | |
63 } | |
64 CSysString sysPath; | |
65 if (!MyGetWindowsDirectory(sysPath)) | |
66 return false; | |
67 path = GetUnicodePath(sysPath); | |
68 return true; | |
69 } | |
70 | |
71 bool MyGetSystemDirectory(UString &path) | |
72 { | |
73 if (g_IsNT) | |
74 { | |
75 UINT needLength = ::GetSystemDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1); | |
76 path.ReleaseBuffer(); | |
77 return (needLength > 0 && needLength <= MAX_PATH); | |
78 } | |
79 CSysString sysPath; | |
80 if (!MyGetSystemDirectory(sysPath)) | |
81 return false; | |
82 path = GetUnicodePath(sysPath); | |
83 return true; | |
84 } | |
85 #endif | |
86 | |
87 bool SetDirTime(LPCWSTR fileName, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) | |
88 { | |
89 #ifndef _UNICODE | |
90 if (!g_IsNT) | |
91 { | |
92 ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED); | |
93 return false; | |
94 } | |
95 #endif | |
96 HANDLE hDir = ::CreateFileW(fileName, GENERIC_WRITE, | |
97 FILE_SHARE_READ | FILE_SHARE_WRITE, | |
98 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); | |
99 #ifdef WIN_LONG_PATH | |
100 if (hDir == INVALID_HANDLE_VALUE) | |
101 { | |
102 UString longPath; | |
103 if (GetLongPath(fileName, longPath)) | |
104 hDir = ::CreateFileW(longPath, GENERIC_WRITE, | |
105 FILE_SHARE_READ | FILE_SHARE_WRITE, | |
106 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); | |
107 } | |
108 #endif | |
109 | |
110 bool res = false; | |
111 if (hDir != INVALID_HANDLE_VALUE) | |
112 { | |
113 res = BOOLToBool(::SetFileTime(hDir, cTime, aTime, mTime)); | |
114 ::CloseHandle(hDir); | |
115 } | |
116 return res; | |
117 } | |
118 | |
119 bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes) | |
120 { | |
121 if (::SetFileAttributes(fileName, fileAttributes)) | |
122 return true; | |
123 #ifdef WIN_LONG_PATH2 | |
124 UString longPath; | |
125 if (GetLongPath(fileName, longPath)) | |
126 return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes)); | |
127 #endif | |
128 return false; | |
129 } | |
130 | |
131 bool MyRemoveDirectory(LPCTSTR pathName) | |
132 { | |
133 if (::RemoveDirectory(pathName)) | |
134 return true; | |
135 #ifdef WIN_LONG_PATH2 | |
136 UString longPath; | |
137 if (GetLongPath(pathName, longPath)) | |
138 return BOOLToBool(::RemoveDirectoryW(longPath)); | |
139 #endif | |
140 return false; | |
141 } | |
142 | |
143 #ifdef WIN_LONG_PATH | |
144 bool GetLongPaths(LPCWSTR s1, LPCWSTR s2, UString &d1, UString &d2) | |
145 { | |
146 if (!GetLongPathBase(s1, d1) || !GetLongPathBase(s2, d2)) | |
147 return false; | |
148 if (d1.IsEmpty() && d2.IsEmpty()) return false; | |
149 if (d1.IsEmpty()) d1 = s1; | |
150 if (d2.IsEmpty()) d2 = s2; | |
151 return true; | |
152 } | |
153 #endif | |
154 | |
155 bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName) | |
156 { | |
157 if (::MoveFile(existFileName, newFileName)) | |
158 return true; | |
159 #ifdef WIN_LONG_PATH2 | |
160 UString d1, d2; | |
161 if (GetLongPaths(existFileName, newFileName, d1, d2)) | |
162 return BOOLToBool(::MoveFileW(d1, d2)); | |
163 #endif | |
164 return false; | |
165 } | |
166 | |
167 #ifndef _UNICODE | |
168 bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes) | |
169 { | |
170 if (!g_IsNT) | |
171 return MySetFileAttributes(GetSysPath(fileName), fileAttributes); | |
172 if (::SetFileAttributesW(fileName, fileAttributes)) | |
173 return true; | |
174 #ifdef WIN_LONG_PATH | |
175 UString longPath; | |
176 if (GetLongPath(fileName, longPath)) | |
177 return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes)); | |
178 #endif | |
179 return false; | |
180 } | |
181 | |
182 | |
183 bool MyRemoveDirectory(LPCWSTR pathName) | |
184 { | |
185 if (!g_IsNT) | |
186 return MyRemoveDirectory(GetSysPath(pathName)); | |
187 if (::RemoveDirectoryW(pathName)) | |
188 return true; | |
189 #ifdef WIN_LONG_PATH | |
190 UString longPath; | |
191 if (GetLongPath(pathName, longPath)) | |
192 return BOOLToBool(::RemoveDirectoryW(longPath)); | |
193 #endif | |
194 return false; | |
195 } | |
196 | |
197 bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName) | |
198 { | |
199 if (!g_IsNT) | |
200 return MyMoveFile(GetSysPath(existFileName), GetSysPath(newFileName)); | |
201 if (::MoveFileW(existFileName, newFileName)) | |
202 return true; | |
203 #ifdef WIN_LONG_PATH | |
204 UString d1, d2; | |
205 if (GetLongPaths(existFileName, newFileName, d1, d2)) | |
206 return BOOLToBool(::MoveFileW(d1, d2)); | |
207 #endif | |
208 return false; | |
209 } | |
210 #endif | |
211 | |
212 bool MyCreateDirectory(LPCTSTR pathName) | |
213 { | |
214 if (::CreateDirectory(pathName, NULL)) | |
215 return true; | |
216 #ifdef WIN_LONG_PATH2 | |
217 if (::GetLastError() != ERROR_ALREADY_EXISTS) | |
218 { | |
219 UString longPath; | |
220 if (GetLongPath(pathName, longPath)) | |
221 return BOOLToBool(::CreateDirectoryW(longPath, NULL)); | |
222 } | |
223 #endif | |
224 return false; | |
225 } | |
226 | |
227 #ifndef _UNICODE | |
228 bool MyCreateDirectory(LPCWSTR pathName) | |
229 { | |
230 if (!g_IsNT) | |
231 return MyCreateDirectory(GetSysPath(pathName)); | |
232 if (::CreateDirectoryW(pathName, NULL)) | |
233 return true; | |
234 #ifdef WIN_LONG_PATH | |
235 if (::GetLastError() != ERROR_ALREADY_EXISTS) | |
236 { | |
237 UString longPath; | |
238 if (GetLongPath(pathName, longPath)) | |
239 return BOOLToBool(::CreateDirectoryW(longPath, NULL)); | |
240 } | |
241 #endif | |
242 return false; | |
243 } | |
244 #endif | |
245 | |
246 /* | |
247 bool CreateComplexDirectory(LPCTSTR pathName) | |
248 { | |
249 NName::CParsedPath path; | |
250 path.ParsePath(pathName); | |
251 CSysString fullPath = path.Prefix; | |
252 DWORD errorCode = ERROR_SUCCESS; | |
253 for (int i = 0; i < path.PathParts.Size(); i++) | |
254 { | |
255 const CSysString &string = path.PathParts[i]; | |
256 if (string.IsEmpty()) | |
257 { | |
258 if (i != path.PathParts.Size() - 1) | |
259 return false; | |
260 return true; | |
261 } | |
262 fullPath += path.PathParts[i]; | |
263 if (!MyCreateDirectory(fullPath)) | |
264 { | |
265 DWORD errorCode = GetLastError(); | |
266 if (errorCode != ERROR_ALREADY_EXISTS) | |
267 return false; | |
268 } | |
269 fullPath += NName::kDirDelimiter; | |
270 } | |
271 return true; | |
272 } | |
273 */ | |
274 | |
275 bool CreateComplexDirectory(LPCTSTR _aPathName) | |
276 { | |
277 CSysString pathName = _aPathName; | |
278 int pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR)); | |
279 if (pos > 0 && pos == pathName.Length() - 1) | |
280 { | |
281 if (pathName.Length() == 3 && pathName[1] == ':') | |
282 return true; // Disk folder; | |
283 pathName.Delete(pos); | |
284 } | |
285 CSysString pathName2 = pathName; | |
286 pos = pathName.Length(); | |
287 for (;;) | |
288 { | |
289 if (MyCreateDirectory(pathName)) | |
290 break; | |
291 if (::GetLastError() == ERROR_ALREADY_EXISTS) | |
292 { | |
293 NFind::CFileInfo fileInfo; | |
294 if (!NFind::FindFile(pathName, fileInfo)) // For network folders | |
295 return true; | |
296 if (!fileInfo.IsDir()) | |
297 return false; | |
298 break; | |
299 } | |
300 pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR)); | |
301 if (pos < 0 || pos == 0) | |
302 return false; | |
303 if (pathName[pos - 1] == ':') | |
304 return false; | |
305 pathName = pathName.Left(pos); | |
306 } | |
307 pathName = pathName2; | |
308 while (pos < pathName.Length()) | |
309 { | |
310 pos = pathName.Find(TEXT(CHAR_PATH_SEPARATOR), pos + 1); | |
311 if (pos < 0) | |
312 pos = pathName.Length(); | |
313 if (!MyCreateDirectory(pathName.Left(pos))) | |
314 return false; | |
315 } | |
316 return true; | |
317 } | |
318 | |
319 #ifndef _UNICODE | |
320 | |
321 bool CreateComplexDirectory(LPCWSTR _aPathName) | |
322 { | |
323 UString pathName = _aPathName; | |
324 int pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR); | |
325 if (pos > 0 && pos == pathName.Length() - 1) | |
326 { | |
327 if (pathName.Length() == 3 && pathName[1] == L':') | |
328 return true; // Disk folder; | |
329 pathName.Delete(pos); | |
330 } | |
331 UString pathName2 = pathName; | |
332 pos = pathName.Length(); | |
333 for (;;) | |
334 { | |
335 if (MyCreateDirectory(pathName)) | |
336 break; | |
337 if (::GetLastError() == ERROR_ALREADY_EXISTS) | |
338 { | |
339 NFind::CFileInfoW fileInfo; | |
340 if (!NFind::FindFile(pathName, fileInfo)) // For network folders | |
341 return true; | |
342 if (!fileInfo.IsDir()) | |
343 return false; | |
344 break; | |
345 } | |
346 pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR); | |
347 if (pos < 0 || pos == 0) | |
348 return false; | |
349 if (pathName[pos - 1] == L':') | |
350 return false; | |
351 pathName = pathName.Left(pos); | |
352 } | |
353 pathName = pathName2; | |
354 while (pos < pathName.Length()) | |
355 { | |
356 pos = pathName.Find(WCHAR_PATH_SEPARATOR, pos + 1); | |
357 if (pos < 0) | |
358 pos = pathName.Length(); | |
359 if (!MyCreateDirectory(pathName.Left(pos))) | |
360 return false; | |
361 } | |
362 return true; | |
363 } | |
364 | |
365 #endif | |
366 | |
367 bool DeleteFileAlways(LPCTSTR name) | |
368 { | |
369 if (!MySetFileAttributes(name, 0)) | |
370 return false; | |
371 if (::DeleteFile(name)) | |
372 return true; | |
373 #ifdef WIN_LONG_PATH2 | |
374 UString longPath; | |
375 if (GetLongPath(name, longPath)) | |
376 return BOOLToBool(::DeleteFileW(longPath)); | |
377 #endif | |
378 return false; | |
379 } | |
380 | |
381 #ifndef _UNICODE | |
382 bool DeleteFileAlways(LPCWSTR name) | |
383 { | |
384 if (!g_IsNT) | |
385 return DeleteFileAlways(GetSysPath(name)); | |
386 if (!MySetFileAttributes(name, 0)) | |
387 return false; | |
388 if (::DeleteFileW(name)) | |
389 return true; | |
390 #ifdef WIN_LONG_PATH | |
391 UString longPath; | |
392 if (GetLongPath(name, longPath)) | |
393 return BOOLToBool(::DeleteFileW(longPath)); | |
394 #endif | |
395 return false; | |
396 } | |
397 #endif | |
398 | |
399 static bool RemoveDirectorySubItems2(const CSysString pathPrefix, const NFind::CFileInfo &fileInfo) | |
400 { | |
401 if (fileInfo.IsDir()) | |
402 return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name); | |
403 return DeleteFileAlways(pathPrefix + fileInfo.Name); | |
404 } | |
405 | |
406 bool RemoveDirectoryWithSubItems(const CSysString &path) | |
407 { | |
408 NFind::CFileInfo fileInfo; | |
409 CSysString pathPrefix = path + NName::kDirDelimiter; | |
410 { | |
411 NFind::CEnumerator enumerator(pathPrefix + TCHAR(NName::kAnyStringWildcard)); | |
412 while (enumerator.Next(fileInfo)) | |
413 if (!RemoveDirectorySubItems2(pathPrefix, fileInfo)) | |
414 return false; | |
415 } | |
416 if (!MySetFileAttributes(path, 0)) | |
417 return false; | |
418 return MyRemoveDirectory(path); | |
419 } | |
420 | |
421 #ifndef _UNICODE | |
422 static bool RemoveDirectorySubItems2(const UString pathPrefix, const NFind::CFileInfoW &fileInfo) | |
423 { | |
424 if (fileInfo.IsDir()) | |
425 return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name); | |
426 return DeleteFileAlways(pathPrefix + fileInfo.Name); | |
427 } | |
428 bool RemoveDirectoryWithSubItems(const UString &path) | |
429 { | |
430 NFind::CFileInfoW fileInfo; | |
431 UString pathPrefix = path + UString(NName::kDirDelimiter); | |
432 { | |
433 NFind::CEnumeratorW enumerator(pathPrefix + UString(NName::kAnyStringWildcard)); | |
434 while (enumerator.Next(fileInfo)) | |
435 if (!RemoveDirectorySubItems2(pathPrefix, fileInfo)) | |
436 return false; | |
437 } | |
438 if (!MySetFileAttributes(path, 0)) | |
439 return false; | |
440 return MyRemoveDirectory(path); | |
441 } | |
442 #endif | |
443 | |
444 #ifndef _WIN32_WCE | |
445 | |
446 bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath) | |
447 { | |
448 DWORD needLength = ::GetShortPathName(longPath, shortPath.GetBuffer(MAX_PATH + 1), MAX_PATH + 1); | |
449 shortPath.ReleaseBuffer(); | |
450 return (needLength > 0 && needLength < MAX_PATH); | |
451 } | |
452 | |
453 bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex) | |
454 { | |
455 resultPath.Empty(); | |
456 LPTSTR fileNamePointer = 0; | |
457 LPTSTR buffer = resultPath.GetBuffer(MAX_PATH); | |
458 DWORD needLength = ::GetFullPathName(fileName, MAX_PATH + 1, buffer, &fileNamePointer); | |
459 resultPath.ReleaseBuffer(); | |
460 if (needLength == 0) | |
461 return false; | |
462 if (needLength >= MAX_PATH) | |
463 { | |
464 #ifdef WIN_LONG_PATH2 | |
465 needLength++; | |
466 buffer = resultPath.GetBuffer(needLength + 1); | |
467 DWORD needLength2 = ::GetFullPathNameW(fileName, needLength, buffer, &fileNamePointer); | |
468 resultPath.ReleaseBuffer(); | |
469 if (needLength2 == 0 || needLength2 > needLength) | |
470 #endif | |
471 return false; | |
472 } | |
473 if (fileNamePointer == 0) | |
474 fileNamePartStartIndex = lstrlen(fileName); | |
475 else | |
476 fileNamePartStartIndex = (int)(fileNamePointer - buffer); | |
477 return true; | |
478 } | |
479 | |
480 #ifndef _UNICODE | |
481 bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex) | |
482 { | |
483 resultPath.Empty(); | |
484 if (g_IsNT) | |
485 { | |
486 LPWSTR fileNamePointer = 0; | |
487 LPWSTR buffer = resultPath.GetBuffer(MAX_PATH); | |
488 DWORD needLength = ::GetFullPathNameW(fileName, MAX_PATH + 1, buffer, &fileNamePointer); | |
489 resultPath.ReleaseBuffer(); | |
490 if (needLength == 0) | |
491 return false; | |
492 if (needLength >= MAX_PATH) | |
493 { | |
494 #ifdef WIN_LONG_PATH | |
495 needLength++; | |
496 buffer = resultPath.GetBuffer(needLength + 1); | |
497 DWORD needLength2 = ::GetFullPathNameW(fileName, needLength, buffer, &fileNamePointer); | |
498 resultPath.ReleaseBuffer(); | |
499 if (needLength2 == 0 || needLength2 > needLength) | |
500 #endif | |
501 return false; | |
502 } | |
503 if (fileNamePointer == 0) | |
504 fileNamePartStartIndex = MyStringLen(fileName); | |
505 else | |
506 fileNamePartStartIndex = (int)(fileNamePointer - buffer); | |
507 } | |
508 else | |
509 { | |
510 CSysString sysPath; | |
511 if (!MyGetFullPathName(GetSysPath(fileName), sysPath, fileNamePartStartIndex)) | |
512 return false; | |
513 UString resultPath1 = GetUnicodePath(sysPath.Left(fileNamePartStartIndex)); | |
514 UString resultPath2 = GetUnicodePath(sysPath.Mid(fileNamePartStartIndex)); | |
515 fileNamePartStartIndex = resultPath1.Length(); | |
516 resultPath = resultPath1 + resultPath2; | |
517 } | |
518 return true; | |
519 } | |
520 #endif | |
521 | |
522 | |
523 bool MyGetFullPathName(LPCTSTR fileName, CSysString &path) | |
524 { | |
525 int index; | |
526 return MyGetFullPathName(fileName, path, index); | |
527 } | |
528 | |
529 #ifndef _UNICODE | |
530 bool MyGetFullPathName(LPCWSTR fileName, UString &path) | |
531 { | |
532 int index; | |
533 return MyGetFullPathName(fileName, path, index); | |
534 } | |
535 #endif | |
536 | |
537 bool GetOnlyName(LPCTSTR fileName, CSysString &resultName) | |
538 { | |
539 int index; | |
540 if (!MyGetFullPathName(fileName, resultName, index)) | |
541 return false; | |
542 resultName = resultName.Mid(index); | |
543 return true; | |
544 } | |
545 | |
546 #ifndef _UNICODE | |
547 bool GetOnlyName(LPCWSTR fileName, UString &resultName) | |
548 { | |
549 int index; | |
550 if (!MyGetFullPathName(fileName, resultName, index)) | |
551 return false; | |
552 resultName = resultName.Mid(index); | |
553 return true; | |
554 } | |
555 #endif | |
556 | |
557 bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName) | |
558 { | |
559 int index; | |
560 if (!MyGetFullPathName(fileName, resultName, index)) | |
561 return false; | |
562 resultName = resultName.Left(index); | |
563 return true; | |
564 } | |
565 | |
566 #ifndef _UNICODE | |
567 bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName) | |
568 { | |
569 int index; | |
570 if (!MyGetFullPathName(fileName, resultName, index)) | |
571 return false; | |
572 resultName = resultName.Left(index); | |
573 return true; | |
574 } | |
575 #endif | |
576 | |
577 bool MyGetCurrentDirectory(CSysString &path) | |
578 { | |
579 DWORD needLength = ::GetCurrentDirectory(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1)); | |
580 path.ReleaseBuffer(); | |
581 return (needLength > 0 && needLength <= MAX_PATH); | |
582 } | |
583 | |
584 #ifndef _UNICODE | |
585 bool MySetCurrentDirectory(LPCWSTR path) | |
586 { | |
587 if (g_IsNT) | |
588 return BOOLToBool(::SetCurrentDirectoryW(path)); | |
589 return MySetCurrentDirectory(GetSysPath(path)); | |
590 } | |
591 bool MyGetCurrentDirectory(UString &path) | |
592 { | |
593 if (g_IsNT) | |
594 { | |
595 DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1)); | |
596 path.ReleaseBuffer(); | |
597 return (needLength > 0 && needLength <= MAX_PATH); | |
598 } | |
599 CSysString sysPath; | |
600 if (!MyGetCurrentDirectory(sysPath)) | |
601 return false; | |
602 path = GetUnicodePath(sysPath); | |
603 return true; | |
604 } | |
605 #endif | |
606 #endif | |
607 | |
608 bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension, | |
609 CSysString &resultPath, UINT32 &filePart) | |
610 { | |
611 LPTSTR filePartPointer; | |
612 DWORD value = ::SearchPath(path, fileName, extension, | |
613 MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer); | |
614 filePart = (UINT32)(filePartPointer - (LPCTSTR)resultPath); | |
615 resultPath.ReleaseBuffer(); | |
616 return (value > 0 && value <= MAX_PATH); | |
617 } | |
618 | |
619 #ifndef _UNICODE | |
620 bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, | |
621 UString &resultPath, UINT32 &filePart) | |
622 { | |
623 if (g_IsNT) | |
624 { | |
625 LPWSTR filePartPointer = 0; | |
626 DWORD value = ::SearchPathW(path, fileName, extension, | |
627 MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer); | |
628 filePart = (UINT32)(filePartPointer - (LPCWSTR)resultPath); | |
629 resultPath.ReleaseBuffer(); | |
630 return (value > 0 && value <= MAX_PATH); | |
631 } | |
632 | |
633 CSysString sysPath; | |
634 if (!MySearchPath( | |
635 path != 0 ? (LPCTSTR)GetSysPath(path): 0, | |
636 fileName != 0 ? (LPCTSTR)GetSysPath(fileName): 0, | |
637 extension != 0 ? (LPCTSTR)GetSysPath(extension): 0, | |
638 sysPath, filePart)) | |
639 return false; | |
640 UString resultPath1 = GetUnicodePath(sysPath.Left(filePart)); | |
641 UString resultPath2 = GetUnicodePath(sysPath.Mid(filePart)); | |
642 filePart = resultPath1.Length(); | |
643 resultPath = resultPath1 + resultPath2; | |
644 return true; | |
645 } | |
646 #endif | |
647 | |
648 bool MyGetTempPath(CSysString &path) | |
649 { | |
650 DWORD needLength = ::GetTempPath(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1)); | |
651 path.ReleaseBuffer(); | |
652 return (needLength > 0 && needLength <= MAX_PATH); | |
653 } | |
654 | |
655 #ifndef _UNICODE | |
656 bool MyGetTempPath(UString &path) | |
657 { | |
658 path.Empty(); | |
659 if (g_IsNT) | |
660 { | |
661 DWORD needLength = ::GetTempPathW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1)); | |
662 path.ReleaseBuffer(); | |
663 return (needLength > 0 && needLength <= MAX_PATH); | |
664 } | |
665 CSysString sysPath; | |
666 if (!MyGetTempPath(sysPath)) | |
667 return false; | |
668 path = GetUnicodePath(sysPath); | |
669 return true; | |
670 } | |
671 #endif | |
672 | |
673 UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &path) | |
674 { | |
675 UINT number = ::GetTempFileName(dirPath, prefix, 0, path.GetBuffer(MAX_PATH + 1)); | |
676 path.ReleaseBuffer(); | |
677 return number; | |
678 } | |
679 | |
680 #ifndef _UNICODE | |
681 UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &path) | |
682 { | |
683 if (g_IsNT) | |
684 { | |
685 UINT number = ::GetTempFileNameW(dirPath, prefix, 0, path.GetBuffer(MAX_PATH)); | |
686 path.ReleaseBuffer(); | |
687 return number; | |
688 } | |
689 CSysString sysPath; | |
690 UINT number = MyGetTempFileName( | |
691 dirPath ? (LPCTSTR)GetSysPath(dirPath): 0, | |
692 prefix ? (LPCTSTR)GetSysPath(prefix): 0, | |
693 sysPath); | |
694 path = GetUnicodePath(sysPath); | |
695 return number; | |
696 } | |
697 #endif | |
698 | |
699 UINT CTempFile::Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath) | |
700 { | |
701 Remove(); | |
702 UINT number = MyGetTempFileName(dirPath, prefix, resultPath); | |
703 if (number != 0) | |
704 { | |
705 _fileName = resultPath; | |
706 _mustBeDeleted = true; | |
707 } | |
708 return number; | |
709 } | |
710 | |
711 bool CTempFile::Create(LPCTSTR prefix, CSysString &resultPath) | |
712 { | |
713 CSysString tempPath; | |
714 if (!MyGetTempPath(tempPath)) | |
715 return false; | |
716 if (Create(tempPath, prefix, resultPath) != 0) | |
717 return true; | |
718 if (!MyGetWindowsDirectory(tempPath)) | |
719 return false; | |
720 return (Create(tempPath, prefix, resultPath) != 0); | |
721 } | |
722 | |
723 bool CTempFile::Remove() | |
724 { | |
725 if (!_mustBeDeleted) | |
726 return true; | |
727 _mustBeDeleted = !DeleteFileAlways(_fileName); | |
728 return !_mustBeDeleted; | |
729 } | |
730 | |
731 #ifndef _UNICODE | |
732 | |
733 UINT CTempFileW::Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath) | |
734 { | |
735 Remove(); | |
736 UINT number = MyGetTempFileName(dirPath, prefix, resultPath); | |
737 if (number != 0) | |
738 { | |
739 _fileName = resultPath; | |
740 _mustBeDeleted = true; | |
741 } | |
742 return number; | |
743 } | |
744 | |
745 bool CTempFileW::Create(LPCWSTR prefix, UString &resultPath) | |
746 { | |
747 UString tempPath; | |
748 if (!MyGetTempPath(tempPath)) | |
749 return false; | |
750 if (Create(tempPath, prefix, resultPath) != 0) | |
751 return true; | |
752 if (!MyGetWindowsDirectory(tempPath)) | |
753 return false; | |
754 return (Create(tempPath, prefix, resultPath) != 0); | |
755 } | |
756 | |
757 bool CTempFileW::Remove() | |
758 { | |
759 if (!_mustBeDeleted) | |
760 return true; | |
761 _mustBeDeleted = !DeleteFileAlways(_fileName); | |
762 return !_mustBeDeleted; | |
763 } | |
764 | |
765 #endif | |
766 | |
767 bool CreateTempDirectory(LPCTSTR prefix, CSysString &dirName) | |
768 { | |
769 /* | |
770 CSysString prefix = tempPath + prefixChars; | |
771 CRandom random; | |
772 random.Init(); | |
773 */ | |
774 for (;;) | |
775 { | |
776 CTempFile tempFile; | |
777 if (!tempFile.Create(prefix, dirName)) | |
778 return false; | |
779 if (!::DeleteFile(dirName)) | |
780 return false; | |
781 /* | |
782 UINT32 randomNumber = random.Generate(); | |
783 TCHAR randomNumberString[32]; | |
784 _stprintf(randomNumberString, _T("%04X"), randomNumber); | |
785 dirName = prefix + randomNumberString; | |
786 */ | |
787 if (NFind::DoesFileExist(dirName)) | |
788 continue; | |
789 if (MyCreateDirectory(dirName)) | |
790 return true; | |
791 if (::GetLastError() != ERROR_ALREADY_EXISTS) | |
792 return false; | |
793 } | |
794 } | |
795 | |
796 bool CTempDirectory::Create(LPCTSTR prefix) | |
797 { | |
798 Remove(); | |
799 return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir)); | |
800 } | |
801 | |
802 #ifndef _UNICODE | |
803 | |
804 bool CreateTempDirectory(LPCWSTR prefix, UString &dirName) | |
805 { | |
806 /* | |
807 CSysString prefix = tempPath + prefixChars; | |
808 CRandom random; | |
809 random.Init(); | |
810 */ | |
811 for (;;) | |
812 { | |
813 CTempFileW tempFile; | |
814 if (!tempFile.Create(prefix, dirName)) | |
815 return false; | |
816 if (!DeleteFileAlways(dirName)) | |
817 return false; | |
818 /* | |
819 UINT32 randomNumber = random.Generate(); | |
820 TCHAR randomNumberString[32]; | |
821 _stprintf(randomNumberString, _T("%04X"), randomNumber); | |
822 dirName = prefix + randomNumberString; | |
823 */ | |
824 if (NFind::DoesFileExist(dirName)) | |
825 continue; | |
826 if (MyCreateDirectory(dirName)) | |
827 return true; | |
828 if (::GetLastError() != ERROR_ALREADY_EXISTS) | |
829 return false; | |
830 } | |
831 } | |
832 | |
833 bool CTempDirectoryW::Create(LPCWSTR prefix) | |
834 { | |
835 Remove(); | |
836 return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir)); | |
837 } | |
838 | |
839 #endif | |
840 | |
841 }}} |