From d9666cf046a8453b33b3e2fbf4d82295a9f87df3 Mon Sep 17 00:00:00 2001 From: Igor Pavlov Date: Sat, 20 Jan 2007 00:00:00 +0000 Subject: 4.44 beta --- CPP/Windows/COM.cpp | 37 ++ CPP/Windows/COM.h | 57 +++ CPP/Windows/CommonDialog.cpp | 164 +++++++ CPP/Windows/CommonDialog.h | 17 + CPP/Windows/Console.cpp | 10 + CPP/Windows/Console.h | 52 ++ CPP/Windows/Control/ComboBox.cpp | 63 +++ CPP/Windows/Control/ComboBox.h | 54 +++ CPP/Windows/Control/Dialog.cpp | 145 ++++++ CPP/Windows/Control/Dialog.h | 144 ++++++ CPP/Windows/Control/Edit.h | 21 + CPP/Windows/Control/ImageList.cpp | 11 + CPP/Windows/Control/ImageList.h | 86 ++++ CPP/Windows/Control/ListView.cpp | 58 +++ CPP/Windows/Control/ListView.h | 138 ++++++ CPP/Windows/Control/ProgressBar.h | 41 ++ CPP/Windows/Control/PropertyPage.cpp | 163 +++++++ CPP/Windows/Control/PropertyPage.h | 47 ++ CPP/Windows/Control/ReBar.h | 35 ++ CPP/Windows/Control/Static.h | 27 ++ CPP/Windows/Control/StatusBar.h | 43 ++ CPP/Windows/Control/StdAfx.h | 9 + CPP/Windows/Control/ToolBar.h | 34 ++ CPP/Windows/Control/Trackbar.h | 28 ++ CPP/Windows/Control/Window2.cpp | 203 ++++++++ CPP/Windows/Control/Window2.h | 59 +++ CPP/Windows/DLL.cpp | 115 +++++ CPP/Windows/DLL.h | 54 +++ CPP/Windows/Defs.h | 21 + CPP/Windows/Error.cpp | 50 ++ CPP/Windows/Error.h | 33 ++ CPP/Windows/FileDevice.cpp | 49 ++ CPP/Windows/FileDevice.h | 123 +++++ CPP/Windows/FileDir.cpp | 835 +++++++++++++++++++++++++++++++++ CPP/Windows/FileDir.h | 178 +++++++ CPP/Windows/FileFind.cpp | 408 ++++++++++++++++ CPP/Windows/FileFind.h | 153 ++++++ CPP/Windows/FileIO.cpp | 305 ++++++++++++ CPP/Windows/FileIO.h | 97 ++++ CPP/Windows/FileMapping.cpp | 14 + CPP/Windows/FileMapping.h | 50 ++ CPP/Windows/FileName.cpp | 111 +++++ CPP/Windows/FileName.h | 43 ++ CPP/Windows/FileSystem.cpp | 126 +++++ CPP/Windows/FileSystem.h | 51 ++ CPP/Windows/Handle.h | 37 ++ CPP/Windows/Memory.cpp | 64 +++ CPP/Windows/Memory.h | 45 ++ CPP/Windows/MemoryLock.cpp | 78 +++ CPP/Windows/MemoryLock.h | 13 + CPP/Windows/Menu.cpp | 178 +++++++ CPP/Windows/Menu.h | 137 ++++++ CPP/Windows/NationalTime.cpp | 37 ++ CPP/Windows/NationalTime.h | 20 + CPP/Windows/Net.cpp | 380 +++++++++++++++ CPP/Windows/Net.h | 87 ++++ CPP/Windows/ProcessMessages.cpp | 22 + CPP/Windows/ProcessMessages.h | 14 + CPP/Windows/PropVariant.cpp | 312 ++++++++++++ CPP/Windows/PropVariant.h | 57 +++ CPP/Windows/PropVariantConversions.cpp | 150 ++++++ CPP/Windows/PropVariantConversions.h | 14 + CPP/Windows/Registry.cpp | 324 +++++++++++++ CPP/Windows/Registry.h | 77 +++ CPP/Windows/ResourceString.cpp | 53 +++ CPP/Windows/ResourceString.h | 20 + CPP/Windows/Security.cpp | 181 +++++++ CPP/Windows/Security.h | 168 +++++++ CPP/Windows/Shell.cpp | 292 ++++++++++++ CPP/Windows/Shell.h | 92 ++++ CPP/Windows/StdAfx.h | 9 + CPP/Windows/Synchronization.cpp | 17 + CPP/Windows/Synchronization.h | 133 ++++++ CPP/Windows/System.h | 21 + CPP/Windows/Thread.h | 51 ++ CPP/Windows/Time.h | 66 +++ CPP/Windows/Window.cpp | 169 +++++++ CPP/Windows/Window.h | 219 +++++++++ 78 files changed, 8099 insertions(+) create mode 100755 CPP/Windows/COM.cpp create mode 100755 CPP/Windows/COM.h create mode 100755 CPP/Windows/CommonDialog.cpp create mode 100755 CPP/Windows/CommonDialog.h create mode 100755 CPP/Windows/Console.cpp create mode 100755 CPP/Windows/Console.h create mode 100755 CPP/Windows/Control/ComboBox.cpp create mode 100755 CPP/Windows/Control/ComboBox.h create mode 100755 CPP/Windows/Control/Dialog.cpp create mode 100755 CPP/Windows/Control/Dialog.h create mode 100755 CPP/Windows/Control/Edit.h create mode 100755 CPP/Windows/Control/ImageList.cpp create mode 100755 CPP/Windows/Control/ImageList.h create mode 100755 CPP/Windows/Control/ListView.cpp create mode 100755 CPP/Windows/Control/ListView.h create mode 100755 CPP/Windows/Control/ProgressBar.h create mode 100755 CPP/Windows/Control/PropertyPage.cpp create mode 100755 CPP/Windows/Control/PropertyPage.h create mode 100755 CPP/Windows/Control/ReBar.h create mode 100755 CPP/Windows/Control/Static.h create mode 100755 CPP/Windows/Control/StatusBar.h create mode 100755 CPP/Windows/Control/StdAfx.h create mode 100755 CPP/Windows/Control/ToolBar.h create mode 100755 CPP/Windows/Control/Trackbar.h create mode 100755 CPP/Windows/Control/Window2.cpp create mode 100755 CPP/Windows/Control/Window2.h create mode 100755 CPP/Windows/DLL.cpp create mode 100755 CPP/Windows/DLL.h create mode 100755 CPP/Windows/Defs.h create mode 100755 CPP/Windows/Error.cpp create mode 100755 CPP/Windows/Error.h create mode 100755 CPP/Windows/FileDevice.cpp create mode 100755 CPP/Windows/FileDevice.h create mode 100755 CPP/Windows/FileDir.cpp create mode 100755 CPP/Windows/FileDir.h create mode 100755 CPP/Windows/FileFind.cpp create mode 100755 CPP/Windows/FileFind.h create mode 100755 CPP/Windows/FileIO.cpp create mode 100755 CPP/Windows/FileIO.h create mode 100755 CPP/Windows/FileMapping.cpp create mode 100755 CPP/Windows/FileMapping.h create mode 100755 CPP/Windows/FileName.cpp create mode 100755 CPP/Windows/FileName.h create mode 100755 CPP/Windows/FileSystem.cpp create mode 100755 CPP/Windows/FileSystem.h create mode 100755 CPP/Windows/Handle.h create mode 100755 CPP/Windows/Memory.cpp create mode 100755 CPP/Windows/Memory.h create mode 100755 CPP/Windows/MemoryLock.cpp create mode 100755 CPP/Windows/MemoryLock.h create mode 100755 CPP/Windows/Menu.cpp create mode 100755 CPP/Windows/Menu.h create mode 100755 CPP/Windows/NationalTime.cpp create mode 100755 CPP/Windows/NationalTime.h create mode 100755 CPP/Windows/Net.cpp create mode 100755 CPP/Windows/Net.h create mode 100755 CPP/Windows/ProcessMessages.cpp create mode 100755 CPP/Windows/ProcessMessages.h create mode 100755 CPP/Windows/PropVariant.cpp create mode 100755 CPP/Windows/PropVariant.h create mode 100755 CPP/Windows/PropVariantConversions.cpp create mode 100755 CPP/Windows/PropVariantConversions.h create mode 100755 CPP/Windows/Registry.cpp create mode 100755 CPP/Windows/Registry.h create mode 100755 CPP/Windows/ResourceString.cpp create mode 100755 CPP/Windows/ResourceString.h create mode 100755 CPP/Windows/Security.cpp create mode 100755 CPP/Windows/Security.h create mode 100755 CPP/Windows/Shell.cpp create mode 100755 CPP/Windows/Shell.h create mode 100755 CPP/Windows/StdAfx.h create mode 100755 CPP/Windows/Synchronization.cpp create mode 100755 CPP/Windows/Synchronization.h create mode 100755 CPP/Windows/System.h create mode 100755 CPP/Windows/Thread.h create mode 100755 CPP/Windows/Time.h create mode 100755 CPP/Windows/Window.cpp create mode 100755 CPP/Windows/Window.h (limited to 'CPP/Windows') 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 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 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 + +#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 + +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 ¶m) 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 + +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 ¶m) 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 &pagesInfo, HWND hwndParent, const UString &title) +{ + #ifndef _UNICODE + AStringVector titles; + #endif + #ifndef _UNICODE + CRecordVector pagesA; + #endif + CRecordVector 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 &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 + +#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 *)¤tSize); + 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 *)¤tSize); + 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 + +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 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 +#include + +#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 + +#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 + -- cgit v1.2.3