summaryrefslogtreecommitdiffstats
path: root/src/libs/7zip/win/CPP/Windows
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/7zip/win/CPP/Windows')
-rw-r--r--src/libs/7zip/win/CPP/Windows/DLL.cpp130
-rw-r--r--src/libs/7zip/win/CPP/Windows/DLL.h25
-rw-r--r--src/libs/7zip/win/CPP/Windows/Error.cpp50
-rw-r--r--src/libs/7zip/win/CPP/Windows/Error.h33
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileDir.cpp1050
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileDir.h180
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileFind.cpp605
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileFind.h127
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileIO.cpp430
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileIO.h217
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileLink.cpp426
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileMapping.cpp12
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileMapping.h8
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileName.cpp675
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileName.h69
-rw-r--r--src/libs/7zip/win/CPP/Windows/MemoryLock.cpp82
-rw-r--r--src/libs/7zip/win/CPP/Windows/MemoryLock.h15
-rw-r--r--src/libs/7zip/win/CPP/Windows/NtCheck.h44
-rw-r--r--src/libs/7zip/win/CPP/Windows/PropVariant.cpp105
-rw-r--r--src/libs/7zip/win/CPP/Windows/PropVariant.h97
-rw-r--r--src/libs/7zip/win/CPP/Windows/PropVariantConv.cpp99
-rw-r--r--src/libs/7zip/win/CPP/Windows/PropVariantConv.h30
-rw-r--r--src/libs/7zip/win/CPP/Windows/PropVariantConversions.cpp105
-rw-r--r--src/libs/7zip/win/CPP/Windows/PropVariantConversions.h14
-rw-r--r--src/libs/7zip/win/CPP/Windows/Registry.cpp369
-rw-r--r--src/libs/7zip/win/CPP/Windows/Registry.h85
-rw-r--r--src/libs/7zip/win/CPP/Windows/SecurityUtils.cpp179
-rw-r--r--src/libs/7zip/win/CPP/Windows/SecurityUtils.h167
-rw-r--r--src/libs/7zip/win/CPP/Windows/StdAfx.h3
-rw-r--r--src/libs/7zip/win/CPP/Windows/System.h2
-rw-r--r--src/libs/7zip/win/CPP/Windows/Thread.h2
-rw-r--r--src/libs/7zip/win/CPP/Windows/Time.h21
-rw-r--r--src/libs/7zip/win/CPP/Windows/TimeUtils.cpp (renamed from src/libs/7zip/win/CPP/Windows/Time.cpp)63
-rw-r--r--src/libs/7zip/win/CPP/Windows/TimeUtils.h23
-rw-r--r--src/libs/7zip/win/CPP/Windows/Windows.pri29
35 files changed, 3143 insertions, 2428 deletions
diff --git a/src/libs/7zip/win/CPP/Windows/DLL.cpp b/src/libs/7zip/win/CPP/Windows/DLL.cpp
index 5afd72d9d..cf3dd1ceb 100644
--- a/src/libs/7zip/win/CPP/Windows/DLL.cpp
+++ b/src/libs/7zip/win/CPP/Windows/DLL.cpp
@@ -2,109 +2,109 @@
#include "StdAfx.h"
-#ifndef _UNICODE
-#include "../Common/StringConvert.h"
-#endif
-
#include "DLL.h"
#ifndef _UNICODE
extern bool g_IsNT;
#endif
+extern HINSTANCE g_hInstance;
+
namespace NWindows {
namespace NDLL {
-bool CLibrary::Free()
+bool CLibrary::Free() throw()
{
if (_module == 0)
return true;
- // MessageBox(0, TEXT(""), TEXT("Free"), 0);
- // Sleep(5000);
if (!::FreeLibrary(_module))
return false;
_module = 0;
return true;
}
-bool CLibrary::LoadOperations(HMODULE newModule)
+bool CLibrary::LoadEx(CFSTR path, DWORD flags) throw()
{
- if (newModule == NULL)
- return false;
if (!Free())
return false;
- _module = newModule;
- return true;
-}
-
-bool CLibrary::LoadEx(LPCTSTR fileName, DWORD flags)
-{
- // MessageBox(0, fileName, TEXT("LoadEx"), 0);
- return LoadOperations(::LoadLibraryEx(fileName, NULL, flags));
-}
-
-bool CLibrary::Load(LPCTSTR fileName)
-{
- // MessageBox(0, fileName, TEXT("Load"), 0);
- // Sleep(5000);
- // OutputDebugString(fileName);
- // OutputDebugString(TEXT("\n"));
- return LoadOperations(::LoadLibrary(fileName));
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ _module = ::LoadLibraryEx(fs2fas(path), NULL, flags);
+ }
+ else
+ #endif
+ {
+ _module = ::LoadLibraryExW(fs2us(path), NULL, flags);
+ }
+ return (_module != NULL);
}
-#ifndef _UNICODE
-static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
-CSysString GetSysPath(LPCWSTR sysPath)
- { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); }
-
-bool CLibrary::LoadEx(LPCWSTR fileName, DWORD flags)
+bool CLibrary::Load(CFSTR path) throw()
{
- if (g_IsNT)
- return LoadOperations(::LoadLibraryExW(fileName, NULL, flags));
- return LoadEx(GetSysPath(fileName), flags);
-}
-bool CLibrary::Load(LPCWSTR fileName)
-{
- if (g_IsNT)
- return LoadOperations(::LoadLibraryW(fileName));
- return Load(GetSysPath(fileName));
+ if (!Free())
+ return false;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ _module = ::LoadLibrary(fs2fas(path));
+ }
+ else
+ #endif
+ {
+ _module = ::LoadLibraryW(fs2us(path));
+ }
+ return (_module != NULL);
}
-#endif
-bool MyGetModuleFileName(HMODULE hModule, CSysString &result)
+bool MyGetModuleFileName(FString &path)
{
- result.Empty();
- TCHAR fullPath[MAX_PATH + 2];
- DWORD size = ::GetModuleFileName(hModule, fullPath, MAX_PATH + 1);
- if (size <= MAX_PATH && size != 0)
+ HMODULE hModule = g_hInstance;
+ path.Empty();
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- result = fullPath;
- return true;
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ DWORD size = ::GetModuleFileName(hModule, s, MAX_PATH + 1);
+ if (size <= MAX_PATH && size != 0)
+ {
+ path = fas2fs(s);
+ return true;
+ }
+ }
+ else
+ #endif
+ {
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ DWORD size = ::GetModuleFileNameW(hModule, s, MAX_PATH + 1);
+ if (size <= MAX_PATH && size != 0)
+ {
+ path = us2fs(s);
+ return true;
+ }
}
return false;
}
-#ifndef _UNICODE
-bool MyGetModuleFileName(HMODULE hModule, UString &result)
+#ifndef _SFX
+
+FString GetModuleDirPrefix()
{
- result.Empty();
- if (g_IsNT)
+ FString s;
+ if (MyGetModuleFileName(s))
{
- wchar_t fullPath[MAX_PATH + 2];
- DWORD size = ::GetModuleFileNameW(hModule, fullPath, MAX_PATH + 1);
- if (size <= MAX_PATH && size != 0)
+ int pos = s.ReverseFind(FCHAR_PATH_SEPARATOR);
+ if (pos >= 0)
{
- result = fullPath;
- return true;
+ s.DeleteFrom(pos + 1);
+ return s;
}
- return false;
}
- CSysString resultSys;
- if (!MyGetModuleFileName(hModule, resultSys))
- return false;
- result = MultiByteToUnicodeString(resultSys, GetCurrentCodePage());
- return true;
+ return FTEXT(".") FSTRING_PATH_SEPARATOR;
}
+
#endif
}}
diff --git a/src/libs/7zip/win/CPP/Windows/DLL.h b/src/libs/7zip/win/CPP/Windows/DLL.h
index 4a253b326..d8848ce95 100644
--- a/src/libs/7zip/win/CPP/Windows/DLL.h
+++ b/src/libs/7zip/win/CPP/Windows/DLL.h
@@ -9,15 +9,13 @@ namespace NWindows {
namespace NDLL {
#ifdef UNDER_CE
-#define My_GetProcAddress(module, proceName) GetProcAddressA(module, proceName)
+#define My_GetProcAddress(module, procName) ::GetProcAddressA(module, procName)
#else
-#define My_GetProcAddress(module, proceName) ::GetProcAddress(module, proceName)
+#define My_GetProcAddress(module, procName) ::GetProcAddress(module, procName)
#endif
-
+
class CLibrary
{
- bool LoadOperations(HMODULE newModule);
-protected:
HMODULE _module;
public:
CLibrary(): _module(NULL) {};
@@ -39,20 +37,15 @@ public:
return m;
}
- bool Free();
- bool LoadEx(LPCTSTR fileName, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);
- bool Load(LPCTSTR fileName);
- #ifndef _UNICODE
- bool LoadEx(LPCWSTR fileName, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);
- bool Load(LPCWSTR fileName);
- #endif
+ bool Free() throw();
+ bool LoadEx(CFSTR path, DWORD flags = LOAD_LIBRARY_AS_DATAFILE) throw();
+ bool Load(CFSTR path) throw();
FARPROC GetProc(LPCSTR procName) const { return My_GetProcAddress(_module, procName); }
};
-bool MyGetModuleFileName(HMODULE hModule, CSysString &result);
-#ifndef _UNICODE
-bool MyGetModuleFileName(HMODULE hModule, UString &result);
-#endif
+bool MyGetModuleFileName(FString &path);
+
+FString GetModuleDirPrefix();
}}
diff --git a/src/libs/7zip/win/CPP/Windows/Error.cpp b/src/libs/7zip/win/CPP/Windows/Error.cpp
deleted file mode 100644
index 7b18c29cc..000000000
--- a/src/libs/7zip/win/CPP/Windows/Error.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-// Windows/Error.h
-
-#include "StdAfx.h"
-
-#include "Windows/Error.h"
-#ifndef _UNICODE
-#include "Common/StringConvert.h"
-#endif
-
-#ifndef _UNICODE
-extern bool g_IsNT;
-#endif
-
-namespace NWindows {
-namespace NError {
-
-bool MyFormatMessage(DWORD messageID, CSysString &message)
-{
- LPVOID msgBuf;
- if (::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,messageID, 0, (LPTSTR) &msgBuf,0, NULL) == 0)
- return false;
- message = (LPCTSTR)msgBuf;
- ::LocalFree(msgBuf);
- return true;
-}
-
-#ifndef _UNICODE
-bool MyFormatMessage(DWORD messageID, UString &message)
-{
- if (g_IsNT)
- {
- LPVOID msgBuf;
- if (::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, messageID, 0, (LPWSTR) &msgBuf, 0, NULL) == 0)
- return false;
- message = (LPCWSTR)msgBuf;
- ::LocalFree(msgBuf);
- return true;
- }
- CSysString messageSys;
- bool result = MyFormatMessage(messageID, messageSys);
- message = GetUnicodeString(messageSys);
- return result;
-}
-#endif
-
-}}
diff --git a/src/libs/7zip/win/CPP/Windows/Error.h b/src/libs/7zip/win/CPP/Windows/Error.h
deleted file mode 100644
index 05b5cd0ea..000000000
--- a/src/libs/7zip/win/CPP/Windows/Error.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Windows/Error.h
-
-#ifndef __WINDOWS_ERROR_H
-#define __WINDOWS_ERROR_H
-
-#include "Common/MyString.h"
-
-namespace NWindows {
-namespace NError {
-
-bool MyFormatMessage(DWORD messageID, CSysString &message);
-inline CSysString MyFormatMessage(DWORD messageID)
-{
- CSysString message;
- MyFormatMessage(messageID, message);
- return message;
-}
-#ifdef _UNICODE
-inline UString MyFormatMessageW(DWORD messageID)
- { return MyFormatMessage(messageID); }
-#else
-bool MyFormatMessage(DWORD messageID, UString &message);
-inline UString MyFormatMessageW(DWORD messageID)
-{
- UString message;
- MyFormatMessage(messageID, message);
- return message;
-}
-#endif
-
-}}
-
-#endif
diff --git a/src/libs/7zip/win/CPP/Windows/FileDir.cpp b/src/libs/7zip/win/CPP/Windows/FileDir.cpp
index 857946031..097f81efb 100644
--- a/src/libs/7zip/win/CPP/Windows/FileDir.cpp
+++ b/src/libs/7zip/win/CPP/Windows/FileDir.cpp
@@ -14,81 +14,62 @@
extern bool g_IsNT;
#endif
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
+
namespace NWindows {
namespace NFile {
-
-#if defined(WIN_LONG_PATH) && defined(_UNICODE)
-#define WIN_LONG_PATH2
-#endif
-
-// SetCurrentDirectory doesn't support \\?\ prefix
-
-#ifdef WIN_LONG_PATH
-bool GetLongPathBase(LPCWSTR fileName, UString &res);
-bool GetLongPath(LPCWSTR fileName, UString &res);
-#endif
-
-namespace NDirectory {
-
-#ifndef _UNICODE
-static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
-static UString GetUnicodePath(const CSysString &sysPath)
- { return MultiByteToUnicodeString(sysPath, GetCurrentCodePage()); }
-static CSysString GetSysPath(LPCWSTR sysPath)
- { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); }
-#endif
+namespace NDir {
#ifndef UNDER_CE
-bool MyGetWindowsDirectory(CSysString &path)
-{
- UINT needLength = ::GetWindowsDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
- path.ReleaseBuffer();
- return (needLength > 0 && needLength <= MAX_PATH);
-}
-
-bool MyGetSystemDirectory(CSysString &path)
+bool GetWindowsDir(FString &path)
{
- UINT needLength = ::GetSystemDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
- path.ReleaseBuffer();
+ 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);
}
-#endif
-
-#ifndef _UNICODE
-bool MyGetWindowsDirectory(UString &path)
+bool GetSystemDir(FString &path)
{
- if (g_IsNT)
+ UINT needLength;
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- UINT needLength = ::GetWindowsDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
- path.ReleaseBuffer();
- return (needLength > 0 && needLength <= MAX_PATH);
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetSystemDirectory(s, MAX_PATH + 1);
+ path = fas2fs(s);
}
- CSysString sysPath;
- if (!MyGetWindowsDirectory(sysPath))
- return false;
- path = GetUnicodePath(sysPath);
- return true;
-}
-
-bool MyGetSystemDirectory(UString &path)
-{
- if (g_IsNT)
+ else
+ #endif
{
- UINT needLength = ::GetSystemDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
- path.ReleaseBuffer();
- return (needLength > 0 && needLength <= MAX_PATH);
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetSystemDirectoryW(s, MAX_PATH + 1);
+ path = us2fs(s);
}
- CSysString sysPath;
- if (!MyGetSystemDirectory(sysPath))
- return false;
- path = GetUnicodePath(sysPath);
- return true;
+ return (needLength > 0 && needLength <= MAX_PATH);
}
#endif
-bool SetDirTime(LPCWSTR fileName, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
+bool SetDirTime(CFSTR path, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
{
#ifndef _UNICODE
if (!g_IsNT)
@@ -97,17 +78,18 @@ bool SetDirTime(LPCWSTR fileName, const FILETIME *cTime, const FILETIME *aTime,
return false;
}
#endif
- HANDLE hDir = ::CreateFileW(fileName, GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+
+ HANDLE hDir = INVALID_HANDLE_VALUE;
+ IF_USE_MAIN_PATH
+ hDir = ::CreateFileW(fs2us(path), 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)
+ if (hDir == INVALID_HANDLE_VALUE && USE_SUPER_PATH)
{
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);
+ if (GetSuperPath(path, longPath, USE_MAIN_PATH))
+ hDir = ::CreateFileW(longPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
}
#endif
@@ -120,790 +102,482 @@ bool SetDirTime(LPCWSTR fileName, const FILETIME *cTime, const FILETIME *aTime,
return res;
}
-bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes)
-{
- if (::SetFileAttributes(fileName, fileAttributes))
- return true;
- #ifdef WIN_LONG_PATH2
- UString longPath;
- if (GetLongPath(fileName, longPath))
- return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes));
- #endif
- return false;
-}
-
-bool MyRemoveDirectory(LPCTSTR pathName)
-{
- if (::RemoveDirectory(pathName))
- return true;
- #ifdef WIN_LONG_PATH2
- UString longPath;
- if (GetLongPath(pathName, longPath))
- return BOOLToBool(::RemoveDirectoryW(longPath));
- #endif
- return false;
-}
-
-#ifdef WIN_LONG_PATH
-bool GetLongPaths(LPCWSTR s1, LPCWSTR 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 = s1;
- if (d2.IsEmpty()) d2 = s2;
- return true;
-}
-#endif
-
-bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName)
-{
- if (::MoveFile(existFileName, newFileName))
- return true;
- #ifdef WIN_LONG_PATH2
- UString d1, d2;
- if (GetLongPaths(existFileName, newFileName, d1, d2))
- return BOOLToBool(::MoveFileW(d1, d2));
- #endif
- return false;
-}
-
-#ifndef _UNICODE
-bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes)
+bool SetFileAttrib(CFSTR path, DWORD attrib)
{
+ #ifndef _UNICODE
if (!g_IsNT)
- return MySetFileAttributes(GetSysPath(fileName), fileAttributes);
- if (::SetFileAttributesW(fileName, fileAttributes))
- return true;
- #ifdef WIN_LONG_PATH
- UString longPath;
- if (GetLongPath(fileName, longPath))
- return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes));
+ {
+ if (::SetFileAttributes(fs2fas(path), attrib))
+ return true;
+ }
+ else
#endif
+ {
+ IF_USE_MAIN_PATH
+ if (::SetFileAttributesW(fs2us(path), attrib))
+ return true;
+ #ifdef WIN_LONG_PATH
+ if (USE_SUPER_PATH)
+ {
+ UString longPath;
+ if (GetSuperPath(path, longPath, USE_MAIN_PATH))
+ return BOOLToBool(::SetFileAttributesW(longPath, attrib));
+ }
+ #endif
+ }
return false;
}
-
-bool MyRemoveDirectory(LPCWSTR pathName)
+bool RemoveDir(CFSTR path)
{
+ #ifndef _UNICODE
if (!g_IsNT)
- return MyRemoveDirectory(GetSysPath(pathName));
- if (::RemoveDirectoryW(pathName))
- return true;
- #ifdef WIN_LONG_PATH
- UString longPath;
- if (GetLongPath(pathName, longPath))
- return BOOLToBool(::RemoveDirectoryW(longPath));
+ {
+ if (::RemoveDirectory(fs2fas(path)))
+ return true;
+ }
+ else
#endif
+ {
+ IF_USE_MAIN_PATH
+ if (::RemoveDirectoryW(fs2us(path)))
+ return true;
+ #ifdef WIN_LONG_PATH
+ if (USE_SUPER_PATH)
+ {
+ UString longPath;
+ if (GetSuperPath(path, longPath, USE_MAIN_PATH))
+ return BOOLToBool(::RemoveDirectoryW(longPath));
+ }
+ #endif
+ }
return false;
}
-bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName)
+bool MyMoveFile(CFSTR oldFile, CFSTR newFile)
{
+ #ifndef _UNICODE
if (!g_IsNT)
- return MyMoveFile(GetSysPath(existFileName), GetSysPath(newFileName));
- if (::MoveFileW(existFileName, newFileName))
- return true;
- #ifdef WIN_LONG_PATH
- UString d1, d2;
- if (GetLongPaths(existFileName, newFileName, d1, d2))
- return BOOLToBool(::MoveFileW(d1, d2));
- #endif
- return false;
-}
-#endif
-
-bool MyCreateDirectory(LPCTSTR pathName)
-{
- if (::CreateDirectory(pathName, NULL))
- return true;
- #ifdef WIN_LONG_PATH2
- if (::GetLastError() != ERROR_ALREADY_EXISTS)
{
- UString longPath;
- if (GetLongPath(pathName, longPath))
- return BOOLToBool(::CreateDirectoryW(longPath, NULL));
+ if (::MoveFile(fs2fas(oldFile), fs2fas(newFile)))
+ return true;
}
+ else
#endif
+ {
+ IF_USE_MAIN_PATH_2(oldFile, newFile)
+ if (::MoveFileW(fs2us(oldFile), fs2us(newFile)))
+ return true;
+ #ifdef WIN_LONG_PATH
+ if (USE_SUPER_PATH_2)
+ {
+ UString d1, d2;
+ if (GetSuperPaths(oldFile, newFile, d1, d2, USE_MAIN_PATH_2))
+ return BOOLToBool(::MoveFileW(d1, d2));
+ }
+ #endif
+ }
return false;
}
-#ifndef _UNICODE
-bool MyCreateDirectory(LPCWSTR pathName)
+#ifndef UNDER_CE
+
+EXTERN_C_BEGIN
+typedef BOOL (WINAPI *Func_CreateHardLinkW)(
+ LPCWSTR lpFileName,
+ LPCWSTR lpExistingFileName,
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes
+ );
+EXTERN_C_END
+
+bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName)
{
+ #ifndef _UNICODE
if (!g_IsNT)
- return MyCreateDirectory(GetSysPath(pathName));
- if (::CreateDirectoryW(pathName, NULL))
- return true;
- #ifdef WIN_LONG_PATH
- if (::GetLastError() != ERROR_ALREADY_EXISTS)
{
- UString longPath;
- if (GetLongPath(pathName, longPath))
- return BOOLToBool(::CreateDirectoryW(longPath, NULL));
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return false;
+ /*
+ if (::CreateHardLink(fs2fas(newFileName), fs2fas(existFileName), NULL))
+ return true;
+ */
}
+ else
#endif
- return false;
-}
-#endif
-
-/*
-bool CreateComplexDirectory(LPCTSTR pathName)
-{
- NName::CParsedPath path;
- path.ParsePath(pathName);
- CSysString fullPath = path.Prefix;
- DWORD errorCode = ERROR_SUCCESS;
- for (int i = 0; i < path.PathParts.Size(); i++)
{
- const CSysString &string = path.PathParts[i];
- if (string.IsEmpty())
- {
- if (i != path.PathParts.Size() - 1)
- return false;
- return true;
- }
- fullPath += path.PathParts[i];
- if (!MyCreateDirectory(fullPath))
+ Func_CreateHardLinkW my_CreateHardLinkW = (Func_CreateHardLinkW)
+ ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), "CreateHardLinkW");
+ if (!my_CreateHardLinkW)
+ return false;
+ IF_USE_MAIN_PATH_2(newFileName, existFileName)
+ if (my_CreateHardLinkW(fs2us(newFileName), fs2us(existFileName), NULL))
+ return true;
+ #ifdef WIN_LONG_PATH
+ if (USE_SUPER_PATH_2)
{
- DWORD errorCode = GetLastError();
- if (errorCode != ERROR_ALREADY_EXISTS)
- return false;
+ UString d1, d2;
+ if (GetSuperPaths(newFileName, existFileName, d1, d2, USE_MAIN_PATH_2))
+ return BOOLToBool(my_CreateHardLinkW(d1, d2, NULL));
}
- fullPath += NName::kDirDelimiter;
+ #endif
}
- return true;
+ return false;
}
-*/
-bool CreateComplexDirectory(LPCTSTR _aPathName)
+#endif
+
+bool CreateDir(CFSTR path)
{
- CSysString pathName = _aPathName;
- int pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
- if (pos > 0 && pos == pathName.Length() - 1)
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- if (pathName.Length() == 3 && pathName[1] == ':')
- return true; // Disk folder;
- pathName.Delete(pos);
+ if (::CreateDirectory(fs2fas(path), NULL))
+ return true;
}
- CSysString pathName2 = pathName;
- pos = pathName.Length();
- for (;;)
+ else
+ #endif
{
- if (MyCreateDirectory(pathName))
- break;
- if (::GetLastError() == ERROR_ALREADY_EXISTS)
- {
- NFind::CFileInfo fileInfo;
- if (!fileInfo.Find(pathName)) // For network folders
+ IF_USE_MAIN_PATH
+ if (::CreateDirectoryW(fs2us(path), NULL))
return true;
- if (!fileInfo.IsDir())
- return false;
- break;
+ #ifdef WIN_LONG_PATH
+ if ((!USE_MAIN_PATH || ::GetLastError() != ERROR_ALREADY_EXISTS) && USE_SUPER_PATH)
+ {
+ UString longPath;
+ if (GetSuperPath(path, longPath, USE_MAIN_PATH))
+ return BOOLToBool(::CreateDirectoryW(longPath, NULL));
}
- pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
- if (pos < 0 || pos == 0)
- return false;
- if (pathName[pos - 1] == ':')
- return false;
- pathName = pathName.Left(pos);
- }
- pathName = pathName2;
- while (pos < pathName.Length())
- {
- pos = pathName.Find(TEXT(CHAR_PATH_SEPARATOR), pos + 1);
- if (pos < 0)
- pos = pathName.Length();
- if (!MyCreateDirectory(pathName.Left(pos)))
- return false;
+ #endif
}
- return true;
+ return false;
}
-#ifndef _UNICODE
-
-bool CreateComplexDirectory(LPCWSTR _aPathName)
+bool CreateComplexDir(CFSTR _aPathName)
{
- UString pathName = _aPathName;
- int pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
- if (pos > 0 && pos == pathName.Length() - 1)
+ FString pathName = _aPathName;
+ int pos = pathName.ReverseFind(FCHAR_PATH_SEPARATOR);
+ if (pos > 0 && (unsigned)pos == pathName.Len() - 1)
{
- if (pathName.Length() == 3 && pathName[1] == L':')
+ if (pathName.Len() == 3 && pathName[1] == L':')
return true; // Disk folder;
pathName.Delete(pos);
}
- UString pathName2 = pathName;
- pos = pathName.Length();
+ const FString pathName2 = pathName;
+ pos = pathName.Len();
+
for (;;)
{
- if (MyCreateDirectory(pathName))
+ if (CreateDir(pathName))
break;
if (::GetLastError() == ERROR_ALREADY_EXISTS)
{
- NFind::CFileInfoW fileInfo;
+ NFind::CFileInfo fileInfo;
if (!fileInfo.Find(pathName)) // For network folders
return true;
if (!fileInfo.IsDir())
return false;
break;
}
- pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
+ 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.DeleteFrom(pos);
}
- pathName = pathName2;
- while (pos < pathName.Length())
+
+ while (pos < (int)pathName2.Len())
{
- pos = pathName.Find(WCHAR_PATH_SEPARATOR, pos + 1);
+ pos = pathName2.Find(FCHAR_PATH_SEPARATOR, pos + 1);
if (pos < 0)
- pos = pathName.Length();
- if (!MyCreateDirectory(pathName.Left(pos)))
+ pos = pathName2.Len();
+ pathName.SetFrom(pathName2, pos);
+ if (!CreateDir(pathName))
return false;
}
+
return true;
}
-#endif
-
-bool DeleteFileAlways(LPCTSTR name)
+bool DeleteFileAlways(CFSTR path)
{
- if (!MySetFileAttributes(name, 0))
+ if (!SetFileAttrib(path, 0))
return false;
- if (::DeleteFile(name))
- return true;
- #ifdef WIN_LONG_PATH2
- UString longPath;
- if (GetLongPath(name, longPath))
- return BOOLToBool(::DeleteFileW(longPath));
- #endif
- return false;
-}
-
-#ifndef _UNICODE
-bool DeleteFileAlways(LPCWSTR name)
-{
+ #ifndef _UNICODE
if (!g_IsNT)
- return DeleteFileAlways(GetSysPath(name));
- if (!MySetFileAttributes(name, 0))
- return false;
- if (::DeleteFileW(name))
- return true;
- #ifdef WIN_LONG_PATH
- UString longPath;
- if (GetLongPath(name, longPath))
- return BOOLToBool(::DeleteFileW(longPath));
+ {
+ if (::DeleteFile(fs2fas(path)))
+ return true;
+ }
+ else
#endif
+ {
+ IF_USE_MAIN_PATH
+ if (::DeleteFileW(fs2us(path)))
+ return true;
+ #ifdef WIN_LONG_PATH
+ if (USE_SUPER_PATH)
+ {
+ UString longPath;
+ if (GetSuperPath(path, longPath, USE_MAIN_PATH))
+ return BOOLToBool(::DeleteFileW(longPath));
+ }
+ #endif
+ }
return false;
}
-#endif
-
-static bool RemoveDirectorySubItems2(const CSysString pathPrefix, const NFind::CFileInfo &fileInfo)
-{
- if (fileInfo.IsDir())
- return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
- return DeleteFileAlways(pathPrefix + fileInfo.Name);
-}
-bool RemoveDirectoryWithSubItems(const CSysString &path)
+bool RemoveDirWithSubItems(const FString &path)
{
- NFind::CFileInfo fileInfo;
- CSysString pathPrefix = path + NName::kDirDelimiter;
+ bool needRemoveSubItems = true;
{
- NFind::CEnumerator enumerator(pathPrefix + TCHAR(NName::kAnyStringWildcard));
- while (enumerator.Next(fileInfo))
- if (!RemoveDirectorySubItems2(pathPrefix, fileInfo))
- return false;
+ NFind::CFileInfo fi;
+ if (!fi.Find(path))
+ return false;
+ if (!fi.IsDir())
+ {
+ ::SetLastError(ERROR_DIRECTORY);
+ return false;
+ }
+ if (fi.HasReparsePoint())
+ needRemoveSubItems = false;
}
- if (!MySetFileAttributes(path, 0))
- return false;
- return MyRemoveDirectory(path);
-}
-#ifndef _UNICODE
-static bool RemoveDirectorySubItems2(const UString pathPrefix, const NFind::CFileInfoW &fileInfo)
-{
- if (fileInfo.IsDir())
- return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
- return DeleteFileAlways(pathPrefix + fileInfo.Name);
-}
-bool RemoveDirectoryWithSubItems(const UString &path)
-{
- NFind::CFileInfoW fileInfo;
- UString pathPrefix = path + UString(NName::kDirDelimiter);
+ if (needRemoveSubItems)
{
- NFind::CEnumeratorW enumerator(pathPrefix + UString(NName::kAnyStringWildcard));
- while (enumerator.Next(fileInfo))
- if (!RemoveDirectorySubItems2(pathPrefix, fileInfo))
+ FString s = path;
+ s += FCHAR_PATH_SEPARATOR;
+ unsigned prefixSize = s.Len();
+ s += FCHAR_ANY_MASK;
+ NFind::CEnumerator enumerator(s);
+ NFind::CFileInfo fi;
+ while (enumerator.Next(fi))
+ {
+ s.DeleteFrom(prefixSize);
+ s += fi.Name;
+ if (fi.IsDir())
+ {
+ if (!RemoveDirWithSubItems(s))
+ return false;
+ }
+ else if (!DeleteFileAlways(s))
return false;
+ }
}
- if (!MySetFileAttributes(path, 0))
- return false;
- return MyRemoveDirectory(path);
-}
-#endif
-bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName)
-{
- int index;
- if (!MyGetFullPathName(fileName, resultName, index))
+ if (!SetFileAttrib(path, 0))
return false;
- resultName = resultName.Left(index);
- return true;
-}
-
-bool GetOnlyName(LPCTSTR fileName, CSysString &resultName)
-{
- int index;
- if (!MyGetFullPathName(fileName, resultName, index))
- return false;
- resultName = resultName.Mid(index);
- return true;
+ return RemoveDir(path);
}
#ifdef UNDER_CE
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath)
-{
- resultPath = fileName;
- return true;
-}
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex)
+bool MyGetFullPathName(CFSTR path, FString &resFullPath)
{
- resultPath = fileName;
- // change it
- fileNamePartStartIndex = resultPath.ReverseFind(WCHAR_PATH_SEPARATOR);
- fileNamePartStartIndex++;
+ resFullPath = path;
return true;
}
#else
-bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath)
+bool MyGetFullPathName(CFSTR path, FString &resFullPath)
{
- DWORD needLength = ::GetShortPathName(longPath, shortPath.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
- shortPath.ReleaseBuffer();
- return (needLength > 0 && needLength < MAX_PATH);
+ return GetFullPath(path, resFullPath);
}
-#ifdef WIN_LONG_PATH
-
-static UString GetLastPart(LPCWSTR path)
+bool SetCurrentDir(CFSTR path)
{
- int i = (int)wcslen(path);
- for (; i > 0; i--)
- {
- WCHAR c = path[i - 1];
- if (c == WCHAR_PATH_SEPARATOR || c == '/')
- break;
- }
- return path + i;
-}
-
-static void AddTrailingDots(LPCWSTR oldPath, UString &newPath)
-{
- int len = (int)wcslen(oldPath);
- int i;
- for (i = len; i > 0 && oldPath[i - 1] == '.'; i--);
- if (i == 0 || i == len)
- return;
- UString oldName = GetLastPart(oldPath);
- UString 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(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex)
-{
- resultPath.Empty();
- LPTSTR fileNamePointer = 0;
- LPTSTR buffer = resultPath.GetBuffer(MAX_PATH);
- DWORD needLength = ::GetFullPathName(fileName, MAX_PATH + 1, buffer, &fileNamePointer);
- resultPath.ReleaseBuffer();
- if (needLength == 0)
- return false;
- if (needLength >= MAX_PATH)
+ // SetCurrentDirectory doesn't support \\?\ prefix
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- #ifdef WIN_LONG_PATH2
- needLength++;
- buffer = resultPath.GetBuffer(needLength + 1);
- DWORD needLength2 = ::GetFullPathNameW(fileName, needLength, buffer, &fileNamePointer);
- resultPath.ReleaseBuffer();
- if (needLength2 == 0 || needLength2 > needLength)
- #endif
- return false;
+ return BOOLToBool(::SetCurrentDirectory(fs2fas(path)));
}
- if (fileNamePointer == 0)
- fileNamePartStartIndex = lstrlen(fileName);
else
- fileNamePartStartIndex = (int)(fileNamePointer - buffer);
- #ifdef _UNICODE
- #ifdef WIN_LONG_PATH
- AddTrailingDots(fileName, resultPath);
#endif
- #endif
- return true;
+ {
+ return BOOLToBool(::SetCurrentDirectoryW(fs2us(path)));
+ }
}
-#ifndef _UNICODE
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex)
+bool GetCurrentDir(FString &path)
{
- resultPath.Empty();
- if (g_IsNT)
+ path.Empty();
+ DWORD needLength;
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- LPWSTR fileNamePointer = 0;
- LPWSTR buffer = resultPath.GetBuffer(MAX_PATH);
- DWORD needLength = ::GetFullPathNameW(fileName, MAX_PATH + 1, buffer, &fileNamePointer);
- resultPath.ReleaseBuffer();
- if (needLength == 0)
- return false;
- if (needLength >= MAX_PATH)
- {
- #ifdef WIN_LONG_PATH
- needLength++;
- buffer = resultPath.GetBuffer(needLength + 1);
- DWORD needLength2 = ::GetFullPathNameW(fileName, needLength, buffer, &fileNamePointer);
- resultPath.ReleaseBuffer();
- if (needLength2 == 0 || needLength2 > needLength)
- #endif
- return false;
- }
- if (fileNamePointer == 0)
- fileNamePartStartIndex = MyStringLen(fileName);
- else
- fileNamePartStartIndex = (int)(fileNamePointer - buffer);
- #ifdef WIN_LONG_PATH
- AddTrailingDots(fileName, resultPath);
- #endif
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetCurrentDirectory(MAX_PATH + 1, s);
+ path = fas2fs(s);
}
else
+ #endif
{
- CSysString sysPath;
- if (!MyGetFullPathName(GetSysPath(fileName), sysPath, fileNamePartStartIndex))
- return false;
- UString resultPath1 = GetUnicodePath(sysPath.Left(fileNamePartStartIndex));
- UString resultPath2 = GetUnicodePath(sysPath.Mid(fileNamePartStartIndex));
- fileNamePartStartIndex = resultPath1.Length();
- resultPath = resultPath1 + resultPath2;
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, s);
+ path = us2fs(s);
}
- return true;
-}
-#endif
-
-
-bool MyGetFullPathName(LPCTSTR fileName, CSysString &path)
-{
- int index;
- return MyGetFullPathName(fileName, path, index);
+ return (needLength > 0 && needLength <= MAX_PATH);
}
-#ifndef _UNICODE
-bool MyGetFullPathName(LPCWSTR fileName, UString &path)
-{
- int index;
- return MyGetFullPathName(fileName, path, index);
-}
#endif
-#ifndef _UNICODE
-bool GetOnlyName(LPCWSTR fileName, UString &resultName)
+bool GetFullPathAndSplit(CFSTR path, FString &resDirPrefix, FString &resFileName)
{
- int index;
- if (!MyGetFullPathName(fileName, resultName, index))
- return false;
- resultName = resultName.Mid(index);
- return true;
-}
-#endif
-
-#ifndef _UNICODE
-bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName)
-{
- int index;
- if (!MyGetFullPathName(fileName, resultName, index))
- return false;
- resultName = resultName.Left(index);
- return true;
+ bool res = MyGetFullPathName(path, resDirPrefix);
+ if (!res)
+ resDirPrefix = path;
+ int pos = resDirPrefix.ReverseFind(FCHAR_PATH_SEPARATOR);
+ resFileName = resDirPrefix.Ptr(pos + 1);
+ resDirPrefix.DeleteFrom(pos + 1);
+ return res;
}
-#endif
-bool MyGetCurrentDirectory(CSysString &path)
+bool GetOnlyDirPrefix(CFSTR path, FString &resDirPrefix)
{
- DWORD needLength = ::GetCurrentDirectory(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
- path.ReleaseBuffer();
- return (needLength > 0 && needLength <= MAX_PATH);
+ FString resFileName;
+ return GetFullPathAndSplit(path, resDirPrefix, resFileName);
}
-#ifndef _UNICODE
-bool MySetCurrentDirectory(LPCWSTR path)
+bool MyGetTempPath(FString &path)
{
- if (g_IsNT)
- return BOOLToBool(::SetCurrentDirectoryW(path));
- return MySetCurrentDirectory(GetSysPath(path));
-}
-bool MyGetCurrentDirectory(UString &path)
-{
- if (g_IsNT)
+ path.Empty();
+ DWORD needLength;
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
- path.ReleaseBuffer();
- return (needLength > 0 && needLength <= MAX_PATH);
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetTempPath(MAX_PATH + 1, s);
+ path = fas2fs(s);
}
- CSysString sysPath;
- if (!MyGetCurrentDirectory(sysPath))
- return false;
- path = GetUnicodePath(sysPath);
- return true;
-}
-#endif
-
-bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension,
- CSysString &resultPath, UINT32 &filePart)
-{
- LPTSTR filePartPointer;
- DWORD value = ::SearchPath(path, fileName, extension,
- MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);
- filePart = (UINT32)(filePartPointer - (LPCTSTR)resultPath);
- resultPath.ReleaseBuffer();
- return (value > 0 && value <= MAX_PATH);
-}
-#endif
-
-#ifndef _UNICODE
-bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension,
- UString &resultPath, UINT32 &filePart)
-{
- if (g_IsNT)
+ else
+ #endif
{
- LPWSTR filePartPointer = 0;
- DWORD value = ::SearchPathW(path, fileName, extension,
- MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);
- filePart = (UINT32)(filePartPointer - (LPCWSTR)resultPath);
- resultPath.ReleaseBuffer();
- return (value > 0 && value <= MAX_PATH);
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetTempPathW(MAX_PATH + 1, s);;
+ path = us2fs(s);
}
-
- CSysString sysPath;
- if (!MySearchPath(
- path != 0 ? (LPCTSTR)GetSysPath(path): 0,
- fileName != 0 ? (LPCTSTR)GetSysPath(fileName): 0,
- extension != 0 ? (LPCTSTR)GetSysPath(extension): 0,
- sysPath, filePart))
- return false;
- UString resultPath1 = GetUnicodePath(sysPath.Left(filePart));
- UString resultPath2 = GetUnicodePath(sysPath.Mid(filePart));
- filePart = resultPath1.Length();
- resultPath = resultPath1 + resultPath2;
- return true;
-}
-#endif
-
-bool MyGetTempPath(CSysString &path)
-{
- DWORD needLength = ::GetTempPath(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
- path.ReleaseBuffer();
return (needLength > 0 && needLength <= MAX_PATH);
}
-#ifndef _UNICODE
-bool MyGetTempPath(UString &path)
-{
- path.Empty();
- if (g_IsNT)
- {
- DWORD needLength = ::GetTempPathW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
- path.ReleaseBuffer();
- return (needLength > 0 && needLength <= MAX_PATH);
- }
- CSysString sysPath;
- if (!MyGetTempPath(sysPath))
- return false;
- path = GetUnicodePath(sysPath);
- return true;
-}
-#endif
-
-UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &path)
-{
- UINT number = ::GetTempFileName(dirPath, prefix, 0, path.GetBuffer(MAX_PATH + 1));
- path.ReleaseBuffer();
- return number;
-}
-
-#ifndef _UNICODE
-UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &path)
+static bool CreateTempFile(CFSTR prefix, bool addRandom, FString &path, NIO::COutFile *outFile)
{
- if (g_IsNT)
+ UInt32 d = (GetTickCount() << 12) ^ (GetCurrentThreadId() << 14) ^ GetCurrentProcessId();
+ for (unsigned i = 0; i < 100; i++)
{
- UINT number = ::GetTempFileNameW(dirPath, prefix, 0, path.GetBuffer(MAX_PATH));
- path.ReleaseBuffer();
- return number;
+ 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 (CreateDir(path))
+ return true;
+ }
+ DWORD error = GetLastError();
+ if (error != ERROR_FILE_EXISTS &&
+ error != ERROR_ALREADY_EXISTS)
+ break;
}
- CSysString sysPath;
- UINT number = MyGetTempFileName(
- dirPath ? (LPCTSTR)GetSysPath(dirPath): 0,
- prefix ? (LPCTSTR)GetSysPath(prefix): 0,
- sysPath);
- path = GetUnicodePath(sysPath);
- return number;
+ path.Empty();
+ return false;
}
-#endif
-UINT CTempFile::Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath)
+bool CTempFile::Create(CFSTR prefix, NIO::COutFile *outFile)
{
- Remove();
- UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
- if (number != 0)
- {
- _fileName = resultPath;
- _mustBeDeleted = true;
- }
- return number;
+ if (!Remove())
+ return false;
+ if (!CreateTempFile(prefix, false, _path, outFile))
+ return false;
+ _mustBeDeleted = true;
+ return true;
}
-bool CTempFile::Create(LPCTSTR prefix, CSysString &resultPath)
+bool CTempFile::CreateRandomInTempFolder(CFSTR namePrefix, NIO::COutFile *outFile)
{
- CSysString tempPath;
+ if (!Remove())
+ return false;
+ FString tempPath;
if (!MyGetTempPath(tempPath))
return false;
- if (Create(tempPath, prefix, resultPath) != 0)
- return true;
- #ifdef UNDER_CE
- return false;
- #else
- if (!MyGetWindowsDirectory(tempPath))
+ if (!CreateTempFile(tempPath + namePrefix, true, _path, outFile))
return false;
- return (Create(tempPath, prefix, resultPath) != 0);
- #endif
+ _mustBeDeleted = true;
+ return true;
}
bool CTempFile::Remove()
{
if (!_mustBeDeleted)
return true;
- _mustBeDeleted = !DeleteFileAlways(_fileName);
+ _mustBeDeleted = !DeleteFileAlways(_path);
return !_mustBeDeleted;
}
-#ifndef _UNICODE
-
-UINT CTempFileW::Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath)
+bool CTempFile::MoveTo(CFSTR name, bool deleteDestBefore)
{
- Remove();
- UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
- if (number != 0)
- {
- _fileName = resultPath;
- _mustBeDeleted = true;
- }
- return number;
+ if (deleteDestBefore)
+ if (NFind::DoesFileExist(name))
+ if (!DeleteFileAlways(name))
+ return false;
+ DisableDeleting();
+ return MyMoveFile(_path, name);
}
-bool CTempFileW::Create(LPCWSTR prefix, UString &resultPath)
+bool CTempDir::Create(CFSTR prefix)
{
- UString tempPath;
+ if (!Remove())
+ return false;
+ FString tempPath;
if (!MyGetTempPath(tempPath))
return false;
- if (Create(tempPath, prefix, resultPath) != 0)
- return true;
- if (!MyGetWindowsDirectory(tempPath))
+ if (!CreateTempFile(tempPath + prefix, true, _path, NULL))
return false;
- return (Create(tempPath, prefix, resultPath) != 0);
+ _mustBeDeleted = true;
+ return true;
}
-bool CTempFileW::Remove()
+bool CTempDir::Remove()
{
if (!_mustBeDeleted)
return true;
- _mustBeDeleted = !DeleteFileAlways(_fileName);
+ _mustBeDeleted = !RemoveDirWithSubItems(_path);
return !_mustBeDeleted;
}
-#endif
-
-bool CreateTempDirectory(LPCTSTR prefix, CSysString &dirName)
-{
- /*
- CSysString prefix = tempPath + prefixChars;
- CRandom random;
- random.Init();
- */
- for (;;)
- {
- {
- CTempFile tempFile;
- if (!tempFile.Create(prefix, dirName))
- return false;
- if (!tempFile.Remove())
- return false;
- }
- /*
- UINT32 randomNumber = random.Generate();
- TCHAR randomNumberString[32];
- _stprintf(randomNumberString, _T("%04X"), randomNumber);
- dirName = prefix + randomNumberString;
- */
- if (NFind::DoesFileOrDirExist(dirName))
- continue;
- if (MyCreateDirectory(dirName))
- return true;
- if (::GetLastError() != ERROR_ALREADY_EXISTS)
- return false;
- }
-}
-
-bool CTempDirectory::Create(LPCTSTR prefix)
-{
- Remove();
- return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
-}
-
-#ifndef _UNICODE
-
-bool CreateTempDirectory(LPCWSTR prefix, UString &dirName)
-{
- /*
- CSysString prefix = tempPath + prefixChars;
- CRandom random;
- random.Init();
- */
- for (;;)
- {
- {
- CTempFileW tempFile;
- if (!tempFile.Create(prefix, dirName))
- return false;
- if (!tempFile.Remove())
- return false;
- }
- /*
- UINT32 randomNumber = random.Generate();
- TCHAR randomNumberString[32];
- _stprintf(randomNumberString, _T("%04X"), randomNumber);
- dirName = prefix + randomNumberString;
- */
- if (NFind::DoesFileOrDirExist(dirName))
- continue;
- if (MyCreateDirectory(dirName))
- return true;
- if (::GetLastError() != ERROR_ALREADY_EXISTS)
- return false;
- }
-}
-
-bool CTempDirectoryW::Create(LPCWSTR prefix)
-{
- Remove();
- return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
-}
-
-#endif
-
}}}
diff --git a/src/libs/7zip/win/CPP/Windows/FileDir.h b/src/libs/7zip/win/CPP/Windows/FileDir.h
index 04542d872..02d3e5a57 100644
--- a/src/libs/7zip/win/CPP/Windows/FileDir.h
+++ b/src/libs/7zip/win/CPP/Windows/FileDir.h
@@ -1,174 +1,94 @@
// Windows/FileDir.h
-#ifndef __WINDOWS_FILEDIR_H
-#define __WINDOWS_FILEDIR_H
+#ifndef __WINDOWS_FILE_DIR_H
+#define __WINDOWS_FILE_DIR_H
#include "../Common/MyString.h"
-#include "Defs.h"
+
+#include "FileIO.h"
namespace NWindows {
namespace NFile {
-namespace NDirectory {
+namespace NDir {
-#ifdef WIN_LONG_PATH
-bool GetLongPaths(LPCWSTR s1, LPCWSTR s2, UString &d1, UString &d2);
-#endif
+bool GetWindowsDir(FString &path);
+bool GetSystemDir(FString &path);
-bool MyGetWindowsDirectory(CSysString &path);
-bool MyGetSystemDirectory(CSysString &path);
-#ifndef _UNICODE
-bool MyGetWindowsDirectory(UString &path);
-bool MyGetSystemDirectory(UString &path);
-#endif
+bool SetDirTime(CFSTR path, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime);
+bool SetFileAttrib(CFSTR path, DWORD attrib);
+bool MyMoveFile(CFSTR existFileName, CFSTR newFileName);
-bool SetDirTime(LPCWSTR fileName, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime);
-
-bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes);
-bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName);
-bool MyRemoveDirectory(LPCTSTR pathName);
-bool MyCreateDirectory(LPCTSTR pathName);
-bool CreateComplexDirectory(LPCTSTR pathName);
-bool DeleteFileAlways(LPCTSTR name);
-bool RemoveDirectoryWithSubItems(const CSysString &path);
-
-#ifndef _UNICODE
-bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes);
-bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName);
-bool MyRemoveDirectory(LPCWSTR pathName);
-bool MyCreateDirectory(LPCWSTR pathName);
-bool CreateComplexDirectory(LPCWSTR pathName);
-bool DeleteFileAlways(LPCWSTR name);
-bool RemoveDirectoryWithSubItems(const UString &path);
+#ifndef UNDER_CE
+bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName);
#endif
-bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName);
-bool GetOnlyName(LPCTSTR fileName, CSysString &resultName);
-#ifdef UNDER_CE
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath);
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex);
-#else
-bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath);
-
-bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex);
-bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath);
-#ifndef _UNICODE
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath,
- int &fileNamePartStartIndex);
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath);
-bool GetOnlyName(LPCWSTR fileName, UString &resultName);
-bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName);
-#endif
+bool RemoveDir(CFSTR path);
+bool CreateDir(CFSTR path);
+bool CreateComplexDir(CFSTR path);
+bool DeleteFileAlways(CFSTR name);
+bool RemoveDirWithSubItems(const FString &path);
-inline bool MySetCurrentDirectory(LPCTSTR path)
- { return BOOLToBool(::SetCurrentDirectory(path)); }
-bool MyGetCurrentDirectory(CSysString &resultPath);
-#ifndef _UNICODE
-bool MySetCurrentDirectory(LPCWSTR path);
-bool MyGetCurrentDirectory(UString &resultPath);
-#endif
+bool MyGetFullPathName(CFSTR path, FString &resFullPath);
+bool GetFullPathAndSplit(CFSTR path, FString &resDirPrefix, FString &resFileName);
+bool GetOnlyDirPrefix(CFSTR path, FString &resDirPrefix);
-bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension, CSysString &resultPath, UINT32 &filePart);
-#ifndef _UNICODE
-bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, UString &resultPath, UINT32 &filePart);
-#endif
+#ifndef UNDER_CE
-inline bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension, CSysString &resultPath)
-{
- UINT32 value;
- return MySearchPath(path, fileName, extension, resultPath, value);
-}
-
-#ifndef _UNICODE
-inline bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, UString &resultPath)
-{
- UINT32 value;
- return MySearchPath(path, fileName, extension, resultPath, value);
-}
-#endif
+bool SetCurrentDir(CFSTR path);
+bool GetCurrentDir(FString &resultPath);
#endif
-bool MyGetTempPath(CSysString &resultPath);
-#ifndef _UNICODE
-bool MyGetTempPath(UString &resultPath);
-#endif
-
-UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath);
-#ifndef _UNICODE
-UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath);
-#endif
+bool MyGetTempPath(FString &resultPath);
class CTempFile
{
bool _mustBeDeleted;
- CSysString _fileName;
+ FString _path;
+ void DisableDeleting() { _mustBeDeleted = false; }
public:
CTempFile(): _mustBeDeleted(false) {}
~CTempFile() { Remove(); }
- void DisableDeleting() { _mustBeDeleted = false; }
- UINT Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath);
- bool Create(LPCTSTR prefix, CSysString &resultPath);
+ const FString &GetPath() const { return _path; }
+ bool Create(CFSTR pathPrefix, NIO::COutFile *outFile); // pathPrefix is not folder prefix
+ bool CreateRandomInTempFolder(CFSTR namePrefix, NIO::COutFile *outFile);
bool Remove();
+ bool MoveTo(CFSTR name, bool deleteDestBefore);
};
-#ifdef _UNICODE
-typedef CTempFile CTempFileW;
-#else
-class CTempFileW
+class CTempDir
{
bool _mustBeDeleted;
- UString _fileName;
+ FString _path;
public:
- CTempFileW(): _mustBeDeleted(false) {}
- ~CTempFileW() { Remove(); }
+ CTempDir(): _mustBeDeleted(false) {}
+ ~CTempDir() { Remove(); }
+ const FString &GetPath() const { return _path; }
void DisableDeleting() { _mustBeDeleted = false; }
- UINT Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath);
- bool Create(LPCWSTR prefix, UString &resultPath);
+ bool Create(CFSTR namePrefix) ;
bool Remove();
};
-#endif
-
-bool CreateTempDirectory(LPCTSTR prefixChars, CSysString &dirName);
-class CTempDirectory
+#if !defined(UNDER_CE)
+class CCurrentDirRestorer
{
- bool _mustBeDeleted;
- CSysString _tempDir;
+ FString _path;
public:
- const CSysString &GetPath() const { return _tempDir; }
- CTempDirectory(): _mustBeDeleted(false) {}
- ~CTempDirectory() { Remove(); }
- bool Create(LPCTSTR prefix) ;
- bool Remove()
+ bool NeedRestore;
+
+ CCurrentDirRestorer(): NeedRestore(true)
{
- if (!_mustBeDeleted)
- return true;
- _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);
- return (!_mustBeDeleted);
+ GetCurrentDir(_path);
}
- void DisableDeleting() { _mustBeDeleted = false; }
-};
-
-#ifdef _UNICODE
-typedef CTempDirectory CTempDirectoryW;
-#else
-class CTempDirectoryW
-{
- bool _mustBeDeleted;
- UString _tempDir;
-public:
- const UString &GetPath() const { return _tempDir; }
- CTempDirectoryW(): _mustBeDeleted(false) {}
- ~CTempDirectoryW() { Remove(); }
- bool Create(LPCWSTR prefix) ;
- bool Remove()
+ ~CCurrentDirRestorer()
{
- if (!_mustBeDeleted)
- return true;
- _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);
- return (!_mustBeDeleted);
+ if (!NeedRestore)
+ return;
+ FString s;
+ if (GetCurrentDir(s))
+ if (s != _path)
+ SetCurrentDir(_path);
}
- void DisableDeleting() { _mustBeDeleted = false; }
};
#endif
diff --git a/src/libs/7zip/win/CPP/Windows/FileFind.cpp b/src/libs/7zip/win/CPP/Windows/FileFind.cpp
index e3358f905..7f58288fe 100644
--- a/src/libs/7zip/win/CPP/Windows/FileFind.cpp
+++ b/src/libs/7zip/win/CPP/Windows/FileFind.cpp
@@ -4,6 +4,7 @@
#include "FileFind.h"
#include "FileIO.h"
+#include "FileName.h"
#ifndef _UNICODE
#include "../Common/StringConvert.h"
#endif
@@ -12,45 +13,55 @@
extern bool g_IsNT;
#endif
-namespace NWindows {
-namespace NFile {
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
-#ifdef SUPPORT_DEVICE_FILE
-bool IsDeviceName(LPCTSTR n);
-#ifndef _UNICODE
-bool IsDeviceName(LPCWSTR n);
-#endif
-#endif
+#if defined(_WIN32) && !defined(UNDER_CE)
-#if defined(WIN_LONG_PATH) && defined(_UNICODE)
-#define WIN_LONG_PATH2
-#endif
+EXTERN_C_BEGIN
+
+typedef enum
+{
+ My_FindStreamInfoStandard,
+ My_FindStreamInfoMaxInfoLevel
+} MY_STREAM_INFO_LEVELS;
+
+typedef struct
+{
+ LARGE_INTEGER StreamSize;
+ WCHAR cStreamName[MAX_PATH + 36];
+} MY_WIN32_FIND_STREAM_DATA, *MY_PWIN32_FIND_STREAM_DATA;
-bool GetLongPath(LPCWSTR fileName, UString &res);
+typedef WINBASEAPI HANDLE (WINAPI *FindFirstStreamW_Ptr)(LPCWSTR fileName, MY_STREAM_INFO_LEVELS infoLevel,
+ LPVOID findStreamData, DWORD flags);
-namespace NFind {
+typedef WINBASEAPI BOOL (APIENTRY *FindNextStreamW_Ptr)(HANDLE findStream, LPVOID findStreamData);
-static const TCHAR kDot = TEXT('.');
+EXTERN_C_END
-bool CFileInfo::IsDots() const
+#endif
+
+namespace NWindows {
+namespace NFile {
+
+#ifdef SUPPORT_DEVICE_FILE
+namespace NSystem
{
- if (!IsDir() || Name.IsEmpty())
- return false;
- if (Name[0] != kDot)
- return false;
- return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
+bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize);
}
+#endif
-#ifndef _UNICODE
-bool CFileInfoW::IsDots() const
+namespace NFind {
+
+bool CFileInfo::IsDots() const throw()
{
if (!IsDir() || Name.IsEmpty())
return false;
- if (Name[0] != kDot)
+ if (Name[0] != FTEXT('.'))
return false;
- return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
+ return Name.Len() == 1 || (Name.Len() == 2 && Name[1] == FTEXT('.'));
}
-#endif
#define WIN_FD_TO_MY_FI(fi, fd) \
fi.Attrib = fd.dwFileAttributes; \
@@ -58,6 +69,7 @@ bool CFileInfoW::IsDots() const
fi.ATime = fd.ftLastAccessTime; \
fi.MTime = fd.ftLastWriteTime; \
fi.Size = (((UInt64)fd.nFileSizeHigh) << 32) + fd.nFileSizeLow; \
+ fi.IsAltStream = false; \
fi.IsDevice = false;
/*
@@ -68,33 +80,31 @@ bool CFileInfoW::IsDots() const
#endif
*/
-static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATA &fd, CFileInfo &fi)
+static void Convert_WIN32_FIND_DATA_to_FileInfo(const WIN32_FIND_DATAW &fd, CFileInfo &fi)
{
WIN_FD_TO_MY_FI(fi, fd);
- fi.Name = fd.cFileName;
+ fi.Name = us2fs(fd.cFileName);
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ // fi.ShortName = us2fs(fd.cAlternateFileName);
+ #endif
}
#ifndef _UNICODE
-static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
-
-static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATAW &fd, CFileInfoW &fi)
-{
- WIN_FD_TO_MY_FI(fi, fd);
- fi.Name = fd.cFileName;
-}
-
-static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATA &fd, CFileInfoW &fi)
+static void Convert_WIN32_FIND_DATA_to_FileInfo(const WIN32_FIND_DATA &fd, CFileInfo &fi)
{
WIN_FD_TO_MY_FI(fi, fd);
- fi.Name = GetUnicodeString(fd.cFileName, GetCurrentCodePage());
+ fi.Name = fas2fs(fd.cFileName);
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ // fi.ShortName = fas2fs(fd.cAlternateFileName);
+ #endif
}
#endif
-
+
////////////////////////////////
// CFindFile
-bool CFindFile::Close()
+bool CFindFileBase::Close() throw()
{
if (_handle == INVALID_HANDLE_VALUE)
return true;
@@ -104,183 +114,344 @@ bool CFindFile::Close()
return true;
}
-
-bool CFindFile::FindFirst(LPCTSTR wildcard, CFileInfo &fi)
+bool CFindFile::FindFirst(CFSTR path, CFileInfo &fi)
{
if (!Close())
return false;
- WIN32_FIND_DATA fd;
- _handle = ::FindFirstFile(wildcard, &fd);
- #ifdef WIN_LONG_PATH2
- if (_handle == INVALID_HANDLE_VALUE)
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- UString longPath;
- if (GetLongPath(wildcard, longPath))
- _handle = ::FindFirstFileW(longPath, &fd);
+ WIN32_FIND_DATAA fd;
+ _handle = ::FindFirstFileA(fs2fas(path), &fd);
+ if (_handle == INVALID_HANDLE_VALUE)
+ return false;
+ Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi);
}
+ else
#endif
- if (_handle == INVALID_HANDLE_VALUE)
- return false;
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
- return true;
-}
-
-#ifndef _UNICODE
-bool CFindFile::FindFirst(LPCWSTR wildcard, CFileInfoW &fi)
-{
- if (!Close())
- return false;
- if (g_IsNT)
{
WIN32_FIND_DATAW fd;
- _handle = ::FindFirstFileW(wildcard, &fd);
+
+ IF_USE_MAIN_PATH
+ _handle = ::FindFirstFileW(fs2us(path), &fd);
#ifdef WIN_LONG_PATH
- if (_handle == INVALID_HANDLE_VALUE)
+ if (_handle == INVALID_HANDLE_VALUE && USE_SUPER_PATH)
{
UString longPath;
- if (GetLongPath(wildcard, longPath))
+ if (GetSuperPath(path, longPath, USE_MAIN_PATH))
_handle = ::FindFirstFileW(longPath, &fd);
}
#endif
- if (_handle != INVALID_HANDLE_VALUE)
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
+ if (_handle == INVALID_HANDLE_VALUE)
+ return false;
+ Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi);
}
- else
+ return true;
+}
+
+bool CFindFile::FindNext(CFileInfo &fi)
+{
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
WIN32_FIND_DATAA fd;
- _handle = ::FindFirstFileA(UnicodeStringToMultiByte(wildcard,
- GetCurrentCodePage()), &fd);
- if (_handle != INVALID_HANDLE_VALUE)
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
+ if (!::FindNextFileA(_handle, &fd))
+ return false;
+ Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi);
}
- return (_handle != INVALID_HANDLE_VALUE);
+ else
+ #endif
+ {
+ WIN32_FIND_DATAW fd;
+ if (!::FindNextFileW(_handle, &fd))
+ return false;
+ Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi);
+ }
+ return true;
}
-#endif
-bool CFindFile::FindNext(CFileInfo &fi)
+#if defined(_WIN32) && !defined(UNDER_CE)
+
+////////////////////////////////
+// AltStreams
+
+static FindFirstStreamW_Ptr g_FindFirstStreamW;
+static FindNextStreamW_Ptr g_FindNextStreamW;
+
+struct CFindStreamLoader
{
- WIN32_FIND_DATA fd;
- bool result = BOOLToBool(::FindNextFile(_handle, &fd));
- if (result)
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
- return result;
+ CFindStreamLoader()
+ {
+ g_FindFirstStreamW = (FindFirstStreamW_Ptr)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "FindFirstStreamW");
+ g_FindNextStreamW = (FindNextStreamW_Ptr)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "FindNextStreamW");
+ }
+} g_FindStreamLoader;
+
+bool CStreamInfo::IsMainStream() const throw()
+{
+ return Name == L"::$DATA";
+};
+
+UString CStreamInfo::GetReducedName() const
+{
+ UString s = Name;
+ if (s.Len() >= 6)
+ if (wcscmp(s.RightPtr(6), L":$DATA") == 0)
+ s.DeleteFrom(s.Len() - 6);
+ return s;
}
-#ifndef _UNICODE
-bool CFindFile::FindNext(CFileInfoW &fi)
+static void Convert_WIN32_FIND_STREAM_DATA_to_StreamInfo(const MY_WIN32_FIND_STREAM_DATA &sd, CStreamInfo &si)
+{
+ si.Size = sd.StreamSize.QuadPart;
+ si.Name = sd.cStreamName;
+}
+
+bool CFindStream::FindFirst(CFSTR path, CStreamInfo &si)
{
- if (g_IsNT)
+ if (!Close())
+ return false;
+ if (!g_FindFirstStreamW)
{
- WIN32_FIND_DATAW fd;
- if (!::FindNextFileW(_handle, &fd))
+ ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return false;
+ }
+ {
+ MY_WIN32_FIND_STREAM_DATA sd;
+ IF_USE_MAIN_PATH
+ _handle = g_FindFirstStreamW(fs2us(path), My_FindStreamInfoStandard, &sd, 0);
+ if (_handle == INVALID_HANDLE_VALUE)
+ {
+ if (::GetLastError() == ERROR_HANDLE_EOF)
+ return false;
+ // long name can be tricky for path like ".\dirName".
+ #ifdef WIN_LONG_PATH
+ if (USE_SUPER_PATH)
+ {
+ UString longPath;
+ if (GetSuperPath(path, longPath, USE_MAIN_PATH))
+ _handle = g_FindFirstStreamW(longPath, My_FindStreamInfoStandard, &sd, 0);
+ }
+ #endif
+ }
+ if (_handle == INVALID_HANDLE_VALUE)
return false;
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
+ Convert_WIN32_FIND_STREAM_DATA_to_StreamInfo(sd, si);
}
- else
+ return true;
+}
+
+bool CFindStream::FindNext(CStreamInfo &si)
+{
+ if (!g_FindNextStreamW)
{
- WIN32_FIND_DATAA fd;
- if (!::FindNextFileA(_handle, &fd))
+ ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return false;
+ }
+ {
+ MY_WIN32_FIND_STREAM_DATA sd;
+ if (!g_FindNextStreamW(_handle, &sd))
return false;
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
+ Convert_WIN32_FIND_STREAM_DATA_to_StreamInfo(sd, si);
}
return true;
}
+
+bool CStreamEnumerator::Next(CStreamInfo &si, bool &found)
+{
+ bool res;
+ if (_find.IsHandleAllocated())
+ res = _find.FindNext(si);
+ else
+ res = _find.FindFirst(_filePath, si);
+ if (res)
+ {
+ found = true;
+ return true;
+ }
+ found = false;
+ return (::GetLastError() == ERROR_HANDLE_EOF);
+}
+
#endif
+
#define MY_CLEAR_FILETIME(ft) ft.dwLowDateTime = ft.dwHighDateTime = 0;
-void CFileInfoBase::Clear()
+void CFileInfoBase::Clear() throw()
{
Size = 0;
MY_CLEAR_FILETIME(CTime);
MY_CLEAR_FILETIME(ATime);
MY_CLEAR_FILETIME(MTime);
Attrib = 0;
+ IsAltStream = false;
+ IsDevice = false;
}
-
-bool CFileInfo::Find(LPCTSTR wildcard)
+
+#if defined(_WIN32) && !defined(UNDER_CE)
+
+static int FindAltStreamColon(CFSTR path)
{
- #ifdef SUPPORT_DEVICE_FILE
- if (IsDeviceName(wildcard))
+ for (int i = 0;; i++)
{
- Clear();
- IsDevice = true;
- NIO::CInFile inFile;
- if (!inFile.Open(wildcard))
- return false;
- Name = wildcard + 4;
- if (inFile.LengthDefined)
- Size = inFile.Length;
- return true;
+ FChar c = path[i];
+ if (c == 0)
+ return -1;
+ if (c == ':')
+ {
+ if (path[i + 1] == '\\')
+ if (i == 1 || (i > 1 && path[i - 2] == '\\'))
+ {
+ wchar_t c0 = path[i - 1];
+ if (c0 >= 'a' && c0 <= 'z' ||
+ c0 >= 'A' && c0 <= 'Z')
+ continue;
+ }
+ return i;
+ }
}
- #endif
- CFindFile finder;
- return finder.FindFirst(wildcard, *this);
}
+#endif
-#ifndef _UNICODE
-bool CFileInfoW::Find(LPCWSTR wildcard)
+bool CFileInfo::Find(CFSTR path)
{
#ifdef SUPPORT_DEVICE_FILE
- if (IsDeviceName(wildcard))
+ if (IsDevicePath(path))
{
Clear();
+ Name = path + 4;
+
IsDevice = true;
+ if (/* path[0] == '\\' && path[1] == '\\' && path[2] == '.' && path[3] == '\\' && */
+ path[5] == ':' && path[6] == 0)
+ {
+ FChar drive[4] = { path[4], ':', '\\', 0 };
+ UInt64 clusterSize, totalSize, freeSize;
+ if (NSystem::MyGetDiskFreeSpace(drive, clusterSize, totalSize, freeSize))
+ {
+ Size = totalSize;
+ return true;
+ }
+ }
+
NIO::CInFile inFile;
- if (!inFile.Open(wildcard))
+ // ::OutputDebugStringW(path);
+ if (!inFile.Open(path))
return false;
- Name = wildcard + 4;
- if (inFile.LengthDefined)
- Size = inFile.Length;
+ // ::OutputDebugStringW(L"---");
+ if (inFile.SizeDefined)
+ Size = inFile.Size;
return true;
}
#endif
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+
+ int colonPos = FindAltStreamColon(path);
+ if (colonPos >= 0)
+ {
+ UString streamName = fs2us(path + (unsigned)colonPos);
+ FString filePath = path;
+ filePath.DeleteFrom(colonPos);
+ streamName += L":$DATA"; // change it!!!!
+ if (Find(filePath))
+ {
+ // if (IsDir())
+ Attrib &= ~FILE_ATTRIBUTE_DIRECTORY;
+ Size = 0;
+ CStreamEnumerator enumerator(filePath);
+ for (;;)
+ {
+ CStreamInfo si;
+ bool found;
+ if (!enumerator.Next(si, found))
+ return false;
+ if (!found)
+ {
+ ::SetLastError(ERROR_FILE_NOT_FOUND);
+ return false;
+ }
+ if (si.Name.IsEqualToNoCase(streamName))
+ {
+ Name += us2fs(si.Name);
+ Name.DeleteFrom(Name.Len() - 6);
+ Size = si.Size;
+ IsAltStream = true;
+ return true;
+ }
+ }
+ }
+ }
+
+ #endif
+
CFindFile finder;
- return finder.FindFirst(wildcard, *this);
+ if (finder.FindFirst(path, *this))
+ return true;
+ #ifdef _WIN32
+ {
+ DWORD lastError = GetLastError();
+ if (lastError == ERROR_BAD_NETPATH ||
+ lastError == ERROR_FILE_NOT_FOUND ||
+ lastError == ERROR_INVALID_NAME // for "\\SERVER\shared" paths that are translated to "\\?\UNC\SERVER\shared"
+ )
+ {
+ unsigned len = MyStringLen(path);
+ if (len > 2 && path[0] == '\\' && path[1] == '\\')
+ {
+ int startPos = 2;
+ if (len > kSuperUncPathPrefixSize && IsSuperUncPath(path))
+ startPos = kSuperUncPathPrefixSize;
+ int pos = FindCharPosInString(path + startPos, FTEXT('\\'));
+ if (pos >= 0)
+ {
+ pos += startPos + 1;
+ len -= pos;
+ int pos2 = FindCharPosInString(path + pos, FTEXT('\\'));
+ if (pos2 < 0 || pos2 == (int)len - 1)
+ {
+ FString s = path;
+ if (pos2 < 0)
+ {
+ pos2 = len;
+ s += FTEXT('\\');
+ }
+ s += FCHAR_ANY_MASK;
+ if (finder.FindFirst(s, *this))
+ if (Name == FTEXT("."))
+ {
+ Name.SetFrom(s.Ptr(pos), pos2);
+ return true;
+ }
+ ::SetLastError(lastError);
+ }
+ }
+ }
+ }
+ }
+ #endif
+ return false;
}
-#endif
-bool DoesFileExist(LPCTSTR name)
+bool DoesFileExist(CFSTR name)
{
CFileInfo fi;
return fi.Find(name) && !fi.IsDir();
}
-bool DoesDirExist(LPCTSTR name)
+bool DoesDirExist(CFSTR name)
{
CFileInfo fi;
return fi.Find(name) && fi.IsDir();
}
-
-bool DoesFileOrDirExist(LPCTSTR name)
+bool DoesFileOrDirExist(CFSTR name)
{
CFileInfo fi;
return fi.Find(name);
}
-#ifndef _UNICODE
-bool DoesFileExist(LPCWSTR name)
-{
- CFileInfoW fi;
- return fi.Find(name) && !fi.IsDir();
-}
-
-bool DoesDirExist(LPCWSTR name)
-{
- CFileInfoW fi;
- return fi.Find(name) && fi.IsDir();
-}
-bool DoesFileOrDirExist(LPCWSTR name)
-{
- CFileInfoW fi;
- return fi.Find(name);
-}
-#endif
-
-/////////////////////////////////////
-// CEnumerator
-
bool CEnumerator::NextAny(CFileInfo &fi)
{
if (_findFile.IsHandleAllocated())
@@ -311,44 +482,11 @@ bool CEnumerator::Next(CFileInfo &fi, bool &found)
return (::GetLastError() == ERROR_NO_MORE_FILES);
}
-#ifndef _UNICODE
-bool CEnumeratorW::NextAny(CFileInfoW &fi)
-{
- if (_findFile.IsHandleAllocated())
- return _findFile.FindNext(fi);
- else
- return _findFile.FindFirst(_wildcard, fi);
-}
-
-bool CEnumeratorW::Next(CFileInfoW &fi)
-{
- for (;;)
- {
- if (!NextAny(fi))
- return false;
- if (!fi.IsDots())
- return true;
- }
-}
-
-bool CEnumeratorW::Next(CFileInfoW &fi, bool &found)
-{
- if (Next(fi))
- {
- found = true;
- return true;
- }
- found = false;
- return (::GetLastError() == ERROR_NO_MORE_FILES);
-}
-
-#endif
-
////////////////////////////////
// CFindChangeNotification
// FindFirstChangeNotification can return 0. MSDN doesn't tell about it.
-bool CFindChangeNotification::Close()
+bool CFindChangeNotification::Close() throw()
{
if (!IsHandleAllocated())
return true;
@@ -357,105 +495,84 @@ bool CFindChangeNotification::Close()
_handle = INVALID_HANDLE_VALUE;
return true;
}
-
-HANDLE CFindChangeNotification::FindFirst(LPCTSTR pathName, bool watchSubtree, DWORD notifyFilter)
-{
- _handle = ::FindFirstChangeNotification(pathName, BoolToBOOL(watchSubtree), notifyFilter);
- #ifdef WIN_LONG_PATH2
- if (!IsHandleAllocated())
- {
- UString longPath;
- if (GetLongPath(pathName, longPath))
- _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
- }
- #endif
- return _handle;
-}
-#ifndef _UNICODE
-HANDLE CFindChangeNotification::FindFirst(LPCWSTR pathName, bool watchSubtree, DWORD notifyFilter)
+HANDLE CFindChangeNotification::FindFirst(CFSTR path, bool watchSubtree, DWORD notifyFilter)
{
+ #ifndef _UNICODE
if (!g_IsNT)
- return FindFirst(UnicodeStringToMultiByte(pathName, GetCurrentCodePage()), watchSubtree, notifyFilter);
- _handle = ::FindFirstChangeNotificationW(pathName, BoolToBOOL(watchSubtree), notifyFilter);
- #ifdef WIN_LONG_PATH
- if (!IsHandleAllocated())
+ _handle = ::FindFirstChangeNotification(fs2fas(path), BoolToBOOL(watchSubtree), notifyFilter);
+ else
+ #endif
{
- UString longPath;
- if (GetLongPath(pathName, longPath))
- _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
+ IF_USE_MAIN_PATH
+ _handle = ::FindFirstChangeNotificationW(fs2us(path), BoolToBOOL(watchSubtree), notifyFilter);
+ #ifdef WIN_LONG_PATH
+ if (!IsHandleAllocated())
+ {
+ UString longPath;
+ if (GetSuperPath(path, longPath, USE_MAIN_PATH))
+ _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
+ }
+ #endif
}
- #endif
return _handle;
}
-#endif
#ifndef UNDER_CE
-bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings)
+
+bool MyGetLogicalDriveStrings(CObjectVector<FString> &driveStrings)
{
driveStrings.Clear();
- UINT32 size = GetLogicalDriveStrings(0, NULL);
- if (size == 0)
- return false;
- CSysString buffer;
- UINT32 newSize = GetLogicalDriveStrings(size, buffer.GetBuffer(size));
- if (newSize == 0)
- return false;
- if (newSize > size)
- return false;
- CSysString string;
- for (UINT32 i = 0; i < newSize; i++)
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- TCHAR c = buffer[i];
- if (c == TEXT('\0'))
+ driveStrings.Clear();
+ UINT32 size = GetLogicalDriveStrings(0, NULL);
+ if (size == 0)
+ return false;
+ AString buf;
+ UINT32 newSize = GetLogicalDriveStrings(size, buf.GetBuffer(size));
+ if (newSize == 0 || newSize > size)
+ return false;
+ AString s;
+ for (UINT32 i = 0; i < newSize; i++)
{
- driveStrings.Add(string);
- string.Empty();
+ char c = buf[i];
+ if (c == '\0')
+ {
+ driveStrings.Add(fas2fs(s));
+ s.Empty();
+ }
+ else
+ s += c;
}
- else
- string += c;
+ return s.IsEmpty();
}
- if (!string.IsEmpty())
- return false;
- return true;
-}
-
-#ifndef _UNICODE
-bool MyGetLogicalDriveStrings(UStringVector &driveStrings)
-{
- driveStrings.Clear();
- if (g_IsNT)
+ else
+ #endif
{
UINT32 size = GetLogicalDriveStringsW(0, NULL);
if (size == 0)
return false;
- UString buffer;
- UINT32 newSize = GetLogicalDriveStringsW(size, buffer.GetBuffer(size));
- if (newSize == 0)
- return false;
- if (newSize > size)
+ UString buf;
+ UINT32 newSize = GetLogicalDriveStringsW(size, buf.GetBuffer(size));
+ if (newSize == 0 || newSize > size)
return false;
- UString string;
+ UString s;
for (UINT32 i = 0; i < newSize; i++)
{
- WCHAR c = buffer[i];
+ WCHAR c = buf[i];
if (c == L'\0')
{
- driveStrings.Add(string);
- string.Empty();
+ driveStrings.Add(us2fs(s));
+ s.Empty();
}
else
- string += c;
+ s += c;
}
- return string.IsEmpty();
+ return s.IsEmpty();
}
- CSysStringVector driveStringsA;
- bool res = MyGetLogicalDriveStrings(driveStringsA);
- for (int i = 0; i < driveStringsA.Size(); i++)
- driveStrings.Add(GetUnicodeString(driveStringsA[i]));
- return res;
}
-#endif
#endif
diff --git a/src/libs/7zip/win/CPP/Windows/FileFind.h b/src/libs/7zip/win/CPP/Windows/FileFind.h
index 63631f66b..aaa7499bd 100644
--- a/src/libs/7zip/win/CPP/Windows/FileFind.h
+++ b/src/libs/7zip/win/CPP/Windows/FileFind.h
@@ -1,12 +1,10 @@
// Windows/FileFind.h
-#ifndef __WINDOWS_FILEFIND_H
-#define __WINDOWS_FILEFIND_H
+#ifndef __WINDOWS_FILE_FIND_H
+#define __WINDOWS_FILE_FIND_H
#include "../Common/MyString.h"
-#include "../Common/Types.h"
#include "Defs.h"
-#include "FileName.h"
namespace NWindows {
namespace NFile {
@@ -26,14 +24,13 @@ namespace NAttributes
class CFileInfoBase
{
bool MatchesMask(UINT32 mask) const { return ((Attrib & mask) != 0); }
-protected:
- void Clear();
public:
UInt64 Size;
FILETIME CTime;
FILETIME ATime;
FILETIME MTime;
DWORD Attrib;
+ bool IsAltStream;
bool IsDevice;
/*
@@ -44,6 +41,11 @@ public:
#endif
*/
+ CFileInfoBase() { Clear(); }
+ void Clear() throw();
+
+ void SetAsDir() { Attrib = FILE_ATTRIBUTE_DIRECTORY; }
+
bool IsArchived() const { return MatchesMask(FILE_ATTRIBUTE_ARCHIVE); }
bool IsCompressed() const { return MatchesMask(FILE_ATTRIBUTE_COMPRESSED); }
bool IsDir() const { return MatchesMask(FILE_ATTRIBUTE_DIRECTORY); }
@@ -60,78 +62,80 @@ public:
struct CFileInfo: public CFileInfoBase
{
- CSysString Name;
+ FString Name;
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ // FString ShortName;
+ #endif
+
+ bool IsDots() const throw();
+ bool Find(CFSTR wildcard);
+};
+
+class CFindFileBase
+{
+protected:
+ HANDLE _handle;
+public:
+ bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE; }
+ CFindFileBase(): _handle(INVALID_HANDLE_VALUE) {}
+ ~CFindFileBase() { Close(); }
+ bool Close() throw();
+};
- bool IsDots() const;
- bool Find(LPCTSTR wildcard);
+class CFindFile: public CFindFileBase
+{
+public:
+ bool FindFirst(CFSTR wildcard, CFileInfo &fileInfo);
+ bool FindNext(CFileInfo &fileInfo);
};
-#ifdef _UNICODE
-typedef CFileInfo CFileInfoW;
-#else
-struct CFileInfoW: public CFileInfoBase
+#if defined(_WIN32) && !defined(UNDER_CE)
+
+struct CStreamInfo
{
UString Name;
+ UInt64 Size;
- bool IsDots() const;
- bool Find(LPCWSTR wildcard);
+ UString GetReducedName() const;
+ bool IsMainStream() const throw();
};
-#endif
-class CFindFile
+class CFindStream: public CFindFileBase
{
- friend class CEnumerator;
- HANDLE _handle;
public:
- bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE; }
- CFindFile(): _handle(INVALID_HANDLE_VALUE) {}
- ~CFindFile() { Close(); }
- bool FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo);
- bool FindNext(CFileInfo &fileInfo);
- #ifndef _UNICODE
- bool FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo);
- bool FindNext(CFileInfoW &fileInfo);
- #endif
- bool Close();
+ bool FindFirst(CFSTR filePath, CStreamInfo &streamInfo);
+ bool FindNext(CStreamInfo &streamInfo);
+};
+
+class CStreamEnumerator
+{
+ CFindStream _find;
+ FString _filePath;
+
+ bool NextAny(CFileInfo &fileInfo);
+public:
+ CStreamEnumerator(const FString &filePath): _filePath(filePath) {}
+ bool Next(CStreamInfo &streamInfo, bool &found);
};
-bool DoesFileExist(LPCTSTR name);
-bool DoesDirExist(LPCTSTR name);
-bool DoesFileOrDirExist(LPCTSTR name);
-#ifndef _UNICODE
-bool DoesFileExist(LPCWSTR name);
-bool DoesDirExist(LPCWSTR name);
-bool DoesFileOrDirExist(LPCWSTR name);
#endif
+bool DoesFileExist(CFSTR name);
+bool DoesDirExist(CFSTR name);
+bool DoesFileOrDirExist(CFSTR name);
+
class CEnumerator
{
CFindFile _findFile;
- CSysString _wildcard;
+ FString _wildcard;
+
bool NextAny(CFileInfo &fileInfo);
public:
- CEnumerator(): _wildcard(NName::kAnyStringWildcard) {}
- CEnumerator(const CSysString &wildcard): _wildcard(wildcard) {}
+ CEnumerator(const FString &wildcard): _wildcard(wildcard) {}
bool Next(CFileInfo &fileInfo);
bool Next(CFileInfo &fileInfo, bool &found);
};
-#ifdef _UNICODE
-typedef CEnumerator CEnumeratorW;
-#else
-class CEnumeratorW
-{
- CFindFile _findFile;
- UString _wildcard;
- bool NextAny(CFileInfoW &fileInfo);
-public:
- CEnumeratorW(): _wildcard(NName::kAnyStringWildcard) {}
- CEnumeratorW(const UString &wildcard): _wildcard(wildcard) {}
- bool Next(CFileInfoW &fileInfo);
- bool Next(CFileInfoW &fileInfo, bool &found);
-};
-#endif
-
class CFindChangeNotification
{
HANDLE _handle;
@@ -140,22 +144,15 @@ public:
bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE && _handle != 0; }
CFindChangeNotification(): _handle(INVALID_HANDLE_VALUE) {}
~CFindChangeNotification() { Close(); }
- bool Close();
- HANDLE FindFirst(LPCTSTR pathName, bool watchSubtree, DWORD notifyFilter);
- #ifndef _UNICODE
- HANDLE FindFirst(LPCWSTR pathName, bool watchSubtree, DWORD notifyFilter);
- #endif
+ bool Close() throw();
+ HANDLE FindFirst(CFSTR pathName, bool watchSubtree, DWORD notifyFilter);
bool FindNext() { return BOOLToBool(::FindNextChangeNotification(_handle)); }
};
#ifndef UNDER_CE
-bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings);
-#ifndef _UNICODE
-bool MyGetLogicalDriveStrings(UStringVector &driveStrings);
-#endif
+bool MyGetLogicalDriveStrings(CObjectVector<FString> &driveStrings);
#endif
}}}
#endif
-
diff --git a/src/libs/7zip/win/CPP/Windows/FileIO.cpp b/src/libs/7zip/win/CPP/Windows/FileIO.cpp
index 938e6c701..fec859ed3 100644
--- a/src/libs/7zip/win/CPP/Windows/FileIO.cpp
+++ b/src/libs/7zip/win/CPP/Windows/FileIO.cpp
@@ -2,161 +2,86 @@
#include "StdAfx.h"
-#include "FileIO.h"
-
-#if defined(WIN_LONG_PATH) || defined(SUPPORT_DEVICE_FILE)
-#include "../Common/MyString.h"
-#endif
-#ifndef _UNICODE
-#include "../Common/StringConvert.h"
+#ifdef SUPPORT_DEVICE_FILE
+#include "../../C/Alloc.h"
#endif
+#include "FileIO.h"
+#include "FileName.h"
+
#ifndef _UNICODE
extern bool g_IsNT;
#endif
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
+
namespace NWindows {
namespace NFile {
#ifdef SUPPORT_DEVICE_FILE
-bool IsDeviceName(LPCTSTR n)
-{
- #ifdef UNDER_CE
- int len = (int)MyStringLen(n);
- if (len < 5 || len > 5 || memcmp(n, TEXT("DSK"), 3 * sizeof(TCHAR)) != 0)
- return false;
- if (n[4] != ':')
- return false;
- // for reading use SG_REQ sg; if (DeviceIoControl(dsk, IOCTL_DISK_READ));
- #else
- if (n[0] != '\\' || n[1] != '\\' || n[2] != '.' || n[3] != '\\')
- return false;
- int len = (int)MyStringLen(n);
- if (len == 6 && n[5] == ':')
- return true;
- if (len < 18 || len > 22 || memcmp(n + 4, TEXT("PhysicalDrive"), 13 * sizeof(TCHAR)) != 0)
- return false;
- for (int i = 17; i < len; i++)
- if (n[i] < '0' || n[i] > '9')
- return false;
- #endif
- return true;
-}
-#ifndef _UNICODE
-bool IsDeviceName(LPCWSTR n)
+namespace NSystem
{
- if (n[0] != '\\' || n[1] != '\\' || n[2] != '.' || n[3] != '\\')
- return false;
- int len = (int)wcslen(n);
- if (len == 6 && n[5] == ':')
- return true;
- if (len < 18 || len > 22 || wcsncmp(n + 4, L"PhysicalDrive", 13) != 0)
- return false;
- for (int i = 17; i < len; i++)
- if (n[i] < '0' || n[i] > '9')
- return false;
- return true;
+bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize);
}
#endif
-#endif
-#if defined(WIN_LONG_PATH) && defined(_UNICODE)
-#define WIN_LONG_PATH2
-#endif
-
-#ifdef WIN_LONG_PATH
-bool GetLongPathBase(LPCWSTR s, UString &res)
-{
- res.Empty();
- int len = MyStringLen(s);
- wchar_t c = s[0];
- if (len < 1 || c == L'\\' || c == L'.' && (len == 1 || len == 2 && s[1] == L'.'))
- return true;
- UString curDir;
- bool isAbs = false;
- if (len > 3)
- isAbs = (s[1] == L':' && s[2] == L'\\' && (c >= L'a' && c <= L'z' || c >= L'A' && c <= L'Z'));
+namespace NIO {
- if (!isAbs)
- {
- DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, curDir.GetBuffer(MAX_PATH + 1));
- curDir.ReleaseBuffer();
- if (needLength == 0 || needLength > MAX_PATH)
- return false;
- if (curDir[curDir.Length() - 1] != L'\\')
- curDir += L'\\';
- }
- res = UString(L"\\\\?\\") + curDir + s;
- return true;
-}
+/*
+WinXP-64 CreateFile():
+ "" - ERROR_PATH_NOT_FOUND
+ :stream - OK
+ .:stream - ERROR_PATH_NOT_FOUND
+ .\:stream - OK
-bool GetLongPath(LPCWSTR path, UString &longPath)
-{
- if (GetLongPathBase(path, longPath))
- return !longPath.IsEmpty();
- return false;
-}
-#endif
+ folder\:stream - ERROR_INVALID_NAME
+ folder:stream - OK
-namespace NIO {
+ c:\:stream - OK
-CFileBase::~CFileBase() { Close(); }
+ c::stream - ERROR_INVALID_NAME, if current dir is NOT ROOT ( c:\dir1 )
+ c::stream - OK, if current dir is ROOT ( c:\ )
+*/
-bool CFileBase::Create(LPCTSTR fileName, DWORD desiredAccess,
+bool CFileBase::Create(CFSTR path, DWORD desiredAccess,
DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
{
if (!Close())
return false;
- _handle = ::CreateFile(fileName, desiredAccess, shareMode,
- (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
- flagsAndAttributes, (HANDLE)NULL);
- #ifdef WIN_LONG_PATH2
- if (_handle == INVALID_HANDLE_VALUE)
- {
- UString longPath;
- if (GetLongPath(fileName, longPath))
- _handle = ::CreateFileW(longPath, desiredAccess, shareMode,
- (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
- flagsAndAttributes, (HANDLE)NULL);
- }
- #endif
+
#ifdef SUPPORT_DEVICE_FILE
IsDeviceFile = false;
#endif
- return (_handle != INVALID_HANDLE_VALUE);
-}
-#ifndef _UNICODE
-bool CFileBase::Create(LPCWSTR fileName, DWORD desiredAccess,
- DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
-{
+ #ifndef _UNICODE
if (!g_IsNT)
- return Create(UnicodeStringToMultiByte(fileName, ::AreFileApisANSI() ? CP_ACP : CP_OEMCP),
- desiredAccess, shareMode, creationDisposition, flagsAndAttributes);
- if (!Close())
- return false;
- _handle = ::CreateFileW(fileName, desiredAccess, shareMode,
- (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
- flagsAndAttributes, (HANDLE)NULL);
- #ifdef WIN_LONG_PATH
- if (_handle == INVALID_HANDLE_VALUE)
{
- UString longPath;
- if (GetLongPath(fileName, longPath))
- _handle = ::CreateFileW(longPath, desiredAccess, shareMode,
- (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
- flagsAndAttributes, (HANDLE)NULL);
+ _handle = ::CreateFile(fs2fas(path), desiredAccess, shareMode,
+ (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, flagsAndAttributes, (HANDLE)NULL);
}
+ else
#endif
- #ifdef SUPPORT_DEVICE_FILE
- IsDeviceFile = false;
- #endif
+ {
+ IF_USE_MAIN_PATH
+ _handle = ::CreateFileW(fs2us(path), desiredAccess, shareMode,
+ (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, flagsAndAttributes, (HANDLE)NULL);
+ #ifdef WIN_LONG_PATH
+ if (_handle == INVALID_HANDLE_VALUE && USE_SUPER_PATH)
+ {
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ _handle = ::CreateFileW(superPath, desiredAccess, shareMode,
+ (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, flagsAndAttributes, (HANDLE)NULL);
+ }
+ #endif
+ }
return (_handle != INVALID_HANDLE_VALUE);
}
-#endif
-bool CFileBase::Close()
+bool CFileBase::Close() throw()
{
if (_handle == INVALID_HANDLE_VALUE)
return true;
@@ -166,17 +91,17 @@ bool CFileBase::Close()
return true;
}
-bool CFileBase::GetPosition(UInt64 &position) const
+bool CFileBase::GetPosition(UInt64 &position) const throw()
{
return Seek(0, FILE_CURRENT, position);
}
-bool CFileBase::GetLength(UInt64 &length) const
+bool CFileBase::GetLength(UInt64 &length) const throw()
{
#ifdef SUPPORT_DEVICE_FILE
- if (IsDeviceFile && LengthDefined)
+ if (IsDeviceFile && SizeDefined)
{
- length = Length;
+ length = Size;
return true;
}
#endif
@@ -190,127 +115,211 @@ bool CFileBase::GetLength(UInt64 &length) const
return true;
}
-bool CFileBase::Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const
+bool CFileBase::Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const throw()
{
#ifdef SUPPORT_DEVICE_FILE
- if (IsDeviceFile && LengthDefined && moveMethod == FILE_END)
+ if (IsDeviceFile && SizeDefined && moveMethod == FILE_END)
{
- distanceToMove += Length;
+ distanceToMove += Size;
moveMethod = FILE_BEGIN;
}
#endif
- LARGE_INTEGER value;
- value.QuadPart = distanceToMove;
- value.LowPart = ::SetFilePointer(_handle, value.LowPart, &value.HighPart, moveMethod);
- if (value.LowPart == 0xFFFFFFFF)
+ LONG high = (LONG)(distanceToMove >> 32);
+ DWORD low = ::SetFilePointer(_handle, (LONG)(distanceToMove & 0xFFFFFFFF), &high, moveMethod);
+ if (low == 0xFFFFFFFF)
if (::GetLastError() != NO_ERROR)
return false;
- newPosition = value.QuadPart;
+ newPosition = (((UInt64)high) << 32) + low;
return true;
}
-bool CFileBase::Seek(UInt64 position, UInt64 &newPosition)
+bool CFileBase::Seek(UInt64 position, UInt64 &newPosition) const throw()
{
return Seek(position, FILE_BEGIN, newPosition);
}
-bool CFileBase::SeekToBegin()
+bool CFileBase::SeekToBegin() const throw()
{
UInt64 newPosition;
return Seek(0, newPosition);
}
-bool CFileBase::SeekToEnd(UInt64 &newPosition)
+bool CFileBase::SeekToEnd(UInt64 &newPosition) const throw()
{
return Seek(0, FILE_END, newPosition);
}
-bool CFileBase::GetFileInformation(CByHandleFileInfo &fileInfo) const
+// ---------- CInFile ---------
+
+#ifdef SUPPORT_DEVICE_FILE
+
+void CInFile::CorrectDeviceSize()
{
- BY_HANDLE_FILE_INFORMATION winFileInfo;
- if (!::GetFileInformationByHandle(_handle, &winFileInfo))
- return false;
- fileInfo.Attrib = winFileInfo.dwFileAttributes;
- fileInfo.CTime = winFileInfo.ftCreationTime;
- fileInfo.ATime = winFileInfo.ftLastAccessTime;
- fileInfo.MTime = winFileInfo.ftLastWriteTime;
- fileInfo.VolumeSerialNumber = winFileInfo.dwFileAttributes;
- fileInfo.Size = (((UInt64)winFileInfo.nFileSizeHigh) << 32) + winFileInfo.nFileSizeLow;
- fileInfo.NumberOfLinks = winFileInfo.nNumberOfLinks;
- fileInfo.FileIndex = (((UInt64)winFileInfo.nFileIndexHigh) << 32) + winFileInfo.nFileIndexLow;
- return true;
+ // maybe we must decrease kClusterSize to 1 << 12, if we want correct size at tail
+ static const UInt32 kClusterSize = 1 << 14;
+ UInt64 pos = Size & ~(UInt64)(kClusterSize - 1);
+ UInt64 realNewPosition;
+ if (!Seek(pos, realNewPosition))
+ return;
+ Byte *buf = (Byte *)MidAlloc(kClusterSize);
+
+ bool needbackward = true;
+
+ for (;;)
+ {
+ UInt32 processed = 0;
+ // up test is slow for "PhysicalDrive".
+ // processed size for latest block for "PhysicalDrive0" is 0.
+ if (!Read1(buf, kClusterSize, processed))
+ break;
+ if (processed == 0)
+ break;
+ needbackward = false;
+ Size = pos + processed;
+ if (processed != kClusterSize)
+ break;
+ pos += kClusterSize;
+ }
+
+ if (needbackward && pos != 0)
+ {
+ pos -= kClusterSize;
+ for (;;)
+ {
+ // break;
+ if (!Seek(pos, realNewPosition))
+ break;
+ if (!buf)
+ {
+ buf = (Byte *)MidAlloc(kClusterSize);
+ if (!buf)
+ break;
+ }
+ UInt32 processed = 0;
+ // that code doesn't work for "PhysicalDrive0"
+ if (!Read1(buf, kClusterSize, processed))
+ break;
+ if (processed != 0)
+ {
+ Size = pos + processed;
+ break;
+ }
+ if (pos == 0)
+ break;
+ pos -= kClusterSize;
+ }
+ }
+ MidFree(buf);
}
-/////////////////////////
-// CInFile
-#ifdef SUPPORT_DEVICE_FILE
-void CInFile::GetDeviceLength()
+void CInFile::CalcDeviceSize(CFSTR s)
{
- if (_handle != INVALID_HANDLE_VALUE && IsDeviceFile)
- {
- #ifdef UNDER_CE
- LengthDefined = true;
- Length = 128 << 20;
+ SizeDefined = false;
+ Size = 0;
+ if (_handle == INVALID_HANDLE_VALUE || !IsDeviceFile)
+ return;
+ #ifdef UNDER_CE
+
+ SizeDefined = true;
+ Size = 128 << 20;
+
+ #else
+
+ PARTITION_INFORMATION partInfo;
+ bool needCorrectSize = true;
- #else
- PARTITION_INFORMATION partInfo;
- LengthDefined = true;
- Length = 0;
+ /*
+ WinXP 64-bit:
+
+ HDD \\.\PhysicalDrive0 (MBR):
+ GetPartitionInfo == GeometryEx : corrrect size? (includes tail)
+ Geometry : smaller than GeometryEx (no tail, maybe correct too?)
+ MyGetDiskFreeSpace : FAIL
+ Size correction is slow and block size (kClusterSize) must be small?
+
+ HDD partition \\.\N: (NTFS):
+ MyGetDiskFreeSpace : Size of NTFS clusters. Same size can be calculated after correction
+ GetPartitionInfo : size of partition data: NTFS clusters + TAIL; TAIL contains extra empty sectors and copy of first sector of NTFS
+ Geometry / CdRomGeometry / GeometryEx : size of HDD (not that partition)
+
+ CD-ROM drive (ISO):
+ MyGetDiskFreeSpace : correct size. Same size can be calculated after correction
+ Geometry == CdRomGeometry : smaller than corrrect size
+ GetPartitionInfo == GeometryEx : larger than corrrect size
+
+ Floppy \\.\a: (FAT):
+ Geometry : correct size.
+ CdRomGeometry / GeometryEx / GetPartitionInfo / MyGetDiskFreeSpace - FAIL
+ correction works OK for FAT.
+ correction works OK for non-FAT, if kClusterSize = 512.
+ */
+
+ if (GetPartitionInfo(&partInfo))
+ {
+ Size = partInfo.PartitionLength.QuadPart;
+ SizeDefined = true;
+ needCorrectSize = false;
+ if ((s)[0] == '\\' && (s)[1] == '\\' && (s)[2] == '.' && (s)[3] == '\\' && (s)[5] == ':' && (s)[6] == 0)
+ {
+ FChar path[4] = { s[4], ':', '\\', 0 };
+ UInt64 clusterSize, totalSize, freeSize;
+ if (NSystem::MyGetDiskFreeSpace(path, clusterSize, totalSize, freeSize))
+ Size = totalSize;
+ else
+ needCorrectSize = true;
+ }
+ }
- if (GetPartitionInfo(&partInfo))
- Length = partInfo.PartitionLength.QuadPart;
+ if (!SizeDefined)
+ {
+ my_DISK_GEOMETRY_EX geomEx;
+ SizeDefined = GetGeometryEx(&geomEx);
+ if (SizeDefined)
+ Size = geomEx.DiskSize.QuadPart;
else
{
DISK_GEOMETRY geom;
- if (!GetGeometry(&geom))
- if (!GetCdRomGeometry(&geom))
- LengthDefined = false;
- if (LengthDefined)
- Length = geom.Cylinders.QuadPart * geom.TracksPerCylinder * geom.SectorsPerTrack * geom.BytesPerSector;
+ SizeDefined = GetGeometry(&geom);
+ if (!SizeDefined)
+ SizeDefined = GetCdRomGeometry(&geom);
+ if (SizeDefined)
+ Size = geom.Cylinders.QuadPart * geom.TracksPerCylinder * geom.SectorsPerTrack * geom.BytesPerSector;
}
- // SeekToBegin();
- #endif
}
+
+ if (needCorrectSize && SizeDefined && Size != 0)
+ {
+ CorrectDeviceSize();
+ SeekToBegin();
+ }
+
+ // SeekToBegin();
+ #endif
}
// ((desiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA | GENERIC_WRITE)) == 0 &&
#define MY_DEVICE_EXTRA_CODE \
- IsDeviceFile = IsDeviceName(fileName); \
- GetDeviceLength();
+ IsDeviceFile = IsDevicePath(fileName); \
+ CalcDeviceSize(fileName);
#else
#define MY_DEVICE_EXTRA_CODE
#endif
-bool CInFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
-{
- bool res = Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes);
- MY_DEVICE_EXTRA_CODE
- return res;
-}
-
-bool CInFile::OpenShared(LPCTSTR fileName, bool shareForWrite)
-{ return Open(fileName, FILE_SHARE_READ | (shareForWrite ? FILE_SHARE_WRITE : 0), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
-
-bool CInFile::Open(LPCTSTR fileName)
- { return OpenShared(fileName, false); }
-
-#ifndef _UNICODE
-bool CInFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+bool CInFile::Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
{
bool res = Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes);
MY_DEVICE_EXTRA_CODE
return res;
}
-bool CInFile::OpenShared(LPCWSTR fileName, bool shareForWrite)
+bool CInFile::OpenShared(CFSTR fileName, bool shareForWrite)
{ return Open(fileName, FILE_SHARE_READ | (shareForWrite ? FILE_SHARE_WRITE : 0), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
-bool CInFile::Open(LPCWSTR fileName)
+bool CInFile::Open(CFSTR fileName)
{ return OpenShared(fileName, false); }
-#endif
// ReadFile and WriteFile functions in Windows have BUG:
// If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
@@ -323,7 +332,7 @@ bool CInFile::Open(LPCWSTR fileName)
static UInt32 kChunkSizeMax = (1 << 22);
-bool CInFile::Read1(void *data, UInt32 size, UInt32 &processedSize)
+bool CInFile::Read1(void *data, UInt32 size, UInt32 &processedSize) throw()
{
DWORD processedLoc = 0;
bool res = BOOLToBool(::ReadFile(_handle, data, size, &processedLoc, NULL));
@@ -331,14 +340,14 @@ bool CInFile::Read1(void *data, UInt32 size, UInt32 &processedSize)
return res;
}
-bool CInFile::ReadPart(void *data, UInt32 size, UInt32 &processedSize)
+bool CInFile::ReadPart(void *data, UInt32 size, UInt32 &processedSize) throw()
{
if (size > kChunkSizeMax)
size = kChunkSizeMax;
return Read1(data, size, processedSize);
}
-bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize)
+bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize) throw()
{
processedSize = 0;
do
@@ -357,40 +366,29 @@ bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize)
return true;
}
-/////////////////////////
-// COutFile
-
-bool COutFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
- { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); }
+// ---------- COutFile ---------
static inline DWORD GetCreationDisposition(bool createAlways)
{ return createAlways? CREATE_ALWAYS: CREATE_NEW; }
-bool COutFile::Open(LPCTSTR fileName, DWORD creationDisposition)
- { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); }
-
-bool COutFile::Create(LPCTSTR fileName, bool createAlways)
- { return Open(fileName, GetCreationDisposition(createAlways)); }
-
-#ifndef _UNICODE
-
-bool COutFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+bool COutFile::Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
{ return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); }
-bool COutFile::Open(LPCWSTR fileName, DWORD creationDisposition)
+bool COutFile::Open(CFSTR fileName, DWORD creationDisposition)
{ return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); }
-bool COutFile::Create(LPCWSTR fileName, bool createAlways)
+bool COutFile::Create(CFSTR fileName, bool createAlways)
{ return Open(fileName, GetCreationDisposition(createAlways)); }
-#endif
+bool COutFile::CreateAlways(CFSTR fileName, DWORD flagsAndAttributes)
+ { return Open(fileName, FILE_SHARE_READ, GetCreationDisposition(true), flagsAndAttributes); }
-bool COutFile::SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
+bool COutFile::SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) throw()
{ return BOOLToBool(::SetFileTime(_handle, cTime, aTime, mTime)); }
-bool COutFile::SetMTime(const FILETIME *mTime) { return SetTime(NULL, NULL, mTime); }
+bool COutFile::SetMTime(const FILETIME *mTime) throw() { return SetTime(NULL, NULL, mTime); }
-bool COutFile::WritePart(const void *data, UInt32 size, UInt32 &processedSize)
+bool COutFile::WritePart(const void *data, UInt32 size, UInt32 &processedSize) throw()
{
if (size > kChunkSizeMax)
size = kChunkSizeMax;
@@ -400,7 +398,7 @@ bool COutFile::WritePart(const void *data, UInt32 size, UInt32 &processedSize)
return res;
}
-bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize)
+bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize) throw()
{
processedSize = 0;
do
@@ -419,9 +417,9 @@ bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize)
return true;
}
-bool COutFile::SetEndOfFile() { return BOOLToBool(::SetEndOfFile(_handle)); }
+bool COutFile::SetEndOfFile() throw() { return BOOLToBool(::SetEndOfFile(_handle)); }
-bool COutFile::SetLength(UInt64 length)
+bool COutFile::SetLength(UInt64 length) throw()
{
UInt64 newPosition;
if (!Seek(length, newPosition))
diff --git a/src/libs/7zip/win/CPP/Windows/FileIO.h b/src/libs/7zip/win/CPP/Windows/FileIO.h
index dce692fed..f595121ef 100644
--- a/src/libs/7zip/win/CPP/Windows/FileIO.h
+++ b/src/libs/7zip/win/CPP/Windows/FileIO.h
@@ -1,134 +1,199 @@
// Windows/FileIO.h
-#ifndef __WINDOWS_FILEIO_H
-#define __WINDOWS_FILEIO_H
+#ifndef __WINDOWS_FILE_IO_H
+#define __WINDOWS_FILE_IO_H
-#include "../Common/Types.h"
+#if defined(_WIN32) && !defined(UNDER_CE)
+#include <winioctl.h>
+#endif
+
+#include "../Common/MyString.h"
+#include "../Common/MyBuffer.h"
#include "Defs.h"
+#define _my_IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
+#define _my_IO_REPARSE_TAG_SYMLINK (0xA000000CL)
+
+#define _my_SYMLINK_FLAG_RELATIVE 1
+
+#define my_FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) // REPARSE_DATA_BUFFER
+#define my_FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) // REPARSE_DATA_BUFFER
+
namespace NWindows {
namespace NFile {
-namespace NIO {
-struct CByHandleFileInfo
+#if defined(_WIN32) && !defined(UNDER_CE)
+bool FillLinkData(CByteBuffer &dest, const wchar_t *path, bool isSymLink);
+#endif
+
+struct CReparseShortInfo
+{
+ unsigned Offset;
+ unsigned Size;
+
+ bool Parse(const Byte *p, size_t size);
+};
+
+struct CReparseAttr
{
- DWORD Attrib;
- FILETIME CTime;
- FILETIME ATime;
- FILETIME MTime;
- DWORD VolumeSerialNumber;
- UInt64 Size;
- DWORD NumberOfLinks;
- UInt64 FileIndex;
+ UInt32 Tag;
+ UInt32 Flags;
+ UString SubsName;
+ UString PrintName;
+
+ CReparseAttr(): Tag(0), Flags(0) {}
+ bool Parse(const Byte *p, size_t size);
+
+ bool IsMountPoint() const { return Tag == _my_IO_REPARSE_TAG_MOUNT_POINT; } // it's Junction
+ bool IsSymLink() const { return Tag == _my_IO_REPARSE_TAG_SYMLINK; }
+ bool IsRelative() const { return Flags == _my_SYMLINK_FLAG_RELATIVE; }
+ // bool IsVolume() const;
+
+ bool IsOkNamePair() const;
+ UString GetPath() const;
};
+namespace NIO {
+
+bool GetReparseData(CFSTR path, CByteBuffer &reparseData, BY_HANDLE_FILE_INFORMATION *fileInfo = NULL);
+bool SetReparseData(CFSTR path, bool isDir, const void *data, DWORD size);
+
class CFileBase
{
protected:
HANDLE _handle;
-
- bool Create(LPCTSTR fileName, DWORD desiredAccess,
- DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
- #ifndef _UNICODE
- bool Create(LPCWSTR fileName, DWORD desiredAccess,
+
+ bool Create(CFSTR path, DWORD desiredAccess,
DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
- #endif
+
+public:
+
+ bool DeviceIoControl(DWORD controlCode, LPVOID inBuffer, DWORD inSize,
+ LPVOID outBuffer, DWORD outSize, LPDWORD bytesReturned, LPOVERLAPPED overlapped = NULL) const
+ {
+ return BOOLToBool(::DeviceIoControl(_handle, controlCode, inBuffer, inSize,
+ outBuffer, outSize, bytesReturned, overlapped));
+ }
+
+ bool DeviceIoControlOut(DWORD controlCode, LPVOID outBuffer, DWORD outSize, LPDWORD bytesReturned) const
+ {
+ return DeviceIoControl(controlCode, NULL, 0, outBuffer, outSize, bytesReturned);
+ }
+
+ bool DeviceIoControlOut(DWORD controlCode, LPVOID outBuffer, DWORD outSize) const
+ {
+ DWORD bytesReturned;
+ return DeviceIoControlOut(controlCode, outBuffer, outSize, &bytesReturned);
+ }
public:
#ifdef SUPPORT_DEVICE_FILE
bool IsDeviceFile;
- bool LengthDefined;
- UInt64 Length;
+ bool SizeDefined;
+ UInt64 Size; // it can be larger than real available size
#endif
CFileBase(): _handle(INVALID_HANDLE_VALUE) {};
- ~CFileBase();
+ ~CFileBase() { Close(); }
+
+ bool Close() throw();
+
+ bool GetPosition(UInt64 &position) const throw();
+ bool GetLength(UInt64 &length) const throw();
- bool Close();
+ bool Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const throw();
+ bool Seek(UInt64 position, UInt64 &newPosition) const throw();
+ bool SeekToBegin() const throw();
+ bool SeekToEnd(UInt64 &newPosition) const throw();
- bool GetPosition(UInt64 &position) const;
- bool GetLength(UInt64 &length) const;
+ bool GetFileInformation(BY_HANDLE_FILE_INFORMATION *info) const
+ { return BOOLToBool(GetFileInformationByHandle(_handle, info)); }
- bool Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const;
- bool Seek(UInt64 position, UInt64 &newPosition);
- bool SeekToBegin();
- bool SeekToEnd(UInt64 &newPosition);
-
- bool GetFileInformation(CByHandleFileInfo &fileInfo) const;
+ static bool GetFileInformation(CFSTR path, BY_HANDLE_FILE_INFORMATION *info)
+ {
+ NIO::CFileBase file;
+ if (!file.Create(path, 0, FILE_SHARE_READ, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS))
+ return false;
+ return file.GetFileInformation(info);
+ }
};
+#ifndef UNDER_CE
#define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY CTL_CODE(IOCTL_CDROM_BASE, 0x0013, METHOD_BUFFERED, FILE_READ_ACCESS)
-#define IOCTL_CDROM_MEDIA_REMOVAL CTL_CODE(IOCTL_CDROM_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS)
+// #define IOCTL_CDROM_MEDIA_REMOVAL CTL_CODE(IOCTL_CDROM_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS)
+
+// IOCTL_DISK_GET_DRIVE_GEOMETRY_EX works since WinXP
+#define my_IOCTL_DISK_GET_DRIVE_GEOMETRY_EX CTL_CODE(IOCTL_DISK_BASE, 0x0028, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+struct my_DISK_GEOMETRY_EX
+{
+ DISK_GEOMETRY Geometry;
+ LARGE_INTEGER DiskSize;
+ BYTE Data[1];
+};
+#endif
class CInFile: public CFileBase
{
#ifdef SUPPORT_DEVICE_FILE
- bool DeviceIoControl(DWORD controlCode, LPVOID inBuffer, DWORD inSize,
- LPVOID outBuffer, DWORD outSize, LPDWORD bytesReturned, LPOVERLAPPED overlapped) const
- {
- return BOOLToBool(::DeviceIoControl(_handle, controlCode, inBuffer, inSize,
- outBuffer, outSize, bytesReturned, overlapped));
- }
-
- bool DeviceIoControl(DWORD controlCode, LPVOID inBuffer,
- DWORD inSize, LPVOID outBuffer, DWORD outSize) const
- {
- DWORD ret;
- return DeviceIoControl(controlCode, inBuffer, inSize, outBuffer, outSize, &ret, 0);
- }
-
- bool DeviceIoControlOut(DWORD controlCode, LPVOID outBuffer, DWORD outSize) const
- { return DeviceIoControl(controlCode, NULL, 0, outBuffer, outSize); }
#ifndef UNDER_CE
+
bool GetGeometry(DISK_GEOMETRY *res) const
{ return DeviceIoControlOut(IOCTL_DISK_GET_DRIVE_GEOMETRY, res, sizeof(*res)); }
+ bool GetGeometryEx(my_DISK_GEOMETRY_EX *res) const
+ { return DeviceIoControlOut(my_IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, res, sizeof(*res)); }
+
bool GetCdRomGeometry(DISK_GEOMETRY *res) const
{ return DeviceIoControlOut(IOCTL_CDROM_GET_DRIVE_GEOMETRY, res, sizeof(*res)); }
-
+
bool GetPartitionInfo(PARTITION_INFORMATION *res)
{ return DeviceIoControlOut(IOCTL_DISK_GET_PARTITION_INFO, LPVOID(res), sizeof(*res)); }
+
#endif
- void GetDeviceLength();
+ void CorrectDeviceSize();
+ void CalcDeviceSize(CFSTR name);
+
#endif
public:
- bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
- bool OpenShared(LPCTSTR fileName, bool shareForWrite);
- bool Open(LPCTSTR fileName);
- #ifndef _UNICODE
- bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
- bool OpenShared(LPCWSTR fileName, bool shareForWrite);
- bool Open(LPCWSTR fileName);
+ bool Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ bool OpenShared(CFSTR fileName, bool shareForWrite);
+ bool Open(CFSTR fileName);
+
+ #ifndef UNDER_CE
+
+ bool OpenReparse(CFSTR fileName)
+ {
+ return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS);
+ }
+
#endif
- bool Read1(void *data, UInt32 size, UInt32 &processedSize);
- bool ReadPart(void *data, UInt32 size, UInt32 &processedSize);
- bool Read(void *data, UInt32 size, UInt32 &processedSize);
+
+ bool Read1(void *data, UInt32 size, UInt32 &processedSize) throw();
+ bool ReadPart(void *data, UInt32 size, UInt32 &processedSize) throw();
+ bool Read(void *data, UInt32 size, UInt32 &processedSize) throw();
};
class COutFile: public CFileBase
{
public:
- bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
- bool Open(LPCTSTR fileName, DWORD creationDisposition);
- bool Create(LPCTSTR fileName, bool createAlways);
-
- #ifndef _UNICODE
- bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
- bool Open(LPCWSTR fileName, DWORD creationDisposition);
- bool Create(LPCWSTR fileName, bool createAlways);
- #endif
-
- bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime);
- bool SetMTime(const FILETIME *mTime);
- bool WritePart(const void *data, UInt32 size, UInt32 &processedSize);
- bool Write(const void *data, UInt32 size, UInt32 &processedSize);
- bool SetEndOfFile();
- bool SetLength(UInt64 length);
+ bool Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ bool Open(CFSTR fileName, DWORD creationDisposition);
+ bool Create(CFSTR fileName, bool createAlways);
+ bool CreateAlways(CFSTR fileName, DWORD flagsAndAttributes);
+
+ bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) throw();
+ bool SetMTime(const FILETIME *mTime) throw();
+ bool WritePart(const void *data, UInt32 size, UInt32 &processedSize) throw();
+ bool Write(const void *data, UInt32 size, UInt32 &processedSize) throw();
+ bool SetEndOfFile() throw();
+ bool SetLength(UInt64 length) throw();
};
}}}
diff --git a/src/libs/7zip/win/CPP/Windows/FileLink.cpp b/src/libs/7zip/win/CPP/Windows/FileLink.cpp
new file mode 100644
index 000000000..dc524700d
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/FileLink.cpp
@@ -0,0 +1,426 @@
+// Windows/FileLink.cpp
+
+#include "StdAfx.h"
+
+#include "../../C/CpuArch.h"
+
+#ifdef SUPPORT_DEVICE_FILE
+#include "../../C/Alloc.h"
+#endif
+
+#include "FileDir.h"
+#include "FileFind.h"
+#include "FileIO.h"
+#include "FileName.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NFile {
+
+using namespace NName;
+
+/*
+ Reparse Points (Junctions and Symbolic Links):
+ struct
+ {
+ UInt32 Tag;
+ UInt16 Size; // not including starting 8 bytes
+ UInt16 Reserved; // = 0
+
+ UInt16 SubstituteOffset; // offset in bytes from start of namesChars
+ UInt16 SubstituteLen; // size in bytes, it doesn't include tailed NUL
+ UInt16 PrintOffset; // offset in bytes from start of namesChars
+ UInt16 PrintLen; // size in bytes, it doesn't include tailed NUL
+
+ [UInt32] Flags; // for Symbolic Links only.
+
+ UInt16 namesChars[]
+ }
+
+ MOUNT_POINT (Junction point):
+ 1) there is NUL wchar after path
+ 2) Default Order in table:
+ Substitute Path
+ Print Path
+ 3) pathnames can not contain dot directory names
+
+ SYMLINK:
+ 1) there is no NUL wchar after path
+ 2) Default Order in table:
+ Print Path
+ Substitute Path
+*/
+
+/*
+static const UInt32 kReparseFlags_Alias = (1 << 29);
+static const UInt32 kReparseFlags_HighLatency = (1 << 30);
+static const UInt32 kReparseFlags_Microsoft = ((UInt32)1 << 31);
+
+#define _my_IO_REPARSE_TAG_HSM (0xC0000004L)
+#define _my_IO_REPARSE_TAG_HSM2 (0x80000006L)
+#define _my_IO_REPARSE_TAG_SIS (0x80000007L)
+#define _my_IO_REPARSE_TAG_WIM (0x80000008L)
+#define _my_IO_REPARSE_TAG_CSV (0x80000009L)
+#define _my_IO_REPARSE_TAG_DFS (0x8000000AL)
+#define _my_IO_REPARSE_TAG_DFSR (0x80000012L)
+*/
+
+#define Get16(p) GetUi16(p)
+#define Get32(p) GetUi32(p)
+
+#define Set16(p, v) SetUi16(p, v)
+#define Set32(p, v) SetUi32(p, v)
+
+static const wchar_t *k_LinkPrefix = L"\\??\\";
+static const unsigned k_LinkPrefix_Size = 4;
+
+static const bool IsLinkPrefix(const wchar_t *s)
+{
+ return IsString1PrefixedByString2(s, k_LinkPrefix);
+}
+
+/*
+static const wchar_t *k_VolumePrefix = L"Volume{";
+static const bool IsVolumeName(const wchar_t *s)
+{
+ return IsString1PrefixedByString2(s, k_VolumePrefix);
+}
+*/
+
+void WriteString(Byte *dest, const wchar_t *path)
+{
+ for (;;)
+ {
+ wchar_t c = *path++;
+ if (c == 0)
+ return;
+ Set16(dest, (UInt16)c);
+ dest += 2;
+ }
+}
+
+bool FillLinkData(CByteBuffer &dest, const wchar_t *path, bool isSymLink)
+{
+ bool isAbs = IsAbsolutePath(path);
+ if (!isAbs && !isSymLink)
+ return false;
+
+ bool needPrintName = true;
+
+ if (IsSuperPath(path))
+ {
+ path += kSuperPathPrefixSize;
+ if (!IsDrivePath(path))
+ needPrintName = false;
+ }
+
+ const unsigned add_Prefix_Len = isAbs ? k_LinkPrefix_Size : 0;
+
+ unsigned len2 = MyStringLen(path) * 2;
+ const unsigned len1 = len2 + add_Prefix_Len * 2;
+ if (!needPrintName)
+ len2 = 0;
+
+ unsigned totalNamesSize = (len1 + len2);
+
+ /* some WIM imagex software uses old scheme for symbolic links.
+ so we can old scheme for byte to byte compatibility */
+
+ bool newOrderScheme = isSymLink;
+ // newOrderScheme = false;
+
+ if (!newOrderScheme)
+ totalNamesSize += 2 * 2;
+
+ const size_t size = 8 + 8 + (isSymLink ? 4 : 0) + totalNamesSize;
+ dest.Alloc(size);
+ memset(dest, 0, size);
+ const UInt32 tag = isSymLink ?
+ _my_IO_REPARSE_TAG_SYMLINK :
+ _my_IO_REPARSE_TAG_MOUNT_POINT;
+ Byte *p = dest;
+ Set32(p, tag);
+ Set16(p + 4, (UInt16)(size - 8));
+ Set16(p + 6, 0);
+ p += 8;
+
+ unsigned subOffs = 0;
+ unsigned printOffs = 0;
+ if (newOrderScheme)
+ subOffs = len2;
+ else
+ printOffs = len1 + 2;
+
+ Set16(p + 0, (UInt16)subOffs);
+ Set16(p + 2, (UInt16)len1);
+ Set16(p + 4, (UInt16)printOffs);
+ Set16(p + 6, (UInt16)len2);
+
+ p += 8;
+ if (isSymLink)
+ {
+ UInt32 flags = isAbs ? 0 : _my_SYMLINK_FLAG_RELATIVE;
+ Set32(p, flags);
+ p += 4;
+ }
+
+ if (add_Prefix_Len != 0)
+ WriteString(p + subOffs, k_LinkPrefix);
+ WriteString(p + subOffs + add_Prefix_Len * 2, path);
+ if (needPrintName)
+ WriteString(p + printOffs, path);
+ return true;
+}
+
+static void GetString(const Byte *p, unsigned len, UString &res)
+{
+ wchar_t *s = res.GetBuffer(len);
+ for (unsigned i = 0; i < len; i++)
+ s[i] = Get16(p + i * 2);
+ s[len] = 0;
+ res.ReleaseBuffer();
+}
+
+bool CReparseAttr::Parse(const Byte *p, size_t size)
+{
+ if (size < 8)
+ return false;
+ Tag = Get32(p);
+ UInt32 len = Get16(p + 4);
+ if (len + 8 > size)
+ return false;
+ /*
+ if ((type & kReparseFlags_Alias) == 0 ||
+ (type & kReparseFlags_Microsoft) == 0 ||
+ (type & 0xFFFF) != 3)
+ */
+ if (Tag != _my_IO_REPARSE_TAG_MOUNT_POINT &&
+ Tag != _my_IO_REPARSE_TAG_SYMLINK)
+ // return true;
+ return false;
+
+ if (Get16(p + 6) != 0) // padding
+ return false;
+
+ p += 8;
+ size -= 8;
+
+ if (len != size) // do we need that check?
+ return false;
+
+ if (len < 8)
+ return false;
+ unsigned subOffs = Get16(p);
+ unsigned subLen = Get16(p + 2);
+ unsigned printOffs = Get16(p + 4);
+ unsigned printLen = Get16(p + 6);
+ len -= 8;
+ p += 8;
+
+ Flags = 0;
+ if (Tag == _my_IO_REPARSE_TAG_SYMLINK)
+ {
+ if (len < 4)
+ return false;
+ Flags = Get32(p);
+ len -= 4;
+ p += 4;
+ }
+
+ if ((subOffs & 1) != 0 || subOffs > len || len - subOffs < subLen)
+ return false;
+ if ((printOffs & 1) != 0 || printOffs > len || len - printOffs < printLen)
+ return false;
+ GetString(p + subOffs, subLen >> 1, SubsName);
+ GetString(p + printOffs, printLen >> 1, PrintName);
+
+ return true;
+}
+
+bool CReparseShortInfo::Parse(const Byte *p, size_t size)
+{
+ const Byte *start = p;
+ Offset= 0;
+ Size = 0;
+ if (size < 8)
+ return false;
+ UInt32 Tag = Get32(p);
+ UInt32 len = Get16(p + 4);
+ if (len + 8 > size)
+ return false;
+ /*
+ if ((type & kReparseFlags_Alias) == 0 ||
+ (type & kReparseFlags_Microsoft) == 0 ||
+ (type & 0xFFFF) != 3)
+ */
+ if (Tag != _my_IO_REPARSE_TAG_MOUNT_POINT &&
+ Tag != _my_IO_REPARSE_TAG_SYMLINK)
+ // return true;
+ return false;
+
+ if (Get16(p + 6) != 0) // padding
+ return false;
+
+ p += 8;
+ size -= 8;
+
+ if (len != size) // do we need that check?
+ return false;
+
+ if (len < 8)
+ return false;
+ unsigned subOffs = Get16(p);
+ unsigned subLen = Get16(p + 2);
+ unsigned printOffs = Get16(p + 4);
+ unsigned printLen = Get16(p + 6);
+ len -= 8;
+ p += 8;
+
+ // UInt32 Flags = 0;
+ if (Tag == _my_IO_REPARSE_TAG_SYMLINK)
+ {
+ if (len < 4)
+ return false;
+ // Flags = Get32(p);
+ len -= 4;
+ p += 4;
+ }
+
+ if ((subOffs & 1) != 0 || subOffs > len || len - subOffs < subLen)
+ return false;
+ if ((printOffs & 1) != 0 || printOffs > len || len - printOffs < printLen)
+ return false;
+
+ Offset = (unsigned)(p - start) + subOffs;
+ Size = subLen;
+ return true;
+}
+
+bool CReparseAttr::IsOkNamePair() const
+{
+ if (IsLinkPrefix(SubsName))
+ {
+ if (!IsDrivePath(SubsName.Ptr(k_LinkPrefix_Size)))
+ return PrintName.IsEmpty();
+ if (wcscmp(SubsName.Ptr(k_LinkPrefix_Size), PrintName) == 0)
+ return true;
+ }
+ return wcscmp(SubsName, PrintName) == 0;
+}
+
+/*
+bool CReparseAttr::IsVolume() const
+{
+ if (!IsLinkPrefix(SubsName))
+ return false;
+ return IsVolumeName(SubsName.Ptr(k_LinkPrefix_Size));
+}
+*/
+
+UString CReparseAttr::GetPath() const
+{
+ UString s = SubsName;
+ if (IsLinkPrefix(s))
+ {
+ s.ReplaceOneCharAtPos(1, '\\');
+ if (IsDrivePath(s.Ptr(k_LinkPrefix_Size)))
+ s.DeleteFrontal(k_LinkPrefix_Size);
+ }
+ return s;
+}
+
+
+#ifdef SUPPORT_DEVICE_FILE
+
+namespace NSystem
+{
+bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize);
+}
+#endif
+
+#ifndef UNDER_CE
+
+namespace NIO {
+
+bool GetReparseData(CFSTR path, CByteBuffer &reparseData, BY_HANDLE_FILE_INFORMATION *fileInfo)
+{
+ reparseData.Free();
+ CInFile file;
+ if (!file.OpenReparse(path))
+ return false;
+
+ if (fileInfo)
+ file.GetFileInformation(fileInfo);
+
+ const unsigned kBufSize = MAXIMUM_REPARSE_DATA_BUFFER_SIZE;
+ CByteArr buf(kBufSize);
+ DWORD returnedSize;
+ if (!file.DeviceIoControlOut(my_FSCTL_GET_REPARSE_POINT, buf, kBufSize, &returnedSize))
+ return false;
+ reparseData.CopyFrom(buf, returnedSize);
+ return true;
+}
+
+static bool CreatePrefixDirOfFile(CFSTR path)
+{
+ FString path2 = path;
+ int pos = path2.ReverseFind(FCHAR_PATH_SEPARATOR);
+ if (pos < 0)
+ return true;
+ #ifdef _WIN32
+ if (pos == 2 && path2[1] == L':')
+ return true; // we don't create Disk folder;
+ #endif
+ path2.DeleteFrom(pos);
+ return NDir::CreateComplexDir(path2);
+}
+
+// If there is Reprase data already, it still writes new Reparse data
+bool SetReparseData(CFSTR path, bool isDir, const void *data, DWORD size)
+{
+ NFile::NFind::CFileInfo fi;
+ if (fi.Find(path))
+ {
+ if (fi.IsDir() != isDir)
+ {
+ ::SetLastError(ERROR_DIRECTORY);
+ return false;
+ }
+ }
+ else
+ {
+ if (isDir)
+ {
+ if (!NDir::CreateComplexDir(path))
+ return false;
+ }
+ else
+ {
+ CreatePrefixDirOfFile(path);
+ COutFile file;
+ if (!file.Create(path, CREATE_NEW))
+ return false;
+ }
+ }
+
+ COutFile file;
+ if (!file.Open(path,
+ FILE_SHARE_WRITE,
+ OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS))
+ return false;
+
+ DWORD returnedSize;
+ if (!file.DeviceIoControl(my_FSCTL_SET_REPARSE_POINT, (void *)data, size, NULL, 0, &returnedSize))
+ return false;
+ return true;
+}
+
+}
+
+#endif
+
+}}
diff --git a/src/libs/7zip/win/CPP/Windows/FileMapping.cpp b/src/libs/7zip/win/CPP/Windows/FileMapping.cpp
deleted file mode 100644
index 55048fdb2..000000000
--- a/src/libs/7zip/win/CPP/Windows/FileMapping.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-// Windows/FileMapping.cpp
-
-#include "StdAfx.h"
-
-#include "Windows/FileMapping.h"
-
-namespace NWindows {
-namespace NFile {
-namespace NMapping {
-
-
-}}}
diff --git a/src/libs/7zip/win/CPP/Windows/FileMapping.h b/src/libs/7zip/win/CPP/Windows/FileMapping.h
index 3f0ebd74c..f90c429f1 100644
--- a/src/libs/7zip/win/CPP/Windows/FileMapping.h
+++ b/src/libs/7zip/win/CPP/Windows/FileMapping.h
@@ -3,7 +3,7 @@
#ifndef __WINDOWS_FILEMAPPING_H
#define __WINDOWS_FILEMAPPING_H
-#include "Common/Types.h"
+#include "../Common/MyTypes.h"
#include "Handle.h"
@@ -18,7 +18,11 @@ public:
return ::GetLastError();
}
- WRes Open(DWORD desiredAccess, LPCTSTR name)
+ WRes Open(DWORD
+ #ifndef UNDER_CE
+ desiredAccess
+ #endif
+ , LPCTSTR name)
{
#ifdef UNDER_CE
WRes res = Create(PAGE_READONLY, 0, name);
diff --git a/src/libs/7zip/win/CPP/Windows/FileName.cpp b/src/libs/7zip/win/CPP/Windows/FileName.cpp
index 8443a4af9..0a6aee100 100644
--- a/src/libs/7zip/win/CPP/Windows/FileName.cpp
+++ b/src/libs/7zip/win/CPP/Windows/FileName.cpp
@@ -2,49 +2,686 @@
#include "StdAfx.h"
-#include "Windows/FileName.h"
-#include "Common/Wildcard.h"
+#include "FileName.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
namespace NWindows {
namespace NFile {
namespace NName {
-void NormalizeDirPathPrefix(CSysString &dirPath)
+#ifndef USE_UNICODE_FSTRING
+void NormalizeDirPathPrefix(FString &dirPath)
{
if (dirPath.IsEmpty())
return;
- if (dirPath.ReverseFind(kDirDelimiter) != dirPath.Length() - 1)
- dirPath += kDirDelimiter;
+ if (dirPath.Back() != FCHAR_PATH_SEPARATOR)
+ dirPath += FCHAR_PATH_SEPARATOR;
}
+#endif
-#ifndef _UNICODE
void NormalizeDirPathPrefix(UString &dirPath)
{
if (dirPath.IsEmpty())
return;
- if (dirPath.ReverseFind(wchar_t(kDirDelimiter)) != dirPath.Length() - 1)
- dirPath += wchar_t(kDirDelimiter);
+ if (dirPath.Back() != WCHAR_PATH_SEPARATOR)
+ dirPath += WCHAR_PATH_SEPARATOR;
+}
+
+
+#ifdef _WIN32
+
+const wchar_t *kSuperPathPrefix = L"\\\\?\\";
+static const wchar_t *kSuperUncPrefix = L"\\\\?\\UNC\\";
+
+#define IS_DEVICE_PATH(s) ((s)[0] == '\\' && (s)[1] == '\\' && (s)[2] == '.' && (s)[3] == '\\')
+#define IS_SUPER_PREFIX(s) ((s)[0] == '\\' && (s)[1] == '\\' && (s)[2] == '?' && (s)[3] == '\\')
+#define IS_SUPER_OR_DEVICE_PATH(s) ((s)[0] == '\\' && (s)[1] == '\\' && ((s)[2] == '?' || (s)[2] == '.') && (s)[3] == '\\')
+#define IS_LETTER_CHAR(c) ((c) >= 'a' && (c) <= 'z' || (c) >= 'A' && (c) <= 'Z')
+
+#define IS_UNC_WITH_SLASH(s) ( \
+ ((s)[0] == 'U' || (s)[0] == 'u') && \
+ ((s)[1] == 'N' || (s)[1] == 'n') && \
+ ((s)[2] == 'C' || (s)[2] == 'c') && \
+ (s)[3] == '\\')
+
+bool IsDevicePath(CFSTR s) throw()
+{
+ #ifdef UNDER_CE
+
+ s = s;
+ return false;
+ /*
+ // actually we don't know the way to open device file in WinCE.
+ unsigned len = MyStringLen(s);
+ if (len < 5 || len > 5 || memcmp(s, FTEXT("DSK"), 3 * sizeof(FChar)) != 0)
+ return false;
+ if (s[4] != ':')
+ return false;
+ // for reading use SG_REQ sg; if (DeviceIoControl(dsk, IOCTL_DISK_READ));
+ */
+
+ #else
+
+ if (!IS_DEVICE_PATH(s))
+ return false;
+ unsigned len = MyStringLen(s);
+ if (len == 6 && s[5] == ':')
+ return true;
+ if (len < 18 || len > 22 || memcmp(s + kDevicePathPrefixSize, FTEXT("PhysicalDrive"), 13 * sizeof(FChar)) != 0)
+ return false;
+ for (unsigned i = 17; i < len; i++)
+ if (s[i] < '0' || s[i] > '9')
+ return false;
+ return true;
+
+ #endif
+}
+
+bool IsSuperUncPath(CFSTR s) throw() { return (IS_SUPER_PREFIX(s) && IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)); }
+
+bool IsDrivePath(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == '\\'; }
+bool IsSuperPath(const wchar_t *s) throw() { return IS_SUPER_PREFIX(s); }
+bool IsSuperOrDevicePath(const wchar_t *s) throw() { return IS_SUPER_OR_DEVICE_PATH(s); }
+// bool IsSuperUncPath(const wchar_t *s) { return (IS_SUPER_PREFIX(s) && IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)); }
+
+#ifndef USE_UNICODE_FSTRING
+bool IsDrivePath(CFSTR s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == '\\'; }
+bool IsSuperPath(CFSTR s) throw() { return IS_SUPER_PREFIX(s); }
+bool IsSuperOrDevicePath(CFSTR s) throw() { return IS_SUPER_OR_DEVICE_PATH(s); }
+#endif // USE_UNICODE_FSTRING
+
+bool IsAbsolutePath(const wchar_t *s) throw()
+{
+ return s[0] == WCHAR_PATH_SEPARATOR || IsDrivePath(s);
+}
+
+static const unsigned kDrivePrefixSize = 3; /* c:\ */
+
+#ifndef USE_UNICODE_FSTRING
+
+static unsigned GetRootPrefixSize_Of_NetworkPath(CFSTR s) throw()
+{
+ // Network path: we look "server\path\" as root prefix
+ int pos = FindCharPosInString(s, '\\');
+ if (pos < 0)
+ return 0;
+ int pos2 = FindCharPosInString(s + pos + 1, '\\');
+ if (pos2 < 0)
+ return 0;
+ return pos + pos2 + 2;
+}
+
+static unsigned GetRootPrefixSize_Of_SimplePath(CFSTR s) throw()
+{
+ if (IsDrivePath(s))
+ return kDrivePrefixSize;
+ if (s[0] != '\\' || s[1] != '\\')
+ return 0;
+ unsigned size = GetRootPrefixSize_Of_NetworkPath(s + 2);
+ return (size == 0) ? 0 : 2 + size;
+}
+
+static unsigned GetRootPrefixSize_Of_SuperPath(CFSTR s) throw()
+{
+ if (IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize))
+ {
+ unsigned size = GetRootPrefixSize_Of_NetworkPath(s + kSuperUncPathPrefixSize);
+ return (size == 0) ? 0 : kSuperUncPathPrefixSize + size;
+ }
+ // we support \\?\c:\ paths and volume GUID paths \\?\Volume{GUID}\"
+ int pos = FindCharPosInString(s + kSuperPathPrefixSize, FCHAR_PATH_SEPARATOR);
+ if (pos < 0)
+ return 0;
+ return kSuperPathPrefixSize + pos + 1;
+}
+
+unsigned GetRootPrefixSize(CFSTR s) throw()
+{
+ if (IS_DEVICE_PATH(s))
+ return kDevicePathPrefixSize;
+ if (IsSuperPath(s))
+ return GetRootPrefixSize_Of_SuperPath(s);
+ return GetRootPrefixSize_Of_SimplePath(s);
+}
+
+#endif // USE_UNICODE_FSTRING
+
+static unsigned GetRootPrefixSize_Of_NetworkPath(const wchar_t *s) throw()
+{
+ // Network path: we look "server\path\" as root prefix
+ int pos = FindCharPosInString(s, L'\\');
+ if (pos < 0)
+ return 0;
+ int pos2 = FindCharPosInString(s + pos + 1, L'\\');
+ if (pos2 < 0)
+ return 0;
+ return pos + pos2 + 2;
+}
+
+static unsigned GetRootPrefixSize_Of_SimplePath(const wchar_t *s) throw()
+{
+ if (IsDrivePath(s))
+ return kDrivePrefixSize;
+ if (s[0] != '\\' || s[1] != '\\')
+ return 0;
+ unsigned size = GetRootPrefixSize_Of_NetworkPath(s + 2);
+ return (size == 0) ? 0 : 2 + size;
+}
+
+static unsigned GetRootPrefixSize_Of_SuperPath(const wchar_t *s) throw()
+{
+ if (IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize))
+ {
+ unsigned size = GetRootPrefixSize_Of_NetworkPath(s + kSuperUncPathPrefixSize);
+ return (size == 0) ? 0 : kSuperUncPathPrefixSize + size;
+ }
+ // we support \\?\c:\ paths and volume GUID paths \\?\Volume{GUID}\"
+ int pos = FindCharPosInString(s + kSuperPathPrefixSize, L'\\');
+ if (pos < 0)
+ return 0;
+ return kSuperPathPrefixSize + pos + 1;
+}
+
+unsigned GetRootPrefixSize(const wchar_t *s) throw()
+{
+ if (IS_DEVICE_PATH(s))
+ return kDevicePathPrefixSize;
+ if (IsSuperPath(s))
+ return GetRootPrefixSize_Of_SuperPath(s);
+ return GetRootPrefixSize_Of_SimplePath(s);
+}
+
+#else // _WIN32
+
+bool IsAbsolutePath(const wchar_t *s) throw() { return s[0] == WCHAR_PATH_SEPARATOR }
+
+#ifndef USE_UNICODE_FSTRING
+unsigned GetRootPrefixSize(CFSTR s) throw() { return s[0] == CHAR_PATH_SEPRATOR ? 1 : 0; }
+#endif
+unsigned GetRootPrefixSize(const wchar_t *s) throw() { return s[0] == CHAR_PATH_SEPRATOR ? 1 : 0; }
+
+#endif // _WIN32
+
+
+#ifndef UNDER_CE
+
+static bool GetCurDir(UString &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 = fs2us(fas2fs(s));
+ }
+ else
+ #endif
+ {
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, s);
+ path = s;
+ }
+ return (needLength > 0 && needLength <= MAX_PATH);
+}
+
+static bool ResolveDotsFolders(UString &s)
+{
+ #ifdef _WIN32
+ s.Replace(L'/', WCHAR_PATH_SEPARATOR);
+ #endif
+ for (int i = 0;;)
+ {
+ wchar_t c = s[i];
+ if (c == 0)
+ return true;
+ if (c == '.' && (i == 0 || s[i - 1] == WCHAR_PATH_SEPARATOR))
+ {
+ wchar_t c1 = s[i + 1];
+ if (c1 == '.')
+ {
+ wchar_t c2 = s[i + 2];
+ if (c2 == WCHAR_PATH_SEPARATOR || c2 == 0)
+ {
+ if (i == 0)
+ return false;
+ int k = i - 2;
+ for (; k >= 0; k--)
+ if (s[k] == WCHAR_PATH_SEPARATOR)
+ break;
+ unsigned num;
+ if (k >= 0)
+ {
+ num = i + 2 - k;
+ i = k;
+ }
+ else
+ {
+ num = (c2 == 0 ? (i + 2) : (i + 3));
+ i = 0;
+ }
+ s.Delete(i, num);
+ continue;
+ }
+ }
+ else
+ {
+ if (c1 == WCHAR_PATH_SEPARATOR || c1 == 0)
+ {
+ unsigned num = 2;
+ if (i != 0)
+ i--;
+ else if (c1 == 0)
+ num = 1;
+ s.Delete(i, num);
+ continue;
+ }
+ }
+ }
+ i++;
+ }
+}
+
+#endif // UNDER_CE
+
+#define LONG_PATH_DOTS_FOLDERS_PARSING
+
+
+/*
+Windows (at least 64-bit XP) can't resolve "." or ".." in paths that start with SuperPrefix \\?\
+To solve that problem we check such path:
+ - super path contains "." or ".." - we use kSuperPathType_UseOnlySuper
+ - super path doesn't contain "." or ".." - we use kSuperPathType_UseOnlyMain
+*/
+#ifdef LONG_PATH_DOTS_FOLDERS_PARSING
+#ifndef UNDER_CE
+static bool AreThereDotsFolders(CFSTR s)
+{
+ for (unsigned i = 0;; i++)
+ {
+ FChar c = s[i];
+ if (c == 0)
+ return false;
+ if (c == '.' && (i == 0 || s[i - 1] == CHAR_PATH_SEPARATOR))
+ {
+ FChar c1 = s[i + 1];
+ if (c1 == 0 || c1 == CHAR_PATH_SEPARATOR ||
+ (c1 == '.' && (s[i + 2] == 0 || s[i + 2] == CHAR_PATH_SEPARATOR)))
+ return true;
+ }
+ }
}
#endif
+#endif // LONG_PATH_DOTS_FOLDERS_PARSING
+
+#ifdef WIN_LONG_PATH
+
+/*
+Most of Windows versions have problems, if some file or dir name
+contains '.' or ' ' at the end of name (Bad Path).
+To solve that problem, we always use Super Path ("\\?\" prefix and full path)
+in such cases. Note that "." and ".." are not bad names.
+
+There are 3 cases:
+ 1) If the path is already Super Path, we use that path
+ 2) If the path is not Super Path :
+ 2.1) Bad Path; we use only Super Path.
+ 2.2) Good Path; we use Main Path. If it fails, we use Super Path.
+
+ NeedToUseOriginalPath returns:
+ kSuperPathType_UseOnlyMain : Super already
+ kSuperPathType_UseOnlySuper : not Super, Bad Path
+ kSuperPathType_UseMainAndSuper : not Super, Good Path
+*/
+
+int GetUseSuperPathType(CFSTR s) throw()
+{
+ if (IsSuperOrDevicePath(s))
+ {
+ #ifdef LONG_PATH_DOTS_FOLDERS_PARSING
+ if ((s)[2] != '.')
+ if (AreThereDotsFolders(s + kSuperPathPrefixSize))
+ return kSuperPathType_UseOnlySuper;
+ #endif
+ return kSuperPathType_UseOnlyMain;
+ }
+
+ for (unsigned i = 0;; i++)
+ {
+ FChar c = s[i];
+ if (c == 0)
+ return kSuperPathType_UseMainAndSuper;
+ if (c == '.' || c == ' ')
+ {
+ FChar c2 = s[i + 1];
+ if (c2 == 0 || c2 == CHAR_PATH_SEPARATOR)
+ {
+ // if it's "." or "..", it's not bad name.
+ if (c == '.')
+ {
+ if (i == 0 || s[i - 1] == CHAR_PATH_SEPARATOR)
+ continue;
+ if (s[i - 1] == '.')
+ {
+ if (i - 1 == 0 || s[i - 2] == CHAR_PATH_SEPARATOR)
+ continue;
+ }
+ }
+ return kSuperPathType_UseOnlySuper;
+ }
+ }
+ }
+}
+
+
+/*
+ returns false in two cases:
+ - if GetCurDir was used, and GetCurDir returned error.
+ - if we can't resolve ".." name.
+ if path is ".", "..", res is empty.
+ if it's Super Path already, res is empty.
+ for \**** , and if GetCurDir is not drive (c:\), res is empty
+ for absolute paths, returns true, res is Super path.
+*/
+
+
+static bool GetSuperPathBase(CFSTR s, UString &res)
+{
+ res.Empty();
+
+ FChar c = s[0];
+ if (c == 0)
+ return true;
+ if (c == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)))
+ return true;
+
+ if (IsSuperOrDevicePath(s))
+ {
+ #ifdef LONG_PATH_DOTS_FOLDERS_PARSING
+
+ if ((s)[2] == '.')
+ return true;
+
+ // we will return true here, so we will try to use these problem paths.
+
+ if (!AreThereDotsFolders(s + kSuperPathPrefixSize))
+ return true;
+
+ UString temp = fs2us(s);
+ unsigned fixedSize = GetRootPrefixSize_Of_SuperPath(temp);
+ if (fixedSize == 0)
+ return true;
+
+ UString rem = &temp[fixedSize];
+ if (!ResolveDotsFolders(rem))
+ return true;
+
+ temp.DeleteFrom(fixedSize);
+ res += temp;
+ res += rem;
+
+ #endif
+
+ return true;
+ }
+
+ if (c == CHAR_PATH_SEPARATOR)
+ {
+ if (s[1] == CHAR_PATH_SEPARATOR)
+ {
+ UString temp = fs2us(s + 2);
+ unsigned fixedSize = GetRootPrefixSize_Of_NetworkPath(temp);
+ if (fixedSize == 0) // maybe we must ignore that error to allow short network paths?
+ return false;
+ UString rem = &temp[fixedSize];
+ if (!ResolveDotsFolders(rem))
+ return false;
+ res += kSuperUncPrefix;
+ temp.DeleteFrom(fixedSize);
+ res += temp;
+ res += rem;
+ return true;
+ }
+ }
+ else
+ {
+ if (IsDrivePath(s))
+ {
+ UString temp = fs2us(s);
+ UString rem = &temp[kDrivePrefixSize];
+ if (!ResolveDotsFolders(rem))
+ return true;
+ res += kSuperPathPrefix;
+ temp.DeleteFrom(kDrivePrefixSize);
+ res += temp;
+ res += rem;
+ return true;
+ }
+ }
+
+ UString curDir;
+ if (!GetCurDir(curDir))
+ return false;
+ if (curDir.Back() != WCHAR_PATH_SEPARATOR)
+ curDir += WCHAR_PATH_SEPARATOR;
+
+ unsigned fixedSizeStart = 0;
+ unsigned fixedSize = 0;
+ const wchar_t *superMarker = NULL;
+ if (IsSuperPath(curDir))
+ {
+ fixedSize = GetRootPrefixSize_Of_SuperPath(curDir);
+ if (fixedSize == 0)
+ return false;
+ }
+ else
+ {
+ if (IsDrivePath(curDir))
+ {
+ superMarker = kSuperPathPrefix;
+ fixedSize = kDrivePrefixSize;
+ }
+ else
+ {
+ if (curDir[0] != CHAR_PATH_SEPARATOR || curDir[1] != CHAR_PATH_SEPARATOR)
+ return false;
+ fixedSizeStart = 2;
+ fixedSize = GetRootPrefixSize_Of_NetworkPath(&curDir[2]);
+ if (fixedSize == 0)
+ return false;
+ superMarker = kSuperUncPrefix;
+ }
+ }
+
+ UString temp;
+ if (c == CHAR_PATH_SEPARATOR)
+ {
+ temp = fs2us(s + 1);
+ }
+ else
+ {
+ temp += &curDir[fixedSizeStart + fixedSize];
+ temp += fs2us(s);
+ }
+ if (!ResolveDotsFolders(temp))
+ return false;
+ if (superMarker)
+ res += superMarker;
+ res += curDir.Mid(fixedSizeStart, fixedSize);
+ res += temp;
+ return true;
+}
+
-const wchar_t kExtensionDelimiter = L'.';
+/*
+ In that case if GetSuperPathBase doesn't return new path, we don't need
+ to use same path that was used as main path
-void SplitNameToPureNameAndExtension(const UString &fullName,
- UString &pureName, UString &extensionDelimiter, UString &extension)
+ GetSuperPathBase superPath.IsEmpty() onlyIfNew
+ false * * GetCurDir Error
+ true false * use Super path
+ true true true don't use any path, we already used mainPath
+ true true false use main path as Super Path, we don't try mainMath
+ That case is possible now if GetCurDir returns unknow
+ type of path (not drive and not network)
+
+ We can change that code if we want to try mainPath, if GetSuperPathBase returns error,
+ and we didn't try mainPath still.
+ If we want to work that way, we don't need to use GetSuperPathBase return code.
+*/
+
+bool GetSuperPath(CFSTR path, UString &superPath, bool onlyIfNew)
+{
+ if (GetSuperPathBase(path, superPath))
+ {
+ if (superPath.IsEmpty())
+ {
+ // actually the only possible when onlyIfNew == true and superPath is empty
+ // is case when
+
+ if (onlyIfNew)
+ return false;
+ superPath = fs2us(path);
+ }
+ return true;
+ }
+ return false;
+}
+
+bool GetSuperPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2, bool onlyIfNew)
+{
+ if (!GetSuperPathBase(s1, d1) ||
+ !GetSuperPathBase(s2, d2))
+ return false;
+ if (d1.IsEmpty() && d2.IsEmpty() && onlyIfNew)
+ return false;
+ if (d1.IsEmpty()) d1 = fs2us(s1);
+ if (d2.IsEmpty()) d2 = fs2us(s2);
+ return true;
+}
+
+
+/*
+// returns true, if we need additional use with New Super path.
+bool GetSuperPath(CFSTR path, UString &superPath)
+{
+ if (GetSuperPathBase(path, superPath))
+ return !superPath.IsEmpty();
+ return false;
+}
+*/
+#endif // WIN_LONG_PATH
+
+bool GetFullPath(CFSTR dirPrefix, CFSTR s, FString &res)
{
- int index = fullName.ReverseFind(kExtensionDelimiter);
- if (index < 0)
+ res = s;
+
+ #ifdef UNDER_CE
+
+ if (s[0] != CHAR_PATH_SEPARATOR)
+ {
+ if (!dirPrefix)
+ return false;
+ res = dirPrefix;
+ res += s;
+ }
+
+ #else
+
+ unsigned prefixSize = GetRootPrefixSize(s);
+ if (prefixSize != 0)
+ {
+ if (!AreThereDotsFolders(s + prefixSize))
+ return true;
+
+ UString rem = fs2us(s + prefixSize);
+ if (!ResolveDotsFolders(rem))
+ return true; // maybe false;
+ res.DeleteFrom(prefixSize);
+ res += us2fs(rem);
+ return true;
+ }
+
+ /*
+ FChar c = s[0];
+ if (c == 0)
+ return true;
+ if (c == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)))
+ return true;
+ if (c == CHAR_PATH_SEPARATOR && s[1] == CHAR_PATH_SEPARATOR)
+ return true;
+ if (IsDrivePath(s))
+ return true;
+ */
+
+ UString curDir;
+ if (dirPrefix)
+ curDir = fs2us(dirPrefix);
+ else
+ {
+ if (!GetCurDir(curDir))
+ return false;
+ }
+ if (!curDir.IsEmpty() && curDir.Back() != WCHAR_PATH_SEPARATOR)
+ curDir += WCHAR_PATH_SEPARATOR;
+
+ unsigned fixedSize = 0;
+
+ #ifdef _WIN32
+
+ if (IsSuperPath(curDir))
+ {
+ fixedSize = GetRootPrefixSize_Of_SuperPath(curDir);
+ if (fixedSize == 0)
+ return false;
+ }
+ else
+ {
+ if (IsDrivePath(curDir))
+ fixedSize = kDrivePrefixSize;
+ else
+ {
+ if (curDir[0] != WCHAR_PATH_SEPARATOR || curDir[1] != WCHAR_PATH_SEPARATOR)
+ return false;
+ fixedSize = GetRootPrefixSize_Of_NetworkPath(&curDir[2]);
+ if (fixedSize == 0)
+ return false;
+ fixedSize += 2;
+ }
+ }
+
+ #endif // _WIN32
+
+ UString temp;
+ if (s[0] == CHAR_PATH_SEPARATOR)
{
- pureName = fullName;
- extensionDelimiter.Empty();
- extension.Empty();
+ temp = fs2us(s + 1);
}
else
{
- pureName = fullName.Left(index);
- extensionDelimiter = kExtensionDelimiter;
- extension = fullName.Mid(index + 1);
+ temp += curDir.Ptr(fixedSize);
+ temp += fs2us(s);
}
+ if (!ResolveDotsFolders(temp))
+ return false;
+ curDir.DeleteFrom(fixedSize);
+ res = us2fs(curDir);
+ res += us2fs(temp);
+
+ #endif // UNDER_CE
+
+ return true;
+}
+
+bool GetFullPath(CFSTR path, FString &fullPath)
+{
+ return GetFullPath(NULL, path, fullPath);
}
}}}
diff --git a/src/libs/7zip/win/CPP/Windows/FileName.h b/src/libs/7zip/win/CPP/Windows/FileName.h
index d98079026..04fc79b2d 100644
--- a/src/libs/7zip/win/CPP/Windows/FileName.h
+++ b/src/libs/7zip/win/CPP/Windows/FileName.h
@@ -1,9 +1,7 @@
// Windows/FileName.h
-#ifndef __WINDOWS_FILENAME_H
-#define __WINDOWS_FILENAME_H
-
-#include "../../C/Types.h"
+#ifndef __WINDOWS_FILE_NAME_H
+#define __WINDOWS_FILE_NAME_H
#include "../Common/MyString.h"
@@ -11,16 +9,65 @@ namespace NWindows {
namespace NFile {
namespace NName {
-const TCHAR kDirDelimiter = CHAR_PATH_SEPARATOR;
-const TCHAR kAnyStringWildcard = '*';
+void NormalizeDirPathPrefix(FString &dirPath); // ensures that it ended with '\\', if dirPath is not epmty
+void NormalizeDirPathPrefix(UString &dirPath);
+
+#ifdef _WIN32
+
+extern const wchar_t *kSuperPathPrefix; /* \\?\ */
+const unsigned kDevicePathPrefixSize = 4;
+const unsigned kSuperPathPrefixSize = 4;
+const unsigned kSuperUncPathPrefixSize = kSuperPathPrefixSize + 4;
+
+bool IsDevicePath(CFSTR s) throw(); /* \\.\ */
+bool IsSuperUncPath(CFSTR s) throw();
-void NormalizeDirPathPrefix(CSysString &dirPath); // ensures that it ended with '\\'
-#ifndef _UNICODE
-void NormalizeDirPathPrefix(UString &dirPath); // ensures that it ended with '\\'
+bool IsDrivePath(const wchar_t *s) throw();
+bool IsSuperPath(const wchar_t *s) throw();
+bool IsSuperOrDevicePath(const wchar_t *s) throw();
+
+#ifndef USE_UNICODE_FSTRING
+bool IsDrivePath(CFSTR s) throw();
+bool IsSuperPath(CFSTR s) throw();
+bool IsSuperOrDevicePath(CFSTR s) throw();
#endif
-void SplitNameToPureNameAndExtension(const UString &fullName,
- UString &pureName, UString &extensionDelimiter, UString &extension);
+#endif // _WIN32
+
+bool IsAbsolutePath(const wchar_t *s) throw();
+unsigned GetRootPrefixSize(const wchar_t *s) throw();
+
+#ifdef WIN_LONG_PATH
+
+const int kSuperPathType_UseOnlyMain = 0;
+const int kSuperPathType_UseOnlySuper = 1;
+const int kSuperPathType_UseMainAndSuper = 2;
+
+int GetUseSuperPathType(CFSTR s) throw();
+bool GetSuperPath(CFSTR path, UString &longPath, bool onlyIfNew);
+bool GetSuperPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2, bool onlyIfNew);
+
+#define USE_MAIN_PATH (__useSuperPathType != kSuperPathType_UseOnlySuper)
+#define USE_MAIN_PATH_2 (__useSuperPathType1 != kSuperPathType_UseOnlySuper && __useSuperPathType2 != kSuperPathType_UseOnlySuper)
+
+#define USE_SUPER_PATH (__useSuperPathType != kSuperPathType_UseOnlyMain)
+#define USE_SUPER_PATH_2 (__useSuperPathType1 != kSuperPathType_UseOnlyMain || __useSuperPathType2 != kSuperPathType_UseOnlyMain)
+
+#define IF_USE_MAIN_PATH int __useSuperPathType = GetUseSuperPathType(path); if (USE_MAIN_PATH)
+#define IF_USE_MAIN_PATH_2(x1, x2) \
+ int __useSuperPathType1 = GetUseSuperPathType(x1); \
+ int __useSuperPathType2 = GetUseSuperPathType(x2); \
+ if (USE_MAIN_PATH_2)
+
+#else
+
+#define IF_USE_MAIN_PATH
+#define IF_USE_MAIN_PATH_2(x1, x2)
+
+#endif // WIN_LONG_PATH
+
+bool GetFullPath(CFSTR dirPrefix, CFSTR path, FString &fullPath);
+bool GetFullPath(CFSTR path, FString &fullPath);
}}}
diff --git a/src/libs/7zip/win/CPP/Windows/MemoryLock.cpp b/src/libs/7zip/win/CPP/Windows/MemoryLock.cpp
deleted file mode 100644
index e0f430996..000000000
--- a/src/libs/7zip/win/CPP/Windows/MemoryLock.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-// Common/MemoryLock.cpp
-
-#include "StdAfx.h"
-
-namespace NWindows {
-namespace NSecurity {
-
-#ifndef UNDER_CE
-
-#ifndef _UNICODE
-typedef BOOL (WINAPI * OpenProcessTokenP)(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);
-typedef BOOL (WINAPI * LookupPrivilegeValueP)(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid);
-typedef BOOL (WINAPI * AdjustTokenPrivilegesP)(HANDLE TokenHandle, BOOL DisableAllPrivileges,
- PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState,PDWORD ReturnLength);
-#endif
-
-#ifdef _UNICODE
-bool EnableLockMemoryPrivilege(
-#else
-static bool EnableLockMemoryPrivilege2(HMODULE hModule,
-#endif
-bool enable)
-{
- #ifndef _UNICODE
- if (hModule == NULL)
- return false;
- OpenProcessTokenP openProcessToken = (OpenProcessTokenP)GetProcAddress(hModule, "OpenProcessToken");
- LookupPrivilegeValueP lookupPrivilegeValue = (LookupPrivilegeValueP)GetProcAddress(hModule, "LookupPrivilegeValueA" );
- AdjustTokenPrivilegesP adjustTokenPrivileges = (AdjustTokenPrivilegesP)GetProcAddress(hModule, "AdjustTokenPrivileges");
- if (openProcessToken == NULL || adjustTokenPrivileges == NULL || lookupPrivilegeValue == NULL)
- return false;
- #endif
-
- HANDLE token;
- if (!
- #ifdef _UNICODE
- ::OpenProcessToken
- #else
- openProcessToken
- #endif
- (::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
- return false;
- TOKEN_PRIVILEGES tp;
- bool res = false;
- if (
- #ifdef _UNICODE
- ::LookupPrivilegeValue
- #else
- lookupPrivilegeValue
- #endif
- (NULL, SE_LOCK_MEMORY_NAME, &(tp.Privileges[0].Luid)))
- {
- tp.PrivilegeCount = 1;
- tp.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED: 0;
- if (
- #ifdef _UNICODE
- ::AdjustTokenPrivileges
- #else
- adjustTokenPrivileges
- #endif
- (token, FALSE, &tp, 0, NULL, NULL))
- res = (GetLastError() == ERROR_SUCCESS);
- }
- ::CloseHandle(token);
- return res;
-}
-
-#ifndef _UNICODE
-bool EnableLockMemoryPrivilege(bool enable)
-{
- HMODULE hModule = LoadLibrary(TEXT("Advapi32.dll"));
- if (hModule == NULL)
- return false;
- bool res = EnableLockMemoryPrivilege2(hModule, enable);
- ::FreeLibrary(hModule);
- return res;
-}
-#endif
-
-#endif
-
-}}
diff --git a/src/libs/7zip/win/CPP/Windows/MemoryLock.h b/src/libs/7zip/win/CPP/Windows/MemoryLock.h
deleted file mode 100644
index 5fe619de0..000000000
--- a/src/libs/7zip/win/CPP/Windows/MemoryLock.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Windows/MemoryLock.h
-
-#ifndef __WINDOWS_MEMORYLOCK_H
-#define __WINDOWS_MEMORYLOCK_H
-
-namespace NWindows {
-namespace NSecurity {
-
-#ifndef UNDER_CE
-bool EnableLockMemoryPrivilege(bool enable = true);
-#endif
-
-}}
-
-#endif
diff --git a/src/libs/7zip/win/CPP/Windows/NtCheck.h b/src/libs/7zip/win/CPP/Windows/NtCheck.h
deleted file mode 100644
index e56318f00..000000000
--- a/src/libs/7zip/win/CPP/Windows/NtCheck.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Windows/NtCheck.h
-
-#ifndef __WINDOWS_NT_CHECK_H
-#define __WINDOWS_NT_CHECK_H
-
-#ifdef _WIN32
-
-#if !defined(_WIN64) && !defined(UNDER_CE)
-static inline bool IsItWindowsNT()
-{
- OSVERSIONINFO vi;
- vi.dwOSVersionInfoSize = sizeof(vi);
- return (::GetVersionEx(&vi) && vi.dwPlatformId == VER_PLATFORM_WIN32_NT);
-}
-#endif
-
-#ifndef _UNICODE
- #if defined(_WIN64) || defined(UNDER_CE)
- bool g_IsNT = true;
- #define SET_IS_NT
- #else
- bool g_IsNT = false;
- #define SET_IS_NT g_IsNT = IsItWindowsNT();
- #endif
- #define NT_CHECK_ACTION
- // #define NT_CHECK_ACTION { NT_CHECK_FAIL_ACTION }
-#else
- #if !defined(_WIN64) && !defined(UNDER_CE)
- #define NT_CHECK_ACTION if (!IsItWindowsNT()) { NT_CHECK_FAIL_ACTION }
- #else
- #define NT_CHECK_ACTION
- #endif
- #define SET_IS_NT
-#endif
-
-#define NT_CHECK NT_CHECK_ACTION SET_IS_NT
-
-#else
-
-#define NT_CHECK
-
-#endif
-
-#endif
diff --git a/src/libs/7zip/win/CPP/Windows/PropVariant.cpp b/src/libs/7zip/win/CPP/Windows/PropVariant.cpp
index 90212e08f..d16f576cc 100644
--- a/src/libs/7zip/win/CPP/Windows/PropVariant.cpp
+++ b/src/libs/7zip/win/CPP/Windows/PropVariant.cpp
@@ -2,13 +2,43 @@
#include "StdAfx.h"
-#include "PropVariant.h"
-
#include "../Common/Defs.h"
+#include "PropVariant.h"
+
namespace NWindows {
namespace NCOM {
+HRESULT PropVarEm_Alloc_Bstr(PROPVARIANT *p, unsigned numChars) throw()
+{
+ p->bstrVal = ::SysAllocStringLen(0, numChars);
+ if (!p->bstrVal)
+ {
+ p->vt = VT_ERROR;
+ p->scode = E_OUTOFMEMORY;
+ return E_OUTOFMEMORY;
+ }
+ p->vt = VT_BSTR;
+ return S_OK;
+}
+
+HRESULT PropVarEm_Set_Str(PROPVARIANT *p, const char *s) throw()
+{
+ UINT len = (UINT)strlen(s);
+ p->bstrVal = ::SysAllocStringLen(0, len);
+ if (!p->bstrVal)
+ {
+ p->vt = VT_ERROR;
+ p->scode = E_OUTOFMEMORY;
+ return E_OUTOFMEMORY;
+ }
+ p->vt = VT_BSTR;
+ BSTR dest = p->bstrVal;
+ for (UINT i = 0; i <= len; i++)
+ dest[i] = s[i];
+ return S_OK;
+}
+
CPropVariant::CPropVariant(const PROPVARIANT &varSrc)
{
vt = VT_EMPTY;
@@ -58,7 +88,7 @@ CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
vt = VT_BSTR;
wReserved1 = 0;
bstrVal = ::SysAllocString(lpszSrc);
- if (bstrVal == NULL && lpszSrc != NULL)
+ if (!bstrVal && lpszSrc)
{
throw kMemException;
// vt = VT_ERROR;
@@ -67,15 +97,14 @@ CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
return *this;
}
-
CPropVariant& CPropVariant::operator=(const char *s)
{
InternalClear();
vt = VT_BSTR;
wReserved1 = 0;
UINT len = (UINT)strlen(s);
- bstrVal = ::SysAllocStringByteLen(0, (UINT)len * sizeof(OLECHAR));
- if (bstrVal == NULL)
+ bstrVal = ::SysAllocStringLen(0, len);
+ if (!bstrVal)
{
throw kMemException;
// vt = VT_ERROR;
@@ -89,7 +118,7 @@ CPropVariant& CPropVariant::operator=(const char *s)
return *this;
}
-CPropVariant& CPropVariant::operator=(bool bSrc)
+CPropVariant& CPropVariant::operator=(bool bSrc) throw()
{
if (vt != VT_BOOL)
{
@@ -100,22 +129,40 @@ CPropVariant& CPropVariant::operator=(bool bSrc)
return *this;
}
+BSTR CPropVariant::AllocBstr(unsigned numChars)
+{
+ if (vt != VT_EMPTY)
+ InternalClear();
+ vt = VT_BSTR;
+ wReserved1 = 0;
+ bstrVal = ::SysAllocStringLen(0, numChars);
+ if (!bstrVal)
+ {
+ throw kMemException;
+ // vt = VT_ERROR;
+ // scode = E_OUTOFMEMORY;
+ }
+ return bstrVal;
+}
+
#define SET_PROP_FUNC(type, id, dest) \
- CPropVariant& CPropVariant::operator=(type value) \
+ CPropVariant& CPropVariant::operator=(type value) throw() \
{ if (vt != id) { InternalClear(); vt = id; } \
dest = value; return *this; }
SET_PROP_FUNC(Byte, VT_UI1, bVal)
-SET_PROP_FUNC(Int16, VT_I2, iVal)
+// SET_PROP_FUNC(Int16, VT_I2, iVal)
SET_PROP_FUNC(Int32, VT_I4, lVal)
SET_PROP_FUNC(UInt32, VT_UI4, ulVal)
SET_PROP_FUNC(UInt64, VT_UI8, uhVal.QuadPart)
+SET_PROP_FUNC(Int64, VT_I8, hVal.QuadPart)
SET_PROP_FUNC(const FILETIME &, VT_FILETIME, filetime)
-static HRESULT MyPropVariantClear(PROPVARIANT *prop)
+HRESULT PropVariant_Clear(PROPVARIANT *prop) throw()
{
- switch(prop->vt)
+ switch (prop->vt)
{
+ case VT_EMPTY:
case VT_UI1:
case VT_I1:
case VT_I2:
@@ -134,17 +181,24 @@ static HRESULT MyPropVariantClear(PROPVARIANT *prop)
case VT_DATE:
prop->vt = VT_EMPTY;
prop->wReserved1 = 0;
+ prop->wReserved2 = 0;
+ prop->wReserved3 = 0;
+ prop->uhVal.QuadPart = 0;
return S_OK;
}
return ::VariantClear((VARIANTARG *)prop);
+ // return ::PropVariantClear(prop);
+ // PropVariantClear can clear VT_BLOB.
}
-HRESULT CPropVariant::Clear()
+HRESULT CPropVariant::Clear() throw()
{
- return MyPropVariantClear(this);
+ if (vt == VT_EMPTY)
+ return S_OK;
+ return PropVariant_Clear(this);
}
-HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc)
+HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) throw()
{
::VariantClear((tagVARIANT *)this);
switch(pSrc->vt)
@@ -172,7 +226,7 @@ HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc)
}
-HRESULT CPropVariant::Attach(PROPVARIANT *pSrc)
+HRESULT CPropVariant::Attach(PROPVARIANT *pSrc) throw()
{
HRESULT hr = Clear();
if (FAILED(hr))
@@ -182,18 +236,23 @@ HRESULT CPropVariant::Attach(PROPVARIANT *pSrc)
return S_OK;
}
-HRESULT CPropVariant::Detach(PROPVARIANT *pDest)
+HRESULT CPropVariant::Detach(PROPVARIANT *pDest) throw()
{
- HRESULT hr = MyPropVariantClear(pDest);
- if (FAILED(hr))
- return hr;
+ if (pDest->vt != VT_EMPTY)
+ {
+ HRESULT hr = PropVariant_Clear(pDest);
+ if (FAILED(hr))
+ return hr;
+ }
memcpy(pDest, this, sizeof(PROPVARIANT));
vt = VT_EMPTY;
return S_OK;
}
-HRESULT CPropVariant::InternalClear()
+HRESULT CPropVariant::InternalClear() throw()
{
+ if (vt == VT_EMPTY)
+ return S_OK;
HRESULT hr = Clear();
if (FAILED(hr))
{
@@ -215,7 +274,7 @@ void CPropVariant::InternalCopy(const PROPVARIANT *pSrc)
}
}
-int CPropVariant::Compare(const CPropVariant &a)
+int CPropVariant::Compare(const CPropVariant &a) throw()
{
if (vt != a.vt)
return MyCompare(vt, a.vt);
@@ -233,9 +292,7 @@ int CPropVariant::Compare(const CPropVariant &a)
case VT_UI8: return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart);
case VT_BOOL: return -MyCompare(boolVal, a.boolVal);
case VT_FILETIME: return ::CompareFileTime(&filetime, &a.filetime);
- case VT_BSTR:
- return 0; // Not implemented
- // return MyCompare(aPropVarint.cVal);
+ case VT_BSTR: return 0; // Not implemented
default: return 0;
}
}
diff --git a/src/libs/7zip/win/CPP/Windows/PropVariant.h b/src/libs/7zip/win/CPP/Windows/PropVariant.h
index d018034eb..d71b85e1d 100644
--- a/src/libs/7zip/win/CPP/Windows/PropVariant.h
+++ b/src/libs/7zip/win/CPP/Windows/PropVariant.h
@@ -1,29 +1,73 @@
// Windows/PropVariant.h
-#ifndef __WINDOWS_PROPVARIANT_H
-#define __WINDOWS_PROPVARIANT_H
+#ifndef __WINDOWS_PROP_VARIANT_H
+#define __WINDOWS_PROP_VARIANT_H
+#include "../Common/MyTypes.h"
#include "../Common/MyWindows.h"
-#include "../Common/Types.h"
namespace NWindows {
namespace NCOM {
+HRESULT PropVariant_Clear(PROPVARIANT *p) throw();
+
+HRESULT PropVarEm_Alloc_Bstr(PROPVARIANT *p, unsigned numChars) throw();
+HRESULT PropVarEm_Set_Str(PROPVARIANT *p, const char *s) throw();
+
+inline void PropVarEm_Set_UInt32(PROPVARIANT *p, UInt32 v) throw()
+{
+ p->vt = VT_UI4;
+ p->ulVal = v;
+}
+
+inline void PropVarEm_Set_UInt64(PROPVARIANT *p, UInt64 v) throw()
+{
+ p->vt = VT_UI8;
+ p->uhVal.QuadPart = v;
+}
+
+inline void PropVarEm_Set_FileTime64(PROPVARIANT *p, UInt64 v) throw()
+{
+ p->vt = VT_FILETIME;
+ p->filetime.dwLowDateTime = (DWORD)v;
+ p->filetime.dwHighDateTime = (DWORD)(v >> 32);
+}
+
+inline void PropVarEm_Set_Bool(PROPVARIANT *p, bool b) throw()
+{
+ p->vt = VT_BOOL;
+ p->boolVal = (b ? VARIANT_TRUE : VARIANT_FALSE);
+}
+
+
class CPropVariant : public tagPROPVARIANT
{
public:
- CPropVariant() { vt = VT_EMPTY; wReserved1 = 0; }
- ~CPropVariant() { Clear(); }
+ CPropVariant()
+ {
+ vt = VT_EMPTY;
+ wReserved1 = 0;
+ // wReserved2 = 0;
+ // wReserved3 = 0;
+ // uhVal.QuadPart = 0;
+ bstrVal = 0;
+ }
+ ~CPropVariant() throw() { Clear(); }
CPropVariant(const PROPVARIANT &varSrc);
CPropVariant(const CPropVariant &varSrc);
CPropVariant(BSTR bstrSrc);
CPropVariant(LPCOLESTR lpszSrc);
CPropVariant(bool bSrc) { vt = VT_BOOL; wReserved1 = 0; boolVal = (bSrc ? VARIANT_TRUE : VARIANT_FALSE); };
CPropVariant(Byte value) { vt = VT_UI1; wReserved1 = 0; bVal = value; }
- CPropVariant(Int16 value) { vt = VT_I2; wReserved1 = 0; iVal = value; }
- CPropVariant(Int32 value) { vt = VT_I4; wReserved1 = 0; lVal = value; }
+
+private:
+ CPropVariant(Int16 value); // { vt = VT_I2; wReserved1 = 0; iVal = value; }
+ CPropVariant(Int32 value); // { vt = VT_I4; wReserved1 = 0; lVal = value; }
+
+public:
CPropVariant(UInt32 value) { vt = VT_UI4; wReserved1 = 0; ulVal = value; }
CPropVariant(UInt64 value) { vt = VT_UI8; wReserved1 = 0; uhVal.QuadPart = value; }
+ CPropVariant(Int64 value) { vt = VT_I8; wReserved1 = 0; hVal.QuadPart = value; }
CPropVariant(const FILETIME &value) { vt = VT_FILETIME; wReserved1 = 0; filetime = value; }
CPropVariant& operator=(const CPropVariant &varSrc);
@@ -31,24 +75,31 @@ public:
CPropVariant& operator=(BSTR bstrSrc);
CPropVariant& operator=(LPCOLESTR lpszSrc);
CPropVariant& operator=(const char *s);
- CPropVariant& operator=(bool bSrc);
- CPropVariant& operator=(Byte value);
- CPropVariant& operator=(Int16 value);
- CPropVariant& operator=(Int32 value);
- CPropVariant& operator=(UInt32 value);
- CPropVariant& operator=(Int64 value);
- CPropVariant& operator=(UInt64 value);
- CPropVariant& operator=(const FILETIME &value);
-
- HRESULT Clear();
- HRESULT Copy(const PROPVARIANT *pSrc);
- HRESULT Attach(PROPVARIANT *pSrc);
- HRESULT Detach(PROPVARIANT *pDest);
-
- HRESULT InternalClear();
+
+ CPropVariant& operator=(bool bSrc) throw();
+ CPropVariant& operator=(Byte value) throw();
+
+private:
+ CPropVariant& operator=(Int16 value) throw();
+
+public:
+ CPropVariant& operator=(Int32 value) throw();
+ CPropVariant& operator=(UInt32 value) throw();
+ CPropVariant& operator=(UInt64 value) throw();
+ CPropVariant& operator=(Int64 value) throw();
+ CPropVariant& operator=(const FILETIME &value) throw();
+
+ BSTR AllocBstr(unsigned numChars);
+
+ HRESULT Clear() throw();
+ HRESULT Copy(const PROPVARIANT *pSrc) throw();
+ HRESULT Attach(PROPVARIANT *pSrc) throw();
+ HRESULT Detach(PROPVARIANT *pDest) throw();
+
+ HRESULT InternalClear() throw();
void InternalCopy(const PROPVARIANT *pSrc);
- int Compare(const CPropVariant &a1);
+ int Compare(const CPropVariant &a) throw();
};
}}
diff --git a/src/libs/7zip/win/CPP/Windows/PropVariantConv.cpp b/src/libs/7zip/win/CPP/Windows/PropVariantConv.cpp
new file mode 100644
index 000000000..dfb93d6d6
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/PropVariantConv.cpp
@@ -0,0 +1,99 @@
+// PropVariantConvert.cpp
+
+#include "StdAfx.h"
+
+#include "../Common/IntToString.h"
+
+#include "Defs.h"
+#include "PropVariantConv.h"
+
+#define UINT_TO_STR_2(c, val) { s[0] = (c); s[1] = (char)('0' + (val) / 10); s[2] = (char)('0' + (val) % 10); s += 3; }
+
+bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime, bool includeSeconds) throw()
+{
+ SYSTEMTIME st;
+ if (!BOOLToBool(FileTimeToSystemTime(&ft, &st)))
+ {
+ *s = 0;
+ return false;
+ }
+ unsigned val = st.wYear;
+ if (val >= 10000)
+ {
+ *s++ = (char)('0' + val / 10000);
+ val %= 10000;
+ }
+ {
+ s[3] = (char)('0' + val % 10); val /= 10;
+ s[2] = (char)('0' + val % 10); val /= 10;
+ s[1] = (char)('0' + val % 10);
+ s[0] = (char)('0' + val / 10);
+ s += 4;
+ }
+ UINT_TO_STR_2('-', st.wMonth);
+ UINT_TO_STR_2('-', st.wDay);
+ if (includeTime)
+ {
+ UINT_TO_STR_2(' ', st.wHour);
+ UINT_TO_STR_2(':', st.wMinute);
+ if (includeSeconds)
+ UINT_TO_STR_2(':', st.wSecond);
+ }
+ *s = 0;
+ return true;
+}
+
+void ConvertFileTimeToString(const FILETIME &ft, wchar_t *dest, bool includeTime, bool includeSeconds) throw()
+{
+ char s[32];
+ ConvertFileTimeToString(ft, s, includeTime, includeSeconds);
+ for (unsigned i = 0;; i++)
+ {
+ unsigned char c = s[i];
+ dest[i] = c;
+ if (c == 0)
+ return;
+ }
+}
+
+void ConvertPropVariantToShortString(const PROPVARIANT &prop, char *dest) throw()
+{
+ *dest = 0;
+ switch (prop.vt)
+ {
+ case VT_EMPTY: return;
+ case VT_BSTR: dest[0] = '?'; dest[1] = 0; return;
+ case VT_UI1: ConvertUInt32ToString(prop.bVal, dest); return;
+ case VT_UI2: ConvertUInt32ToString(prop.uiVal, dest); return;
+ case VT_UI4: ConvertUInt32ToString(prop.ulVal, dest); return;
+ case VT_UI8: ConvertUInt64ToString(prop.uhVal.QuadPart, dest); return;
+ case VT_FILETIME: ConvertFileTimeToString(prop.filetime, dest, true, true); return;
+ // case VT_I1: return ConvertInt64ToString(prop.cVal, dest); return;
+ case VT_I2: ConvertInt64ToString(prop.iVal, dest); return;
+ case VT_I4: ConvertInt64ToString(prop.lVal, dest); return;
+ case VT_I8: ConvertInt64ToString(prop.hVal.QuadPart, dest); return;
+ case VT_BOOL: dest[0] = VARIANT_BOOLToBool(prop.boolVal) ? '+' : '-'; dest[1] = 0; return;
+ default: dest[0] = '?'; dest[1] = ':'; ConvertUInt64ToString(prop.vt, dest + 2);
+ }
+}
+
+void ConvertPropVariantToShortString(const PROPVARIANT &prop, wchar_t *dest) throw()
+{
+ *dest = 0;
+ switch (prop.vt)
+ {
+ case VT_EMPTY: return;
+ case VT_BSTR: dest[0] = '?'; dest[1] = 0; return;
+ case VT_UI1: ConvertUInt32ToString(prop.bVal, dest); return;
+ case VT_UI2: ConvertUInt32ToString(prop.uiVal, dest); return;
+ case VT_UI4: ConvertUInt32ToString(prop.ulVal, dest); return;
+ case VT_UI8: ConvertUInt64ToString(prop.uhVal.QuadPart, dest); return;
+ case VT_FILETIME: ConvertFileTimeToString(prop.filetime, dest, true, true); return;
+ // case VT_I1: return ConvertInt64ToString(prop.cVal, dest); return;
+ case VT_I2: ConvertInt64ToString(prop.iVal, dest); return;
+ case VT_I4: ConvertInt64ToString(prop.lVal, dest); return;
+ case VT_I8: ConvertInt64ToString(prop.hVal.QuadPart, dest); return;
+ case VT_BOOL: dest[0] = VARIANT_BOOLToBool(prop.boolVal) ? '+' : '-'; dest[1] = 0; return;
+ default: dest[0] = '?'; dest[1] = ':'; ConvertUInt32ToString(prop.vt, dest + 2);
+ }
+}
diff --git a/src/libs/7zip/win/CPP/Windows/PropVariantConv.h b/src/libs/7zip/win/CPP/Windows/PropVariantConv.h
new file mode 100644
index 000000000..5d26357f0
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/PropVariantConv.h
@@ -0,0 +1,30 @@
+// Windows/PropVariantConv.h
+
+#ifndef __PROP_VARIANT_CONV_H
+#define __PROP_VARIANT_CONV_H
+
+#include "../Common/MyTypes.h"
+
+// provide at least 32 bytes for buffer including zero-end
+bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime = true, bool includeSeconds = true) throw();
+void ConvertFileTimeToString(const FILETIME &ft, wchar_t *s, bool includeTime = true, bool includeSeconds = true) throw();
+
+// provide at least 32 bytes for buffer including zero-end
+// don't send VT_BSTR to these functions
+void ConvertPropVariantToShortString(const PROPVARIANT &prop, char *dest) throw();
+void ConvertPropVariantToShortString(const PROPVARIANT &prop, wchar_t *dest) throw();
+
+inline bool ConvertPropVariantToUInt64(const PROPVARIANT &prop, UInt64 &value)
+{
+ switch (prop.vt)
+ {
+ case VT_UI8: value = (UInt64)prop.uhVal.QuadPart; return true;
+ case VT_UI4: value = prop.ulVal; return true;
+ case VT_UI2: value = prop.uiVal; return true;
+ case VT_UI1: value = prop.bVal; return true;
+ case VT_EMPTY: return false;
+ default: throw 151199;
+ }
+}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/PropVariantConversions.cpp b/src/libs/7zip/win/CPP/Windows/PropVariantConversions.cpp
deleted file mode 100644
index 2d8456cd6..000000000
--- a/src/libs/7zip/win/CPP/Windows/PropVariantConversions.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-// PropVariantConversions.cpp
-
-#include "StdAfx.h"
-
-#include "Common/IntToString.h"
-#include "Common/StringConvert.h"
-
-#include "Windows/Defs.h"
-
-#include "PropVariantConversions.h"
-
-static UString ConvertUInt64ToString(UInt64 value)
-{
- wchar_t buffer[32];
- ConvertUInt64ToString(value, buffer);
- return buffer;
-}
-
-static UString ConvertInt64ToString(Int64 value)
-{
- wchar_t buffer[32];
- ConvertInt64ToString(value, buffer);
- return buffer;
-}
-
-static char *UIntToStringSpec(char c, UInt32 value, char *s, int numPos)
-{
- if (c != 0)
- *s++ = c;
- char temp[16];
- int pos = 0;
- do
- {
- temp[pos++] = (char)('0' + value % 10);
- value /= 10;
- }
- while (value != 0);
- int i;
- for (i = 0; i < numPos - pos; i++)
- *s++ = '0';
- do
- *s++ = temp[--pos];
- while (pos > 0);
- *s = '\0';
- return s;
-}
-
-bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime, bool includeSeconds)
-{
- s[0] = '\0';
- SYSTEMTIME st;
- if (!BOOLToBool(FileTimeToSystemTime(&ft, &st)))
- return false;
- s = UIntToStringSpec(0, st.wYear, s, 4);
- s = UIntToStringSpec('-', st.wMonth, s, 2);
- s = UIntToStringSpec('-', st.wDay, s, 2);
- if (includeTime)
- {
- s = UIntToStringSpec(' ', st.wHour, s, 2);
- s = UIntToStringSpec(':', st.wMinute, s, 2);
- if (includeSeconds)
- UIntToStringSpec(':', st.wSecond, s, 2);
- }
- return true;
-}
-
-UString ConvertFileTimeToString(const FILETIME &ft, bool includeTime, bool includeSeconds)
-{
- char s[32];
- ConvertFileTimeToString(ft, s, includeTime, includeSeconds);
- return GetUnicodeString(s);
-}
-
-
-UString ConvertPropVariantToString(const PROPVARIANT &prop)
-{
- switch (prop.vt)
- {
- case VT_EMPTY: return UString();
- case VT_BSTR: return prop.bstrVal;
- case VT_UI1: return ConvertUInt64ToString(prop.bVal);
- case VT_UI2: return ConvertUInt64ToString(prop.uiVal);
- case VT_UI4: return ConvertUInt64ToString(prop.ulVal);
- case VT_UI8: return ConvertUInt64ToString(prop.uhVal.QuadPart);
- case VT_FILETIME: return ConvertFileTimeToString(prop.filetime, true, true);
- // case VT_I1: return ConvertInt64ToString(prop.cVal);
- case VT_I2: return ConvertInt64ToString(prop.iVal);
- case VT_I4: return ConvertInt64ToString(prop.lVal);
- case VT_I8: return ConvertInt64ToString(prop.hVal.QuadPart);
- case VT_BOOL: return VARIANT_BOOLToBool(prop.boolVal) ? L"+" : L"-";
- default: throw 150245;
- }
-}
-
-UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &prop)
-{
- switch (prop.vt)
- {
- case VT_UI1: return prop.bVal;
- case VT_UI2: return prop.uiVal;
- case VT_UI4: return prop.ulVal;
- case VT_UI8: return (UInt64)prop.uhVal.QuadPart;
- default: throw 151199;
- }
-}
diff --git a/src/libs/7zip/win/CPP/Windows/PropVariantConversions.h b/src/libs/7zip/win/CPP/Windows/PropVariantConversions.h
deleted file mode 100644
index 3de4dedb3..000000000
--- a/src/libs/7zip/win/CPP/Windows/PropVariantConversions.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// Windows/PropVariantConversions.h
-
-#ifndef __PROP_VARIANT_CONVERSIONS_H
-#define __PROP_VARIANT_CONVERSIONS_H
-
-#include "Common/MyString.h"
-#include "Common/Types.h"
-
-bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime = true, bool includeSeconds = true);
-UString ConvertFileTimeToString(const FILETIME &ft, bool includeTime = true, bool includeSeconds = true);
-UString ConvertPropVariantToString(const PROPVARIANT &prop);
-UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &prop);
-
-#endif
diff --git a/src/libs/7zip/win/CPP/Windows/Registry.cpp b/src/libs/7zip/win/CPP/Windows/Registry.cpp
deleted file mode 100644
index 8b25375d9..000000000
--- a/src/libs/7zip/win/CPP/Windows/Registry.cpp
+++ /dev/null
@@ -1,369 +0,0 @@
-// Windows/Registry.cpp
-
-#include "StdAfx.h"
-
-#ifndef _UNICODE
-#include "Common/StringConvert.h"
-#endif
-#include "Windows/Registry.h"
-
-#ifndef _UNICODE
-extern bool g_IsNT;
-#endif
-
-namespace NWindows {
-namespace NRegistry {
-
-#define MYASSERT(expr) // _ASSERTE(expr)
-
-LONG CKey::Create(HKEY parentKey, LPCTSTR keyName,
- LPTSTR keyClass, DWORD options, REGSAM accessMask,
- LPSECURITY_ATTRIBUTES securityAttributes, LPDWORD disposition)
-{
- MYASSERT(parentKey != NULL);
- DWORD dispositionReal;
- HKEY key = NULL;
- LONG res = RegCreateKeyEx(parentKey, keyName, 0, keyClass,
- options, accessMask, securityAttributes, &key, &dispositionReal);
- if (disposition != NULL)
- *disposition = dispositionReal;
- if (res == ERROR_SUCCESS)
- {
- res = Close();
- _object = key;
- }
- return res;
-}
-
-LONG CKey::Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask)
-{
- MYASSERT(parentKey != NULL);
- HKEY key = NULL;
- LONG res = RegOpenKeyEx(parentKey, keyName, 0, accessMask, &key);
- if (res == ERROR_SUCCESS)
- {
- res = Close();
- MYASSERT(res == ERROR_SUCCESS);
- _object = key;
- }
- return res;
-}
-
-LONG CKey::Close()
-{
- LONG res = ERROR_SUCCESS;
- if (_object != NULL)
- {
- res = RegCloseKey(_object);
- _object = NULL;
- }
- return res;
-}
-
-// win95, win98: deletes sunkey and all its subkeys
-// winNT to be deleted must not have subkeys
-LONG CKey::DeleteSubKey(LPCTSTR subKeyName)
-{
- MYASSERT(_object != NULL);
- return RegDeleteKey(_object, subKeyName);
-}
-
-LONG CKey::RecurseDeleteKey(LPCTSTR subKeyName)
-{
- CKey key;
- LONG res = key.Open(_object, subKeyName, KEY_READ | KEY_WRITE);
- if (res != ERROR_SUCCESS)
- return res;
- FILETIME fileTime;
- const UInt32 kBufferSize = MAX_PATH + 1; // 256 in ATL
- DWORD size = kBufferSize;
- TCHAR buffer[kBufferSize];
- while (RegEnumKeyEx(key._object, 0, buffer, &size, NULL, NULL, NULL, &fileTime) == ERROR_SUCCESS)
- {
- res = key.RecurseDeleteKey(buffer);
- if (res != ERROR_SUCCESS)
- return res;
- size = kBufferSize;
- }
- key.Close();
- return DeleteSubKey(subKeyName);
-}
-
-
-/////////////////////////
-// Value Functions
-
-static inline UInt32 BoolToUINT32(bool value) { return (value ? 1: 0); }
-static inline bool UINT32ToBool(UInt32 value) { return (value != 0); }
-
-
-LONG CKey::DeleteValue(LPCTSTR name)
-{
- MYASSERT(_object != NULL);
- return ::RegDeleteValue(_object, name);
-}
-
-#ifndef _UNICODE
-LONG CKey::DeleteValue(LPCWSTR name)
-{
- MYASSERT(_object != NULL);
- if (g_IsNT)
- return ::RegDeleteValueW(_object, name);
- return DeleteValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name));
-}
-#endif
-
-LONG CKey::SetValue(LPCTSTR name, UInt32 value)
-{
- MYASSERT(_object != NULL);
- return RegSetValueEx(_object, name, NULL, REG_DWORD,
- (BYTE * const)&value, sizeof(UInt32));
-}
-
-LONG CKey::SetValue(LPCTSTR name, bool value)
-{
- return SetValue(name, BoolToUINT32(value));
-}
-
-LONG CKey::SetValue(LPCTSTR name, LPCTSTR value)
-{
- MYASSERT(value != NULL);
- MYASSERT(_object != NULL);
- return RegSetValueEx(_object, name, NULL, REG_SZ,
- (const BYTE * )value, (lstrlen(value) + 1) * sizeof(TCHAR));
-}
-
-/*
-LONG CKey::SetValue(LPCTSTR name, const CSysString &value)
-{
- MYASSERT(value != NULL);
- MYASSERT(_object != NULL);
- return RegSetValueEx(_object, name, NULL, REG_SZ,
- (const BYTE *)(const TCHAR *)value, (value.Length() + 1) * sizeof(TCHAR));
-}
-*/
-
-#ifndef _UNICODE
-
-LONG CKey::SetValue(LPCWSTR name, LPCWSTR value)
-{
- MYASSERT(value != NULL);
- MYASSERT(_object != NULL);
- if (g_IsNT)
- return RegSetValueExW(_object, name, NULL, REG_SZ,
- (const BYTE * )value, (DWORD)((wcslen(value) + 1) * sizeof(wchar_t)));
- return SetValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name),
- value == 0 ? 0 : (LPCSTR)GetSystemString(value));
-}
-
-#endif
-
-
-LONG CKey::SetValue(LPCTSTR name, const void *value, UInt32 size)
-{
- MYASSERT(value != NULL);
- MYASSERT(_object != NULL);
- return RegSetValueEx(_object, name, NULL, REG_BINARY,
- (const BYTE *)value, size);
-}
-
-LONG SetValue(HKEY parentKey, LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value)
-{
- MYASSERT(value != NULL);
- CKey key;
- LONG res = key.Create(parentKey, keyName);
- if (res == ERROR_SUCCESS)
- res = key.SetValue(valueName, value);
- return res;
-}
-
-LONG CKey::SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value)
-{
- MYASSERT(value != NULL);
- CKey key;
- LONG res = key.Create(_object, keyName);
- if (res == ERROR_SUCCESS)
- res = key.SetValue(valueName, value);
- return res;
-}
-
-LONG CKey::QueryValue(LPCTSTR name, UInt32 &value)
-{
- DWORD type = NULL;
- DWORD count = sizeof(DWORD);
- LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type,
- (LPBYTE)&value, &count);
- MYASSERT((res!=ERROR_SUCCESS) || (type == REG_DWORD));
- MYASSERT((res!=ERROR_SUCCESS) || (count == sizeof(UInt32)));
- return res;
-}
-
-LONG CKey::QueryValue(LPCTSTR name, bool &value)
-{
- UInt32 uintValue = BoolToUINT32(value);
- LONG res = QueryValue(name, uintValue);
- value = UINT32ToBool(uintValue);
- return res;
-}
-
-LONG CKey::GetValue_IfOk(LPCTSTR name, UInt32 &value)
-{
- UInt32 newVal;
- LONG res = QueryValue(name, newVal);
- if (res == ERROR_SUCCESS)
- value = newVal;
- return res;
-}
-
-LONG CKey::GetValue_IfOk(LPCTSTR name, bool &value)
-{
- bool newVal;
- LONG res = QueryValue(name, newVal);
- if (res == ERROR_SUCCESS)
- value = newVal;
- return res;
-}
-
-LONG CKey::QueryValue(LPCTSTR name, LPTSTR value, UInt32 &count)
-{
- MYASSERT(count != NULL);
- DWORD type = NULL;
- LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, (LPBYTE)value, (DWORD *)&count);
- MYASSERT((res!=ERROR_SUCCESS) || (type == REG_SZ) || (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));
- return res;
-}
-
-LONG CKey::QueryValue(LPCTSTR name, CSysString &value)
-{
- value.Empty();
- DWORD type = NULL;
- UInt32 currentSize = 0;
- LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, NULL, (DWORD *)&currentSize);
- if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
- return res;
- res = QueryValue(name, value.GetBuffer(currentSize), currentSize);
- value.ReleaseBuffer();
- return res;
-}
-
-#ifndef _UNICODE
-LONG CKey::QueryValue(LPCWSTR name, LPWSTR value, UInt32 &count)
-{
- MYASSERT(count != NULL);
- DWORD type = NULL;
- LONG res = RegQueryValueExW(_object, name, NULL, &type, (LPBYTE)value, (DWORD *)&count);
- MYASSERT((res!=ERROR_SUCCESS) || (type == REG_SZ) || (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));
- return res;
-}
-LONG CKey::QueryValue(LPCWSTR name, UString &value)
-{
- value.Empty();
- DWORD type = NULL;
- UInt32 currentSize = 0;
-
- LONG res;
- if (g_IsNT)
- {
- res = RegQueryValueExW(_object, name, NULL, &type, NULL, (DWORD *)&currentSize);
- if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
- return res;
- res = QueryValue(name, value.GetBuffer(currentSize), currentSize);
- value.ReleaseBuffer();
- }
- else
- {
- AString vTemp;
- res = QueryValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name), vTemp);
- value = GetUnicodeString(vTemp);
- }
- return res;
-}
-#endif
-
-LONG CKey::QueryValue(LPCTSTR name, void *value, UInt32 &count)
-{
- DWORD type = NULL;
- LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, (LPBYTE)value, (DWORD *)&count);
- MYASSERT((res!=ERROR_SUCCESS) || (type == REG_BINARY));
- return res;
-}
-
-
-LONG CKey::QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize)
-{
- DWORD type = NULL;
- dataSize = 0;
- LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, NULL, (DWORD *)&dataSize);
- if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
- return res;
- value.SetCapacity(dataSize);
- return QueryValue(name, (BYTE *)value, dataSize);
-}
-
-LONG CKey::EnumKeys(CSysStringVector &keyNames)
-{
- keyNames.Clear();
- CSysString keyName;
- for (UInt32 index = 0; ; index++)
- {
- const UInt32 kBufferSize = MAX_PATH + 1; // 256 in ATL
- FILETIME lastWriteTime;
- UInt32 nameSize = kBufferSize;
- LONG result = ::RegEnumKeyEx(_object, index, keyName.GetBuffer(kBufferSize),
- (DWORD *)&nameSize, NULL, NULL, NULL, &lastWriteTime);
- keyName.ReleaseBuffer();
- if (result == ERROR_NO_MORE_ITEMS)
- break;
- if (result != ERROR_SUCCESS)
- return result;
- keyNames.Add(keyName);
- }
- return ERROR_SUCCESS;
-}
-
-LONG CKey::SetValue_Strings(LPCTSTR valueName, const UStringVector &strings)
-{
- UInt32 numChars = 0;
- int i;
- for (i = 0; i < strings.Size(); i++)
- numChars += strings[i].Length() + 1;
- CBuffer<wchar_t> buffer;
- buffer.SetCapacity(numChars);
- int pos = 0;
- for (i = 0; i < strings.Size(); i++)
- {
- const UString &s = strings[i];
- MyStringCopy((wchar_t *)buffer + pos, (const wchar_t *)s);
- pos += s.Length() + 1;
- }
- return SetValue(valueName, buffer, numChars * sizeof(wchar_t));
-}
-
-LONG CKey::GetValue_Strings(LPCTSTR valueName, UStringVector &strings)
-{
- strings.Clear();
- CByteBuffer buffer;
- UInt32 dataSize;
- LONG res = QueryValue(valueName, buffer, dataSize);
- if (res != ERROR_SUCCESS)
- return res;
- if (dataSize % sizeof(wchar_t) != 0)
- return E_FAIL;
- const wchar_t *data = (const wchar_t *)(const Byte *)buffer;
- int numChars = dataSize / sizeof(wchar_t);
- UString s;
- for (int i = 0; i < numChars; i++)
- {
- wchar_t c = data[i];
- if (c == 0)
- {
- strings.Add(s);
- s.Empty();
- }
- else
- s += c;
- }
- return res;
-}
-
-}}
diff --git a/src/libs/7zip/win/CPP/Windows/Registry.h b/src/libs/7zip/win/CPP/Windows/Registry.h
deleted file mode 100644
index f0561e688..000000000
--- a/src/libs/7zip/win/CPP/Windows/Registry.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// Windows/Registry.h
-
-#ifndef __WINDOWS_REGISTRY_H
-#define __WINDOWS_REGISTRY_H
-
-#include "Common/Buffer.h"
-#include "Common/MyString.h"
-#include "Common/Types.h"
-
-namespace NWindows {
-namespace NRegistry {
-
-LONG SetValue(HKEY parentKey, LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value);
-
-class CKey
-{
- HKEY _object;
-public:
- CKey(): _object(NULL) {}
- ~CKey() { Close(); }
-
- operator HKEY() const { return _object; }
- void Attach(HKEY key) { _object = key; }
- HKEY Detach()
- {
- HKEY key = _object;
- _object = NULL;
- return key;
- }
-
- LONG Create(HKEY parentKey, LPCTSTR keyName,
- LPTSTR keyClass = REG_NONE, DWORD options = REG_OPTION_NON_VOLATILE,
- REGSAM accessMask = KEY_ALL_ACCESS,
- LPSECURITY_ATTRIBUTES securityAttributes = NULL,
- LPDWORD disposition = NULL);
- LONG Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask = KEY_ALL_ACCESS);
-
- LONG Close();
-
- LONG DeleteSubKey(LPCTSTR subKeyName);
- LONG RecurseDeleteKey(LPCTSTR subKeyName);
-
- LONG DeleteValue(LPCTSTR name);
- #ifndef _UNICODE
- LONG DeleteValue(LPCWSTR name);
- #endif
-
- LONG SetValue(LPCTSTR valueName, UInt32 value);
- LONG SetValue(LPCTSTR valueName, bool value);
- LONG SetValue(LPCTSTR valueName, LPCTSTR value);
- // LONG SetValue(LPCTSTR valueName, const CSysString &value);
- #ifndef _UNICODE
- LONG SetValue(LPCWSTR name, LPCWSTR value);
- // LONG SetValue(LPCWSTR name, const UString &value);
- #endif
-
- LONG SetValue(LPCTSTR name, const void *value, UInt32 size);
-
- LONG SetValue_Strings(LPCTSTR valueName, const UStringVector &strings);
- LONG GetValue_Strings(LPCTSTR valueName, UStringVector &strings);
-
- LONG SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value);
-
- LONG QueryValue(LPCTSTR name, UInt32 &value);
- LONG QueryValue(LPCTSTR name, bool &value);
- LONG QueryValue(LPCTSTR name, LPTSTR value, UInt32 &dataSize);
- LONG QueryValue(LPCTSTR name, CSysString &value);
-
- LONG GetValue_IfOk(LPCTSTR name, UInt32 &value);
- LONG GetValue_IfOk(LPCTSTR name, bool &value);
-
- #ifndef _UNICODE
- LONG QueryValue(LPCWSTR name, LPWSTR value, UInt32 &dataSize);
- LONG QueryValue(LPCWSTR name, UString &value);
- #endif
-
- LONG QueryValue(LPCTSTR name, void *value, UInt32 &dataSize);
- LONG QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize);
-
- LONG EnumKeys(CSysStringVector &keyNames);
-};
-
-}}
-
-#endif
diff --git a/src/libs/7zip/win/CPP/Windows/SecurityUtils.cpp b/src/libs/7zip/win/CPP/Windows/SecurityUtils.cpp
new file mode 100644
index 000000000..f997738ce
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/SecurityUtils.cpp
@@ -0,0 +1,179 @@
+// Windows/SecurityUtils.cpp
+
+#include "StdAfx.h"
+
+#include "SecurityUtils.h"
+
+namespace NWindows {
+namespace NSecurity {
+
+/*
+bool MyLookupAccountSid(LPCTSTR systemName, PSID sid,
+ CSysString &accountName, CSysString &domainName, PSID_NAME_USE sidNameUse)
+{
+ DWORD accountNameSize = 0, domainNameSize = 0;
+
+ if (!::LookupAccountSid(systemName, sid,
+ accountName.GetBuffer(0), &accountNameSize,
+ domainName.GetBuffer(0), &domainNameSize, sidNameUse))
+ {
+ if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ return false;
+ }
+ bool result = BOOLToBool(::LookupAccountSid(systemName, sid,
+ accountName.GetBuffer(accountNameSize), &accountNameSize,
+ domainName.GetBuffer(domainNameSize), &domainNameSize, sidNameUse));
+ accountName.ReleaseBuffer();
+ domainName.ReleaseBuffer();
+ return result;
+}
+*/
+
+static void SetLsaString(LPWSTR src, PLSA_UNICODE_STRING dest)
+{
+ int len = (int)wcslen(src);
+ dest->Length = (USHORT)(len * sizeof(WCHAR));
+ dest->MaximumLength = (USHORT)((len + 1) * sizeof(WCHAR));
+ dest->Buffer = src;
+}
+
+/*
+static void MyLookupSids(CPolicy &policy, PSID ps)
+{
+ LSA_REFERENCED_DOMAIN_LIST *referencedDomains = NULL;
+ LSA_TRANSLATED_NAME *names = NULL;
+ NTSTATUS nts = policy.LookupSids(1, &ps, &referencedDomains, &names);
+ int res = LsaNtStatusToWinError(nts);
+ LsaFreeMemory(referencedDomains);
+ LsaFreeMemory(names);
+}
+*/
+
+#ifndef _UNICODE
+typedef BOOL (WINAPI * LookupAccountNameWP)(
+ LPCWSTR lpSystemName,
+ LPCWSTR lpAccountName,
+ PSID Sid,
+ LPDWORD cbSid,
+ LPWSTR ReferencedDomainName,
+ LPDWORD cchReferencedDomainName,
+ PSID_NAME_USE peUse
+ );
+#endif
+
+static PSID GetSid(LPWSTR accountName)
+{
+ #ifndef _UNICODE
+ HMODULE hModule = GetModuleHandle(TEXT("Advapi32.dll"));
+ if (hModule == NULL)
+ return NULL;
+ LookupAccountNameWP lookupAccountNameW = (LookupAccountNameWP)GetProcAddress(hModule, "LookupAccountNameW");
+ if (lookupAccountNameW == NULL)
+ return NULL;
+ #endif
+
+ DWORD sidLen = 0, domainLen = 0;
+ SID_NAME_USE sidNameUse;
+ if (!
+ #ifdef _UNICODE
+ ::LookupAccountNameW
+ #else
+ lookupAccountNameW
+ #endif
+ (NULL, accountName, NULL, &sidLen, NULL, &domainLen, &sidNameUse))
+ {
+ if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+ {
+ PSID pSid = ::HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sidLen);
+ LPWSTR domainName = (LPWSTR)::HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (domainLen + 1) * sizeof(WCHAR));
+ BOOL res =
+ #ifdef _UNICODE
+ ::LookupAccountNameW
+ #else
+ lookupAccountNameW
+ #endif
+ (NULL, accountName, pSid, &sidLen, domainName, &domainLen, &sidNameUse);
+ ::HeapFree(GetProcessHeap(), 0, domainName);
+ if (res)
+ return pSid;
+ }
+ }
+ return NULL;
+}
+
+#define MY__SE_LOCK_MEMORY_NAME L"SeLockMemoryPrivilege"
+
+bool AddLockMemoryPrivilege()
+{
+ CPolicy policy;
+ LSA_OBJECT_ATTRIBUTES attr;
+ attr.Length = sizeof(attr);
+ attr.RootDirectory = NULL;
+ attr.ObjectName = NULL;
+ attr.Attributes = 0;
+ attr.SecurityDescriptor = NULL;
+ attr.SecurityQualityOfService = NULL;
+ if (policy.Open(NULL, &attr,
+ // GENERIC_WRITE)
+ POLICY_ALL_ACCESS)
+ // STANDARD_RIGHTS_REQUIRED,
+ // GENERIC_READ | GENERIC_EXECUTE | POLICY_VIEW_LOCAL_INFORMATION | POLICY_LOOKUP_NAMES)
+ != 0)
+ return false;
+ LSA_UNICODE_STRING userRights;
+ wchar_t s[128] = MY__SE_LOCK_MEMORY_NAME;
+ SetLsaString(s, &userRights);
+ WCHAR userName[256 + 2];
+ DWORD size = 256;
+ if (!GetUserNameW(userName, &size))
+ return false;
+ PSID psid = GetSid(userName);
+ if (psid == NULL)
+ return false;
+ bool res = false;
+
+ /*
+ PLSA_UNICODE_STRING userRightsArray;
+ ULONG countOfRights;
+ NTSTATUS status = policy.EnumerateAccountRights(psid, &userRightsArray, &countOfRights);
+ if (status != 0)
+ return false;
+ bool finded = false;
+ for (ULONG i = 0; i < countOfRights; i++)
+ {
+ LSA_UNICODE_STRING &ur = userRightsArray[i];
+ if (ur.Length != s.Length() * sizeof(WCHAR))
+ continue;
+ if (wcsncmp(ur.Buffer, s, s.Length()) != 0)
+ continue;
+ finded = true;
+ res = true;
+ break;
+ }
+ if (!finded)
+ */
+ {
+ /*
+ LSA_ENUMERATION_INFORMATION *enums;
+ ULONG countReturned;
+ NTSTATUS status = policy.EnumerateAccountsWithUserRight(&userRights, &enums, &countReturned);
+ if (status == 0)
+ {
+ for (ULONG i = 0; i < countReturned; i++)
+ MyLookupSids(policy, enums[i].Sid);
+ if (enums)
+ ::LsaFreeMemory(enums);
+ res = true;
+ }
+ */
+ NTSTATUS status = policy.AddAccountRights(psid, &userRights);
+ if (status == 0)
+ res = true;
+ // ULONG res = LsaNtStatusToWinError(status);
+ }
+ HeapFree(GetProcessHeap(), 0, psid);
+ return res;
+}
+
+}}
+
diff --git a/src/libs/7zip/win/CPP/Windows/SecurityUtils.h b/src/libs/7zip/win/CPP/Windows/SecurityUtils.h
new file mode 100644
index 000000000..715de2505
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/SecurityUtils.h
@@ -0,0 +1,167 @@
+// Windows/SecurityUtils.h
+
+#ifndef __WINDOWS_SECURITY_UTILS_H
+#define __WINDOWS_SECURITY_UTILS_H
+
+#include <NTSecAPI.h>
+
+#include "Defs.h"
+
+namespace NWindows {
+namespace NSecurity {
+
+class CAccessToken
+{
+ HANDLE _handle;
+public:
+ CAccessToken(): _handle(NULL) {};
+ ~CAccessToken() { Close(); }
+ bool Close()
+ {
+ if (_handle == NULL)
+ return true;
+ bool res = BOOLToBool(::CloseHandle(_handle));
+ if (res)
+ _handle = NULL;
+ return res;
+ }
+
+ bool OpenProcessToken(HANDLE processHandle, DWORD desiredAccess)
+ {
+ Close();
+ return BOOLToBool(::OpenProcessToken(processHandle, desiredAccess, &_handle));
+ }
+
+ /*
+ bool OpenThreadToken(HANDLE threadHandle, DWORD desiredAccess, bool openAsSelf)
+ {
+ Close();
+ return BOOLToBool(::OpenTreadToken(threadHandle, desiredAccess, BoolToBOOL(anOpenAsSelf), &_handle));
+ }
+ */
+
+ bool AdjustPrivileges(bool disableAllPrivileges, PTOKEN_PRIVILEGES newState,
+ DWORD bufferLength, PTOKEN_PRIVILEGES previousState, PDWORD returnLength)
+ { return BOOLToBool(::AdjustTokenPrivileges(_handle, BoolToBOOL(disableAllPrivileges),
+ newState, bufferLength, previousState, returnLength)); }
+
+ bool AdjustPrivileges(bool disableAllPrivileges, PTOKEN_PRIVILEGES newState)
+ { return AdjustPrivileges(disableAllPrivileges, newState, 0, NULL, NULL); }
+
+ bool AdjustPrivileges(PTOKEN_PRIVILEGES newState)
+ { return AdjustPrivileges(false, newState); }
+
+};
+
+#ifndef _UNICODE
+typedef NTSTATUS (NTAPI *LsaOpenPolicyP)(PLSA_UNICODE_STRING SystemName,
+ PLSA_OBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK DesiredAccess, PLSA_HANDLE PolicyHandle);
+typedef NTSTATUS (NTAPI *LsaCloseP)(LSA_HANDLE ObjectHandle);
+typedef NTSTATUS (NTAPI *LsaAddAccountRightsP)(LSA_HANDLE PolicyHandle,
+ PSID AccountSid, PLSA_UNICODE_STRING UserRights, ULONG CountOfRights );
+#define MY_STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002L)
+#endif
+
+struct CPolicy
+{
+protected:
+ LSA_HANDLE _handle;
+ #ifndef _UNICODE
+ HMODULE hModule;
+ #endif
+public:
+ operator LSA_HANDLE() const { return _handle; }
+ CPolicy(): _handle(NULL)
+ {
+ #ifndef _UNICODE
+ hModule = GetModuleHandle(TEXT("Advapi32.dll"));
+ #endif
+ };
+ ~CPolicy() { Close(); }
+
+ NTSTATUS Open(PLSA_UNICODE_STRING systemName, PLSA_OBJECT_ATTRIBUTES objectAttributes,
+ ACCESS_MASK desiredAccess)
+ {
+ #ifndef _UNICODE
+ if (hModule == NULL)
+ return MY_STATUS_NOT_IMPLEMENTED;
+ LsaOpenPolicyP lsaOpenPolicy = (LsaOpenPolicyP)GetProcAddress(hModule, "LsaOpenPolicy");
+ if (lsaOpenPolicy == NULL)
+ return MY_STATUS_NOT_IMPLEMENTED;
+ #endif
+
+ Close();
+ return
+ #ifdef _UNICODE
+ ::LsaOpenPolicy
+ #else
+ lsaOpenPolicy
+ #endif
+ (systemName, objectAttributes, desiredAccess, &_handle);
+ }
+
+ NTSTATUS Close()
+ {
+ if (_handle == NULL)
+ return 0;
+
+ #ifndef _UNICODE
+ if (hModule == NULL)
+ return MY_STATUS_NOT_IMPLEMENTED;
+ LsaCloseP lsaClose = (LsaCloseP)GetProcAddress(hModule, "LsaClose");
+ if (lsaClose == NULL)
+ return MY_STATUS_NOT_IMPLEMENTED;
+ #endif
+
+ NTSTATUS res =
+ #ifdef _UNICODE
+ ::LsaClose
+ #else
+ lsaClose
+ #endif
+ (_handle);
+ _handle = NULL;
+ return res;
+ }
+
+ NTSTATUS EnumerateAccountsWithUserRight(PLSA_UNICODE_STRING userRights,
+ PLSA_ENUMERATION_INFORMATION *enumerationBuffer, PULONG countReturned)
+ { return LsaEnumerateAccountsWithUserRight(_handle, userRights, (void **)enumerationBuffer, countReturned); }
+
+ NTSTATUS EnumerateAccountRights(PSID sid, PLSA_UNICODE_STRING* userRights, PULONG countOfRights)
+ { return ::LsaEnumerateAccountRights(_handle, sid, userRights, countOfRights); }
+
+ NTSTATUS LookupSids(ULONG count, PSID* sids,
+ PLSA_REFERENCED_DOMAIN_LIST* referencedDomains, PLSA_TRANSLATED_NAME* names)
+ { return LsaLookupSids(_handle, count, sids, referencedDomains, names); }
+
+ NTSTATUS AddAccountRights(PSID accountSid, PLSA_UNICODE_STRING userRights, ULONG countOfRights)
+ {
+ #ifndef _UNICODE
+ if (hModule == NULL)
+ return MY_STATUS_NOT_IMPLEMENTED;
+ LsaAddAccountRightsP lsaAddAccountRights = (LsaAddAccountRightsP)GetProcAddress(hModule, "LsaAddAccountRights");
+ if (lsaAddAccountRights == NULL)
+ return MY_STATUS_NOT_IMPLEMENTED;
+ #endif
+
+ return
+ #ifdef _UNICODE
+ ::LsaAddAccountRights
+ #else
+ lsaAddAccountRights
+ #endif
+ (_handle, accountSid, userRights, countOfRights);
+ }
+ NTSTATUS AddAccountRights(PSID accountSid, PLSA_UNICODE_STRING userRights)
+ { return AddAccountRights(accountSid, userRights, 1); }
+
+ NTSTATUS RemoveAccountRights(PSID accountSid, bool allRights, PLSA_UNICODE_STRING userRights, ULONG countOfRights)
+ { return LsaRemoveAccountRights(_handle, accountSid, (BOOLEAN)(allRights ? TRUE : FALSE), userRights, countOfRights); }
+};
+
+bool AddLockMemoryPrivilege();
+
+}}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/StdAfx.h b/src/libs/7zip/win/CPP/Windows/StdAfx.h
index 8b383c5ba..1766dfa86 100644
--- a/src/libs/7zip/win/CPP/Windows/StdAfx.h
+++ b/src/libs/7zip/win/CPP/Windows/StdAfx.h
@@ -3,7 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
-#include "../Common/MyWindows.h"
-#include "../Common/NewHandler.h"
+#include "../Common/Common.h"
#endif
diff --git a/src/libs/7zip/win/CPP/Windows/System.h b/src/libs/7zip/win/CPP/Windows/System.h
index e0067158f..4133a7b30 100644
--- a/src/libs/7zip/win/CPP/Windows/System.h
+++ b/src/libs/7zip/win/CPP/Windows/System.h
@@ -3,7 +3,7 @@
#ifndef __WINDOWS_SYSTEM_H
#define __WINDOWS_SYSTEM_H
-#include "../Common/Types.h"
+#include "../Common/MyTypes.h"
namespace NWindows {
namespace NSystem {
diff --git a/src/libs/7zip/win/CPP/Windows/Thread.h b/src/libs/7zip/win/CPP/Windows/Thread.h
index 16a509d47..f9ecaed85 100644
--- a/src/libs/7zip/win/CPP/Windows/Thread.h
+++ b/src/libs/7zip/win/CPP/Windows/Thread.h
@@ -20,7 +20,7 @@ public:
WRes Create(THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter)
{ return Thread_Create(&thread, startAddress, parameter); }
WRes Wait() { return Thread_Wait(&thread); }
-
+
#ifdef _WIN32
operator HANDLE() { return thread; }
void Attach(HANDLE handle) { thread = handle; }
diff --git a/src/libs/7zip/win/CPP/Windows/Time.h b/src/libs/7zip/win/CPP/Windows/Time.h
deleted file mode 100644
index 6f510b22b..000000000
--- a/src/libs/7zip/win/CPP/Windows/Time.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Windows/Time.h
-
-#ifndef __WINDOWS_TIME_H
-#define __WINDOWS_TIME_H
-
-#include "Common/Types.h"
-
-namespace NWindows {
-namespace NTime {
-
-bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime);
-bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime);
-void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime);
-bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime);
-bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
- unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds);
-void GetCurUtcFileTime(FILETIME &ft);
-
-}}
-
-#endif
diff --git a/src/libs/7zip/win/CPP/Windows/Time.cpp b/src/libs/7zip/win/CPP/Windows/TimeUtils.cpp
index ec9ca47d9..7ef44d9cc 100644
--- a/src/libs/7zip/win/CPP/Windows/Time.cpp
+++ b/src/libs/7zip/win/CPP/Windows/TimeUtils.cpp
@@ -1,10 +1,9 @@
-// Windows/Time.cpp
+// Windows/TimeUtils.cpp
#include "StdAfx.h"
-#include "Windows/Defs.h"
-
-#include "Time.h"
+#include "Defs.h"
+#include "TimeUtils.h"
namespace NWindows {
namespace NTime {
@@ -13,10 +12,11 @@ static const UInt32 kNumTimeQuantumsInSecond = 10000000;
static const UInt32 kFileTimeStartYear = 1601;
static const UInt32 kDosTimeStartYear = 1980;
static const UInt32 kUnixTimeStartYear = 1970;
-static const UInt64 kUnixTimeStartValue = ((UInt64)kNumTimeQuantumsInSecond) *
- 60 * 60 * 24 * (89 + 365 * (kUnixTimeStartYear - kFileTimeStartYear));
+static const UInt64 kUnixTimeOffset =
+ (UInt64)60 * 60 * 24 * (89 + 365 * (kUnixTimeStartYear - kFileTimeStartYear));
+static const UInt64 kNumSecondsInFileTime = (UInt64)(Int64)-1 / kNumTimeQuantumsInSecond;
-bool DosTimeToFileTime(UInt32 dosTime, FILETIME &ft)
+bool DosTimeToFileTime(UInt32 dosTime, FILETIME &ft) throw()
{
#if defined(_WIN32) && !defined(UNDER_CE)
return BOOLToBool(::DosDateTimeToFileTime((UInt16)(dosTime >> 16), (UInt16)(dosTime & 0xFFFF), &ft));
@@ -41,7 +41,7 @@ static const UInt32 kLowDosTime = 0x210000;
#define PERIOD_100 (PERIOD_4 * 25 - 1)
#define PERIOD_400 (PERIOD_100 * 4 + 1)
-bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime)
+bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime) throw()
{
#if defined(_WIN32) && !defined(UNDER_CE)
@@ -115,22 +115,48 @@ bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime)
return true;
}
-void UnixTimeToFileTime(UInt32 unixTime, FILETIME &ft)
+void UnixTimeToFileTime(UInt32 unixTime, FILETIME &ft) throw()
{
- UInt64 v = kUnixTimeStartValue + ((UInt64)unixTime) * kNumTimeQuantumsInSecond;
+ UInt64 v = (kUnixTimeOffset + (UInt64)unixTime) * kNumTimeQuantumsInSecond;
ft.dwLowDateTime = (DWORD)v;
ft.dwHighDateTime = (DWORD)(v >> 32);
}
-bool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime)
+bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &ft) throw()
+{
+ if (unixTime > kNumSecondsInFileTime - kUnixTimeOffset)
+ {
+ ft.dwLowDateTime = ft.dwHighDateTime = (UInt32)(Int32)-1;
+ return false;
+ }
+ Int64 v = (Int64)kUnixTimeOffset + unixTime;
+ if (v < 0)
+ {
+ ft.dwLowDateTime = ft.dwHighDateTime = 0;
+ return false;
+ }
+ UInt64 v2 = (UInt64)v * kNumTimeQuantumsInSecond;
+ ft.dwLowDateTime = (DWORD)v2;
+ ft.dwHighDateTime = (DWORD)(v2 >> 32);
+ return true;
+}
+
+Int64 FileTimeToUnixTime64(const FILETIME &ft) throw()
{
UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
- if (winTime < kUnixTimeStartValue)
+ return (Int64)(winTime / kNumTimeQuantumsInSecond) - kUnixTimeOffset;
+}
+
+bool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime) throw()
+{
+ UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
+ winTime /= kNumTimeQuantumsInSecond;
+ if (winTime < kUnixTimeOffset)
{
unixTime = 0;
return false;
}
- winTime = (winTime - kUnixTimeStartValue) / kNumTimeQuantumsInSecond;
+ winTime -= kUnixTimeOffset;
if (winTime > 0xFFFFFFFF)
{
unixTime = 0xFFFFFFFF;
@@ -141,7 +167,7 @@ bool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime)
}
bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
- unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds)
+ unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds) throw()
{
resSeconds = 0;
if (year < kFileTimeStartYear || year >= 10000 || month < 1 || month > 12 ||
@@ -160,11 +186,18 @@ bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
return true;
}
-void GetCurUtcFileTime(FILETIME &ft)
+void GetCurUtcFileTime(FILETIME &ft) throw()
{
+ // Both variants provide same low resolution on WinXP: about 15 ms.
+ // But GetSystemTimeAsFileTime is much faster.
+
+ #ifdef UNDER_CE
SYSTEMTIME st;
GetSystemTime(&st);
SystemTimeToFileTime(&st, &ft);
+ #else
+ GetSystemTimeAsFileTime(&ft);
+ #endif
}
}}
diff --git a/src/libs/7zip/win/CPP/Windows/TimeUtils.h b/src/libs/7zip/win/CPP/Windows/TimeUtils.h
new file mode 100644
index 000000000..2967214e6
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/TimeUtils.h
@@ -0,0 +1,23 @@
+// Windows/TimeUtils.h
+
+#ifndef __WINDOWS_TIME_UTILS_H
+#define __WINDOWS_TIME_UTILS_H
+
+#include "../Common/MyTypes.h"
+
+namespace NWindows {
+namespace NTime {
+
+bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime) throw();
+bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime) throw();
+void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime) throw();
+bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &fileTime) throw();
+bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime) throw();
+Int64 FileTimeToUnixTime64(const FILETIME &ft) throw();
+bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
+ unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds) throw();
+void GetCurUtcFileTime(FILETIME &ft) throw();
+
+}}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/Windows.pri b/src/libs/7zip/win/CPP/Windows/Windows.pri
new file mode 100644
index 000000000..a69279060
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Windows.pri
@@ -0,0 +1,29 @@
+HEADERS += $$7ZIP_BASE/CPP/Windows/DLL.h \
+ $$7ZIP_BASE/CPP/Windows/Defs.h \
+ $$7ZIP_BASE/CPP/Windows/FileDir.h \
+ $$7ZIP_BASE/CPP/Windows/FileFind.h \
+ $$7ZIP_BASE/CPP/Windows/FileIO.h \
+ $$7ZIP_BASE/CPP/Windows/FileMapping.h \
+ $$7ZIP_BASE/CPP/Windows/FileName.h \
+ $$7ZIP_BASE/CPP/Windows/Handle.h \
+ $$7ZIP_BASE/CPP/Windows/PropVariant.h \
+ $$7ZIP_BASE/CPP/Windows/PropVariantConv.h \
+ $$7ZIP_BASE/CPP/Windows/SecurityUtils.h \
+ $$7ZIP_BASE/CPP/Windows/StdAfx.h \
+ $$7ZIP_BASE/CPP/Windows/Synchronization.h \
+ $$7ZIP_BASE/CPP/Windows/System.h \
+ $$7ZIP_BASE/CPP/Windows/Thread.h \
+ $$7ZIP_BASE/CPP/Windows/TimeUtils.h
+
+SOURCES += $$7ZIP_BASE/CPP/Windows/DLL.cpp \
+ $$7ZIP_BASE/CPP/Windows/FileDir.cpp \
+ $$7ZIP_BASE/CPP/Windows/FileFind.cpp \
+ $$7ZIP_BASE/CPP/Windows/FileIO.cpp \
+ $$7ZIP_BASE/CPP/Windows/FileLink.cpp \
+ $$7ZIP_BASE/CPP/Windows/FileName.cpp \
+ $$7ZIP_BASE/CPP/Windows/PropVariant.cpp \
+ $$7ZIP_BASE/CPP/Windows/PropVariantConv.cpp \
+ $$7ZIP_BASE/CPP/Windows/SecurityUtils.cpp \
+ $$7ZIP_BASE/CPP/Windows/Synchronization.cpp \
+ $$7ZIP_BASE/CPP/Windows/System.cpp \
+ $$7ZIP_BASE/CPP/Windows/TimeUtils.cpp