annotate src/win32/7zip/7z/CPP/Windows/FileDir.cpp @ 5:8fe0c57e53d2

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