summaryrefslogtreecommitdiffstats
path: root/src/libs/7zip/win/CPP/Windows
diff options
context:
space:
mode:
authorkh1 <karsten.heimrich@nokia.com>2012-03-15 14:53:47 +0100
committerKarsten Heimrich <karsten.heimrich@nokia.com>2012-03-19 16:14:04 +0100
commitbe3b47d0d504a3409ce66bd77bb8c0acff87c4f5 (patch)
tree09dfb02d484a4f395991972b828da71400fb761a /src/libs/7zip/win/CPP/Windows
parent9fd62353cf7f973d78cd2093328ac15b5c4980b6 (diff)
Reorganize the tree, have better ifw.pri. Shadow build support.
Change-Id: I01fb12537f863ed0744979973c7e4153889cc5cb Reviewed-by: Tim Jenssen <tim.jenssen@nokia.com>
Diffstat (limited to 'src/libs/7zip/win/CPP/Windows')
-rw-r--r--src/libs/7zip/win/CPP/Windows/COM.cpp37
-rw-r--r--src/libs/7zip/win/CPP/Windows/COM.h69
-rw-r--r--src/libs/7zip/win/CPP/Windows/Clipboard.cpp135
-rw-r--r--src/libs/7zip/win/CPP/Windows/Clipboard.h28
-rw-r--r--src/libs/7zip/win/CPP/Windows/CommonDialog.cpp184
-rw-r--r--src/libs/7zip/win/CPP/Windows/CommonDialog.h19
-rw-r--r--src/libs/7zip/win/CPP/Windows/Console.cpp10
-rw-r--r--src/libs/7zip/win/CPP/Windows/Console.h52
-rw-r--r--src/libs/7zip/win/CPP/Windows/DLL.cpp110
-rw-r--r--src/libs/7zip/win/CPP/Windows/DLL.h59
-rw-r--r--src/libs/7zip/win/CPP/Windows/Defs.h17
-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.cpp909
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileDir.h177
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileFind.cpp462
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileFind.h161
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileIO.cpp434
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileIO.h136
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileMapping.cpp12
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileMapping.h62
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileName.cpp50
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileName.h27
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileSystem.cpp126
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileSystem.h51
-rw-r--r--src/libs/7zip/win/CPP/Windows/Handle.h37
-rw-r--r--src/libs/7zip/win/CPP/Windows/Memory.cpp36
-rw-r--r--src/libs/7zip/win/CPP/Windows/Memory.h53
-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/Menu.cpp191
-rw-r--r--src/libs/7zip/win/CPP/Windows/Menu.h153
-rw-r--r--src/libs/7zip/win/CPP/Windows/NationalTime.cpp37
-rw-r--r--src/libs/7zip/win/CPP/Windows/NationalTime.h20
-rw-r--r--src/libs/7zip/win/CPP/Windows/Net.cpp380
-rw-r--r--src/libs/7zip/win/CPP/Windows/Net.h87
-rw-r--r--src/libs/7zip/win/CPP/Windows/NtCheck.h44
-rw-r--r--src/libs/7zip/win/CPP/Windows/Process.cpp81
-rw-r--r--src/libs/7zip/win/CPP/Windows/Process.h100
-rw-r--r--src/libs/7zip/win/CPP/Windows/ProcessMessages.cpp22
-rw-r--r--src/libs/7zip/win/CPP/Windows/ProcessMessages.h14
-rw-r--r--src/libs/7zip/win/CPP/Windows/PropVariant.cpp243
-rw-r--r--src/libs/7zip/win/CPP/Windows/PropVariant.h56
-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/PropVariantUtils.cpp78
-rw-r--r--src/libs/7zip/win/CPP/Windows/PropVariantUtils.h28
-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/ResourceString.cpp64
-rw-r--r--src/libs/7zip/win/CPP/Windows/ResourceString.h22
-rw-r--r--src/libs/7zip/win/CPP/Windows/Security.cpp179
-rw-r--r--src/libs/7zip/win/CPP/Windows/Security.h167
-rw-r--r--src/libs/7zip/win/CPP/Windows/Shell.cpp335
-rw-r--r--src/libs/7zip/win/CPP/Windows/Shell.h93
-rw-r--r--src/libs/7zip/win/CPP/Windows/StdAfx.h9
-rw-r--r--src/libs/7zip/win/CPP/Windows/Synchronization.cpp10
-rw-r--r--src/libs/7zip/win/CPP/Windows/Synchronization.h164
-rw-r--r--src/libs/7zip/win/CPP/Windows/System.cpp72
-rw-r--r--src/libs/7zip/win/CPP/Windows/System.h16
-rw-r--r--src/libs/7zip/win/CPP/Windows/Thread.h38
-rw-r--r--src/libs/7zip/win/CPP/Windows/Time.cpp170
-rw-r--r--src/libs/7zip/win/CPP/Windows/Time.h21
-rw-r--r--src/libs/7zip/win/CPP/Windows/Window.cpp169
-rw-r--r--src/libs/7zip/win/CPP/Windows/Window.h261
65 files changed, 7530 insertions, 0 deletions
diff --git a/src/libs/7zip/win/CPP/Windows/COM.cpp b/src/libs/7zip/win/CPP/Windows/COM.cpp
new file mode 100644
index 000000000..a746de12b
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/COM.cpp
@@ -0,0 +1,37 @@
+// Windows/COM.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/COM.h"
+#include "Common/StringConvert.h"
+
+namespace NWindows {
+namespace NCOM {
+
+// CoInitialize (NULL); must be called!
+
+UString GUIDToStringW(REFGUID guid)
+{
+ UString string;
+ const int kStringSize = 48;
+ StringFromGUID2(guid, string.GetBuffer(kStringSize), kStringSize);
+ string.ReleaseBuffer();
+ return string;
+}
+
+AString GUIDToStringA(REFGUID guid)
+{
+ return UnicodeStringToMultiByte(GUIDToStringW(guid));
+}
+
+HRESULT StringToGUIDW(const wchar_t *string, GUID &classID)
+{
+ return CLSIDFromString((wchar_t *)string, &classID);
+}
+
+HRESULT StringToGUIDA(const char *string, GUID &classID)
+{
+ return StringToGUIDW(MultiByteToUnicodeString(string), classID);
+}
+
+}}
diff --git a/src/libs/7zip/win/CPP/Windows/COM.h b/src/libs/7zip/win/CPP/Windows/COM.h
new file mode 100644
index 000000000..506bbbc64
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/COM.h
@@ -0,0 +1,69 @@
+// Windows/COM.h
+
+#ifndef __WINDOWS_COM_H
+#define __WINDOWS_COM_H
+
+#include "Common/MyString.h"
+
+namespace NWindows {
+namespace NCOM {
+
+#ifdef _WIN32
+
+class CComInitializer
+{
+public:
+ CComInitializer()
+ {
+ #ifdef UNDER_CE
+ CoInitializeEx(NULL, COINIT_MULTITHREADED);
+ #else
+ // it's single thread. Do we need multithread?
+ CoInitialize(NULL);
+ #endif
+ };
+ ~CComInitializer() { CoUninitialize(); };
+};
+
+class CStgMedium
+{
+ STGMEDIUM _object;
+public:
+ bool _mustBeReleased;
+ CStgMedium(): _mustBeReleased(false) {}
+ ~CStgMedium() { Free(); }
+ void Free()
+ {
+ if (_mustBeReleased)
+ ReleaseStgMedium(&_object);
+ _mustBeReleased = false;
+ }
+ const STGMEDIUM* operator->() const { return &_object;}
+ STGMEDIUM* operator->() { return &_object;}
+ STGMEDIUM* operator&() { return &_object; }
+};
+
+#endif
+
+//////////////////////////////////
+// GUID <--> String Conversions
+UString GUIDToStringW(REFGUID guid);
+AString GUIDToStringA(REFGUID guid);
+#ifdef UNICODE
+ #define GUIDToString GUIDToStringW
+#else
+ #define GUIDToString GUIDToStringA
+#endif
+
+HRESULT StringToGUIDW(const wchar_t *string, GUID &classID);
+HRESULT StringToGUIDA(const char *string, GUID &classID);
+#ifdef UNICODE
+ #define StringToGUID StringToGUIDW
+#else
+ #define StringToGUID StringToGUIDA
+#endif
+
+
+}}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/Clipboard.cpp b/src/libs/7zip/win/CPP/Windows/Clipboard.cpp
new file mode 100644
index 000000000..e1ff62be2
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Clipboard.cpp
@@ -0,0 +1,135 @@
+// Windows/Clipboard.cpp
+
+#include "StdAfx.h"
+
+#ifdef UNDER_CE
+#include <winuserm.h>
+#endif
+
+#include "Windows/Clipboard.h"
+#include "Windows/Defs.h"
+#include "Windows/Memory.h"
+#include "Windows/Shell.h"
+#include "Windows/Memory.h"
+
+#include "Common/StringConvert.h"
+
+namespace NWindows {
+
+bool CClipboard::Open(HWND wndNewOwner)
+{
+ m_Open = BOOLToBool(::OpenClipboard(wndNewOwner));
+ return m_Open;
+}
+
+CClipboard::~CClipboard()
+{
+ Close();
+}
+
+bool CClipboard::Close()
+{
+ if (!m_Open)
+ return true;
+ m_Open = !BOOLToBool(CloseClipboard());
+ return !m_Open;
+}
+
+bool ClipboardIsFormatAvailableHDROP()
+{
+ return BOOLToBool(IsClipboardFormatAvailable(CF_HDROP));
+}
+
+/*
+bool ClipboardGetTextString(AString &s)
+{
+ s.Empty();
+ if (!IsClipboardFormatAvailable(CF_TEXT))
+ return false;
+ CClipboard clipboard;
+
+ if (!clipboard.Open(NULL))
+ return false;
+
+ HGLOBAL h = ::GetClipboardData(CF_TEXT);
+ if (h != NULL)
+ {
+ NMemory::CGlobalLock globalLock(h);
+ const char *p = (const char *)globalLock.GetPointer();
+ if (p != NULL)
+ {
+ s = p;
+ return true;
+ }
+ }
+ return false;
+}
+*/
+
+/*
+bool ClipboardGetFileNames(UStringVector &names)
+{
+ names.Clear();
+ if (!IsClipboardFormatAvailable(CF_HDROP))
+ return false;
+ CClipboard clipboard;
+
+ if (!clipboard.Open(NULL))
+ return false;
+
+ HGLOBAL h = ::GetClipboardData(CF_HDROP);
+ if (h != NULL)
+ {
+ NMemory::CGlobalLock globalLock(h);
+ void *p = (void *)globalLock.GetPointer();
+ if (p != NULL)
+ {
+ NShell::CDrop drop(false);
+ drop.Attach((HDROP)p);
+ drop.QueryFileNames(names);
+ return true;
+ }
+ }
+ return false;
+}
+*/
+
+static bool ClipboardSetData(UINT uFormat, const void *data, size_t size)
+{
+ NMemory::CGlobal global;
+ if (!global.Alloc(GMEM_DDESHARE | GMEM_MOVEABLE, size))
+ return false;
+ {
+ NMemory::CGlobalLock globalLock(global);
+ LPVOID p = globalLock.GetPointer();
+ if (p == NULL)
+ return false;
+ memcpy(p, data, size);
+ }
+ if (::SetClipboardData(uFormat, global) == NULL)
+ return false;
+ global.Detach();
+ return true;
+}
+
+bool ClipboardSetText(HWND owner, const UString &s)
+{
+ CClipboard clipboard;
+ if (!clipboard.Open(owner))
+ return false;
+ if (!::EmptyClipboard())
+ return false;
+
+ bool res;
+ res = ClipboardSetData(CF_UNICODETEXT, (const wchar_t *)s, (s.Length() + 1) * sizeof(wchar_t));
+ #ifndef _UNICODE
+ AString a;
+ a = UnicodeStringToMultiByte(s, CP_ACP);
+ res |= ClipboardSetData(CF_TEXT, (const char *)a, (a.Length() + 1) * sizeof(char));
+ a = UnicodeStringToMultiByte(s, CP_OEMCP);
+ res |= ClipboardSetData(CF_OEMTEXT, (const char *)a, (a.Length() + 1) * sizeof(char));
+ #endif
+ return res;
+}
+
+}
diff --git a/src/libs/7zip/win/CPP/Windows/Clipboard.h b/src/libs/7zip/win/CPP/Windows/Clipboard.h
new file mode 100644
index 000000000..c80ba5ea7
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Clipboard.h
@@ -0,0 +1,28 @@
+// Windows/Clipboard.h
+
+#ifndef __CLIPBOARD_H
+#define __CLIPBOARD_H
+
+#include "Common/MyString.h"
+
+namespace NWindows {
+
+class CClipboard
+{
+ bool m_Open;
+public:
+ CClipboard(): m_Open(false) {};
+ ~CClipboard();
+ bool Open(HWND wndNewOwner);
+ bool Close();
+};
+
+bool ClipboardIsFormatAvailableHDROP();
+
+// bool ClipboardGetFileNames(UStringVector &names);
+// bool ClipboardGetTextString(AString &s);
+bool ClipboardSetText(HWND owner, const UString &s);
+
+}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/CommonDialog.cpp b/src/libs/7zip/win/CPP/Windows/CommonDialog.cpp
new file mode 100644
index 000000000..4ee7412d0
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/CommonDialog.cpp
@@ -0,0 +1,184 @@
+// Windows/CommonDialog.cpp
+
+#include "StdAfx.h"
+
+#ifdef UNDER_CE
+#include <commdlg.h>
+#endif
+
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+#include "Common/MyCom.h"
+
+#include "Windows/Defs.h"
+
+#include "CommonDialog.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows{
+
+#ifndef _UNICODE
+class CDoubleZeroStringListA
+{
+ CRecordVector<int> m_Indexes;
+ AString m_String;
+public:
+ void Add(LPCSTR s);
+ void SetForBuffer(LPSTR buffer);
+};
+
+void CDoubleZeroStringListA::Add(LPCSTR s)
+{
+ m_String += s;
+ m_Indexes.Add(m_String.Length());
+ m_String += ' ';
+}
+
+void CDoubleZeroStringListA::SetForBuffer(LPSTR buffer)
+{
+ MyStringCopy(buffer, (const char *)m_String);
+ for (int i = 0; i < m_Indexes.Size(); i++)
+ buffer[m_Indexes[i]] = '\0';
+}
+#endif
+
+class CDoubleZeroStringListW
+{
+ CRecordVector<int> m_Indexes;
+ UString m_String;
+public:
+ void Add(LPCWSTR s);
+ void SetForBuffer(LPWSTR buffer);
+};
+
+void CDoubleZeroStringListW::Add(LPCWSTR s)
+{
+ m_String += s;
+ m_Indexes.Add(m_String.Length());
+ m_String += L' ';
+}
+
+void CDoubleZeroStringListW::SetForBuffer(LPWSTR buffer)
+{
+ MyStringCopy(buffer, (const wchar_t *)m_String);
+ for (int i = 0; i < m_Indexes.Size(); i++)
+ buffer[m_Indexes[i]] = L'\0';
+}
+
+#define MY_OFN_PROJECT 0x00400000
+#define MY_OFN_SHOW_ALL 0x01000000
+
+bool MyGetOpenFileName(HWND hwnd, LPCWSTR title, LPCWSTR fullFileName,
+ LPCWSTR s, UString &resPath
+ #ifdef UNDER_CE
+ , bool openFolder
+ #endif
+ )
+{
+ const int kBufferSize = MAX_PATH * 2;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ CHAR buffer[kBufferSize];
+ MyStringCopy(buffer, (const char *)GetSystemString(fullFileName));
+ OPENFILENAME info;
+ info.lStructSize = sizeof(info);
+ info.hwndOwner = hwnd;
+ info.hInstance = 0;
+ const int kFilterBufferSize = MAX_PATH;
+ CHAR filterBuffer[kFilterBufferSize];
+ CDoubleZeroStringListA doubleZeroStringList;
+ doubleZeroStringList.Add(GetSystemString(s));
+ doubleZeroStringList.Add("*.*");
+ doubleZeroStringList.SetForBuffer(filterBuffer);
+ info.lpstrFilter = filterBuffer;
+
+ info.lpstrCustomFilter = NULL;
+ info.nMaxCustFilter = 0;
+ info.nFilterIndex = 0;
+
+ info.lpstrFile = buffer;
+ info.nMaxFile = kBufferSize;
+
+ info.lpstrFileTitle = NULL;
+ info.nMaxFileTitle = 0;
+
+ info.lpstrInitialDir= NULL;
+
+ info.lpstrTitle = 0;
+ AString titleA;
+ if (title != 0)
+ {
+ titleA = GetSystemString(title);
+ info.lpstrTitle = titleA;
+ }
+
+ info.Flags = OFN_EXPLORER | OFN_HIDEREADONLY;
+ info.nFileOffset = 0;
+ info.nFileExtension = 0;
+ info.lpstrDefExt = NULL;
+
+ info.lCustData = 0;
+ info.lpfnHook = NULL;
+ info.lpTemplateName = NULL;
+
+ bool res = BOOLToBool(::GetOpenFileNameA(&info));
+ resPath = GetUnicodeString(buffer);
+ return res;
+ }
+ else
+ #endif
+ {
+ WCHAR buffer[kBufferSize];
+ MyStringCopy(buffer, fullFileName);
+ OPENFILENAMEW info;
+ info.lStructSize = sizeof(info);
+ info.hwndOwner = hwnd;
+ info.hInstance = 0;
+ const int kFilterBufferSize = MAX_PATH;
+ WCHAR filterBuffer[kFilterBufferSize];
+ CDoubleZeroStringListW doubleZeroStringList;
+ doubleZeroStringList.Add(s);
+ doubleZeroStringList.Add(L"*.*");
+ doubleZeroStringList.SetForBuffer(filterBuffer);
+ info.lpstrFilter = filterBuffer;
+
+ info.lpstrCustomFilter = NULL;
+ info.nMaxCustFilter = 0;
+ info.nFilterIndex = 0;
+
+ info.lpstrFile = buffer;
+ info.nMaxFile = kBufferSize;
+
+ info.lpstrFileTitle = NULL;
+ info.nMaxFileTitle = 0;
+
+ info.lpstrInitialDir= NULL;
+
+ info.lpstrTitle = title;
+
+ info.Flags = OFN_EXPLORER | OFN_HIDEREADONLY
+ #ifdef UNDER_CE
+ | (openFolder ? (MY_OFN_PROJECT | MY_OFN_SHOW_ALL) : 0)
+ #endif
+ ;
+
+ info.nFileOffset = 0;
+ info.nFileExtension = 0;
+ info.lpstrDefExt = NULL;
+
+ info.lCustData = 0;
+ info.lpfnHook = NULL;
+ info.lpTemplateName = NULL;
+
+ bool res = BOOLToBool(::GetOpenFileNameW(&info));
+ resPath = buffer;
+ return res;
+ }
+}
+
+}
diff --git a/src/libs/7zip/win/CPP/Windows/CommonDialog.h b/src/libs/7zip/win/CPP/Windows/CommonDialog.h
new file mode 100644
index 000000000..f24bb5b24
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/CommonDialog.h
@@ -0,0 +1,19 @@
+// Windows/CommonDialog.h
+
+#ifndef __WINDOWS_COMMON_DIALOG_H
+#define __WINDOWS_COMMON_DIALOG_H
+
+#include "Common/MyString.h"
+
+namespace NWindows{
+
+bool MyGetOpenFileName(HWND hwnd, LPCWSTR title, LPCWSTR fullFileName,
+ LPCWSTR s, UString &resPath
+ #ifdef UNDER_CE
+ , bool openFolder = false
+ #endif
+);
+
+}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/Console.cpp b/src/libs/7zip/win/CPP/Windows/Console.cpp
new file mode 100644
index 000000000..7773fee22
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Console.cpp
@@ -0,0 +1,10 @@
+// Windows/Console.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Console.h"
+
+namespace NWindows{
+namespace NConsole{
+
+}}
diff --git a/src/libs/7zip/win/CPP/Windows/Console.h b/src/libs/7zip/win/CPP/Windows/Console.h
new file mode 100644
index 000000000..99ae90f1a
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Console.h
@@ -0,0 +1,52 @@
+// Windows/Console.h
+
+#ifndef __WINDOWS_CONSOLE_H
+#define __WINDOWS_CONSOLE_H
+
+#include "Windows/Defs.h"
+
+namespace NWindows{
+namespace NConsole{
+
+class CBase
+{
+protected:
+ HANDLE m_Object;
+public:
+ void Attach(HANDLE aHandle) { m_Object = aHandle; };
+ bool GetMode(DWORD &aMode)
+ { return BOOLToBool(::GetConsoleMode(m_Object, &aMode)); }
+ bool SetMode(DWORD aMode)
+ { return BOOLToBool(::SetConsoleMode(m_Object, aMode)); }
+};
+
+class CIn: public CBase
+{
+public:
+ bool PeekEvents(PINPUT_RECORD anEvents, DWORD aNumEvents, DWORD &aNumEventsRead)
+ { return BOOLToBool(::PeekConsoleInput(m_Object, anEvents, aNumEvents, &aNumEventsRead)); }
+ bool PeekEvent(INPUT_RECORD &anEvent, DWORD &aNumEventsRead)
+ { return PeekEvents(&anEvent, 1, aNumEventsRead); }
+ bool ReadEvents(PINPUT_RECORD anEvents, DWORD aNumEvents, DWORD &aNumEventsRead)
+ { return BOOLToBool(::ReadConsoleInput(m_Object, anEvents, aNumEvents, &aNumEventsRead)); }
+ bool ReadEvent(INPUT_RECORD &anEvent, DWORD &aNumEventsRead)
+ { return ReadEvents(&anEvent, 1, aNumEventsRead); }
+ bool GetNumberOfEvents(DWORD &aNumberOfEvents)
+ { return BOOLToBool(::GetNumberOfConsoleInputEvents(m_Object, &aNumberOfEvents)); }
+
+ bool WriteEvents(const INPUT_RECORD *anEvents, DWORD aNumEvents, DWORD &aNumEventsWritten)
+ { return BOOLToBool(::WriteConsoleInput(m_Object, anEvents, aNumEvents, &aNumEventsWritten)); }
+ bool WriteEvent(const INPUT_RECORD &anEvent, DWORD &aNumEventsWritten)
+ { return WriteEvents(&anEvent, 1, aNumEventsWritten); }
+
+ bool Read(LPVOID aBuffer, DWORD aNumberOfCharsToRead, DWORD &aNumberOfCharsRead)
+ { return BOOLToBool(::ReadConsole(m_Object, aBuffer, aNumberOfCharsToRead, &aNumberOfCharsRead, NULL)); }
+
+ bool Flush()
+ { return BOOLToBool(::FlushConsoleInputBuffer(m_Object)); }
+
+};
+
+}}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/DLL.cpp b/src/libs/7zip/win/CPP/Windows/DLL.cpp
new file mode 100644
index 000000000..5afd72d9d
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/DLL.cpp
@@ -0,0 +1,110 @@
+// Windows/DLL.cpp
+
+#include "StdAfx.h"
+
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#include "DLL.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NDLL {
+
+bool CLibrary::Free()
+{
+ 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)
+{
+ 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
+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)
+{
+ 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));
+}
+#endif
+
+bool MyGetModuleFileName(HMODULE hModule, CSysString &result)
+{
+ result.Empty();
+ TCHAR fullPath[MAX_PATH + 2];
+ DWORD size = ::GetModuleFileName(hModule, fullPath, MAX_PATH + 1);
+ if (size <= MAX_PATH && size != 0)
+ {
+ result = fullPath;
+ return true;
+ }
+ return false;
+}
+
+#ifndef _UNICODE
+bool MyGetModuleFileName(HMODULE hModule, UString &result)
+{
+ result.Empty();
+ if (g_IsNT)
+ {
+ wchar_t fullPath[MAX_PATH + 2];
+ DWORD size = ::GetModuleFileNameW(hModule, fullPath, MAX_PATH + 1);
+ if (size <= MAX_PATH && size != 0)
+ {
+ result = fullPath;
+ return true;
+ }
+ return false;
+ }
+ CSysString resultSys;
+ if (!MyGetModuleFileName(hModule, resultSys))
+ return false;
+ result = MultiByteToUnicodeString(resultSys, GetCurrentCodePage());
+ return true;
+}
+#endif
+
+}}
diff --git a/src/libs/7zip/win/CPP/Windows/DLL.h b/src/libs/7zip/win/CPP/Windows/DLL.h
new file mode 100644
index 000000000..4a253b326
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/DLL.h
@@ -0,0 +1,59 @@
+// Windows/DLL.h
+
+#ifndef __WINDOWS_DLL_H
+#define __WINDOWS_DLL_H
+
+#include "../Common/MyString.h"
+
+namespace NWindows {
+namespace NDLL {
+
+#ifdef UNDER_CE
+#define My_GetProcAddress(module, proceName) GetProcAddressA(module, proceName)
+#else
+#define My_GetProcAddress(module, proceName) ::GetProcAddress(module, proceName)
+#endif
+
+class CLibrary
+{
+ bool LoadOperations(HMODULE newModule);
+protected:
+ HMODULE _module;
+public:
+ CLibrary(): _module(NULL) {};
+ ~CLibrary() { Free(); }
+
+ operator HMODULE() const { return _module; }
+ HMODULE* operator&() { return &_module; }
+ bool IsLoaded() const { return (_module != NULL); };
+
+ void Attach(HMODULE m)
+ {
+ Free();
+ _module = m;
+ }
+ HMODULE Detach()
+ {
+ HMODULE m = _module;
+ _module = NULL;
+ 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
+ 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
+
+}}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/Defs.h b/src/libs/7zip/win/CPP/Windows/Defs.h
new file mode 100644
index 000000000..281c40c33
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Defs.h
@@ -0,0 +1,17 @@
+// Windows/Defs.h
+
+#ifndef __WINDOWS_DEFS_H
+#define __WINDOWS_DEFS_H
+
+#include "../Common/MyWindows.h"
+
+#ifdef _WIN32
+inline bool LRESULTToBool(LRESULT v) { return (v != FALSE); }
+inline bool BOOLToBool(BOOL v) { return (v != FALSE); }
+inline BOOL BoolToBOOL(bool v) { return (v ? TRUE: FALSE); }
+#endif
+
+inline VARIANT_BOOL BoolToVARIANT_BOOL(bool v) { return (v ? VARIANT_TRUE: VARIANT_FALSE); }
+inline bool VARIANT_BOOLToBool(VARIANT_BOOL v) { return (v != VARIANT_FALSE); }
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/Error.cpp b/src/libs/7zip/win/CPP/Windows/Error.cpp
new file mode 100644
index 000000000..7b18c29cc
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Error.cpp
@@ -0,0 +1,50 @@
+// 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
new file mode 100644
index 000000000..05b5cd0ea
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Error.h
@@ -0,0 +1,33 @@
+// 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
new file mode 100644
index 000000000..857946031
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/FileDir.cpp
@@ -0,0 +1,909 @@
+// Windows/FileDir.cpp
+
+#include "StdAfx.h"
+
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#include "FileDir.h"
+#include "FileFind.h"
+#include "FileName.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NFile {
+
+#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
+
+#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)
+{
+ UINT needLength = ::GetSystemDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+}
+
+#endif
+
+#ifndef _UNICODE
+bool MyGetWindowsDirectory(UString &path)
+{
+ if (g_IsNT)
+ {
+ UINT needLength = ::GetWindowsDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+ }
+ CSysString sysPath;
+ if (!MyGetWindowsDirectory(sysPath))
+ return false;
+ path = GetUnicodePath(sysPath);
+ return true;
+}
+
+bool MyGetSystemDirectory(UString &path)
+{
+ if (g_IsNT)
+ {
+ UINT needLength = ::GetSystemDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+ }
+ CSysString sysPath;
+ if (!MyGetSystemDirectory(sysPath))
+ return false;
+ path = GetUnicodePath(sysPath);
+ return true;
+}
+#endif
+
+bool SetDirTime(LPCWSTR fileName, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
+{
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return false;
+ }
+ #endif
+ HANDLE hDir = ::CreateFileW(fileName, GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ #ifdef WIN_LONG_PATH
+ if (hDir == INVALID_HANDLE_VALUE)
+ {
+ UString longPath;
+ if (GetLongPath(fileName, longPath))
+ hDir = ::CreateFileW(longPath, GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ }
+ #endif
+
+ bool res = false;
+ if (hDir != INVALID_HANDLE_VALUE)
+ {
+ res = BOOLToBool(::SetFileTime(hDir, cTime, aTime, mTime));
+ ::CloseHandle(hDir);
+ }
+ return res;
+}
+
+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)
+{
+ 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));
+ #endif
+ return false;
+}
+
+
+bool MyRemoveDirectory(LPCWSTR pathName)
+{
+ 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));
+ #endif
+ return false;
+}
+
+bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName)
+{
+ 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));
+ }
+ #endif
+ return false;
+}
+
+#ifndef _UNICODE
+bool MyCreateDirectory(LPCWSTR pathName)
+{
+ 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));
+ }
+ #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))
+ {
+ DWORD errorCode = GetLastError();
+ if (errorCode != ERROR_ALREADY_EXISTS)
+ return false;
+ }
+ fullPath += NName::kDirDelimiter;
+ }
+ return true;
+}
+*/
+
+bool CreateComplexDirectory(LPCTSTR _aPathName)
+{
+ CSysString pathName = _aPathName;
+ int pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
+ if (pos > 0 && pos == pathName.Length() - 1)
+ {
+ if (pathName.Length() == 3 && pathName[1] == ':')
+ return true; // Disk folder;
+ pathName.Delete(pos);
+ }
+ CSysString pathName2 = pathName;
+ pos = pathName.Length();
+ for (;;)
+ {
+ if (MyCreateDirectory(pathName))
+ break;
+ if (::GetLastError() == ERROR_ALREADY_EXISTS)
+ {
+ NFind::CFileInfo fileInfo;
+ if (!fileInfo.Find(pathName)) // For network folders
+ return true;
+ if (!fileInfo.IsDir())
+ return false;
+ break;
+ }
+ pos = pathName.ReverseFind(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;
+ }
+ return true;
+}
+
+#ifndef _UNICODE
+
+bool CreateComplexDirectory(LPCWSTR _aPathName)
+{
+ UString pathName = _aPathName;
+ int pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
+ if (pos > 0 && pos == pathName.Length() - 1)
+ {
+ if (pathName.Length() == 3 && pathName[1] == L':')
+ return true; // Disk folder;
+ pathName.Delete(pos);
+ }
+ UString pathName2 = pathName;
+ pos = pathName.Length();
+ for (;;)
+ {
+ if (MyCreateDirectory(pathName))
+ break;
+ if (::GetLastError() == ERROR_ALREADY_EXISTS)
+ {
+ NFind::CFileInfoW fileInfo;
+ if (!fileInfo.Find(pathName)) // For network folders
+ return true;
+ if (!fileInfo.IsDir())
+ return false;
+ break;
+ }
+ pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
+ if (pos < 0 || pos == 0)
+ return false;
+ if (pathName[pos - 1] == L':')
+ return false;
+ pathName = pathName.Left(pos);
+ }
+ pathName = pathName2;
+ while (pos < pathName.Length())
+ {
+ pos = pathName.Find(WCHAR_PATH_SEPARATOR, pos + 1);
+ if (pos < 0)
+ pos = pathName.Length();
+ if (!MyCreateDirectory(pathName.Left(pos)))
+ return false;
+ }
+ return true;
+}
+
+#endif
+
+bool DeleteFileAlways(LPCTSTR name)
+{
+ if (!MySetFileAttributes(name, 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)
+{
+ 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));
+ #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)
+{
+ NFind::CFileInfo fileInfo;
+ CSysString pathPrefix = path + NName::kDirDelimiter;
+ {
+ NFind::CEnumerator enumerator(pathPrefix + TCHAR(NName::kAnyStringWildcard));
+ while (enumerator.Next(fileInfo))
+ if (!RemoveDirectorySubItems2(pathPrefix, fileInfo))
+ return 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);
+ {
+ NFind::CEnumeratorW enumerator(pathPrefix + UString(NName::kAnyStringWildcard));
+ while (enumerator.Next(fileInfo))
+ if (!RemoveDirectorySubItems2(pathPrefix, fileInfo))
+ 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))
+ 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;
+}
+
+#ifdef UNDER_CE
+bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath)
+{
+ resultPath = fileName;
+ return true;
+}
+
+bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex)
+{
+ resultPath = fileName;
+ // change it
+ fileNamePartStartIndex = resultPath.ReverseFind(WCHAR_PATH_SEPARATOR);
+ fileNamePartStartIndex++;
+ return true;
+}
+
+#else
+
+bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath)
+{
+ DWORD needLength = ::GetShortPathName(longPath, shortPath.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+ shortPath.ReleaseBuffer();
+ return (needLength > 0 && needLength < MAX_PATH);
+}
+
+#ifdef WIN_LONG_PATH
+
+static UString GetLastPart(LPCWSTR 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)
+ {
+ #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;
+ }
+ if (fileNamePointer == 0)
+ fileNamePartStartIndex = lstrlen(fileName);
+ else
+ fileNamePartStartIndex = (int)(fileNamePointer - buffer);
+ #ifdef _UNICODE
+ #ifdef WIN_LONG_PATH
+ AddTrailingDots(fileName, resultPath);
+ #endif
+ #endif
+ return true;
+}
+
+#ifndef _UNICODE
+bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex)
+{
+ resultPath.Empty();
+ 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
+ }
+ else
+ {
+ 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;
+ }
+ return true;
+}
+#endif
+
+
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &path)
+{
+ int index;
+ return MyGetFullPathName(fileName, path, index);
+}
+
+#ifndef _UNICODE
+bool MyGetFullPathName(LPCWSTR fileName, UString &path)
+{
+ int index;
+ return MyGetFullPathName(fileName, path, index);
+}
+#endif
+
+#ifndef _UNICODE
+bool GetOnlyName(LPCWSTR fileName, UString &resultName)
+{
+ 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;
+}
+#endif
+
+bool MyGetCurrentDirectory(CSysString &path)
+{
+ DWORD needLength = ::GetCurrentDirectory(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+}
+
+#ifndef _UNICODE
+bool MySetCurrentDirectory(LPCWSTR path)
+{
+ if (g_IsNT)
+ return BOOLToBool(::SetCurrentDirectoryW(path));
+ return MySetCurrentDirectory(GetSysPath(path));
+}
+bool MyGetCurrentDirectory(UString &path)
+{
+ if (g_IsNT)
+ {
+ DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+ }
+ 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)
+ {
+ 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);
+ }
+
+ 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)
+{
+ if (g_IsNT)
+ {
+ UINT number = ::GetTempFileNameW(dirPath, prefix, 0, path.GetBuffer(MAX_PATH));
+ path.ReleaseBuffer();
+ return number;
+ }
+ CSysString sysPath;
+ UINT number = MyGetTempFileName(
+ dirPath ? (LPCTSTR)GetSysPath(dirPath): 0,
+ prefix ? (LPCTSTR)GetSysPath(prefix): 0,
+ sysPath);
+ path = GetUnicodePath(sysPath);
+ return number;
+}
+#endif
+
+UINT CTempFile::Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath)
+{
+ Remove();
+ UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
+ if (number != 0)
+ {
+ _fileName = resultPath;
+ _mustBeDeleted = true;
+ }
+ return number;
+}
+
+bool CTempFile::Create(LPCTSTR prefix, CSysString &resultPath)
+{
+ CSysString tempPath;
+ if (!MyGetTempPath(tempPath))
+ return false;
+ if (Create(tempPath, prefix, resultPath) != 0)
+ return true;
+ #ifdef UNDER_CE
+ return false;
+ #else
+ if (!MyGetWindowsDirectory(tempPath))
+ return false;
+ return (Create(tempPath, prefix, resultPath) != 0);
+ #endif
+}
+
+bool CTempFile::Remove()
+{
+ if (!_mustBeDeleted)
+ return true;
+ _mustBeDeleted = !DeleteFileAlways(_fileName);
+ return !_mustBeDeleted;
+}
+
+#ifndef _UNICODE
+
+UINT CTempFileW::Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath)
+{
+ Remove();
+ UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
+ if (number != 0)
+ {
+ _fileName = resultPath;
+ _mustBeDeleted = true;
+ }
+ return number;
+}
+
+bool CTempFileW::Create(LPCWSTR prefix, UString &resultPath)
+{
+ UString tempPath;
+ if (!MyGetTempPath(tempPath))
+ return false;
+ if (Create(tempPath, prefix, resultPath) != 0)
+ return true;
+ if (!MyGetWindowsDirectory(tempPath))
+ return false;
+ return (Create(tempPath, prefix, resultPath) != 0);
+}
+
+bool CTempFileW::Remove()
+{
+ if (!_mustBeDeleted)
+ return true;
+ _mustBeDeleted = !DeleteFileAlways(_fileName);
+ 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
new file mode 100644
index 000000000..04542d872
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/FileDir.h
@@ -0,0 +1,177 @@
+// Windows/FileDir.h
+
+#ifndef __WINDOWS_FILEDIR_H
+#define __WINDOWS_FILEDIR_H
+
+#include "../Common/MyString.h"
+#include "Defs.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NDirectory {
+
+#ifdef WIN_LONG_PATH
+bool GetLongPaths(LPCWSTR s1, LPCWSTR s2, UString &d1, UString &d2);
+#endif
+
+bool MyGetWindowsDirectory(CSysString &path);
+bool MyGetSystemDirectory(CSysString &path);
+#ifndef _UNICODE
+bool MyGetWindowsDirectory(UString &path);
+bool MyGetSystemDirectory(UString &path);
+#endif
+
+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);
+#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
+
+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 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
+
+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
+
+#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
+
+class CTempFile
+{
+ bool _mustBeDeleted;
+ CSysString _fileName;
+public:
+ CTempFile(): _mustBeDeleted(false) {}
+ ~CTempFile() { Remove(); }
+ void DisableDeleting() { _mustBeDeleted = false; }
+ UINT Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath);
+ bool Create(LPCTSTR prefix, CSysString &resultPath);
+ bool Remove();
+};
+
+#ifdef _UNICODE
+typedef CTempFile CTempFileW;
+#else
+class CTempFileW
+{
+ bool _mustBeDeleted;
+ UString _fileName;
+public:
+ CTempFileW(): _mustBeDeleted(false) {}
+ ~CTempFileW() { Remove(); }
+ void DisableDeleting() { _mustBeDeleted = false; }
+ UINT Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath);
+ bool Create(LPCWSTR prefix, UString &resultPath);
+ bool Remove();
+};
+#endif
+
+bool CreateTempDirectory(LPCTSTR prefixChars, CSysString &dirName);
+
+class CTempDirectory
+{
+ bool _mustBeDeleted;
+ CSysString _tempDir;
+public:
+ const CSysString &GetPath() const { return _tempDir; }
+ CTempDirectory(): _mustBeDeleted(false) {}
+ ~CTempDirectory() { Remove(); }
+ bool Create(LPCTSTR prefix) ;
+ bool Remove()
+ {
+ if (!_mustBeDeleted)
+ return true;
+ _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);
+ return (!_mustBeDeleted);
+ }
+ 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()
+ {
+ if (!_mustBeDeleted)
+ return true;
+ _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);
+ return (!_mustBeDeleted);
+ }
+ void DisableDeleting() { _mustBeDeleted = false; }
+};
+#endif
+
+}}}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/FileFind.cpp b/src/libs/7zip/win/CPP/Windows/FileFind.cpp
new file mode 100644
index 000000000..e3358f905
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/FileFind.cpp
@@ -0,0 +1,462 @@
+// Windows/FileFind.cpp
+
+#include "StdAfx.h"
+
+#include "FileFind.h"
+#include "FileIO.h"
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NFile {
+
+#ifdef SUPPORT_DEVICE_FILE
+bool IsDeviceName(LPCTSTR n);
+#ifndef _UNICODE
+bool IsDeviceName(LPCWSTR n);
+#endif
+#endif
+
+#if defined(WIN_LONG_PATH) && defined(_UNICODE)
+#define WIN_LONG_PATH2
+#endif
+
+bool GetLongPath(LPCWSTR fileName, UString &res);
+
+namespace NFind {
+
+static const TCHAR kDot = TEXT('.');
+
+bool CFileInfo::IsDots() const
+{
+ if (!IsDir() || Name.IsEmpty())
+ return false;
+ if (Name[0] != kDot)
+ return false;
+ return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
+}
+
+#ifndef _UNICODE
+bool CFileInfoW::IsDots() const
+{
+ if (!IsDir() || Name.IsEmpty())
+ return false;
+ if (Name[0] != kDot)
+ return false;
+ return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
+}
+#endif
+
+#define WIN_FD_TO_MY_FI(fi, fd) \
+ fi.Attrib = fd.dwFileAttributes; \
+ fi.CTime = fd.ftCreationTime; \
+ fi.ATime = fd.ftLastAccessTime; \
+ fi.MTime = fd.ftLastWriteTime; \
+ fi.Size = (((UInt64)fd.nFileSizeHigh) << 32) + fd.nFileSizeLow; \
+ fi.IsDevice = false;
+
+ /*
+ #ifdef UNDER_CE
+ fi.ObjectID = fd.dwOID;
+ #else
+ fi.ReparseTag = fd.dwReserved0;
+ #endif
+ */
+
+static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATA &fd, CFileInfo &fi)
+{
+ WIN_FD_TO_MY_FI(fi, fd);
+ fi.Name = fd.cFileName;
+}
+
+#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)
+{
+ WIN_FD_TO_MY_FI(fi, fd);
+ fi.Name = GetUnicodeString(fd.cFileName, GetCurrentCodePage());
+}
+#endif
+
+////////////////////////////////
+// CFindFile
+
+bool CFindFile::Close()
+{
+ if (_handle == INVALID_HANDLE_VALUE)
+ return true;
+ if (!::FindClose(_handle))
+ return false;
+ _handle = INVALID_HANDLE_VALUE;
+ return true;
+}
+
+
+bool CFindFile::FindFirst(LPCTSTR wildcard, CFileInfo &fi)
+{
+ if (!Close())
+ return false;
+ WIN32_FIND_DATA fd;
+ _handle = ::FindFirstFile(wildcard, &fd);
+ #ifdef WIN_LONG_PATH2
+ if (_handle == INVALID_HANDLE_VALUE)
+ {
+ UString longPath;
+ if (GetLongPath(wildcard, longPath))
+ _handle = ::FindFirstFileW(longPath, &fd);
+ }
+ #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);
+ #ifdef WIN_LONG_PATH
+ if (_handle == INVALID_HANDLE_VALUE)
+ {
+ UString longPath;
+ if (GetLongPath(wildcard, longPath))
+ _handle = ::FindFirstFileW(longPath, &fd);
+ }
+ #endif
+ if (_handle != INVALID_HANDLE_VALUE)
+ ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
+ }
+ else
+ {
+ WIN32_FIND_DATAA fd;
+ _handle = ::FindFirstFileA(UnicodeStringToMultiByte(wildcard,
+ GetCurrentCodePage()), &fd);
+ if (_handle != INVALID_HANDLE_VALUE)
+ ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
+ }
+ return (_handle != INVALID_HANDLE_VALUE);
+}
+#endif
+
+bool CFindFile::FindNext(CFileInfo &fi)
+{
+ WIN32_FIND_DATA fd;
+ bool result = BOOLToBool(::FindNextFile(_handle, &fd));
+ if (result)
+ ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
+ return result;
+}
+
+#ifndef _UNICODE
+bool CFindFile::FindNext(CFileInfoW &fi)
+{
+ if (g_IsNT)
+ {
+ WIN32_FIND_DATAW fd;
+ if (!::FindNextFileW(_handle, &fd))
+ return false;
+ ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
+ }
+ else
+ {
+ WIN32_FIND_DATAA fd;
+ if (!::FindNextFileA(_handle, &fd))
+ return false;
+ ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
+ }
+ return true;
+}
+#endif
+
+#define MY_CLEAR_FILETIME(ft) ft.dwLowDateTime = ft.dwHighDateTime = 0;
+
+void CFileInfoBase::Clear()
+{
+ Size = 0;
+ MY_CLEAR_FILETIME(CTime);
+ MY_CLEAR_FILETIME(ATime);
+ MY_CLEAR_FILETIME(MTime);
+ Attrib = 0;
+}
+
+bool CFileInfo::Find(LPCTSTR wildcard)
+{
+ #ifdef SUPPORT_DEVICE_FILE
+ if (IsDeviceName(wildcard))
+ {
+ Clear();
+ IsDevice = true;
+ NIO::CInFile inFile;
+ if (!inFile.Open(wildcard))
+ return false;
+ Name = wildcard + 4;
+ if (inFile.LengthDefined)
+ Size = inFile.Length;
+ return true;
+ }
+ #endif
+ CFindFile finder;
+ return finder.FindFirst(wildcard, *this);
+}
+
+
+#ifndef _UNICODE
+bool CFileInfoW::Find(LPCWSTR wildcard)
+{
+ #ifdef SUPPORT_DEVICE_FILE
+ if (IsDeviceName(wildcard))
+ {
+ Clear();
+ IsDevice = true;
+ NIO::CInFile inFile;
+ if (!inFile.Open(wildcard))
+ return false;
+ Name = wildcard + 4;
+ if (inFile.LengthDefined)
+ Size = inFile.Length;
+ return true;
+ }
+ #endif
+ CFindFile finder;
+ return finder.FindFirst(wildcard, *this);
+}
+#endif
+
+bool DoesFileExist(LPCTSTR name)
+{
+ CFileInfo fi;
+ return fi.Find(name) && !fi.IsDir();
+}
+
+bool DoesDirExist(LPCTSTR name)
+{
+ CFileInfo fi;
+ return fi.Find(name) && fi.IsDir();
+}
+
+bool DoesFileOrDirExist(LPCTSTR 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())
+ return _findFile.FindNext(fi);
+ else
+ return _findFile.FindFirst(_wildcard, fi);
+}
+
+bool CEnumerator::Next(CFileInfo &fi)
+{
+ for (;;)
+ {
+ if (!NextAny(fi))
+ return false;
+ if (!fi.IsDots())
+ return true;
+ }
+}
+
+bool CEnumerator::Next(CFileInfo &fi, bool &found)
+{
+ if (Next(fi))
+ {
+ found = true;
+ return true;
+ }
+ found = false;
+ 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()
+{
+ if (!IsHandleAllocated())
+ return true;
+ if (!::FindCloseChangeNotification(_handle))
+ return false;
+ _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)
+{
+ if (!g_IsNT)
+ return FindFirst(UnicodeStringToMultiByte(pathName, GetCurrentCodePage()), watchSubtree, notifyFilter);
+ _handle = ::FindFirstChangeNotificationW(pathName, BoolToBOOL(watchSubtree), notifyFilter);
+ #ifdef WIN_LONG_PATH
+ if (!IsHandleAllocated())
+ {
+ UString longPath;
+ if (GetLongPath(pathName, longPath))
+ _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
+ }
+ #endif
+ return _handle;
+}
+#endif
+
+#ifndef UNDER_CE
+bool MyGetLogicalDriveStrings(CSysStringVector &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++)
+ {
+ TCHAR c = buffer[i];
+ if (c == TEXT('\0'))
+ {
+ driveStrings.Add(string);
+ string.Empty();
+ }
+ else
+ string += c;
+ }
+ if (!string.IsEmpty())
+ return false;
+ return true;
+}
+
+#ifndef _UNICODE
+bool MyGetLogicalDriveStrings(UStringVector &driveStrings)
+{
+ driveStrings.Clear();
+ if (g_IsNT)
+ {
+ 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)
+ return false;
+ UString string;
+ for (UINT32 i = 0; i < newSize; i++)
+ {
+ WCHAR c = buffer[i];
+ if (c == L'\0')
+ {
+ driveStrings.Add(string);
+ string.Empty();
+ }
+ else
+ string += c;
+ }
+ return string.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
new file mode 100644
index 000000000..63631f66b
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/FileFind.h
@@ -0,0 +1,161 @@
+// Windows/FileFind.h
+
+#ifndef __WINDOWS_FILEFIND_H
+#define __WINDOWS_FILEFIND_H
+
+#include "../Common/MyString.h"
+#include "../Common/Types.h"
+#include "Defs.h"
+#include "FileName.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NFind {
+
+namespace NAttributes
+{
+ inline bool IsReadOnly(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_READONLY) != 0; }
+ inline bool IsHidden(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_HIDDEN) != 0; }
+ inline bool IsSystem(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_SYSTEM) != 0; }
+ inline bool IsDir(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0; }
+ inline bool IsArchived(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_ARCHIVE) != 0; }
+ inline bool IsCompressed(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_COMPRESSED) != 0; }
+ inline bool IsEncrypted(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_ENCRYPTED) != 0; }
+}
+
+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 IsDevice;
+
+ /*
+ #ifdef UNDER_CE
+ DWORD ObjectID;
+ #else
+ UINT32 ReparseTag;
+ #endif
+ */
+
+ bool IsArchived() const { return MatchesMask(FILE_ATTRIBUTE_ARCHIVE); }
+ bool IsCompressed() const { return MatchesMask(FILE_ATTRIBUTE_COMPRESSED); }
+ bool IsDir() const { return MatchesMask(FILE_ATTRIBUTE_DIRECTORY); }
+ bool IsEncrypted() const { return MatchesMask(FILE_ATTRIBUTE_ENCRYPTED); }
+ bool IsHidden() const { return MatchesMask(FILE_ATTRIBUTE_HIDDEN); }
+ bool IsNormal() const { return MatchesMask(FILE_ATTRIBUTE_NORMAL); }
+ bool IsOffline() const { return MatchesMask(FILE_ATTRIBUTE_OFFLINE); }
+ bool IsReadOnly() const { return MatchesMask(FILE_ATTRIBUTE_READONLY); }
+ bool HasReparsePoint() const { return MatchesMask(FILE_ATTRIBUTE_REPARSE_POINT); }
+ bool IsSparse() const { return MatchesMask(FILE_ATTRIBUTE_SPARSE_FILE); }
+ bool IsSystem() const { return MatchesMask(FILE_ATTRIBUTE_SYSTEM); }
+ bool IsTemporary() const { return MatchesMask(FILE_ATTRIBUTE_TEMPORARY); }
+};
+
+struct CFileInfo: public CFileInfoBase
+{
+ CSysString Name;
+
+ bool IsDots() const;
+ bool Find(LPCTSTR wildcard);
+};
+
+#ifdef _UNICODE
+typedef CFileInfo CFileInfoW;
+#else
+struct CFileInfoW: public CFileInfoBase
+{
+ UString Name;
+
+ bool IsDots() const;
+ bool Find(LPCWSTR wildcard);
+};
+#endif
+
+class CFindFile
+{
+ 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 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
+
+class CEnumerator
+{
+ CFindFile _findFile;
+ CSysString _wildcard;
+ bool NextAny(CFileInfo &fileInfo);
+public:
+ CEnumerator(): _wildcard(NName::kAnyStringWildcard) {}
+ CEnumerator(const CSysString &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;
+public:
+ operator HANDLE () { return _handle; }
+ 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 FindNext() { return BOOLToBool(::FindNextChangeNotification(_handle)); }
+};
+
+#ifndef UNDER_CE
+bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings);
+#ifndef _UNICODE
+bool MyGetLogicalDriveStrings(UStringVector &driveStrings);
+#endif
+#endif
+
+}}}
+
+#endif
+
diff --git a/src/libs/7zip/win/CPP/Windows/FileIO.cpp b/src/libs/7zip/win/CPP/Windows/FileIO.cpp
new file mode 100644
index 000000000..938e6c701
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/FileIO.cpp
@@ -0,0 +1,434 @@
+// Windows/FileIO.cpp
+
+#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"
+#endif
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+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)
+{
+ 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;
+}
+#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'));
+
+ 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;
+}
+
+bool GetLongPath(LPCWSTR path, UString &longPath)
+{
+ if (GetLongPathBase(path, longPath))
+ return !longPath.IsEmpty();
+ return false;
+}
+#endif
+
+namespace NIO {
+
+CFileBase::~CFileBase() { Close(); }
+
+bool CFileBase::Create(LPCTSTR fileName, 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)
+{
+ 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);
+ }
+ #endif
+ #ifdef SUPPORT_DEVICE_FILE
+ IsDeviceFile = false;
+ #endif
+ return (_handle != INVALID_HANDLE_VALUE);
+}
+#endif
+
+bool CFileBase::Close()
+{
+ if (_handle == INVALID_HANDLE_VALUE)
+ return true;
+ if (!::CloseHandle(_handle))
+ return false;
+ _handle = INVALID_HANDLE_VALUE;
+ return true;
+}
+
+bool CFileBase::GetPosition(UInt64 &position) const
+{
+ return Seek(0, FILE_CURRENT, position);
+}
+
+bool CFileBase::GetLength(UInt64 &length) const
+{
+ #ifdef SUPPORT_DEVICE_FILE
+ if (IsDeviceFile && LengthDefined)
+ {
+ length = Length;
+ return true;
+ }
+ #endif
+
+ DWORD sizeHigh;
+ DWORD sizeLow = ::GetFileSize(_handle, &sizeHigh);
+ if (sizeLow == 0xFFFFFFFF)
+ if (::GetLastError() != NO_ERROR)
+ return false;
+ length = (((UInt64)sizeHigh) << 32) + sizeLow;
+ return true;
+}
+
+bool CFileBase::Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const
+{
+ #ifdef SUPPORT_DEVICE_FILE
+ if (IsDeviceFile && LengthDefined && moveMethod == FILE_END)
+ {
+ distanceToMove += Length;
+ moveMethod = FILE_BEGIN;
+ }
+ #endif
+
+ LARGE_INTEGER value;
+ value.QuadPart = distanceToMove;
+ value.LowPart = ::SetFilePointer(_handle, value.LowPart, &value.HighPart, moveMethod);
+ if (value.LowPart == 0xFFFFFFFF)
+ if (::GetLastError() != NO_ERROR)
+ return false;
+ newPosition = value.QuadPart;
+ return true;
+}
+
+bool CFileBase::Seek(UInt64 position, UInt64 &newPosition)
+{
+ return Seek(position, FILE_BEGIN, newPosition);
+}
+
+bool CFileBase::SeekToBegin()
+{
+ UInt64 newPosition;
+ return Seek(0, newPosition);
+}
+
+bool CFileBase::SeekToEnd(UInt64 &newPosition)
+{
+ return Seek(0, FILE_END, newPosition);
+}
+
+bool CFileBase::GetFileInformation(CByHandleFileInfo &fileInfo) const
+{
+ 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;
+}
+
+/////////////////////////
+// CInFile
+
+#ifdef SUPPORT_DEVICE_FILE
+void CInFile::GetDeviceLength()
+{
+ if (_handle != INVALID_HANDLE_VALUE && IsDeviceFile)
+ {
+ #ifdef UNDER_CE
+ LengthDefined = true;
+ Length = 128 << 20;
+
+ #else
+ PARTITION_INFORMATION partInfo;
+ LengthDefined = true;
+ Length = 0;
+
+ if (GetPartitionInfo(&partInfo))
+ Length = partInfo.PartitionLength.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;
+ }
+ // SeekToBegin();
+ #endif
+ }
+}
+
+// ((desiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA | GENERIC_WRITE)) == 0 &&
+
+#define MY_DEVICE_EXTRA_CODE \
+ IsDeviceFile = IsDeviceName(fileName); \
+ GetDeviceLength();
+#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 res = Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes);
+ MY_DEVICE_EXTRA_CODE
+ return res;
+}
+
+bool CInFile::OpenShared(LPCWSTR fileName, bool shareForWrite)
+{ return Open(fileName, FILE_SHARE_READ | (shareForWrite ? FILE_SHARE_WRITE : 0), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
+
+bool CInFile::Open(LPCWSTR 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)
+// from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
+// (Insufficient system resources exist to complete the requested service).
+
+// Probably in some version of Windows there are problems with other sizes:
+// for 32 MB (maybe also for 16 MB).
+// And message can be "Network connection was lost"
+
+static UInt32 kChunkSizeMax = (1 << 22);
+
+bool CInFile::Read1(void *data, UInt32 size, UInt32 &processedSize)
+{
+ DWORD processedLoc = 0;
+ bool res = BOOLToBool(::ReadFile(_handle, data, size, &processedLoc, NULL));
+ processedSize = (UInt32)processedLoc;
+ return res;
+}
+
+bool CInFile::ReadPart(void *data, UInt32 size, UInt32 &processedSize)
+{
+ if (size > kChunkSizeMax)
+ size = kChunkSizeMax;
+ return Read1(data, size, processedSize);
+}
+
+bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize)
+{
+ processedSize = 0;
+ do
+ {
+ UInt32 processedLoc = 0;
+ bool res = ReadPart(data, size, processedLoc);
+ processedSize += processedLoc;
+ if (!res)
+ return false;
+ if (processedLoc == 0)
+ return true;
+ data = (void *)((unsigned char *)data + processedLoc);
+ size -= processedLoc;
+ }
+ while (size > 0);
+ return true;
+}
+
+/////////////////////////
+// COutFile
+
+bool COutFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+ { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); }
+
+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)
+ { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); }
+
+bool COutFile::Open(LPCWSTR fileName, DWORD creationDisposition)
+ { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); }
+
+bool COutFile::Create(LPCWSTR fileName, bool createAlways)
+ { return Open(fileName, GetCreationDisposition(createAlways)); }
+
+#endif
+
+bool COutFile::SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
+ { return BOOLToBool(::SetFileTime(_handle, cTime, aTime, mTime)); }
+
+bool COutFile::SetMTime(const FILETIME *mTime) { return SetTime(NULL, NULL, mTime); }
+
+bool COutFile::WritePart(const void *data, UInt32 size, UInt32 &processedSize)
+{
+ if (size > kChunkSizeMax)
+ size = kChunkSizeMax;
+ DWORD processedLoc = 0;
+ bool res = BOOLToBool(::WriteFile(_handle, data, size, &processedLoc, NULL));
+ processedSize = (UInt32)processedLoc;
+ return res;
+}
+
+bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize)
+{
+ processedSize = 0;
+ do
+ {
+ UInt32 processedLoc = 0;
+ bool res = WritePart(data, size, processedLoc);
+ processedSize += processedLoc;
+ if (!res)
+ return false;
+ if (processedLoc == 0)
+ return true;
+ data = (const void *)((const unsigned char *)data + processedLoc);
+ size -= processedLoc;
+ }
+ while (size > 0);
+ return true;
+}
+
+bool COutFile::SetEndOfFile() { return BOOLToBool(::SetEndOfFile(_handle)); }
+
+bool COutFile::SetLength(UInt64 length)
+{
+ UInt64 newPosition;
+ if (!Seek(length, newPosition))
+ return false;
+ if (newPosition != length)
+ return false;
+ return SetEndOfFile();
+}
+
+}}}
diff --git a/src/libs/7zip/win/CPP/Windows/FileIO.h b/src/libs/7zip/win/CPP/Windows/FileIO.h
new file mode 100644
index 000000000..dce692fed
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/FileIO.h
@@ -0,0 +1,136 @@
+// Windows/FileIO.h
+
+#ifndef __WINDOWS_FILEIO_H
+#define __WINDOWS_FILEIO_H
+
+#include "../Common/Types.h"
+
+#include "Defs.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NIO {
+
+struct CByHandleFileInfo
+{
+ DWORD Attrib;
+ FILETIME CTime;
+ FILETIME ATime;
+ FILETIME MTime;
+ DWORD VolumeSerialNumber;
+ UInt64 Size;
+ DWORD NumberOfLinks;
+ UInt64 FileIndex;
+};
+
+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,
+ DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ #endif
+
+public:
+ #ifdef SUPPORT_DEVICE_FILE
+ bool IsDeviceFile;
+ bool LengthDefined;
+ UInt64 Length;
+ #endif
+
+ CFileBase(): _handle(INVALID_HANDLE_VALUE) {};
+ ~CFileBase();
+
+ bool Close();
+
+ bool GetPosition(UInt64 &position) const;
+ bool GetLength(UInt64 &length) const;
+
+ 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;
+};
+
+#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)
+
+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 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();
+ #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);
+ #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);
+};
+
+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);
+};
+
+}}}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/FileMapping.cpp b/src/libs/7zip/win/CPP/Windows/FileMapping.cpp
new file mode 100644
index 000000000..55048fdb2
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/FileMapping.cpp
@@ -0,0 +1,12 @@
+// 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
new file mode 100644
index 000000000..3f0ebd74c
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/FileMapping.h
@@ -0,0 +1,62 @@
+// Windows/FileMapping.h
+
+#ifndef __WINDOWS_FILEMAPPING_H
+#define __WINDOWS_FILEMAPPING_H
+
+#include "Common/Types.h"
+
+#include "Handle.h"
+
+namespace NWindows {
+
+class CFileMapping: public CHandle
+{
+public:
+ WRes Create(DWORD protect, UInt64 maxSize, LPCTSTR name)
+ {
+ _handle = ::CreateFileMapping(INVALID_HANDLE_VALUE, NULL, protect, (DWORD)(maxSize >> 32), (DWORD)maxSize, name);
+ return ::GetLastError();
+ }
+
+ WRes Open(DWORD desiredAccess, LPCTSTR name)
+ {
+ #ifdef UNDER_CE
+ WRes res = Create(PAGE_READONLY, 0, name);
+ if (res == ERROR_ALREADY_EXISTS)
+ return 0;
+ Close();
+ if (res == 0)
+ res = ERROR_FILE_NOT_FOUND;
+ return res;
+ #else
+ _handle = ::OpenFileMapping(desiredAccess, FALSE, name);
+ if (_handle != 0)
+ return 0;
+ return ::GetLastError();
+ #endif
+ }
+
+ LPVOID Map(DWORD desiredAccess, UInt64 fileOffset, SIZE_T numberOfBytesToMap)
+ {
+ return ::MapViewOfFile(_handle, desiredAccess, (DWORD)(fileOffset >> 32), (DWORD)fileOffset, numberOfBytesToMap);
+ }
+
+ #ifndef UNDER_CE
+ LPVOID Map(DWORD desiredAccess, UInt64 fileOffset, SIZE_T numberOfBytesToMap, LPVOID baseAddress)
+ {
+ return ::MapViewOfFileEx(_handle, desiredAccess, (DWORD)(fileOffset >> 32), (DWORD)fileOffset, numberOfBytesToMap, baseAddress);
+ }
+ #endif
+};
+
+class CFileUnmapper
+{
+ const void *_data;
+public:
+ CFileUnmapper(const void *data) : _data(data) {}
+ ~CFileUnmapper() { ::UnmapViewOfFile(_data); }
+};
+
+}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/FileName.cpp b/src/libs/7zip/win/CPP/Windows/FileName.cpp
new file mode 100644
index 000000000..8443a4af9
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/FileName.cpp
@@ -0,0 +1,50 @@
+// Windows/FileName.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/FileName.h"
+#include "Common/Wildcard.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NName {
+
+void NormalizeDirPathPrefix(CSysString &dirPath)
+{
+ if (dirPath.IsEmpty())
+ return;
+ if (dirPath.ReverseFind(kDirDelimiter) != dirPath.Length() - 1)
+ dirPath += kDirDelimiter;
+}
+
+#ifndef _UNICODE
+void NormalizeDirPathPrefix(UString &dirPath)
+{
+ if (dirPath.IsEmpty())
+ return;
+ if (dirPath.ReverseFind(wchar_t(kDirDelimiter)) != dirPath.Length() - 1)
+ dirPath += wchar_t(kDirDelimiter);
+}
+#endif
+
+const wchar_t kExtensionDelimiter = L'.';
+
+void SplitNameToPureNameAndExtension(const UString &fullName,
+ UString &pureName, UString &extensionDelimiter, UString &extension)
+{
+ int index = fullName.ReverseFind(kExtensionDelimiter);
+ if (index < 0)
+ {
+ pureName = fullName;
+ extensionDelimiter.Empty();
+ extension.Empty();
+ }
+ else
+ {
+ pureName = fullName.Left(index);
+ extensionDelimiter = kExtensionDelimiter;
+ extension = fullName.Mid(index + 1);
+ }
+}
+
+}}}
diff --git a/src/libs/7zip/win/CPP/Windows/FileName.h b/src/libs/7zip/win/CPP/Windows/FileName.h
new file mode 100644
index 000000000..d98079026
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/FileName.h
@@ -0,0 +1,27 @@
+// Windows/FileName.h
+
+#ifndef __WINDOWS_FILENAME_H
+#define __WINDOWS_FILENAME_H
+
+#include "../../C/Types.h"
+
+#include "../Common/MyString.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NName {
+
+const TCHAR kDirDelimiter = CHAR_PATH_SEPARATOR;
+const TCHAR kAnyStringWildcard = '*';
+
+void NormalizeDirPathPrefix(CSysString &dirPath); // ensures that it ended with '\\'
+#ifndef _UNICODE
+void NormalizeDirPathPrefix(UString &dirPath); // ensures that it ended with '\\'
+#endif
+
+void SplitNameToPureNameAndExtension(const UString &fullName,
+ UString &pureName, UString &extensionDelimiter, UString &extension);
+
+}}}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/FileSystem.cpp b/src/libs/7zip/win/CPP/Windows/FileSystem.cpp
new file mode 100644
index 000000000..3ebfb7523
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/FileSystem.cpp
@@ -0,0 +1,126 @@
+// Windows/FileSystem.cpp
+
+#include "StdAfx.h"
+
+#include "FileSystem.h"
+#include "Defs.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NFile {
+namespace NSystem {
+
+bool MyGetVolumeInformation(
+ LPCTSTR rootPathName,
+ CSysString &volumeName,
+ LPDWORD volumeSerialNumber,
+ LPDWORD maximumComponentLength,
+ LPDWORD fileSystemFlags,
+ CSysString &fileSystemName)
+{
+ bool result = BOOLToBool(GetVolumeInformation(
+ rootPathName,
+ volumeName.GetBuffer(MAX_PATH), MAX_PATH,
+ volumeSerialNumber,
+ maximumComponentLength,
+ fileSystemFlags,
+ fileSystemName.GetBuffer(MAX_PATH), MAX_PATH));
+ volumeName.ReleaseBuffer();
+ fileSystemName.ReleaseBuffer();
+ return result;
+}
+
+
+#ifndef _UNICODE
+bool MyGetVolumeInformation(
+ LPCWSTR rootPathName,
+ UString &volumeName,
+ LPDWORD volumeSerialNumber,
+ LPDWORD maximumComponentLength,
+ LPDWORD fileSystemFlags,
+ UString &fileSystemName)
+{
+ if (g_IsNT)
+ {
+ bool result = BOOLToBool(GetVolumeInformationW(
+ rootPathName,
+ volumeName.GetBuffer(MAX_PATH), MAX_PATH,
+ volumeSerialNumber,
+ maximumComponentLength,
+ fileSystemFlags,
+ fileSystemName.GetBuffer(MAX_PATH), MAX_PATH));
+ volumeName.ReleaseBuffer();
+ fileSystemName.ReleaseBuffer();
+ return result;
+ }
+ AString volumeNameA, fileSystemNameA;
+ bool result = MyGetVolumeInformation(GetSystemString(rootPathName), volumeNameA,
+ volumeSerialNumber, maximumComponentLength, fileSystemFlags,fileSystemNameA);
+ if (result)
+ {
+ volumeName = GetUnicodeString(volumeNameA);
+ fileSystemName = GetUnicodeString(fileSystemNameA);
+ }
+ return result;
+}
+#endif
+
+typedef BOOL (WINAPI * GetDiskFreeSpaceExPointer)(
+ LPCTSTR lpDirectoryName, // directory name
+ PULARGE_INTEGER lpFreeBytesAvailable, // bytes available to caller
+ PULARGE_INTEGER lpTotalNumberOfBytes, // bytes on disk
+ PULARGE_INTEGER lpTotalNumberOfFreeBytes // free bytes on disk
+);
+
+bool MyGetDiskFreeSpace(LPCTSTR rootPathName,
+ UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize)
+{
+ GetDiskFreeSpaceExPointer pGetDiskFreeSpaceEx =
+ (GetDiskFreeSpaceExPointer)GetProcAddress(
+ GetModuleHandle(TEXT("kernel32.dll")), "GetDiskFreeSpaceExA");
+
+ bool sizeIsDetected = false;
+ if (pGetDiskFreeSpaceEx)
+ {
+ ULARGE_INTEGER i64FreeBytesToCaller, totalSize2, freeSize2;
+ sizeIsDetected = BOOLToBool(pGetDiskFreeSpaceEx(rootPathName,
+ &i64FreeBytesToCaller,
+ &totalSize2,
+ &freeSize2));
+ totalSize = totalSize2.QuadPart;
+ freeSize = freeSize2.QuadPart;
+ }
+
+ DWORD numSectorsPerCluster;
+ DWORD bytesPerSector;
+ DWORD numberOfFreeClusters;
+ DWORD totalNumberOfClusters;
+
+ if (!::GetDiskFreeSpace(rootPathName,
+ &numSectorsPerCluster,
+ &bytesPerSector,
+ &numberOfFreeClusters,
+ &totalNumberOfClusters))
+ return false;
+
+ clusterSize = (UInt64)bytesPerSector * (UInt64)numSectorsPerCluster;
+ if (!sizeIsDetected)
+ {
+ totalSize = clusterSize * (UInt64)totalNumberOfClusters;
+ freeSize = clusterSize * (UInt64)numberOfFreeClusters;
+ }
+ return true;
+}
+
+#ifndef _UNICODE
+bool MyGetDiskFreeSpace(LPCWSTR rootPathName,
+ UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize)
+{
+ return MyGetDiskFreeSpace(GetSystemString(rootPathName), clusterSize, totalSize, freeSize);
+}
+#endif
+
+}}}
diff --git a/src/libs/7zip/win/CPP/Windows/FileSystem.h b/src/libs/7zip/win/CPP/Windows/FileSystem.h
new file mode 100644
index 000000000..727497bbd
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/FileSystem.h
@@ -0,0 +1,51 @@
+// Windows/FileSystem.h
+
+#ifndef __WINDOWS_FILESYSTEM_H
+#define __WINDOWS_FILESYSTEM_H
+
+#include "../Common/MyString.h"
+#include "../Common/Types.h"
+
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+namespace NWindows {
+namespace NFile {
+namespace NSystem {
+
+bool MyGetVolumeInformation(
+ LPCTSTR rootPathName,
+ CSysString &volumeName,
+ LPDWORD volumeSerialNumber,
+ LPDWORD maximumComponentLength,
+ LPDWORD fileSystemFlags,
+ CSysString &fileSystemName);
+
+#ifndef _UNICODE
+bool MyGetVolumeInformation(
+ LPCWSTR rootPathName,
+ UString &volumeName,
+ LPDWORD volumeSerialNumber,
+ LPDWORD maximumComponentLength,
+ LPDWORD fileSystemFlags,
+ UString &fileSystemName);
+#endif
+
+inline UINT MyGetDriveType(LPCTSTR pathName) { return GetDriveType(pathName); }
+#ifndef _UNICODE
+inline UINT MyGetDriveType(LPCWSTR pathName) { return GetDriveType(GetSystemString(pathName)); }
+#endif
+
+bool MyGetDiskFreeSpace(LPCTSTR rootPathName,
+ UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize);
+
+#ifndef _UNICODE
+bool MyGetDiskFreeSpace(LPCWSTR rootPathName,
+ UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize);
+#endif
+
+}}}
+
+#endif
+
diff --git a/src/libs/7zip/win/CPP/Windows/Handle.h b/src/libs/7zip/win/CPP/Windows/Handle.h
new file mode 100644
index 000000000..bb7cb705d
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Handle.h
@@ -0,0 +1,37 @@
+// Windows/Handle.h
+
+#ifndef __WINDOWS_HANDLE_H
+#define __WINDOWS_HANDLE_H
+
+namespace NWindows {
+
+class CHandle
+{
+protected:
+ HANDLE _handle;
+public:
+ operator HANDLE() { return _handle; }
+ CHandle(): _handle(NULL) {}
+ ~CHandle() { Close(); }
+ bool IsCreated() const { return (_handle != NULL); }
+ bool Close()
+ {
+ if (_handle == NULL)
+ return true;
+ if (!::CloseHandle(_handle))
+ return false;
+ _handle = NULL;
+ return true;
+ }
+ void Attach(HANDLE handle) { _handle = handle; }
+ HANDLE Detach()
+ {
+ HANDLE handle = _handle;
+ _handle = NULL;
+ return handle;
+ }
+};
+
+}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/Memory.cpp b/src/libs/7zip/win/CPP/Windows/Memory.cpp
new file mode 100644
index 000000000..4c23205e1
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Memory.cpp
@@ -0,0 +1,36 @@
+// Windows/Memory.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Memory.h"
+
+namespace NWindows {
+namespace NMemory {
+
+bool CGlobal::Alloc(UINT flags, SIZE_T size)
+{
+ HGLOBAL newBlock = ::GlobalAlloc(flags, size);
+ if (newBlock == NULL)
+ return false;
+ m_MemoryHandle = newBlock;
+ return true;
+}
+
+bool CGlobal::Free()
+{
+ if (m_MemoryHandle == NULL)
+ return true;
+ m_MemoryHandle = ::GlobalFree(m_MemoryHandle);
+ return (m_MemoryHandle == NULL);
+}
+
+bool CGlobal::ReAlloc(SIZE_T size)
+{
+ HGLOBAL newBlock = ::GlobalReAlloc(m_MemoryHandle, size, GMEM_MOVEABLE);
+ if (newBlock == NULL)
+ return false;
+ m_MemoryHandle = newBlock;
+ return true;
+}
+
+}}
diff --git a/src/libs/7zip/win/CPP/Windows/Memory.h b/src/libs/7zip/win/CPP/Windows/Memory.h
new file mode 100644
index 000000000..1984baf6a
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Memory.h
@@ -0,0 +1,53 @@
+// Windows/Memory.h
+
+#ifndef __WINDOWS_MEMORY_H
+#define __WINDOWS_MEMORY_H
+
+namespace NWindows {
+namespace NMemory {
+
+class CGlobal
+{
+ HGLOBAL m_MemoryHandle;
+public:
+ CGlobal(): m_MemoryHandle(NULL){};
+ ~CGlobal() { Free(); }
+ operator HGLOBAL() const { return m_MemoryHandle; };
+ void Attach(HGLOBAL hGlobal)
+ {
+ Free();
+ m_MemoryHandle = hGlobal;
+ }
+ HGLOBAL Detach()
+ {
+ HGLOBAL h = m_MemoryHandle;
+ m_MemoryHandle = NULL;
+ return h;
+ }
+ bool Alloc(UINT flags, SIZE_T size);
+ bool Free();
+ LPVOID Lock() const { return GlobalLock(m_MemoryHandle); }
+ void Unlock() const { GlobalUnlock(m_MemoryHandle); }
+ bool ReAlloc(SIZE_T size);
+};
+
+class CGlobalLock
+{
+ HGLOBAL m_Global;
+ LPVOID m_Pointer;
+public:
+ LPVOID GetPointer() const { return m_Pointer; }
+ CGlobalLock(HGLOBAL hGlobal): m_Global(hGlobal)
+ {
+ m_Pointer = GlobalLock(hGlobal);
+ };
+ ~CGlobalLock()
+ {
+ if (m_Pointer != NULL)
+ GlobalUnlock(m_Global);
+ }
+};
+
+}}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/MemoryLock.cpp b/src/libs/7zip/win/CPP/Windows/MemoryLock.cpp
new file mode 100644
index 000000000..e0f430996
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/MemoryLock.cpp
@@ -0,0 +1,82 @@
+// 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
new file mode 100644
index 000000000..5fe619de0
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/MemoryLock.h
@@ -0,0 +1,15 @@
+// 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/Menu.cpp b/src/libs/7zip/win/CPP/Windows/Menu.cpp
new file mode 100644
index 000000000..675f86237
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Menu.cpp
@@ -0,0 +1,191 @@
+// Windows/Menu.cpp
+
+#include "StdAfx.h"
+
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+#include "Windows/Menu.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+
+static void ConvertItemToSysForm(const CMenuItem &item, MENUITEMINFOW &si)
+{
+ ZeroMemory(&si, sizeof(si));
+ si.cbSize = sizeof(si);
+ si.fMask = item.fMask;
+ si.fType = item.fType;
+ si.fState = item.fState;
+ si.wID = item.wID;
+ si.hSubMenu = item.hSubMenu;
+ si.hbmpChecked = item.hbmpChecked;
+ si.hbmpUnchecked = item.hbmpUnchecked;
+ si.dwItemData = item.dwItemData;
+}
+
+#ifndef _UNICODE
+static void ConvertItemToSysForm(const CMenuItem &item, MENUITEMINFOA &si)
+{
+ ZeroMemory(&si, sizeof(si));
+ si.cbSize = sizeof(si);
+ si.fMask = item.fMask;
+ si.fType = item.fType;
+ si.fState = item.fState;
+ si.wID = item.wID;
+ si.hSubMenu = item.hSubMenu;
+ si.hbmpChecked = item.hbmpChecked;
+ si.hbmpUnchecked = item.hbmpUnchecked;
+ si.dwItemData = item.dwItemData;
+}
+#endif
+
+static void ConvertItemToMyForm(const MENUITEMINFOW &si, CMenuItem &item)
+{
+ item.fMask = si.fMask;
+ item.fType = si.fType;
+ item.fState = si.fState;
+ item.wID = si.wID;
+ item.hSubMenu = si.hSubMenu;
+ item.hbmpChecked = si.hbmpChecked;
+ item.hbmpUnchecked = si.hbmpUnchecked;
+ item.dwItemData = si.dwItemData;
+}
+
+#ifndef _UNICODE
+static void ConvertItemToMyForm(const MENUITEMINFOA &si, CMenuItem &item)
+{
+ item.fMask = si.fMask;
+ item.fType = si.fType;
+ item.fState = si.fState;
+ item.wID = si.wID;
+ item.hSubMenu = si.hSubMenu;
+ item.hbmpChecked = si.hbmpChecked;
+ item.hbmpUnchecked = si.hbmpUnchecked;
+ item.dwItemData = si.dwItemData;
+}
+#endif
+
+bool CMenu::GetItem(UINT itemIndex, bool byPosition, CMenuItem &item)
+{
+ const UINT kMaxSize = 512;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ CHAR s[kMaxSize + 1];
+ MENUITEMINFOA si;
+ ConvertItemToSysForm(item, si);
+ if (item.IsString())
+ {
+ si.cch = kMaxSize;
+ si.dwTypeData = s;
+ }
+ if (GetItemInfo(itemIndex, byPosition, &si))
+ {
+ ConvertItemToMyForm(si, item);
+ if (item.IsString())
+ item.StringValue = GetUnicodeString(s);
+ return true;
+ }
+ }
+ else
+ #endif
+ {
+ wchar_t s[kMaxSize + 1];
+ MENUITEMINFOW si;
+ ConvertItemToSysForm(item, si);
+ if (item.IsString())
+ {
+ si.cch = kMaxSize;
+ si.dwTypeData = s;
+ }
+ if (GetItemInfo(itemIndex, byPosition, &si))
+ {
+ ConvertItemToMyForm(si, item);
+ if (item.IsString())
+ item.StringValue = s;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool CMenu::SetItem(UINT itemIndex, bool byPosition, const CMenuItem &item)
+{
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ MENUITEMINFOA si;
+ ConvertItemToSysForm(item, si);
+ AString s;
+ if (item.IsString())
+ {
+ s = GetSystemString(item.StringValue);
+ si.dwTypeData = (LPTSTR)(LPCTSTR)s;
+ }
+ return SetItemInfo(itemIndex, byPosition, &si);
+ }
+ else
+ #endif
+ {
+ MENUITEMINFOW si;
+ ConvertItemToSysForm(item, si);
+ if (item.IsString())
+ si.dwTypeData = (LPWSTR)(LPCWSTR)item.StringValue;
+ return SetItemInfo(itemIndex, byPosition, &si);
+ }
+}
+
+bool CMenu::InsertItem(UINT itemIndex, bool byPosition, const CMenuItem &item)
+{
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ MENUITEMINFOA si;
+ ConvertItemToSysForm(item, si);
+ AString s;
+ if (item.IsString())
+ {
+ s = GetSystemString(item.StringValue);
+ si.dwTypeData = (LPTSTR)(LPCTSTR)s;
+ }
+ return InsertItem(itemIndex, byPosition, &si);
+ }
+ else
+ #endif
+ {
+ MENUITEMINFOW si;
+ ConvertItemToSysForm(item, si);
+ if (item.IsString())
+ si.dwTypeData = (LPWSTR)(LPCWSTR)item.StringValue;
+ #ifdef UNDER_CE
+ UINT flags = (item.fType & MFT_SEPARATOR) ? MF_SEPARATOR : MF_STRING;
+ UINT id = item.wID;
+ if ((item.fMask & MIIM_SUBMENU) != 0)
+ {
+ flags |= MF_POPUP;
+ id = (UINT)item.hSubMenu;
+ }
+ if (!Insert(itemIndex, flags | (byPosition ? MF_BYPOSITION : MF_BYCOMMAND), id, item.StringValue))
+ return false;
+ return SetItemInfo(itemIndex, byPosition, &si);
+ #else
+ return InsertItem(itemIndex, byPosition, &si);
+ #endif
+ }
+}
+
+#ifndef _UNICODE
+bool CMenu::AppendItem(UINT flags, UINT_PTR newItemID, LPCWSTR newItem)
+{
+ if (g_IsNT)
+ return BOOLToBool(::AppendMenuW(_menu, flags, newItemID, newItem));
+ else
+ return AppendItem(flags, newItemID, GetSystemString(newItem));
+}
+#endif
+
+}
diff --git a/src/libs/7zip/win/CPP/Windows/Menu.h b/src/libs/7zip/win/CPP/Windows/Menu.h
new file mode 100644
index 000000000..2563b9117
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Menu.h
@@ -0,0 +1,153 @@
+// Windows/Menu.h
+
+#ifndef __WINDOWS_MENU_H
+#define __WINDOWS_MENU_H
+
+#include "Common/MyString.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+
+struct CMenuItem
+{
+ UString StringValue;
+ UINT fMask;
+ UINT fType;
+ UINT fState;
+ UINT wID;
+ HMENU hSubMenu;
+ HBITMAP hbmpChecked;
+ HBITMAP hbmpUnchecked;
+ ULONG_PTR dwItemData;
+ // LPTSTR dwTypeData;
+ // UINT cch;
+ // HBITMAP hbmpItem;
+ bool IsString() const // change it MIIM_STRING
+ { return ((fMask & MIIM_TYPE) != 0 && (fType == MFT_STRING)); }
+ bool IsSeparator() const { return (fType == MFT_SEPARATOR); }
+ CMenuItem(): fMask(0), fType(0), fState(0), wID(0), hSubMenu(0), hbmpChecked(0),
+ hbmpUnchecked(0), dwItemData(0) {}
+};
+
+class CMenu
+{
+ HMENU _menu;
+public:
+ CMenu(): _menu(NULL) {};
+ operator HMENU() const { return _menu; }
+ void Attach(HMENU menu) { _menu = menu; }
+
+ HMENU Detach()
+ {
+ HMENU menu = _menu;
+ _menu = NULL;
+ return menu;
+ }
+
+ bool Create()
+ {
+ _menu = ::CreateMenu();
+ return (_menu != NULL);
+ }
+
+ bool CreatePopup()
+ {
+ _menu = ::CreatePopupMenu();
+ return (_menu != NULL);
+ }
+
+ bool Destroy()
+ {
+ if (_menu == NULL)
+ return false;
+ return BOOLToBool(::DestroyMenu(Detach()));
+ }
+
+ int GetItemCount()
+ {
+ #ifdef UNDER_CE
+ for (int i = 0;; i++)
+ {
+ CMenuItem item;
+ item.fMask = MIIM_STATE;
+ if (!GetItem(i, true, item))
+ return i;
+ }
+ #else
+ return GetMenuItemCount(_menu);
+ #endif
+ }
+
+ HMENU GetSubMenu(int pos) { return ::GetSubMenu(_menu, pos); }
+ #ifndef UNDER_CE
+ bool GetItemString(UINT idItem, UINT flag, CSysString &result)
+ {
+ result.Empty();
+ int len = ::GetMenuString(_menu, idItem, 0, 0, flag);
+ len = ::GetMenuString(_menu, idItem, result.GetBuffer(len + 2), len + 1, flag);
+ result.ReleaseBuffer();
+ return (len != 0);
+ }
+ UINT GetItemID(int pos) { return ::GetMenuItemID(_menu, pos); }
+ UINT GetItemState(UINT id, UINT flags) { return ::GetMenuState(_menu, id, flags); }
+ #endif
+
+ bool GetItemInfo(UINT itemIndex, bool byPosition, LPMENUITEMINFO itemInfo)
+ { return BOOLToBool(::GetMenuItemInfo(_menu, itemIndex, BoolToBOOL(byPosition), itemInfo)); }
+ bool SetItemInfo(UINT itemIndex, bool byPosition, LPMENUITEMINFO itemInfo)
+ { return BOOLToBool(::SetMenuItemInfo(_menu, itemIndex, BoolToBOOL(byPosition), itemInfo)); }
+
+ bool AppendItem(UINT flags, UINT_PTR newItemID, LPCTSTR newItem)
+ { return BOOLToBool(::AppendMenu(_menu, flags, newItemID, newItem)); }
+
+ bool Insert(UINT position, UINT flags, UINT_PTR idNewItem, LPCTSTR newItem)
+ { return BOOLToBool(::InsertMenu(_menu, position, flags, idNewItem, newItem)); }
+
+ #ifndef UNDER_CE
+ bool InsertItem(UINT itemIndex, bool byPosition, LPCMENUITEMINFO itemInfo)
+ { return BOOLToBool(::InsertMenuItem(_menu, itemIndex, BoolToBOOL(byPosition), itemInfo)); }
+ #endif
+
+ bool RemoveItem(UINT item, UINT flags) { return BOOLToBool(::RemoveMenu(_menu, item, flags)); }
+ void RemoveAllItemsFrom(UINT index) { while (RemoveItem(index, MF_BYPOSITION)); }
+ void RemoveAllItems() { RemoveAllItemsFrom(0); }
+
+ #ifndef _UNICODE
+ bool GetItemInfo(UINT itemIndex, bool byPosition, LPMENUITEMINFOW itemInfo)
+ { return BOOLToBool(::GetMenuItemInfoW(_menu, itemIndex, BoolToBOOL(byPosition), itemInfo)); }
+ bool InsertItem(UINT itemIndex, bool byPosition, LPMENUITEMINFOW itemInfo)
+ { return BOOLToBool(::InsertMenuItemW(_menu, itemIndex, BoolToBOOL(byPosition), itemInfo)); }
+ bool SetItemInfo(UINT itemIndex, bool byPosition, LPMENUITEMINFOW itemInfo)
+ { return BOOLToBool(::SetMenuItemInfoW(_menu, itemIndex, BoolToBOOL(byPosition), itemInfo)); }
+ bool AppendItem(UINT flags, UINT_PTR newItemID, LPCWSTR newItem);
+ #endif
+
+ bool GetItem(UINT itemIndex, bool byPosition, CMenuItem &item);
+ bool SetItem(UINT itemIndex, bool byPosition, const CMenuItem &item);
+ bool InsertItem(UINT itemIndex, bool byPosition, const CMenuItem &item);
+
+ int Track(UINT flags, int x, int y, HWND hWnd) { return ::TrackPopupMenuEx(_menu, flags, x, y, hWnd, NULL); }
+
+ bool CheckRadioItem(UINT idFirst, UINT idLast, UINT idCheck, UINT flags)
+ { return BOOLToBool(::CheckMenuRadioItem(_menu, idFirst, idLast, idCheck, flags)); }
+
+ DWORD CheckItem(UINT id, UINT uCheck) { return ::CheckMenuItem(_menu, id, uCheck); }
+ DWORD CheckItemByID(UINT id, bool check) { return CheckItem(id, MF_BYCOMMAND | (check ? MF_CHECKED : MF_UNCHECKED)); }
+
+ BOOL EnableItem(UINT uIDEnableItem, UINT uEnable) { return EnableMenuItem(_menu, uIDEnableItem, uEnable); }
+};
+
+class CMenuDestroyer
+{
+ CMenu *_menu;
+public:
+ CMenuDestroyer(CMenu &menu): _menu(&menu) {}
+ CMenuDestroyer(): _menu(0) {}
+ ~CMenuDestroyer() { if (_menu) _menu->Destroy(); }
+ void Attach(CMenu &menu) { _menu = &menu; }
+ void Disable() { _menu = 0; }
+};
+
+}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/NationalTime.cpp b/src/libs/7zip/win/CPP/Windows/NationalTime.cpp
new file mode 100644
index 000000000..c231d3ced
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/NationalTime.cpp
@@ -0,0 +1,37 @@
+// Windows/NationalTime.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/NationalTime.h"
+
+namespace NWindows {
+namespace NNational {
+namespace NTime {
+
+bool MyGetTimeFormat(LCID locale, DWORD flags, CONST SYSTEMTIME *time,
+ LPCTSTR format, CSysString &resultString)
+{
+ resultString.Empty();
+ int numChars = ::GetTimeFormat(locale, flags, time, format, NULL, 0);
+ if (numChars == 0)
+ return false;
+ numChars = ::GetTimeFormat(locale, flags, time, format,
+ resultString.GetBuffer(numChars), numChars + 1);
+ resultString.ReleaseBuffer();
+ return (numChars != 0);
+}
+
+bool MyGetDateFormat(LCID locale, DWORD flags, CONST SYSTEMTIME *time,
+ LPCTSTR format, CSysString &resultString)
+{
+ resultString.Empty();
+ int numChars = ::GetDateFormat(locale, flags, time, format, NULL, 0);
+ if (numChars == 0)
+ return false;
+ numChars = ::GetDateFormat(locale, flags, time, format,
+ resultString.GetBuffer(numChars), numChars + 1);
+ resultString.ReleaseBuffer();
+ return (numChars != 0);
+}
+
+}}}
diff --git a/src/libs/7zip/win/CPP/Windows/NationalTime.h b/src/libs/7zip/win/CPP/Windows/NationalTime.h
new file mode 100644
index 000000000..86e014bf9
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/NationalTime.h
@@ -0,0 +1,20 @@
+// Windows/NationalTime.h
+
+#ifndef __WINDOWS_NATIONALTIME_H
+#define __WINDOWS_NATIONALTIME_H
+
+#include "Common/String.h"
+
+namespace NWindows {
+namespace NNational {
+namespace NTime {
+
+bool MyGetTimeFormat(LCID locale, DWORD flags, CONST SYSTEMTIME *time,
+ LPCTSTR format, CSysString &resultString);
+
+bool MyGetDateFormat(LCID locale, DWORD flags, CONST SYSTEMTIME *time,
+ LPCTSTR format, CSysString &resultString);
+
+}}}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/Net.cpp b/src/libs/7zip/win/CPP/Windows/Net.cpp
new file mode 100644
index 000000000..b0a18732a
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Net.cpp
@@ -0,0 +1,380 @@
+// Windows/Net.cpp
+
+#include "StdAfx.h"
+
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+
+#include "Windows/Net.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NNet {
+
+DWORD CEnum::Open(DWORD scope, DWORD type, DWORD usage, LPNETRESOURCE netResource)
+{
+ Close();
+ DWORD result = ::WNetOpenEnum(scope, type, usage, netResource, &_handle);
+ _handleAllocated = (result == NO_ERROR);
+ return result;
+}
+
+#ifndef _UNICODE
+DWORD CEnum::Open(DWORD scope, DWORD type, DWORD usage, LPNETRESOURCEW netResource)
+{
+ Close();
+ DWORD result = ::WNetOpenEnumW(scope, type, usage, netResource, &_handle);
+ _handleAllocated = (result == NO_ERROR);
+ return result;
+}
+#endif
+
+static void SetComplexString(bool &defined, CSysString &destString, LPCTSTR srsString)
+{
+ defined = (srsString != 0);
+ if (defined)
+ destString = srsString;
+ else
+ destString.Empty();
+}
+
+static void ConvertNETRESOURCEToCResource(const NETRESOURCE &netResource, CResource &resource)
+{
+ resource.Scope = netResource.dwScope;
+ resource.Type = netResource.dwType;
+ resource.DisplayType = netResource.dwDisplayType;
+ resource.Usage = netResource.dwUsage;
+ SetComplexString(resource.LocalNameIsDefined, resource.LocalName, netResource.lpLocalName);
+ SetComplexString(resource.RemoteNameIsDefined, resource.RemoteName, netResource.lpRemoteName);
+ SetComplexString(resource.CommentIsDefined, resource.Comment, netResource.lpComment);
+ SetComplexString(resource.ProviderIsDefined, resource.Provider, netResource.lpProvider);
+}
+
+static void SetComplexString2(LPTSTR *destString, bool defined, const CSysString &srcString)
+{
+ if (defined)
+ *destString = (TCHAR *)(const TCHAR *)srcString;
+ else
+ *destString = 0;
+}
+
+static void ConvertCResourceToNETRESOURCE(const CResource &resource, NETRESOURCE &netResource)
+{
+ netResource.dwScope = resource.Scope;
+ netResource.dwType = resource.Type;
+ netResource.dwDisplayType = resource.DisplayType;
+ netResource.dwUsage = resource.Usage;
+ SetComplexString2(&netResource.lpLocalName, resource.LocalNameIsDefined, resource.LocalName);
+ SetComplexString2(&netResource.lpRemoteName, resource.RemoteNameIsDefined, resource.RemoteName);
+ SetComplexString2(&netResource.lpComment, resource.CommentIsDefined, resource.Comment);
+ SetComplexString2(&netResource.lpProvider, resource.ProviderIsDefined, resource.Provider);
+}
+
+#ifndef _UNICODE
+
+static void SetComplexString(bool &defined, UString &destString, LPCWSTR srsString)
+{
+ defined = (srsString != 0);
+ if (defined)
+ destString = srsString;
+ else
+ destString.Empty();
+}
+
+static void ConvertNETRESOURCEToCResource(const NETRESOURCEW &netResource, CResourceW &resource)
+{
+ resource.Scope = netResource.dwScope;
+ resource.Type = netResource.dwType;
+ resource.DisplayType = netResource.dwDisplayType;
+ resource.Usage = netResource.dwUsage;
+ SetComplexString(resource.LocalNameIsDefined, resource.LocalName, netResource.lpLocalName);
+ SetComplexString(resource.RemoteNameIsDefined, resource.RemoteName, netResource.lpRemoteName);
+ SetComplexString(resource.CommentIsDefined, resource.Comment, netResource.lpComment);
+ SetComplexString(resource.ProviderIsDefined, resource.Provider, netResource.lpProvider);
+}
+
+static void SetComplexString2(LPWSTR *destString, bool defined, const UString &srcString)
+{
+ if (defined)
+ *destString = (WCHAR *)(const WCHAR *)srcString;
+ else
+ *destString = 0;
+}
+
+static void ConvertCResourceToNETRESOURCE(const CResourceW &resource, NETRESOURCEW &netResource)
+{
+ netResource.dwScope = resource.Scope;
+ netResource.dwType = resource.Type;
+ netResource.dwDisplayType = resource.DisplayType;
+ netResource.dwUsage = resource.Usage;
+ SetComplexString2(&netResource.lpLocalName, resource.LocalNameIsDefined, resource.LocalName);
+ SetComplexString2(&netResource.lpRemoteName, resource.RemoteNameIsDefined, resource.RemoteName);
+ SetComplexString2(&netResource.lpComment, resource.CommentIsDefined, resource.Comment);
+ SetComplexString2(&netResource.lpProvider, resource.ProviderIsDefined, resource.Provider);
+}
+
+static void ConvertResourceWToResource(const CResourceW &resourceW, CResource &resource)
+{
+ *(CResourceBase *)&resource = *(CResourceBase *)&resourceW;
+ resource.LocalName = GetSystemString(resourceW.LocalName);
+ resource.RemoteName = GetSystemString(resourceW.RemoteName);
+ resource.Comment = GetSystemString(resourceW.Comment);
+ resource.Provider = GetSystemString(resourceW.Provider);
+}
+
+static void ConvertResourceToResourceW(const CResource &resource, CResourceW &resourceW)
+{
+ *(CResourceBase *)&resourceW = *(CResourceBase *)&resource;
+ resourceW.LocalName = GetUnicodeString(resource.LocalName);
+ resourceW.RemoteName = GetUnicodeString(resource.RemoteName);
+ resourceW.Comment = GetUnicodeString(resource.Comment);
+ resourceW.Provider = GetUnicodeString(resource.Provider);
+}
+#endif
+
+DWORD CEnum::Open(DWORD scope, DWORD type, DWORD usage, const CResource *resource)
+{
+ NETRESOURCE netResource;
+ LPNETRESOURCE pointer;
+ if (resource == 0)
+ pointer = 0;
+ else
+ {
+ ConvertCResourceToNETRESOURCE(*resource, netResource);
+ pointer = &netResource;
+ }
+ return Open(scope, type, usage, pointer);
+}
+
+#ifndef _UNICODE
+DWORD CEnum::Open(DWORD scope, DWORD type, DWORD usage, const CResourceW *resource)
+{
+ if (g_IsNT)
+ {
+ NETRESOURCEW netResource;
+ LPNETRESOURCEW pointer;
+ if (resource == 0)
+ pointer = 0;
+ else
+ {
+ ConvertCResourceToNETRESOURCE(*resource, netResource);
+ pointer = &netResource;
+ }
+ return Open(scope, type, usage, pointer);
+ }
+ CResource *pointer;
+ CResource resourceA;
+ if (resource == 0)
+ pointer = 0;
+ else
+ {
+ ConvertResourceWToResource(*resource, resourceA);
+ pointer = &resourceA;
+ }
+ return Open(scope, type, usage, pointer);
+}
+#endif
+
+DWORD CEnum::Close()
+{
+ if (!_handleAllocated)
+ return NO_ERROR;
+ DWORD result = ::WNetCloseEnum(_handle);
+ _handleAllocated = (result != NO_ERROR);
+ return result;
+}
+
+DWORD CEnum::Next(LPDWORD lpcCount, LPVOID lpBuffer, LPDWORD lpBufferSize)
+{
+ return ::WNetEnumResource(_handle, lpcCount, lpBuffer, lpBufferSize);
+}
+
+#ifndef _UNICODE
+DWORD CEnum::NextW(LPDWORD lpcCount, LPVOID lpBuffer, LPDWORD lpBufferSize)
+{
+ return ::WNetEnumResourceW(_handle, lpcCount, lpBuffer, lpBufferSize);
+}
+#endif
+
+DWORD CEnum::Next(CResource &resource)
+{
+ CByteBuffer byteBuffer;
+ const DWORD kBufferSize = 16384;
+ byteBuffer.SetCapacity(kBufferSize);
+ LPNETRESOURCE lpnrLocal = (LPNETRESOURCE) (BYTE *)(byteBuffer);
+ ZeroMemory(lpnrLocal, kBufferSize);
+ DWORD bufferSize = kBufferSize;
+ DWORD numEntries = 1;
+ DWORD result = Next(&numEntries, lpnrLocal, &bufferSize);
+ if (result != NO_ERROR)
+ return result;
+ if (numEntries != 1)
+ return (DWORD)E_FAIL;
+ ConvertNETRESOURCEToCResource(lpnrLocal[0], resource);
+ return result;
+}
+
+#ifndef _UNICODE
+DWORD CEnum::Next(CResourceW &resource)
+{
+ if (g_IsNT)
+ {
+ CByteBuffer byteBuffer;
+ const DWORD kBufferSize = 16384;
+ byteBuffer.SetCapacity(kBufferSize);
+ LPNETRESOURCEW lpnrLocal = (LPNETRESOURCEW) (BYTE *)(byteBuffer);
+ ZeroMemory(lpnrLocal, kBufferSize);
+ DWORD bufferSize = kBufferSize;
+ DWORD numEntries = 1;
+ DWORD result = NextW(&numEntries, lpnrLocal, &bufferSize);
+ if (result != NO_ERROR)
+ return result;
+ if (numEntries != 1)
+ return (DWORD)E_FAIL;
+ ConvertNETRESOURCEToCResource(lpnrLocal[0], resource);
+ return result;
+ }
+ CResource resourceA;
+ DWORD result = Next(resourceA);
+ ConvertResourceToResourceW(resourceA, resource);
+ return result;
+}
+#endif
+
+
+DWORD GetResourceParent(const CResource &resource, CResource &parentResource)
+{
+ CByteBuffer byteBuffer;
+ const DWORD kBufferSize = 16384;
+ byteBuffer.SetCapacity(kBufferSize);
+ LPNETRESOURCE lpnrLocal = (LPNETRESOURCE) (BYTE *)(byteBuffer);
+ ZeroMemory(lpnrLocal, kBufferSize);
+ DWORD bufferSize = kBufferSize;
+ NETRESOURCE netResource;
+ ConvertCResourceToNETRESOURCE(resource, netResource);
+ DWORD result = ::WNetGetResourceParent(&netResource, lpnrLocal, &bufferSize);
+ if (result != NO_ERROR)
+ return result;
+ ConvertNETRESOURCEToCResource(lpnrLocal[0], parentResource);
+ return result;
+}
+
+#ifndef _UNICODE
+DWORD GetResourceParent(const CResourceW &resource, CResourceW &parentResource)
+{
+ if (g_IsNT)
+ {
+ CByteBuffer byteBuffer;
+ const DWORD kBufferSize = 16384;
+ byteBuffer.SetCapacity(kBufferSize);
+ LPNETRESOURCEW lpnrLocal = (LPNETRESOURCEW) (BYTE *)(byteBuffer);
+ ZeroMemory(lpnrLocal, kBufferSize);
+ DWORD bufferSize = kBufferSize;
+ NETRESOURCEW netResource;
+ ConvertCResourceToNETRESOURCE(resource, netResource);
+ DWORD result = ::WNetGetResourceParentW(&netResource, lpnrLocal, &bufferSize);
+ if (result != NO_ERROR)
+ return result;
+ ConvertNETRESOURCEToCResource(lpnrLocal[0], parentResource);
+ return result;
+ }
+ CResource resourceA, parentResourceA;
+ ConvertResourceWToResource(resource, resourceA);
+ DWORD result = GetResourceParent(resourceA, parentResourceA);
+ ConvertResourceToResourceW(parentResourceA, parentResource);
+ return result;
+}
+#endif
+
+DWORD GetResourceInformation(const CResource &resource,
+ CResource &destResource, CSysString &systemPathPart)
+{
+ CByteBuffer byteBuffer;
+ const DWORD kBufferSize = 16384;
+ byteBuffer.SetCapacity(kBufferSize);
+ LPNETRESOURCE lpnrLocal = (LPNETRESOURCE) (BYTE *)(byteBuffer);
+ ZeroMemory(lpnrLocal, kBufferSize);
+ DWORD bufferSize = kBufferSize;
+ NETRESOURCE netResource;
+ ConvertCResourceToNETRESOURCE(resource, netResource);
+ LPTSTR lplpSystem;
+ DWORD result = ::WNetGetResourceInformation(&netResource,
+ lpnrLocal, &bufferSize, &lplpSystem);
+ if (result != NO_ERROR)
+ return result;
+ if (lplpSystem != 0)
+ systemPathPart = lplpSystem;
+ ConvertNETRESOURCEToCResource(lpnrLocal[0], destResource);
+ return result;
+}
+
+#ifndef _UNICODE
+DWORD GetResourceInformation(const CResourceW &resource,
+ CResourceW &destResource, UString &systemPathPart)
+{
+ if (g_IsNT)
+ {
+ CByteBuffer byteBuffer;
+ const DWORD kBufferSize = 16384;
+ byteBuffer.SetCapacity(kBufferSize);
+ LPNETRESOURCEW lpnrLocal = (LPNETRESOURCEW) (BYTE *)(byteBuffer);
+ ZeroMemory(lpnrLocal, kBufferSize);
+ DWORD bufferSize = kBufferSize;
+ NETRESOURCEW netResource;
+ ConvertCResourceToNETRESOURCE(resource, netResource);
+ LPWSTR lplpSystem;
+ DWORD result = ::WNetGetResourceInformationW(&netResource,
+ lpnrLocal, &bufferSize, &lplpSystem);
+ if (result != NO_ERROR)
+ return result;
+ if (lplpSystem != 0)
+ systemPathPart = lplpSystem;
+ ConvertNETRESOURCEToCResource(lpnrLocal[0], destResource);
+ return result;
+ }
+ CResource resourceA, destResourceA;
+ ConvertResourceWToResource(resource, resourceA);
+ AString systemPathPartA;
+ DWORD result = GetResourceInformation(resourceA, destResourceA, systemPathPartA);
+ ConvertResourceToResourceW(destResourceA, destResource);
+ systemPathPart = GetUnicodeString(systemPathPartA);
+ return result;
+}
+#endif
+
+DWORD AddConnection2(const CResource &resource,
+ LPCTSTR password, LPCTSTR userName, DWORD flags)
+{
+ NETRESOURCE netResource;
+ ConvertCResourceToNETRESOURCE(resource, netResource);
+ return ::WNetAddConnection2(&netResource,
+ password, userName, flags);
+}
+
+DWORD AddConnection2(const CResource &resource, LPCTSTR password, LPCTSTR userName, DWORD flags);
+
+#ifndef _UNICODE
+DWORD AddConnection2(const CResourceW &resource, LPCWSTR password, LPCWSTR userName, DWORD flags)
+{
+ if (g_IsNT)
+ {
+ NETRESOURCEW netResource;
+ ConvertCResourceToNETRESOURCE(resource, netResource);
+ return ::WNetAddConnection2W(&netResource,password, userName, flags);
+ }
+ CResource resourceA;
+ ConvertResourceWToResource(resource, resourceA);
+ CSysString passwordA = GetSystemString(password);
+ CSysString userNameA = GetSystemString(userName);
+ return AddConnection2(resourceA,
+ password ? (LPCTSTR)passwordA: 0,
+ userName ? (LPCTSTR)userNameA: 0,
+ flags);
+}
+#endif
+
+}}
diff --git a/src/libs/7zip/win/CPP/Windows/Net.h b/src/libs/7zip/win/CPP/Windows/Net.h
new file mode 100644
index 000000000..c88b61130
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Net.h
@@ -0,0 +1,87 @@
+// Windows/Net.h
+
+#ifndef __WINDOWS_NET_H
+#define __WINDOWS_NET_H
+
+#include "Common/Buffer.h"
+#include "Common/MyString.h"
+
+namespace NWindows {
+namespace NNet {
+
+struct CResourceBase
+{
+ DWORD Scope;
+ DWORD Type;
+ DWORD DisplayType;
+ DWORD Usage;
+ bool LocalNameIsDefined;
+ bool RemoteNameIsDefined;
+ bool CommentIsDefined;
+ bool ProviderIsDefined;
+};
+
+struct CResource: public CResourceBase
+{
+ CSysString LocalName;
+ CSysString RemoteName;
+ CSysString Comment;
+ CSysString Provider;
+};
+
+#ifdef _UNICODE
+typedef CResource CResourceW;
+#else
+struct CResourceW: public CResourceBase
+{
+ UString LocalName;
+ UString RemoteName;
+ UString Comment;
+ UString Provider;
+};
+#endif
+
+class CEnum
+{
+ HANDLE _handle;
+ bool _handleAllocated;
+ DWORD Open(DWORD scope, DWORD type, DWORD usage, LPNETRESOURCE netResource);
+ DWORD Next(LPDWORD lpcCount, LPVOID lpBuffer, LPDWORD lpBufferSize);
+ #ifndef _UNICODE
+ DWORD Open(DWORD scope, DWORD type, DWORD usage, LPNETRESOURCEW netResource);
+ DWORD NextW(LPDWORD lpcCount, LPVOID lpBuffer, LPDWORD lpBufferSize);
+ #endif
+protected:
+ bool IsHandleAllocated() const { return _handleAllocated; }
+public:
+ CEnum(): _handleAllocated(false) {}
+ ~CEnum() { Close(); }
+ DWORD Close();
+ DWORD Open(DWORD scope, DWORD type, DWORD usage, const CResource *resource);
+ DWORD Next(CResource &resource);
+ #ifndef _UNICODE
+ DWORD Open(DWORD scope, DWORD type, DWORD usage, const CResourceW *resource);
+ DWORD Next(CResourceW &resource);
+ #endif
+};
+
+DWORD GetResourceParent(const CResource &resource, CResource &parentResource);
+#ifndef _UNICODE
+DWORD GetResourceParent(const CResourceW &resource, CResourceW &parentResource);
+#endif
+
+DWORD GetResourceInformation(const CResource &resource,
+ CResource &destResource, CSysString &systemPathPart);
+#ifndef _UNICODE
+DWORD GetResourceInformation(const CResourceW &resource,
+ CResourceW &destResource, UString &systemPathPart);
+#endif
+
+DWORD AddConnection2(const CResource &resource, LPCTSTR password, LPCTSTR userName, DWORD flags);
+#ifndef _UNICODE
+DWORD AddConnection2(const CResourceW &resource, LPCWSTR password, LPCWSTR userName, DWORD flags);
+#endif
+
+}}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/NtCheck.h b/src/libs/7zip/win/CPP/Windows/NtCheck.h
new file mode 100644
index 000000000..e56318f00
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/NtCheck.h
@@ -0,0 +1,44 @@
+// 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/Process.cpp b/src/libs/7zip/win/CPP/Windows/Process.cpp
new file mode 100644
index 000000000..9bcee7d5a
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Process.cpp
@@ -0,0 +1,81 @@
+// Process.cpp
+
+#include "StdAfx.h"
+
+#include "../Common/StringConvert.h"
+
+#include "Process.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+
+static UString GetQuotedString(const UString &s)
+{
+ return UString(L'\"') + s + UString(L'\"');
+}
+
+WRes CProcess::Create(LPCWSTR imageName, const UString &params, LPCWSTR curDir)
+{
+ Close();
+ const UString params2 =
+ #ifndef UNDER_CE
+ GetQuotedString(imageName) + L' ' +
+ #endif
+ params;
+ #ifdef UNDER_CE
+ curDir = 0;
+ #else
+ imageName = 0;
+ #endif
+ PROCESS_INFORMATION pi;
+ BOOL result;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ STARTUPINFOA si;
+ si.cb = sizeof(si);
+ si.lpReserved = 0;
+ si.lpDesktop = 0;
+ si.lpTitle = 0;
+ si.dwFlags = 0;
+ si.cbReserved2 = 0;
+ si.lpReserved2 = 0;
+
+ CSysString curDirA;
+ if (curDir != 0)
+ curDirA = GetSystemString(curDir);
+ result = ::CreateProcessA(NULL, (LPSTR)(LPCSTR)GetSystemString(params2),
+ NULL, NULL, FALSE, 0, NULL, ((curDir != 0) ? (LPCSTR)curDirA: 0), &si, &pi);
+ }
+ else
+ #endif
+ {
+ STARTUPINFOW si;
+ si.cb = sizeof(si);
+ si.lpReserved = 0;
+ si.lpDesktop = 0;
+ si.lpTitle = 0;
+ si.dwFlags = 0;
+ si.cbReserved2 = 0;
+ si.lpReserved2 = 0;
+
+ result = CreateProcessW(imageName, (LPWSTR)(LPCWSTR)params2,
+ NULL, NULL, FALSE, 0, NULL, (LPWSTR)curDir, &si, &pi);
+ }
+ if (result == 0)
+ return ::GetLastError();
+ ::CloseHandle(pi.hThread);
+ _handle = pi.hProcess;
+ return 0;
+}
+
+WRes MyCreateProcess(LPCWSTR imageName, const UString &params)
+{
+ CProcess process;
+ return process.Create(imageName, params, 0);
+}
+
+}
diff --git a/src/libs/7zip/win/CPP/Windows/Process.h b/src/libs/7zip/win/CPP/Windows/Process.h
new file mode 100644
index 000000000..5b01c377a
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Process.h
@@ -0,0 +1,100 @@
+// Windows/Process.h
+
+#ifndef __WINDOWS_PROCESS_H
+#define __WINDOWS_PROCESS_H
+
+#include <psapi.h>
+
+#include "../Common/MyString.h"
+
+#include "Defs.h"
+#include "Handle.h"
+
+namespace NWindows {
+
+class CProcess: public CHandle
+{
+public:
+ bool Open(DWORD desiredAccess, bool inheritHandle, DWORD processId)
+ {
+ _handle = ::OpenProcess(desiredAccess, inheritHandle, processId);
+ return (_handle != 0);
+ }
+
+ #ifndef UNDER_CE
+
+ bool GetExitCodeProcess(LPDWORD lpExitCode) { return BOOLToBool(::GetExitCodeProcess(_handle, lpExitCode)); }
+ bool Terminate(UINT exitCode) { return BOOLToBool(::TerminateProcess(_handle, exitCode)); }
+ #if(WINVER >= 0x0500)
+ DWORD GetGuiResources (DWORD uiFlags) { return ::GetGuiResources(_handle, uiFlags); }
+ #endif
+ bool SetPriorityClass(DWORD dwPriorityClass) { return BOOLToBool(::SetPriorityClass(_handle, dwPriorityClass)); }
+ DWORD GetPriorityClass() { return ::GetPriorityClass(_handle); }
+ bool GetIoCounters(PIO_COUNTERS lpIoCounters ) { return BOOLToBool(::GetProcessIoCounters(_handle, lpIoCounters )); }
+
+ bool GetTimes(LPFILETIME creationTime, LPFILETIME exitTime, LPFILETIME kernelTime, LPFILETIME userTime)
+ { return BOOLToBool(::GetProcessTimes(_handle, creationTime, exitTime, kernelTime, userTime)); }
+
+ DWORD WaitForInputIdle(DWORD milliseconds) { return ::WaitForInputIdle(_handle, milliseconds); }
+
+ // Debug
+
+ bool ReadMemory(LPCVOID baseAddress, LPVOID buffer, SIZE_T size, SIZE_T* numberOfBytesRead)
+ { return BOOLToBool(::ReadProcessMemory(_handle, baseAddress, buffer, size, numberOfBytesRead)); }
+
+ bool WriteMemory(LPVOID baseAddress, LPCVOID buffer, SIZE_T size, SIZE_T* numberOfBytesWritten)
+ { return BOOLToBool(::WriteProcessMemory(_handle, baseAddress, buffer, size, numberOfBytesWritten)); }
+
+ bool FlushInstructionCache(LPCVOID baseAddress = 0, SIZE_T size = 0)
+ { return BOOLToBool(::FlushInstructionCache(_handle, baseAddress, size)); }
+
+ LPVOID VirtualAlloc(LPVOID address, SIZE_T size, DWORD allocationType, DWORD protect)
+ { return VirtualAllocEx(_handle, address, size, allocationType, protect); }
+
+ bool VirtualFree(LPVOID address, SIZE_T size, DWORD freeType)
+ { return BOOLToBool(::VirtualFreeEx(_handle, address, size, freeType)); }
+
+ // Process Status API (PSAPI)
+
+ bool EmptyWorkingSet()
+ { return BOOLToBool(::EmptyWorkingSet(_handle)); }
+ bool EnumModules(HMODULE *hModules, DWORD arraySizeInBytes, LPDWORD receivedBytes)
+ { return BOOLToBool(::EnumProcessModules(_handle, hModules, arraySizeInBytes, receivedBytes)); }
+
+ DWORD MyGetModuleBaseName(HMODULE hModule, LPTSTR baseName, DWORD size)
+ { return ::GetModuleBaseName(_handle, hModule, baseName, size); }
+ bool MyGetModuleBaseName(HMODULE hModule, CSysString &name)
+ {
+ const int length = 1000;
+ DWORD resultLen = MyGetModuleBaseName(hModule, name.GetBuffer(length), length);
+ name.ReleaseBuffer();
+ return (resultLen != 0);
+ }
+
+ DWORD MyGetModuleFileNameEx(HMODULE hModule, LPTSTR baseName, DWORD size)
+ { return ::GetModuleFileNameEx(_handle, hModule, baseName, size); }
+ bool MyGetModuleFileNameEx(HMODULE hModule, CSysString &name)
+ {
+ const int length = MAX_PATH + 100;
+ DWORD resultLen = MyGetModuleFileNameEx(hModule, name.GetBuffer(length), length);
+ name.ReleaseBuffer();
+ return (resultLen != 0);
+ }
+
+ bool GetModuleInformation(HMODULE hModule, LPMODULEINFO moduleInfo)
+ { return BOOLToBool(::GetModuleInformation(_handle, hModule, moduleInfo, sizeof(MODULEINFO))); }
+ bool GetMemoryInfo(PPROCESS_MEMORY_COUNTERS memCounters)
+ { return BOOLToBool(::GetProcessMemoryInfo(_handle, memCounters, sizeof(PROCESS_MEMORY_COUNTERS))); }
+
+ #endif
+
+ WRes Create(LPCWSTR imageName, const UString &params, LPCWSTR curDir);
+
+ DWORD Wait() { return ::WaitForSingleObject(_handle, INFINITE); }
+};
+
+WRes MyCreateProcess(LPCWSTR imageName, const UString &params);
+
+}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/ProcessMessages.cpp b/src/libs/7zip/win/CPP/Windows/ProcessMessages.cpp
new file mode 100644
index 000000000..0f48aee25
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/ProcessMessages.cpp
@@ -0,0 +1,22 @@
+// Windows/ProcessMessages.cpp
+
+#include "StdAfx.h"
+
+#include "ProcessMessages.h"
+
+namespace NWindows {
+
+void ProcessMessages(HWND window)
+{
+ MSG msg;
+ while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
+ {
+ if (window == (HWND) NULL || !IsDialogMessage(window, &msg))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+}
+
+}
diff --git a/src/libs/7zip/win/CPP/Windows/ProcessMessages.h b/src/libs/7zip/win/CPP/Windows/ProcessMessages.h
new file mode 100644
index 000000000..63f8ec8a0
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/ProcessMessages.h
@@ -0,0 +1,14 @@
+// Windows/ProcessMessages.h
+
+#ifndef __WINDOWS_PROCESSMESSAGES_H
+#define __WINDOWS_PROCESSMESSAGES_H
+
+namespace NWindows {
+
+void ProcessMessages(HWND window);
+
+}
+
+#endif
+
+
diff --git a/src/libs/7zip/win/CPP/Windows/PropVariant.cpp b/src/libs/7zip/win/CPP/Windows/PropVariant.cpp
new file mode 100644
index 000000000..90212e08f
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/PropVariant.cpp
@@ -0,0 +1,243 @@
+// Windows/PropVariant.cpp
+
+#include "StdAfx.h"
+
+#include "PropVariant.h"
+
+#include "../Common/Defs.h"
+
+namespace NWindows {
+namespace NCOM {
+
+CPropVariant::CPropVariant(const PROPVARIANT &varSrc)
+{
+ vt = VT_EMPTY;
+ InternalCopy(&varSrc);
+}
+
+CPropVariant::CPropVariant(const CPropVariant &varSrc)
+{
+ vt = VT_EMPTY;
+ InternalCopy(&varSrc);
+}
+
+CPropVariant::CPropVariant(BSTR bstrSrc)
+{
+ vt = VT_EMPTY;
+ *this = bstrSrc;
+}
+
+CPropVariant::CPropVariant(LPCOLESTR lpszSrc)
+{
+ vt = VT_EMPTY;
+ *this = lpszSrc;
+}
+
+CPropVariant& CPropVariant::operator=(const CPropVariant &varSrc)
+{
+ InternalCopy(&varSrc);
+ return *this;
+}
+CPropVariant& CPropVariant::operator=(const PROPVARIANT &varSrc)
+{
+ InternalCopy(&varSrc);
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(BSTR bstrSrc)
+{
+ *this = (LPCOLESTR)bstrSrc;
+ return *this;
+}
+
+static const char *kMemException = "out of memory";
+
+CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
+{
+ InternalClear();
+ vt = VT_BSTR;
+ wReserved1 = 0;
+ bstrVal = ::SysAllocString(lpszSrc);
+ if (bstrVal == NULL && lpszSrc != NULL)
+ {
+ throw kMemException;
+ // vt = VT_ERROR;
+ // scode = E_OUTOFMEMORY;
+ }
+ 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)
+ {
+ throw kMemException;
+ // vt = VT_ERROR;
+ // scode = E_OUTOFMEMORY;
+ }
+ else
+ {
+ for (UINT i = 0; i <= len; i++)
+ bstrVal[i] = s[i];
+ }
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(bool bSrc)
+{
+ if (vt != VT_BOOL)
+ {
+ InternalClear();
+ vt = VT_BOOL;
+ }
+ boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
+ return *this;
+}
+
+#define SET_PROP_FUNC(type, id, dest) \
+ CPropVariant& CPropVariant::operator=(type value) \
+ { 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(Int32, VT_I4, lVal)
+SET_PROP_FUNC(UInt32, VT_UI4, ulVal)
+SET_PROP_FUNC(UInt64, VT_UI8, uhVal.QuadPart)
+SET_PROP_FUNC(const FILETIME &, VT_FILETIME, filetime)
+
+static HRESULT MyPropVariantClear(PROPVARIANT *prop)
+{
+ switch(prop->vt)
+ {
+ case VT_UI1:
+ case VT_I1:
+ case VT_I2:
+ case VT_UI2:
+ case VT_BOOL:
+ case VT_I4:
+ case VT_UI4:
+ case VT_R4:
+ case VT_INT:
+ case VT_UINT:
+ case VT_ERROR:
+ case VT_FILETIME:
+ case VT_UI8:
+ case VT_R8:
+ case VT_CY:
+ case VT_DATE:
+ prop->vt = VT_EMPTY;
+ prop->wReserved1 = 0;
+ return S_OK;
+ }
+ return ::VariantClear((VARIANTARG *)prop);
+}
+
+HRESULT CPropVariant::Clear()
+{
+ return MyPropVariantClear(this);
+}
+
+HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc)
+{
+ ::VariantClear((tagVARIANT *)this);
+ switch(pSrc->vt)
+ {
+ case VT_UI1:
+ case VT_I1:
+ case VT_I2:
+ case VT_UI2:
+ case VT_BOOL:
+ case VT_I4:
+ case VT_UI4:
+ case VT_R4:
+ case VT_INT:
+ case VT_UINT:
+ case VT_ERROR:
+ case VT_FILETIME:
+ case VT_UI8:
+ case VT_R8:
+ case VT_CY:
+ case VT_DATE:
+ memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT));
+ return S_OK;
+ }
+ return ::VariantCopy((tagVARIANT *)this, (tagVARIANT *)const_cast<PROPVARIANT *>(pSrc));
+}
+
+
+HRESULT CPropVariant::Attach(PROPVARIANT *pSrc)
+{
+ HRESULT hr = Clear();
+ if (FAILED(hr))
+ return hr;
+ memcpy(this, pSrc, sizeof(PROPVARIANT));
+ pSrc->vt = VT_EMPTY;
+ return S_OK;
+}
+
+HRESULT CPropVariant::Detach(PROPVARIANT *pDest)
+{
+ HRESULT hr = MyPropVariantClear(pDest);
+ if (FAILED(hr))
+ return hr;
+ memcpy(pDest, this, sizeof(PROPVARIANT));
+ vt = VT_EMPTY;
+ return S_OK;
+}
+
+HRESULT CPropVariant::InternalClear()
+{
+ HRESULT hr = Clear();
+ if (FAILED(hr))
+ {
+ vt = VT_ERROR;
+ scode = hr;
+ }
+ return hr;
+}
+
+void CPropVariant::InternalCopy(const PROPVARIANT *pSrc)
+{
+ HRESULT hr = Copy(pSrc);
+ if (FAILED(hr))
+ {
+ if (hr == E_OUTOFMEMORY)
+ throw kMemException;
+ vt = VT_ERROR;
+ scode = hr;
+ }
+}
+
+int CPropVariant::Compare(const CPropVariant &a)
+{
+ if (vt != a.vt)
+ return MyCompare(vt, a.vt);
+ switch (vt)
+ {
+ case VT_EMPTY: return 0;
+ // case VT_I1: return MyCompare(cVal, a.cVal);
+ case VT_UI1: return MyCompare(bVal, a.bVal);
+ case VT_I2: return MyCompare(iVal, a.iVal);
+ case VT_UI2: return MyCompare(uiVal, a.uiVal);
+ case VT_I4: return MyCompare(lVal, a.lVal);
+ case VT_UI4: return MyCompare(ulVal, a.ulVal);
+ // case VT_UINT: return MyCompare(uintVal, a.uintVal);
+ case VT_I8: return MyCompare(hVal.QuadPart, a.hVal.QuadPart);
+ 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);
+ default: return 0;
+ }
+}
+
+}}
diff --git a/src/libs/7zip/win/CPP/Windows/PropVariant.h b/src/libs/7zip/win/CPP/Windows/PropVariant.h
new file mode 100644
index 000000000..d018034eb
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/PropVariant.h
@@ -0,0 +1,56 @@
+// Windows/PropVariant.h
+
+#ifndef __WINDOWS_PROPVARIANT_H
+#define __WINDOWS_PROPVARIANT_H
+
+#include "../Common/MyWindows.h"
+#include "../Common/Types.h"
+
+namespace NWindows {
+namespace NCOM {
+
+class CPropVariant : public tagPROPVARIANT
+{
+public:
+ CPropVariant() { vt = VT_EMPTY; wReserved1 = 0; }
+ ~CPropVariant() { 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; }
+ CPropVariant(UInt32 value) { vt = VT_UI4; wReserved1 = 0; ulVal = value; }
+ CPropVariant(UInt64 value) { vt = VT_UI8; wReserved1 = 0; uhVal.QuadPart = value; }
+ CPropVariant(const FILETIME &value) { vt = VT_FILETIME; wReserved1 = 0; filetime = value; }
+
+ CPropVariant& operator=(const CPropVariant &varSrc);
+ CPropVariant& operator=(const PROPVARIANT &varSrc);
+ 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();
+ void InternalCopy(const PROPVARIANT *pSrc);
+
+ int Compare(const CPropVariant &a1);
+};
+
+}}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/PropVariantConversions.cpp b/src/libs/7zip/win/CPP/Windows/PropVariantConversions.cpp
new file mode 100644
index 000000000..2d8456cd6
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/PropVariantConversions.cpp
@@ -0,0 +1,105 @@
+// 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
new file mode 100644
index 000000000..3de4dedb3
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/PropVariantConversions.h
@@ -0,0 +1,14 @@
+// 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/PropVariantUtils.cpp b/src/libs/7zip/win/CPP/Windows/PropVariantUtils.cpp
new file mode 100644
index 000000000..0a9cfab7f
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/PropVariantUtils.cpp
@@ -0,0 +1,78 @@
+// PropVariantUtils.cpp
+
+#include "StdAfx.h"
+
+#include "PropVariantUtils.h"
+#include "Common/StringConvert.h"
+#include "Common/IntToString.h"
+
+using namespace NWindows;
+
+static AString GetHex(UInt32 v)
+{
+ char sz[32] = { '0', 'x' };
+ ConvertUInt64ToString(v, sz + 2, 16);
+ return sz;
+}
+
+void StringToProp(const AString &s, NCOM::CPropVariant &prop)
+{
+ prop = MultiByteToUnicodeString(s);
+}
+
+void PairToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 value, NCOM::CPropVariant &prop)
+{
+ AString s;
+ for (unsigned i = 0; i < num; i++)
+ {
+ const CUInt32PCharPair &p = pairs[i];
+ if (p.Value == value)
+ s = p.Name;
+ }
+ if (s.IsEmpty())
+ s = GetHex(value);
+ StringToProp(s, prop);
+}
+
+AString TypeToString(const char *table[], unsigned num, UInt32 value)
+{
+ if (value < num)
+ return table[value];
+ return GetHex(value);
+}
+
+void TypeToProp(const char *table[], unsigned num, UInt32 value, NCOM::CPropVariant &prop)
+{
+ StringToProp(TypeToString(table, num, value), prop);
+}
+
+
+AString FlagsToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags)
+{
+ AString s;
+ for (unsigned i = 0; i < num; i++)
+ {
+ const CUInt32PCharPair &p = pairs[i];
+ UInt32 flag = (UInt32)1 << (unsigned)p.Value;
+ if ((flags & flag) != 0)
+ {
+ if (!s.IsEmpty())
+ s += ' ';
+ s += p.Name;
+ }
+ flags &= ~flag;
+ }
+ if (flags != 0)
+ {
+ if (!s.IsEmpty())
+ s += ' ';
+ s += GetHex(flags);
+ }
+ return s;
+}
+
+void FlagsToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags, NCOM::CPropVariant &prop)
+{
+ StringToProp(FlagsToString(pairs, num, flags), prop);
+}
+
diff --git a/src/libs/7zip/win/CPP/Windows/PropVariantUtils.h b/src/libs/7zip/win/CPP/Windows/PropVariantUtils.h
new file mode 100644
index 000000000..5aaf65cb9
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/PropVariantUtils.h
@@ -0,0 +1,28 @@
+// Windows/PropVariantUtils.h
+
+#ifndef __PROP_VARIANT_UTILS_H
+#define __PROP_VARIANT_UTILS_H
+
+#include "Common/MyString.h"
+#include "PropVariant.h"
+
+struct CUInt32PCharPair
+{
+ UInt32 Value;
+ const char *Name;
+};
+
+void StringToProp(const AString &s, NWindows::NCOM::CPropVariant &prop);
+void PairToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 value, NWindows::NCOM::CPropVariant &prop);
+
+AString FlagsToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags);
+void FlagsToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags, NWindows::NCOM::CPropVariant &prop);
+
+AString TypeToString(const char *table[], unsigned num, UInt32 value);
+void TypeToProp(const char *table[], unsigned num, UInt32 value, NWindows::NCOM::CPropVariant &prop);
+
+#define PAIR_TO_PROP(pairs, value, prop) PairToProp(pairs, sizeof(pairs) / sizeof(pairs[0]), value, prop)
+#define FLAGS_TO_PROP(pairs, value, prop) FlagsToProp(pairs, sizeof(pairs) / sizeof(pairs[0]), value, prop)
+#define TYPE_TO_PROP(table, value, prop) TypeToProp(table, sizeof(table) / sizeof(table[0]), value, prop)
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/Registry.cpp b/src/libs/7zip/win/CPP/Windows/Registry.cpp
new file mode 100644
index 000000000..8b25375d9
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Registry.cpp
@@ -0,0 +1,369 @@
+// 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
new file mode 100644
index 000000000..f0561e688
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Registry.h
@@ -0,0 +1,85 @@
+// 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/ResourceString.cpp b/src/libs/7zip/win/CPP/Windows/ResourceString.cpp
new file mode 100644
index 000000000..781f03b33
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/ResourceString.cpp
@@ -0,0 +1,64 @@
+// Windows/ResourceString.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/ResourceString.h"
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+
+extern HINSTANCE g_hInstance;
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+
+CSysString MyLoadString(HINSTANCE hInstance, UINT resourceID)
+{
+ CSysString s;
+ int size = 256;
+ int len;
+ do
+ {
+ size += 256;
+ len = ::LoadString(hInstance, resourceID, s.GetBuffer(size - 1), size);
+ }
+ while (size - len <= 1);
+ s.ReleaseBuffer();
+ return s;
+}
+
+CSysString MyLoadString(UINT resourceID)
+{
+ return MyLoadString(g_hInstance, resourceID);
+}
+
+#ifndef _UNICODE
+UString MyLoadStringW(HINSTANCE hInstance, UINT resourceID)
+{
+ if (g_IsNT)
+ {
+ UString s;
+ int size = 256;
+ int len;
+ do
+ {
+ size += 256;
+ len = ::LoadStringW(hInstance, resourceID, s.GetBuffer(size - 1), size);
+ }
+ while (size - len <= 1);
+ s.ReleaseBuffer();
+ return s;
+ }
+ return GetUnicodeString(MyLoadString(hInstance, resourceID));
+}
+
+UString MyLoadStringW(UINT resourceID)
+{
+ return MyLoadStringW(g_hInstance, resourceID);
+}
+
+#endif
+
+}
diff --git a/src/libs/7zip/win/CPP/Windows/ResourceString.h b/src/libs/7zip/win/CPP/Windows/ResourceString.h
new file mode 100644
index 000000000..ac9c5cd5d
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/ResourceString.h
@@ -0,0 +1,22 @@
+// Windows/ResourceString.h
+
+#ifndef __WINDOWS_RESOURCESTRING_H
+#define __WINDOWS_RESOURCESTRING_H
+
+#include "Common/MyString.h"
+
+namespace NWindows {
+
+CSysString MyLoadString(HINSTANCE hInstance, UINT resourceID);
+CSysString MyLoadString(UINT resourceID);
+#ifdef _UNICODE
+inline UString MyLoadStringW(HINSTANCE hInstance, UINT resourceID) { return MyLoadString(hInstance, resourceID); }
+inline UString MyLoadStringW(UINT resourceID) { return MyLoadString(resourceID); }
+#else
+UString MyLoadStringW(HINSTANCE hInstance, UINT resourceID);
+UString MyLoadStringW(UINT resourceID);
+#endif
+
+}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/Security.cpp b/src/libs/7zip/win/CPP/Windows/Security.cpp
new file mode 100644
index 000000000..6f5bcad35
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Security.cpp
@@ -0,0 +1,179 @@
+// Windows/Security.cpp
+
+#include "StdAfx.h"
+
+#include "Security.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/Security.h b/src/libs/7zip/win/CPP/Windows/Security.h
new file mode 100644
index 000000000..ba66de445
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Security.h
@@ -0,0 +1,167 @@
+// Windows/Security.h
+
+#ifndef __WINDOWS_SECURITY_H
+#define __WINDOWS_SECURITY_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/Shell.cpp b/src/libs/7zip/win/CPP/Windows/Shell.cpp
new file mode 100644
index 000000000..010449fb4
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Shell.cpp
@@ -0,0 +1,335 @@
+// Windows/Shell.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyCom.h"
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+
+#include "Windows/COM.h"
+#include "Windows/Shell.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NShell {
+
+#ifndef UNDER_CE
+
+// SHGetMalloc is unsupported in Windows Mobile?
+
+void CItemIDList::Free()
+{
+ if (m_Object == NULL)
+ return;
+ CMyComPtr<IMalloc> shellMalloc;
+ if (::SHGetMalloc(&shellMalloc) != NOERROR)
+ throw 41099;
+ shellMalloc->Free(m_Object);
+ m_Object = NULL;
+}
+
+/*
+CItemIDList::(LPCITEMIDLIST itemIDList): m_Object(NULL)
+ { *this = itemIDList; }
+CItemIDList::(const CItemIDList& itemIDList): m_Object(NULL)
+ { *this = itemIDList; }
+
+CItemIDList& CItemIDList::operator=(LPCITEMIDLIST object)
+{
+ Free();
+ if (object != 0)
+ {
+ UINT32 size = GetSize(object);
+ m_Object = (LPITEMIDLIST)CoTaskMemAlloc(size);
+ if (m_Object != NULL)
+ MoveMemory(m_Object, object, size);
+ }
+ return *this;
+}
+
+CItemIDList& CItemIDList::operator=(const CItemIDList &object)
+{
+ Free();
+ if (object.m_Object != NULL)
+ {
+ UINT32 size = GetSize(object.m_Object);
+ m_Object = (LPITEMIDLIST)CoTaskMemAlloc(size);
+ if (m_Object != NULL)
+ MoveMemory(m_Object, object.m_Object, size);
+ }
+ return *this;
+}
+*/
+
+/////////////////////////////
+// CDrop
+
+void CDrop::Attach(HDROP object)
+{
+ Free();
+ m_Object = object;
+ m_Assigned = true;
+}
+
+void CDrop::Free()
+{
+ if (m_MustBeFinished && m_Assigned)
+ Finish();
+ m_Assigned = false;
+}
+
+UINT CDrop::QueryCountOfFiles()
+{
+ return QueryFile(0xFFFFFFFF, (LPTSTR)NULL, 0);
+}
+
+UString CDrop::QueryFileName(UINT fileIndex)
+{
+ UString fileName;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ AString fileNameA;
+ UINT bufferSize = QueryFile(fileIndex, (LPTSTR)NULL, 0);
+ QueryFile(fileIndex, fileNameA.GetBuffer(bufferSize + 2), bufferSize + 1);
+ fileNameA.ReleaseBuffer();
+ fileName = GetUnicodeString(fileNameA);
+ }
+ else
+ #endif
+ {
+ UINT bufferSize = QueryFile(fileIndex, (LPWSTR)NULL, 0);
+ QueryFile(fileIndex, fileName.GetBuffer(bufferSize + 2), bufferSize + 1);
+ fileName.ReleaseBuffer();
+ }
+ return fileName;
+}
+
+void CDrop::QueryFileNames(UStringVector &fileNames)
+{
+ fileNames.Clear();
+ UINT numFiles = QueryCountOfFiles();
+ fileNames.Reserve(numFiles);
+ for (UINT i = 0; i < numFiles; i++)
+ fileNames.Add(QueryFileName(i));
+}
+
+
+bool GetPathFromIDList(LPCITEMIDLIST itemIDList, CSysString &path)
+{
+ bool result = BOOLToBool(::SHGetPathFromIDList(itemIDList, path.GetBuffer(MAX_PATH * 2)));
+ path.ReleaseBuffer();
+ return result;
+}
+
+#endif
+
+#ifdef UNDER_CE
+
+bool BrowseForFolder(LPBROWSEINFO, CSysString)
+{
+ return false;
+}
+
+bool BrowseForFolder(HWND, LPCTSTR, UINT, LPCTSTR, CSysString &)
+{
+ return false;
+}
+
+bool BrowseForFolder(HWND owner, LPCTSTR title,
+ LPCTSTR initialFolder, CSysString &resultPath)
+{
+ /*
+ // SHBrowseForFolder doesn't work before CE 6.0 ?
+ if (GetProcAddress(LoadLibrary(L"ceshell.dll", L"SHBrowseForFolder") == 0)
+ MessageBoxW(0, L"no", L"", 0);
+ else
+ MessageBoxW(0, L"yes", L"", 0);
+ */
+ /*
+ UString s = L"all files";
+ s += L" (*.*)";
+ return MyGetOpenFileName(owner, title, initialFolder, s, resultPath, true);
+ */
+ return false;
+}
+
+#else
+
+bool BrowseForFolder(LPBROWSEINFO browseInfo, CSysString &resultPath)
+{
+ NWindows::NCOM::CComInitializer comInitializer;
+ LPITEMIDLIST itemIDList = ::SHBrowseForFolder(browseInfo);
+ if (itemIDList == NULL)
+ return false;
+ CItemIDList itemIDListHolder;
+ itemIDListHolder.Attach(itemIDList);
+ return GetPathFromIDList(itemIDList, resultPath);
+}
+
+
+int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM /* lp */, LPARAM data)
+{
+ #ifndef UNDER_CE
+ switch(uMsg)
+ {
+ case BFFM_INITIALIZED:
+ {
+ SendMessage(hwnd, BFFM_SETSELECTION, TRUE, data);
+ break;
+ }
+ /*
+ case BFFM_SELCHANGED:
+ {
+ TCHAR dir[MAX_PATH];
+ if (::SHGetPathFromIDList((LPITEMIDLIST) lp , dir))
+ SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)dir);
+ else
+ SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)TEXT(""));
+ break;
+ }
+ */
+ default:
+ break;
+ }
+ #endif
+ return 0;
+}
+
+
+bool BrowseForFolder(HWND owner, LPCTSTR title, UINT ulFlags,
+ LPCTSTR initialFolder, CSysString &resultPath)
+{
+ CSysString displayName;
+ BROWSEINFO browseInfo;
+ browseInfo.hwndOwner = owner;
+ browseInfo.pidlRoot = NULL;
+
+ // there are Unicode/astring problems in WinCE SDK!!!
+ #ifdef UNDER_CE
+ browseInfo.pszDisplayName = (LPSTR)displayName.GetBuffer(MAX_PATH);
+ browseInfo.lpszTitle = (LPCSTR)title;
+ #else
+ browseInfo.pszDisplayName = displayName.GetBuffer(MAX_PATH);
+ browseInfo.lpszTitle = title;
+ #endif
+ browseInfo.ulFlags = ulFlags;
+ browseInfo.lpfn = (initialFolder != NULL) ? BrowseCallbackProc : NULL;
+ browseInfo.lParam = (LPARAM)initialFolder;
+ return BrowseForFolder(&browseInfo, resultPath);
+}
+
+bool BrowseForFolder(HWND owner, LPCTSTR title,
+ LPCTSTR initialFolder, CSysString &resultPath)
+{
+ return BrowseForFolder(owner, title,
+ #ifndef UNDER_CE
+ BIF_NEWDIALOGSTYLE |
+ #endif
+ BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT, initialFolder, resultPath);
+ // BIF_STATUSTEXT; BIF_USENEWUI (Version 5.0)
+}
+
+#ifndef _UNICODE
+
+typedef BOOL (WINAPI * SHGetPathFromIDListWP)(LPCITEMIDLIST pidl, LPWSTR pszPath);
+
+bool GetPathFromIDList(LPCITEMIDLIST itemIDList, UString &path)
+{
+ path.Empty();
+ SHGetPathFromIDListWP shGetPathFromIDListW = (SHGetPathFromIDListWP)
+ ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHGetPathFromIDListW");
+ if (shGetPathFromIDListW == 0)
+ return false;
+ bool result = BOOLToBool(shGetPathFromIDListW(itemIDList, path.GetBuffer(MAX_PATH * 2)));
+ path.ReleaseBuffer();
+ return result;
+}
+
+typedef LPITEMIDLIST (WINAPI * SHBrowseForFolderWP)(LPBROWSEINFOW lpbi);
+
+bool BrowseForFolder(LPBROWSEINFOW browseInfo, UString &resultPath)
+{
+ NWindows::NCOM::CComInitializer comInitializer;
+ SHBrowseForFolderWP shBrowseForFolderW = (SHBrowseForFolderWP)
+ ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHBrowseForFolderW");
+ if (shBrowseForFolderW == 0)
+ return false;
+ LPITEMIDLIST itemIDList = shBrowseForFolderW(browseInfo);
+ if (itemIDList == NULL)
+ return false;
+ CItemIDList itemIDListHolder;
+ itemIDListHolder.Attach(itemIDList);
+ return GetPathFromIDList(itemIDList, resultPath);
+}
+
+
+int CALLBACK BrowseCallbackProc2(HWND hwnd, UINT uMsg, LPARAM /* lp */, LPARAM data)
+{
+ switch(uMsg)
+ {
+ case BFFM_INITIALIZED:
+ {
+ SendMessageW(hwnd, BFFM_SETSELECTIONW, TRUE, data);
+ break;
+ }
+ /*
+ case BFFM_SELCHANGED:
+ {
+ wchar_t dir[MAX_PATH * 2];
+
+ if (shGetPathFromIDListW((LPITEMIDLIST)lp , dir))
+ SendMessageW(hwnd, BFFM_SETSTATUSTEXTW, 0, (LPARAM)dir);
+ else
+ SendMessageW(hwnd, BFFM_SETSTATUSTEXTW, 0, (LPARAM)L"");
+ break;
+ }
+ */
+ default:
+ break;
+ }
+ return 0;
+}
+
+
+static bool BrowseForFolder(HWND owner, LPCWSTR title, UINT ulFlags,
+ LPCWSTR initialFolder, UString &resultPath)
+{
+ UString displayName;
+ BROWSEINFOW browseInfo;
+ browseInfo.hwndOwner = owner;
+ browseInfo.pidlRoot = NULL;
+ browseInfo.pszDisplayName = displayName.GetBuffer(MAX_PATH);
+ browseInfo.lpszTitle = title;
+ browseInfo.ulFlags = ulFlags;
+ browseInfo.lpfn = (initialFolder != NULL) ? BrowseCallbackProc2 : NULL;
+ browseInfo.lParam = (LPARAM)initialFolder;
+ return BrowseForFolder(&browseInfo, resultPath);
+}
+
+bool BrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR initialFolder, UString &resultPath)
+{
+ if (g_IsNT)
+ return BrowseForFolder(owner, title,
+ BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS
+ // | BIF_STATUSTEXT // This flag is not supported when BIF_NEWDIALOGSTYLE is specified.
+ , initialFolder, resultPath);
+ // BIF_STATUSTEXT; BIF_USENEWUI (Version 5.0)
+ CSysString s;
+ bool res = BrowseForFolder(owner, GetSystemString(title),
+ BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS
+ // | BIF_STATUSTEXT // This flag is not supported when BIF_NEWDIALOGSTYLE is specified.
+ , GetSystemString(initialFolder), s);
+ resultPath = GetUnicodeString(s);
+ return res;
+}
+
+#endif
+
+#endif
+
+}}
diff --git a/src/libs/7zip/win/CPP/Windows/Shell.h b/src/libs/7zip/win/CPP/Windows/Shell.h
new file mode 100644
index 000000000..d2b39acfe
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Shell.h
@@ -0,0 +1,93 @@
+// Windows/Shell.h
+
+#ifndef __WINDOWS_SHELL_H
+#define __WINDOWS_SHELL_H
+
+#include <windows.h>
+#include <shlobj.h>
+
+#include "Common/MyString.h"
+#include "Windows/Defs.h"
+
+namespace NWindows{
+namespace NShell{
+
+/////////////////////////
+// CItemIDList
+#ifndef UNDER_CE
+
+class CItemIDList
+{
+ LPITEMIDLIST m_Object;
+public:
+ CItemIDList(): m_Object(NULL) {}
+ // CItemIDList(LPCITEMIDLIST itemIDList);
+ // CItemIDList(const CItemIDList& itemIDList);
+ ~CItemIDList() { Free(); }
+ void Free();
+ void Attach(LPITEMIDLIST object)
+ {
+ Free();
+ m_Object = object;
+ }
+ LPITEMIDLIST Detach()
+ {
+ LPITEMIDLIST object = m_Object;
+ m_Object = NULL;
+ return object;
+ }
+ operator LPITEMIDLIST() { return m_Object;}
+ operator LPCITEMIDLIST() const { return m_Object;}
+ LPITEMIDLIST* operator&() { return &m_Object; }
+ LPITEMIDLIST operator->() { return m_Object; }
+
+ // CItemIDList& operator=(LPCITEMIDLIST object);
+ // CItemIDList& operator=(const CItemIDList &object);
+};
+
+/////////////////////////////
+// CDrop
+
+class CDrop
+{
+ HDROP m_Object;
+ bool m_MustBeFinished;
+ bool m_Assigned;
+ void Free();
+public:
+ CDrop(bool mustBeFinished) : m_MustBeFinished(mustBeFinished), m_Assigned(false) {}
+ ~CDrop() { Free(); }
+
+ void Attach(HDROP object);
+ operator HDROP() { return m_Object;}
+ bool QueryPoint(LPPOINT point)
+ { return BOOLToBool(::DragQueryPoint(m_Object, point)); }
+ void Finish() { ::DragFinish(m_Object); }
+ UINT QueryFile(UINT fileIndex, LPTSTR fileName, UINT fileNameSize)
+ { return ::DragQueryFile(m_Object, fileIndex, fileName, fileNameSize); }
+ #ifndef _UNICODE
+ UINT QueryFile(UINT fileIndex, LPWSTR fileName, UINT fileNameSize)
+ { return ::DragQueryFileW(m_Object, fileIndex, fileName, fileNameSize); }
+ #endif
+ UINT QueryCountOfFiles();
+ UString QueryFileName(UINT fileIndex);
+ void QueryFileNames(UStringVector &fileNames);
+};
+
+#endif
+
+/////////////////////////////
+// Functions
+
+bool GetPathFromIDList(LPCITEMIDLIST itemIDList, CSysString &path);
+bool BrowseForFolder(LPBROWSEINFO lpbi, CSysString &resultPath);
+bool BrowseForFolder(HWND owner, LPCTSTR title, LPCTSTR initialFolder, CSysString &resultPath);
+
+#ifndef _UNICODE
+bool GetPathFromIDList(LPCITEMIDLIST itemIDList, UString &path);
+bool BrowseForFolder(LPBROWSEINFO lpbi, UString &resultPath);
+bool BrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR initialFolder, UString &resultPath);
+#endif
+}}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/StdAfx.h b/src/libs/7zip/win/CPP/Windows/StdAfx.h
new file mode 100644
index 000000000..8b383c5ba
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/StdAfx.h
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../Common/MyWindows.h"
+#include "../Common/NewHandler.h"
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/Synchronization.cpp b/src/libs/7zip/win/CPP/Windows/Synchronization.cpp
new file mode 100644
index 000000000..5f86d1eb1
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Synchronization.cpp
@@ -0,0 +1,10 @@
+// Windows/Synchronization.cpp
+
+#include "StdAfx.h"
+
+#include "Synchronization.h"
+
+namespace NWindows {
+namespace NSynchronization {
+
+}}
diff --git a/src/libs/7zip/win/CPP/Windows/Synchronization.h b/src/libs/7zip/win/CPP/Windows/Synchronization.h
new file mode 100644
index 000000000..dc695f6f3
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Synchronization.h
@@ -0,0 +1,164 @@
+// Windows/Synchronization.h
+
+#ifndef __WINDOWS_SYNCHRONIZATION_H
+#define __WINDOWS_SYNCHRONIZATION_H
+
+#include "../../C/Threads.h"
+
+#include "Defs.h"
+
+#ifdef _WIN32
+#include "Handle.h"
+#endif
+
+namespace NWindows {
+namespace NSynchronization {
+
+class CBaseEvent
+{
+protected:
+ ::CEvent _object;
+public:
+ bool IsCreated() { return Event_IsCreated(&_object) != 0; }
+ operator HANDLE() { return _object; }
+ CBaseEvent() { Event_Construct(&_object); }
+ ~CBaseEvent() { Close(); }
+ WRes Close() { return Event_Close(&_object); }
+ #ifdef _WIN32
+ WRes Create(bool manualReset, bool initiallyOwn, LPCTSTR name = NULL, LPSECURITY_ATTRIBUTES sa = NULL)
+ {
+ _object = ::CreateEvent(sa, BoolToBOOL(manualReset), BoolToBOOL(initiallyOwn), name);
+ if (name == NULL && _object != 0)
+ return 0;
+ return ::GetLastError();
+ }
+ WRes Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
+ {
+ _object = ::OpenEvent(desiredAccess, BoolToBOOL(inheritHandle), name);
+ if (_object != 0)
+ return 0;
+ return ::GetLastError();
+ }
+ #endif
+
+ WRes Set() { return Event_Set(&_object); }
+ // bool Pulse() { return BOOLToBool(::PulseEvent(_handle)); }
+ WRes Reset() { return Event_Reset(&_object); }
+ WRes Lock() { return Event_Wait(&_object); }
+};
+
+class CManualResetEvent: public CBaseEvent
+{
+public:
+ WRes Create(bool initiallyOwn = false)
+ {
+ return ManualResetEvent_Create(&_object, initiallyOwn ? 1: 0);
+ }
+ WRes CreateIfNotCreated()
+ {
+ if (IsCreated())
+ return 0;
+ return ManualResetEvent_CreateNotSignaled(&_object);
+ }
+ #ifdef _WIN32
+ WRes CreateWithName(bool initiallyOwn, LPCTSTR name)
+ {
+ return CBaseEvent::Create(true, initiallyOwn, name);
+ }
+ #endif
+};
+
+class CAutoResetEvent: public CBaseEvent
+{
+public:
+ WRes Create()
+ {
+ return AutoResetEvent_CreateNotSignaled(&_object);
+ }
+ WRes CreateIfNotCreated()
+ {
+ if (IsCreated())
+ return 0;
+ return AutoResetEvent_CreateNotSignaled(&_object);
+ }
+};
+
+#ifdef _WIN32
+class CObject: public CHandle
+{
+public:
+ WRes Lock(DWORD timeoutInterval = INFINITE)
+ { return (::WaitForSingleObject(_handle, timeoutInterval) == WAIT_OBJECT_0 ? 0 : ::GetLastError()); }
+};
+class CMutex: public CObject
+{
+public:
+ WRes Create(bool initiallyOwn, LPCTSTR name = NULL, LPSECURITY_ATTRIBUTES sa = NULL)
+ {
+ _handle = ::CreateMutex(sa, BoolToBOOL(initiallyOwn), name);
+ if (name == NULL && _handle != 0)
+ return 0;
+ return ::GetLastError();
+ }
+ #ifndef UNDER_CE
+ WRes Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
+ {
+ _handle = ::OpenMutex(desiredAccess, BoolToBOOL(inheritHandle), name);
+ if (_handle != 0)
+ return 0;
+ return ::GetLastError();
+ }
+ #endif
+ WRes Release()
+ {
+ return ::ReleaseMutex(_handle) ? 0 : ::GetLastError();
+ }
+};
+class CMutexLock
+{
+ CMutex *_object;
+public:
+ CMutexLock(CMutex &object): _object(&object) { _object->Lock(); }
+ ~CMutexLock() { _object->Release(); }
+};
+#endif
+
+class CSemaphore
+{
+ ::CSemaphore _object;
+public:
+ CSemaphore() { Semaphore_Construct(&_object); }
+ ~CSemaphore() { Close(); }
+ WRes Close() { return Semaphore_Close(&_object); }
+ operator HANDLE() { return _object; }
+ WRes Create(UInt32 initiallyCount, UInt32 maxCount)
+ {
+ return Semaphore_Create(&_object, initiallyCount, maxCount);
+ }
+ WRes Release() { return Semaphore_Release1(&_object); }
+ WRes Release(UInt32 releaseCount) { return Semaphore_ReleaseN(&_object, releaseCount); }
+ WRes Lock() { return Semaphore_Wait(&_object); }
+};
+
+class CCriticalSection
+{
+ ::CCriticalSection _object;
+public:
+ CCriticalSection() { CriticalSection_Init(&_object); }
+ ~CCriticalSection() { CriticalSection_Delete(&_object); }
+ void Enter() { CriticalSection_Enter(&_object); }
+ void Leave() { CriticalSection_Leave(&_object); }
+};
+
+class CCriticalSectionLock
+{
+ CCriticalSection *_object;
+ void Unlock() { _object->Leave(); }
+public:
+ CCriticalSectionLock(CCriticalSection &object): _object(&object) {_object->Enter(); }
+ ~CCriticalSectionLock() { Unlock(); }
+};
+
+}}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/System.cpp b/src/libs/7zip/win/CPP/Windows/System.cpp
new file mode 100644
index 000000000..4bc8d2a3f
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/System.cpp
@@ -0,0 +1,72 @@
+// Windows/System.cpp
+
+#include "StdAfx.h"
+
+#include "../Common/Defs.h"
+
+#include "System.h"
+
+namespace NWindows {
+namespace NSystem {
+
+UInt32 GetNumberOfProcessors()
+{
+ SYSTEM_INFO systemInfo;
+ GetSystemInfo(&systemInfo);
+ return (UInt32)systemInfo.dwNumberOfProcessors;
+}
+
+#ifndef UNDER_CE
+
+#if !defined(_WIN64) && defined(__GNUC__)
+
+typedef struct _MY_MEMORYSTATUSEX {
+ DWORD dwLength;
+ DWORD dwMemoryLoad;
+ DWORDLONG ullTotalPhys;
+ DWORDLONG ullAvailPhys;
+ DWORDLONG ullTotalPageFile;
+ DWORDLONG ullAvailPageFile;
+ DWORDLONG ullTotalVirtual;
+ DWORDLONG ullAvailVirtual;
+ DWORDLONG ullAvailExtendedVirtual;
+} MY_MEMORYSTATUSEX, *MY_LPMEMORYSTATUSEX;
+
+#else
+
+#define MY_MEMORYSTATUSEX MEMORYSTATUSEX
+#define MY_LPMEMORYSTATUSEX LPMEMORYSTATUSEX
+
+#endif
+
+typedef BOOL (WINAPI *GlobalMemoryStatusExP)(MY_LPMEMORYSTATUSEX lpBuffer);
+
+#endif
+
+UInt64 GetRamSize()
+{
+ #ifndef UNDER_CE
+ MY_MEMORYSTATUSEX stat;
+ stat.dwLength = sizeof(stat);
+ #endif
+ #ifdef _WIN64
+ if (!::GlobalMemoryStatusEx(&stat))
+ return 0;
+ return MyMin(stat.ullTotalVirtual, stat.ullTotalPhys);
+ #else
+ #ifndef UNDER_CE
+ GlobalMemoryStatusExP globalMemoryStatusEx = (GlobalMemoryStatusExP)
+ ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")), "GlobalMemoryStatusEx");
+ if (globalMemoryStatusEx != 0 && globalMemoryStatusEx(&stat))
+ return MyMin(stat.ullTotalVirtual, stat.ullTotalPhys);
+ #endif
+ {
+ MEMORYSTATUS stat;
+ stat.dwLength = sizeof(stat);
+ ::GlobalMemoryStatus(&stat);
+ return MyMin(stat.dwTotalVirtual, stat.dwTotalPhys);
+ }
+ #endif
+}
+
+}}
diff --git a/src/libs/7zip/win/CPP/Windows/System.h b/src/libs/7zip/win/CPP/Windows/System.h
new file mode 100644
index 000000000..e0067158f
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/System.h
@@ -0,0 +1,16 @@
+// Windows/System.h
+
+#ifndef __WINDOWS_SYSTEM_H
+#define __WINDOWS_SYSTEM_H
+
+#include "../Common/Types.h"
+
+namespace NWindows {
+namespace NSystem {
+
+UInt32 GetNumberOfProcessors();
+UInt64 GetRamSize();
+
+}}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/Thread.h b/src/libs/7zip/win/CPP/Windows/Thread.h
new file mode 100644
index 000000000..16a509d47
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Thread.h
@@ -0,0 +1,38 @@
+// Windows/Thread.h
+
+#ifndef __WINDOWS_THREAD_H
+#define __WINDOWS_THREAD_H
+
+#include "../../C/Threads.h"
+
+#include "Defs.h"
+
+namespace NWindows {
+
+class CThread
+{
+ ::CThread thread;
+public:
+ CThread() { Thread_Construct(&thread); }
+ ~CThread() { Close(); }
+ bool IsCreated() { return Thread_WasCreated(&thread) != 0; }
+ WRes Close() { return Thread_Close(&thread); }
+ 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; }
+ HANDLE Detach() { HANDLE h = thread; thread = NULL; return h; }
+ DWORD Resume() { return ::ResumeThread(thread); }
+ DWORD Suspend() { return ::SuspendThread(thread); }
+ bool Terminate(DWORD exitCode) { return BOOLToBool(::TerminateThread(thread, exitCode)); }
+ int GetPriority() { return ::GetThreadPriority(thread); }
+ bool SetPriority(int priority) { return BOOLToBool(::SetThreadPriority(thread, priority)); }
+ #endif
+};
+
+}
+
+#endif
diff --git a/src/libs/7zip/win/CPP/Windows/Time.cpp b/src/libs/7zip/win/CPP/Windows/Time.cpp
new file mode 100644
index 000000000..ec9ca47d9
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Time.cpp
@@ -0,0 +1,170 @@
+// Windows/Time.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Defs.h"
+
+#include "Time.h"
+
+namespace NWindows {
+namespace NTime {
+
+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));
+
+bool DosTimeToFileTime(UInt32 dosTime, FILETIME &ft)
+{
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ return BOOLToBool(::DosDateTimeToFileTime((UInt16)(dosTime >> 16), (UInt16)(dosTime & 0xFFFF), &ft));
+ #else
+ ft.dwLowDateTime = 0;
+ ft.dwHighDateTime = 0;
+ UInt64 res;
+ if (!GetSecondsSince1601(kDosTimeStartYear + (dosTime >> 25), (dosTime >> 21) & 0xF, (dosTime >> 16) & 0x1F,
+ (dosTime >> 11) & 0x1F, (dosTime >> 5) & 0x3F, (dosTime & 0x1F) * 2, res))
+ return false;
+ res *= kNumTimeQuantumsInSecond;
+ ft.dwLowDateTime = (UInt32)res;
+ ft.dwHighDateTime = (UInt32)(res >> 32);
+ return true;
+ #endif
+}
+
+static const UInt32 kHighDosTime = 0xFF9FBF7D;
+static const UInt32 kLowDosTime = 0x210000;
+
+#define PERIOD_4 (4 * 365 + 1)
+#define PERIOD_100 (PERIOD_4 * 25 - 1)
+#define PERIOD_400 (PERIOD_100 * 4 + 1)
+
+bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime)
+{
+ #if defined(_WIN32) && !defined(UNDER_CE)
+
+ WORD datePart, timePart;
+ if (!::FileTimeToDosDateTime(&ft, &datePart, &timePart))
+ {
+ dosTime = (ft.dwHighDateTime >= 0x01C00000) ? kHighDosTime : kLowDosTime;
+ return false;
+ }
+ dosTime = (((UInt32)datePart) << 16) + timePart;
+
+ #else
+
+ unsigned year, mon, day, hour, min, sec;
+ UInt64 v64 = ft.dwLowDateTime | ((UInt64)ft.dwHighDateTime << 32);
+ Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ unsigned temp;
+ UInt32 v;
+ v64 += (kNumTimeQuantumsInSecond * 2 - 1);
+ v64 /= kNumTimeQuantumsInSecond;
+ sec = (unsigned)(v64 % 60);
+ v64 /= 60;
+ min = (unsigned)(v64 % 60);
+ v64 /= 60;
+ hour = (unsigned)(v64 % 24);
+ v64 /= 24;
+
+ v = (UInt32)v64;
+
+ year = (unsigned)(kFileTimeStartYear + v / PERIOD_400 * 400);
+ v %= PERIOD_400;
+
+ temp = (unsigned)(v / PERIOD_100);
+ if (temp == 4)
+ temp = 3;
+ year += temp * 100;
+ v -= temp * PERIOD_100;
+
+ temp = v / PERIOD_4;
+ if (temp == 25)
+ temp = 24;
+ year += temp * 4;
+ v -= temp * PERIOD_4;
+
+ temp = v / 365;
+ if (temp == 4)
+ temp = 3;
+ year += temp;
+ v -= temp * 365;
+
+ if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
+ ms[1] = 29;
+ for (mon = 1; mon <= 12; mon++)
+ {
+ unsigned s = ms[mon - 1];
+ if (v < s)
+ break;
+ v -= s;
+ }
+ day = (unsigned)v + 1;
+
+ dosTime = kLowDosTime;
+ if (year < kDosTimeStartYear)
+ return false;
+ year -= kDosTimeStartYear;
+ dosTime = kHighDosTime;
+ if (year >= 128)
+ return false;
+ dosTime = (year << 25) | (mon << 21) | (day << 16) | (hour << 11) | (min << 5) | (sec >> 1);
+ #endif
+ return true;
+}
+
+void UnixTimeToFileTime(UInt32 unixTime, FILETIME &ft)
+{
+ UInt64 v = kUnixTimeStartValue + ((UInt64)unixTime) * kNumTimeQuantumsInSecond;
+ ft.dwLowDateTime = (DWORD)v;
+ ft.dwHighDateTime = (DWORD)(v >> 32);
+}
+
+bool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime)
+{
+ UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
+ if (winTime < kUnixTimeStartValue)
+ {
+ unixTime = 0;
+ return false;
+ }
+ winTime = (winTime - kUnixTimeStartValue) / kNumTimeQuantumsInSecond;
+ if (winTime > 0xFFFFFFFF)
+ {
+ unixTime = 0xFFFFFFFF;
+ return false;
+ }
+ unixTime = (UInt32)winTime;
+ return true;
+}
+
+bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
+ unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds)
+{
+ resSeconds = 0;
+ if (year < kFileTimeStartYear || year >= 10000 || month < 1 || month > 12 ||
+ day < 1 || day > 31 || hour > 23 || min > 59 || sec > 59)
+ return false;
+ UInt32 numYears = year - kFileTimeStartYear;
+ UInt32 numDays = numYears * 365 + numYears / 4 - numYears / 100 + numYears / 400;
+ Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
+ ms[1] = 29;
+ month--;
+ for (unsigned i = 0; i < month; i++)
+ numDays += ms[i];
+ numDays += day - 1;
+ resSeconds = ((UInt64)(numDays * 24 + hour) * 60 + min) * 60 + sec;
+ return true;
+}
+
+void GetCurUtcFileTime(FILETIME &ft)
+{
+ SYSTEMTIME st;
+ GetSystemTime(&st);
+ SystemTimeToFileTime(&st, &ft);
+}
+
+}}
diff --git a/src/libs/7zip/win/CPP/Windows/Time.h b/src/libs/7zip/win/CPP/Windows/Time.h
new file mode 100644
index 000000000..6f510b22b
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Time.h
@@ -0,0 +1,21 @@
+// 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/Window.cpp b/src/libs/7zip/win/CPP/Windows/Window.cpp
new file mode 100644
index 000000000..3ad29e6d7
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Window.cpp
@@ -0,0 +1,169 @@
+// Windows/Window.cpp
+
+#include "StdAfx.h"
+
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+#include "Windows/Window.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+
+#ifndef _UNICODE
+ATOM MyRegisterClass(CONST WNDCLASSW *wndClass)
+{
+ if (g_IsNT)
+ return RegisterClassW(wndClass);
+ WNDCLASSA wndClassA;
+ wndClassA.style = wndClass->style;
+ wndClassA.lpfnWndProc = wndClass->lpfnWndProc;
+ wndClassA.cbClsExtra = wndClass->cbClsExtra;
+ wndClassA.cbWndExtra = wndClass->cbWndExtra;
+ wndClassA.hInstance = wndClass->hInstance;
+ wndClassA.hIcon = wndClass->hIcon;
+ wndClassA.hCursor = wndClass->hCursor;
+ wndClassA.hbrBackground = wndClass->hbrBackground;
+ AString menuName;
+ AString className;
+ if (IS_INTRESOURCE(wndClass->lpszMenuName))
+ wndClassA.lpszMenuName = (LPCSTR)wndClass->lpszMenuName;
+ else
+ {
+ menuName = GetSystemString(wndClass->lpszMenuName);
+ wndClassA.lpszMenuName = menuName;
+ }
+ if (IS_INTRESOURCE(wndClass->lpszClassName))
+ wndClassA.lpszClassName = (LPCSTR)wndClass->lpszClassName;
+ else
+ {
+ className = GetSystemString(wndClass->lpszClassName);
+ wndClassA.lpszClassName = className;
+ }
+ return RegisterClassA(&wndClassA);
+}
+
+bool CWindow::Create(LPCWSTR className,
+ LPCWSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam)
+{
+ if (g_IsNT)
+ {
+ _window = ::CreateWindowW(className, windowName,
+ style, x, y, width, height, parentWindow,
+ idOrHMenu, instance, createParam);
+ return (_window != NULL);
+ }
+ return Create(GetSystemString(className), GetSystemString(windowName),
+ style, x, y, width, height, parentWindow,
+ idOrHMenu, instance, createParam);
+}
+
+bool CWindow::CreateEx(DWORD exStyle, LPCWSTR className,
+ LPCWSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam)
+{
+ if (g_IsNT)
+ {
+ _window = ::CreateWindowExW(exStyle, className, windowName,
+ style, x, y, width, height, parentWindow,
+ idOrHMenu, instance, createParam);
+ return (_window != NULL);
+ }
+ AString classNameA;
+ LPCSTR classNameP;
+ if (IS_INTRESOURCE(className))
+ classNameP = (LPCSTR)className;
+ else
+ {
+ classNameA = GetSystemString(className);
+ classNameP = classNameA;
+ }
+ AString windowNameA;
+ LPCSTR windowNameP;
+ if (IS_INTRESOURCE(windowName))
+ windowNameP = (LPCSTR)windowName;
+ else
+ {
+ windowNameA = GetSystemString(windowName);
+ windowNameP = windowNameA;
+ }
+ return CreateEx(exStyle, classNameP, windowNameP,
+ style, x, y, width, height, parentWindow,
+ idOrHMenu, instance, createParam);
+}
+
+#endif
+
+#ifndef _UNICODE
+bool MySetWindowText(HWND wnd, LPCWSTR s)
+{
+ if (g_IsNT)
+ return BOOLToBool(::SetWindowTextW(wnd, s));
+ return BOOLToBool(::SetWindowTextA(wnd, UnicodeStringToMultiByte(s)));
+}
+#endif
+
+bool CWindow::GetText(CSysString &s)
+{
+ s.Empty();
+ int length = GetTextLength();
+ if (length == 0)
+ return (::GetLastError() == ERROR_SUCCESS);
+ length = GetText(s.GetBuffer(length), length + 1);
+ s.ReleaseBuffer();
+ if (length == 0)
+ return (::GetLastError() != ERROR_SUCCESS);
+ return true;
+}
+
+#ifndef _UNICODE
+bool CWindow::GetText(UString &s)
+{
+ if (g_IsNT)
+ {
+ s.Empty();
+ int length = GetWindowTextLengthW(_window);
+ if (length == 0)
+ return (::GetLastError() == ERROR_SUCCESS);
+ length = GetWindowTextW(_window, s.GetBuffer(length), length + 1);
+ s.ReleaseBuffer();
+ if (length == 0)
+ return (::GetLastError() == ERROR_SUCCESS);
+ return true;
+ }
+ CSysString sysString;
+ bool result = GetText(sysString);
+ s = GetUnicodeString(sysString);
+ return result;
+}
+#endif
+
+
+/*
+bool CWindow::ModifyStyleBase(int styleOffset,
+ DWORD remove, DWORD add, UINT flags)
+{
+ DWORD style = GetWindowLong(styleOffset);
+ DWORD newStyle = (style & ~remove) | add;
+ if (style == newStyle)
+ return false; // it is not good
+
+ SetWindowLong(styleOffset, newStyle);
+ if (flags != 0)
+ {
+ ::SetWindowPos(_window, NULL, 0, 0, 0, 0,
+ SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | flags);
+ }
+ return TRUE;
+}
+*/
+
+}
diff --git a/src/libs/7zip/win/CPP/Windows/Window.h b/src/libs/7zip/win/CPP/Windows/Window.h
new file mode 100644
index 000000000..729b0f24b
--- /dev/null
+++ b/src/libs/7zip/win/CPP/Windows/Window.h
@@ -0,0 +1,261 @@
+// Windows/Window.h
+
+#ifndef __WINDOWS_WINDOW_H
+#define __WINDOWS_WINDOW_H
+
+#include "Defs.h"
+#include "Common/MyString.h"
+
+namespace NWindows {
+
+inline ATOM MyRegisterClass(CONST WNDCLASS *wndClass)
+ { return ::RegisterClass(wndClass); }
+
+#ifndef _UNICODE
+ATOM MyRegisterClass(CONST WNDCLASSW *wndClass);
+#endif
+
+#ifdef _UNICODE
+inline bool MySetWindowText(HWND wnd, LPCWSTR s) { return BOOLToBool(::SetWindowText(wnd, s)); }
+#else
+bool MySetWindowText(HWND wnd, LPCWSTR s);
+#endif
+
+
+#ifdef UNDER_CE
+#define GWLP_USERDATA GWL_USERDATA
+#define GWLP_WNDPROC GWL_WNDPROC
+#define BTNS_BUTTON TBSTYLE_BUTTON
+#define WC_COMBOBOXW L"ComboBox"
+#define DWLP_MSGRESULT DWL_MSGRESULT
+#endif
+
+class CWindow
+{
+private:
+ // bool ModifyStyleBase(int styleOffset, DWORD remove, DWORD add, UINT flags);
+protected:
+ HWND _window;
+public:
+ CWindow(HWND newWindow = NULL): _window(newWindow){};
+ CWindow& operator=(HWND newWindow)
+ {
+ _window = newWindow;
+ return *this;
+ }
+ operator HWND() const { return _window; }
+ void Attach(HWND newWindow) { _window = newWindow; }
+ HWND Detach()
+ {
+ HWND window = _window;
+ _window = NULL;
+ return window;
+ }
+
+ bool Foreground() { return BOOLToBool(::SetForegroundWindow(_window)); }
+
+ HWND GetParent() const { return ::GetParent(_window); }
+ bool GetWindowRect(LPRECT rect) const { return BOOLToBool(::GetWindowRect(_window,rect)); }
+ #ifndef UNDER_CE
+ bool IsZoomed() const { return BOOLToBool(::IsZoomed(_window)); }
+ #endif
+ bool ClientToScreen(LPPOINT point) const { return BOOLToBool(::ClientToScreen(_window, point)); }
+ bool ScreenToClient(LPPOINT point) const { return BOOLToBool(::ScreenToClient(_window, point)); }
+
+ bool CreateEx(DWORD exStyle, LPCTSTR className,
+ LPCTSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam)
+ {
+ _window = ::CreateWindowEx(exStyle, className, windowName,
+ style, x, y, width, height, parentWindow,
+ idOrHMenu, instance, createParam);
+ return (_window != NULL);
+ }
+
+ bool Create(LPCTSTR className,
+ LPCTSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam)
+ {
+ _window = ::CreateWindow(className, windowName,
+ style, x, y, width, height, parentWindow,
+ idOrHMenu, instance, createParam);
+ return (_window != NULL);
+ }
+
+ #ifndef _UNICODE
+ bool Create(LPCWSTR className,
+ LPCWSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam);
+ bool CreateEx(DWORD exStyle, LPCWSTR className,
+ LPCWSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam);
+ #endif
+
+
+ bool Destroy()
+ {
+ if (_window == NULL)
+ return true;
+ bool result = BOOLToBool(::DestroyWindow(_window));
+ if (result)
+ _window = NULL;
+ return result;
+ }
+ bool IsWindow() { return BOOLToBool(::IsWindow(_window)); }
+ bool Move(int x, int y, int width, int height, bool repaint = true)
+ { return BOOLToBool(::MoveWindow(_window, x, y, width, height, BoolToBOOL(repaint))); }
+
+ bool ChangeSubWindowSizeX(HWND hwnd, int xSize)
+ {
+ RECT rect;
+ ::GetWindowRect(hwnd, &rect);
+ POINT p1;
+ p1.x = rect.left;
+ p1.y = rect.top;
+ ScreenToClient(&p1);
+ return BOOLToBool(::MoveWindow(hwnd, p1.x, p1.y, xSize, rect.bottom - rect.top, TRUE));
+ }
+
+ void ScreenToClient(RECT *rect)
+ {
+ POINT p1, p2;
+ p1.x = rect->left;
+ p1.y = rect->top;
+ p2.x = rect->right;
+ p2.y = rect->bottom;
+ ScreenToClient(&p1);
+ ScreenToClient(&p2);
+
+ rect->left = p1.x;
+ rect->top = p1.y;
+ rect->right = p2.x;
+ rect->bottom = p2.y;
+ }
+
+ bool GetClientRect(LPRECT rect) { return BOOLToBool(::GetClientRect(_window, rect)); }
+ bool Show(int cmdShow) { return BOOLToBool(::ShowWindow(_window, cmdShow)); }
+ #ifndef UNDER_CE
+ bool SetPlacement(CONST WINDOWPLACEMENT *placement) { return BOOLToBool(::SetWindowPlacement(_window, placement)); }
+ bool GetPlacement(WINDOWPLACEMENT *placement) { return BOOLToBool(::GetWindowPlacement(_window, placement)); }
+ #endif
+ bool Update() { return BOOLToBool(::UpdateWindow(_window)); }
+ bool InvalidateRect(LPCRECT rect, bool backgroundErase = true)
+ { return BOOLToBool(::InvalidateRect(_window, rect, BoolToBOOL(backgroundErase))); }
+ void SetRedraw(bool redraw = true) { SendMessage(WM_SETREDRAW, BoolToBOOL(redraw), 0); }
+
+ LONG_PTR SetStyle(LONG_PTR style) { return SetLongPtr(GWL_STYLE, style); }
+ LONG_PTR GetStyle() const { return GetLongPtr(GWL_STYLE); }
+ // bool MyIsMaximized() const { return ((GetStyle() & WS_MAXIMIZE) != 0); }
+
+ LONG_PTR SetLong(int index, LONG newLongPtr) { return ::SetWindowLong(_window, index, newLongPtr); }
+ LONG_PTR GetLong(int index) const { return ::GetWindowLong(_window, index); }
+ LONG_PTR SetUserDataLong(LONG newLongPtr) { return SetLong(GWLP_USERDATA, newLongPtr); }
+ LONG_PTR GetUserDataLong() const { return GetLong(GWLP_USERDATA); }
+
+
+ #ifdef UNDER_CE
+
+ LONG_PTR SetLongPtr(int index, LONG_PTR newLongPtr) { return SetLong(index, newLongPtr); }
+ LONG_PTR GetLongPtr(int index) const { return GetLong(index); }
+
+ LONG_PTR SetUserDataLongPtr(LONG_PTR newLongPtr) { return SetUserDataLong(newLongPtr); }
+ LONG_PTR GetUserDataLongPtr() const { return GetUserDataLong(); }
+
+ #else
+
+ LONG_PTR SetLongPtr(int index, LONG_PTR newLongPtr)
+ { return ::SetWindowLongPtr(_window, index,
+ #ifndef _WIN64
+ (LONG)
+ #endif
+ newLongPtr); }
+ #ifndef _UNICODE
+ LONG_PTR SetLongPtrW(int index, LONG_PTR newLongPtr)
+ { return ::SetWindowLongPtrW(_window, index,
+ #ifndef _WIN64
+ (LONG)
+ #endif
+ newLongPtr); }
+ #endif
+
+ LONG_PTR GetLongPtr(int index) const { return ::GetWindowLongPtr(_window, index); }
+ LONG_PTR SetUserDataLongPtr(LONG_PTR newLongPtr) { return SetLongPtr(GWLP_USERDATA, newLongPtr); }
+ LONG_PTR GetUserDataLongPtr() const { return GetLongPtr(GWLP_USERDATA); }
+
+ #endif
+
+ /*
+ bool ModifyStyle(HWND hWnd, DWORD remove, DWORD add, UINT flags = 0)
+ { return ModifyStyleBase(GWL_STYLE, remove, add, flags); }
+ bool ModifyStyleEx(HWND hWnd, DWORD remove, DWORD add, UINT flags = 0)
+ { return ModifyStyleBase(GWL_EXSTYLE, remove, add, flags); }
+ */
+
+ HWND SetFocus() { return ::SetFocus(_window); }
+
+ LRESULT SendMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
+ { return ::SendMessage(_window, message, wParam, lParam) ;}
+ #ifndef _UNICODE
+ LRESULT SendMessageW(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
+ { return ::SendMessageW(_window, message, wParam, lParam) ;}
+ #endif
+
+ bool PostMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
+ { return BOOLToBool(::PostMessage(_window, message, wParam, lParam)) ;}
+ #ifndef _UNICODE
+ LRESULT PostMessageW(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
+ { return ::PostMessageW(_window, message, wParam, lParam) ;}
+ #endif
+
+ bool SetText(LPCTSTR s) { return BOOLToBool(::SetWindowText(_window, s)); }
+ #ifndef _UNICODE
+ bool CWindow::SetText(LPCWSTR s) { return MySetWindowText(_window, s); }
+ #endif
+
+ int GetTextLength() const
+ { return GetWindowTextLength(_window); }
+ UINT GetText(LPTSTR string, int maxCount) const
+ { return GetWindowText(_window, string, maxCount); }
+ bool GetText(CSysString &s);
+ #ifndef _UNICODE
+ /*
+ UINT GetText(LPWSTR string, int maxCount) const
+ { return GetWindowTextW(_window, string, maxCount); }
+ */
+ bool GetText(UString &s);
+ #endif
+
+ bool Enable(bool enable)
+ { return BOOLToBool(::EnableWindow(_window, BoolToBOOL(enable))); }
+
+ bool IsEnabled()
+ { return BOOLToBool(::IsWindowEnabled(_window)); }
+
+ #ifndef UNDER_CE
+ HMENU GetSystemMenu(bool revert)
+ { return ::GetSystemMenu(_window, BoolToBOOL(revert)); }
+ #endif
+
+ UINT_PTR SetTimer(UINT_PTR idEvent, UINT elapse, TIMERPROC timerFunc = 0)
+ { return ::SetTimer(_window, idEvent, elapse, timerFunc); }
+ bool KillTimer(UINT_PTR idEvent)
+ {return BOOLToBool(::KillTimer(_window, idEvent)); }
+
+ HICON SetIcon(WPARAM sizeType, HICON icon) { return (HICON)SendMessage(WM_SETICON, sizeType, (LPARAM)icon); }
+};
+
+#define RECT_SIZE_X(r) ((r).right - (r).left)
+#define RECT_SIZE_Y(r) ((r).bottom - (r).top)
+
+}
+
+#endif
+