Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/Windows')
-rwxr-xr-xCPP/Windows/COM.cpp37
-rwxr-xr-xCPP/Windows/COM.h57
-rwxr-xr-xCPP/Windows/CommonDialog.cpp164
-rwxr-xr-xCPP/Windows/CommonDialog.h17
-rwxr-xr-xCPP/Windows/Console.cpp10
-rwxr-xr-xCPP/Windows/Console.h52
-rwxr-xr-xCPP/Windows/Control/ComboBox.cpp63
-rwxr-xr-xCPP/Windows/Control/ComboBox.h54
-rwxr-xr-xCPP/Windows/Control/Dialog.cpp145
-rwxr-xr-xCPP/Windows/Control/Dialog.h144
-rwxr-xr-xCPP/Windows/Control/Edit.h21
-rwxr-xr-xCPP/Windows/Control/ImageList.cpp11
-rwxr-xr-xCPP/Windows/Control/ImageList.h86
-rwxr-xr-xCPP/Windows/Control/ListView.cpp58
-rwxr-xr-xCPP/Windows/Control/ListView.h138
-rwxr-xr-xCPP/Windows/Control/ProgressBar.h41
-rwxr-xr-xCPP/Windows/Control/PropertyPage.cpp163
-rwxr-xr-xCPP/Windows/Control/PropertyPage.h47
-rwxr-xr-xCPP/Windows/Control/ReBar.h35
-rwxr-xr-xCPP/Windows/Control/Static.h27
-rwxr-xr-xCPP/Windows/Control/StatusBar.h43
-rwxr-xr-xCPP/Windows/Control/StdAfx.h9
-rwxr-xr-xCPP/Windows/Control/ToolBar.h34
-rwxr-xr-xCPP/Windows/Control/Trackbar.h28
-rwxr-xr-xCPP/Windows/Control/Window2.cpp203
-rwxr-xr-xCPP/Windows/Control/Window2.h59
-rwxr-xr-xCPP/Windows/DLL.cpp115
-rwxr-xr-xCPP/Windows/DLL.h54
-rwxr-xr-xCPP/Windows/Defs.h21
-rwxr-xr-xCPP/Windows/Error.cpp50
-rwxr-xr-xCPP/Windows/Error.h33
-rwxr-xr-xCPP/Windows/FileDevice.cpp49
-rwxr-xr-xCPP/Windows/FileDevice.h123
-rwxr-xr-xCPP/Windows/FileDir.cpp835
-rwxr-xr-xCPP/Windows/FileDir.h178
-rwxr-xr-xCPP/Windows/FileFind.cpp408
-rwxr-xr-xCPP/Windows/FileFind.h153
-rwxr-xr-xCPP/Windows/FileIO.cpp305
-rwxr-xr-xCPP/Windows/FileIO.h97
-rwxr-xr-xCPP/Windows/FileMapping.cpp14
-rwxr-xr-xCPP/Windows/FileMapping.h50
-rwxr-xr-xCPP/Windows/FileName.cpp111
-rwxr-xr-xCPP/Windows/FileName.h43
-rwxr-xr-xCPP/Windows/FileSystem.cpp126
-rwxr-xr-xCPP/Windows/FileSystem.h51
-rwxr-xr-xCPP/Windows/Handle.h37
-rwxr-xr-xCPP/Windows/Memory.cpp64
-rwxr-xr-xCPP/Windows/Memory.h45
-rwxr-xr-xCPP/Windows/MemoryLock.cpp78
-rwxr-xr-xCPP/Windows/MemoryLock.h13
-rwxr-xr-xCPP/Windows/Menu.cpp178
-rwxr-xr-xCPP/Windows/Menu.h137
-rwxr-xr-xCPP/Windows/NationalTime.cpp37
-rwxr-xr-xCPP/Windows/NationalTime.h20
-rwxr-xr-xCPP/Windows/Net.cpp380
-rwxr-xr-xCPP/Windows/Net.h87
-rwxr-xr-xCPP/Windows/ProcessMessages.cpp22
-rwxr-xr-xCPP/Windows/ProcessMessages.h14
-rwxr-xr-xCPP/Windows/PropVariant.cpp312
-rwxr-xr-xCPP/Windows/PropVariant.h57
-rwxr-xr-xCPP/Windows/PropVariantConversions.cpp150
-rwxr-xr-xCPP/Windows/PropVariantConversions.h14
-rwxr-xr-xCPP/Windows/Registry.cpp324
-rwxr-xr-xCPP/Windows/Registry.h77
-rwxr-xr-xCPP/Windows/ResourceString.cpp53
-rwxr-xr-xCPP/Windows/ResourceString.h20
-rwxr-xr-xCPP/Windows/Security.cpp181
-rwxr-xr-xCPP/Windows/Security.h168
-rwxr-xr-xCPP/Windows/Shell.cpp292
-rwxr-xr-xCPP/Windows/Shell.h92
-rwxr-xr-xCPP/Windows/StdAfx.h9
-rwxr-xr-xCPP/Windows/Synchronization.cpp17
-rwxr-xr-xCPP/Windows/Synchronization.h133
-rwxr-xr-xCPP/Windows/System.h21
-rwxr-xr-xCPP/Windows/Thread.h51
-rwxr-xr-xCPP/Windows/Time.h66
-rwxr-xr-xCPP/Windows/Window.cpp169
-rwxr-xr-xCPP/Windows/Window.h219
78 files changed, 8099 insertions, 0 deletions
diff --git a/CPP/Windows/COM.cpp b/CPP/Windows/COM.cpp
new file mode 100755
index 00000000..2f9fdcda
--- /dev/null
+++ b/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);
+}
+
+}} \ No newline at end of file
diff --git a/CPP/Windows/COM.h b/CPP/Windows/COM.h
new file mode 100755
index 00000000..80651406
--- /dev/null
+++ b/CPP/Windows/COM.h
@@ -0,0 +1,57 @@
+// Windows/COM.h
+
+#ifndef __WINDOWS_COM_H
+#define __WINDOWS_COM_H
+
+#include "Common/String.h"
+
+namespace NWindows {
+namespace NCOM {
+
+class CComInitializer
+{
+public:
+ CComInitializer() { CoInitialize(NULL);};
+ ~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; }
+};
+
+//////////////////////////////////
+// GUID <--> String Conversions
+UString GUIDToStringW(REFGUID guid);
+AString GUIDToStringA(REFGUID guid);
+#ifdef UNICODE
+ #define GUIDToString GUIDToStringW
+#else
+ #define GUIDToString GUIDToStringA
+#endif // !UNICODE
+
+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 // !UNICODE
+
+
+}}
+
+#endif
diff --git a/CPP/Windows/CommonDialog.cpp b/CPP/Windows/CommonDialog.cpp
new file mode 100755
index 00000000..d0234c54
--- /dev/null
+++ b/CPP/Windows/CommonDialog.cpp
@@ -0,0 +1,164 @@
+// Windows/CommonDialog.cpp
+
+#include "StdAfx.h"
+
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+#include "Common/MyCom.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';
+}
+
+bool MyGetOpenFileName(HWND hwnd, LPCWSTR title, LPCWSTR fullFileName, LPCWSTR s, UString &resPath)
+{
+ 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;
+ 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/CPP/Windows/CommonDialog.h b/CPP/Windows/CommonDialog.h
new file mode 100755
index 00000000..d0149aba
--- /dev/null
+++ b/CPP/Windows/CommonDialog.h
@@ -0,0 +1,17 @@
+// Windows/CommonDialog.h
+
+#ifndef __WINDOWS_COMMONDIALOG_H
+#define __WINDOWS_COMMONDIALOG_H
+
+#include <windows.h>
+
+#include "Common/String.h"
+#include "Windows/Defs.h"
+
+namespace NWindows{
+
+bool MyGetOpenFileName(HWND hwnd, LPCWSTR title, LPCWSTR fullFileName, LPCWSTR s, UString &resPath);
+
+}
+
+#endif
diff --git a/CPP/Windows/Console.cpp b/CPP/Windows/Console.cpp
new file mode 100755
index 00000000..1dffc377
--- /dev/null
+++ b/CPP/Windows/Console.cpp
@@ -0,0 +1,10 @@
+// Windows/Console.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Console.h"
+
+namespace NWindows{
+namespace NConsole{
+
+}} \ No newline at end of file
diff --git a/CPP/Windows/Console.h b/CPP/Windows/Console.h
new file mode 100755
index 00000000..b4e6d35b
--- /dev/null
+++ b/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 \ No newline at end of file
diff --git a/CPP/Windows/Control/ComboBox.cpp b/CPP/Windows/Control/ComboBox.cpp
new file mode 100755
index 00000000..5b1d2651
--- /dev/null
+++ b/CPP/Windows/Control/ComboBox.cpp
@@ -0,0 +1,63 @@
+// Windows/Control/ComboBox.cpp
+
+// #define _UNICODE
+// #define UNICODE
+
+#include "StdAfx.h"
+
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+
+#include "Windows/Control/ComboBox.h"
+#include "Windows/Defs.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NControl {
+
+LRESULT CComboBox::GetLBText(int index, CSysString &s)
+{
+ s.Empty();
+ LRESULT len = GetLBTextLen(index);
+ if (len == CB_ERR)
+ return len;
+ len = GetLBText(index, s.GetBuffer((int)len + 1));
+ s.ReleaseBuffer();
+ return len;
+}
+
+#ifndef _UNICODE
+LRESULT CComboBox::AddString(LPCWSTR s)
+{
+ if (g_IsNT)
+ return SendMessageW(CB_ADDSTRING, 0, (LPARAM)s);
+ return AddString(GetSystemString(s));
+}
+
+LRESULT CComboBox::GetLBText(int index, UString &s)
+{
+ s.Empty();
+ if (g_IsNT)
+ {
+ LRESULT len = SendMessageW(CB_GETLBTEXTLEN, index, 0);
+ if (len == CB_ERR)
+ return len;
+ len = SendMessageW(CB_GETLBTEXT, index, (LPARAM)s.GetBuffer((int)len + 1));
+ s.ReleaseBuffer();
+ return len;
+ }
+ AString sa;
+ LRESULT len = GetLBText(index, sa);
+ if (len == CB_ERR)
+ return len;
+ s = GetUnicodeString(sa);
+ return s.Length();
+}
+#endif
+
+
+}}
diff --git a/CPP/Windows/Control/ComboBox.h b/CPP/Windows/Control/ComboBox.h
new file mode 100755
index 00000000..2fb2302e
--- /dev/null
+++ b/CPP/Windows/Control/ComboBox.h
@@ -0,0 +1,54 @@
+// Windows/Control/ComboBox.h
+
+#ifndef __WINDOWS_CONTROL_COMBOBOX_H
+#define __WINDOWS_CONTROL_COMBOBOX_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+#include <commctrl.h>
+
+namespace NWindows {
+namespace NControl {
+
+class CComboBox: public CWindow
+{
+public:
+ void ResetContent() { SendMessage(CB_RESETCONTENT, 0, 0); }
+ LRESULT AddString(LPCTSTR string) { return SendMessage(CB_ADDSTRING, 0, (LPARAM)string); }
+ #ifndef _UNICODE
+ LRESULT AddString(LPCWSTR string);
+ #endif
+ LRESULT SetCurSel(int index) { return SendMessage(CB_SETCURSEL, index, 0); }
+ int GetCurSel() { return (int)SendMessage(CB_GETCURSEL, 0, 0); }
+ int GetCount() { return (int)SendMessage(CB_GETCOUNT, 0, 0); }
+
+ LRESULT GetLBTextLen(int index) { return SendMessage(CB_GETLBTEXTLEN, index, 0); }
+ LRESULT GetLBText(int index, LPTSTR string) { return SendMessage(CB_GETLBTEXT, index, (LPARAM)string); }
+ LRESULT GetLBText(int index, CSysString &s);
+ #ifndef _UNICODE
+ LRESULT GetLBText(int index, UString &s);
+ #endif
+
+ LRESULT SetItemData(int index, LPARAM lParam)
+ { return SendMessage(CB_SETITEMDATA, index, lParam); }
+ LRESULT GetItemData(int index)
+ { return SendMessage(CB_GETITEMDATA, index, 0); }
+};
+
+class CComboBoxEx: public CWindow
+{
+public:
+ LRESULT DeleteItem(int index)
+ { return SendMessage(CBEM_DELETEITEM, index, 0); }
+ LRESULT InsertItem(COMBOBOXEXITEM *item)
+ { return SendMessage(CBEM_INSERTITEM, 0, (LPARAM)item); }
+ DWORD SetExtendedStyle(DWORD exMask, DWORD exStyle)
+ { return (DWORD)SendMessage(CBEM_SETEXTENDEDSTYLE, exMask, exStyle); }
+ HWND GetEditControl()
+ { return (HWND)SendMessage(CBEM_GETEDITCONTROL, 0, 0); }
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/CPP/Windows/Control/Dialog.cpp b/CPP/Windows/Control/Dialog.cpp
new file mode 100755
index 00000000..64009b79
--- /dev/null
+++ b/CPP/Windows/Control/Dialog.cpp
@@ -0,0 +1,145 @@
+// Windows/Control/Dialog.cpp
+
+#include "StdAfx.h"
+
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+#include "Windows/Control/Dialog.h"
+
+extern HINSTANCE g_hInstance;
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NControl {
+
+static INT_PTR APIENTRY DialogProcedure(HWND dialogHWND, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ CWindow dialogTmp(dialogHWND);
+ if (message == WM_INITDIALOG)
+ dialogTmp.SetUserDataLongPtr(lParam);
+ CDialog *dialog = (CDialog *)(dialogTmp.GetUserDataLongPtr());
+ if (dialog == NULL)
+ return FALSE;
+ if (message == WM_INITDIALOG)
+ dialog->Attach(dialogHWND);
+
+ return BoolToBOOL(dialog->OnMessage(message, wParam, lParam));
+}
+
+bool CDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ return OnInit();
+ case WM_COMMAND:
+ return OnCommand(wParam, lParam);
+ case WM_NOTIFY:
+ return OnNotify((UINT)wParam, (LPNMHDR) lParam);
+ case WM_HELP:
+ {
+ OnHelp((LPHELPINFO)lParam);
+ return true;
+ }
+ case WM_TIMER:
+ {
+ return OnTimer(wParam, lParam);
+ }
+ default:
+ return false;
+ }
+}
+
+bool CDialog::OnCommand(WPARAM wParam, LPARAM lParam)
+{
+ return OnCommand(HIWORD(wParam), LOWORD(wParam), lParam);
+}
+
+bool CDialog::OnCommand(int code, int itemID, LPARAM lParam)
+{
+ if (code == BN_CLICKED)
+ return OnButtonClicked(itemID, (HWND)lParam);
+ return false;
+}
+
+bool CDialog::OnButtonClicked(int buttonID, HWND /* buttonHWND */)
+{
+ switch(buttonID)
+ {
+ case IDOK:
+ OnOK();
+ break;
+ case IDCANCEL:
+ OnCancel();
+ break;
+ case IDHELP:
+ OnHelp();
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+bool CModelessDialog::Create(LPCTSTR templateName, HWND parentWindow)
+{
+ HWND aHWND = CreateDialogParam(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
+ if (aHWND == 0)
+ return false;
+ Attach(aHWND);
+ return true;
+}
+
+INT_PTR CModalDialog::Create(LPCTSTR templateName, HWND parentWindow)
+{
+ return DialogBoxParam(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
+}
+
+#ifndef _UNICODE
+
+bool CModelessDialog::Create(LPCWSTR templateName, HWND parentWindow)
+{
+ HWND aHWND;
+ if (g_IsNT)
+ aHWND = CreateDialogParamW(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
+ else
+ {
+ AString name;
+ LPCSTR templateNameA;
+ if (IS_INTRESOURCE(templateName))
+ templateNameA = (LPCSTR)templateName;
+ else
+ {
+ name = GetSystemString(templateName);
+ templateNameA = name;
+ }
+ aHWND = CreateDialogParamA(g_hInstance, templateNameA, parentWindow, DialogProcedure, (LPARAM)this);
+ }
+ if (aHWND == 0)
+ return false;
+ Attach(aHWND);
+ return true;
+}
+
+INT_PTR CModalDialog::Create(LPCWSTR templateName, HWND parentWindow)
+{
+ if (g_IsNT)
+ return DialogBoxParamW(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
+ AString name;
+ LPCSTR templateNameA;
+ if (IS_INTRESOURCE(templateName))
+ templateNameA = (LPCSTR)templateName;
+ else
+ {
+ name = GetSystemString(templateName);
+ templateNameA = name;
+ }
+ return DialogBoxParamA(g_hInstance, templateNameA, parentWindow, DialogProcedure, (LPARAM)this);
+}
+#endif
+
+}}
diff --git a/CPP/Windows/Control/Dialog.h b/CPP/Windows/Control/Dialog.h
new file mode 100755
index 00000000..f6182c4b
--- /dev/null
+++ b/CPP/Windows/Control/Dialog.h
@@ -0,0 +1,144 @@
+// Windows/Control/Dialog.h
+
+#ifndef __WINDOWS_CONTROL_DIALOG_H
+#define __WINDOWS_CONTROL_DIALOG_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CDialog: public CWindow
+{
+public:
+ CDialog(HWND wndow = NULL): CWindow(wndow){};
+ virtual ~CDialog() {};
+
+ HWND GetItem(int itemID) const
+ { return GetDlgItem(_window, itemID); }
+
+ bool EnableItem(int itemID, bool enable) const
+ { return BOOLToBool(::EnableWindow(GetItem(itemID), BoolToBOOL(enable))); }
+
+ bool ShowItem(int itemID, int cmdShow) const
+ { return BOOLToBool(::ShowWindow(GetItem(itemID), cmdShow)); }
+
+ bool SetItemText(int itemID, LPCTSTR s)
+ { return BOOLToBool(SetDlgItemText(_window, itemID, s)); }
+
+ #ifndef _UNICODE
+ bool SetItemText(int itemID, LPCWSTR s)
+ {
+ CWindow window(GetItem(itemID));
+ return window.SetText(s);
+ }
+ #endif
+
+ UINT GetItemText(int itemID, LPTSTR string, int maxCount)
+ { return GetDlgItemText(_window, itemID, string, maxCount); }
+ #ifndef _UNICODE
+ /*
+ bool GetItemText(int itemID, LPWSTR string, int maxCount)
+ {
+ CWindow window(GetItem(itemID));
+ return window.GetText(string, maxCount);
+ }
+ */
+ #endif
+
+ bool SetItemInt(int itemID, UINT value, bool isSigned)
+ { return BOOLToBool(SetDlgItemInt(_window, itemID, value, BoolToBOOL(isSigned))); }
+ bool GetItemInt(int itemID, bool isSigned, UINT &value)
+ {
+ BOOL result;
+ value = GetDlgItemInt(_window, itemID, &result, BoolToBOOL(isSigned));
+ return BOOLToBool(result);
+ }
+
+ HWND GetNextGroupItem(HWND control, bool previous)
+ { return GetNextDlgGroupItem(_window, control, BoolToBOOL(previous)); }
+ HWND GetNextTabItem(HWND control, bool previous)
+ { return GetNextDlgTabItem(_window, control, BoolToBOOL(previous)); }
+
+ bool MapRect(LPRECT rect)
+ { return BOOLToBool(MapDialogRect(_window, rect)); }
+
+ bool IsMessage(LPMSG message)
+ { return BOOLToBool(IsDialogMessage(_window, message)); }
+
+ LRESULT SendItemMessage(int itemID, UINT message, WPARAM wParam, LPARAM lParam)
+ { return SendDlgItemMessage(_window, itemID, message, wParam, lParam); }
+
+ bool CheckButton(int buttonID, UINT checkState)
+ { return BOOLToBool(CheckDlgButton(_window, buttonID, checkState)); }
+ bool CheckButton(int buttonID, bool checkState)
+ { return CheckButton(buttonID, UINT(checkState ? BST_CHECKED : BST_UNCHECKED)); }
+
+ UINT IsButtonChecked(int buttonID) const
+ { return IsDlgButtonChecked(_window, buttonID); }
+ bool IsButtonCheckedBool(int buttonID) const
+ { return (IsButtonChecked(buttonID) == BST_CHECKED); }
+
+ bool CheckRadioButton(int firstButtonID, int lastButtonID, int checkButtonID)
+ { return BOOLToBool(::CheckRadioButton(_window, firstButtonID, lastButtonID, checkButtonID)); }
+
+ virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+ virtual bool OnInit() { return true; }
+ virtual bool OnCommand(WPARAM wParam, LPARAM lParam);
+ virtual bool OnCommand(int code, int itemID, LPARAM lParam);
+ virtual void OnHelp(LPHELPINFO /* helpInfo */) { OnHelp(); };
+ virtual void OnHelp() {};
+ virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ virtual void OnOK() {};
+ virtual void OnCancel() {};
+ virtual bool OnNotify(UINT /* controlID */, LPNMHDR /* lParam */) { return false; }
+ virtual bool OnTimer(WPARAM /* timerID */, LPARAM /* callback */) { return false; }
+
+ LONG_PTR SetMsgResult(LONG_PTR newLongPtr )
+ { return SetLongPtr(DWLP_MSGRESULT, newLongPtr); }
+ LONG_PTR GetMsgResult() const
+ { return GetLongPtr(DWLP_MSGRESULT); }
+};
+
+class CModelessDialog: public CDialog
+{
+public:
+ bool Create(LPCTSTR templateName, HWND parentWindow);
+ #ifndef _UNICODE
+ bool Create(LPCWSTR templateName, HWND parentWindow);
+ #endif
+ virtual void OnOK() { Destroy(); }
+ virtual void OnCancel() { Destroy(); }
+};
+
+class CModalDialog: public CDialog
+{
+public:
+ INT_PTR Create(LPCTSTR templateName, HWND parentWindow);
+ INT_PTR Create(UINT resID, HWND parentWindow)
+ { return Create(MAKEINTRESOURCEW(resID), parentWindow); }
+ #ifndef _UNICODE
+ INT_PTR Create(LPCWSTR templateName, HWND parentWindow);
+ #endif
+
+ bool End(INT_PTR result)
+ { return BOOLToBool(::EndDialog(_window, result)); }
+ virtual void OnOK() { End(IDOK); }
+ virtual void OnCancel() { End(IDCANCEL); }
+};
+
+class CDialogChildControl: public NWindows::CWindow
+{
+public:
+ int m_ID;
+ void Init(const NWindows::NControl::CDialog &parentDialog, int id)
+ {
+ m_ID = id;
+ Attach(parentDialog.GetItem(id));
+ }
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/CPP/Windows/Control/Edit.h b/CPP/Windows/Control/Edit.h
new file mode 100755
index 00000000..d1af3644
--- /dev/null
+++ b/CPP/Windows/Control/Edit.h
@@ -0,0 +1,21 @@
+// Windows/Control/Edit.h
+
+#ifndef __WINDOWS_CONTROL_EDIT_H
+#define __WINDOWS_CONTROL_EDIT_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CEdit: public CWindow
+{
+public:
+ void SetPasswordChar(WPARAM c)
+ { SendMessage(EM_SETPASSWORDCHAR, c); }
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/CPP/Windows/Control/ImageList.cpp b/CPP/Windows/Control/ImageList.cpp
new file mode 100755
index 00000000..16a46fa4
--- /dev/null
+++ b/CPP/Windows/Control/ImageList.cpp
@@ -0,0 +1,11 @@
+// Windows/Control/ImageList.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Control/ImageList.h"
+
+namespace NWindows {
+namespace NControl {
+
+}}
+
diff --git a/CPP/Windows/Control/ImageList.h b/CPP/Windows/Control/ImageList.h
new file mode 100755
index 00000000..fc8ddfbd
--- /dev/null
+++ b/CPP/Windows/Control/ImageList.h
@@ -0,0 +1,86 @@
+// Windows/Control/ImageList.h
+
+#ifndef __WINDOWS_CONTROL_IMAGELIST_H
+#define __WINDOWS_CONTROL_IMAGELIST_H
+
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CImageList
+{
+ HIMAGELIST m_Object;
+public:
+ operator HIMAGELIST() const {return m_Object; }
+ CImageList(): m_Object(NULL) {}
+ bool Attach(HIMAGELIST imageList)
+ {
+ if(imageList == NULL)
+ return false;
+ m_Object = imageList;
+ return true;
+ }
+
+ HIMAGELIST Detach()
+ {
+ HIMAGELIST imageList = m_Object;
+ m_Object = NULL;
+ return imageList;
+ }
+
+ bool Create(int width, int height, UINT flags, int initialNumber, int grow)
+ {
+ HIMAGELIST a = ImageList_Create(width, height, flags,
+ initialNumber, grow);
+ if(a == NULL)
+ return false;
+ return Attach(a);
+ }
+
+ bool Destroy() // DeleteImageList() in MFC
+ {
+ if (m_Object == NULL)
+ return false;
+ return BOOLToBool(ImageList_Destroy(Detach()));
+ }
+
+ ~CImageList()
+ { Destroy(); }
+
+ int GetImageCount() const
+ { return ImageList_GetImageCount(m_Object); }
+
+ bool GetImageInfo(int index, IMAGEINFO* imageInfo) const
+ { return BOOLToBool(ImageList_GetImageInfo(m_Object, index, imageInfo)); }
+
+ int Add(HBITMAP hbmImage, HBITMAP hbmMask = 0)
+ { return ImageList_Add(m_Object, hbmImage, hbmMask); }
+ int AddMasked(HBITMAP hbmImage, COLORREF mask)
+ { return ImageList_AddMasked(m_Object, hbmImage, mask); }
+ int AddIcon(HICON icon)
+ { return ImageList_AddIcon(m_Object, icon); }
+ int Replace(int index, HICON icon)
+ { return ImageList_ReplaceIcon(m_Object, index, icon); }
+
+ // If index is -1, the function removes all images.
+ bool Remove(int index)
+ { return BOOLToBool(ImageList_Remove(m_Object, index)); }
+ bool RemoveAll()
+ { return BOOLToBool(ImageList_RemoveAll(m_Object)); }
+
+ HICON ExtractIcon(int index)
+ { return ImageList_ExtractIcon(NULL, m_Object, index); }
+ HICON GetIcon(int index, UINT flags)
+ { return ImageList_GetIcon(m_Object, index, flags); }
+
+ bool GetIconSize(int &width, int &height) const
+ { return BOOLToBool(ImageList_GetIconSize(m_Object, &width, &height)); }
+ bool SetIconSize(int width, int height)
+ { return BOOLToBool(ImageList_SetIconSize(m_Object, width, height)); }
+};
+
+}}
+
+#endif
+ \ No newline at end of file
diff --git a/CPP/Windows/Control/ListView.cpp b/CPP/Windows/Control/ListView.cpp
new file mode 100755
index 00000000..b532a7a4
--- /dev/null
+++ b/CPP/Windows/Control/ListView.cpp
@@ -0,0 +1,58 @@
+// Windows/Control/ListView.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Control/ListView.h"
+
+namespace NWindows {
+namespace NControl {
+
+bool CListView::CreateEx(DWORD exStyle, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam)
+{
+ return CWindow::CreateEx(exStyle, WC_LISTVIEW, TEXT(""), style, x, y, width,
+ height, parentWindow, idOrHMenu, instance, createParam);
+}
+
+bool CListView::GetItemParam(int itemIndex, LPARAM &param) const
+{
+ LVITEM item;
+ item.iItem = itemIndex;
+ item.iSubItem = 0;
+ item.mask = LVIF_PARAM;
+ bool aResult = GetItem(&item);
+ param = item.lParam;
+ return aResult;
+}
+
+/*
+int CListView::InsertItem(UINT mask, int item, LPCTSTR itemText,
+ UINT nState, UINT nStateMask, int nImage, LPARAM lParam)
+{
+ LVITEM item;
+ item.mask = nMask;
+ item.iItem = nItem;
+ item.iSubItem = 0;
+ item.pszText = (LPTSTR)itemText;
+ item.state = nState;
+ item.stateMask = nStateMask;
+ item.iImage = nImage;
+ item.lParam = lParam;
+ return InsertItem(&item);
+}
+
+int CListView::InsertItem(int nItem, LPCTSTR itemText)
+{
+ return InsertItem(LVIF_TEXT, nItem, itemText, 0, 0, 0, 0);
+}
+
+int CListView::InsertItem(int nItem, LPCTSTR itemText, int nImage)
+{
+ return InsertItem(LVIF_TEXT | LVIF_IMAGE, nItem, itemText, 0, 0, nImage, 0);
+}
+*/
+
+}}
+
diff --git a/CPP/Windows/Control/ListView.h b/CPP/Windows/Control/ListView.h
new file mode 100755
index 00000000..60b8146e
--- /dev/null
+++ b/CPP/Windows/Control/ListView.h
@@ -0,0 +1,138 @@
+// Windows/Control/ListView.h
+
+#ifndef __WINDOWS_CONTROL_LISTVIEW_H
+#define __WINDOWS_CONTROL_LISTVIEW_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+#include <commctrl.h>
+
+namespace NWindows {
+namespace NControl {
+
+class CListView: public NWindows::CWindow
+{
+public:
+ bool CreateEx(DWORD exStyle, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam);
+
+ bool SetUnicodeFormat(bool fUnicode)
+ { return BOOLToBool(ListView_SetUnicodeFormat(_window, BOOLToBool(fUnicode))); }
+
+ bool DeleteAllItems()
+ { return BOOLToBool(ListView_DeleteAllItems(_window)); }
+ int InsertColumn(int columnIndex, const LVCOLUMN *columnInfo)
+ { return ListView_InsertColumn(_window, columnIndex, columnInfo); }
+ #ifndef _UNICODE
+ int InsertColumn(int columnIndex, const LVCOLUMNW *columnInfo)
+ { return (int)SendMessage(LVM_INSERTCOLUMNW, (WPARAM)columnIndex, (LPARAM)columnInfo); }
+ #endif
+ bool DeleteColumn(int columnIndex)
+ { return BOOLToBool(ListView_DeleteColumn(_window, columnIndex)); }
+
+ int InsertItem(const LVITEM* item)
+ { return ListView_InsertItem(_window, item); }
+ #ifndef _UNICODE
+ int InsertItem(const LV_ITEMW* item)
+ { return (int)SendMessage(LVM_INSERTITEMW, 0, (LPARAM)item); }
+ #endif
+
+ bool SetItem(const LVITEM* item)
+ { return BOOLToBool(ListView_SetItem(_window, item)); }
+ #ifndef _UNICODE
+ bool SetItem(const LV_ITEMW* item)
+ { return BOOLToBool((BOOL)SendMessage(LVM_SETITEMW, 0, (LPARAM)item)); }
+ #endif
+
+ bool DeleteItem(int itemIndex)
+ { return BOOLToBool(ListView_DeleteItem(_window, itemIndex)); }
+
+ UINT GetSelectedCount() const
+ { return ListView_GetSelectedCount(_window); }
+ int GetItemCount() const
+ { return ListView_GetItemCount(_window); }
+
+ INT GetSelectionMark() const
+ { return ListView_GetSelectionMark(_window); }
+
+ void SetItemCount(int numItems)
+ { ListView_SetItemCount(_window, numItems); }
+ void SetItemCountEx(int numItems, DWORD flags)
+ { ListView_SetItemCountEx(_window, numItems, flags); }
+
+ int GetNextItem(int startIndex, UINT flags) const
+ { return ListView_GetNextItem(_window, startIndex, flags); }
+ int GetNextSelectedItem(int startIndex) const
+ { return GetNextItem(startIndex, LVNI_SELECTED); }
+ int GetFocusedItem() const
+ { return GetNextItem(-1, LVNI_FOCUSED); }
+
+ bool GetItem(LVITEM* item) const
+ { return BOOLToBool(ListView_GetItem(_window, item)); }
+ bool GetItemParam(int itemIndex, LPARAM &param) const;
+ void GetItemText(int itemIndex, int aSubItemIndex, LPTSTR aText, int aTextSizeMax) const
+ { ListView_GetItemText(_window, itemIndex, aSubItemIndex, aText, aTextSizeMax); }
+ bool SortItems(PFNLVCOMPARE compareFunction, LPARAM dataParam)
+ { return BOOLToBool(ListView_SortItems(_window, compareFunction, dataParam)); }
+
+ void SetItemState(int index, UINT state, UINT mask)
+ { ListView_SetItemState(_window, index, state, mask); }
+ UINT GetItemState(int index, UINT mask) const
+ { return ListView_GetItemState(_window, index, mask); }
+
+ bool GetColumn(int columnIndex, LVCOLUMN* columnInfo) const
+ { return BOOLToBool(ListView_GetColumn(_window, columnIndex, columnInfo)); }
+
+ HIMAGELIST SetImageList(HIMAGELIST imageList, int imageListType)
+ { return ListView_SetImageList(_window, imageList, imageListType); }
+
+ // version 4.70: NT5 | (NT4 + ie3) | w98 | (w95 + ie3)
+ DWORD GetExtendedListViewStyle()
+ { return ListView_GetExtendedListViewStyle(_window); }
+ void SetExtendedListViewStyle(DWORD exStyle)
+ { ListView_SetExtendedListViewStyle(_window, exStyle); }
+ void SetExtendedListViewStyle(DWORD exMask, DWORD exStyle)
+ { ListView_SetExtendedListViewStyleEx(_window, exMask, exStyle); }
+
+ #ifndef _WIN32_WCE
+ void SetCheckState(UINT index, bool checkState)
+ { ListView_SetCheckState(_window, index, BoolToBOOL(checkState)); }
+ #endif
+ bool GetCheckState(UINT index)
+ { return BOOLToBool(ListView_GetCheckState(_window, index)); }
+
+
+ bool EnsureVisible(int index, bool partialOK)
+ { return BOOLToBool(ListView_EnsureVisible(_window, index, BoolToBOOL(partialOK))); }
+
+ bool GetItemRect(int index, RECT *rect, int code)
+ { return BOOLToBool(ListView_GetItemRect(_window, index, rect, code)); }
+
+ HWND GetEditControl()
+ { return ListView_GetEditControl(_window) ; }
+ HWND EditLabel(int itemIndex)
+ { return ListView_EditLabel(_window, itemIndex) ; }
+
+ bool RedrawItems(int firstIndex, int lastIndex)
+ { return BOOLToBool(ListView_RedrawItems(_window, firstIndex, lastIndex)); }
+ bool RedrawAllItems()
+ {
+ if (GetItemCount() > 0)
+ return RedrawItems(0, GetItemCount() - 1);
+ return true;
+ }
+ bool RedrawItem(int index)
+ { return RedrawItems(index, index); }
+
+ int HitTest(LPLVHITTESTINFO info)
+ { return ListView_HitTest(_window, info); }
+
+ COLORREF GetBkColor()
+ { return ListView_GetBkColor(_window); }
+};
+
+}}
+#endif \ No newline at end of file
diff --git a/CPP/Windows/Control/ProgressBar.h b/CPP/Windows/Control/ProgressBar.h
new file mode 100755
index 00000000..6ce837cc
--- /dev/null
+++ b/CPP/Windows/Control/ProgressBar.h
@@ -0,0 +1,41 @@
+// Windows/Control/ProgressBar.h
+
+#ifndef __WINDOWS_CONTROL_PROGRESSBAR_H
+#define __WINDOWS_CONTROL_PROGRESSBAR_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CProgressBar: public CWindow
+{
+public:
+ LRESULT SetPos(int pos)
+ { return SendMessage(PBM_SETPOS, pos, 0); }
+ LRESULT DeltaPos(int increment)
+ { return SendMessage(PBM_DELTAPOS, increment, 0); }
+ UINT GetPos()
+ { return (UINT)SendMessage(PBM_GETPOS, 0, 0); }
+ LRESULT SetRange(unsigned short minValue, unsigned short maxValue)
+ { return SendMessage(PBM_SETRANGE, 0, MAKELPARAM(minValue, maxValue)); }
+ DWORD SetRange32(int minValue, int maxValue)
+ { return (DWORD)SendMessage(PBM_SETRANGE32, minValue, maxValue); }
+ int SetStep(int step)
+ { return (int)SendMessage(PBM_SETSTEP, step, 0); }
+ LRESULT StepIt()
+ { return SendMessage(PBM_STEPIT, 0, 0); }
+
+ INT GetRange(bool minValue, PPBRANGE range)
+ { return (INT)SendMessage(PBM_GETRANGE, BoolToBOOL(minValue), (LPARAM)range); }
+
+ COLORREF SetBarColor(COLORREF color)
+ { return (COLORREF)SendMessage(PBM_SETBARCOLOR, 0, color); }
+ COLORREF SetBackgroundColor(COLORREF color)
+ { return (COLORREF)SendMessage(PBM_SETBKCOLOR, 0, color); }
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/CPP/Windows/Control/PropertyPage.cpp b/CPP/Windows/Control/PropertyPage.cpp
new file mode 100755
index 00000000..f8996be1
--- /dev/null
+++ b/CPP/Windows/Control/PropertyPage.cpp
@@ -0,0 +1,163 @@
+// Windows/Control/PropertyPage.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Control/PropertyPage.h"
+#include "../../Common/Vector.h"
+#ifndef _UNICODE
+#include "../../Common/StringConvert.h"
+#endif
+
+extern HINSTANCE g_hInstance;
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NControl {
+
+INT_PTR APIENTRY ProperyPageProcedure(HWND dialogHWND, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ CDialog tempDialog(dialogHWND);
+ if (message == WM_INITDIALOG)
+ tempDialog.SetUserDataLongPtr(((PROPSHEETPAGE *)lParam)->lParam);
+ CDialog *dialog = (CDialog *)(tempDialog.GetUserDataLongPtr());
+ if (message == WM_INITDIALOG)
+ dialog->Attach(dialogHWND);
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ return dialog->OnInit();
+ case WM_COMMAND:
+ return dialog->OnCommand(wParam, lParam);
+ case WM_NOTIFY:
+ return dialog->OnNotify((UINT)wParam, (LPNMHDR) lParam);
+ }
+ if (dialog == NULL)
+ return false;
+ return dialog->OnMessage(message, wParam, lParam);
+}
+
+bool CPropertyPage::OnNotify(UINT /* controlID */, LPNMHDR lParam)
+{
+ switch(lParam->code)
+ {
+ case PSN_APPLY:
+ SetMsgResult(OnApply(LPPSHNOTIFY(lParam)));
+ break;
+ case PSN_KILLACTIVE:
+ SetMsgResult(BoolToBOOL(OnKillActive(LPPSHNOTIFY(lParam))));
+ break;
+ case PSN_SETACTIVE:
+ SetMsgResult(OnSetActive(LPPSHNOTIFY(lParam)));
+ break;
+ case PSN_RESET:
+ OnReset(LPPSHNOTIFY(lParam));
+ break;
+ case PSN_HELP:
+ OnNotifyHelp(LPPSHNOTIFY(lParam));
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+INT_PTR MyPropertySheet(const CObjectVector<CPageInfo> &pagesInfo, HWND hwndParent, const UString &title)
+{
+ #ifndef _UNICODE
+ AStringVector titles;
+ #endif
+ #ifndef _UNICODE
+ CRecordVector<PROPSHEETPAGEA> pagesA;
+ #endif
+ CRecordVector<PROPSHEETPAGEW> pagesW;
+
+ int i;
+ #ifndef _UNICODE
+ for (i = 0; i < pagesInfo.Size(); i++)
+ titles.Add(GetSystemString(pagesInfo[i].Title));
+ #endif
+
+ for (i = 0; i < pagesInfo.Size(); i++)
+ {
+ const CPageInfo &pageInfo = pagesInfo[i];
+ #ifndef _UNICODE
+ {
+ PROPSHEETPAGE page;
+ page.dwSize = sizeof(page);
+ page.dwFlags = PSP_HASHELP;
+ page.hInstance = g_hInstance;
+ page.pszTemplate = MAKEINTRESOURCE(pageInfo.ID);
+ page.pszIcon = NULL;
+ page.pfnDlgProc = NWindows::NControl::ProperyPageProcedure;
+
+ if (titles[i].IsEmpty())
+ page.pszTitle = NULL;
+ else
+ {
+ page.dwFlags |= PSP_USETITLE;
+ page.pszTitle = titles[i];
+ }
+ page.lParam = (LPARAM)pageInfo.Page;
+ page.pfnCallback = NULL;
+ pagesA.Add(page);
+ }
+ #endif
+ {
+ PROPSHEETPAGEW page;
+ page.dwSize = sizeof(page);
+ page.dwFlags = PSP_HASHELP;
+ page.hInstance = g_hInstance;
+ page.pszTemplate = MAKEINTRESOURCEW(pageInfo.ID);
+ page.pszIcon = NULL;
+ page.pfnDlgProc = NWindows::NControl::ProperyPageProcedure;
+
+ if (pageInfo.Title.IsEmpty())
+ page.pszTitle = NULL;
+ else
+ {
+ page.dwFlags |= PSP_USETITLE;
+ page.pszTitle = pageInfo.Title;
+ }
+ page.lParam = (LPARAM)pageInfo.Page;
+ page.pfnCallback = NULL;
+ pagesW.Add(page);
+ }
+ }
+
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ PROPSHEETHEADER sheet;
+ sheet.dwSize = sizeof(sheet);
+ sheet.dwFlags = PSH_PROPSHEETPAGE;
+ sheet.hwndParent = hwndParent;
+ sheet.hInstance = g_hInstance;
+ AString titleA = GetSystemString(title);
+ sheet.pszCaption = titleA;
+ sheet.nPages = pagesInfo.Size();
+ sheet.nStartPage = 0;
+ sheet.ppsp = &pagesA.Front();
+ sheet.pfnCallback = NULL;
+ return ::PropertySheetA(&sheet);
+ }
+ else
+ #endif
+ {
+ PROPSHEETHEADERW sheet;
+ sheet.dwSize = sizeof(sheet);
+ sheet.dwFlags = PSH_PROPSHEETPAGE;
+ sheet.hwndParent = hwndParent;
+ sheet.hInstance = g_hInstance;
+ sheet.pszCaption = title;
+ sheet.nPages = pagesInfo.Size();
+ sheet.nStartPage = 0;
+ sheet.ppsp = &pagesW.Front();
+ sheet.pfnCallback = NULL;
+ return ::PropertySheetW(&sheet);
+ }
+}
+
+}}
diff --git a/CPP/Windows/Control/PropertyPage.h b/CPP/Windows/Control/PropertyPage.h
new file mode 100755
index 00000000..e041d289
--- /dev/null
+++ b/CPP/Windows/Control/PropertyPage.h
@@ -0,0 +1,47 @@
+// Windows/Control/PropertyPage.h
+
+#ifndef __WINDOWS_CONTROL_PROPERTYPAGE_H
+#define __WINDOWS_CONTROL_PROPERTYPAGE_H
+
+#include "Windows/Control/Dialog.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+INT_PTR APIENTRY ProperyPageProcedure(HWND dialogHWND, UINT message, WPARAM wParam, LPARAM lParam);
+
+class CPropertyPage: public CDialog
+{
+public:
+ CPropertyPage(HWND window = NULL): CDialog(window){};
+
+ void Changed() { PropSheet_Changed(GetParent(), HWND(*this)); }
+ void UnChanged() { PropSheet_UnChanged(GetParent(), HWND(*this)); }
+
+ virtual bool OnNotify(UINT controlID, LPNMHDR lParam);
+
+ virtual bool OnKillActive() { return false; } // false = OK
+ virtual bool OnKillActive(const PSHNOTIFY * /* aPSHNOTIFY */) { return OnKillActive(); }
+ virtual LONG OnSetActive() { return false; } // false = OK
+ virtual LONG OnSetActive(const PSHNOTIFY * /* aPSHNOTIFY */) { return OnKillActive(); }
+ virtual LONG OnApply() { return PSNRET_NOERROR; }
+ virtual LONG OnApply(const PSHNOTIFY * /* aPSHNOTIFY */) { return OnApply(); }
+ virtual void OnNotifyHelp() { }
+ virtual void OnNotifyHelp(const PSHNOTIFY * /* aPSHNOTIFY */) { OnNotifyHelp(); }
+ virtual void OnReset() { }
+ virtual void OnReset(const PSHNOTIFY * /* aPSHNOTIFY */) { OnReset(); }
+};
+
+struct CPageInfo
+{
+ CPropertyPage *Page;
+ UString Title;
+ UINT ID;
+};
+
+INT_PTR MyPropertySheet(const CObjectVector<CPageInfo> &pagesInfo, HWND hwndParent, const UString &title);
+
+}}
+
+#endif
diff --git a/CPP/Windows/Control/ReBar.h b/CPP/Windows/Control/ReBar.h
new file mode 100755
index 00000000..ec27f0ed
--- /dev/null
+++ b/CPP/Windows/Control/ReBar.h
@@ -0,0 +1,35 @@
+// Windows/Control/ReBar.h
+
+#ifndef __WINDOWS_CONTROL_REBAR_H
+#define __WINDOWS_CONTROL_REBAR_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CReBar: public NWindows::CWindow
+{
+public:
+ bool SetBarInfo(LPREBARINFO barInfo)
+ { return LRESULTToBool(SendMessage(RB_SETBARINFO, 0, (LPARAM)barInfo)); }
+ bool InsertBand(int index, LPREBARBANDINFO bandInfo)
+ { return LRESULTToBool(SendMessage(RB_INSERTBAND, index, (LPARAM)bandInfo)); }
+ bool SetBandInfo(int index, LPREBARBANDINFO bandInfo)
+ { return LRESULTToBool(SendMessage(RB_SETBANDINFO, index, (LPARAM)bandInfo)); }
+ void MaximizeBand(int index, bool ideal)
+ { SendMessage(RB_MAXIMIZEBAND, index, BoolToBOOL(ideal)); }
+ bool SizeToRect(LPRECT rect)
+ { return LRESULTToBool(SendMessage(RB_SIZETORECT, 0, (LPARAM)rect)); }
+ UINT GetHeight()
+ { return (UINT)SendMessage(RB_GETBARHEIGHT); }
+ UINT GetBandCount()
+ { return (UINT)SendMessage(RB_GETBANDCOUNT); }
+ bool DeleteBand(UINT index)
+ { return LRESULTToBool(SendMessage(RB_DELETEBAND, index)); }
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/CPP/Windows/Control/Static.h b/CPP/Windows/Control/Static.h
new file mode 100755
index 00000000..5dded0ec
--- /dev/null
+++ b/CPP/Windows/Control/Static.h
@@ -0,0 +1,27 @@
+// Windows/Control/Static.h
+
+#ifndef __WINDOWS_CONTROL_STATIC_H
+#define __WINDOWS_CONTROL_STATIC_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CStatic: public CWindow
+{
+public:
+ HICON SetIcon(HICON icon)
+ { return (HICON)SendMessage(STM_SETICON, (WPARAM)icon, 0); }
+ HICON GetIcon()
+ { return (HICON)SendMessage(STM_GETICON, 0, 0); }
+ HANDLE SetImage(WPARAM imageType, HANDLE handle)
+ { return (HANDLE)SendMessage(STM_SETIMAGE, imageType, (LPARAM)handle); }
+ HANDLE GetImage(WPARAM imageType)
+ { return (HANDLE)SendMessage(STM_GETIMAGE, imageType, 0); }
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/CPP/Windows/Control/StatusBar.h b/CPP/Windows/Control/StatusBar.h
new file mode 100755
index 00000000..e8018a56
--- /dev/null
+++ b/CPP/Windows/Control/StatusBar.h
@@ -0,0 +1,43 @@
+// Windows/Control/StatusBar.h
+
+#ifndef __WINDOWS_CONTROL_STATUSBAR_H
+#define __WINDOWS_CONTROL_STATUSBAR_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CStatusBar: public NWindows::CWindow
+{
+public:
+ bool Create(LONG style, LPCTSTR text, HWND hwndParent, UINT id)
+ { return (_window = ::CreateStatusWindow(style, text, hwndParent, id)) != 0; }
+ bool SetParts(int numParts, const int *edgePostions)
+ { return LRESULTToBool(SendMessage(SB_SETPARTS, numParts, (LPARAM)edgePostions)); }
+ bool SetText(LPCTSTR text)
+ { return CWindow::SetText(text); }
+
+ bool SetText(int index, LPCTSTR text, UINT type)
+ { return LRESULTToBool(SendMessage(SB_SETTEXT, index | type, (LPARAM)text)); }
+ bool SetText(int index, LPCTSTR text)
+ { return SetText(index, text, 0); }
+ void Simple(bool simple)
+ { SendMessage(SB_SIMPLE, BoolToBOOL(simple), 0); }
+
+ #ifndef _UNICODE
+ bool Create(LONG style, LPCWSTR text, HWND hwndParent, UINT id)
+ { return (_window = ::CreateStatusWindowW(style, text, hwndParent, id)) != 0; }
+ bool SetText(LPCWSTR text)
+ { return CWindow::SetText(text); }
+ bool SetText(int index, LPCWSTR text, UINT type)
+ { return LRESULTToBool(SendMessage(SB_SETTEXTW, index | type, (LPARAM)text)); }
+ bool SetText(int index, LPCWSTR text)
+ { return SetText(index, text, 0); }
+ #endif
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/CPP/Windows/Control/StdAfx.h b/CPP/Windows/Control/StdAfx.h
new file mode 100755
index 00000000..27a77b10
--- /dev/null
+++ b/CPP/Windows/Control/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/CPP/Windows/Control/ToolBar.h b/CPP/Windows/Control/ToolBar.h
new file mode 100755
index 00000000..ff5cafd2
--- /dev/null
+++ b/CPP/Windows/Control/ToolBar.h
@@ -0,0 +1,34 @@
+// Windows/Control/ToolBar.h
+
+#ifndef __WINDOWS_CONTROL_TOOLBAR_H
+#define __WINDOWS_CONTROL_TOOLBAR_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CToolBar: public NWindows::CWindow
+{
+public:
+ bool GetMaxSize(LPSIZE size)
+ { return LRESULTToBool(SendMessage(TB_GETMAXSIZE, 0, (LPARAM)size)); }
+ bool EnableButton(UINT buttonID, bool enable)
+ { return LRESULTToBool(SendMessage(TB_ENABLEBUTTON, buttonID,
+ MAKELONG(BoolToBOOL(enable), 0))); }
+ void ButtonStructSize()
+ { SendMessage(TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON)); }
+ HIMAGELIST SetImageList(UINT listIndex, HIMAGELIST imageList)
+ { return HIMAGELIST(SendMessage(TB_SETIMAGELIST, listIndex, (LPARAM)imageList)); }
+ bool AddButton(UINT numButtons, LPTBBUTTON buttons)
+ { return LRESULTToBool(SendMessage(TB_ADDBUTTONS, numButtons, (LPARAM)buttons)); }
+ #ifndef _UNICODE
+ bool AddButtonW(UINT numButtons, LPTBBUTTON buttons)
+ { return LRESULTToBool(SendMessage(TB_ADDBUTTONSW, numButtons, (LPARAM)buttons)); }
+ #endif
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/CPP/Windows/Control/Trackbar.h b/CPP/Windows/Control/Trackbar.h
new file mode 100755
index 00000000..bbd7009a
--- /dev/null
+++ b/CPP/Windows/Control/Trackbar.h
@@ -0,0 +1,28 @@
+// Windows/Control/Trackbar.h
+
+#ifndef __WINDOWS_CONTROL_TRACKBAR_H
+#define __WINDOWS_CONTROL_TRACKBAR_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CTrackbar: public CWindow
+{
+public:
+ void SetRange(int minimum, int maximum, bool redraw = true)
+ { SendMessage(TBM_SETRANGE, BoolToBOOL(redraw), MAKELONG(minimum, maximum)); }
+ void SetPos(int pos, bool redraw = true)
+ { SendMessage(TBM_SETPOS, BoolToBOOL(redraw), pos); }
+ void SetTicFreq(int freq)
+ { SendMessage(TBM_SETTICFREQ, freq); }
+
+ int GetPos()
+ { return SendMessage(TBM_GETPOS); }
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/CPP/Windows/Control/Window2.cpp b/CPP/Windows/Control/Window2.cpp
new file mode 100755
index 00000000..66857523
--- /dev/null
+++ b/CPP/Windows/Control/Window2.cpp
@@ -0,0 +1,203 @@
+// Windows/Control/Window2.cpp
+
+#include "StdAfx.h"
+
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+#include "Windows/Control/Window2.h"
+
+// extern HINSTANCE g_hInstance;
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+
+#ifndef _UNICODE
+ATOM MyRegisterClass(CONST WNDCLASSW *wndClass);
+#endif
+
+namespace NControl {
+
+static LRESULT CALLBACK WindowProcedure(HWND aHWND, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ CWindow tempWindow(aHWND);
+ if (message == WM_NCCREATE)
+ tempWindow.SetUserDataLongPtr(
+ LONG_PTR(((LPCREATESTRUCT)lParam)->lpCreateParams));
+ CWindow2 *window = (CWindow2*)(tempWindow.GetUserDataLongPtr());
+ if (window != NULL && message == WM_NCCREATE)
+ window->Attach(aHWND);
+ if (window == 0)
+ {
+ #ifndef _UNICODE
+ if (g_IsNT)
+ return DefWindowProcW(aHWND, message, wParam, lParam);
+ else
+ #endif
+ return DefWindowProc(aHWND, message, wParam, lParam);
+ }
+ return window->OnMessage(message, wParam, lParam);
+}
+
+bool CWindow2::CreateEx(DWORD exStyle, LPCTSTR className,
+ LPCTSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance)
+{
+ WNDCLASS windowClass;
+ if(!::GetClassInfo(instance, className, &windowClass))
+ {
+ // windowClass.style = CS_HREDRAW | CS_VREDRAW;
+ windowClass.style = 0;
+
+ windowClass.lpfnWndProc = WindowProcedure;
+ windowClass.cbClsExtra = NULL;
+ windowClass.cbWndExtra = NULL;
+ windowClass.hInstance = instance;
+ windowClass.hIcon = NULL;
+ windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+ windowClass.lpszMenuName = NULL;
+ windowClass.lpszClassName = className;
+ if (::RegisterClass(&windowClass) == 0)
+ return false;
+ }
+ return CWindow::CreateEx(exStyle, className, windowName,
+ style, x, y, width, height, parentWindow,
+ idOrHMenu, instance, this);
+}
+
+#ifndef _UNICODE
+
+bool CWindow2::CreateEx(DWORD exStyle, LPCWSTR className,
+ LPCWSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance)
+{
+ bool needRegister;
+ if(g_IsNT)
+ {
+ WNDCLASSW windowClass;
+ needRegister = ::GetClassInfoW(instance, className, &windowClass) == 0;
+ }
+ else
+ {
+ WNDCLASSA windowClassA;
+ AString classNameA;
+ LPCSTR classNameP;
+ if (IS_INTRESOURCE(className))
+ classNameP = (LPCSTR)className;
+ else
+ {
+ classNameA = GetSystemString(className);
+ classNameP = classNameA;
+ }
+ needRegister = ::GetClassInfoA(instance, classNameP, &windowClassA) == 0;
+ }
+ if (needRegister)
+ {
+ WNDCLASSW windowClass;
+ // windowClass.style = CS_HREDRAW | CS_VREDRAW;
+ windowClass.style = 0;
+ windowClass.lpfnWndProc = WindowProcedure;
+ windowClass.cbClsExtra = NULL;
+ windowClass.cbWndExtra = NULL;
+ windowClass.hInstance = instance;
+ windowClass.hIcon = NULL;
+ windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+ windowClass.lpszMenuName = NULL;
+ windowClass.lpszClassName = className;
+ if (MyRegisterClass(&windowClass) == 0)
+ return false;
+ }
+ return CWindow::CreateEx(exStyle, className, windowName,
+ style, x, y, width, height, parentWindow,
+ idOrHMenu, instance, this);
+
+}
+#endif
+
+LRESULT CWindow2::DefProc(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ #ifndef _UNICODE
+ if (g_IsNT)
+ return DefWindowProcW(_window, message, wParam, lParam);
+ else
+ #endif
+ return DefWindowProc(_window, message, wParam, lParam);
+}
+
+LRESULT CWindow2::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT result;
+ switch (message)
+ {
+ case WM_CREATE:
+ if (!OnCreate((CREATESTRUCT *)lParam))
+ return -1;
+ break;
+ case WM_COMMAND:
+ if (OnCommand(wParam, lParam, result))
+ return result;
+ break;
+ case WM_NOTIFY:
+ if (OnNotify((UINT)wParam, (LPNMHDR) lParam, result))
+ return result;
+ break;
+ case WM_DESTROY:
+ OnDestroy();
+ break;
+ case WM_CLOSE:
+ OnClose();
+ return 0;
+ case WM_SIZE:
+ if (OnSize(wParam, LOWORD(lParam), HIWORD(lParam)))
+ return 0;
+ }
+ return DefProc(message, wParam, lParam);
+}
+
+bool CWindow2::OnCommand(WPARAM wParam, LPARAM lParam, LRESULT &result)
+{
+ return OnCommand(HIWORD(wParam), LOWORD(wParam), lParam, result);
+}
+
+bool CWindow2::OnCommand(int /* code */, int /* itemID */, LPARAM /* lParam */, LRESULT & /* result */)
+{
+ return false;
+ // return DefProc(message, wParam, lParam);
+ /*
+ if (code == BN_CLICKED)
+ return OnButtonClicked(itemID, (HWND)lParam);
+ */
+}
+
+/*
+bool CDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch(aButtonID)
+ {
+ case IDOK:
+ OnOK();
+ break;
+ case IDCANCEL:
+ OnCancel();
+ break;
+ case IDHELP:
+ OnHelp();
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+*/
+
+}}
diff --git a/CPP/Windows/Control/Window2.h b/CPP/Windows/Control/Window2.h
new file mode 100755
index 00000000..2d0e574d
--- /dev/null
+++ b/CPP/Windows/Control/Window2.h
@@ -0,0 +1,59 @@
+// Windows/Control/Window2.h
+
+#ifndef __WINDOWS_CONTROL_WINDOW2_H
+#define __WINDOWS_CONTROL_WINDOW2_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CWindow2: public CWindow
+{
+ LRESULT DefProc(UINT message, WPARAM wParam, LPARAM lParam);
+public:
+ CWindow2(HWND newWindow = NULL): CWindow(newWindow){};
+ virtual ~CWindow2() {};
+
+
+ bool CreateEx(DWORD exStyle, LPCTSTR className,
+ LPCTSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance);
+
+ #ifndef _UNICODE
+ bool CreateEx(DWORD exStyle, LPCWSTR className,
+ LPCWSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance);
+ #endif
+
+ virtual LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+ virtual bool OnCreate(CREATESTRUCT * /* createStruct */) { return true; }
+ // virtual LRESULT OnCommand(WPARAM wParam, LPARAM lParam);
+ virtual bool OnCommand(WPARAM wParam, LPARAM lParam, LRESULT &result);
+ virtual bool OnCommand(int code, int itemID, LPARAM lParam, LRESULT &result);
+ virtual bool OnSize(WPARAM /* wParam */, int /* xSize */, int /* ySize */) { return false; }
+ virtual bool OnNotify(UINT /* controlID */, LPNMHDR /* lParam */, LRESULT & /* result */) { return false; }
+ virtual void OnDestroy() { PostQuitMessage(0); }
+ virtual void OnClose() { Destroy(); }
+ /*
+ virtual LRESULT OnHelp(LPHELPINFO helpInfo) { OnHelp(); };
+ virtual LRESULT OnHelp() {};
+ virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ virtual void OnOK() {};
+ virtual void OnCancel() {};
+ */
+
+ LONG_PTR SetMsgResult(LONG_PTR newLongPtr )
+ { return SetLongPtr(DWLP_MSGRESULT, newLongPtr); }
+ LONG_PTR GetMsgResult() const
+ { return GetLongPtr(DWLP_MSGRESULT); }
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/CPP/Windows/DLL.cpp b/CPP/Windows/DLL.cpp
new file mode 100755
index 00000000..9e92dc26
--- /dev/null
+++ b/CPP/Windows/DLL.cpp
@@ -0,0 +1,115 @@
+// Windows/DLL.cpp
+
+#include "StdAfx.h"
+
+#include "DLL.h"
+#include "Defs.h"
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NDLL {
+
+CLibrary::~CLibrary()
+{
+ Free();
+}
+
+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/CPP/Windows/DLL.h b/CPP/Windows/DLL.h
new file mode 100755
index 00000000..bad0dd6d
--- /dev/null
+++ b/CPP/Windows/DLL.h
@@ -0,0 +1,54 @@
+// Windows/DLL.h
+
+#ifndef __WINDOWS_DLL_H
+#define __WINDOWS_DLL_H
+
+#include "../Common/String.h"
+
+namespace NWindows {
+namespace NDLL {
+
+class CLibrary
+{
+ bool LoadOperations(HMODULE newModule);
+protected:
+ HMODULE _module;
+public:
+ operator HMODULE() const { return _module; }
+ HMODULE* operator&() { return &_module; }
+
+ CLibrary():_module(NULL) {};
+ ~CLibrary();
+ void Attach(HMODULE m)
+ {
+ Free();
+ _module = m;
+ }
+ HMODULE Detach()
+ {
+ HMODULE m = _module;
+ _module = NULL;
+ return m;
+ }
+
+ // operator HMODULE() const { return _module; };
+ bool IsLoaded() const { return (_module != NULL); };
+ 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 GetProcAddress(LPCSTR procName) const
+ { return ::GetProcAddress(_module, procName); }
+};
+
+bool MyGetModuleFileName(HMODULE hModule, CSysString &result);
+#ifndef _UNICODE
+bool MyGetModuleFileName(HMODULE hModule, UString &result);
+#endif
+
+}}
+
+#endif
diff --git a/CPP/Windows/Defs.h b/CPP/Windows/Defs.h
new file mode 100755
index 00000000..f8c6daaa
--- /dev/null
+++ b/CPP/Windows/Defs.h
@@ -0,0 +1,21 @@
+// Windows/Defs.h
+
+#ifndef __WINDOWS_DEFS_H
+#define __WINDOWS_DEFS_H
+
+inline bool BOOLToBool(BOOL value)
+ { return (value != FALSE); }
+
+inline bool LRESULTToBool(LRESULT value)
+ { return (value != FALSE); }
+
+inline BOOL BoolToBOOL(bool value)
+ { return (value ? TRUE: FALSE); }
+
+inline VARIANT_BOOL BoolToVARIANT_BOOL(bool value)
+ { return (value ? VARIANT_TRUE: VARIANT_FALSE); }
+
+inline bool VARIANT_BOOLToBool(VARIANT_BOOL value)
+ { return (value != VARIANT_FALSE); }
+
+#endif
diff --git a/CPP/Windows/Error.cpp b/CPP/Windows/Error.cpp
new file mode 100755
index 00000000..e559c4cc
--- /dev/null
+++ b/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/CPP/Windows/Error.h b/CPP/Windows/Error.h
new file mode 100755
index 00000000..4d9a9fa6
--- /dev/null
+++ b/CPP/Windows/Error.h
@@ -0,0 +1,33 @@
+// Windows/Error.h
+
+#ifndef __WINDOWS_ERROR_H
+#define __WINDOWS_ERROR_H
+
+#include "Common/String.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/CPP/Windows/FileDevice.cpp b/CPP/Windows/FileDevice.cpp
new file mode 100755
index 00000000..76f1aa7a
--- /dev/null
+++ b/CPP/Windows/FileDevice.cpp
@@ -0,0 +1,49 @@
+// Windows/FileDevice.cpp
+
+#include "StdAfx.h"
+
+#include "FileDevice.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NDevice {
+
+bool CFileBase::GetLengthSmart(UInt64 &length)
+{
+ PARTITION_INFORMATION partInfo;
+ if (GetPartitionInfo(&partInfo))
+ {
+ length = partInfo.PartitionLength.QuadPart;
+ return true;
+ }
+ DISK_GEOMETRY geom;
+ if (!GetGeometry(&geom))
+ if (!GetCdRomGeometry(&geom))
+ return false;
+ length = geom.Cylinders.QuadPart * geom.TracksPerCylinder * geom.SectorsPerTrack * geom.BytesPerSector;
+ return true;
+}
+
+bool CInFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+ { return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); }
+
+bool CInFile::Open(LPCTSTR fileName)
+ { return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
+
+#ifndef _UNICODE
+bool CInFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+ { return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); }
+
+bool CInFile::Open(LPCWSTR fileName)
+ { return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
+#endif
+
+bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize)
+{
+ DWORD processedLoc = 0;
+ bool res = BOOLToBool(::ReadFile(_handle, data, size, &processedLoc, NULL));
+ processedSize = (UInt32)processedLoc;
+ return res;
+}
+
+}}}
diff --git a/CPP/Windows/FileDevice.h b/CPP/Windows/FileDevice.h
new file mode 100755
index 00000000..d4d71c39
--- /dev/null
+++ b/CPP/Windows/FileDevice.h
@@ -0,0 +1,123 @@
+// Windows/FileDevice.h
+
+#ifndef __WINDOWS_FILEDEVICE_H
+#define __WINDOWS_FILEDEVICE_H
+
+#include "FileIO.h"
+#include "Defs.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NDevice {
+
+typedef struct _GET_LENGTH_INFORMATION
+{
+ LARGE_INTEGER Length;
+} GET_LENGTH_INFORMATION, *PGET_LENGTH_INFORMATION;
+
+#define IOCTL_DISK_GET_LENGTH_INFO CTL_CODE(IOCTL_DISK_BASE, 0x0017, METHOD_BUFFERED, FILE_READ_ACCESS)
+
+/*
+typedef struct _DISK_GEOMETRY_EX {
+ DISK_GEOMETRY Geometry; // Standard disk geometry: may be faked by driver.
+ LARGE_INTEGER DiskSize; // Must always be correct
+ BYTE Data[1]; // Partition, Detect info
+} DISK_GEOMETRY_EX, *PDISK_GEOMETRY_EX;
+*/
+
+#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 CFileBase: public NIO::CFileBase
+{
+public:
+ 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 DeviceIoControlIn(DWORD controlCode, LPVOID inBuffer, DWORD inSize) const
+ { return DeviceIoControl(controlCode, inBuffer, inSize, NULL, 0); }
+
+ bool DeviceIoControlOut(DWORD controlCode, LPVOID outBuffer, DWORD outSize) const
+ { return DeviceIoControl(controlCode, NULL, 0, outBuffer, outSize); }
+
+ 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 GetCdRomGeometryEx(DISK_GEOMETRY_EX *res) const
+ { return DeviceIoControlOut(IOCTL_CDROM_GET_DRIVE_GEOMETRY, res, sizeof(*res)); }
+ */
+
+ bool CdRomLock(bool lock) const
+ {
+ PREVENT_MEDIA_REMOVAL rem;
+ rem.PreventMediaRemoval = (BOOLEAN)(lock ? TRUE : FALSE);
+ return DeviceIoControlIn(IOCTL_CDROM_MEDIA_REMOVAL, &rem, sizeof(rem));
+ }
+
+ bool GetLengthInfo(UInt64 &length) const
+ {
+ GET_LENGTH_INFORMATION lengthInfo;
+ bool res = DeviceIoControlOut(IOCTL_DISK_GET_LENGTH_INFO, &lengthInfo, sizeof(lengthInfo));
+ length = lengthInfo.Length.QuadPart;
+ return res;
+ }
+
+ bool GetLengthSmart(UInt64 &length);
+
+
+ /*
+ bool FormatTracks(const FORMAT_PARAMETERS *formatParams,
+ BAD_TRACK_NUMBER *badTrackNumbers, DWORD numBadTrackNumbers,
+ DWORD &numBadTrackNumbersReturned)
+ {
+ DWORD ret;
+ // Check params, Probabably error
+ bool res = DeviceIoControl(IOCTL_DISK_FORMAT_TRACKS, badTrackNumbers, sizeof(*formatParams),
+ badTrackNumbers, numBadTrackNumbers * sizeof(*badTrackNumbers), &ret, NULL);
+ numBadTrackNumbersReturned = ret / sizeof(*badTrackNumbers);
+ return res;
+ }
+ */
+
+
+ bool Performance(DISK_PERFORMANCE *res)
+ { return DeviceIoControlOut(IOCTL_DISK_PERFORMANCE, LPVOID(res), sizeof(*res)); }
+
+ bool GetPartitionInfo(PARTITION_INFORMATION *res)
+ { return DeviceIoControlOut(IOCTL_DISK_GET_PARTITION_INFO, LPVOID(res), sizeof(*res)); }
+
+ bool Verify(const VERIFY_INFORMATION *verifyInformation)
+ { return DeviceIoControlIn(IOCTL_DISK_VERIFY, LPVOID(verifyInformation), sizeof(*verifyInformation)); }
+};
+
+class CInFile: public CFileBase
+{
+public:
+ bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ bool Open(LPCTSTR fileName);
+ #ifndef _UNICODE
+ bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ bool Open(LPCWSTR fileName);
+ #endif
+ bool Read(void *data, UInt32 size, UInt32 &processedSize);
+};
+
+}}}
+
+#endif
diff --git a/CPP/Windows/FileDir.cpp b/CPP/Windows/FileDir.cpp
new file mode 100755
index 00000000..c94c737d
--- /dev/null
+++ b/CPP/Windows/FileDir.cpp
@@ -0,0 +1,835 @@
+// Windows/FileDir.cpp
+
+#include "StdAfx.h"
+
+#include "FileDir.h"
+#include "FileName.h"
+#include "FileFind.h"
+#include "Defs.h"
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#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
+
+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);
+}
+
+#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 *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime)
+{
+ #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, creationTime, lastAccessTime, lastWriteTime));
+ ::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
+ 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
+ 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 (!NFind::FindFile(pathName, fileInfo)) // For network folders
+ return true;
+ if (!fileInfo.IsDirectory())
+ 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 (!NFind::FindFile(pathName, fileInfo)) // For network folders
+ return true;
+ if (!fileInfo.IsDirectory())
+ 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.IsDirectory())
+ 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.IsDirectory())
+ 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
+
+#ifndef _WIN32_WCE
+
+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);
+}
+
+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);
+ 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);
+ }
+ 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
+
+bool GetOnlyName(LPCTSTR fileName, CSysString &resultName)
+{
+ int index;
+ if (!MyGetFullPathName(fileName, resultName, index))
+ return false;
+ resultName = resultName.Mid(index);
+ return true;
+}
+
+#ifndef _UNICODE
+bool GetOnlyName(LPCWSTR fileName, UString &resultName)
+{
+ int index;
+ if (!MyGetFullPathName(fileName, resultName, index))
+ return false;
+ resultName = resultName.Mid(index);
+ return true;
+}
+#endif
+
+bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName)
+{
+ int index;
+ if (!MyGetFullPathName(fileName, resultName, index))
+ return false;
+ resultName = resultName.Left(index);
+ return true;
+}
+
+#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
+#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);
+}
+
+#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;
+ if (!MyGetWindowsDirectory(tempPath))
+ return false;
+ return (Create(tempPath, prefix, resultPath) != 0);
+}
+
+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 (!::DeleteFile(dirName))
+ return false;
+ /*
+ UINT32 randomNumber = random.Generate();
+ TCHAR randomNumberString[32];
+ _stprintf(randomNumberString, _T("%04X"), randomNumber);
+ dirName = prefix + randomNumberString;
+ */
+ if(NFind::DoesFileExist(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 (!DeleteFileAlways(dirName))
+ return false;
+ /*
+ UINT32 randomNumber = random.Generate();
+ TCHAR randomNumberString[32];
+ _stprintf(randomNumberString, _T("%04X"), randomNumber);
+ dirName = prefix + randomNumberString;
+ */
+ if(NFind::DoesFileExist(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/CPP/Windows/FileDir.h b/CPP/Windows/FileDir.h
new file mode 100755
index 00000000..3ebf3e63
--- /dev/null
+++ b/CPP/Windows/FileDir.h
@@ -0,0 +1,178 @@
+// Windows/FileDir.h
+
+#ifndef __WINDOWS_FILEDIR_H
+#define __WINDOWS_FILEDIR_H
+
+#include "../Common/String.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 *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime);
+
+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
+
+#ifndef _WIN32_WCE
+bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath);
+
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath,
+ int &fileNamePartStartIndex);
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath);
+bool GetOnlyName(LPCTSTR fileName, CSysString &resultName);
+bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName);
+#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
+#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
+
+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/CPP/Windows/FileFind.cpp b/CPP/Windows/FileFind.cpp
new file mode 100755
index 00000000..3b5bdf70
--- /dev/null
+++ b/CPP/Windows/FileFind.cpp
@@ -0,0 +1,408 @@
+// Windows/FileFind.cpp
+
+#include "StdAfx.h"
+
+#include "FileFind.h"
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NFile {
+
+#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 (!IsDirectory() || 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 (!IsDirectory() || Name.IsEmpty())
+ return false;
+ if (Name[0] != kDot)
+ return false;
+ return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
+}
+#endif
+
+static void ConvertWIN32_FIND_DATA_To_FileInfo(
+ const WIN32_FIND_DATA &findData,
+ CFileInfo &fileInfo)
+{
+ fileInfo.Attributes = findData.dwFileAttributes;
+ fileInfo.CreationTime = findData.ftCreationTime;
+ fileInfo.LastAccessTime = findData.ftLastAccessTime;
+ fileInfo.LastWriteTime = findData.ftLastWriteTime;
+ fileInfo.Size = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
+ fileInfo.Name = findData.cFileName;
+ #ifndef _WIN32_WCE
+ fileInfo.ReparseTag = findData.dwReserved0;
+ #else
+ fileInfo.ObjectID = findData.dwOID;
+ #endif
+}
+
+#ifndef _UNICODE
+
+static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+
+static void ConvertWIN32_FIND_DATA_To_FileInfo(
+ const WIN32_FIND_DATAW &findData,
+ CFileInfoW &fileInfo)
+{
+ fileInfo.Attributes = findData.dwFileAttributes;
+ fileInfo.CreationTime = findData.ftCreationTime;
+ fileInfo.LastAccessTime = findData.ftLastAccessTime;
+ fileInfo.LastWriteTime = findData.ftLastWriteTime;
+ fileInfo.Size = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
+ fileInfo.Name = findData.cFileName;
+ #ifndef _WIN32_WCE
+ fileInfo.ReparseTag = findData.dwReserved0;
+ #else
+ fileInfo.ObjectID = findData.dwOID;
+ #endif
+}
+
+static void ConvertWIN32_FIND_DATA_To_FileInfo(
+ const WIN32_FIND_DATA &findData,
+ CFileInfoW &fileInfo)
+{
+ fileInfo.Attributes = findData.dwFileAttributes;
+ fileInfo.CreationTime = findData.ftCreationTime;
+ fileInfo.LastAccessTime = findData.ftLastAccessTime;
+ fileInfo.LastWriteTime = findData.ftLastWriteTime;
+ fileInfo.Size = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
+ fileInfo.Name = GetUnicodeString(findData.cFileName, GetCurrentCodePage());
+ #ifndef _WIN32_WCE
+ fileInfo.ReparseTag = findData.dwReserved0;
+ #else
+ fileInfo.ObjectID = findData.dwOID;
+ #endif
+}
+#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 &fileInfo)
+{
+ if (!Close())
+ return false;
+ WIN32_FIND_DATA findData;
+ _handle = ::FindFirstFile(wildcard, &findData);
+ #ifdef WIN_LONG_PATH2
+ if (_handle == INVALID_HANDLE_VALUE)
+ {
+ UString longPath;
+ if (GetLongPath(wildcard, longPath))
+ _handle = ::FindFirstFileW(longPath, &findData);
+ }
+ #endif
+ if (_handle == INVALID_HANDLE_VALUE)
+ return false;
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ return true;
+}
+
+#ifndef _UNICODE
+bool CFindFile::FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo)
+{
+ if (!Close())
+ return false;
+ if (g_IsNT)
+ {
+ WIN32_FIND_DATAW findData;
+ _handle = ::FindFirstFileW(wildcard, &findData);
+ #ifdef WIN_LONG_PATH
+ if (_handle == INVALID_HANDLE_VALUE)
+ {
+ UString longPath;
+ if (GetLongPath(wildcard, longPath))
+ _handle = ::FindFirstFileW(longPath, &findData);
+ }
+ #endif
+ if (_handle != INVALID_HANDLE_VALUE)
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ }
+ else
+ {
+ WIN32_FIND_DATAA findData;
+ _handle = ::FindFirstFileA(UnicodeStringToMultiByte(wildcard,
+ GetCurrentCodePage()), &findData);
+ if (_handle != INVALID_HANDLE_VALUE)
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ }
+ return (_handle != INVALID_HANDLE_VALUE);
+}
+#endif
+
+bool CFindFile::FindNext(CFileInfo &fileInfo)
+{
+ WIN32_FIND_DATA findData;
+ bool result = BOOLToBool(::FindNextFile(_handle, &findData));
+ if (result)
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ return result;
+}
+
+#ifndef _UNICODE
+bool CFindFile::FindNext(CFileInfoW &fileInfo)
+{
+ if (g_IsNT)
+ {
+ WIN32_FIND_DATAW findData;
+ if (!::FindNextFileW(_handle, &findData))
+ return false;
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ }
+ else
+ {
+ WIN32_FIND_DATAA findData;
+ if (!::FindNextFileA(_handle, &findData))
+ return false;
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ }
+ return true;
+}
+#endif
+
+bool FindFile(LPCTSTR wildcard, CFileInfo &fileInfo)
+{
+ CFindFile finder;
+ return finder.FindFirst(wildcard, fileInfo);
+}
+
+#ifndef _UNICODE
+bool FindFile(LPCWSTR wildcard, CFileInfoW &fileInfo)
+{
+ CFindFile finder;
+ return finder.FindFirst(wildcard, fileInfo);
+}
+#endif
+
+bool DoesFileExist(LPCTSTR name)
+{
+ CFileInfo fileInfo;
+ return FindFile(name, fileInfo);
+}
+
+#ifndef _UNICODE
+bool DoesFileExist(LPCWSTR name)
+{
+ CFileInfoW fileInfo;
+ return FindFile(name, fileInfo);
+}
+#endif
+
+/////////////////////////////////////
+// CEnumerator
+
+bool CEnumerator::NextAny(CFileInfo &fileInfo)
+{
+ if (_findFile.IsHandleAllocated())
+ return _findFile.FindNext(fileInfo);
+ else
+ return _findFile.FindFirst(_wildcard, fileInfo);
+}
+
+bool CEnumerator::Next(CFileInfo &fileInfo)
+{
+ for (;;)
+ {
+ if (!NextAny(fileInfo))
+ return false;
+ if (!fileInfo.IsDots())
+ return true;
+ }
+}
+
+bool CEnumerator::Next(CFileInfo &fileInfo, bool &found)
+{
+ if (Next(fileInfo))
+ {
+ found = true;
+ return true;
+ }
+ found = false;
+ return (::GetLastError() == ERROR_NO_MORE_FILES);
+}
+
+#ifndef _UNICODE
+bool CEnumeratorW::NextAny(CFileInfoW &fileInfo)
+{
+ if (_findFile.IsHandleAllocated())
+ return _findFile.FindNext(fileInfo);
+ else
+ return _findFile.FindFirst(_wildcard, fileInfo);
+}
+
+bool CEnumeratorW::Next(CFileInfoW &fileInfo)
+{
+ for (;;)
+ {
+ if (!NextAny(fileInfo))
+ return false;
+ if (!fileInfo.IsDots())
+ return true;
+ }
+}
+
+bool CEnumeratorW::Next(CFileInfoW &fileInfo, bool &found)
+{
+ if (Next(fileInfo))
+ {
+ 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 _WIN32_WCE
+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/CPP/Windows/FileFind.h b/CPP/Windows/FileFind.h
new file mode 100755
index 00000000..4d2439aa
--- /dev/null
+++ b/CPP/Windows/FileFind.h
@@ -0,0 +1,153 @@
+// Windows/FileFind.h
+
+#ifndef __WINDOWS_FILEFIND_H
+#define __WINDOWS_FILEFIND_H
+
+#include "../Common/String.h"
+#include "../Common/Types.h"
+#include "FileName.h"
+#include "Defs.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NFind {
+
+namespace NAttributes
+{
+ inline bool IsReadOnly(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_READONLY) != 0; }
+ inline bool IsHidden(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_HIDDEN) != 0; }
+ inline bool IsSystem(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_SYSTEM) != 0; }
+ inline bool IsDirectory(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; }
+ inline bool IsArchived(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_ARCHIVE) != 0; }
+ inline bool IsCompressed(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_COMPRESSED) != 0; }
+ inline bool IsEncrypted(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_ENCRYPTED) != 0; }
+}
+
+class CFileInfoBase
+{
+ bool MatchesMask(UINT32 mask) const { return ((Attributes & mask) != 0); }
+public:
+ DWORD Attributes;
+ FILETIME CreationTime;
+ FILETIME LastAccessTime;
+ FILETIME LastWriteTime;
+ UInt64 Size;
+
+ #ifndef _WIN32_WCE
+ UINT32 ReparseTag;
+ #else
+ DWORD ObjectID;
+ #endif
+
+ bool IsArchived() const { return MatchesMask(FILE_ATTRIBUTE_ARCHIVE); }
+ bool IsCompressed() const { return MatchesMask(FILE_ATTRIBUTE_COMPRESSED); }
+ bool IsDirectory() 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); }
+};
+
+class CFileInfo: public CFileInfoBase
+{
+public:
+ CSysString Name;
+ bool IsDots() const;
+};
+
+#ifdef _UNICODE
+typedef CFileInfo CFileInfoW;
+#else
+class CFileInfoW: public CFileInfoBase
+{
+public:
+ UString Name;
+ bool IsDots() const;
+};
+#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 FindFile(LPCTSTR wildcard, CFileInfo &fileInfo);
+
+bool DoesFileExist(LPCTSTR name);
+#ifndef _UNICODE
+bool FindFile(LPCWSTR wildcard, CFileInfoW &fileInfo);
+bool DoesFileExist(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 _WIN32_WCE
+bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings);
+#ifndef _UNICODE
+bool MyGetLogicalDriveStrings(UStringVector &driveStrings);
+#endif
+#endif
+
+}}}
+
+#endif
+
diff --git a/CPP/Windows/FileIO.cpp b/CPP/Windows/FileIO.cpp
new file mode 100755
index 00000000..efad8582
--- /dev/null
+++ b/CPP/Windows/FileIO.cpp
@@ -0,0 +1,305 @@
+// Windows/FileIO.cpp
+
+#include "StdAfx.h"
+
+#include "FileIO.h"
+#include "Defs.h"
+#ifdef WIN_LONG_PATH
+#include "../Common/String.h"
+#endif
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NFile {
+
+#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;
+ if (len > 3)
+ if (s[1] != L':' || s[2] != L'\\' || !(c >= L'a' && c <= L'z' || c >= L'A' && c <= L'Z'))
+ {
+ 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
+ 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
+ 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
+{
+ 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
+{
+ 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.Attributes = winFileInfo.dwFileAttributes;
+ fileInfo.CreationTime = winFileInfo.ftCreationTime;
+ fileInfo.LastAccessTime = winFileInfo.ftLastAccessTime;
+ fileInfo.LastWriteTime = 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
+
+bool CInFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+ { return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); }
+
+bool CInFile::Open(LPCTSTR fileName)
+ { return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
+
+#ifndef _UNICODE
+bool CInFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+ { return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); }
+
+bool CInFile::Open(LPCWSTR fileName)
+ { return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
+#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).
+
+static UInt32 kChunkSizeMax = (1 << 24);
+
+bool CInFile::ReadPart(void *data, UInt32 size, UInt32 &processedSize)
+{
+ if (size > kChunkSizeMax)
+ size = kChunkSizeMax;
+ DWORD processedLoc = 0;
+ bool res = BOOLToBool(::ReadFile(_handle, data, size, &processedLoc, NULL));
+ processedSize = (UInt32)processedLoc;
+ return res;
+}
+
+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 *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime)
+ { return BOOLToBool(::SetFileTime(_handle, creationTime, lastAccessTime, lastWriteTime)); }
+
+bool COutFile::SetLastWriteTime(const FILETIME *lastWriteTime)
+ { return SetTime(NULL, NULL, lastWriteTime); }
+
+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/CPP/Windows/FileIO.h b/CPP/Windows/FileIO.h
new file mode 100755
index 00000000..ec936ac6
--- /dev/null
+++ b/CPP/Windows/FileIO.h
@@ -0,0 +1,97 @@
+// Windows/FileIO.h
+
+#ifndef __WINDOWS_FILEIO_H
+#define __WINDOWS_FILEIO_H
+
+#include "../Common/Types.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NIO {
+
+struct CByHandleFileInfo
+{
+ DWORD Attributes;
+ FILETIME CreationTime;
+ FILETIME LastAccessTime;
+ FILETIME LastWriteTime;
+ 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:
+ CFileBase(): _handle(INVALID_HANDLE_VALUE){};
+ virtual ~CFileBase();
+
+ virtual 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;
+};
+
+class CInFile: public CFileBase
+{
+public:
+ bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ bool Open(LPCTSTR fileName);
+ #ifndef _UNICODE
+ bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ bool Open(LPCWSTR fileName);
+ #endif
+ bool ReadPart(void *data, UInt32 size, UInt32 &processedSize);
+ bool Read(void *data, UInt32 size, UInt32 &processedSize);
+};
+
+class COutFile: public CFileBase
+{
+ // DWORD m_CreationDisposition;
+public:
+ // COutFile(): m_CreationDisposition(CREATE_NEW){};
+ 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
+
+ /*
+ void SetOpenCreationDisposition(DWORD creationDisposition)
+ { m_CreationDisposition = creationDisposition; }
+ void SetOpenCreationDispositionCreateAlways()
+ { m_CreationDisposition = CREATE_ALWAYS; }
+ */
+
+ bool SetTime(const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime);
+ bool SetLastWriteTime(const FILETIME *lastWriteTime);
+ 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/CPP/Windows/FileMapping.cpp b/CPP/Windows/FileMapping.cpp
new file mode 100755
index 00000000..d884afb1
--- /dev/null
+++ b/CPP/Windows/FileMapping.cpp
@@ -0,0 +1,14 @@
+// Windows/FileMapping.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/FileMapping.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NMapping {
+
+
+
+
+}}} \ No newline at end of file
diff --git a/CPP/Windows/FileMapping.h b/CPP/Windows/FileMapping.h
new file mode 100755
index 00000000..22db8f17
--- /dev/null
+++ b/CPP/Windows/FileMapping.h
@@ -0,0 +1,50 @@
+// Windows/FileMapping.h
+
+#ifndef __WINDOWS_FILEMAPPING_H
+#define __WINDOWS_FILEMAPPING_H
+
+#include "Windows/Handle.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+// namespace NFile {
+// namespace NMapping {
+
+class CFileMapping: public CHandle
+{
+public:
+ bool Create(HANDLE file, LPSECURITY_ATTRIBUTES attributes,
+ DWORD protect, UINT64 maximumSize, LPCTSTR name)
+ {
+ _handle = ::CreateFileMapping(file, attributes,
+ protect, DWORD(maximumSize >> 32), DWORD(maximumSize), name);
+ return (_handle != NULL);
+ }
+
+ bool Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
+ {
+ _handle = ::OpenFileMapping(desiredAccess, BoolToBOOL(inheritHandle), name);
+ return (_handle != NULL);
+ }
+
+ LPVOID MapViewOfFile(DWORD desiredAccess, UINT64 fileOffset,
+ SIZE_T numberOfBytesToMap)
+ {
+ return ::MapViewOfFile(_handle, desiredAccess,
+ DWORD(fileOffset >> 32), DWORD(fileOffset), numberOfBytesToMap);
+ }
+
+ LPVOID MapViewOfFileEx(DWORD desiredAccess, UINT64 fileOffset,
+ SIZE_T numberOfBytesToMap, LPVOID baseAddress)
+ {
+ return ::MapViewOfFileEx(_handle, desiredAccess,
+ DWORD(fileOffset >> 32), DWORD(fileOffset),
+ numberOfBytesToMap, baseAddress);
+ }
+
+
+};
+
+}
+
+#endif
diff --git a/CPP/Windows/FileName.cpp b/CPP/Windows/FileName.cpp
new file mode 100755
index 00000000..49e957cf
--- /dev/null
+++ b/CPP/Windows/FileName.cpp
@@ -0,0 +1,111 @@
+// Windows/FileName.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/FileName.h"
+#include "Common/Wildcard.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NName {
+
+static const wchar_t kDiskDelimiter = L':';
+
+/*
+static bool IsCharAPrefixDelimiter(wchar_t c)
+ { return (c == kDirDelimiter || c == kDiskDelimiter); }
+*/
+
+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
+
+namespace NPathType
+{
+ EEnum GetPathType(const UString &path)
+ {
+ if (path.Length() <= 2)
+ return kLocal;
+ if (path[0] == kDirDelimiter && path[1] == kDirDelimiter)
+ return kUNC;
+ return kLocal;
+ }
+}
+
+void CParsedPath::ParsePath(const UString &path)
+{
+ int curPos = 0;
+ switch (NPathType::GetPathType(path))
+ {
+ case NPathType::kLocal:
+ {
+ int posDiskDelimiter = path.Find(kDiskDelimiter);
+ if(posDiskDelimiter >= 0)
+ {
+ curPos = posDiskDelimiter + 1;
+ if (path.Length() > curPos)
+ if(path[curPos] == kDirDelimiter)
+ curPos++;
+ }
+ break;
+ }
+ case NPathType::kUNC:
+ {
+ int curPos = path.Find(kDirDelimiter, 2);
+ if(curPos < 0)
+ curPos = path.Length();
+ else
+ curPos++;
+ }
+ }
+ Prefix = path.Left(curPos);
+ SplitPathToParts(path.Mid(curPos), PathParts);
+}
+
+UString CParsedPath::MergePath() const
+{
+ UString result = Prefix;
+ for(int i = 0; i < PathParts.Size(); i++)
+ {
+ if (i != 0)
+ result += kDirDelimiter;
+ result += PathParts[i];
+ }
+ return result;
+}
+
+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/CPP/Windows/FileName.h b/CPP/Windows/FileName.h
new file mode 100755
index 00000000..f8567652
--- /dev/null
+++ b/CPP/Windows/FileName.h
@@ -0,0 +1,43 @@
+// Windows/FileName.h
+
+#ifndef __WINDOWS_FILENAME_H
+#define __WINDOWS_FILENAME_H
+
+#include "../Common/String.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
+
+namespace NPathType
+{
+ enum EEnum
+ {
+ kLocal,
+ kUNC
+ };
+ EEnum GetPathType(const UString &path);
+}
+
+struct CParsedPath
+{
+ UString Prefix; // Disk or UNC with slash
+ UStringVector PathParts;
+ void ParsePath(const UString &path);
+ UString MergePath() const;
+};
+
+void SplitNameToPureNameAndExtension(const UString &fullName,
+ UString &pureName, UString &extensionDelimiter, UString &extension);
+
+}}}
+
+#endif
diff --git a/CPP/Windows/FileSystem.cpp b/CPP/Windows/FileSystem.cpp
new file mode 100755
index 00000000..37c76856
--- /dev/null
+++ b/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/CPP/Windows/FileSystem.h b/CPP/Windows/FileSystem.h
new file mode 100755
index 00000000..25488804
--- /dev/null
+++ b/CPP/Windows/FileSystem.h
@@ -0,0 +1,51 @@
+// Windows/FileSystem.h
+
+#ifndef __WINDOWS_FILESYSTEM_H
+#define __WINDOWS_FILESYSTEM_H
+
+#include "../Common/String.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/CPP/Windows/Handle.h b/CPP/Windows/Handle.h
new file mode 100755
index 00000000..d4d8aae5
--- /dev/null
+++ b/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 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/CPP/Windows/Memory.cpp b/CPP/Windows/Memory.cpp
new file mode 100755
index 00000000..435ea999
--- /dev/null
+++ b/CPP/Windows/Memory.cpp
@@ -0,0 +1,64 @@
+// Windows/Memory.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Memory.h"
+
+namespace NWindows {
+namespace NMemory {
+
+CGlobal::~CGlobal()
+{
+ Free();
+}
+
+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);
+}
+
+void CGlobal::Attach(HGLOBAL hGlobal)
+{
+ Free();
+ m_MemoryHandle = hGlobal;
+}
+
+HGLOBAL CGlobal::Detach()
+{
+ HGLOBAL h = m_MemoryHandle;
+ m_MemoryHandle = NULL;
+ return h;
+}
+
+LPVOID CGlobal::Lock() const
+{
+ return ::GlobalLock(m_MemoryHandle);
+}
+
+void CGlobal::Unlock() const
+{
+ ::GlobalUnlock(m_MemoryHandle);
+}
+
+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/CPP/Windows/Memory.h b/CPP/Windows/Memory.h
new file mode 100755
index 00000000..bd8773b8
--- /dev/null
+++ b/CPP/Windows/Memory.h
@@ -0,0 +1,45 @@
+// 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();
+ operator HGLOBAL() const { return m_MemoryHandle; };
+ void Attach(HGLOBAL hGlobal);
+ HGLOBAL Detach();
+ bool Alloc(UINT flags, SIZE_T size);
+ bool Free();
+ LPVOID Lock() const;
+ void Unlock() const;
+ 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/CPP/Windows/MemoryLock.cpp b/CPP/Windows/MemoryLock.cpp
new file mode 100755
index 00000000..b468e528
--- /dev/null
+++ b/CPP/Windows/MemoryLock.cpp
@@ -0,0 +1,78 @@
+// Common/MemoryLock.cpp
+
+#include "StdAfx.h"
+
+namespace NWindows {
+namespace NSecurity {
+
+#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
+
+}}
diff --git a/CPP/Windows/MemoryLock.h b/CPP/Windows/MemoryLock.h
new file mode 100755
index 00000000..03a88b41
--- /dev/null
+++ b/CPP/Windows/MemoryLock.h
@@ -0,0 +1,13 @@
+// Windows/MemoryLock.h
+
+#ifndef __WINDOWS_MEMORYLOCK_H
+#define __WINDOWS_MEMORYLOCK_H
+
+namespace NWindows {
+namespace NSecurity {
+
+bool EnableLockMemoryPrivilege(bool enable = true);
+
+}}
+
+#endif
diff --git a/CPP/Windows/Menu.cpp b/CPP/Windows/Menu.cpp
new file mode 100755
index 00000000..5869b365
--- /dev/null
+++ b/CPP/Windows/Menu.cpp
@@ -0,0 +1,178 @@
+// 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;
+ return InsertItem(itemIndex, byPosition, &si);
+ }
+}
+
+#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/CPP/Windows/Menu.h b/CPP/Windows/Menu.h
new file mode 100755
index 00000000..11ba5537
--- /dev/null
+++ b/CPP/Windows/Menu.h
@@ -0,0 +1,137 @@
+// Windows/Menu.h
+
+#ifndef __WINDOWS_MENU_H
+#define __WINDOWS_MENU_H
+
+#include "Common/String.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)); }
+ 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()
+ { return GetMenuItemCount(_menu); }
+
+ HMENU GetSubMenu(int pos)
+ { return ::GetSubMenu(_menu, pos); }
+ 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); }
+
+ 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)); }
+
+ bool InsertItem(UINT itemIndex, bool byPosition, LPCMENUITEMINFO itemInfo)
+ { return BOOLToBool(::InsertMenuItem(_menu, itemIndex, BoolToBOOL(byPosition), itemInfo)); }
+
+ bool RemoveItem(UINT item, UINT flags)
+ { return BOOLToBool(::RemoveMenu(_menu, item, flags)); }
+
+ #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); }
+};
+
+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/CPP/Windows/NationalTime.cpp b/CPP/Windows/NationalTime.cpp
new file mode 100755
index 00000000..76060216
--- /dev/null
+++ b/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/CPP/Windows/NationalTime.h b/CPP/Windows/NationalTime.h
new file mode 100755
index 00000000..4e40f84a
--- /dev/null
+++ b/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/CPP/Windows/Net.cpp b/CPP/Windows/Net.cpp
new file mode 100755
index 00000000..113cec94
--- /dev/null
+++ b/CPP/Windows/Net.cpp
@@ -0,0 +1,380 @@
+// Windows/Net.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Net.h"
+
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+
+#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/CPP/Windows/Net.h b/CPP/Windows/Net.h
new file mode 100755
index 00000000..ff501d70
--- /dev/null
+++ b/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/String.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/CPP/Windows/ProcessMessages.cpp b/CPP/Windows/ProcessMessages.cpp
new file mode 100755
index 00000000..2f2841c1
--- /dev/null
+++ b/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);
+ }
+ }
+}
+
+} \ No newline at end of file
diff --git a/CPP/Windows/ProcessMessages.h b/CPP/Windows/ProcessMessages.h
new file mode 100755
index 00000000..63f8ec8a
--- /dev/null
+++ b/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/CPP/Windows/PropVariant.cpp b/CPP/Windows/PropVariant.cpp
new file mode 100755
index 00000000..690e2b6c
--- /dev/null
+++ b/CPP/Windows/PropVariant.cpp
@@ -0,0 +1,312 @@
+// 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;
+}
+
+CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
+{
+ InternalClear();
+ vt = VT_BSTR;
+ wReserved1 = 0;
+ bstrVal = ::SysAllocString(lpszSrc);
+ if (bstrVal == NULL && lpszSrc != NULL)
+ {
+ vt = VT_ERROR;
+ scode = E_OUTOFMEMORY;
+ }
+ return *this;
+}
+
+
+CPropVariant& CPropVariant::operator=(bool bSrc)
+{
+ if (vt != VT_BOOL)
+ {
+ InternalClear();
+ vt = VT_BOOL;
+ }
+ boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(UInt32 value)
+{
+ if (vt != VT_UI4)
+ {
+ InternalClear();
+ vt = VT_UI4;
+ }
+ ulVal = value;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(UInt64 value)
+{
+ if (vt != VT_UI8)
+ {
+ InternalClear();
+ vt = VT_UI8;
+ }
+ uhVal.QuadPart = value;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(const FILETIME &value)
+{
+ if (vt != VT_FILETIME)
+ {
+ InternalClear();
+ vt = VT_FILETIME;
+ }
+ filetime = value;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(Int32 value)
+{
+ if (vt != VT_I4)
+ {
+ InternalClear();
+ vt = VT_I4;
+ }
+ lVal = value;
+
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(Byte value)
+{
+ if (vt != VT_UI1)
+ {
+ InternalClear();
+ vt = VT_UI1;
+ }
+ bVal = value;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(Int16 value)
+{
+ if (vt != VT_I2)
+ {
+ InternalClear();
+ vt = VT_I2;
+ }
+ iVal = value;
+ return *this;
+}
+
+/*
+CPropVariant& CPropVariant::operator=(LONG value)
+{
+ if (vt != VT_I4)
+ {
+ InternalClear();
+ vt = VT_I4;
+ }
+ lVal = value;
+ return *this;
+}
+*/
+
+static HRESULT MyPropVariantClear(PROPVARIANT *propVariant)
+{
+ switch(propVariant->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:
+ propVariant->vt = VT_EMPTY;
+ propVariant->wReserved1 = 0;
+ return S_OK;
+ }
+ return ::VariantClear((VARIANTARG *)propVariant);
+}
+
+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 *)(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))
+ {
+ vt = VT_ERROR;
+ scode = hr;
+ }
+}
+
+int CPropVariant::Compare(const CPropVariant &a)
+{
+ if(vt != a.vt)
+ return 0; // it's mean some bug
+ 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_INT:
+ return MyCompare(intVal, a.intVal);
+ */
+ 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/CPP/Windows/PropVariant.h b/CPP/Windows/PropVariant.h
new file mode 100755
index 00000000..d44215f0
--- /dev/null
+++ b/CPP/Windows/PropVariant.h
@@ -0,0 +1,57 @@
+// 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(UInt32 value) { vt = VT_UI4; wReserved1 = 0; ulVal = value; }
+ CPropVariant(UInt64 value) { vt = VT_UI8; wReserved1 = 0; uhVal = *(ULARGE_INTEGER*)&value; }
+ CPropVariant(const FILETIME &value) { vt = VT_FILETIME; wReserved1 = 0; filetime = value; }
+ CPropVariant(Int32 value) { vt = VT_I4; wReserved1 = 0; lVal = value; }
+ CPropVariant(Byte value) { vt = VT_UI1; wReserved1 = 0; bVal = value; }
+ CPropVariant(Int16 value) { vt = VT_I2; wReserved1 = 0; iVal = value; }
+ // CPropVariant(LONG value, VARTYPE vtSrc = VT_I4) { vt = vtSrc; lVal = value; }
+
+ CPropVariant& operator=(const CPropVariant& varSrc);
+ CPropVariant& operator=(const PROPVARIANT& varSrc);
+ CPropVariant& operator=(BSTR bstrSrc);
+ CPropVariant& operator=(LPCOLESTR lpszSrc);
+ CPropVariant& operator=(bool bSrc);
+ CPropVariant& operator=(UInt32 value);
+ CPropVariant& operator=(UInt64 value);
+ CPropVariant& operator=(const FILETIME &value);
+
+ CPropVariant& operator=(Int32 value);
+ CPropVariant& operator=(Byte value);
+ CPropVariant& operator=(Int16 value);
+ // CPropVariant& operator=(LONG 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/CPP/Windows/PropVariantConversions.cpp b/CPP/Windows/PropVariantConversions.cpp
new file mode 100755
index 00000000..80ba5ac2
--- /dev/null
+++ b/CPP/Windows/PropVariantConversions.cpp
@@ -0,0 +1,150 @@
+// PropVariantConversions.cpp
+
+#include "StdAfx.h"
+
+// #include <stdio.h>
+
+#include "PropVariantConversions.h"
+
+#include "Windows/Defs.h"
+
+#include "Common/StringConvert.h"
+#include "Common/IntToString.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(UInt32 value, char *s, int numPos)
+{
+ 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(st.wYear, s, 4);
+ *s++ = '-';
+ s = UIntToStringSpec(st.wMonth, s, 2);
+ *s++ = '-';
+ s = UIntToStringSpec(st.wDay, s, 2);
+ if (includeTime)
+ {
+ *s++ = ' ';
+ s = UIntToStringSpec(st.wHour, s, 2);
+ *s++ = ':';
+ s = UIntToStringSpec(st.wMinute, s, 2);
+ if (includeSeconds)
+ {
+ *s++ = ':';
+ UIntToStringSpec(st.wSecond, s, 2);
+ }
+ }
+ /*
+ sprintf(s, "%04d-%02d-%02d", st.wYear, st.wMonth, st.wDay);
+ if (includeTime)
+ {
+ sprintf(s + strlen(s), " %02d:%02d", st.wHour, st.wMinute);
+ if (includeSeconds)
+ sprintf(s + strlen(s), ":%02d", st.wSecond);
+ }
+ */
+ return true;
+}
+
+UString ConvertFileTimeToString(const FILETIME &fileTime, bool includeTime, bool includeSeconds)
+{
+ char s[32];
+ ConvertFileTimeToString(fileTime, s, includeTime, includeSeconds);
+ return GetUnicodeString(s);
+}
+
+
+UString ConvertPropVariantToString(const PROPVARIANT &propVariant)
+{
+ switch (propVariant.vt)
+ {
+ case VT_EMPTY:
+ return UString();
+ case VT_BSTR:
+ return propVariant.bstrVal;
+ case VT_UI1:
+ return ConvertUInt64ToString(propVariant.bVal);
+ case VT_UI2:
+ return ConvertUInt64ToString(propVariant.uiVal);
+ case VT_UI4:
+ return ConvertUInt64ToString(propVariant.ulVal);
+ case VT_UI8:
+ return ConvertUInt64ToString(propVariant.uhVal.QuadPart);
+ case VT_FILETIME:
+ return ConvertFileTimeToString(propVariant.filetime, true, true);
+ /*
+ case VT_I1:
+ return ConvertInt64ToString(propVariant.cVal);
+ */
+ case VT_I2:
+ return ConvertInt64ToString(propVariant.iVal);
+ case VT_I4:
+ return ConvertInt64ToString(propVariant.lVal);
+ case VT_I8:
+ return ConvertInt64ToString(propVariant.hVal.QuadPart);
+
+ case VT_BOOL:
+ return VARIANT_BOOLToBool(propVariant.boolVal) ? L"1" : L"0";
+ default:
+ #ifndef _WIN32_WCE
+ throw 150245;
+ #else
+ return UString();
+ #endif
+ }
+}
+
+UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &propVariant)
+{
+ switch (propVariant.vt)
+ {
+ case VT_UI1:
+ return propVariant.bVal;
+ case VT_UI2:
+ return propVariant.uiVal;
+ case VT_UI4:
+ return propVariant.ulVal;
+ case VT_UI8:
+ return (UInt64)propVariant.uhVal.QuadPart;
+ default:
+ #ifndef _WIN32_WCE
+ throw 151199;
+ #else
+ return 0;
+ #endif
+ }
+}
diff --git a/CPP/Windows/PropVariantConversions.h b/CPP/Windows/PropVariantConversions.h
new file mode 100755
index 00000000..a3f3ebbf
--- /dev/null
+++ b/CPP/Windows/PropVariantConversions.h
@@ -0,0 +1,14 @@
+// Windows/PropVariantConversions.h
+
+#ifndef __PROPVARIANTCONVERSIONS_H
+#define __PROPVARIANTCONVERSIONS_H
+
+#include "Common/Types.h"
+#include "Common/String.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 &propVariant);
+UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &propVariant);
+
+#endif
diff --git a/CPP/Windows/Registry.cpp b/CPP/Windows/Registry.cpp
new file mode 100755
index 00000000..2c6b6afc
--- /dev/null
+++ b/CPP/Windows/Registry.cpp
@@ -0,0 +1,324 @@
+// 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)
+
+CKey::~CKey()
+{
+ Close();
+}
+
+HKEY CKey::Detach()
+{
+ HKEY hKey = _object;
+ _object = NULL;
+ return hKey;
+}
+
+void CKey::Attach(HKEY hKey)
+{
+ MYASSERT(_object == NULL);
+ _object = hKey;
+}
+
+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::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;
+}
+
+}}
diff --git a/CPP/Windows/Registry.h b/CPP/Windows/Registry.h
new file mode 100755
index 00000000..435717bd
--- /dev/null
+++ b/CPP/Windows/Registry.h
@@ -0,0 +1,77 @@
+// Windows/Registry.h
+
+#ifndef __WINDOWS_REGISTRY_H
+#define __WINDOWS_REGISTRY_H
+
+#include "Common/Buffer.h"
+#include "Common/String.h"
+#include "Common/Types.h"
+
+namespace NWindows {
+namespace NRegistry {
+
+const TCHAR kKeyNameDelimiter = TEXT('\\');
+
+LONG SetValue(HKEY parentKey, LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value);
+
+class CKey
+{
+ HKEY _object;
+public:
+ CKey(): _object(NULL) {}
+ ~CKey();
+
+ operator HKEY() const { return _object; }
+
+ HKEY Detach();
+ void Attach(HKEY 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 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);
+
+ #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/CPP/Windows/ResourceString.cpp b/CPP/Windows/ResourceString.cpp
new file mode 100755
index 00000000..48dd4936
--- /dev/null
+++ b/CPP/Windows/ResourceString.cpp
@@ -0,0 +1,53 @@
+// 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(UINT resourceID)
+{
+ CSysString s;
+ int size = 256;
+ int len;
+ do
+ {
+ size += 256;
+ len = ::LoadString(g_hInstance, resourceID, s.GetBuffer(size - 1), size);
+ }
+ while (size - len <= 1);
+ s.ReleaseBuffer();
+ return s;
+}
+
+#ifndef _UNICODE
+UString MyLoadStringW(UINT resourceID)
+{
+ if (g_IsNT)
+ {
+ UString s;
+ int size = 256;
+ int len;
+ do
+ {
+ size += 256;
+ len = ::LoadStringW(g_hInstance, resourceID, s.GetBuffer(size - 1), size);
+ }
+ while (size - len <= 1);
+ s.ReleaseBuffer();
+ return s;
+ }
+ return GetUnicodeString(MyLoadString(resourceID));
+}
+#endif
+
+}
diff --git a/CPP/Windows/ResourceString.h b/CPP/Windows/ResourceString.h
new file mode 100755
index 00000000..a74f925d
--- /dev/null
+++ b/CPP/Windows/ResourceString.h
@@ -0,0 +1,20 @@
+// Windows/ResourceString.h
+
+#ifndef __WINDOWS_RESOURCESTRING_H
+#define __WINDOWS_RESOURCESTRING_H
+
+#include "Common/String.h"
+
+namespace NWindows {
+
+CSysString MyLoadString(UINT resourceID);
+#ifdef _UNICODE
+inline UString MyLoadStringW(UINT resourceID)
+ { return MyLoadString(resourceID); }
+#else
+UString MyLoadStringW(UINT resourceID);
+#endif
+
+}
+
+#endif
diff --git a/CPP/Windows/Security.cpp b/CPP/Windows/Security.cpp
new file mode 100755
index 00000000..05b3b640
--- /dev/null
+++ b/CPP/Windows/Security.cpp
@@ -0,0 +1,181 @@
+// Windows/Security.h
+
+#include "StdAfx.h"
+
+#include "Windows/Security.h"
+#include "Windows/Defs.h"
+
+#include "Common/StringConvert.h"
+#include "Defs.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;
+}
+
+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;
+ UString s = GetUnicodeString(SE_LOCK_MEMORY_NAME);
+ SetLsaString((LPWSTR)(LPCWSTR)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/CPP/Windows/Security.h b/CPP/Windows/Security.h
new file mode 100755
index 00000000..ded31b74
--- /dev/null
+++ b/CPP/Windows/Security.h
@@ -0,0 +1,168 @@
+// Windows/Security.h
+
+#ifndef __WINDOWS_SECURITY_H
+#define __WINDOWS_SECURITY_H
+
+#include "Common/String.h"
+#include "Windows/Defs.h"
+
+#include <NTSecAPI.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/CPP/Windows/Shell.cpp b/CPP/Windows/Shell.cpp
new file mode 100755
index 00000000..2906e2d4
--- /dev/null
+++ b/CPP/Windows/Shell.cpp
@@ -0,0 +1,292 @@
+// Windows/Shell.cpp
+
+#include "StdAfx.h"
+
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+#include "Common/MyCom.h"
+#include "Windows/Shell.h"
+#include "Windows/COM.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NShell {
+
+/////////////////////////
+// CItemIDList
+
+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;
+}
+
+CDrop::~CDrop()
+{
+ Free();
+}
+
+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));
+}
+
+
+/////////////////////////////
+// Functions
+
+bool GetPathFromIDList(LPCITEMIDLIST itemIDList, CSysString &path)
+{
+ bool result = BOOLToBool(::SHGetPathFromIDList(itemIDList, path.GetBuffer(MAX_PATH * 2)));
+ path.ReleaseBuffer();
+ return result;
+}
+
+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)
+{
+ 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;
+ }
+ return 0;
+}
+
+
+bool BrowseForFolder(HWND owner, LPCTSTR title, UINT ulFlags,
+ LPCTSTR initialFolder, CSysString &resultPath)
+{
+ CSysString displayName;
+ BROWSEINFO browseInfo;
+ browseInfo.hwndOwner = owner;
+ browseInfo.pidlRoot = NULL;
+ browseInfo.pszDisplayName = displayName.GetBuffer(MAX_PATH);
+ browseInfo.lpszTitle = title;
+ 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,
+ BIF_NEWDIALOGSTYLE | 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
+
+}}
diff --git a/CPP/Windows/Shell.h b/CPP/Windows/Shell.h
new file mode 100755
index 00000000..4770a454
--- /dev/null
+++ b/CPP/Windows/Shell.h
@@ -0,0 +1,92 @@
+// Windows/Shell.h
+
+#ifndef __WINDOWS_SHELL_H
+#define __WINDOWS_SHELL_H
+
+#include <windows.h>
+#include <shlobj.h>
+
+#include "Common/String.h"
+#include "Windows/Defs.h"
+
+
+namespace NWindows{
+namespace NShell{
+
+/////////////////////////
+// CItemIDList
+
+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();
+ 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);
+};
+
+/////////////////////////////
+// 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 \ No newline at end of file
diff --git a/CPP/Windows/StdAfx.h b/CPP/Windows/StdAfx.h
new file mode 100755
index 00000000..e7924c8f
--- /dev/null
+++ b/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/CPP/Windows/Synchronization.cpp b/CPP/Windows/Synchronization.cpp
new file mode 100755
index 00000000..64b811da
--- /dev/null
+++ b/CPP/Windows/Synchronization.cpp
@@ -0,0 +1,17 @@
+// Windows/Synchronization.cpp
+
+#include "StdAfx.h"
+
+#include "Synchronization.h"
+
+namespace NWindows {
+namespace NSynchronization {
+
+CEvent::CEvent(bool manualReset, bool initiallyOwn, LPCTSTR name,
+ LPSECURITY_ATTRIBUTES securityAttributes)
+{
+ if (!Create(manualReset, initiallyOwn, name, securityAttributes))
+ throw "CreateEvent error";
+}
+
+}}
diff --git a/CPP/Windows/Synchronization.h b/CPP/Windows/Synchronization.h
new file mode 100755
index 00000000..89450276
--- /dev/null
+++ b/CPP/Windows/Synchronization.h
@@ -0,0 +1,133 @@
+// Windows/Synchronization.h
+
+#ifndef __WINDOWS_SYNCHRONIZATION_H
+#define __WINDOWS_SYNCHRONIZATION_H
+
+#include "Defs.h"
+#include "Handle.h"
+
+namespace NWindows {
+namespace NSynchronization {
+
+class CObject: public CHandle
+{
+public:
+ bool Lock(DWORD timeoutInterval = INFINITE)
+ { return (::WaitForSingleObject(_handle, timeoutInterval) == WAIT_OBJECT_0); }
+};
+
+class CBaseEvent: public CObject
+{
+public:
+ bool Create(bool manualReset, bool initiallyOwn, LPCTSTR name = NULL,
+ LPSECURITY_ATTRIBUTES securityAttributes = NULL)
+ {
+ _handle = ::CreateEvent(securityAttributes, BoolToBOOL(manualReset),
+ BoolToBOOL(initiallyOwn), name);
+ return (_handle != 0);
+ }
+
+ bool Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
+ {
+ _handle = ::OpenEvent(desiredAccess, BoolToBOOL(inheritHandle), name);
+ return (_handle != 0);
+ }
+
+ bool Set() { return BOOLToBool(::SetEvent(_handle)); }
+ bool Pulse() { return BOOLToBool(::PulseEvent(_handle)); }
+ bool Reset() { return BOOLToBool(::ResetEvent(_handle)); }
+};
+
+class CEvent: public CBaseEvent
+{
+public:
+ CEvent() {};
+ CEvent(bool manualReset, bool initiallyOwn,
+ LPCTSTR name = NULL, LPSECURITY_ATTRIBUTES securityAttributes = NULL);
+};
+
+class CManualResetEvent: public CEvent
+{
+public:
+ CManualResetEvent(bool initiallyOwn = false, LPCTSTR name = NULL,
+ LPSECURITY_ATTRIBUTES securityAttributes = NULL):
+ CEvent(true, initiallyOwn, name, securityAttributes) {};
+};
+
+class CAutoResetEvent: public CEvent
+{
+public:
+ CAutoResetEvent(bool initiallyOwn = false, LPCTSTR name = NULL,
+ LPSECURITY_ATTRIBUTES securityAttributes = NULL):
+ CEvent(false, initiallyOwn, name, securityAttributes) {};
+};
+
+class CMutex: public CObject
+{
+public:
+ bool Create(bool initiallyOwn, LPCTSTR name = NULL,
+ LPSECURITY_ATTRIBUTES securityAttributes = NULL)
+ {
+ _handle = ::CreateMutex(securityAttributes, BoolToBOOL(initiallyOwn), name);
+ return (_handle != 0);
+ }
+ bool Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
+ {
+ _handle = ::OpenMutex(desiredAccess, BoolToBOOL(inheritHandle), name);
+ return (_handle != 0);
+ }
+ bool Release() { return BOOLToBool(::ReleaseMutex(_handle)); }
+};
+
+class CMutexLock
+{
+ CMutex *_object;
+public:
+ CMutexLock(CMutex &object): _object(&object) { _object->Lock(); }
+ ~CMutexLock() { _object->Release(); }
+};
+
+class CSemaphore: public CObject
+{
+public:
+ bool Create(LONG initiallyCount, LONG maxCount, LPCTSTR name = NULL,
+ LPSECURITY_ATTRIBUTES securityAttributes = NULL)
+ {
+ _handle = ::CreateSemaphore(securityAttributes, initiallyCount, maxCount, name);
+ return (_handle != 0);
+ }
+ bool Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
+ {
+ _handle = ::OpenSemaphore(desiredAccess, BoolToBOOL(inheritHandle), name);
+ return (_handle != 0);
+ }
+ bool Release(LONG releaseCount = 1, LPLONG previousCount = NULL)
+ {
+ return BOOLToBool(::ReleaseSemaphore(_handle, releaseCount, previousCount));
+ }
+};
+
+class CCriticalSection
+{
+ CRITICAL_SECTION _object;
+ // void Initialize() { ::InitializeCriticalSection(&_object); }
+ // void Delete() { ::DeleteCriticalSection(&_object); }
+public:
+ CCriticalSection() { ::InitializeCriticalSection(&_object); }
+ ~CCriticalSection() { ::DeleteCriticalSection(&_object); }
+ void Enter() { ::EnterCriticalSection(&_object); }
+ void Leave() { ::LeaveCriticalSection(&_object); }
+};
+
+class CCriticalSectionLock
+{
+ CCriticalSection *_object;
+ void Unlock() { _object->Leave(); }
+public:
+ CCriticalSectionLock(CCriticalSection &object): _object(&object) {_object->Enter(); }
+ ~CCriticalSectionLock() { Unlock(); }
+};
+
+}}
+
+#endif
diff --git a/CPP/Windows/System.h b/CPP/Windows/System.h
new file mode 100755
index 00000000..e1a5abac
--- /dev/null
+++ b/CPP/Windows/System.h
@@ -0,0 +1,21 @@
+// Windows/System.h
+
+#ifndef __WINDOWS_SYSTEM_H
+#define __WINDOWS_SYSTEM_H
+
+#include "..\Common\Types.h"
+
+namespace NWindows {
+namespace NSystem {
+
+inline UInt32 GetNumberOfProcessors()
+{
+ SYSTEM_INFO systemInfo;
+ GetSystemInfo(&systemInfo);
+ return (UInt32)systemInfo.dwNumberOfProcessors;
+}
+
+
+}}
+
+#endif
diff --git a/CPP/Windows/Thread.h b/CPP/Windows/Thread.h
new file mode 100755
index 00000000..5b676027
--- /dev/null
+++ b/CPP/Windows/Thread.h
@@ -0,0 +1,51 @@
+// Windows/Thread.h
+
+#ifndef __WINDOWS_THREAD_H
+#define __WINDOWS_THREAD_H
+
+// #include <process.h>
+
+#include "Handle.h"
+#include "Defs.h"
+
+namespace NWindows {
+
+class CThread: public CHandle
+{
+ bool IsOpen() const { return _handle != 0; }
+public:
+ bool Create(LPSECURITY_ATTRIBUTES threadAttributes,
+ SIZE_T stackSize, LPTHREAD_START_ROUTINE startAddress,
+ LPVOID parameter, DWORD creationFlags, LPDWORD threadId)
+ {
+ _handle = ::CreateThread(threadAttributes, stackSize, startAddress,
+ parameter, creationFlags, threadId);
+ return (_handle != NULL);
+ }
+ bool Create(LPTHREAD_START_ROUTINE startAddress, LPVOID parameter)
+ {
+ DWORD threadId;
+ return Create(NULL, 0, startAddress, parameter, 0, &threadId);
+ /*
+ _handle = (HANDLE)_beginthreadex(NULL, 0, startAddress, parameter, 0, NULL);
+ return (_handle != NULL);
+ */
+ }
+
+ DWORD Resume() { return ::ResumeThread(_handle); }
+ DWORD Suspend() { return ::SuspendThread(_handle); }
+ bool Terminate(DWORD exitCode) { return BOOLToBool(::TerminateThread(_handle, exitCode)); }
+ int GetPriority() { return ::GetThreadPriority(_handle); }
+ bool SetPriority(int priority) { return BOOLToBool(::SetThreadPriority(_handle, priority)); }
+
+ bool Wait()
+ {
+ if (!IsOpen())
+ return true;
+ return (::WaitForSingleObject(_handle, INFINITE) == WAIT_OBJECT_0);
+ }
+};
+
+}
+
+#endif
diff --git a/CPP/Windows/Time.h b/CPP/Windows/Time.h
new file mode 100755
index 00000000..fbba2ddb
--- /dev/null
+++ b/CPP/Windows/Time.h
@@ -0,0 +1,66 @@
+// Windows/Time.h
+
+#ifndef __WINDOWS_TIME_H
+#define __WINDOWS_TIME_H
+
+#include "Common/Types.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NTime {
+
+inline bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime)
+{
+ return BOOLToBool(::DosDateTimeToFileTime(UInt16(dosTime >> 16),
+ UInt16(dosTime & 0xFFFF), &fileTime));
+}
+
+const UInt32 kHighDosTime = 0xFF9FBF7D;
+const UInt32 kLowDosTime = 0x210000;
+
+inline bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime)
+{
+ WORD datePart, timePart;
+ if (!::FileTimeToDosDateTime(&fileTime, &datePart, &timePart))
+ {
+ if (fileTime.dwHighDateTime >= 0x01C00000) // 2000
+ dosTime = kHighDosTime;
+ else
+ dosTime = kLowDosTime;
+ return false;
+ }
+ dosTime = (((UInt32)datePart) << 16) + timePart;
+ return true;
+}
+
+const UInt32 kNumTimeQuantumsInSecond = 10000000;
+const UInt64 kUnixTimeStartValue = ((UInt64)kNumTimeQuantumsInSecond) * 60 * 60 * 24 * 134774;
+
+inline void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime)
+{
+ UInt64 v = kUnixTimeStartValue + ((UInt64)unixTime) * kNumTimeQuantumsInSecond;
+ fileTime.dwLowDateTime = (DWORD)v;
+ fileTime.dwHighDateTime = (DWORD)(v >> 32);
+}
+
+inline bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime)
+{
+ UInt64 winTime = (((UInt64)fileTime.dwHighDateTime) << 32) + fileTime.dwLowDateTime;
+ if (winTime < kUnixTimeStartValue)
+ {
+ unixTime = 0;
+ return false;
+ }
+ winTime = (winTime - kUnixTimeStartValue) / kNumTimeQuantumsInSecond;
+ if (winTime > 0xFFFFFFFF)
+ {
+ unixTime = 0xFFFFFFFF;
+ return false;
+ }
+ unixTime = (UInt32)winTime;
+ return true;
+}
+
+}}
+
+#endif
diff --git a/CPP/Windows/Window.cpp b/CPP/Windows/Window.cpp
new file mode 100755
index 00000000..b30ccdc3
--- /dev/null
+++ b/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/CPP/Windows/Window.h b/CPP/Windows/Window.h
new file mode 100755
index 00000000..3df80191
--- /dev/null
+++ b/CPP/Windows/Window.h
@@ -0,0 +1,219 @@
+// Windows/Window.h
+
+#ifndef __WINDOWS_WINDOW_H
+#define __WINDOWS_WINDOW_H
+
+#include "Windows/Defs.h"
+#include "Common/String.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
+
+
+
+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;
+ }
+
+ HWND GetParent() const { return ::GetParent(_window); }
+ bool GetWindowRect(LPRECT rect) const { return BOOLToBool(::GetWindowRect(_window,rect )); }
+ bool IsZoomed() const { return BOOLToBool(::IsZoomed(_window)); }
+ 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 GetClientRect(LPRECT rect) { return BOOLToBool(::GetClientRect(_window, rect)); }
+ bool Show(int cmdShow) { return BOOLToBool(::ShowWindow(_window, cmdShow)); }
+ bool SetPlacement(CONST WINDOWPLACEMENT *placement) { return BOOLToBool(::SetWindowPlacement(_window, placement)); }
+ bool GetPlacement(WINDOWPLACEMENT *placement) { return BOOLToBool(::GetWindowPlacement(_window, placement)); }
+ 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); }
+
+ #ifndef _WIN32_WCE
+ LONG_PTR SetStyle(LONG_PTR style)
+ { return SetLongPtr(GWL_STYLE, style); }
+ LONG_PTR GetStyle( ) const
+ { return GetLongPtr(GWL_STYLE); }
+ #else
+ LONG SetStyle(LONG_PTR style)
+ { return SetLong(GWL_STYLE, style); }
+ DWORD GetStyle( ) const
+ { return GetLong(GWL_STYLE); }
+ #endif
+
+ 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); }
+
+ #ifndef _WIN32_WCE
+ 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 _WIN32_WCE
+ 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)); }
+};
+
+}
+
+#endif
+