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

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:189d17ce42c5
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 namespace NDirectory {
20
21 #ifndef _UNICODE
22 static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
23 static UString GetUnicodePath(const CSysString &sysPath)
24 { return MultiByteToUnicodeString(sysPath, GetCurrentCodePage()); }
25 static CSysString GetSysPath(LPCWSTR sysPath)
26 { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); }
27 #endif
28
29 bool MyGetWindowsDirectory(CSysString &path)
30 {
31 UINT needLength = ::GetWindowsDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
32 path.ReleaseBuffer();
33 return (needLength > 0 && needLength <= MAX_PATH);
34 }
35
36 bool MyGetSystemDirectory(CSysString &path)
37 {
38 UINT needLength = ::GetSystemDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
39 path.ReleaseBuffer();
40 return (needLength > 0 && needLength <= MAX_PATH);
41 }
42
43 #ifndef _UNICODE
44 bool MyGetWindowsDirectory(UString &path)
45 {
46 if (g_IsNT)
47 {
48 UINT needLength = ::GetWindowsDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
49 path.ReleaseBuffer();
50 return (needLength > 0 && needLength <= MAX_PATH);
51 }
52 CSysString sysPath;
53 if (!MyGetWindowsDirectory(sysPath))
54 return false;
55 path = GetUnicodePath(sysPath);
56 return true;
57 }
58
59 bool MyGetSystemDirectory(UString &path)
60 {
61 if (g_IsNT)
62 {
63 UINT needLength = ::GetSystemDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
64 path.ReleaseBuffer();
65 return (needLength > 0 && needLength <= MAX_PATH);
66 }
67 CSysString sysPath;
68 if (!MyGetSystemDirectory(sysPath))
69 return false;
70 path = GetUnicodePath(sysPath);
71 return true;
72 }
73 #endif
74
75 #ifndef _UNICODE
76 bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes)
77 {
78 if (g_IsNT)
79 return BOOLToBool(::SetFileAttributesW(fileName, fileAttributes));
80 return MySetFileAttributes(GetSysPath(fileName), fileAttributes);
81 }
82
83 bool MyRemoveDirectory(LPCWSTR pathName)
84 {
85 if (g_IsNT)
86 return BOOLToBool(::RemoveDirectoryW(pathName));
87 return MyRemoveDirectory(GetSysPath(pathName));
88 }
89
90 bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName)
91 {
92 if (g_IsNT)
93 return BOOLToBool(::MoveFileW(existFileName, newFileName));
94 return MyMoveFile(GetSysPath(existFileName), GetSysPath(newFileName));
95 }
96 #endif
97
98 bool MyCreateDirectory(LPCTSTR pathName) { return BOOLToBool(::CreateDirectory(pathName, NULL)); }
99
100 #ifndef _UNICODE
101 bool MyCreateDirectory(LPCWSTR pathName)
102 {
103 if (g_IsNT)
104 return BOOLToBool(::CreateDirectoryW(pathName, NULL));
105 return MyCreateDirectory(GetSysPath(pathName));
106 }
107 #endif
108
109 /*
110 bool CreateComplexDirectory(LPCTSTR pathName)
111 {
112 NName::CParsedPath path;
113 path.ParsePath(pathName);
114 CSysString fullPath = path.Prefix;
115 DWORD errorCode = ERROR_SUCCESS;
116 for(int i = 0; i < path.PathParts.Size(); i++)
117 {
118 const CSysString &string = path.PathParts[i];
119 if(string.IsEmpty())
120 {
121 if(i != path.PathParts.Size() - 1)
122 return false;
123 return true;
124 }
125 fullPath += path.PathParts[i];
126 if(!MyCreateDirectory(fullPath))
127 {
128 DWORD errorCode = GetLastError();
129 if(errorCode != ERROR_ALREADY_EXISTS)
130 return false;
131 }
132 fullPath += NName::kDirDelimiter;
133 }
134 return true;
135 }
136 */
137
138 bool CreateComplexDirectory(LPCTSTR _aPathName)
139 {
140 CSysString pathName = _aPathName;
141 int pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
142 if (pos > 0 && pos == pathName.Length() - 1)
143 {
144 if (pathName.Length() == 3 && pathName[1] == ':')
145 return true; // Disk folder;
146 pathName.Delete(pos);
147 }
148 CSysString pathName2 = pathName;
149 pos = pathName.Length();
150 while(true)
151 {
152 if(MyCreateDirectory(pathName))
153 break;
154 if(::GetLastError() == ERROR_ALREADY_EXISTS)
155 {
156 NFind::CFileInfo fileInfo;
157 if (!NFind::FindFile(pathName, fileInfo)) // For network folders
158 return true;
159 if (!fileInfo.IsDirectory())
160 return false;
161 break;
162 }
163 pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
164 if (pos < 0 || pos == 0)
165 return false;
166 if (pathName[pos - 1] == ':')
167 return false;
168 pathName = pathName.Left(pos);
169 }
170 pathName = pathName2;
171 while(pos < pathName.Length())
172 {
173 pos = pathName.Find(TEXT(CHAR_PATH_SEPARATOR), pos + 1);
174 if (pos < 0)
175 pos = pathName.Length();
176 if(!MyCreateDirectory(pathName.Left(pos)))
177 return false;
178 }
179 return true;
180 }
181
182 #ifndef _UNICODE
183
184 bool CreateComplexDirectory(LPCWSTR _aPathName)
185 {
186 UString pathName = _aPathName;
187 int pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
188 if (pos > 0 && pos == pathName.Length() - 1)
189 {
190 if (pathName.Length() == 3 && pathName[1] == L':')
191 return true; // Disk folder;
192 pathName.Delete(pos);
193 }
194 UString pathName2 = pathName;
195 pos = pathName.Length();
196 while(true)
197 {
198 if(MyCreateDirectory(pathName))
199 break;
200 if(::GetLastError() == ERROR_ALREADY_EXISTS)
201 {
202 NFind::CFileInfoW fileInfo;
203 if (!NFind::FindFile(pathName, fileInfo)) // For network folders
204 return true;
205 if (!fileInfo.IsDirectory())
206 return false;
207 break;
208 }
209 pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
210 if (pos < 0 || pos == 0)
211 return false;
212 if (pathName[pos - 1] == L':')
213 return false;
214 pathName = pathName.Left(pos);
215 }
216 pathName = pathName2;
217 while(pos < pathName.Length())
218 {
219 pos = pathName.Find(WCHAR_PATH_SEPARATOR, pos + 1);
220 if (pos < 0)
221 pos = pathName.Length();
222 if(!MyCreateDirectory(pathName.Left(pos)))
223 return false;
224 }
225 return true;
226 }
227
228 #endif
229
230 bool DeleteFileAlways(LPCTSTR name)
231 {
232 if(!::SetFileAttributes(name, 0))
233 return false;
234 return BOOLToBool(::DeleteFile(name));
235 }
236
237 #ifndef _UNICODE
238 bool DeleteFileAlways(LPCWSTR name)
239 {
240 if (g_IsNT)
241 {
242 if(!MySetFileAttributes(name, 0))
243 return false;
244 return BOOLToBool(::DeleteFileW(name));
245 }
246 return DeleteFileAlways(GetSysPath(name));
247 }
248 #endif
249
250 static bool RemoveDirectorySubItems2(const CSysString pathPrefix, const NFind::CFileInfo &fileInfo)
251 {
252 if(fileInfo.IsDirectory())
253 return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
254 else
255 return DeleteFileAlways(pathPrefix + fileInfo.Name);
256 }
257
258 bool RemoveDirectoryWithSubItems(const CSysString &path)
259 {
260 NFind::CFileInfo fileInfo;
261 CSysString pathPrefix = path + NName::kDirDelimiter;
262 {
263 NFind::CEnumerator enumerator(pathPrefix + TCHAR(NName::kAnyStringWildcard));
264 while(enumerator.Next(fileInfo))
265 if(!RemoveDirectorySubItems2(pathPrefix, fileInfo))
266 return false;
267 }
268 if(!BOOLToBool(::SetFileAttributes(path, 0)))
269 return false;
270 return BOOLToBool(::RemoveDirectory(path));
271 }
272
273 #ifndef _UNICODE
274 static bool RemoveDirectorySubItems2(const UString pathPrefix, const NFind::CFileInfoW &fileInfo)
275 {
276 if(fileInfo.IsDirectory())
277 return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
278 else
279 return DeleteFileAlways(pathPrefix + fileInfo.Name);
280 }
281 bool RemoveDirectoryWithSubItems(const UString &path)
282 {
283 NFind::CFileInfoW fileInfo;
284 UString pathPrefix = path + UString(NName::kDirDelimiter);
285 {
286 NFind::CEnumeratorW enumerator(pathPrefix + UString(NName::kAnyStringWildcard));
287 while(enumerator.Next(fileInfo))
288 if(!RemoveDirectorySubItems2(pathPrefix, fileInfo))
289 return false;
290 }
291 if(!MySetFileAttributes(path, 0))
292 return false;
293 return MyRemoveDirectory(path);
294 }
295 #endif
296
297 #ifndef _WIN32_WCE
298
299 bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath)
300 {
301 DWORD needLength = ::GetShortPathName(longPath, shortPath.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
302 shortPath.ReleaseBuffer();
303 return (needLength > 0 && needLength < MAX_PATH);
304 }
305
306 bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex)
307 {
308 resultPath.Empty();
309 LPTSTR fileNamePointer = 0;
310 LPTSTR buffer = resultPath.GetBuffer(MAX_PATH);
311 DWORD needLength = ::GetFullPathName(fileName, MAX_PATH + 1, buffer, &fileNamePointer);
312 resultPath.ReleaseBuffer();
313 if (needLength == 0 || needLength >= MAX_PATH)
314 return false;
315 if (fileNamePointer == 0)
316 fileNamePartStartIndex = lstrlen(fileName);
317 else
318 fileNamePartStartIndex = (int)(fileNamePointer - buffer);
319 return true;
320 }
321
322 #ifndef _UNICODE
323 bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex)
324 {
325 resultPath.Empty();
326 if (g_IsNT)
327 {
328 LPWSTR fileNamePointer = 0;
329 LPWSTR buffer = resultPath.GetBuffer(MAX_PATH);
330 DWORD needLength = ::GetFullPathNameW(fileName, MAX_PATH + 1, buffer, &fileNamePointer);
331 resultPath.ReleaseBuffer();
332 if (needLength == 0 || needLength >= MAX_PATH)
333 return false;
334 if (fileNamePointer == 0)
335 fileNamePartStartIndex = MyStringLen(fileName);
336 else
337 fileNamePartStartIndex = (int)(fileNamePointer - buffer);
338 }
339 else
340 {
341 CSysString sysPath;
342 if (!MyGetFullPathName(GetSysPath(fileName), sysPath, fileNamePartStartIndex))
343 return false;
344 UString resultPath1 = GetUnicodePath(sysPath.Left(fileNamePartStartIndex));
345 UString resultPath2 = GetUnicodePath(sysPath.Mid(fileNamePartStartIndex));
346 fileNamePartStartIndex = resultPath1.Length();
347 resultPath = resultPath1 + resultPath2;
348 }
349 return true;
350 }
351 #endif
352
353
354 bool MyGetFullPathName(LPCTSTR fileName, CSysString &path)
355 {
356 int index;
357 return MyGetFullPathName(fileName, path, index);
358 }
359
360 #ifndef _UNICODE
361 bool MyGetFullPathName(LPCWSTR fileName, UString &path)
362 {
363 int index;
364 return MyGetFullPathName(fileName, path, index);
365 }
366 #endif
367
368 bool GetOnlyName(LPCTSTR fileName, CSysString &resultName)
369 {
370 int index;
371 if (!MyGetFullPathName(fileName, resultName, index))
372 return false;
373 resultName = resultName.Mid(index);
374 return true;
375 }
376
377 #ifndef _UNICODE
378 bool GetOnlyName(LPCWSTR fileName, UString &resultName)
379 {
380 int index;
381 if (!MyGetFullPathName(fileName, resultName, index))
382 return false;
383 resultName = resultName.Mid(index);
384 return true;
385 }
386 #endif
387
388 bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName)
389 {
390 int index;
391 if (!MyGetFullPathName(fileName, resultName, index))
392 return false;
393 resultName = resultName.Left(index);
394 return true;
395 }
396
397 #ifndef _UNICODE
398 bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName)
399 {
400 int index;
401 if (!MyGetFullPathName(fileName, resultName, index))
402 return false;
403 resultName = resultName.Left(index);
404 return true;
405 }
406 #endif
407
408 bool MyGetCurrentDirectory(CSysString &path)
409 {
410 DWORD needLength = ::GetCurrentDirectory(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
411 path.ReleaseBuffer();
412 return (needLength > 0 && needLength <= MAX_PATH);
413 }
414
415 #ifndef _UNICODE
416 bool MySetCurrentDirectory(LPCWSTR path)
417 {
418 if (g_IsNT)
419 return BOOLToBool(::SetCurrentDirectoryW(path));
420 return MySetCurrentDirectory(GetSysPath(path));
421 }
422 bool MyGetCurrentDirectory(UString &path)
423 {
424 if (g_IsNT)
425 {
426 DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
427 path.ReleaseBuffer();
428 return (needLength > 0 && needLength <= MAX_PATH);
429 }
430 CSysString sysPath;
431 if (!MyGetCurrentDirectory(sysPath))
432 return false;
433 path = GetUnicodePath(sysPath);
434 return true;
435 }
436 #endif
437 #endif
438
439 bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension,
440 CSysString &resultPath, UINT32 &filePart)
441 {
442 LPTSTR filePartPointer;
443 DWORD value = ::SearchPath(path, fileName, extension,
444 MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);
445 filePart = (UINT32)(filePartPointer - (LPCTSTR)resultPath);
446 resultPath.ReleaseBuffer();
447 return (value > 0 && value <= MAX_PATH);
448 }
449
450 #ifndef _UNICODE
451 bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension,
452 UString &resultPath, UINT32 &filePart)
453 {
454 if (g_IsNT)
455 {
456 LPWSTR filePartPointer = 0;
457 DWORD value = ::SearchPathW(path, fileName, extension,
458 MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);
459 filePart = (UINT32)(filePartPointer - (LPCWSTR)resultPath);
460 resultPath.ReleaseBuffer();
461 return (value > 0 && value <= MAX_PATH);
462 }
463
464 CSysString sysPath;
465 if (!MySearchPath(
466 path != 0 ? (LPCTSTR)GetSysPath(path): 0,
467 fileName != 0 ? (LPCTSTR)GetSysPath(fileName): 0,
468 extension != 0 ? (LPCTSTR)GetSysPath(extension): 0,
469 sysPath, filePart))
470 return false;
471 UString resultPath1 = GetUnicodePath(sysPath.Left(filePart));
472 UString resultPath2 = GetUnicodePath(sysPath.Mid(filePart));
473 filePart = resultPath1.Length();
474 resultPath = resultPath1 + resultPath2;
475 return true;
476 }
477 #endif
478
479 bool MyGetTempPath(CSysString &path)
480 {
481 DWORD needLength = ::GetTempPath(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
482 path.ReleaseBuffer();
483 return (needLength > 0 && needLength <= MAX_PATH);
484 }
485
486 #ifndef _UNICODE
487 bool MyGetTempPath(UString &path)
488 {
489 path.Empty();
490 if (g_IsNT)
491 {
492 DWORD needLength = ::GetTempPathW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
493 path.ReleaseBuffer();
494 return (needLength > 0 && needLength <= MAX_PATH);
495 }
496 CSysString sysPath;
497 if (!MyGetTempPath(sysPath))
498 return false;
499 path = GetUnicodePath(sysPath);
500 return true;
501 }
502 #endif
503
504 UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &path)
505 {
506 UINT number = ::GetTempFileName(dirPath, prefix, 0, path.GetBuffer(MAX_PATH + 1));
507 path.ReleaseBuffer();
508 return number;
509 }
510
511 #ifndef _UNICODE
512 UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &path)
513 {
514 if (g_IsNT)
515 {
516 UINT number = ::GetTempFileNameW(dirPath, prefix, 0, path.GetBuffer(MAX_PATH));
517 path.ReleaseBuffer();
518 return number;
519 }
520 CSysString sysPath;
521 UINT number = MyGetTempFileName(
522 dirPath ? (LPCTSTR)GetSysPath(dirPath): 0,
523 prefix ? (LPCTSTR)GetSysPath(prefix): 0,
524 sysPath);
525 path = GetUnicodePath(sysPath);
526 return number;
527 }
528 #endif
529
530 UINT CTempFile::Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath)
531 {
532 Remove();
533 UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
534 if(number != 0)
535 {
536 _fileName = resultPath;
537 _mustBeDeleted = true;
538 }
539 return number;
540 }
541
542 bool CTempFile::Create(LPCTSTR prefix, CSysString &resultPath)
543 {
544 CSysString tempPath;
545 if(!MyGetTempPath(tempPath))
546 return false;
547 if (Create(tempPath, prefix, resultPath) != 0)
548 return true;
549 if(!MyGetWindowsDirectory(tempPath))
550 return false;
551 return (Create(tempPath, prefix, resultPath) != 0);
552 }
553
554 bool CTempFile::Remove()
555 {
556 if (!_mustBeDeleted)
557 return true;
558 _mustBeDeleted = !DeleteFileAlways(_fileName);
559 return !_mustBeDeleted;
560 }
561
562 #ifndef _UNICODE
563
564 UINT CTempFileW::Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath)
565 {
566 Remove();
567 UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
568 if(number != 0)
569 {
570 _fileName = resultPath;
571 _mustBeDeleted = true;
572 }
573 return number;
574 }
575
576 bool CTempFileW::Create(LPCWSTR prefix, UString &resultPath)
577 {
578 UString tempPath;
579 if(!MyGetTempPath(tempPath))
580 return false;
581 if (Create(tempPath, prefix, resultPath) != 0)
582 return true;
583 if(!MyGetWindowsDirectory(tempPath))
584 return false;
585 return (Create(tempPath, prefix, resultPath) != 0);
586 }
587
588 bool CTempFileW::Remove()
589 {
590 if (!_mustBeDeleted)
591 return true;
592 _mustBeDeleted = !DeleteFileAlways(_fileName);
593 return !_mustBeDeleted;
594 }
595
596 #endif
597
598 bool CreateTempDirectory(LPCTSTR prefix, CSysString &dirName)
599 {
600 /*
601 CSysString prefix = tempPath + prefixChars;
602 CRandom random;
603 random.Init();
604 */
605 while(true)
606 {
607 CTempFile tempFile;
608 if (!tempFile.Create(prefix, dirName))
609 return false;
610 if (!::DeleteFile(dirName))
611 return false;
612 /*
613 UINT32 randomNumber = random.Generate();
614 TCHAR randomNumberString[32];
615 _stprintf(randomNumberString, _T("%04X"), randomNumber);
616 dirName = prefix + randomNumberString;
617 */
618 if(NFind::DoesFileExist(dirName))
619 continue;
620 if (MyCreateDirectory(dirName))
621 return true;
622 if (::GetLastError() != ERROR_ALREADY_EXISTS)
623 return false;
624 }
625 }
626
627 bool CTempDirectory::Create(LPCTSTR prefix)
628 {
629 Remove();
630 return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
631 }
632
633 #ifndef _UNICODE
634
635 bool CreateTempDirectory(LPCWSTR prefix, UString &dirName)
636 {
637 /*
638 CSysString prefix = tempPath + prefixChars;
639 CRandom random;
640 random.Init();
641 */
642 while(true)
643 {
644 CTempFileW tempFile;
645 if (!tempFile.Create(prefix, dirName))
646 return false;
647 if (!DeleteFileAlways(dirName))
648 return false;
649 /*
650 UINT32 randomNumber = random.Generate();
651 TCHAR randomNumberString[32];
652 _stprintf(randomNumberString, _T("%04X"), randomNumber);
653 dirName = prefix + randomNumberString;
654 */
655 if(NFind::DoesFileExist(dirName))
656 continue;
657 if (MyCreateDirectory(dirName))
658 return true;
659 if (::GetLastError() != ERROR_ALREADY_EXISTS)
660 return false;
661 }
662 }
663
664 bool CTempDirectoryW::Create(LPCWSTR prefix)
665 {
666 Remove();
667 return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
668 }
669
670 #endif
671
672 }}}

mercurial