From 6a23c2f3b766cf4fc7028628f76b5ff9396383f0 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 11 Jan 2015 08:10:25 +0100 Subject: Added full lzma sdk source (nw) --- 3rdparty/lzma/CPP/Windows/FileDir.cpp | 587 ++++++++++++++++++++++++++++++++++ 1 file changed, 587 insertions(+) create mode 100644 3rdparty/lzma/CPP/Windows/FileDir.cpp (limited to '3rdparty/lzma/CPP/Windows/FileDir.cpp') diff --git a/3rdparty/lzma/CPP/Windows/FileDir.cpp b/3rdparty/lzma/CPP/Windows/FileDir.cpp new file mode 100644 index 00000000000..88215faa2ad --- /dev/null +++ b/3rdparty/lzma/CPP/Windows/FileDir.cpp @@ -0,0 +1,587 @@ +// Windows/FileDir.cpp + +#include "StdAfx.h" + +#ifndef _UNICODE +#include "../Common/StringConvert.h" +#endif + +#include "FileDir.h" +#include "FileFind.h" +#include "FileName.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { +namespace NFile { + +// SetCurrentDirectory doesn't support \\?\ prefix + +#ifdef WIN_LONG_PATH +bool GetLongPathBase(CFSTR fileName, UString &res); +bool GetLongPath(CFSTR fileName, UString &res); +#endif + +namespace NDirectory { + +#ifndef UNDER_CE + +bool MyGetWindowsDirectory(FString &path) +{ + UINT needLength; + #ifndef _UNICODE + if (!g_IsNT) + { + TCHAR s[MAX_PATH + 2]; + s[0] = 0; + needLength = ::GetWindowsDirectory(s, MAX_PATH + 1); + path = fas2fs(s); + } + else + #endif + { + WCHAR s[MAX_PATH + 2]; + s[0] = 0; + needLength = ::GetWindowsDirectoryW(s, MAX_PATH + 1); + path = us2fs(s); + } + return (needLength > 0 && needLength <= MAX_PATH); +} + + +bool MyGetSystemDirectory(FString &path) +{ + UINT needLength; + #ifndef _UNICODE + if (!g_IsNT) + { + TCHAR s[MAX_PATH + 2]; + s[0] = 0; + needLength = ::GetSystemDirectory(s, MAX_PATH + 1); + path = fas2fs(s); + } + else + #endif + { + WCHAR s[MAX_PATH + 2]; + s[0] = 0; + needLength = ::GetSystemDirectoryW(s, MAX_PATH + 1); + path = us2fs(s); + } + return (needLength > 0 && needLength <= MAX_PATH); +} +#endif + +bool SetDirTime(CFSTR fileName, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return false; + } + #endif + HANDLE hDir = ::CreateFileW(fs2us(fileName), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + #ifdef WIN_LONG_PATH + if (hDir == INVALID_HANDLE_VALUE) + { + UString longPath; + if (GetLongPath(fileName, longPath)) + hDir = ::CreateFileW(longPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + } + #endif + + bool res = false; + if (hDir != INVALID_HANDLE_VALUE) + { + res = BOOLToBool(::SetFileTime(hDir, cTime, aTime, mTime)); + ::CloseHandle(hDir); + } + return res; +} + +#ifdef WIN_LONG_PATH +bool GetLongPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2) +{ + if (!GetLongPathBase(s1, d1) || + !GetLongPathBase(s2, d2)) + return false; + if (d1.IsEmpty() && d2.IsEmpty()) + return false; + if (d1.IsEmpty()) d1 = fs2us(s1); + if (d2.IsEmpty()) d2 = fs2us(s2); + return true; +} +#endif + +bool MySetFileAttributes(CFSTR fileName, DWORD fileAttributes) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + if (::SetFileAttributes(fs2fas(fileName), fileAttributes)) + return true; + } + else + #endif + { + if (::SetFileAttributesW(fs2us(fileName), fileAttributes)) + return true; + #ifdef WIN_LONG_PATH + UString longPath; + if (GetLongPath(fileName, longPath)) + return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes)); + #endif + } + return false; +} + +bool MyRemoveDirectory(CFSTR path) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + if (::RemoveDirectory(fs2fas(path))) + return true; + } + else + #endif + { + if (::RemoveDirectoryW(fs2us(path))) + return true; + #ifdef WIN_LONG_PATH + UString longPath; + if (GetLongPath(path, longPath)) + return BOOLToBool(::RemoveDirectoryW(longPath)); + #endif + } + return false; +} + +bool MyMoveFile(CFSTR existFileName, CFSTR newFileName) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + if (::MoveFile(fs2fas(existFileName), fs2fas(newFileName))) + return true; + } + else + #endif + { + if (::MoveFileW(fs2us(existFileName), fs2us(newFileName))) + return true; + #ifdef WIN_LONG_PATH + UString d1, d2; + if (GetLongPaths(existFileName, newFileName, d1, d2)) + return BOOLToBool(::MoveFileW(d1, d2)); + #endif + } + return false; +} + +bool MyCreateDirectory(CFSTR path) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + if (::CreateDirectory(fs2fas(path), NULL)) + return true; + } + else + #endif + { + if (::CreateDirectoryW(fs2us(path), NULL)) + return true; + #ifdef WIN_LONG_PATH + if (::GetLastError() != ERROR_ALREADY_EXISTS) + { + UString longPath; + if (GetLongPath(path, longPath)) + return BOOLToBool(::CreateDirectoryW(longPath, NULL)); + } + #endif + } + return false; +} + +bool CreateComplexDirectory(CFSTR _aPathName) +{ + FString pathName = _aPathName; + int pos = pathName.ReverseFind(FCHAR_PATH_SEPARATOR); + if (pos > 0 && pos == pathName.Length() - 1) + { + if (pathName.Length() == 3 && pathName[1] == L':') + return true; // Disk folder; + pathName.Delete(pos); + } + FString pathName2 = pathName; + pos = pathName.Length(); + for (;;) + { + if (MyCreateDirectory(pathName)) + break; + if (::GetLastError() == ERROR_ALREADY_EXISTS) + { + NFind::CFileInfo fileInfo; + if (!fileInfo.Find(pathName)) // For network folders + return true; + if (!fileInfo.IsDir()) + return false; + break; + } + pos = pathName.ReverseFind(FCHAR_PATH_SEPARATOR); + if (pos < 0 || pos == 0) + return false; + if (pathName[pos - 1] == L':') + return false; + pathName = pathName.Left(pos); + } + pathName = pathName2; + while (pos < pathName.Length()) + { + pos = pathName.Find(FCHAR_PATH_SEPARATOR, pos + 1); + if (pos < 0) + pos = pathName.Length(); + if (!MyCreateDirectory(pathName.Left(pos))) + return false; + } + return true; +} + +bool DeleteFileAlways(CFSTR name) +{ + if (!MySetFileAttributes(name, 0)) + return false; + #ifndef _UNICODE + if (!g_IsNT) + { + if (::DeleteFile(fs2fas(name))) + return true; + } + else + #endif + { + if (::DeleteFileW(fs2us(name))) + return true; + #ifdef WIN_LONG_PATH + UString longPath; + if (GetLongPath(name, longPath)) + return BOOLToBool(::DeleteFileW(longPath)); + #endif + } + return false; +} + +static bool RemoveDirectorySubItems2(const FString pathPrefix, const NFind::CFileInfo &fileInfo) +{ + if (fileInfo.IsDir()) + return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name); + return DeleteFileAlways(pathPrefix + fileInfo.Name); +} +bool RemoveDirectoryWithSubItems(const FString &path) +{ + NFind::CFileInfo fileInfo; + FString pathPrefix = path + FCHAR_PATH_SEPARATOR; + { + NFind::CEnumerator enumerator(pathPrefix + FCHAR_ANY_MASK); + while (enumerator.Next(fileInfo)) + if (!RemoveDirectorySubItems2(pathPrefix, fileInfo)) + return false; + } + if (!MySetFileAttributes(path, 0)) + return false; + return MyRemoveDirectory(path); +} + +#ifdef UNDER_CE + +bool MyGetFullPathName(CFSTR fileName, FString &resFullPath) +{ + resFullPath = fileName; + return true; +} + +#else + +#ifdef WIN_LONG_PATH + +static FString GetLastPart(CFSTR path) +{ + int i = MyStringLen(path); + for (; i > 0; i--) + { + FChar c = path[i - 1]; + if (c == FCHAR_PATH_SEPARATOR || c == '/') + break; + } + return path + i; +} + +static void AddTrailingDots(CFSTR oldPath, FString &newPath) +{ + int len = MyStringLen(oldPath); + int i; + for (i = len; i > 0 && oldPath[i - 1] == '.'; i--); + if (i == 0 || i == len) + return; + FString oldName = GetLastPart(oldPath); + FString newName = GetLastPart(newPath); + int nonDotsLen = oldName.Length() - (len - i); + if (nonDotsLen == 0 || newName.CompareNoCase(oldName.Left(nonDotsLen)) != 0) + return; + for (; i != len; i++) + newPath += '.'; +} + +#endif + +bool MyGetFullPathName(CFSTR fileName, FString &resFullPath) +{ + resFullPath.Empty(); + #ifndef _UNICODE + if (!g_IsNT) + { + TCHAR s[MAX_PATH + 2]; + s[0] = 0; + LPTSTR fileNamePointer = 0; + DWORD needLength = ::GetFullPathName(fs2fas(fileName), MAX_PATH + 1, s, &fileNamePointer); + if (needLength == 0 || needLength > MAX_PATH) + return false; + resFullPath = fas2fs(s); + return true; + } + else + #endif + { + LPWSTR fileNamePointer = 0; + WCHAR s[MAX_PATH + 2]; + s[0] = 0; + DWORD needLength = ::GetFullPathNameW(fs2us(fileName), MAX_PATH + 1, s, &fileNamePointer); + if (needLength == 0) + return false; + if (needLength <= MAX_PATH) + { + resFullPath = us2fs(s); + return true; + } + #ifdef WIN_LONG_PATH + needLength++; + UString temp; + LPWSTR buffer = temp.GetBuffer(needLength + 1); + buffer[0] = 0; + DWORD needLength2 = ::GetFullPathNameW(fs2us(fileName), needLength, buffer, &fileNamePointer); + temp.ReleaseBuffer(); + if (needLength2 > 0 && needLength2 <= needLength) + { + resFullPath = us2fs(temp); + AddTrailingDots(fileName, resFullPath); + return true; + } + #endif + return false; + } +} + +bool MySetCurrentDirectory(CFSTR path) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + return BOOLToBool(::SetCurrentDirectory(fs2fas(path))); + } + else + #endif + { + return BOOLToBool(::SetCurrentDirectoryW(fs2us(path))); + } +} + +bool MyGetCurrentDirectory(FString &path) +{ + path.Empty(); + DWORD needLength; + #ifndef _UNICODE + if (!g_IsNT) + { + TCHAR s[MAX_PATH + 2]; + s[0] = 0; + needLength = ::GetCurrentDirectory(MAX_PATH + 1, s); + path = fas2fs(s); + } + else + #endif + { + WCHAR s[MAX_PATH + 2]; + s[0] = 0; + needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, s); + path = us2fs(s); + } + return (needLength > 0 && needLength <= MAX_PATH); +} + +#endif + +bool GetFullPathAndSplit(CFSTR path, FString &resDirPrefix, FString &resFileName) +{ + bool res = MyGetFullPathName(path, resFileName); + if (!res) + resFileName = path; + int pos = resFileName.ReverseFind(FCHAR_PATH_SEPARATOR); + if (pos >= 0) + { + resDirPrefix = resFileName.Left(pos + 1); + resFileName = resFileName.Mid(pos + 1); + } + return res; +} + +bool GetOnlyDirPrefix(CFSTR path, FString &resDirPrefix) +{ + FString resFileName; + return GetFullPathAndSplit(path, resDirPrefix, resFileName); +} + +bool MyGetTempPath(FString &path) +{ + path.Empty(); + DWORD needLength; + #ifndef _UNICODE + if (!g_IsNT) + { + TCHAR s[MAX_PATH + 2]; + s[0] = 0; + needLength = ::GetTempPath(MAX_PATH + 1, s); + path = fas2fs(s); + } + else + #endif + { + WCHAR s[MAX_PATH + 2]; + s[0] = 0; + needLength = ::GetTempPathW(MAX_PATH + 1, s);; + path = us2fs(s); + } + return (needLength > 0 && needLength <= MAX_PATH); +} + +static bool CreateTempFile(CFSTR prefix, bool addRandom, FString &path, NIO::COutFile *outFile) +{ + UInt32 d = (GetTickCount() << 12) ^ (GetCurrentThreadId() << 14) ^ GetCurrentProcessId(); + for (unsigned i = 0; i < 100; i++) + { + path = prefix; + if (addRandom) + { + FChar s[16]; + UInt32 value = d; + unsigned k; + for (k = 0; k < 8; k++) + { + unsigned t = value & 0xF; + value >>= 4; + s[k] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10))); + } + s[k] = '\0'; + if (outFile) + path += FChar('.'); + path += s; + UInt32 step = GetTickCount() + 2; + if (step == 0) + step = 1; + d += step; + } + addRandom = true; + if (outFile) + path += FTEXT(".tmp"); + if (NFind::DoesFileOrDirExist(path)) + { + SetLastError(ERROR_ALREADY_EXISTS); + continue; + } + if (outFile) + { + if (outFile->Create(path, false)) + return true; + } + else + { + if (MyCreateDirectory(path)) + return true; + } + DWORD error = GetLastError(); + if (error != ERROR_FILE_EXISTS && + error != ERROR_ALREADY_EXISTS) + break; + } + path.Empty(); + return false; +} + +bool CTempFile::Create(CFSTR prefix, NIO::COutFile *outFile) +{ + if (!Remove()) + return false; + if (!CreateTempFile(prefix, false, _path, outFile)) + return false; + _mustBeDeleted = true; + return true; +} + +bool CTempFile::CreateRandomInTempFolder(CFSTR namePrefix, NIO::COutFile *outFile) +{ + if (!Remove()) + return false; + FString tempPath; + if (!MyGetTempPath(tempPath)) + return false; + if (!CreateTempFile(tempPath + namePrefix, true, _path, outFile)) + return false; + _mustBeDeleted = true; + return true; +} + +bool CTempFile::Remove() +{ + if (!_mustBeDeleted) + return true; + _mustBeDeleted = !DeleteFileAlways(_path); + return !_mustBeDeleted; +} + +bool CTempFile::MoveTo(CFSTR name, bool deleteDestBefore) +{ + if (deleteDestBefore) + if (NFind::DoesFileExist(name)) + if (!DeleteFileAlways(name)) + return false; + DisableDeleting(); + return MyMoveFile(_path, name); +} + +bool CTempDir::Create(CFSTR prefix) +{ + if (!Remove()) + return false; + FString tempPath; + if (!MyGetTempPath(tempPath)) + return false; + if (!CreateTempFile(tempPath + prefix, true, _path, NULL)) + return false; + _mustBeDeleted = true; + return true; +} + +bool CTempDir::Remove() +{ + if (!_mustBeDeleted) + return true; + _mustBeDeleted = !RemoveDirectoryWithSubItems(_path); + return !_mustBeDeleted; +} + +}}} -- cgit v1.2.3-70-g09d2