This commit is contained in:
Igor Pavlov
2014-11-23 00:00:00 +00:00
committed by Kornel Lesiński
parent 83f8ddcc5b
commit f08f4dcc3c
1158 changed files with 76451 additions and 35082 deletions
Executable → Regular
View File
Executable → Regular
+1 -2
View File
@@ -3,7 +3,7 @@
#ifndef __WINDOWS_COM_H
#define __WINDOWS_COM_H
#include "Common/MyString.h"
#include "../Common/MyString.h"
namespace NWindows {
namespace NCOM {
@@ -63,7 +63,6 @@ HRESULT StringToGUIDA(const char *string, GUID &classID);
#define StringToGUID StringToGUIDA
#endif
}}
#endif
Executable → Regular
+9 -15
View File
@@ -6,13 +6,12 @@
#include <winuserm.h>
#endif
#include "Windows/Clipboard.h"
#include "Windows/Defs.h"
#include "Windows/Memory.h"
#include "Windows/Shell.h"
#include "Windows/Memory.h"
#include "../Common/StringConvert.h"
#include "Common/StringConvert.h"
#include "Clipboard.h"
#include "Defs.h"
#include "MemoryGlobal.h"
#include "Shell.h"
namespace NWindows {
@@ -22,11 +21,6 @@ bool CClipboard::Open(HWND wndNewOwner)
return m_Open;
}
CClipboard::~CClipboard()
{
Close();
}
bool CClipboard::Close()
{
if (!m_Open)
@@ -94,7 +88,7 @@ bool ClipboardGetFileNames(UStringVector &names)
}
*/
static bool ClipboardSetData(UINT uFormat, const void *data, size_t size)
static bool ClipboardSetData(UINT uFormat, const void *data, size_t size) throw()
{
NMemory::CGlobal global;
if (!global.Alloc(GMEM_DDESHARE | GMEM_MOVEABLE, size))
@@ -121,13 +115,13 @@ bool ClipboardSetText(HWND owner, const UString &s)
return false;
bool res;
res = ClipboardSetData(CF_UNICODETEXT, (const wchar_t *)s, (s.Length() + 1) * sizeof(wchar_t));
res = ClipboardSetData(CF_UNICODETEXT, (const wchar_t *)s, (s.Len() + 1) * sizeof(wchar_t));
#ifndef _UNICODE
AString a;
a = UnicodeStringToMultiByte(s, CP_ACP);
res |= ClipboardSetData(CF_TEXT, (const char *)a, (a.Length() + 1) * sizeof(char));
res |= ClipboardSetData(CF_TEXT, (const char *)a, (a.Len() + 1) * sizeof(char));
a = UnicodeStringToMultiByte(s, CP_OEMCP);
res |= ClipboardSetData(CF_OEMTEXT, (const char *)a, (a.Length() + 1) * sizeof(char));
res |= ClipboardSetData(CF_OEMTEXT, (const char *)a, (a.Len() + 1) * sizeof(char));
#endif
return res;
}
Executable → Regular
+4 -4
View File
@@ -3,7 +3,7 @@
#ifndef __CLIPBOARD_H
#define __CLIPBOARD_H
#include "Common/MyString.h"
#include "../Common/MyString.h"
namespace NWindows {
@@ -12,9 +12,9 @@ class CClipboard
bool m_Open;
public:
CClipboard(): m_Open(false) {};
~CClipboard();
bool Open(HWND wndNewOwner);
bool Close();
~CClipboard() { Close(); }
bool Open(HWND wndNewOwner) throw();
bool Close() throw();
};
bool ClipboardIsFormatAvailableHDROP();
Executable → Regular
+119 -120
View File
@@ -7,176 +7,175 @@
#endif
#ifndef _UNICODE
#include "Common/StringConvert.h"
#include "../Common/StringConvert.h"
#endif
#include "Common/MyCom.h"
#include "Windows/Defs.h"
#include "CommonDialog.h"
#include "Defs.h"
#ifndef _UNICODE
extern bool g_IsNT;
#endif
namespace NWindows{
namespace NWindows {
#ifndef _UNICODE
class CDoubleZeroStringListA
{
CRecordVector<int> m_Indexes;
AString m_String;
LPTSTR Buf;
unsigned Size;
public:
void Add(LPCSTR s);
void SetForBuffer(LPSTR buffer);
CDoubleZeroStringListA(LPSTR buf, unsigned size): Buf(buf), Size(size) {}
bool Add(LPCSTR s) throw();
void Finish() { *Buf = 0; }
};
void CDoubleZeroStringListA::Add(LPCSTR s)
bool CDoubleZeroStringListA::Add(LPCSTR s)
{
m_String += s;
m_Indexes.Add(m_String.Length());
m_String += ' ';
unsigned len = MyStringLen(s) + 1;
if (len >= Size)
return false;
MyStringCopy(Buf, s);
Buf += len;
Size -= len;
return true;
}
void CDoubleZeroStringListA::SetForBuffer(LPSTR buffer)
{
MyStringCopy(buffer, (const char *)m_String);
for (int i = 0; i < m_Indexes.Size(); i++)
buffer[m_Indexes[i]] = '\0';
}
#endif
class CDoubleZeroStringListW
{
CRecordVector<int> m_Indexes;
UString m_String;
LPWSTR Buf;
unsigned Size;
public:
void Add(LPCWSTR s);
void SetForBuffer(LPWSTR buffer);
CDoubleZeroStringListW(LPWSTR buf, unsigned size): Buf(buf), Size(size) {}
bool Add(LPCWSTR s) throw();
void Finish() { *Buf = 0; }
};
void CDoubleZeroStringListW::Add(LPCWSTR s)
bool CDoubleZeroStringListW::Add(LPCWSTR s)
{
m_String += s;
m_Indexes.Add(m_String.Length());
m_String += L' ';
unsigned len = MyStringLen(s) + 1;
if (len >= Size)
return false;
MyStringCopy(Buf, s);
Buf += len;
Size -= len;
return true;
}
void CDoubleZeroStringListW::SetForBuffer(LPWSTR buffer)
{
MyStringCopy(buffer, (const wchar_t *)m_String);
for (int i = 0; i < m_Indexes.Size(); i++)
buffer[m_Indexes[i]] = L'\0';
}
#define MY__OFN_PROJECT 0x00400000
#define MY__OFN_SHOW_ALL 0x01000000
#define MY_OFN_PROJECT 0x00400000
#define MY_OFN_SHOW_ALL 0x01000000
/* if (lpstrFilter == NULL && nFilterIndex == 0)
MSDN : "the system doesn't show any files",
but WinXP-64 shows all files. Why ??? */
bool MyGetOpenFileName(HWND hwnd, LPCWSTR title, LPCWSTR fullFileName,
LPCWSTR s, UString &resPath
/*
structures
OPENFILENAMEW
OPENFILENAMEA
contain additional members:
#if (_WIN32_WINNT >= 0x0500)
void *pvReserved;
DWORD dwReserved;
DWORD FlagsEx;
#endif
If we compile the source code with (_WIN32_WINNT >= 0x0500), some functions
will not work at NT 4.0, if we use sizeof(OPENFILENAME*).
So we use size of old version of structure. */
#if defined(UNDER_CE) || defined(_WIN64) || (_WIN32_WINNT < 0x0500)
// || !defined(WINVER)
#define my_compatib_OPENFILENAMEA_size sizeof(OPENFILENAMEA)
#define my_compatib_OPENFILENAMEW_size sizeof(OPENFILENAMEW)
#else
#define my_compatib_OPENFILENAMEA_size OPENFILENAME_SIZE_VERSION_400A
#define my_compatib_OPENFILENAMEW_size OPENFILENAME_SIZE_VERSION_400W
#endif
#define CONV_U_To_A(dest, src, temp) AString temp; if (src) { temp = GetSystemString(src); dest = temp; }
bool MyGetOpenFileName(HWND hwnd, LPCWSTR title,
LPCWSTR initialDir,
LPCWSTR filePath,
LPCWSTR filterDescription,
LPCWSTR filter,
UString &resPath
#ifdef UNDER_CE
, bool openFolder
#endif
)
{
const int kBufferSize = MAX_PATH * 2;
const unsigned kBufSize = MAX_PATH * 2;
const unsigned kFilterBufSize = MAX_PATH;
if (!filter)
filter = L"*.*";
#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)
CHAR buf[kBufSize];
MyStringCopy(buf, (const char *)GetSystemString(filePath));
// OPENFILENAME_NT4A
OPENFILENAMEA p;
memset(&p, 0, sizeof(p));
p.lStructSize = my_compatib_OPENFILENAMEA_size;
p.hwndOwner = hwnd;
CHAR filterBuf[kFilterBufSize];
{
titleA = GetSystemString(title);
info.lpstrTitle = titleA;
CDoubleZeroStringListA dz(filterBuf, kFilterBufSize);
dz.Add(GetSystemString(filterDescription ? filterDescription : filter));
dz.Add(GetSystemString(filter));
dz.Finish();
p.lpstrFilter = filterBuf;
p.nFilterIndex = 1;
}
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);
p.lpstrFile = buf;
p.nMaxFile = kBufSize;
CONV_U_To_A(p.lpstrInitialDir, initialDir, initialDirA);
CONV_U_To_A(p.lpstrTitle, title, titleA);
p.Flags = OFN_EXPLORER | OFN_HIDEREADONLY;
bool res = BOOLToBool(::GetOpenFileNameA(&p));
resPath = GetUnicodeString(buf);
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;
WCHAR buf[kBufSize];
MyStringCopy(buf, filePath);
// OPENFILENAME_NT4W
OPENFILENAMEW p;
memset(&p, 0, sizeof(p));
p.lStructSize = my_compatib_OPENFILENAMEW_size;
p.hwndOwner = hwnd;
WCHAR filterBuf[kFilterBufSize];
{
CDoubleZeroStringListW dz(filterBuf, kFilterBufSize);
dz.Add(filterDescription ? filterDescription : filter);
dz.Add(filter);
dz.Finish();
p.lpstrFilter = filterBuf;
p.nFilterIndex = 1;
}
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
p.lpstrFile = buf;
p.nMaxFile = kBufSize;
p.lpstrInitialDir = initialDir;
p.lpstrTitle = title;
p.Flags = OFN_EXPLORER | OFN_HIDEREADONLY
#ifdef UNDER_CE
| (openFolder ? (MY_OFN_PROJECT | MY_OFN_SHOW_ALL) : 0)
| (openFolder ? (MY__OFN_PROJECT | MY__OFN_SHOW_ALL) : 0)
#endif
;
;
info.nFileOffset = 0;
info.nFileExtension = 0;
info.lpstrDefExt = NULL;
info.lCustData = 0;
info.lpfnHook = NULL;
info.lpTemplateName = NULL;
bool res = BOOLToBool(::GetOpenFileNameW(&info));
resPath = buffer;
bool res = BOOLToBool(::GetOpenFileNameW(&p));
resPath = buf;
return res;
}
}
Executable → Regular
+8 -4
View File
@@ -3,12 +3,16 @@
#ifndef __WINDOWS_COMMON_DIALOG_H
#define __WINDOWS_COMMON_DIALOG_H
#include "Common/MyString.h"
#include "../Common/MyString.h"
namespace NWindows{
namespace NWindows {
bool MyGetOpenFileName(HWND hwnd, LPCWSTR title, LPCWSTR fullFileName,
LPCWSTR s, UString &resPath
bool MyGetOpenFileName(HWND hwnd, LPCWSTR title,
LPCWSTR initialDir, // can be NULL, so dir prefix in filePath will be used
LPCWSTR filePath, // full path
LPCWSTR filterDescription, // like "All files (*.*)"
LPCWSTR filter, // like "*.exe"
UString &resPath
#ifdef UNDER_CE
, bool openFolder = false
#endif
Executable → Regular
View File
Executable → Regular
+24 -24
View File
@@ -3,44 +3,44 @@
#ifndef __WINDOWS_CONSOLE_H
#define __WINDOWS_CONSOLE_H
#include "Windows/Defs.h"
#include "Defs.h"
namespace NWindows{
namespace NConsole{
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)); }
void Attach(HANDLE handle) { m_Object = handle; };
bool GetMode(DWORD &mode)
{ return BOOLToBool(::GetConsoleMode(m_Object, &mode)); }
bool SetMode(DWORD mode)
{ return BOOLToBool(::SetConsoleMode(m_Object, mode)); }
};
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 PeekEvents(PINPUT_RECORD events, DWORD numEvents, DWORD &numEventsRead)
{ return BOOLToBool(::PeekConsoleInput(m_Object, events, numEvents, &numEventsRead)); }
bool PeekEvent(INPUT_RECORD &event, DWORD &numEventsRead)
{ return PeekEvents(&event, 1, numEventsRead); }
bool ReadEvents(PINPUT_RECORD events, DWORD numEvents, DWORD &numEventsRead)
{ return BOOLToBool(::ReadConsoleInput(m_Object, events, numEvents, &numEventsRead)); }
bool ReadEvent(INPUT_RECORD &event, DWORD &numEventsRead)
{ return ReadEvents(&event, 1, numEventsRead); }
bool GetNumberOfEvents(DWORD &numEvents)
{ return BOOLToBool(::GetNumberOfConsoleInputEvents(m_Object, &numEvents)); }
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 WriteEvents(const INPUT_RECORD *events, DWORD numEvents, DWORD &numEventsWritten)
{ return BOOLToBool(::WriteConsoleInput(m_Object, events, numEvents, &numEventsWritten)); }
bool WriteEvent(const INPUT_RECORD &event, DWORD &numEventsWritten)
{ return WriteEvents(&event, 1, numEventsWritten); }
bool Read(LPVOID aBuffer, DWORD aNumberOfCharsToRead, DWORD &aNumberOfCharsRead)
{ return BOOLToBool(::ReadConsole(m_Object, aBuffer, aNumberOfCharsToRead, &aNumberOfCharsRead, NULL)); }
bool Read(LPVOID buffer, DWORD numChars, DWORD &numCharsRead)
{ return BOOLToBool(::ReadConsole(m_Object, buffer, numChars, &numCharsRead, NULL)); }
bool Flush()
{ return BOOLToBool(::FlushConsoleInputBuffer(m_Object)); }
Executable → Regular
+3 -3
View File
@@ -3,10 +3,10 @@
#include "StdAfx.h"
#ifndef _UNICODE
#include "Common/StringConvert.h"
#include "../../Common/StringConvert.h"
#endif
#include "Windows/Control/ComboBox.h"
#include "ComboBox.h"
#ifndef _UNICODE
extern bool g_IsNT;
@@ -51,7 +51,7 @@ LRESULT CComboBox::GetLBText(int index, UString &s)
if (len == CB_ERR)
return len;
s = GetUnicodeString(sa);
return s.Length();
return s.Len();
}
#endif
Executable → Regular
+2
View File
@@ -32,6 +32,8 @@ public:
LRESULT SetItemData(int index, LPARAM lParam) { return SendMessage(CB_SETITEMDATA, index, lParam); }
LRESULT GetItemData(int index) { return SendMessage(CB_GETITEMDATA, index, 0); }
LRESULT GetItemData_of_CurSel() { return GetItemData(GetCurSel()); }
void ShowDropDown(bool show = true) { SendMessage(CB_SHOWDROPDOWN, show ? TRUE : FALSE, 0); }
};
Executable → Regular
+2 -2
View File
@@ -5,7 +5,7 @@
#ifdef UNDER_CE
#include "Windows/Window.h"
#include "../Window.h"
namespace NWindows {
namespace NControl {
@@ -21,7 +21,7 @@ public:
// Macros
// void Destroy() { CommandBar_Destroy(_window); }
bool AddButtons(int iButton, UINT numButtons, LPTBBUTTON buttons) { return BOOLToBool(SendMessage(TB_ADDBUTTONS, (WPARAM)numButtons, (LPARAM)buttons)); }
// bool AddButtons(UINT numButtons, LPTBBUTTON buttons) { return BOOLToBool(SendMessage(TB_ADDBUTTONS, (WPARAM)numButtons, (LPARAM)buttons)); }
bool InsertButton(int iButton, LPTBBUTTON button) { return BOOLToBool(SendMessage(TB_INSERTBUTTON, (WPARAM)iButton, (LPARAM)button)); }
BOOL AddToolTips(UINT numToolTips, LPTSTR toolTips) { return BOOLToBool(SendMessage(TB_SETTOOLTIPS, (WPARAM)numToolTips, (LPARAM)toolTips)); }
void AutoSize() { SendMessage(TB_AUTOSIZE, 0, 0); }
Executable → Regular
+51 -1
View File
@@ -2,11 +2,12 @@
#include "StdAfx.h"
#include "Windows/Control/Dialog.h"
#ifndef _UNICODE
#include "../../Common/StringConvert.h"
#endif
#include "Dialog.h"
extern HINSTANCE g_hInstance;
#ifndef _UNICODE
extern bool g_IsNT;
@@ -99,6 +100,55 @@ bool IsDialogSizeOK(int xSize, int ySize)
ySize / 8 * y <= wy;
}
bool CDialog::GetMargins(int margin, int &x, int &y)
{
x = margin;
y = margin;
RECT rect;
rect.left = 0;
rect.top = 0;
rect.right = margin;
rect.bottom = margin;
if (!MapRect(&rect))
return false;
x = rect.right - rect.left;
y = rect.bottom - rect.top;
return true;
}
int CDialog::Units_To_Pixels_X(int units)
{
RECT rect;
rect.left = 0;
rect.top = 0;
rect.right = units;
rect.bottom = units;
if (!MapRect(&rect))
return units * 3 / 2;
return rect.right - rect.left;
}
bool CDialog::GetItemSizes(int id, int &x, int &y)
{
RECT rect;
if (!::GetWindowRect(GetItem(id), &rect))
return false;
x = RECT_SIZE_X(rect);
y = RECT_SIZE_Y(rect);
return true;
}
void CDialog::GetClientRectOfItem(int id, RECT &rect)
{
::GetWindowRect(GetItem(id), &rect);
ScreenToClient(&rect);
}
bool CDialog::MoveItem(int id, int x, int y, int width, int height, bool repaint)
{
return BOOLToBool(::MoveWindow(GetItem(id), x, y, width, height, BoolToBOOL(repaint)));
}
void CDialog::NormalizeSize(bool fullNormalize)
{
RECT workRect;
Executable → Regular
+10 -48
View File
@@ -3,7 +3,7 @@
#ifndef __WINDOWS_CONTROL_DIALOG_H
#define __WINDOWS_CONTROL_DIALOG_H
#include "Windows/Window.h"
#include "../Window.h"
namespace NWindows {
namespace NControl {
@@ -11,7 +11,7 @@ namespace NControl {
class CDialog: public CWindow
{
public:
CDialog(HWND wndow = NULL): CWindow(wndow){};
CDialog(HWND wnd = NULL): CWindow(wnd){};
virtual ~CDialog() {};
HWND GetItem(int itemID) const
@@ -23,6 +23,9 @@ public:
bool ShowItem(int itemID, int cmdShow) const
{ return BOOLToBool(::ShowWindow(GetItem(itemID), cmdShow)); }
bool ShowItem_Bool(int itemID, bool show) const
{ return ShowItem(itemID, show ? SW_SHOW: SW_HIDE); }
bool HideItem(int itemID) const { return ShowItem(itemID, SW_HIDE); }
bool SetItemText(int itemID, LPCTSTR s)
@@ -110,52 +113,11 @@ public:
LONG_PTR GetMsgResult() const
{ return GetLongPtr(DWLP_MSGRESULT); }
bool GetMargins(int margin, int &x, int &y)
{
RECT rect;
rect.left = 0;
rect.top = 0;
rect.right = margin;
rect.bottom = margin;
if (!MapRect(&rect))
return false;
x = rect.right - rect.left;
y = rect.bottom - rect.top;
return true;
}
int Units_To_Pixels_X(int units)
{
RECT rect;
rect.left = 0;
rect.top = 0;
rect.right = units;
rect.bottom = units;
if (!MapRect(&rect))
return units * 3 / 2;
return rect.right - rect.left;
}
bool GetItemSizes(int id, int &x, int &y)
{
RECT rect;
if (!::GetWindowRect(GetItem(id), &rect))
return false;
x = rect.right - rect.left;
y = rect.bottom - rect.top;
return true;
}
void GetClientRectOfItem(int id, RECT &rect)
{
::GetWindowRect(GetItem(id), &rect);
ScreenToClient(&rect);
}
bool MoveItem(int id, int x, int y, int width, int height, bool repaint = true)
{ return BOOLToBool(::MoveWindow(GetItem(id), x, y, width, height, BoolToBOOL(repaint))); }
bool GetMargins(int margin, int &x, int &y);
int Units_To_Pixels_X(int units);
bool GetItemSizes(int id, int &x, int &y);
void GetClientRectOfItem(int id, RECT &rect);
bool MoveItem(int id, int x, int y, int width, int height, bool repaint = true);
void NormalizeSize(bool fullNormalize = false);
void NormalizePosition();
Executable → Regular
+1 -1
View File
@@ -3,7 +3,7 @@
#ifndef __WINDOWS_CONTROL_EDIT_H
#define __WINDOWS_CONTROL_EDIT_H
#include "Windows/Window.h"
#include "../Window.h"
namespace NWindows {
namespace NControl {
View File
Executable → Regular
+1 -1
View File
@@ -3,7 +3,7 @@
#ifndef __WINDOWS_CONTROL_IMAGELIST_H
#define __WINDOWS_CONTROL_IMAGELIST_H
#include "Windows/Defs.h"
#include "../Defs.h"
namespace NWindows {
namespace NControl {
Executable → Regular
+1 -1
View File
@@ -2,7 +2,7 @@
#include "StdAfx.h"
#include "Windows/Control/ListView.h"
#include "ListView.h"
#ifndef _UNICODE
extern bool g_IsNT;
Executable → Regular
+1 -1
View File
@@ -3,7 +3,7 @@
#ifndef __WINDOWS_CONTROL_LISTVIEW_H
#define __WINDOWS_CONTROL_LISTVIEW_H
#include "Windows/Window.h"
#include "../Window.h"
#include <commctrl.h>
View File
+3 -2
View File
@@ -2,11 +2,12 @@
#include "StdAfx.h"
#include "Windows/Control/PropertyPage.h"
#ifndef _UNICODE
#include "../../Common/StringConvert.h"
#endif
#include "PropertyPage.h"
extern HINSTANCE g_hInstance;
#ifndef _UNICODE
extern bool g_IsNT;
@@ -53,7 +54,7 @@ INT_PTR MyPropertySheet(const CObjectVector<CPageInfo> &pagesInfo, HWND hwndPare
#endif
CRecordVector<PROPSHEETPAGEW> pagesW;
int i;
unsigned i;
#ifndef _UNICODE
for (i = 0; i < pagesInfo.Size(); i++)
titles.Add(GetSystemString(pagesInfo[i].Title));
View File
Executable → Regular
+3 -4
View File
@@ -3,8 +3,7 @@
#ifndef __WINDOWS_CONTROL_REBAR_H
#define __WINDOWS_CONTROL_REBAR_H
#include "Windows/Window.h"
#include "Windows/Defs.h"
#include "../Window.h"
namespace NWindows {
namespace NControl {
@@ -16,9 +15,9 @@ public:
{ 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)
bool SetBandInfo(unsigned index, LPREBARBANDINFO bandInfo)
{ return LRESULTToBool(SendMessage(RB_SETBANDINFO, index, (LPARAM)bandInfo)); }
void MaximizeBand(int index, bool ideal)
void MaximizeBand(unsigned index, bool ideal)
{ SendMessage(RB_MAXIMIZEBAND, index, BoolToBOOL(ideal)); }
bool SizeToRect(LPRECT rect)
{ return LRESULTToBool(SendMessage(RB_SIZETORECT, 0, (LPARAM)rect)); }
Executable → Regular
View File
Executable → Regular
+10 -11
View File
@@ -3,8 +3,7 @@
#ifndef __WINDOWS_CONTROL_STATUSBAR_H
#define __WINDOWS_CONTROL_STATUSBAR_H
#include "Windows/Window.h"
#include "Windows/Defs.h"
#include "../Window.h"
namespace NWindows {
namespace NControl {
@@ -14,28 +13,28 @@ 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)
bool SetText(unsigned index, LPCTSTR text, UINT type)
{ return LRESULTToBool(SendMessage(SB_SETTEXT, index | type, (LPARAM)text)); }
bool SetText(int index, LPCTSTR text)
bool SetText(unsigned 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)
bool SetText(unsigned index, LPCWSTR text, UINT type)
{ return LRESULTToBool(SendMessage(SB_SETTEXTW, index | type, (LPARAM)text)); }
bool SetText(int index, LPCWSTR text)
bool SetText(unsigned index, LPCWSTR text)
{ return SetText(index, text, 0); }
#endif
bool SetParts(unsigned numParts, const int *edgePostions)
{ return LRESULTToBool(SendMessage(SB_SETPARTS, numParts, (LPARAM)edgePostions)); }
void Simple(bool simple)
{ SendMessage(SB_SIMPLE, BoolToBOOL(simple), 0); }
};
}}
Executable → Regular
+1 -2
View File
@@ -3,7 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../../Common/MyWindows.h"
#include "../../Common/NewHandler.h"
#include "../../Common/Common.h"
#endif
Executable → Regular
+1 -1
View File
@@ -3,7 +3,7 @@
#ifndef __WINDOWS_CONTROL_TOOLBAR_H
#define __WINDOWS_CONTROL_TOOLBAR_H
#include "Windows/Window.h"
#include "../Window.h"
namespace NWindows {
namespace NControl {
Executable → Regular
+3 -3
View File
@@ -3,13 +3,13 @@
#ifndef __WINDOWS_CONTROL_TRACKBAR_H
#define __WINDOWS_CONTROL_TRACKBAR_H
#include "Windows/Window.h"
#include "Windows/Defs.h"
#include "../Window.h"
#include "../Defs.h"
namespace NWindows {
namespace NControl {
class CTrackbar: public CWindow
class CTrackbar1: public CWindow
{
public:
void SetRange(int minimum, int maximum, bool redraw = true)
Executable → Regular
+46 -55
View File
@@ -3,11 +3,11 @@
#include "StdAfx.h"
#ifndef _UNICODE
#include "Common/StringConvert.h"
#include "../../Common/StringConvert.h"
#endif
#include "Windows/Control/Window2.h"
// extern HINSTANCE g_hInstance;
#include "Window2.h"
#ifndef _UNICODE
extern bool g_IsNT;
#endif
@@ -26,14 +26,12 @@ namespace NControl {
#define MY_START_WM_CREATE WM_NCCREATE
#endif
static LRESULT CALLBACK WindowProcedure(HWND aHWND, UINT message,
WPARAM wParam, LPARAM lParam)
static LRESULT CALLBACK WindowProcedure(HWND aHWND, UINT message, WPARAM wParam, LPARAM lParam)
{
CWindow tempWindow(aHWND);
if (message == MY_START_WM_CREATE)
tempWindow.SetUserDataLongPtr(
LONG_PTR(((LPCREATESTRUCT)lParam)->lpCreateParams));
CWindow2 *window = (CWindow2*)(tempWindow.GetUserDataLongPtr());
tempWindow.SetUserDataLongPtr((LONG_PTR)(((LPCREATESTRUCT)lParam)->lpCreateParams));
CWindow2 *window = (CWindow2 *)(tempWindow.GetUserDataLongPtr());
if (window != NULL && message == MY_START_WM_CREATE)
window->Attach(aHWND);
if (window == 0)
@@ -48,48 +46,42 @@ static LRESULT CALLBACK WindowProcedure(HWND aHWND, UINT message,
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)
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))
WNDCLASS wc;
if (!::GetClassInfo(instance, className, &wc))
{
// 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)
// wc.style = CS_HREDRAW | CS_VREDRAW;
wc.style = 0;
wc.lpfnWndProc = WindowProcedure;
wc.cbClsExtra = NULL;
wc.cbWndExtra = NULL;
wc.hInstance = instance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = className;
if (::RegisterClass(&wc) == 0)
return false;
}
return CWindow::CreateEx(exStyle, className, windowName,
style, x, y, width, height, parentWindow,
idOrHMenu, instance, this);
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 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;
WNDCLASSW wc;
needRegister = ::GetClassInfoW(instance, className, &wc) == 0;
}
else
{
@@ -107,26 +99,25 @@ bool CWindow2::CreateEx(DWORD exStyle, LPCWSTR className,
}
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)
WNDCLASSW wc;
// wc.style = CS_HREDRAW | CS_VREDRAW;
wc.style = 0;
wc.lpfnWndProc = WindowProcedure;
wc.cbClsExtra = NULL;
wc.cbWndExtra = NULL;
wc.hInstance = instance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = className;
if (MyRegisterClass(&wc) == 0)
return false;
}
return CWindow::CreateEx(exStyle, className, windowName,
style, x, y, width, height, parentWindow,
idOrHMenu, instance, this);
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)
Executable → Regular
+9 -16
View File
@@ -3,7 +3,7 @@
#ifndef __WINDOWS_CONTROL_WINDOW2_H
#define __WINDOWS_CONTROL_WINDOW2_H
#include "Windows/Window.h"
#include "../Window.h"
namespace NWindows {
namespace NControl {
@@ -15,19 +15,14 @@ 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);
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);
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);
@@ -47,10 +42,8 @@ public:
virtual void OnCancel() {};
*/
LONG_PTR SetMsgResult(LONG_PTR newLongPtr )
{ return SetLongPtr(DWLP_MSGRESULT, newLongPtr); }
LONG_PTR GetMsgResult() const
{ return GetLongPtr(DWLP_MSGRESULT); }
LONG_PTR SetMsgResult(LONG_PTR newLongPtr) { return SetLongPtr(DWLP_MSGRESULT, newLongPtr); }
LONG_PTR GetMsgResult() const { return GetLongPtr(DWLP_MSGRESULT); }
};
}}
Executable → Regular
+5 -2
View File
@@ -93,11 +93,14 @@ bool MyGetModuleFileName(FString &path)
FString GetModuleDirPrefix()
{
FString s;
if (NDLL::MyGetModuleFileName(s))
if (MyGetModuleFileName(s))
{
int pos = s.ReverseFind(FCHAR_PATH_SEPARATOR);
if (pos >= 0)
return s.Left(pos + 1);
{
s.DeleteFrom(pos + 1);
return s;
}
}
return FTEXT(".") FSTRING_PATH_SEPARATOR;
}
Executable → Regular
+3 -3
View File
@@ -37,9 +37,9 @@ public:
return m;
}
bool Free();
bool LoadEx(CFSTR path, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);
bool Load(CFSTR path);
bool Free() throw();
bool LoadEx(CFSTR path, DWORD flags = LOAD_LIBRARY_AS_DATAFILE) throw();
bool Load(CFSTR path) throw();
FARPROC GetProc(LPCSTR procName) const { return My_GetProcAddress(_module, procName); }
};
Executable → Regular
View File
-15
View File
@@ -1,15 +0,0 @@
// Windows/Error.h
#ifndef __WINDOWS_ERROR_H
#define __WINDOWS_ERROR_H
#include "Common/MyString.h"
namespace NWindows {
namespace NError {
UString MyFormatMessageW(DWORD errorCode);
}}
#endif
+6 -5
View File
@@ -1,12 +1,13 @@
// Windows/Error.h
// Windows/ErrorMsg.h
#include "StdAfx.h"
#include "Windows/Error.h"
#ifndef _UNICODE
#include "Common/StringConvert.h"
#include "../Common/StringConvert.h"
#endif
#include "ErrorMsg.h"
#ifndef _UNICODE
extern bool g_IsNT;
#endif
@@ -39,7 +40,7 @@ static bool MyFormatMessage(DWORD errorCode, UString &message)
return true;
}
UString MyFormatMessageW(DWORD errorCode)
UString MyFormatMessage(DWORD errorCode)
{
UString message;
if (!MyFormatMessage(errorCode, message))
@@ -47,7 +48,7 @@ UString MyFormatMessageW(DWORD errorCode)
wchar_t s[16];
for (int i = 0; i < 8; i++)
{
int t = errorCode & 0xF;
unsigned t = errorCode & 0xF;
errorCode >>= 4;
s[7 - i] = (wchar_t)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
}
+15
View File
@@ -0,0 +1,15 @@
// Windows/ErrorMsg.h
#ifndef __WINDOWS_ERROR_MSG_H
#define __WINDOWS_ERROR_MSG_H
#include "../Common/MyString.h"
namespace NWindows {
namespace NError {
UString MyFormatMessage(DWORD errorCode);
}}
#endif
Executable → Regular
+177 -181
View File
@@ -14,21 +14,17 @@
extern bool g_IsNT;
#endif
using namespace NWindows;
using namespace NFile;
using namespace NName;
namespace NWindows {
namespace NFile {
// SetCurrentDirectory doesn't support \\?\ prefix
#ifdef WIN_LONG_PATH
bool GetLongPathBase(CFSTR fileName, UString &res);
bool GetLongPath(CFSTR fileName, UString &res);
#endif
namespace NDirectory {
namespace NDir {
#ifndef UNDER_CE
bool MyGetWindowsDirectory(FString &path)
bool GetWindowsDir(FString &path)
{
UINT needLength;
#ifndef _UNICODE
@@ -50,8 +46,7 @@ bool MyGetWindowsDirectory(FString &path)
return (needLength > 0 && needLength <= MAX_PATH);
}
bool MyGetSystemDirectory(FString &path)
bool GetSystemDir(FString &path)
{
UINT needLength;
#ifndef _UNICODE
@@ -74,7 +69,7 @@ bool MyGetSystemDirectory(FString &path)
}
#endif
bool SetDirTime(CFSTR fileName, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
bool SetDirTime(CFSTR path, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
{
#ifndef _UNICODE
if (!g_IsNT)
@@ -83,13 +78,16 @@ bool SetDirTime(CFSTR fileName, const FILETIME *cTime, const FILETIME *aTime, co
return false;
}
#endif
HANDLE hDir = ::CreateFileW(fs2us(fileName), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
HANDLE hDir = INVALID_HANDLE_VALUE;
IF_USE_MAIN_PATH
hDir = ::CreateFileW(fs2us(path), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
#ifdef WIN_LONG_PATH
if (hDir == INVALID_HANDLE_VALUE)
if (hDir == INVALID_HANDLE_VALUE && USE_SUPER_PATH)
{
UString longPath;
if (GetLongPath(fileName, longPath))
if (GetSuperPath(path, longPath, USE_MAIN_PATH))
hDir = ::CreateFileW(longPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
}
@@ -104,43 +102,33 @@ bool SetDirTime(CFSTR fileName, const FILETIME *cTime, const FILETIME *aTime, co
return res;
}
#ifdef WIN_LONG_PATH
bool GetLongPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2)
{
if (!GetLongPathBase(s1, d1) ||
!GetLongPathBase(s2, d2))
return false;
if (d1.IsEmpty() && d2.IsEmpty())
return false;
if (d1.IsEmpty()) d1 = fs2us(s1);
if (d2.IsEmpty()) d2 = fs2us(s2);
return true;
}
#endif
bool MySetFileAttributes(CFSTR fileName, DWORD fileAttributes)
bool SetFileAttrib(CFSTR path, DWORD attrib)
{
#ifndef _UNICODE
if (!g_IsNT)
{
if (::SetFileAttributes(fs2fas(fileName), fileAttributes))
if (::SetFileAttributes(fs2fas(path), attrib))
return true;
}
else
#endif
{
if (::SetFileAttributesW(fs2us(fileName), fileAttributes))
return true;
IF_USE_MAIN_PATH
if (::SetFileAttributesW(fs2us(path), attrib))
return true;
#ifdef WIN_LONG_PATH
UString longPath;
if (GetLongPath(fileName, longPath))
return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes));
if (USE_SUPER_PATH)
{
UString longPath;
if (GetSuperPath(path, longPath, USE_MAIN_PATH))
return BOOLToBool(::SetFileAttributesW(longPath, attrib));
}
#endif
}
return false;
}
bool MyRemoveDirectory(CFSTR path)
bool RemoveDir(CFSTR path)
{
#ifndef _UNICODE
if (!g_IsNT)
@@ -151,40 +139,94 @@ bool MyRemoveDirectory(CFSTR path)
else
#endif
{
if (::RemoveDirectoryW(fs2us(path)))
return true;
IF_USE_MAIN_PATH
if (::RemoveDirectoryW(fs2us(path)))
return true;
#ifdef WIN_LONG_PATH
UString longPath;
if (GetLongPath(path, longPath))
return BOOLToBool(::RemoveDirectoryW(longPath));
if (USE_SUPER_PATH)
{
UString longPath;
if (GetSuperPath(path, longPath, USE_MAIN_PATH))
return BOOLToBool(::RemoveDirectoryW(longPath));
}
#endif
}
return false;
}
bool MyMoveFile(CFSTR existFileName, CFSTR newFileName)
bool MyMoveFile(CFSTR oldFile, CFSTR newFile)
{
#ifndef _UNICODE
if (!g_IsNT)
{
if (::MoveFile(fs2fas(existFileName), fs2fas(newFileName)))
if (::MoveFile(fs2fas(oldFile), fs2fas(newFile)))
return true;
}
else
#endif
{
if (::MoveFileW(fs2us(existFileName), fs2us(newFileName)))
return true;
IF_USE_MAIN_PATH_2(oldFile, newFile)
if (::MoveFileW(fs2us(oldFile), fs2us(newFile)))
return true;
#ifdef WIN_LONG_PATH
UString d1, d2;
if (GetLongPaths(existFileName, newFileName, d1, d2))
return BOOLToBool(::MoveFileW(d1, d2));
if (USE_SUPER_PATH_2)
{
UString d1, d2;
if (GetSuperPaths(oldFile, newFile, d1, d2, USE_MAIN_PATH_2))
return BOOLToBool(::MoveFileW(d1, d2));
}
#endif
}
return false;
}
bool MyCreateDirectory(CFSTR path)
#ifndef UNDER_CE
EXTERN_C_BEGIN
typedef BOOL (WINAPI *Func_CreateHardLinkW)(
LPCWSTR lpFileName,
LPCWSTR lpExistingFileName,
LPSECURITY_ATTRIBUTES lpSecurityAttributes
);
EXTERN_C_END
bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName)
{
#ifndef _UNICODE
if (!g_IsNT)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return false;
/*
if (::CreateHardLink(fs2fas(newFileName), fs2fas(existFileName), NULL))
return true;
*/
}
else
#endif
{
Func_CreateHardLinkW my_CreateHardLinkW = (Func_CreateHardLinkW)
::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), "CreateHardLinkW");
if (!my_CreateHardLinkW)
return false;
IF_USE_MAIN_PATH_2(newFileName, existFileName)
if (my_CreateHardLinkW(fs2us(newFileName), fs2us(existFileName), NULL))
return true;
#ifdef WIN_LONG_PATH
if (USE_SUPER_PATH_2)
{
UString d1, d2;
if (GetSuperPaths(newFileName, existFileName, d1, d2, USE_MAIN_PATH_2))
return BOOLToBool(my_CreateHardLinkW(d1, d2, NULL));
}
#endif
}
return false;
}
#endif
bool CreateDir(CFSTR path)
{
#ifndef _UNICODE
if (!g_IsNT)
@@ -195,13 +237,14 @@ bool MyCreateDirectory(CFSTR path)
else
#endif
{
if (::CreateDirectoryW(fs2us(path), NULL))
return true;
IF_USE_MAIN_PATH
if (::CreateDirectoryW(fs2us(path), NULL))
return true;
#ifdef WIN_LONG_PATH
if (::GetLastError() != ERROR_ALREADY_EXISTS)
if ((!USE_MAIN_PATH || ::GetLastError() != ERROR_ALREADY_EXISTS) && USE_SUPER_PATH)
{
UString longPath;
if (GetLongPath(path, longPath))
if (GetSuperPath(path, longPath, USE_MAIN_PATH))
return BOOLToBool(::CreateDirectoryW(longPath, NULL));
}
#endif
@@ -209,21 +252,22 @@ bool MyCreateDirectory(CFSTR path)
return false;
}
bool CreateComplexDirectory(CFSTR _aPathName)
bool CreateComplexDir(CFSTR _aPathName)
{
FString pathName = _aPathName;
int pos = pathName.ReverseFind(FCHAR_PATH_SEPARATOR);
if (pos > 0 && pos == pathName.Length() - 1)
if (pos > 0 && (unsigned)pos == pathName.Len() - 1)
{
if (pathName.Length() == 3 && pathName[1] == L':')
if (pathName.Len() == 3 && pathName[1] == L':')
return true; // Disk folder;
pathName.Delete(pos);
}
FString pathName2 = pathName;
pos = pathName.Length();
const FString pathName2 = pathName;
pos = pathName.Len();
for (;;)
{
if (MyCreateDirectory(pathName))
if (CreateDir(pathName))
break;
if (::GetLastError() == ERROR_ALREADY_EXISTS)
{
@@ -239,156 +283,111 @@ bool CreateComplexDirectory(CFSTR _aPathName)
return false;
if (pathName[pos - 1] == L':')
return false;
pathName = pathName.Left(pos);
pathName.DeleteFrom(pos);
}
pathName = pathName2;
while (pos < pathName.Length())
while (pos < (int)pathName2.Len())
{
pos = pathName.Find(FCHAR_PATH_SEPARATOR, pos + 1);
pos = pathName2.Find(FCHAR_PATH_SEPARATOR, pos + 1);
if (pos < 0)
pos = pathName.Length();
if (!MyCreateDirectory(pathName.Left(pos)))
pos = pathName2.Len();
pathName.SetFrom(pathName2, pos);
if (!CreateDir(pathName))
return false;
}
return true;
}
bool DeleteFileAlways(CFSTR name)
bool DeleteFileAlways(CFSTR path)
{
if (!MySetFileAttributes(name, 0))
if (!SetFileAttrib(path, 0))
return false;
#ifndef _UNICODE
if (!g_IsNT)
{
if (::DeleteFile(fs2fas(name)))
if (::DeleteFile(fs2fas(path)))
return true;
}
else
#endif
{
if (::DeleteFileW(fs2us(name)))
return true;
IF_USE_MAIN_PATH
if (::DeleteFileW(fs2us(path)))
return true;
#ifdef WIN_LONG_PATH
UString longPath;
if (GetLongPath(name, longPath))
return BOOLToBool(::DeleteFileW(longPath));
if (USE_SUPER_PATH)
{
UString longPath;
if (GetSuperPath(path, longPath, USE_MAIN_PATH))
return BOOLToBool(::DeleteFileW(longPath));
}
#endif
}
return false;
}
static bool RemoveDirectorySubItems2(const FString pathPrefix, const NFind::CFileInfo &fileInfo)
bool RemoveDirWithSubItems(const FString &path)
{
if (fileInfo.IsDir())
return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
return DeleteFileAlways(pathPrefix + fileInfo.Name);
}
bool RemoveDirectoryWithSubItems(const FString &path)
{
NFind::CFileInfo fileInfo;
FString pathPrefix = path + FCHAR_PATH_SEPARATOR;
bool needRemoveSubItems = true;
{
NFind::CEnumerator enumerator(pathPrefix + FCHAR_ANY_MASK);
while (enumerator.Next(fileInfo))
if (!RemoveDirectorySubItems2(pathPrefix, fileInfo))
return false;
NFind::CFileInfo fi;
if (!fi.Find(path))
return false;
if (!fi.IsDir())
{
::SetLastError(ERROR_DIRECTORY);
return false;
}
if (fi.HasReparsePoint())
needRemoveSubItems = false;
}
if (!MySetFileAttributes(path, 0))
if (needRemoveSubItems)
{
FString s = path;
s += FCHAR_PATH_SEPARATOR;
unsigned prefixSize = s.Len();
s += FCHAR_ANY_MASK;
NFind::CEnumerator enumerator(s);
NFind::CFileInfo fi;
while (enumerator.Next(fi))
{
s.DeleteFrom(prefixSize);
s += fi.Name;
if (fi.IsDir())
{
if (!RemoveDirWithSubItems(s))
return false;
}
else if (!DeleteFileAlways(s))
return false;
}
}
if (!SetFileAttrib(path, 0))
return false;
return MyRemoveDirectory(path);
return RemoveDir(path);
}
#ifdef UNDER_CE
bool MyGetFullPathName(CFSTR fileName, FString &resFullPath)
bool MyGetFullPathName(CFSTR path, FString &resFullPath)
{
resFullPath = fileName;
resFullPath = path;
return true;
}
#else
#ifdef WIN_LONG_PATH
static FString GetLastPart(CFSTR path)
bool MyGetFullPathName(CFSTR path, FString &resFullPath)
{
int i = MyStringLen(path);
for (; i > 0; i--)
{
FChar c = path[i - 1];
if (c == FCHAR_PATH_SEPARATOR || c == '/')
break;
}
return path + i;
return GetFullPath(path, resFullPath);
}
static void AddTrailingDots(CFSTR oldPath, FString &newPath)
{
int len = MyStringLen(oldPath);
int i;
for (i = len; i > 0 && oldPath[i - 1] == '.'; i--);
if (i == 0 || i == len)
return;
FString oldName = GetLastPart(oldPath);
FString newName = GetLastPart(newPath);
int nonDotsLen = oldName.Length() - (len - i);
if (nonDotsLen == 0 || newName.CompareNoCase(oldName.Left(nonDotsLen)) != 0)
return;
for (; i != len; i++)
newPath += '.';
}
#endif
bool MyGetFullPathName(CFSTR fileName, FString &resFullPath)
{
resFullPath.Empty();
#ifndef _UNICODE
if (!g_IsNT)
{
TCHAR s[MAX_PATH + 2];
s[0] = 0;
LPTSTR fileNamePointer = 0;
DWORD needLength = ::GetFullPathName(fs2fas(fileName), MAX_PATH + 1, s, &fileNamePointer);
if (needLength == 0 || needLength > MAX_PATH)
return false;
resFullPath = fas2fs(s);
return true;
}
else
#endif
{
LPWSTR fileNamePointer = 0;
WCHAR s[MAX_PATH + 2];
s[0] = 0;
DWORD needLength = ::GetFullPathNameW(fs2us(fileName), MAX_PATH + 1, s, &fileNamePointer);
if (needLength == 0)
return false;
if (needLength <= MAX_PATH)
{
resFullPath = us2fs(s);
return true;
}
#ifdef WIN_LONG_PATH
needLength++;
UString temp;
LPWSTR buffer = temp.GetBuffer(needLength + 1);
buffer[0] = 0;
DWORD needLength2 = ::GetFullPathNameW(fs2us(fileName), needLength, buffer, &fileNamePointer);
temp.ReleaseBuffer();
if (needLength2 > 0 && needLength2 <= needLength)
{
resFullPath = us2fs(temp);
AddTrailingDots(fileName, resFullPath);
return true;
}
#endif
return false;
}
}
bool MySetCurrentDirectory(CFSTR path)
bool SetCurrentDir(CFSTR path)
{
// SetCurrentDirectory doesn't support \\?\ prefix
#ifndef _UNICODE
if (!g_IsNT)
{
@@ -401,7 +400,7 @@ bool MySetCurrentDirectory(CFSTR path)
}
}
bool MyGetCurrentDirectory(FString &path)
bool GetCurrentDir(FString &path)
{
path.Empty();
DWORD needLength;
@@ -428,15 +427,12 @@ bool MyGetCurrentDirectory(FString &path)
bool GetFullPathAndSplit(CFSTR path, FString &resDirPrefix, FString &resFileName)
{
bool res = MyGetFullPathName(path, resFileName);
bool res = MyGetFullPathName(path, resDirPrefix);
if (!res)
resFileName = path;
int pos = resFileName.ReverseFind(FCHAR_PATH_SEPARATOR);
if (pos >= 0)
{
resDirPrefix = resFileName.Left(pos + 1);
resFileName = resFileName.Mid(pos + 1);
}
resDirPrefix = path;
int pos = resDirPrefix.ReverseFind(FCHAR_PATH_SEPARATOR);
resFileName = resDirPrefix.Ptr(pos + 1);
resDirPrefix.DeleteFrom(pos + 1);
return res;
}
@@ -510,7 +506,7 @@ static bool CreateTempFile(CFSTR prefix, bool addRandom, FString &path, NIO::COu
}
else
{
if (MyCreateDirectory(path))
if (CreateDir(path))
return true;
}
DWORD error = GetLastError();
@@ -580,7 +576,7 @@ bool CTempDir::Remove()
{
if (!_mustBeDeleted)
return true;
_mustBeDeleted = !RemoveDirectoryWithSubItems(_path);
_mustBeDeleted = !RemoveDirWithSubItems(_path);
return !_mustBeDeleted;
}
Executable → Regular
+40 -15
View File
@@ -4,27 +4,29 @@
#define __WINDOWS_FILE_DIR_H
#include "../Common/MyString.h"
#include "FileIO.h"
namespace NWindows {
namespace NFile {
namespace NDirectory {
namespace NDir {
#ifdef WIN_LONG_PATH
bool GetLongPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2);
bool GetWindowsDir(FString &path);
bool GetSystemDir(FString &path);
bool SetDirTime(CFSTR path, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime);
bool SetFileAttrib(CFSTR path, DWORD attrib);
bool MyMoveFile(CFSTR existFileName, CFSTR newFileName);
#ifndef UNDER_CE
bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName);
#endif
bool MyGetWindowsDirectory(FString &path);
bool MyGetSystemDirectory(FString &path);
bool SetDirTime(CFSTR fileName, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime);
bool MySetFileAttributes(CFSTR fileName, DWORD fileAttributes);
bool MyMoveFile(CFSTR existFileName, CFSTR newFileName);
bool MyRemoveDirectory(CFSTR path);
bool MyCreateDirectory(CFSTR path);
bool CreateComplexDirectory(CFSTR path);
bool RemoveDir(CFSTR path);
bool CreateDir(CFSTR path);
bool CreateComplexDir(CFSTR path);
bool DeleteFileAlways(CFSTR name);
bool RemoveDirectoryWithSubItems(const FString &path);
bool RemoveDirWithSubItems(const FString &path);
bool MyGetFullPathName(CFSTR path, FString &resFullPath);
bool GetFullPathAndSplit(CFSTR path, FString &resDirPrefix, FString &resFileName);
@@ -32,8 +34,8 @@ bool GetOnlyDirPrefix(CFSTR path, FString &resDirPrefix);
#ifndef UNDER_CE
bool MySetCurrentDirectory(CFSTR path);
bool MyGetCurrentDirectory(FString &resultPath);
bool SetCurrentDir(CFSTR path);
bool GetCurrentDir(FString &resultPath);
#endif
@@ -67,6 +69,29 @@ public:
bool Remove();
};
#if !defined(UNDER_CE)
class CCurrentDirRestorer
{
FString _path;
public:
bool NeedRestore;
CCurrentDirRestorer(): NeedRestore(true)
{
GetCurrentDir(_path);
}
~CCurrentDirRestorer()
{
if (!NeedRestore)
return;
FString s;
if (GetCurrentDir(s))
if (s != _path)
SetCurrentDir(_path);
}
};
#endif
}}}
#endif
Executable → Regular
+274 -43
View File
@@ -4,6 +4,7 @@
#include "FileFind.h"
#include "FileIO.h"
#include "FileName.h"
#ifndef _UNICODE
#include "../Common/StringConvert.h"
#endif
@@ -12,15 +13,43 @@
extern bool g_IsNT;
#endif
using namespace NWindows;
using namespace NFile;
using namespace NName;
#if defined(_WIN32) && !defined(UNDER_CE)
EXTERN_C_BEGIN
typedef enum
{
My_FindStreamInfoStandard,
My_FindStreamInfoMaxInfoLevel
} MY_STREAM_INFO_LEVELS;
typedef struct
{
LARGE_INTEGER StreamSize;
WCHAR cStreamName[MAX_PATH + 36];
} MY_WIN32_FIND_STREAM_DATA, *MY_PWIN32_FIND_STREAM_DATA;
typedef WINBASEAPI HANDLE (WINAPI *FindFirstStreamW_Ptr)(LPCWSTR fileName, MY_STREAM_INFO_LEVELS infoLevel,
LPVOID findStreamData, DWORD flags);
typedef WINBASEAPI BOOL (APIENTRY *FindNextStreamW_Ptr)(HANDLE findStream, LPVOID findStreamData);
EXTERN_C_END
#endif
namespace NWindows {
namespace NFile {
#ifdef SUPPORT_DEVICE_FILE
bool IsDeviceName(CFSTR n);
#endif
#if defined(WIN_LONG_PATH)
bool GetLongPath(CFSTR fileName, UString &res);
namespace NSystem
{
bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize);
}
#endif
namespace NFind {
@@ -31,7 +60,7 @@ bool CFileInfo::IsDots() const
return false;
if (Name[0] != FTEXT('.'))
return false;
return Name.Length() == 1 || (Name.Length() == 2 && Name[1] == FTEXT('.'));
return Name.Len() == 1 || (Name.Len() == 2 && Name[1] == FTEXT('.'));
}
#define WIN_FD_TO_MY_FI(fi, fd) \
@@ -40,6 +69,7 @@ bool CFileInfo::IsDots() const
fi.ATime = fd.ftLastAccessTime; \
fi.MTime = fd.ftLastWriteTime; \
fi.Size = (((UInt64)fd.nFileSizeHigh) << 32) + fd.nFileSizeLow; \
fi.IsAltStream = false; \
fi.IsDevice = false;
/*
@@ -50,27 +80,31 @@ bool CFileInfo::IsDots() const
#endif
*/
static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATAW &fd, CFileInfo &fi)
static void Convert_WIN32_FIND_DATA_to_FileInfo(const WIN32_FIND_DATAW &fd, CFileInfo &fi)
{
WIN_FD_TO_MY_FI(fi, fd);
fi.Name = us2fs(fd.cFileName);
#if defined(_WIN32) && !defined(UNDER_CE)
// fi.ShortName = us2fs(fd.cAlternateFileName);
#endif
}
#ifndef _UNICODE
static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATA &fd, CFileInfo &fi)
static void Convert_WIN32_FIND_DATA_to_FileInfo(const WIN32_FIND_DATA &fd, CFileInfo &fi)
{
WIN_FD_TO_MY_FI(fi, fd);
fi.Name = fas2fs(fd.cFileName);
#if defined(_WIN32) && !defined(UNDER_CE)
// fi.ShortName = fas2fs(fd.cAlternateFileName);
#endif
}
#endif
////////////////////////////////
// CFindFile
bool CFindFile::Close()
bool CFindFileBase::Close()
{
if (_handle == INVALID_HANDLE_VALUE)
return true;
@@ -80,7 +114,7 @@ bool CFindFile::Close()
return true;
}
bool CFindFile::FindFirst(CFSTR wildcard, CFileInfo &fi)
bool CFindFile::FindFirst(CFSTR path, CFileInfo &fi)
{
if (!Close())
return false;
@@ -88,27 +122,29 @@ bool CFindFile::FindFirst(CFSTR wildcard, CFileInfo &fi)
if (!g_IsNT)
{
WIN32_FIND_DATAA fd;
_handle = ::FindFirstFileA(fs2fas(wildcard), &fd);
_handle = ::FindFirstFileA(fs2fas(path), &fd);
if (_handle == INVALID_HANDLE_VALUE)
return false;
ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi);
}
else
#endif
{
WIN32_FIND_DATAW fd;
_handle = ::FindFirstFileW(fs2us(wildcard), &fd);
IF_USE_MAIN_PATH
_handle = ::FindFirstFileW(fs2us(path), &fd);
#ifdef WIN_LONG_PATH
if (_handle == INVALID_HANDLE_VALUE)
if (_handle == INVALID_HANDLE_VALUE && USE_SUPER_PATH)
{
UString longPath;
if (GetLongPath(wildcard, longPath))
if (GetSuperPath(path, longPath, USE_MAIN_PATH))
_handle = ::FindFirstFileW(longPath, &fd);
}
#endif
if (_handle == INVALID_HANDLE_VALUE)
return false;
ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi);
}
return true;
}
@@ -121,7 +157,7 @@ bool CFindFile::FindNext(CFileInfo &fi)
WIN32_FIND_DATAA fd;
if (!::FindNextFileA(_handle, &fd))
return false;
ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi);
}
else
#endif
@@ -129,11 +165,117 @@ bool CFindFile::FindNext(CFileInfo &fi)
WIN32_FIND_DATAW fd;
if (!::FindNextFileW(_handle, &fd))
return false;
ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi);
}
return true;
}
#if defined(_WIN32) && !defined(UNDER_CE)
////////////////////////////////
// AltStreams
static FindFirstStreamW_Ptr g_FindFirstStreamW;
static FindNextStreamW_Ptr g_FindNextStreamW;
struct CFindStreamLoader
{
CFindStreamLoader()
{
g_FindFirstStreamW = (FindFirstStreamW_Ptr)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "FindFirstStreamW");
g_FindNextStreamW = (FindNextStreamW_Ptr)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "FindNextStreamW");
}
} g_FindStreamLoader;
bool CStreamInfo::IsMainStream() const
{
return Name == L"::$DATA";
};
UString CStreamInfo::GetReducedName() const
{
UString s = Name;
if (s.Len() >= 6)
if (wcscmp(s.RightPtr(6), L":$DATA") == 0)
s.DeleteFrom(s.Len() - 6);
return s;
}
static void Convert_WIN32_FIND_STREAM_DATA_to_StreamInfo(const MY_WIN32_FIND_STREAM_DATA &sd, CStreamInfo &si)
{
si.Size = sd.StreamSize.QuadPart;
si.Name = sd.cStreamName;
}
bool CFindStream::FindFirst(CFSTR path, CStreamInfo &si)
{
if (!Close())
return false;
if (!g_FindFirstStreamW)
{
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return false;
}
{
MY_WIN32_FIND_STREAM_DATA sd;
IF_USE_MAIN_PATH
_handle = g_FindFirstStreamW(fs2us(path), My_FindStreamInfoStandard, &sd, 0);
if (_handle == INVALID_HANDLE_VALUE)
{
if (::GetLastError() == ERROR_HANDLE_EOF)
return false;
// long name can be tricky for path like ".\dirName".
#ifdef WIN_LONG_PATH
if (USE_SUPER_PATH)
{
UString longPath;
if (GetSuperPath(path, longPath, USE_MAIN_PATH))
_handle = g_FindFirstStreamW(longPath, My_FindStreamInfoStandard, &sd, 0);
}
#endif
}
if (_handle == INVALID_HANDLE_VALUE)
return false;
Convert_WIN32_FIND_STREAM_DATA_to_StreamInfo(sd, si);
}
return true;
}
bool CFindStream::FindNext(CStreamInfo &si)
{
if (!g_FindNextStreamW)
{
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return false;
}
{
MY_WIN32_FIND_STREAM_DATA sd;
if (!g_FindNextStreamW(_handle, &sd))
return false;
Convert_WIN32_FIND_STREAM_DATA_to_StreamInfo(sd, si);
}
return true;
}
bool CStreamEnumerator::Next(CStreamInfo &si, bool &found)
{
bool res;
if (_find.IsHandleAllocated())
res = _find.FindNext(si);
else
res = _find.FindFirst(_filePath, si);
if (res)
{
found = true;
return true;
}
found = false;
return (::GetLastError() == ERROR_HANDLE_EOF);
}
#endif
#define MY_CLEAR_FILETIME(ft) ft.dwLowDateTime = ft.dwHighDateTime = 0;
void CFileInfoBase::Clear()
@@ -143,46 +285,134 @@ void CFileInfoBase::Clear()
MY_CLEAR_FILETIME(ATime);
MY_CLEAR_FILETIME(MTime);
Attrib = 0;
IsAltStream = false;
IsDevice = false;
}
bool CFileInfo::Find(CFSTR wildcard)
#if defined(_WIN32) && !defined(UNDER_CE)
static int FindAltStreamColon(CFSTR path)
{
for (int i = 0;; i++)
{
FChar c = path[i];
if (c == 0)
return -1;
if (c == ':')
{
if (path[i + 1] == '\\')
if (i == 1 || (i > 1 && path[i - 2] == '\\'))
{
wchar_t c0 = path[i - 1];
if (c0 >= 'a' && c0 <= 'z' ||
c0 >= 'A' && c0 <= 'Z')
continue;
}
return i;
}
}
}
#endif
bool CFileInfo::Find(CFSTR path)
{
#ifdef SUPPORT_DEVICE_FILE
if (IsDeviceName(wildcard))
if (IsDevicePath(path))
{
Clear();
Name = path + 4;
IsDevice = true;
if (/* path[0] == '\\' && path[1] == '\\' && path[2] == '.' && path[3] == '\\' && */
path[5] == ':' && path[6] == 0)
{
FChar drive[4] = { path[4], ':', '\\', 0 };
UInt64 clusterSize, totalSize, freeSize;
if (NSystem::MyGetDiskFreeSpace(drive, clusterSize, totalSize, freeSize))
{
Size = totalSize;
return true;
}
}
NIO::CInFile inFile;
if (!inFile.Open(wildcard))
// ::OutputDebugStringW(path);
if (!inFile.Open(path))
return false;
Name = wildcard + 4;
if (inFile.LengthDefined)
Size = inFile.Length;
// ::OutputDebugStringW(L"---");
if (inFile.SizeDefined)
Size = inFile.Size;
return true;
}
#endif
#if defined(_WIN32) && !defined(UNDER_CE)
int colonPos = FindAltStreamColon(path);
if (colonPos >= 0)
{
UString streamName = fs2us(path + (unsigned)colonPos);
FString filePath = path;
filePath.DeleteFrom(colonPos);
streamName += L":$DATA"; // change it!!!!
if (Find(filePath))
{
// if (IsDir())
Attrib &= ~FILE_ATTRIBUTE_DIRECTORY;
Size = 0;
CStreamEnumerator enumerator(filePath);
for (;;)
{
CStreamInfo si;
bool found;
if (!enumerator.Next(si, found))
return false;
if (!found)
{
::SetLastError(ERROR_FILE_NOT_FOUND);
return false;
}
if (si.Name.IsEqualToNoCase(streamName))
{
Name += us2fs(si.Name);
Name.DeleteFrom(Name.Len() - 6);
Size = si.Size;
IsAltStream = true;
return true;
}
}
}
}
#endif
CFindFile finder;
if (finder.FindFirst(wildcard, *this))
if (finder.FindFirst(path, *this))
return true;
#ifdef _WIN32
{
DWORD lastError = GetLastError();
if (lastError == ERROR_BAD_NETPATH || lastError == ERROR_FILE_NOT_FOUND)
if (lastError == ERROR_BAD_NETPATH ||
lastError == ERROR_FILE_NOT_FOUND ||
lastError == ERROR_INVALID_NAME // for "\\SERVER\shared" paths that are translated to "\\?\UNC\SERVER\shared"
)
{
int len = MyStringLen(wildcard);
if (len > 2 && wildcard[0] == '\\' && wildcard[1] == '\\')
unsigned len = MyStringLen(path);
if (len > 2 && path[0] == '\\' && path[1] == '\\')
{
int pos = FindCharPosInString(wildcard + 2, FTEXT('\\'));
int startPos = 2;
if (len > kSuperUncPathPrefixSize && IsSuperUncPath(path))
startPos = kSuperUncPathPrefixSize;
int pos = FindCharPosInString(path + startPos, FTEXT('\\'));
if (pos >= 0)
{
pos += 2 + 1;
pos += startPos + 1;
len -= pos;
CFSTR remString = wildcard + pos;
int pos2 = FindCharPosInString(remString, FTEXT('\\'));
FString s = wildcard;
if (pos2 < 0 || pos2 == len - 1)
int pos2 = FindCharPosInString(path + pos, FTEXT('\\'));
if (pos2 < 0 || pos2 == (int)len - 1)
{
FString s = wildcard;
FString s = path;
if (pos2 < 0)
{
pos2 = len;
@@ -192,7 +422,7 @@ bool CFileInfo::Find(CFSTR wildcard)
if (finder.FindFirst(s, *this))
if (Name == FTEXT("."))
{
Name = s.Mid(pos, pos2);
Name.SetFrom(s.Ptr(pos), pos2);
return true;
}
::SetLastError(lastError);
@@ -266,20 +496,21 @@ bool CFindChangeNotification::Close()
return true;
}
HANDLE CFindChangeNotification::FindFirst(CFSTR pathName, bool watchSubtree, DWORD notifyFilter)
HANDLE CFindChangeNotification::FindFirst(CFSTR path, bool watchSubtree, DWORD notifyFilter)
{
#ifndef _UNICODE
if (!g_IsNT)
_handle = ::FindFirstChangeNotification(fs2fas(pathName), BoolToBOOL(watchSubtree), notifyFilter);
_handle = ::FindFirstChangeNotification(fs2fas(path), BoolToBOOL(watchSubtree), notifyFilter);
else
#endif
{
_handle = ::FindFirstChangeNotificationW(fs2us(pathName), BoolToBOOL(watchSubtree), notifyFilter);
IF_USE_MAIN_PATH
_handle = ::FindFirstChangeNotificationW(fs2us(path), BoolToBOOL(watchSubtree), notifyFilter);
#ifdef WIN_LONG_PATH
if (!IsHandleAllocated())
{
UString longPath;
if (GetLongPath(pathName, longPath))
if (GetSuperPath(path, longPath, USE_MAIN_PATH))
_handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
}
#endif
Executable → Regular
+52 -10
View File
@@ -4,7 +4,6 @@
#define __WINDOWS_FILE_FIND_H
#include "../Common/MyString.h"
#include "../Common/Types.h"
#include "Defs.h"
namespace NWindows {
@@ -25,14 +24,13 @@ namespace NAttributes
class CFileInfoBase
{
bool MatchesMask(UINT32 mask) const { return ((Attrib & mask) != 0); }
protected:
void Clear();
public:
UInt64 Size;
FILETIME CTime;
FILETIME ATime;
FILETIME MTime;
DWORD Attrib;
bool IsAltStream;
bool IsDevice;
/*
@@ -43,6 +41,11 @@ public:
#endif
*/
CFileInfoBase() { Clear(); }
void Clear() throw();
void SetAsDir() { Attrib = FILE_ATTRIBUTE_DIRECTORY; }
bool IsArchived() const { return MatchesMask(FILE_ATTRIBUTE_ARCHIVE); }
bool IsCompressed() const { return MatchesMask(FILE_ATTRIBUTE_COMPRESSED); }
bool IsDir() const { return MatchesMask(FILE_ATTRIBUTE_DIRECTORY); }
@@ -60,24 +63,63 @@ public:
struct CFileInfo: public CFileInfoBase
{
FString Name;
#if defined(_WIN32) && !defined(UNDER_CE)
// FString ShortName;
#endif
bool IsDots() const;
bool IsDots() const throw();
bool Find(CFSTR wildcard);
};
class CFindFile
class CFindFileBase
{
friend class CEnumerator;
protected:
HANDLE _handle;
public:
bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE; }
CFindFile(): _handle(INVALID_HANDLE_VALUE) {}
~CFindFile() { Close(); }
CFindFileBase(): _handle(INVALID_HANDLE_VALUE) {}
~CFindFileBase() { Close(); }
bool Close() throw();
};
class CFindFile: public CFindFileBase
{
public:
bool FindFirst(CFSTR wildcard, CFileInfo &fileInfo);
bool FindNext(CFileInfo &fileInfo);
bool Close();
};
#if defined(_WIN32) && !defined(UNDER_CE)
struct CStreamInfo
{
UString Name;
UInt64 Size;
UString GetReducedName() const;
bool IsMainStream() const throw();
};
class CFindStream: public CFindFileBase
{
public:
bool FindFirst(CFSTR filePath, CStreamInfo &streamInfo);
bool FindNext(CStreamInfo &streamInfo);
};
class CStreamEnumerator
{
CFindStream _find;
FString _filePath;
bool NextAny(CFileInfo &fileInfo);
public:
CStreamEnumerator(const FString &filePath): _filePath(filePath) {}
bool Next(CStreamInfo &streamInfo, bool &found);
};
#endif
bool DoesFileExist(CFSTR name);
bool DoesDirExist(CFSTR name);
bool DoesFileOrDirExist(CFSTR name);
@@ -102,7 +144,7 @@ public:
bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE && _handle != 0; }
CFindChangeNotification(): _handle(INVALID_HANDLE_VALUE) {}
~CFindChangeNotification() { Close(); }
bool Close();
bool Close() throw();
HANDLE FindFirst(CFSTR pathName, bool watchSubtree, DWORD notifyFilter);
bool FindNext() { return BOOLToBool(::FindNextChangeNotification(_handle)); }
};
Executable → Regular
+170 -123
View File
@@ -2,88 +2,35 @@
#include "StdAfx.h"
#ifdef SUPPORT_DEVICE_FILE
#include "../../C/Alloc.h"
#endif
#include "FileIO.h"
#include "FileName.h"
#ifndef _UNICODE
extern bool g_IsNT;
#endif
using namespace NWindows;
using namespace NFile;
using namespace NName;
namespace NWindows {
namespace NFile {
#ifdef SUPPORT_DEVICE_FILE
bool IsDeviceName(CFSTR n)
namespace NSystem
{
#ifdef UNDER_CE
int len = (int)MyStringLen(n);
if (len < 5 || len > 5 || memcmp(n, FTEXT("DSK"), 3 * sizeof(FCHAR)) != 0)
return false;
if (n[4] != ':')
return false;
// for reading use SG_REQ sg; if (DeviceIoControl(dsk, IOCTL_DISK_READ));
#else
if (n[0] != '\\' || n[1] != '\\' || n[2] != '.' || n[3] != '\\')
return false;
int len = (int)MyStringLen(n);
if (len == 6 && n[5] == ':')
return true;
if (len < 18 || len > 22 || memcmp(n + 4, FTEXT("PhysicalDrive"), 13 * sizeof(FCHAR)) != 0)
return false;
for (int i = 17; i < len; i++)
if (n[i] < '0' || n[i] > '9')
return false;
#endif
return true;
}
#endif
#if defined(WIN_LONG_PATH) && defined(_UNICODE)
#define WIN_LONG_PATH2
#endif
#ifdef WIN_LONG_PATH
bool GetLongPathBase(CFSTR s, UString &res)
{
res.Empty();
int len = MyStringLen(s);
FChar c = s[0];
if (len < 1 || c == '\\' || c == '.' && (len == 1 || len == 2 && s[1] == '.'))
return true;
UString curDir;
bool isAbs = false;
if (len > 3)
isAbs = (s[1] == ':' && s[2] == '\\' && (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'));
if (!isAbs)
{
WCHAR temp[MAX_PATH + 2];
temp[0] = 0;
DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, temp);
if (needLength == 0 || needLength > MAX_PATH)
return false;
curDir = temp;
if (curDir.Back() != L'\\')
curDir += L'\\';
}
res = UString(L"\\\\?\\") + curDir + fs2us(s);
return true;
}
bool GetLongPath(CFSTR path, UString &longPath)
{
if (GetLongPathBase(path, longPath))
return !longPath.IsEmpty();
return false;
bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize);
}
#endif
namespace NIO {
CFileBase::~CFileBase() { Close(); }
bool CFileBase::Create(CFSTR fileName, DWORD desiredAccess,
bool CFileBase::Create(CFSTR path, DWORD desiredAccess,
DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
{
if (!Close())
@@ -96,19 +43,20 @@ bool CFileBase::Create(CFSTR fileName, DWORD desiredAccess,
#ifndef _UNICODE
if (!g_IsNT)
{
_handle = ::CreateFile(fs2fas(fileName), desiredAccess, shareMode,
_handle = ::CreateFile(fs2fas(path), desiredAccess, shareMode,
(LPSECURITY_ATTRIBUTES)NULL, creationDisposition, flagsAndAttributes, (HANDLE)NULL);
}
else
#endif
{
_handle = ::CreateFileW(fs2us(fileName), desiredAccess, shareMode,
IF_USE_MAIN_PATH
_handle = ::CreateFileW(fs2us(path), desiredAccess, shareMode,
(LPSECURITY_ATTRIBUTES)NULL, creationDisposition, flagsAndAttributes, (HANDLE)NULL);
#ifdef WIN_LONG_PATH
if (_handle == INVALID_HANDLE_VALUE)
if (_handle == INVALID_HANDLE_VALUE && USE_SUPER_PATH)
{
UString longPath;
if (GetLongPath(fileName, longPath))
if (GetSuperPath(path, longPath, USE_MAIN_PATH))
_handle = ::CreateFileW(longPath, desiredAccess, shareMode,
(LPSECURITY_ATTRIBUTES)NULL, creationDisposition, flagsAndAttributes, (HANDLE)NULL);
}
@@ -135,9 +83,9 @@ bool CFileBase::GetPosition(UInt64 &position) const
bool CFileBase::GetLength(UInt64 &length) const
{
#ifdef SUPPORT_DEVICE_FILE
if (IsDeviceFile && LengthDefined)
if (IsDeviceFile && SizeDefined)
{
length = Length;
length = Size;
return true;
}
#endif
@@ -154,95 +102,192 @@ bool CFileBase::GetLength(UInt64 &length) const
bool CFileBase::Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const
{
#ifdef SUPPORT_DEVICE_FILE
if (IsDeviceFile && LengthDefined && moveMethod == FILE_END)
if (IsDeviceFile && SizeDefined && moveMethod == FILE_END)
{
distanceToMove += Length;
distanceToMove += Size;
moveMethod = FILE_BEGIN;
}
#endif
LARGE_INTEGER value;
value.QuadPart = distanceToMove;
value.LowPart = ::SetFilePointer(_handle, value.LowPart, &value.HighPart, moveMethod);
if (value.LowPart == 0xFFFFFFFF)
LONG high = (LONG)(distanceToMove >> 32);
DWORD low = ::SetFilePointer(_handle, (LONG)(distanceToMove & 0xFFFFFFFF), &high, moveMethod);
if (low == 0xFFFFFFFF)
if (::GetLastError() != NO_ERROR)
return false;
newPosition = value.QuadPart;
newPosition = (((UInt64)high) << 32) + low;
return true;
}
bool CFileBase::Seek(UInt64 position, UInt64 &newPosition)
bool CFileBase::Seek(UInt64 position, UInt64 &newPosition) const
{
return Seek(position, FILE_BEGIN, newPosition);
}
bool CFileBase::SeekToBegin()
bool CFileBase::SeekToBegin() const
{
UInt64 newPosition;
return Seek(0, newPosition);
}
bool CFileBase::SeekToEnd(UInt64 &newPosition)
bool CFileBase::SeekToEnd(UInt64 &newPosition) const
{
return Seek(0, FILE_END, newPosition);
}
/*
bool CFileBase::GetFileInformation(CByHandleFileInfo &fi) const
{
BY_HANDLE_FILE_INFORMATION wfi;
if (!::GetFileInformationByHandle(_handle, &wfi))
return false;
fi.Attrib = wfi.dwFileAttributes;
fi.CTime = wfi.ftCreationTime;
fi.ATime = wfi.ftLastAccessTime;
fi.MTime = wfi.ftLastWriteTime;
fi.Size = (((UInt64)wfi.nFileSizeHigh) << 32) + wfi.nFileSizeLow;
fi.VolumeSerialNumber = wfi.dwVolumeSerialNumber;
fi.NumLinks = wfi.nNumberOfLinks;
fi.FileIndex = (((UInt64)wfi.nFileIndexHigh) << 32) + wfi.nFileIndexLow;
return true;
}
*/
/////////////////////////
// CInFile
// ---------- CInFile ---------
#ifdef SUPPORT_DEVICE_FILE
void CInFile::GetDeviceLength()
void CInFile::CorrectDeviceSize()
{
if (_handle != INVALID_HANDLE_VALUE && IsDeviceFile)
// maybe we must decrease kClusterSize to 1 << 12, if we want correct size at tail
static const UInt32 kClusterSize = 1 << 14;
UInt64 pos = Size & ~(UInt64)(kClusterSize - 1);
UInt64 realNewPosition;
if (!Seek(pos, realNewPosition))
return;
Byte *buf = (Byte *)MidAlloc(kClusterSize);
bool needbackward = true;
for (;;)
{
#ifdef UNDER_CE
LengthDefined = true;
Length = 128 << 20;
UInt32 processed = 0;
// up test is slow for "PhysicalDrive".
// processed size for latest block for "PhysicalDrive0" is 0.
if (!Read1(buf, kClusterSize, processed))
break;
if (processed == 0)
break;
needbackward = false;
Size = pos + processed;
if (processed != kClusterSize)
break;
pos += kClusterSize;
}
#else
PARTITION_INFORMATION partInfo;
LengthDefined = true;
Length = 0;
if (needbackward && pos != 0)
{
pos -= kClusterSize;
for (;;)
{
// break;
if (!Seek(pos, realNewPosition))
break;
if (!buf)
{
buf = (Byte *)MidAlloc(kClusterSize);
if (!buf)
break;
}
UInt32 processed = 0;
// that code doesn't work for "PhysicalDrive0"
if (!Read1(buf, kClusterSize, processed))
break;
if (processed != 0)
{
Size = pos + processed;
break;
}
if (pos == 0)
break;
pos -= kClusterSize;
}
}
MidFree(buf);
}
if (GetPartitionInfo(&partInfo))
Length = partInfo.PartitionLength.QuadPart;
void CInFile::CalcDeviceSize(CFSTR s)
{
SizeDefined = false;
Size = 0;
if (_handle == INVALID_HANDLE_VALUE || !IsDeviceFile)
return;
#ifdef UNDER_CE
SizeDefined = true;
Size = 128 << 20;
#else
PARTITION_INFORMATION partInfo;
bool needCorrectSize = true;
/*
WinXP 64-bit:
HDD \\.\PhysicalDrive0 (MBR):
GetPartitionInfo == GeometryEx : corrrect size? (includes tail)
Geometry : smaller than GeometryEx (no tail, maybe correct too?)
MyGetDiskFreeSpace : FAIL
Size correction is slow and block size (kClusterSize) must be small?
HDD partition \\.\N: (NTFS):
MyGetDiskFreeSpace : Size of NTFS clusters. Same size can be calculated after correction
GetPartitionInfo : size of partition data: NTFS clusters + TAIL; TAIL contains extra empty sectors and copy of first sector of NTFS
Geometry / CdRomGeometry / GeometryEx : size of HDD (not that partition)
CD-ROM drive (ISO):
MyGetDiskFreeSpace : correct size. Same size can be calculated after correction
Geometry == CdRomGeometry : smaller than corrrect size
GetPartitionInfo == GeometryEx : larger than corrrect size
Floppy \\.\a: (FAT):
Geometry : correct size.
CdRomGeometry / GeometryEx / GetPartitionInfo / MyGetDiskFreeSpace - FAIL
correction works OK for FAT.
correction works OK for non-FAT, if kClusterSize = 512.
*/
if (GetPartitionInfo(&partInfo))
{
Size = partInfo.PartitionLength.QuadPart;
SizeDefined = true;
needCorrectSize = false;
if ((s)[0] == '\\' && (s)[1] == '\\' && (s)[2] == '.' && (s)[3] == '\\' && (s)[5] == ':' && (s)[6] == 0)
{
FChar path[4] = { s[4], ':', '\\', 0 };
UInt64 clusterSize, totalSize, freeSize;
if (NSystem::MyGetDiskFreeSpace(path, clusterSize, totalSize, freeSize))
Size = totalSize;
else
needCorrectSize = true;
}
}
if (!SizeDefined)
{
my_DISK_GEOMETRY_EX geomEx;
SizeDefined = GetGeometryEx(&geomEx);
if (SizeDefined)
Size = geomEx.DiskSize.QuadPart;
else
{
DISK_GEOMETRY geom;
if (!GetGeometry(&geom))
if (!GetCdRomGeometry(&geom))
LengthDefined = false;
if (LengthDefined)
Length = geom.Cylinders.QuadPart * geom.TracksPerCylinder * geom.SectorsPerTrack * geom.BytesPerSector;
SizeDefined = GetGeometry(&geom);
if (!SizeDefined)
SizeDefined = GetCdRomGeometry(&geom);
if (SizeDefined)
Size = geom.Cylinders.QuadPart * geom.TracksPerCylinder * geom.SectorsPerTrack * geom.BytesPerSector;
}
// SeekToBegin();
#endif
}
if (needCorrectSize && SizeDefined && Size != 0)
{
CorrectDeviceSize();
SeekToBegin();
}
// SeekToBegin();
#endif
}
// ((desiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA | GENERIC_WRITE)) == 0 &&
#define MY_DEVICE_EXTRA_CODE \
IsDeviceFile = IsDeviceName(fileName); \
GetDeviceLength();
IsDeviceFile = IsDevicePath(fileName); \
CalcDeviceSize(fileName);
#else
#define MY_DEVICE_EXTRA_CODE
#endif
@@ -305,8 +350,7 @@ bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize)
return true;
}
/////////////////////////
// COutFile
// ---------- COutFile ---------
static inline DWORD GetCreationDisposition(bool createAlways)
{ return createAlways? CREATE_ALWAYS: CREATE_NEW; }
@@ -320,6 +364,9 @@ bool COutFile::Open(CFSTR fileName, DWORD creationDisposition)
bool COutFile::Create(CFSTR fileName, bool createAlways)
{ return Open(fileName, GetCreationDisposition(createAlways)); }
bool COutFile::CreateAlways(CFSTR fileName, DWORD flagsAndAttributes)
{ return Open(fileName, FILE_SHARE_READ, GetCreationDisposition(true), flagsAndAttributes); }
bool COutFile::SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
{ return BOOLToBool(::SetFileTime(_handle, cTime, aTime, mTime)); }
Executable → Regular
+129 -59
View File
@@ -3,96 +3,155 @@
#ifndef __WINDOWS_FILE_IO_H
#define __WINDOWS_FILE_IO_H
#include "../Common/Types.h"
#include "../Common/MyString.h"
#include "../Common/MyBuffer.h"
#include "Defs.h"
#define _my_IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
#define _my_IO_REPARSE_TAG_SYMLINK (0xA000000CL)
#define _my_SYMLINK_FLAG_RELATIVE 1
#define my_FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) // REPARSE_DATA_BUFFER
#define my_FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) // REPARSE_DATA_BUFFER
namespace NWindows {
namespace NFile {
bool FillLinkData(CByteBuffer &dest, const wchar_t *path, bool isSymLink);
struct CReparseShortInfo
{
unsigned Offset;
unsigned Size;
bool Parse(const Byte *p, size_t size);
};
struct CReparseAttr
{
UInt32 Tag;
UInt32 Flags;
UString SubsName;
UString PrintName;
CReparseAttr(): Tag(0), Flags(0) {}
bool Parse(const Byte *p, size_t size);
bool IsMountPoint() const { return Tag == _my_IO_REPARSE_TAG_MOUNT_POINT; } // it's Junction
bool IsSymLink() const { return Tag == _my_IO_REPARSE_TAG_SYMLINK; }
bool IsRelative() const { return Flags == _my_SYMLINK_FLAG_RELATIVE; }
// bool IsVolume() const;
bool IsOkNamePair() const;
UString GetPath() const;
};
namespace NIO {
/*
struct CByHandleFileInfo
{
UInt64 Size;
FILETIME CTime;
FILETIME ATime;
FILETIME MTime;
DWORD Attrib;
DWORD VolumeSerialNumber;
DWORD NumLinks;
UInt64 FileIndex;
};
*/
bool GetReparseData(CFSTR path, CByteBuffer &reparseData, BY_HANDLE_FILE_INFORMATION *fileInfo = NULL);
bool SetReparseData(CFSTR path, bool isDir, const void *data, DWORD size);
class CFileBase
{
protected:
HANDLE _handle;
bool Create(CFSTR fileName, DWORD desiredAccess,
bool Create(CFSTR path, DWORD desiredAccess,
DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
public:
#ifdef SUPPORT_DEVICE_FILE
bool IsDeviceFile;
bool LengthDefined;
UInt64 Length;
#endif
CFileBase(): _handle(INVALID_HANDLE_VALUE) {};
~CFileBase();
bool Close();
bool GetPosition(UInt64 &position) const;
bool GetLength(UInt64 &length) const;
bool Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const;
bool Seek(UInt64 position, UInt64 &newPosition);
bool SeekToBegin();
bool SeekToEnd(UInt64 &newPosition);
// bool GetFileInformation(CByHandleFileInfo &fileInfo) const;
};
#define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY CTL_CODE(IOCTL_CDROM_BASE, 0x0013, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_CDROM_MEDIA_REMOVAL CTL_CODE(IOCTL_CDROM_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS)
class CInFile: public CFileBase
{
#ifdef SUPPORT_DEVICE_FILE
bool DeviceIoControl(DWORD controlCode, LPVOID inBuffer, DWORD inSize,
LPVOID outBuffer, DWORD outSize, LPDWORD bytesReturned, LPOVERLAPPED overlapped) const
LPVOID outBuffer, DWORD outSize, LPDWORD bytesReturned, LPOVERLAPPED overlapped = NULL) 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
bool DeviceIoControlOut(DWORD controlCode, LPVOID outBuffer, DWORD outSize, LPDWORD bytesReturned) const
{
DWORD ret;
return DeviceIoControl(controlCode, inBuffer, inSize, outBuffer, outSize, &ret, 0);
return DeviceIoControl(controlCode, NULL, 0, outBuffer, outSize, bytesReturned);
}
bool DeviceIoControlOut(DWORD controlCode, LPVOID outBuffer, DWORD outSize) const
{ return DeviceIoControl(controlCode, NULL, 0, outBuffer, outSize); }
{
DWORD bytesReturned;
return DeviceIoControlOut(controlCode, outBuffer, outSize, &bytesReturned);
}
public:
#ifdef SUPPORT_DEVICE_FILE
bool IsDeviceFile;
bool SizeDefined;
UInt64 Size; // it can be larger than real available size
#endif
CFileBase(): _handle(INVALID_HANDLE_VALUE) {};
~CFileBase() { Close(); }
bool Close() throw();
bool GetPosition(UInt64 &position) const throw();
bool GetLength(UInt64 &length) const throw();
bool Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const throw();
bool Seek(UInt64 position, UInt64 &newPosition) const throw();
bool SeekToBegin() const throw();
bool SeekToEnd(UInt64 &newPosition) const throw();
bool GetFileInformation(BY_HANDLE_FILE_INFORMATION *info) const
{ return BOOLToBool(GetFileInformationByHandle(_handle, info)); }
static bool GetFileInformation(CFSTR path, BY_HANDLE_FILE_INFORMATION *info)
{
NIO::CFileBase file;
if (!file.Create(path, 0, FILE_SHARE_READ, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS))
return false;
return file.GetFileInformation(info);
}
};
#ifndef UNDER_CE
#define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY CTL_CODE(IOCTL_CDROM_BASE, 0x0013, METHOD_BUFFERED, FILE_READ_ACCESS)
// #define IOCTL_CDROM_MEDIA_REMOVAL CTL_CODE(IOCTL_CDROM_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS)
// IOCTL_DISK_GET_DRIVE_GEOMETRY_EX works since WinXP
#define my_IOCTL_DISK_GET_DRIVE_GEOMETRY_EX CTL_CODE(IOCTL_DISK_BASE, 0x0028, METHOD_BUFFERED, FILE_ANY_ACCESS)
struct my_DISK_GEOMETRY_EX
{
DISK_GEOMETRY Geometry;
LARGE_INTEGER DiskSize;
BYTE Data[1];
};
#endif
class CInFile: public CFileBase
{
#ifdef SUPPORT_DEVICE_FILE
#ifndef UNDER_CE
bool GetGeometry(DISK_GEOMETRY *res) const
{ return DeviceIoControlOut(IOCTL_DISK_GET_DRIVE_GEOMETRY, res, sizeof(*res)); }
bool GetGeometryEx(my_DISK_GEOMETRY_EX *res) const
{ return DeviceIoControlOut(my_IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, res, sizeof(*res)); }
bool GetCdRomGeometry(DISK_GEOMETRY *res) const
{ return DeviceIoControlOut(IOCTL_CDROM_GET_DRIVE_GEOMETRY, res, sizeof(*res)); }
bool GetPartitionInfo(PARTITION_INFORMATION *res)
{ return DeviceIoControlOut(IOCTL_DISK_GET_PARTITION_INFO, LPVOID(res), sizeof(*res)); }
#endif
void GetDeviceLength();
void CorrectDeviceSize();
void CalcDeviceSize(CFSTR name);
#endif
public:
@@ -100,9 +159,19 @@ public:
bool OpenShared(CFSTR fileName, bool shareForWrite);
bool Open(CFSTR fileName);
bool Read1(void *data, UInt32 size, UInt32 &processedSize);
bool ReadPart(void *data, UInt32 size, UInt32 &processedSize);
bool Read(void *data, UInt32 size, UInt32 &processedSize);
#ifndef UNDER_CE
bool OpenReparse(CFSTR fileName)
{
return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING,
FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS);
}
#endif
bool Read1(void *data, UInt32 size, UInt32 &processedSize) throw();
bool ReadPart(void *data, UInt32 size, UInt32 &processedSize) throw();
bool Read(void *data, UInt32 size, UInt32 &processedSize) throw();
};
class COutFile: public CFileBase
@@ -111,13 +180,14 @@ public:
bool Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
bool Open(CFSTR fileName, DWORD creationDisposition);
bool Create(CFSTR fileName, bool createAlways);
bool CreateAlways(CFSTR fileName, DWORD flagsAndAttributes);
bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime);
bool SetMTime(const FILETIME *mTime);
bool WritePart(const void *data, UInt32 size, UInt32 &processedSize);
bool Write(const void *data, UInt32 size, UInt32 &processedSize);
bool SetEndOfFile();
bool SetLength(UInt64 length);
bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) throw();
bool SetMTime(const FILETIME *mTime) throw();
bool WritePart(const void *data, UInt32 size, UInt32 &processedSize) throw();
bool Write(const void *data, UInt32 size, UInt32 &processedSize) throw();
bool SetEndOfFile() throw();
bool SetLength(UInt64 length) throw();
};
}}}
+426
View File
@@ -0,0 +1,426 @@
// Windows/FileLink.cpp
#include "StdAfx.h"
#include "../../C/CpuArch.h"
#ifdef SUPPORT_DEVICE_FILE
#include "../../C/Alloc.h"
#endif
#include "FileDir.h"
#include "FileFind.h"
#include "FileIO.h"
#include "FileName.h"
#ifndef _UNICODE
extern bool g_IsNT;
#endif
namespace NWindows {
namespace NFile {
using namespace NName;
/*
Reparse Points (Junctions and Symbolic Links):
struct
{
UInt32 Tag;
UInt16 Size; // not including starting 8 bytes
UInt16 Reserved; // = 0
UInt16 SubstituteOffset; // offset in bytes from start of namesChars
UInt16 SubstituteLen; // size in bytes, it doesn't include tailed NUL
UInt16 PrintOffset; // offset in bytes from start of namesChars
UInt16 PrintLen; // size in bytes, it doesn't include tailed NUL
[UInt32] Flags; // for Symbolic Links only.
UInt16 namesChars[]
}
MOUNT_POINT (Junction point):
1) there is NUL wchar after path
2) Default Order in table:
Substitute Path
Print Path
3) pathnames can not contain dot directory names
SYMLINK:
1) there is no NUL wchar after path
2) Default Order in table:
Print Path
Substitute Path
*/
/*
static const UInt32 kReparseFlags_Alias = (1 << 29);
static const UInt32 kReparseFlags_HighLatency = (1 << 30);
static const UInt32 kReparseFlags_Microsoft = ((UInt32)1 << 31);
#define _my_IO_REPARSE_TAG_HSM (0xC0000004L)
#define _my_IO_REPARSE_TAG_HSM2 (0x80000006L)
#define _my_IO_REPARSE_TAG_SIS (0x80000007L)
#define _my_IO_REPARSE_TAG_WIM (0x80000008L)
#define _my_IO_REPARSE_TAG_CSV (0x80000009L)
#define _my_IO_REPARSE_TAG_DFS (0x8000000AL)
#define _my_IO_REPARSE_TAG_DFSR (0x80000012L)
*/
#define Get16(p) GetUi16(p)
#define Get32(p) GetUi32(p)
#define Set16(p, v) SetUi16(p, v)
#define Set32(p, v) SetUi32(p, v)
static const wchar_t *k_LinkPrefix = L"\\??\\";
static const unsigned k_LinkPrefix_Size = 4;
static const bool IsLinkPrefix(const wchar_t *s)
{
return IsString1PrefixedByString2(s, k_LinkPrefix);
}
/*
static const wchar_t *k_VolumePrefix = L"Volume{";
static const bool IsVolumeName(const wchar_t *s)
{
return IsString1PrefixedByString2(s, k_VolumePrefix);
}
*/
void WriteString(Byte *dest, const wchar_t *path)
{
for (;;)
{
wchar_t c = *path++;
if (c == 0)
return;
Set16(dest, (UInt16)c);
dest += 2;
}
}
bool FillLinkData(CByteBuffer &dest, const wchar_t *path, bool isSymLink)
{
bool isAbs = IsAbsolutePath(path);
if (!isAbs && !isSymLink)
return false;
bool needPrintName = true;
if (IsSuperPath(path))
{
path += kSuperPathPrefixSize;
if (!IsDrivePath(path))
needPrintName = false;
}
const unsigned add_Prefix_Len = isAbs ? k_LinkPrefix_Size : 0;
unsigned len2 = MyStringLen(path) * 2;
const unsigned len1 = len2 + add_Prefix_Len * 2;
if (!needPrintName)
len2 = 0;
unsigned totalNamesSize = (len1 + len2);
/* some WIM imagex software uses old scheme for symbolic links.
so we can old scheme for byte to byte compatibility */
bool newOrderScheme = isSymLink;
// newOrderScheme = false;
if (!newOrderScheme)
totalNamesSize += 2 * 2;
const size_t size = 8 + 8 + (isSymLink ? 4 : 0) + totalNamesSize;
dest.Alloc(size);
memset(dest, 0, size);
const UInt32 tag = isSymLink ?
_my_IO_REPARSE_TAG_SYMLINK :
_my_IO_REPARSE_TAG_MOUNT_POINT;
Byte *p = dest;
Set32(p, tag);
Set16(p + 4, (UInt16)(size - 8));
Set16(p + 6, 0);
p += 8;
unsigned subOffs = 0;
unsigned printOffs = 0;
if (newOrderScheme)
subOffs = len2;
else
printOffs = len1 + 2;
Set16(p + 0, (UInt16)subOffs);
Set16(p + 2, (UInt16)len1);
Set16(p + 4, (UInt16)printOffs);
Set16(p + 6, (UInt16)len2);
p += 8;
if (isSymLink)
{
UInt32 flags = isAbs ? 0 : _my_SYMLINK_FLAG_RELATIVE;
Set32(p, flags);
p += 4;
}
if (add_Prefix_Len != 0)
WriteString(p + subOffs, k_LinkPrefix);
WriteString(p + subOffs + add_Prefix_Len * 2, path);
if (needPrintName)
WriteString(p + printOffs, path);
return true;
}
static void GetString(const Byte *p, unsigned len, UString &res)
{
wchar_t *s = res.GetBuffer(len);
for (unsigned i = 0; i < len; i++)
s[i] = Get16(p + i * 2);
s[len] = 0;
res.ReleaseBuffer();
}
bool CReparseAttr::Parse(const Byte *p, size_t size)
{
if (size < 8)
return false;
Tag = Get32(p);
UInt32 len = Get16(p + 4);
if (len + 8 > size)
return false;
/*
if ((type & kReparseFlags_Alias) == 0 ||
(type & kReparseFlags_Microsoft) == 0 ||
(type & 0xFFFF) != 3)
*/
if (Tag != _my_IO_REPARSE_TAG_MOUNT_POINT &&
Tag != _my_IO_REPARSE_TAG_SYMLINK)
// return true;
return false;
if (Get16(p + 6) != 0) // padding
return false;
p += 8;
size -= 8;
if (len != size) // do we need that check?
return false;
if (len < 8)
return false;
unsigned subOffs = Get16(p);
unsigned subLen = Get16(p + 2);
unsigned printOffs = Get16(p + 4);
unsigned printLen = Get16(p + 6);
len -= 8;
p += 8;
Flags = 0;
if (Tag == _my_IO_REPARSE_TAG_SYMLINK)
{
if (len < 4)
return false;
Flags = Get32(p);
len -= 4;
p += 4;
}
if ((subOffs & 1) != 0 || subOffs > len || len - subOffs < subLen)
return false;
if ((printOffs & 1) != 0 || printOffs > len || len - printOffs < printLen)
return false;
GetString(p + subOffs, subLen >> 1, SubsName);
GetString(p + printOffs, printLen >> 1, PrintName);
return true;
}
bool CReparseShortInfo::Parse(const Byte *p, size_t size)
{
const Byte *start = p;
Offset= 0;
Size = 0;
if (size < 8)
return false;
UInt32 Tag = Get32(p);
UInt32 len = Get16(p + 4);
if (len + 8 > size)
return false;
/*
if ((type & kReparseFlags_Alias) == 0 ||
(type & kReparseFlags_Microsoft) == 0 ||
(type & 0xFFFF) != 3)
*/
if (Tag != _my_IO_REPARSE_TAG_MOUNT_POINT &&
Tag != _my_IO_REPARSE_TAG_SYMLINK)
// return true;
return false;
if (Get16(p + 6) != 0) // padding
return false;
p += 8;
size -= 8;
if (len != size) // do we need that check?
return false;
if (len < 8)
return false;
unsigned subOffs = Get16(p);
unsigned subLen = Get16(p + 2);
unsigned printOffs = Get16(p + 4);
unsigned printLen = Get16(p + 6);
len -= 8;
p += 8;
UInt32 Flags = 0;
if (Tag == _my_IO_REPARSE_TAG_SYMLINK)
{
if (len < 4)
return false;
Flags = Get32(p);
len -= 4;
p += 4;
}
if ((subOffs & 1) != 0 || subOffs > len || len - subOffs < subLen)
return false;
if ((printOffs & 1) != 0 || printOffs > len || len - printOffs < printLen)
return false;
Offset = (unsigned)(p - start) + subOffs;
Size = subLen;
return true;
}
bool CReparseAttr::IsOkNamePair() const
{
if (IsLinkPrefix(SubsName))
{
if (!IsDrivePath(SubsName.Ptr(k_LinkPrefix_Size)))
return PrintName.IsEmpty();
if (wcscmp(SubsName.Ptr(k_LinkPrefix_Size), PrintName) == 0)
return true;
}
return wcscmp(SubsName, PrintName) == 0;
}
/*
bool CReparseAttr::IsVolume() const
{
if (!IsLinkPrefix(SubsName))
return false;
return IsVolumeName(SubsName.Ptr(k_LinkPrefix_Size));
}
*/
UString CReparseAttr::GetPath() const
{
UString s = SubsName;
if (IsLinkPrefix(s))
{
s.ReplaceOneCharAtPos(1, '\\');
if (IsDrivePath(s.Ptr(k_LinkPrefix_Size)))
s.DeleteFrontal(k_LinkPrefix_Size);
}
return s;
}
#ifdef SUPPORT_DEVICE_FILE
namespace NSystem
{
bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize);
}
#endif
#ifndef UNDER_CE
namespace NIO {
bool GetReparseData(CFSTR path, CByteBuffer &reparseData, BY_HANDLE_FILE_INFORMATION *fileInfo)
{
reparseData.Free();
CInFile file;
if (!file.OpenReparse(path))
return false;
if (fileInfo)
file.GetFileInformation(fileInfo);
const unsigned kBufSize = MAXIMUM_REPARSE_DATA_BUFFER_SIZE;
CByteArr buf(kBufSize);
DWORD returnedSize;
if (!file.DeviceIoControlOut(my_FSCTL_GET_REPARSE_POINT, buf, kBufSize, &returnedSize))
return false;
reparseData.CopyFrom(buf, returnedSize);
return true;
}
static bool CreatePrefixDirOfFile(CFSTR path)
{
FString path2 = path;
int pos = path2.ReverseFind(FCHAR_PATH_SEPARATOR);
if (pos < 0)
return true;
#ifdef _WIN32
if (pos == 2 && path2[1] == L':')
return true; // we don't create Disk folder;
#endif
path2.DeleteFrom(pos);
return NDir::CreateComplexDir(path2);
}
// If there is Reprase data already, it still writes new Reparse data
bool SetReparseData(CFSTR path, bool isDir, const void *data, DWORD size)
{
NFile::NFind::CFileInfo fi;
if (fi.Find(path))
{
if (fi.IsDir() != isDir)
{
::SetLastError(ERROR_DIRECTORY);
return false;
}
}
else
{
if (isDir)
{
if (!NDir::CreateComplexDir(path))
return false;
}
else
{
CreatePrefixDirOfFile(path);
COutFile file;
if (!file.Create(path, CREATE_NEW))
return false;
}
}
COutFile file;
if (!file.Open(path,
FILE_SHARE_WRITE,
OPEN_EXISTING,
FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS))
return false;
DWORD returnedSize;
if (!file.DeviceIoControl(my_FSCTL_SET_REPARSE_POINT, (void *)data, size, NULL, 0, &returnedSize))
return false;
return true;
}
}
#endif
}}
Executable → Regular
View File
Executable → Regular
+6 -2
View File
@@ -3,7 +3,7 @@
#ifndef __WINDOWS_FILEMAPPING_H
#define __WINDOWS_FILEMAPPING_H
#include "Common/Types.h"
#include "../Common/MyTypes.h"
#include "Handle.h"
@@ -18,7 +18,11 @@ public:
return ::GetLastError();
}
WRes Open(DWORD desiredAccess, LPCTSTR name)
WRes Open(DWORD
#ifndef UNDER_CE
desiredAccess
#endif
, LPCTSTR name)
{
#ifdef UNDER_CE
WRes res = Create(PAGE_READONLY, 0, name);
Executable → Regular
+661 -3
View File
@@ -4,26 +4,684 @@
#include "FileName.h"
#ifndef _UNICODE
extern bool g_IsNT;
#endif
namespace NWindows {
namespace NFile {
namespace NName {
#ifndef USE_UNICODE_FSTRING
void NormalizeDirPathPrefix(FString &dirPath)
{
if (dirPath.IsEmpty())
return;
if (dirPath.ReverseFind(FCHAR_PATH_SEPARATOR) != dirPath.Length() - 1)
if (dirPath.Back() != FCHAR_PATH_SEPARATOR)
dirPath += FCHAR_PATH_SEPARATOR;
}
#endif
#ifndef USE_UNICODE_FSTRING
void NormalizeDirPathPrefix(UString &dirPath)
{
if (dirPath.IsEmpty())
return;
if (dirPath.ReverseFind(WCHAR_PATH_SEPARATOR) != dirPath.Length() - 1)
if (dirPath.Back() != WCHAR_PATH_SEPARATOR)
dirPath += WCHAR_PATH_SEPARATOR;
}
#ifdef _WIN32
const wchar_t *kSuperPathPrefix = L"\\\\?\\";
static const wchar_t *kSuperUncPrefix = L"\\\\?\\UNC\\";
#define IS_DEVICE_PATH(s) ((s)[0] == '\\' && (s)[1] == '\\' && (s)[2] == '.' && (s)[3] == '\\')
#define IS_SUPER_PREFIX(s) ((s)[0] == '\\' && (s)[1] == '\\' && (s)[2] == '?' && (s)[3] == '\\')
#define IS_SUPER_OR_DEVICE_PATH(s) ((s)[0] == '\\' && (s)[1] == '\\' && ((s)[2] == '?' || (s)[2] == '.') && (s)[3] == '\\')
#define IS_LETTER_CHAR(c) ((c) >= 'a' && (c) <= 'z' || (c) >= 'A' && (c) <= 'Z')
#define IS_UNC_WITH_SLASH(s) ( \
((s)[0] == 'U' || (s)[0] == 'u') && \
((s)[1] == 'N' || (s)[1] == 'n') && \
((s)[2] == 'C' || (s)[2] == 'c') && \
(s)[3] == '\\')
bool IsDevicePath(CFSTR s)
{
#ifdef UNDER_CE
s = s;
return false;
/*
// actually we don't know the way to open device file in WinCE.
unsigned len = MyStringLen(s);
if (len < 5 || len > 5 || memcmp(s, FTEXT("DSK"), 3 * sizeof(FChar)) != 0)
return false;
if (s[4] != ':')
return false;
// for reading use SG_REQ sg; if (DeviceIoControl(dsk, IOCTL_DISK_READ));
*/
#else
if (!IS_DEVICE_PATH(s))
return false;
unsigned len = MyStringLen(s);
if (len == 6 && s[5] == ':')
return true;
if (len < 18 || len > 22 || memcmp(s + kDevicePathPrefixSize, FTEXT("PhysicalDrive"), 13 * sizeof(FChar)) != 0)
return false;
for (unsigned i = 17; i < len; i++)
if (s[i] < '0' || s[i] > '9')
return false;
return true;
#endif
}
bool IsSuperUncPath(CFSTR s) { return (IS_SUPER_PREFIX(s) && IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)); }
bool IsDrivePath(const wchar_t *s) { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == '\\'; }
bool IsSuperPath(const wchar_t *s) { return IS_SUPER_PREFIX(s); }
bool IsSuperOrDevicePath(const wchar_t *s) { return IS_SUPER_OR_DEVICE_PATH(s); }
// bool IsSuperUncPath(const wchar_t *s) { return (IS_SUPER_PREFIX(s) && IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)); }
#ifndef USE_UNICODE_FSTRING
bool IsDrivePath(CFSTR s) { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == '\\'; }
bool IsSuperPath(CFSTR s) { return IS_SUPER_PREFIX(s); }
bool IsSuperOrDevicePath(CFSTR s) { return IS_SUPER_OR_DEVICE_PATH(s); }
#endif // USE_UNICODE_FSTRING
bool IsAbsolutePath(const wchar_t *s)
{
return s[0] == WCHAR_PATH_SEPARATOR || IsDrivePath(s);
}
static const unsigned kDrivePrefixSize = 3; /* c:\ */
#ifndef USE_UNICODE_FSTRING
static unsigned GetRootPrefixSize_Of_NetworkPath(CFSTR s)
{
// Network path: we look "server\path\" as root prefix
int pos = FindCharPosInString(s, '\\');
if (pos < 0)
return 0;
int pos2 = FindCharPosInString(s + pos + 1, '\\');
if (pos2 < 0)
return 0;
return pos + pos2 + 2;
}
static unsigned GetRootPrefixSize_Of_SimplePath(CFSTR s)
{
if (IsDrivePath(s))
return kDrivePrefixSize;
if (s[0] != '\\' || s[1] != '\\')
return 0;
unsigned size = GetRootPrefixSize_Of_NetworkPath(s + 2);
return (size == 0) ? 0 : 2 + size;
}
static unsigned GetRootPrefixSize_Of_SuperPath(CFSTR s)
{
if (IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize))
{
unsigned size = GetRootPrefixSize_Of_NetworkPath(s + kSuperUncPathPrefixSize);
return (size == 0) ? 0 : kSuperUncPathPrefixSize + size;
}
// we support \\?\c:\ paths and volume GUID paths \\?\Volume{GUID}\"
int pos = FindCharPosInString(s + kSuperPathPrefixSize, FCHAR_PATH_SEPARATOR);
if (pos < 0)
return 0;
return kSuperPathPrefixSize + pos + 1;
}
unsigned GetRootPrefixSize(CFSTR s)
{
if (IS_DEVICE_PATH(s))
return kDevicePathPrefixSize;
if (IsSuperPath(s))
return GetRootPrefixSize_Of_SuperPath(s);
return GetRootPrefixSize_Of_SimplePath(s);
}
#endif // USE_UNICODE_FSTRING
static unsigned GetRootPrefixSize_Of_NetworkPath(const wchar_t *s)
{
// Network path: we look "server\path\" as root prefix
int pos = FindCharPosInString(s, L'\\');
if (pos < 0)
return 0;
int pos2 = FindCharPosInString(s + pos + 1, L'\\');
if (pos2 < 0)
return 0;
return pos + pos2 + 2;
}
static unsigned GetRootPrefixSize_Of_SimplePath(const wchar_t *s)
{
if (IsDrivePath(s))
return kDrivePrefixSize;
if (s[0] != '\\' || s[1] != '\\')
return 0;
unsigned size = GetRootPrefixSize_Of_NetworkPath(s + 2);
return (size == 0) ? 0 : 2 + size;
}
static unsigned GetRootPrefixSize_Of_SuperPath(const wchar_t *s)
{
if (IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize))
{
unsigned size = GetRootPrefixSize_Of_NetworkPath(s + kSuperUncPathPrefixSize);
return (size == 0) ? 0 : kSuperUncPathPrefixSize + size;
}
// we support \\?\c:\ paths and volume GUID paths \\?\Volume{GUID}\"
int pos = FindCharPosInString(s + kSuperPathPrefixSize, L'\\');
if (pos < 0)
return 0;
return kSuperPathPrefixSize + pos + 1;
}
unsigned GetRootPrefixSize(const wchar_t *s)
{
if (IS_DEVICE_PATH(s))
return kDevicePathPrefixSize;
if (IsSuperPath(s))
return GetRootPrefixSize_Of_SuperPath(s);
return GetRootPrefixSize_Of_SimplePath(s);
}
#else // _WIN32
bool IsAbsolutePath(const wchar_t *s) { return s[0] == WCHAR_PATH_SEPARATOR }
#ifndef USE_UNICODE_FSTRING
unsigned GetRootPrefixSize(CFSTR s) { return s[0] == CHAR_PATH_SEPRATOR ? 1 : 0; }
#endif
unsigned GetRootPrefixSize(const wchar_t *s) { return s[0] == CHAR_PATH_SEPRATOR ? 1 : 0; }
#endif // _WIN32
#ifndef UNDER_CE
static bool GetCurDir(UString &path)
{
path.Empty();
DWORD needLength;
#ifndef _UNICODE
if (!g_IsNT)
{
TCHAR s[MAX_PATH + 2];
s[0] = 0;
needLength = ::GetCurrentDirectory(MAX_PATH + 1, s);
path = fs2us(fas2fs(s));
}
else
#endif
{
WCHAR s[MAX_PATH + 2];
s[0] = 0;
needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, s);
path = s;
}
return (needLength > 0 && needLength <= MAX_PATH);
}
static bool ResolveDotsFolders(UString &s)
{
#ifdef _WIN32
s.Replace(L'/', WCHAR_PATH_SEPARATOR);
#endif
for (int i = 0;;)
{
wchar_t c = s[i];
if (c == 0)
return true;
if (c == '.' && (i == 0 || s[i - 1] == WCHAR_PATH_SEPARATOR))
{
wchar_t c1 = s[i + 1];
if (c1 == '.')
{
wchar_t c2 = s[i + 2];
if (c2 == WCHAR_PATH_SEPARATOR || c2 == 0)
{
if (i == 0)
return false;
int k = i - 2;
for (; k >= 0; k--)
if (s[k] == WCHAR_PATH_SEPARATOR)
break;
unsigned num;
if (k >= 0)
{
num = i + 2 - k;
i = k;
}
else
{
num = (c2 == 0 ? (i + 2) : (i + 3));
i = 0;
}
s.Delete(i, num);
continue;
}
}
else
{
if (c1 == WCHAR_PATH_SEPARATOR || c1 == 0)
{
unsigned num = 2;
if (i != 0)
i--;
else if (c1 == 0)
num = 1;
s.Delete(i, num);
continue;
}
}
}
i++;
}
}
#endif // UNDER_CE
#define LONG_PATH_DOTS_FOLDERS_PARSING
/*
Windows (at least 64-bit XP) can't resolve "." or ".." in paths that start with SuperPrefix \\?\
To solve that problem we check such path:
- super path contains "." or ".." - we use kSuperPathType_UseOnlySuper
- super path doesn't contain "." or ".." - we use kSuperPathType_UseOnlyMain
*/
#ifdef LONG_PATH_DOTS_FOLDERS_PARSING
#ifndef UNDER_CE
static bool AreThereDotsFolders(CFSTR s)
{
for (unsigned i = 0;; i++)
{
FChar c = s[i];
if (c == 0)
return false;
if (c == '.' && (i == 0 || s[i - 1] == CHAR_PATH_SEPARATOR))
{
FChar c1 = s[i + 1];
if (c1 == 0 || c1 == CHAR_PATH_SEPARATOR ||
(c1 == '.' && (s[i + 2] == 0 || s[i + 2] == CHAR_PATH_SEPARATOR)))
return true;
}
}
}
#endif
#endif // LONG_PATH_DOTS_FOLDERS_PARSING
#ifdef WIN_LONG_PATH
/*
Most of Windows versions have problems, if some file or dir name
contains '.' or ' ' at the end of name (Bad Path).
To solve that problem, we always use Super Path ("\\?\" prefix and full path)
in such cases. Note that "." and ".." are not bad names.
There are 3 cases:
1) If the path is already Super Path, we use that path
2) If the path is not Super Path :
2.1) Bad Path; we use only Super Path.
2.2) Good Path; we use Main Path. If it fails, we use Super Path.
NeedToUseOriginalPath returns:
kSuperPathType_UseOnlyMain : Super already
kSuperPathType_UseOnlySuper : not Super, Bad Path
kSuperPathType_UseMainAndSuper : not Super, Good Path
*/
int GetUseSuperPathType(CFSTR s)
{
if (IsSuperOrDevicePath(s))
{
#ifdef LONG_PATH_DOTS_FOLDERS_PARSING
if ((s)[2] != '.')
if (AreThereDotsFolders(s + kSuperPathPrefixSize))
return kSuperPathType_UseOnlySuper;
#endif
return kSuperPathType_UseOnlyMain;
}
for (unsigned i = 0;; i++)
{
FChar c = s[i];
if (c == 0)
return kSuperPathType_UseMainAndSuper;
if (c == '.' || c == ' ')
{
FChar c2 = s[i + 1];
if (c2 == 0 || c2 == CHAR_PATH_SEPARATOR)
{
// if it's "." or "..", it's not bad name.
if (c == '.')
{
if (i == 0 || s[i - 1] == CHAR_PATH_SEPARATOR)
continue;
if (s[i - 1] == '.')
{
if (i - 1 == 0 || s[i - 2] == CHAR_PATH_SEPARATOR)
continue;
}
}
return kSuperPathType_UseOnlySuper;
}
}
}
}
/*
returns false in two cases:
- if GetCurDir was used, and GetCurDir returned error.
- if we can't resolve ".." name.
if path is ".", "..", res is empty.
if it's Super Path already, res is empty.
for \**** , and if GetCurDir is not drive (c:\), res is empty
for absolute paths, returns true, res is Super path.
*/
static bool GetSuperPathBase(CFSTR s, UString &res)
{
res.Empty();
FChar c = s[0];
if (c == 0)
return true;
if (c == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)))
return true;
if (IsSuperOrDevicePath(s))
{
#ifdef LONG_PATH_DOTS_FOLDERS_PARSING
if ((s)[2] == '.')
return true;
// we will return true here, so we will try to use these problem paths.
if (!AreThereDotsFolders(s + kSuperPathPrefixSize))
return true;
UString temp = fs2us(s);
unsigned fixedSize = GetRootPrefixSize_Of_SuperPath(temp);
if (fixedSize == 0)
return true;
UString rem = &temp[fixedSize];
if (!ResolveDotsFolders(rem))
return true;
temp.DeleteFrom(fixedSize);
res += temp;
res += rem;
#endif
return true;
}
if (c == CHAR_PATH_SEPARATOR)
{
if (s[1] == CHAR_PATH_SEPARATOR)
{
UString temp = fs2us(s + 2);
unsigned fixedSize = GetRootPrefixSize_Of_NetworkPath(temp);
if (fixedSize == 0) // maybe we must ignore that error to allow short network paths?
return false;
UString rem = &temp[fixedSize];
if (!ResolveDotsFolders(rem))
return false;
res += kSuperUncPrefix;
temp.DeleteFrom(fixedSize);
res += temp;
res += rem;
return true;
}
}
else
{
if (IsDrivePath(s))
{
UString temp = fs2us(s);
UString rem = &temp[kDrivePrefixSize];
if (!ResolveDotsFolders(rem))
return true;
res += kSuperPathPrefix;
temp.DeleteFrom(kDrivePrefixSize);
res += temp;
res += rem;
return true;
}
}
UString curDir;
if (!GetCurDir(curDir))
return false;
if (curDir.Back() != WCHAR_PATH_SEPARATOR)
curDir += WCHAR_PATH_SEPARATOR;
unsigned fixedSizeStart = 0;
unsigned fixedSize = 0;
const wchar_t *superMarker = NULL;
if (IsSuperPath(curDir))
{
fixedSize = GetRootPrefixSize_Of_SuperPath(curDir);
if (fixedSize == 0)
return false;
}
else
{
if (IsDrivePath(curDir))
{
superMarker = kSuperPathPrefix;
fixedSize = kDrivePrefixSize;
}
else
{
if (curDir[0] != CHAR_PATH_SEPARATOR || curDir[1] != CHAR_PATH_SEPARATOR)
return false;
fixedSizeStart = 2;
fixedSize = GetRootPrefixSize_Of_NetworkPath(&curDir[2]);
if (fixedSize == 0)
return false;
superMarker = kSuperUncPrefix;
}
}
UString temp;
if (c == CHAR_PATH_SEPARATOR)
{
temp = fs2us(s + 1);
}
else
{
temp += &curDir[fixedSizeStart + fixedSize];
temp += fs2us(s);
}
if (!ResolveDotsFolders(temp))
return false;
if (superMarker)
res += superMarker;
res += curDir.Mid(fixedSizeStart, fixedSize);
res += temp;
return true;
}
/*
In that case if GetSuperPathBase doesn't return new path, we don't need
to use same path that was used as main path
GetSuperPathBase superPath.IsEmpty() onlyIfNew
false * * GetCurDir Error
true false * use Super path
true true true don't use any path, we already used mainPath
true true false use main path as Super Path, we don't try mainMath
That case is possible now if GetCurDir returns unknow
type of path (not drive and not network)
We can change that code if we want to try mainPath, if GetSuperPathBase returns error,
and we didn't try mainPath still.
If we want to work that way, we don't need to use GetSuperPathBase return code.
*/
bool GetSuperPath(CFSTR path, UString &superPath, bool onlyIfNew)
{
if (GetSuperPathBase(path, superPath))
{
if (superPath.IsEmpty())
{
// actually the only possible when onlyIfNew == true and superPath is empty
// is case when
if (onlyIfNew)
return false;
superPath = fs2us(path);
}
return true;
}
return false;
}
bool GetSuperPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2, bool onlyIfNew)
{
if (!GetSuperPathBase(s1, d1) ||
!GetSuperPathBase(s2, d2))
return false;
if (d1.IsEmpty() && d2.IsEmpty() && onlyIfNew)
return false;
if (d1.IsEmpty()) d1 = fs2us(s1);
if (d2.IsEmpty()) d2 = fs2us(s2);
return true;
}
/*
// returns true, if we need additional use with New Super path.
bool GetSuperPath(CFSTR path, UString &superPath)
{
if (GetSuperPathBase(path, superPath))
return !superPath.IsEmpty();
return false;
}
*/
#endif // WIN_LONG_PATH
bool GetFullPath(CFSTR dirPrefix, CFSTR s, FString &res)
{
res = s;
#ifdef UNDER_CE
if (s[0] != CHAR_PATH_SEPARATOR)
{
if (!dirPrefix)
return false;
res = dirPrefix;
res += s;
}
#else
unsigned prefixSize = GetRootPrefixSize(s);
if (prefixSize != 0)
{
if (!AreThereDotsFolders(s + prefixSize))
return true;
UString rem = fs2us(s + prefixSize);
if (!ResolveDotsFolders(rem))
return true; // maybe false;
res.DeleteFrom(prefixSize);
res += us2fs(rem);
return true;
}
/*
FChar c = s[0];
if (c == 0)
return true;
if (c == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)))
return true;
if (c == CHAR_PATH_SEPARATOR && s[1] == CHAR_PATH_SEPARATOR)
return true;
if (IsDrivePath(s))
return true;
*/
UString curDir;
if (dirPrefix)
curDir = fs2us(dirPrefix);
else
{
if (!GetCurDir(curDir))
return false;
}
if (!curDir.IsEmpty() && curDir.Back() != WCHAR_PATH_SEPARATOR)
curDir += WCHAR_PATH_SEPARATOR;
unsigned fixedSize = 0;
#ifdef _WIN32
if (IsSuperPath(curDir))
{
fixedSize = GetRootPrefixSize_Of_SuperPath(curDir);
if (fixedSize == 0)
return false;
}
else
{
if (IsDrivePath(curDir))
fixedSize = kDrivePrefixSize;
else
{
if (curDir[0] != WCHAR_PATH_SEPARATOR || curDir[1] != WCHAR_PATH_SEPARATOR)
return false;
fixedSize = GetRootPrefixSize_Of_NetworkPath(&curDir[2]);
if (fixedSize == 0)
return false;
fixedSize += 2;
}
}
#endif // _WIN32
UString temp;
if (s[0] == CHAR_PATH_SEPARATOR)
{
temp = fs2us(s + 1);
}
else
{
temp += curDir.Ptr(fixedSize);
temp += fs2us(s);
}
if (!ResolveDotsFolders(temp))
return false;
curDir.DeleteFrom(fixedSize);
res = us2fs(curDir);
res += us2fs(temp);
#endif // UNDER_CE
return true;
}
bool GetFullPath(CFSTR path, FString &fullPath)
{
return GetFullPath(NULL, path, fullPath);
}
}}}
Executable → Regular
+57
View File
@@ -12,6 +12,63 @@ namespace NName {
void NormalizeDirPathPrefix(FString &dirPath); // ensures that it ended with '\\', if dirPath is not epmty
void NormalizeDirPathPrefix(UString &dirPath);
#ifdef _WIN32
extern const wchar_t *kSuperPathPrefix; /* \\?\ */
const unsigned kDevicePathPrefixSize = 4;
const unsigned kSuperPathPrefixSize = 4;
const unsigned kSuperUncPathPrefixSize = kSuperPathPrefixSize + 4;
bool IsDevicePath(CFSTR s) throw(); /* \\.\ */
bool IsSuperUncPath(CFSTR s) throw();
bool IsDrivePath(const wchar_t *s) throw();
bool IsSuperPath(const wchar_t *s) throw();
bool IsSuperOrDevicePath(const wchar_t *s) throw();
#ifndef USE_UNICODE_FSTRING
bool IsDrivePath(CFSTR s) throw();
bool IsSuperPath(CFSTR s) throw();
bool IsSuperOrDevicePath(CFSTR s) throw();
#endif
#endif // _WIN32
bool IsAbsolutePath(const wchar_t *s) throw();
unsigned GetRootPrefixSize(const wchar_t *s) throw();
#ifdef WIN_LONG_PATH
const int kSuperPathType_UseOnlyMain = 0;
const int kSuperPathType_UseOnlySuper = 1;
const int kSuperPathType_UseMainAndSuper = 2;
int GetUseSuperPathType(CFSTR s) throw();
bool GetSuperPath(CFSTR path, UString &longPath, bool onlyIfNew);
bool GetSuperPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2, bool onlyIfNew);
#define USE_MAIN_PATH (__useSuperPathType != kSuperPathType_UseOnlySuper)
#define USE_MAIN_PATH_2 (__useSuperPathType1 != kSuperPathType_UseOnlySuper && __useSuperPathType2 != kSuperPathType_UseOnlySuper)
#define USE_SUPER_PATH (__useSuperPathType != kSuperPathType_UseOnlyMain)
#define USE_SUPER_PATH_2 (__useSuperPathType1 != kSuperPathType_UseOnlyMain || __useSuperPathType2 != kSuperPathType_UseOnlyMain)
#define IF_USE_MAIN_PATH int __useSuperPathType = GetUseSuperPathType(path); if (USE_MAIN_PATH)
#define IF_USE_MAIN_PATH_2(x1, x2) \
int __useSuperPathType1 = GetUseSuperPathType(x1); \
int __useSuperPathType2 = GetUseSuperPathType(x2); \
if (USE_MAIN_PATH_2)
#else
#define IF_USE_MAIN_PATH
#define IF_USE_MAIN_PATH_2(x1, x2)
#endif // WIN_LONG_PATH
bool GetFullPath(CFSTR dirPrefix, CFSTR path, FString &fullPath);
bool GetFullPath(CFSTR path, FString &fullPath);
}}}
#endif
Executable → Regular
+21 -1
View File
@@ -2,8 +2,10 @@
#include "StdAfx.h"
#ifndef UNDER_CE
#ifndef _UNICODE
#include "Common/StringConvert.h"
#include "../Common/StringConvert.h"
#endif
#include "FileSystem.h"
@@ -67,6 +69,13 @@ UINT MyGetDriveType(CFSTR pathName)
}
}
typedef BOOL (WINAPI * GetDiskFreeSpaceExA_Pointer)(
LPCSTR lpDirectoryName, // directory name
PULARGE_INTEGER lpFreeBytesAvailable, // bytes available to caller
PULARGE_INTEGER lpTotalNumberOfBytes, // bytes on disk
PULARGE_INTEGER lpTotalNumberOfFreeBytes // free bytes on disk
);
typedef BOOL (WINAPI * GetDiskFreeSpaceExW_Pointer)(
LPCWSTR lpDirectoryName, // directory name
PULARGE_INTEGER lpFreeBytesAvailable, // bytes available to caller
@@ -81,6 +90,15 @@ bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize,
#ifndef _UNICODE
if (!g_IsNT)
{
GetDiskFreeSpaceExA_Pointer pGetDiskFreeSpaceEx = (GetDiskFreeSpaceExA_Pointer)GetProcAddress(
GetModuleHandle(TEXT("kernel32.dll")), "GetDiskFreeSpaceExA");
if (pGetDiskFreeSpaceEx)
{
ULARGE_INTEGER freeBytesToCaller2, totalSize2, freeSize2;
sizeIsDetected = BOOLToBool(pGetDiskFreeSpaceEx(fs2fas(rootPath), &freeBytesToCaller2, &totalSize2, &freeSize2));
totalSize = totalSize2.QuadPart;
freeSize = freeSize2.QuadPart;
}
if (!::GetDiskFreeSpace(fs2fas(rootPath), &numSectorsPerCluster, &bytesPerSector, &numFreeClusters, &numClusters))
return false;
}
@@ -109,3 +127,5 @@ bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize,
}
}}}
#endif
Executable → Regular
+1 -1
View File
@@ -4,7 +4,7 @@
#define __WINDOWS_FILE_SYSTEM_H
#include "../Common/MyString.h"
#include "../Common/Types.h"
#include "../Common/MyTypes.h"
namespace NWindows {
namespace NFile {
Executable → Regular
View File
-53
View File
@@ -1,53 +0,0 @@
// Windows/Memory.h
#ifndef __WINDOWS_MEMORY_H
#define __WINDOWS_MEMORY_H
namespace NWindows {
namespace NMemory {
class CGlobal
{
HGLOBAL m_MemoryHandle;
public:
CGlobal(): m_MemoryHandle(NULL){};
~CGlobal() { Free(); }
operator HGLOBAL() const { return m_MemoryHandle; };
void Attach(HGLOBAL hGlobal)
{
Free();
m_MemoryHandle = hGlobal;
}
HGLOBAL Detach()
{
HGLOBAL h = m_MemoryHandle;
m_MemoryHandle = NULL;
return h;
}
bool Alloc(UINT flags, SIZE_T size);
bool Free();
LPVOID Lock() const { return GlobalLock(m_MemoryHandle); }
void Unlock() const { GlobalUnlock(m_MemoryHandle); }
bool ReAlloc(SIZE_T size);
};
class CGlobalLock
{
HGLOBAL m_Global;
LPVOID m_Pointer;
public:
LPVOID GetPointer() const { return m_Pointer; }
CGlobalLock(HGLOBAL hGlobal): m_Global(hGlobal)
{
m_Pointer = GlobalLock(hGlobal);
};
~CGlobalLock()
{
if (m_Pointer != NULL)
GlobalUnlock(m_Global);
}
};
}}
#endif
+8 -8
View File
@@ -1,8 +1,8 @@
// Windows/Memory.cpp
// Windows/MemoryGlobal.cpp
#include "StdAfx.h"
#include "Windows/Memory.h"
#include "MemoryGlobal.h"
namespace NWindows {
namespace NMemory {
@@ -12,24 +12,24 @@ bool CGlobal::Alloc(UINT flags, SIZE_T size)
HGLOBAL newBlock = ::GlobalAlloc(flags, size);
if (newBlock == NULL)
return false;
m_MemoryHandle = newBlock;
_global = newBlock;
return true;
}
bool CGlobal::Free()
{
if (m_MemoryHandle == NULL)
if (_global == NULL)
return true;
m_MemoryHandle = ::GlobalFree(m_MemoryHandle);
return (m_MemoryHandle == NULL);
_global = ::GlobalFree(_global);
return (_global == NULL);
}
bool CGlobal::ReAlloc(SIZE_T size)
{
HGLOBAL newBlock = ::GlobalReAlloc(m_MemoryHandle, size, GMEM_MOVEABLE);
HGLOBAL newBlock = ::GlobalReAlloc(_global, size, GMEM_MOVEABLE);
if (newBlock == NULL)
return false;
m_MemoryHandle = newBlock;
_global = newBlock;
return true;
}
+53
View File
@@ -0,0 +1,53 @@
// Windows/MemoryGlobal.h
#ifndef __WINDOWS_MEMORY_GLOBAL_H
#define __WINDOWS_MEMORY_GLOBAL_H
namespace NWindows {
namespace NMemory {
class CGlobal
{
HGLOBAL _global;
public:
CGlobal(): _global(NULL){};
~CGlobal() { Free(); }
operator HGLOBAL() const { return _global; };
void Attach(HGLOBAL hGlobal)
{
Free();
_global = hGlobal;
}
HGLOBAL Detach()
{
HGLOBAL h = _global;
_global = NULL;
return h;
}
bool Alloc(UINT flags, SIZE_T size) throw();
bool Free() throw();
LPVOID Lock() const { return GlobalLock(_global); }
void Unlock() const { GlobalUnlock(_global); }
bool ReAlloc(SIZE_T size) throw();
};
class CGlobalLock
{
HGLOBAL _global;
LPVOID _ptr;
public:
LPVOID GetPointer() const { return _ptr; }
CGlobalLock(HGLOBAL hGlobal): _global(hGlobal)
{
_ptr = GlobalLock(hGlobal);
};
~CGlobalLock()
{
if (_ptr != NULL)
GlobalUnlock(_global);
}
};
}}
#endif
Executable → Regular
+44 -56
View File
@@ -1,4 +1,4 @@
// Common/MemoryLock.cpp
// Windows/MemoryLock.cpp
#include "StdAfx.h"
@@ -7,75 +7,63 @@ namespace NSecurity {
#ifndef UNDER_CE
#ifndef _UNICODE
typedef BOOL (WINAPI * OpenProcessTokenP)(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);
typedef BOOL (WINAPI * LookupPrivilegeValueP)(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid);
typedef BOOL (WINAPI * AdjustTokenPrivilegesP)(HANDLE TokenHandle, BOOL DisableAllPrivileges,
PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState,PDWORD ReturnLength);
#ifdef _UNICODE
#define MY_FUNC_SELECT(f) :: ## f
#else
#define MY_FUNC_SELECT(f) my_ ## f
extern "C" {
typedef BOOL (WINAPI * Func_OpenProcessToken)(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);
typedef BOOL (WINAPI * Func_LookupPrivilegeValue)(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid);
typedef BOOL (WINAPI * Func_AdjustTokenPrivileges)(HANDLE TokenHandle, BOOL DisableAllPrivileges,
PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength);
}
#define GET_PROC_ADDR(fff, name) Func_ ## fff my_ ## fff = (Func_ ## fff)GetProcAddress(hModule, name)
#endif
#ifdef _UNICODE
bool EnableLockMemoryPrivilege(
#else
static bool EnableLockMemoryPrivilege2(HMODULE hModule,
#endif
bool enable)
bool EnablePrivilege(LPCTSTR privilegeName, bool enable)
{
bool res = false;
#ifndef _UNICODE
HMODULE hModule = ::LoadLibrary(TEXT("Advapi32.dll"));
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;
GET_PROC_ADDR(OpenProcessToken, "OpenProcessToken");
GET_PROC_ADDR(LookupPrivilegeValue, "LookupPrivilegeValueA");
GET_PROC_ADDR(AdjustTokenPrivileges, "AdjustTokenPrivileges");
if (my_OpenProcessToken &&
my_AdjustTokenPrivileges &&
my_LookupPrivilegeValue)
#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);
HANDLE token;
if (MY_FUNC_SELECT(OpenProcessToken)(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
{
TOKEN_PRIVILEGES tp;
if (MY_FUNC_SELECT(LookupPrivilegeValue)(NULL, privilegeName, &(tp.Privileges[0].Luid)))
{
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = (enable ? SE_PRIVILEGE_ENABLED : 0);
if (MY_FUNC_SELECT(AdjustTokenPrivileges)(token, FALSE, &tp, 0, NULL, NULL))
res = (GetLastError() == ERROR_SUCCESS);
}
::CloseHandle(token);
}
}
::CloseHandle(token);
return res;
}
#ifndef _UNICODE
#ifndef _UNICODE
bool EnableLockMemoryPrivilege(bool enable)
{
HMODULE hModule = LoadLibrary(TEXT("Advapi32.dll"));
if (hModule == NULL)
return false;
bool res = EnableLockMemoryPrivilege2(hModule, enable);
::FreeLibrary(hModule);
#endif
return res;
}
#endif
#endif
Executable → Regular
+24 -3
View File
@@ -1,13 +1,34 @@
// Windows/MemoryLock.h
#ifndef __WINDOWS_MEMORYLOCK_H
#define __WINDOWS_MEMORYLOCK_H
#ifndef __WINDOWS_MEMORY_LOCK_H
#define __WINDOWS_MEMORY_LOCK_H
namespace NWindows {
namespace NSecurity {
#ifndef UNDER_CE
bool EnableLockMemoryPrivilege(bool enable = true);
bool EnablePrivilege(LPCTSTR privilegeName, bool enable = true);
inline bool EnablePrivilege_LockMemory(bool enable = true)
{
return EnablePrivilege(SE_LOCK_MEMORY_NAME, enable);
}
inline void EnablePrivilege_SymLink()
{
/* Probably we do not to set any Privilege for junction points.
But we need them for Symbolic links */
NSecurity::EnablePrivilege(SE_RESTORE_NAME);
/* Probably we need only SE_RESTORE_NAME, but there is also
SE_CREATE_SYMBOLIC_LINK_NAME. So we set it also. Do we need it? */
NSecurity::EnablePrivilege(TEXT("SeCreateSymbolicLinkPrivilege")); // SE_CREATE_SYMBOLIC_LINK_NAME
// Do we need to set SE_BACKUP_NAME ?
}
#endif
}}
Executable → Regular
+25 -4
View File
@@ -3,9 +3,9 @@
#include "StdAfx.h"
#ifndef _UNICODE
#include "Common/StringConvert.h"
#include "../Common/StringConvert.h"
#endif
#include "Windows/Menu.h"
#include "Menu.h"
#ifndef _UNICODE
extern bool g_IsNT;
@@ -13,10 +13,31 @@ extern bool g_IsNT;
namespace NWindows {
/*
structures
MENUITEMINFOA
MENUITEMINFOW
contain additional member:
#if (WINVER >= 0x0500)
HBITMAP hbmpItem;
#endif
If we compile the source code with (WINVER >= 0x0500), some functions
will not work at NT 4.0, if cbSize is set as sizeof(MENUITEMINFO*).
So we use size of old version of structure. */
#if defined(UNDER_CE) || defined(_WIN64) || (WINVER < 0x0500)
#define my_compatib_MENUITEMINFOA_size sizeof(MENUITEMINFOA)
#define my_compatib_MENUITEMINFOW_size sizeof(MENUITEMINFOW)
#else
#define MY_STRUCT_SIZE_BEFORE(structname, member) ((UINT)(UINT_PTR)((LPBYTE)(&((structname*)0)->member) - (LPBYTE)(structname*)0))
#define my_compatib_MENUITEMINFOA_size MY_STRUCT_SIZE_BEFORE(MENUITEMINFOA, hbmpItem)
#define my_compatib_MENUITEMINFOW_size MY_STRUCT_SIZE_BEFORE(MENUITEMINFOW, hbmpItem)
#endif
static void ConvertItemToSysForm(const CMenuItem &item, MENUITEMINFOW &si)
{
ZeroMemory(&si, sizeof(si));
si.cbSize = sizeof(si);
si.cbSize = my_compatib_MENUITEMINFOW_size; // sizeof(si);
si.fMask = item.fMask;
si.fType = item.fType;
si.fState = item.fState;
@@ -31,7 +52,7 @@ static void ConvertItemToSysForm(const CMenuItem &item, MENUITEMINFOW &si)
static void ConvertItemToSysForm(const CMenuItem &item, MENUITEMINFOA &si)
{
ZeroMemory(&si, sizeof(si));
si.cbSize = sizeof(si);
si.cbSize = my_compatib_MENUITEMINFOA_size; // sizeof(si);
si.fMask = item.fMask;
si.fType = item.fType;
si.fState = item.fState;
Executable → Regular
+3 -2
View File
@@ -3,8 +3,9 @@
#ifndef __WINDOWS_MENU_H
#define __WINDOWS_MENU_H
#include "Common/MyString.h"
#include "Windows/Defs.h"
#include "../Common/MyString.h"
#include "Defs.h"
namespace NWindows {
Executable → Regular
View File
Executable → Regular
View File
Executable → Regular
+10 -14
View File
@@ -2,11 +2,13 @@
#include "StdAfx.h"
#include "../Common/MyBuffer.h"
#ifndef _UNICODE
#include "Common/StringConvert.h"
#include "../Common/StringConvert.h"
#endif
#include "Windows/Net.h"
#include "Net.h"
#ifndef _UNICODE
extern bool g_IsNT;
@@ -202,9 +204,8 @@ DWORD CEnum::NextW(LPDWORD lpcCount, LPVOID lpBuffer, LPDWORD lpBufferSize)
DWORD CEnum::Next(CResource &resource)
{
CByteBuffer byteBuffer;
const DWORD kBufferSize = 16384;
byteBuffer.SetCapacity(kBufferSize);
CByteArr byteBuffer(kBufferSize);
LPNETRESOURCE lpnrLocal = (LPNETRESOURCE) (BYTE *)(byteBuffer);
ZeroMemory(lpnrLocal, kBufferSize);
DWORD bufferSize = kBufferSize;
@@ -223,9 +224,8 @@ DWORD CEnum::Next(CResourceW &resource)
{
if (g_IsNT)
{
CByteBuffer byteBuffer;
const DWORD kBufferSize = 16384;
byteBuffer.SetCapacity(kBufferSize);
CByteArr byteBuffer(kBufferSize);
LPNETRESOURCEW lpnrLocal = (LPNETRESOURCEW) (BYTE *)(byteBuffer);
ZeroMemory(lpnrLocal, kBufferSize);
DWORD bufferSize = kBufferSize;
@@ -248,9 +248,8 @@ DWORD CEnum::Next(CResourceW &resource)
DWORD GetResourceParent(const CResource &resource, CResource &parentResource)
{
CByteBuffer byteBuffer;
const DWORD kBufferSize = 16384;
byteBuffer.SetCapacity(kBufferSize);
CByteArr byteBuffer(kBufferSize);
LPNETRESOURCE lpnrLocal = (LPNETRESOURCE) (BYTE *)(byteBuffer);
ZeroMemory(lpnrLocal, kBufferSize);
DWORD bufferSize = kBufferSize;
@@ -268,9 +267,8 @@ DWORD GetResourceParent(const CResourceW &resource, CResourceW &parentResource)
{
if (g_IsNT)
{
CByteBuffer byteBuffer;
const DWORD kBufferSize = 16384;
byteBuffer.SetCapacity(kBufferSize);
CByteArr byteBuffer(kBufferSize);
LPNETRESOURCEW lpnrLocal = (LPNETRESOURCEW) (BYTE *)(byteBuffer);
ZeroMemory(lpnrLocal, kBufferSize);
DWORD bufferSize = kBufferSize;
@@ -293,9 +291,8 @@ DWORD GetResourceParent(const CResourceW &resource, CResourceW &parentResource)
DWORD GetResourceInformation(const CResource &resource,
CResource &destResource, CSysString &systemPathPart)
{
CByteBuffer byteBuffer;
const DWORD kBufferSize = 16384;
byteBuffer.SetCapacity(kBufferSize);
CByteArr byteBuffer(kBufferSize);
LPNETRESOURCE lpnrLocal = (LPNETRESOURCE) (BYTE *)(byteBuffer);
ZeroMemory(lpnrLocal, kBufferSize);
DWORD bufferSize = kBufferSize;
@@ -318,9 +315,8 @@ DWORD GetResourceInformation(const CResourceW &resource,
{
if (g_IsNT)
{
CByteBuffer byteBuffer;
const DWORD kBufferSize = 16384;
byteBuffer.SetCapacity(kBufferSize);
CByteArr byteBuffer(kBufferSize);
LPNETRESOURCEW lpnrLocal = (LPNETRESOURCEW) (BYTE *)(byteBuffer);
ZeroMemory(lpnrLocal, kBufferSize);
DWORD bufferSize = kBufferSize;
Executable → Regular
+1 -2
View File
@@ -3,8 +3,7 @@
#ifndef __WINDOWS_NET_H
#define __WINDOWS_NET_H
#include "Common/Buffer.h"
#include "Common/MyString.h"
#include "../Common/MyString.h"
namespace NWindows {
namespace NNet {
Executable → Regular
View File
Executable → Regular
View File
Executable → Regular
View File
+8 -3
View File
@@ -1,10 +1,10 @@
// Process.cpp
// ProcessUtils.cpp
#include "StdAfx.h"
#include "../Common/StringConvert.h"
#include "Process.h"
#include "ProcessUtils.h"
#ifndef _UNICODE
extern bool g_IsNT;
@@ -12,10 +12,15 @@ extern bool g_IsNT;
namespace NWindows {
#ifndef UNDER_CE
static UString GetQuotedString(const UString &s)
{
return UString(L'\"') + s + UString(L'\"');
UString s2 = L'\"';
s2 += s;
s2 += L'\"';
return s2;
}
#endif
WRes CProcess::Create(LPCWSTR imageName, const UString &params, LPCWSTR curDir)
{
+3 -3
View File
@@ -1,7 +1,7 @@
// Windows/Process.h
// Windows/ProcessUtils.h
#ifndef __WINDOWS_PROCESS_H
#define __WINDOWS_PROCESS_H
#ifndef __WINDOWS_PROCESS_UTILS_H
#define __WINDOWS_PROCESS_UTILS_H
#include <psapi.h>
Executable → Regular
+70 -13
View File
@@ -2,13 +2,43 @@
#include "StdAfx.h"
#include "PropVariant.h"
#include "../Common/Defs.h"
#include "PropVariant.h"
namespace NWindows {
namespace NCOM {
HRESULT PropVarEm_Alloc_Bstr(PROPVARIANT *p, unsigned numChars)
{
p->bstrVal = ::SysAllocStringLen(0, numChars);
if (!p->bstrVal)
{
p->vt = VT_ERROR;
p->scode = E_OUTOFMEMORY;
return E_OUTOFMEMORY;
}
p->vt = VT_BSTR;
return S_OK;
}
HRESULT PropVarEm_Set_Str(PROPVARIANT *p, const char *s)
{
UINT len = (UINT)strlen(s);
p->bstrVal = ::SysAllocStringByteLen(0, (UINT)len * sizeof(OLECHAR));
if (!p->bstrVal)
{
p->vt = VT_ERROR;
p->scode = E_OUTOFMEMORY;
return E_OUTOFMEMORY;
}
p->vt = VT_BSTR;
BSTR dest = p->bstrVal;
for (UINT i = 0; i <= len; i++)
dest[i] = s[i];
return S_OK;
}
CPropVariant::CPropVariant(const PROPVARIANT &varSrc)
{
vt = VT_EMPTY;
@@ -67,7 +97,6 @@ CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
return *this;
}
CPropVariant& CPropVariant::operator=(const char *s)
{
InternalClear();
@@ -100,22 +129,40 @@ CPropVariant& CPropVariant::operator=(bool bSrc)
return *this;
}
BSTR CPropVariant::AllocBstr(unsigned numChars)
{
if (vt != VT_EMPTY)
InternalClear();
vt = VT_BSTR;
wReserved1 = 0;
bstrVal = ::SysAllocStringLen(0, numChars);
if (bstrVal == NULL)
{
throw kMemException;
// vt = VT_ERROR;
// scode = E_OUTOFMEMORY;
}
return bstrVal;
}
#define SET_PROP_FUNC(type, id, dest) \
CPropVariant& CPropVariant::operator=(type value) \
{ if (vt != id) { InternalClear(); vt = id; } \
dest = value; return *this; }
SET_PROP_FUNC(Byte, VT_UI1, bVal)
SET_PROP_FUNC(Int16, VT_I2, iVal)
// SET_PROP_FUNC(Int16, VT_I2, iVal)
SET_PROP_FUNC(Int32, VT_I4, lVal)
SET_PROP_FUNC(UInt32, VT_UI4, ulVal)
SET_PROP_FUNC(UInt64, VT_UI8, uhVal.QuadPart)
SET_PROP_FUNC(Int64, VT_I8, hVal.QuadPart)
SET_PROP_FUNC(const FILETIME &, VT_FILETIME, filetime)
static HRESULT MyPropVariantClear(PROPVARIANT *prop)
HRESULT PropVariant_Clear(PROPVARIANT *prop) throw()
{
switch(prop->vt)
switch (prop->vt)
{
case VT_EMPTY:
case VT_UI1:
case VT_I1:
case VT_I2:
@@ -134,14 +181,21 @@ static HRESULT MyPropVariantClear(PROPVARIANT *prop)
case VT_DATE:
prop->vt = VT_EMPTY;
prop->wReserved1 = 0;
prop->wReserved2 = 0;
prop->wReserved3 = 0;
prop->uhVal.QuadPart = 0;
return S_OK;
}
return ::VariantClear((VARIANTARG *)prop);
// return ::PropVariantClear(prop);
// PropVariantClear can clear VT_BLOB.
}
HRESULT CPropVariant::Clear()
{
return MyPropVariantClear(this);
if (vt == VT_EMPTY)
return S_OK;
return PropVariant_Clear(this);
}
HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc)
@@ -184,9 +238,12 @@ HRESULT CPropVariant::Attach(PROPVARIANT *pSrc)
HRESULT CPropVariant::Detach(PROPVARIANT *pDest)
{
HRESULT hr = MyPropVariantClear(pDest);
if (FAILED(hr))
return hr;
if (pDest->vt != VT_EMPTY)
{
HRESULT hr = PropVariant_Clear(pDest);
if (FAILED(hr))
return hr;
}
memcpy(pDest, this, sizeof(PROPVARIANT));
vt = VT_EMPTY;
return S_OK;
@@ -194,6 +251,8 @@ HRESULT CPropVariant::Detach(PROPVARIANT *pDest)
HRESULT CPropVariant::InternalClear()
{
if (vt == VT_EMPTY)
return S_OK;
HRESULT hr = Clear();
if (FAILED(hr))
{
@@ -233,9 +292,7 @@ int CPropVariant::Compare(const CPropVariant &a)
case VT_UI8: return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart);
case VT_BOOL: return -MyCompare(boolVal, a.boolVal);
case VT_FILETIME: return ::CompareFileTime(&filetime, &a.filetime);
case VT_BSTR:
return 0; // Not implemented
// return MyCompare(aPropVarint.cVal);
case VT_BSTR: return 0; // Not implemented
default: return 0;
}
}
Executable → Regular
+72 -21
View File
@@ -1,29 +1,73 @@
// Windows/PropVariant.h
#ifndef __WINDOWS_PROPVARIANT_H
#define __WINDOWS_PROPVARIANT_H
#ifndef __WINDOWS_PROP_VARIANT_H
#define __WINDOWS_PROP_VARIANT_H
#include "../Common/MyTypes.h"
#include "../Common/MyWindows.h"
#include "../Common/Types.h"
namespace NWindows {
namespace NCOM {
HRESULT PropVariant_Clear(PROPVARIANT *p) throw();
HRESULT PropVarEm_Alloc_Bstr(PROPVARIANT *p, unsigned numChars) throw();
HRESULT PropVarEm_Set_Str(PROPVARIANT *p, const char *s) throw();
inline void PropVarEm_Set_UInt32(PROPVARIANT *p, UInt32 v) throw()
{
p->vt = VT_UI4;
p->ulVal = v;
}
inline void PropVarEm_Set_UInt64(PROPVARIANT *p, UInt64 v) throw()
{
p->vt = VT_UI8;
p->uhVal.QuadPart = v;
}
inline void PropVarEm_Set_FileTime64(PROPVARIANT *p, UInt64 v) throw()
{
p->vt = VT_FILETIME;
p->filetime.dwLowDateTime = (DWORD)v;
p->filetime.dwHighDateTime = (DWORD)(v >> 32);
}
inline void PropVarEm_Set_Bool(PROPVARIANT *p, bool b) throw()
{
p->vt = VT_BOOL;
p->boolVal = (b ? VARIANT_TRUE : VARIANT_FALSE);
}
class CPropVariant : public tagPROPVARIANT
{
public:
CPropVariant() { vt = VT_EMPTY; wReserved1 = 0; }
~CPropVariant() { Clear(); }
CPropVariant()
{
vt = VT_EMPTY;
wReserved1 = 0;
// wReserved2 = 0;
// wReserved3 = 0;
// uhVal.QuadPart = 0;
bstrVal = 0;
}
~CPropVariant() throw() { Clear(); }
CPropVariant(const PROPVARIANT &varSrc);
CPropVariant(const CPropVariant &varSrc);
CPropVariant(BSTR bstrSrc);
CPropVariant(LPCOLESTR lpszSrc);
CPropVariant(bool bSrc) { vt = VT_BOOL; wReserved1 = 0; boolVal = (bSrc ? VARIANT_TRUE : VARIANT_FALSE); };
CPropVariant(Byte value) { vt = VT_UI1; wReserved1 = 0; bVal = value; }
CPropVariant(Int16 value) { vt = VT_I2; wReserved1 = 0; iVal = value; }
CPropVariant(Int32 value) { vt = VT_I4; wReserved1 = 0; lVal = value; }
private:
CPropVariant(Int16 value); // { vt = VT_I2; wReserved1 = 0; iVal = value; }
CPropVariant(Int32 value); // { vt = VT_I4; wReserved1 = 0; lVal = value; }
public:
CPropVariant(UInt32 value) { vt = VT_UI4; wReserved1 = 0; ulVal = value; }
CPropVariant(UInt64 value) { vt = VT_UI8; wReserved1 = 0; uhVal.QuadPart = value; }
CPropVariant(Int64 value) { vt = VT_I8; wReserved1 = 0; hVal.QuadPart = value; }
CPropVariant(const FILETIME &value) { vt = VT_FILETIME; wReserved1 = 0; filetime = value; }
CPropVariant& operator=(const CPropVariant &varSrc);
@@ -31,24 +75,31 @@ public:
CPropVariant& operator=(BSTR bstrSrc);
CPropVariant& operator=(LPCOLESTR lpszSrc);
CPropVariant& operator=(const char *s);
CPropVariant& operator=(bool bSrc);
CPropVariant& operator=(Byte value);
CPropVariant& operator=(Int16 value);
CPropVariant& operator=(Int32 value);
CPropVariant& operator=(UInt32 value);
CPropVariant& operator=(Int64 value);
CPropVariant& operator=(UInt64 value);
CPropVariant& operator=(const FILETIME &value);
CPropVariant& operator=(bool bSrc) throw();
CPropVariant& operator=(Byte value) throw();
private:
CPropVariant& operator=(Int16 value) throw();
HRESULT Clear();
HRESULT Copy(const PROPVARIANT *pSrc);
HRESULT Attach(PROPVARIANT *pSrc);
HRESULT Detach(PROPVARIANT *pDest);
public:
CPropVariant& operator=(Int32 value) throw();
CPropVariant& operator=(UInt32 value) throw();
CPropVariant& operator=(UInt64 value) throw();
CPropVariant& operator=(Int64 value) throw();
CPropVariant& operator=(const FILETIME &value) throw();
HRESULT InternalClear();
BSTR AllocBstr(unsigned numChars);
HRESULT Clear() throw();
HRESULT Copy(const PROPVARIANT *pSrc) throw();
HRESULT Attach(PROPVARIANT *pSrc) throw();
HRESULT Detach(PROPVARIANT *pDest) throw();
HRESULT InternalClear() throw();
void InternalCopy(const PROPVARIANT *pSrc);
int Compare(const CPropVariant &a1);
int Compare(const CPropVariant &a) throw();
};
}}
+99
View File
@@ -0,0 +1,99 @@
// PropVariantConvert.cpp
#include "StdAfx.h"
#include "../Common/IntToString.h"
#include "Defs.h"
#include "PropVariantConv.h"
#define UINT_TO_STR_2(c, val) { s[0] = (c); s[1] = (char)('0' + (val) / 10); s[2] = (char)('0' + (val) % 10); s += 3; }
bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime, bool includeSeconds)
{
SYSTEMTIME st;
if (!BOOLToBool(FileTimeToSystemTime(&ft, &st)))
{
*s = 0;
return false;
}
unsigned val = st.wYear;
if (val >= 10000)
{
*s++ = (char)('0' + val / 10000);
val %= 10000;
}
{
s[3] = (char)('0' + val % 10); val /= 10;
s[2] = (char)('0' + val % 10); val /= 10;
s[1] = (char)('0' + val % 10);
s[0] = (char)('0' + val / 10);
s += 4;
}
UINT_TO_STR_2('-', st.wMonth);
UINT_TO_STR_2('-', st.wDay);
if (includeTime)
{
UINT_TO_STR_2(' ', st.wHour);
UINT_TO_STR_2(':', st.wMinute);
if (includeSeconds)
UINT_TO_STR_2(':', st.wSecond);
}
*s = 0;
return true;
}
void ConvertFileTimeToString(const FILETIME &ft, wchar_t *dest, bool includeTime, bool includeSeconds)
{
char s[32];
ConvertFileTimeToString(ft, s, includeTime, includeSeconds);
for (unsigned i = 0;; i++)
{
unsigned char c = s[i];
dest[i] = c;
if (c == 0)
return;
}
}
void ConvertPropVariantToShortString(const PROPVARIANT &prop, char *dest)
{
*dest = 0;
switch (prop.vt)
{
case VT_EMPTY: return;
case VT_BSTR: dest[0] = '?'; dest[1] = 0; return;
case VT_UI1: ConvertUInt32ToString(prop.bVal, dest); return;
case VT_UI2: ConvertUInt32ToString(prop.uiVal, dest); return;
case VT_UI4: ConvertUInt32ToString(prop.ulVal, dest); return;
case VT_UI8: ConvertUInt64ToString(prop.uhVal.QuadPart, dest); return;
case VT_FILETIME: ConvertFileTimeToString(prop.filetime, dest, true, true); return;
// case VT_I1: return ConvertInt64ToString(prop.cVal, dest); return;
case VT_I2: ConvertInt64ToString(prop.iVal, dest); return;
case VT_I4: ConvertInt64ToString(prop.lVal, dest); return;
case VT_I8: ConvertInt64ToString(prop.hVal.QuadPart, dest); return;
case VT_BOOL: dest[0] = VARIANT_BOOLToBool(prop.boolVal) ? '+' : '-'; dest[1] = 0; return;
default: dest[0] = '?'; dest[1] = ':'; ConvertUInt64ToString(prop.vt, dest + 2);
}
}
void ConvertPropVariantToShortString(const PROPVARIANT &prop, wchar_t *dest)
{
*dest = 0;
switch (prop.vt)
{
case VT_EMPTY: return;
case VT_BSTR: dest[0] = '?'; dest[1] = 0; return;
case VT_UI1: ConvertUInt32ToString(prop.bVal, dest); return;
case VT_UI2: ConvertUInt32ToString(prop.uiVal, dest); return;
case VT_UI4: ConvertUInt32ToString(prop.ulVal, dest); return;
case VT_UI8: ConvertUInt64ToString(prop.uhVal.QuadPart, dest); return;
case VT_FILETIME: ConvertFileTimeToString(prop.filetime, dest, true, true); return;
// case VT_I1: return ConvertInt64ToString(prop.cVal, dest); return;
case VT_I2: ConvertInt64ToString(prop.iVal, dest); return;
case VT_I4: ConvertInt64ToString(prop.lVal, dest); return;
case VT_I8: ConvertInt64ToString(prop.hVal.QuadPart, dest); return;
case VT_BOOL: dest[0] = VARIANT_BOOLToBool(prop.boolVal) ? '+' : '-'; dest[1] = 0; return;
default: dest[0] = '?'; dest[1] = ':'; ConvertUInt32ToString(prop.vt, dest + 2);
}
}
+30
View File
@@ -0,0 +1,30 @@
// Windows/PropVariantConv.h
#ifndef __PROP_VARIANT_CONV_H
#define __PROP_VARIANT_CONV_H
#include "../Common/MyTypes.h"
// provide at least 32 bytes for buffer including zero-end
bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime = true, bool includeSeconds = true) throw();
void ConvertFileTimeToString(const FILETIME &ft, wchar_t *s, bool includeTime = true, bool includeSeconds = true) throw();
// provide at least 32 bytes for buffer including zero-end
// don't send VT_BSTR to these functions
void ConvertPropVariantToShortString(const PROPVARIANT &prop, char *dest) throw();
void ConvertPropVariantToShortString(const PROPVARIANT &prop, wchar_t *dest) throw();
inline bool ConvertPropVariantToUInt64(const PROPVARIANT &prop, UInt64 &value)
{
switch (prop.vt)
{
case VT_UI8: value = (UInt64)prop.uhVal.QuadPart; return true;
case VT_UI4: value = prop.ulVal; return true;
case VT_UI2: value = prop.uiVal; return true;
case VT_UI1: value = prop.bVal; return true;
case VT_EMPTY: return false;
default: throw 151199;
}
}
#endif
-105
View File
@@ -1,105 +0,0 @@
// PropVariantConversions.cpp
#include "StdAfx.h"
#include "Common/IntToString.h"
#include "Common/StringConvert.h"
#include "Windows/Defs.h"
#include "PropVariantConversions.h"
static UString ConvertUInt64ToString(UInt64 value)
{
wchar_t buffer[32];
ConvertUInt64ToString(value, buffer);
return buffer;
}
static UString ConvertInt64ToString(Int64 value)
{
wchar_t buffer[32];
ConvertInt64ToString(value, buffer);
return buffer;
}
static char *UIntToStringSpec(char c, UInt32 value, char *s, int numPos)
{
if (c != 0)
*s++ = c;
char temp[16];
int pos = 0;
do
{
temp[pos++] = (char)('0' + value % 10);
value /= 10;
}
while (value != 0);
int i;
for (i = 0; i < numPos - pos; i++)
*s++ = '0';
do
*s++ = temp[--pos];
while (pos > 0);
*s = '\0';
return s;
}
bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime, bool includeSeconds)
{
s[0] = '\0';
SYSTEMTIME st;
if (!BOOLToBool(FileTimeToSystemTime(&ft, &st)))
return false;
s = UIntToStringSpec(0, st.wYear, s, 4);
s = UIntToStringSpec('-', st.wMonth, s, 2);
s = UIntToStringSpec('-', st.wDay, s, 2);
if (includeTime)
{
s = UIntToStringSpec(' ', st.wHour, s, 2);
s = UIntToStringSpec(':', st.wMinute, s, 2);
if (includeSeconds)
UIntToStringSpec(':', st.wSecond, s, 2);
}
return true;
}
UString ConvertFileTimeToString(const FILETIME &ft, bool includeTime, bool includeSeconds)
{
char s[32];
ConvertFileTimeToString(ft, s, includeTime, includeSeconds);
return GetUnicodeString(s);
}
UString ConvertPropVariantToString(const PROPVARIANT &prop)
{
switch (prop.vt)
{
case VT_EMPTY: return UString();
case VT_BSTR: return prop.bstrVal;
case VT_UI1: return ConvertUInt64ToString(prop.bVal);
case VT_UI2: return ConvertUInt64ToString(prop.uiVal);
case VT_UI4: return ConvertUInt64ToString(prop.ulVal);
case VT_UI8: return ConvertUInt64ToString(prop.uhVal.QuadPart);
case VT_FILETIME: return ConvertFileTimeToString(prop.filetime, true, true);
// case VT_I1: return ConvertInt64ToString(prop.cVal);
case VT_I2: return ConvertInt64ToString(prop.iVal);
case VT_I4: return ConvertInt64ToString(prop.lVal);
case VT_I8: return ConvertInt64ToString(prop.hVal.QuadPart);
case VT_BOOL: return VARIANT_BOOLToBool(prop.boolVal) ? L"+" : L"-";
default: throw 150245;
}
}
UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &prop)
{
switch (prop.vt)
{
case VT_UI1: return prop.bVal;
case VT_UI2: return prop.uiVal;
case VT_UI4: return prop.ulVal;
case VT_UI8: return (UInt64)prop.uhVal.QuadPart;
default: throw 151199;
}
}
-14
View File
@@ -1,14 +0,0 @@
// Windows/PropVariantConversions.h
#ifndef __PROP_VARIANT_CONVERSIONS_H
#define __PROP_VARIANT_CONVERSIONS_H
#include "Common/MyString.h"
#include "Common/Types.h"
bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime = true, bool includeSeconds = true);
UString ConvertFileTimeToString(const FILETIME &ft, bool includeTime = true, bool includeSeconds = true);
UString ConvertPropVariantToString(const PROPVARIANT &prop);
UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &prop);
#endif
Executable → Regular
+37 -13
View File
@@ -2,24 +2,21 @@
#include "StdAfx.h"
#include "../Common/IntToString.h"
#include "PropVariantUtils.h"
#include "Common/StringConvert.h"
#include "Common/IntToString.h"
using namespace NWindows;
static AString GetHex(UInt32 v)
{
char sz[32] = { '0', 'x' };
ConvertUInt64ToString(v, sz + 2, 16);
char sz[16];
sz[0] = '0';
sz[1] = 'x';
ConvertUInt32ToHex(v, sz + 2);
return sz;
}
void StringToProp(const AString &s, NCOM::CPropVariant &prop)
{
prop = MultiByteToUnicodeString(s);
}
AString TypePairToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 value)
{
AString s;
@@ -34,12 +31,12 @@ AString TypePairToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 val
return s;
}
void PairToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 value, NCOM::CPropVariant &prop)
{
StringToProp(TypePairToString(pairs, num, value), prop);
prop = TypePairToString(pairs, num, value);
}
AString TypeToString(const char *table[], unsigned num, UInt32 value)
{
if (value < num)
@@ -49,10 +46,37 @@ AString TypeToString(const char *table[], unsigned num, UInt32 value)
void TypeToProp(const char *table[], unsigned num, UInt32 value, NCOM::CPropVariant &prop)
{
StringToProp(TypeToString(table, num, value), prop);
prop = TypeToString(table, num, value);
}
AString FlagsToString(const char **names, unsigned num, UInt32 flags)
{
AString s;
for (unsigned i = 0; i < num; i++)
{
UInt32 flag = (UInt32)1 << i;
if ((flags & flag) != 0)
{
const char *name = names[i];
if (name != 0 && name[0] != 0)
{
if (!s.IsEmpty())
s += ' ';
s += name;
flags &= ~flag;
}
}
}
if (flags != 0)
{
if (!s.IsEmpty())
s += ' ';
s += GetHex(flags);
}
return s;
}
AString FlagsToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags)
{
AString s;
@@ -82,5 +106,5 @@ AString FlagsToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags)
void FlagsToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags, NCOM::CPropVariant &prop)
{
StringToProp(FlagsToString(pairs, num, flags), prop);
prop = FlagsToString(pairs, num, flags);
}
Executable → Regular
+6 -5
View File
@@ -3,7 +3,8 @@
#ifndef __PROP_VARIANT_UTILS_H
#define __PROP_VARIANT_UTILS_H
#include "Common/MyString.h"
#include "../Common/MyString.h"
#include "PropVariant.h"
struct CUInt32PCharPair
@@ -12,18 +13,18 @@ struct CUInt32PCharPair
const char *Name;
};
void StringToProp(const AString &s, NWindows::NCOM::CPropVariant &prop);
AString TypePairToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 value);
void PairToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 value, NWindows::NCOM::CPropVariant &prop);
AString FlagsToString(const char **names, unsigned num, UInt32 flags);
AString FlagsToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags);
void FlagsToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags, NWindows::NCOM::CPropVariant &prop);
AString TypeToString(const char *table[], unsigned num, UInt32 value);
void TypeToProp(const char *table[], unsigned num, UInt32 value, NWindows::NCOM::CPropVariant &prop);
#define PAIR_TO_PROP(pairs, value, prop) PairToProp(pairs, sizeof(pairs) / sizeof(pairs[0]), value, prop)
#define FLAGS_TO_PROP(pairs, value, prop) FlagsToProp(pairs, sizeof(pairs) / sizeof(pairs[0]), value, prop)
#define TYPE_TO_PROP(table, value, prop) TypeToProp(table, sizeof(table) / sizeof(table[0]), value, prop)
#define PAIR_TO_PROP(pairs, value, prop) PairToProp(pairs, ARRAY_SIZE(pairs), value, prop)
#define FLAGS_TO_PROP(pairs, value, prop) FlagsToProp(pairs, ARRAY_SIZE(pairs), value, prop)
#define TYPE_TO_PROP(table, value, prop) TypeToProp(table, ARRAY_SIZE(table), value, prop)
#endif
Executable → Regular
+16 -17
View File
@@ -3,9 +3,9 @@
#include "StdAfx.h"
#ifndef _UNICODE
#include "Common/StringConvert.h"
#include "../Common/StringConvert.h"
#endif
#include "Windows/Registry.h"
#include "Registry.h"
#ifndef _UNICODE
extern bool g_IsNT;
@@ -139,7 +139,7 @@ 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));
(const BYTE *)(const TCHAR *)value, (value.Len() + 1) * sizeof(TCHAR));
}
*/
@@ -193,8 +193,8 @@ LONG CKey::QueryValue(LPCTSTR name, UInt32 &value)
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)));
MYASSERT((res != ERROR_SUCCESS) || (type == REG_DWORD));
MYASSERT((res != ERROR_SUCCESS) || (count == sizeof(UInt32)));
return res;
}
@@ -229,7 +229,7 @@ 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));
MYASSERT((res != ERROR_SUCCESS) || (type == REG_SZ) || (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));
return res;
}
@@ -252,7 +252,7 @@ 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));
MYASSERT((res != ERROR_SUCCESS) || (type == REG_SZ) || (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));
return res;
}
LONG CKey::QueryValue(LPCWSTR name, UString &value)
@@ -284,7 +284,7 @@ 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));
MYASSERT((res != ERROR_SUCCESS) || (type == REG_BINARY));
return res;
}
@@ -296,7 +296,7 @@ LONG CKey::QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize)
LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, NULL, (DWORD *)&dataSize);
if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
return res;
value.SetCapacity(dataSize);
value.Alloc(dataSize);
return QueryValue(name, (BYTE *)value, dataSize);
}
@@ -324,17 +324,16 @@ LONG CKey::EnumKeys(CSysStringVector &keyNames)
LONG CKey::SetValue_Strings(LPCTSTR valueName, const UStringVector &strings)
{
UInt32 numChars = 0;
int i;
unsigned i;
for (i = 0; i < strings.Size(); i++)
numChars += strings[i].Length() + 1;
CBuffer<wchar_t> buffer;
buffer.SetCapacity(numChars);
int pos = 0;
numChars += strings[i].Len() + 1;
CBuffer<wchar_t> buffer(numChars);
unsigned pos = 0;
for (i = 0; i < strings.Size(); i++)
{
const UString &s = strings[i];
MyStringCopy((wchar_t *)buffer + pos, (const wchar_t *)s);
pos += s.Length() + 1;
pos += s.Len() + 1;
}
return SetValue(valueName, buffer, numChars * sizeof(wchar_t));
}
@@ -350,9 +349,9 @@ LONG CKey::GetValue_Strings(LPCTSTR valueName, UStringVector &strings)
if (dataSize % sizeof(wchar_t) != 0)
return E_FAIL;
const wchar_t *data = (const wchar_t *)(const Byte *)buffer;
int numChars = dataSize / sizeof(wchar_t);
unsigned numChars = dataSize / sizeof(wchar_t);
UString s;
for (int i = 0; i < numChars; i++)
for (unsigned i = 0; i < numChars; i++)
{
wchar_t c = data[i];
if (c == 0)
Executable → Regular
+20 -21
View File
@@ -3,9 +3,8 @@
#ifndef __WINDOWS_REGISTRY_H
#define __WINDOWS_REGISTRY_H
#include "Common/Buffer.h"
#include "Common/MyString.h"
#include "Common/Types.h"
#include "../Common/MyBuffer.h"
#include "../Common/MyString.h"
namespace NWindows {
namespace NRegistry {
@@ -32,49 +31,49 @@ public:
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);
LPDWORD disposition = NULL) throw();
LONG Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask = KEY_ALL_ACCESS) throw();
LONG Close();
LONG Close() throw();
LONG DeleteSubKey(LPCTSTR subKeyName);
LONG RecurseDeleteKey(LPCTSTR subKeyName);
LONG DeleteSubKey(LPCTSTR subKeyName) throw();
LONG RecurseDeleteKey(LPCTSTR subKeyName) throw();
LONG DeleteValue(LPCTSTR name);
LONG DeleteValue(LPCTSTR name) throw();
#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, UInt32 value) throw();
LONG SetValue(LPCTSTR valueName, bool value) throw();
LONG SetValue(LPCTSTR valueName, LPCTSTR value) throw();
// LONG SetValue(LPCTSTR valueName, const CSysString &value);
#ifndef _UNICODE
LONG SetValue(LPCWSTR name, LPCWSTR value);
// LONG SetValue(LPCWSTR name, const UString &value);
#endif
LONG SetValue(LPCTSTR name, const void *value, UInt32 size);
LONG SetValue(LPCTSTR name, const void *value, UInt32 size) throw();
LONG SetValue_Strings(LPCTSTR valueName, const UStringVector &strings);
LONG SetValue_Strings(LPCTSTR valueName, const UStringVector &strings) throw();
LONG GetValue_Strings(LPCTSTR valueName, UStringVector &strings);
LONG SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value);
LONG SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value) throw();
LONG QueryValue(LPCTSTR name, UInt32 &value);
LONG QueryValue(LPCTSTR name, bool &value);
LONG QueryValue(LPCTSTR name, LPTSTR value, UInt32 &dataSize);
LONG QueryValue(LPCTSTR name, UInt32 &value) throw();
LONG QueryValue(LPCTSTR name, bool &value) throw();
LONG QueryValue(LPCTSTR name, LPTSTR value, UInt32 &dataSize) throw();
LONG QueryValue(LPCTSTR name, CSysString &value);
LONG GetValue_IfOk(LPCTSTR name, UInt32 &value);
LONG GetValue_IfOk(LPCTSTR name, bool &value);
LONG GetValue_IfOk(LPCTSTR name, UInt32 &value) throw();
LONG GetValue_IfOk(LPCTSTR name, bool &value) throw();
#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, void *value, UInt32 &dataSize) throw();
LONG QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize);
LONG EnumKeys(CSysStringVector &keyNames);
Executable → Regular
+74 -35
View File
@@ -2,11 +2,12 @@
#include "StdAfx.h"
#include "Windows/ResourceString.h"
#ifndef _UNICODE
#include "Common/StringConvert.h"
#include "../Common/StringConvert.h"
#endif
#include "ResourceString.h"
extern HINSTANCE g_hInstance;
#ifndef _UNICODE
extern bool g_IsNT;
@@ -14,14 +15,16 @@ extern bool g_IsNT;
namespace NWindows {
CSysString MyLoadString(HINSTANCE hInstance, UINT resourceID)
#ifndef _UNICODE
static CSysString MyLoadStringA(HINSTANCE hInstance, UINT resourceID)
{
CSysString s;
int size = 256;
int size = 128;
int len;
do
{
size += 256;
size <<= 1;
len = ::LoadString(hInstance, resourceID, s.GetBuffer(size - 1), size);
}
while (size - len <= 1);
@@ -29,36 +32,72 @@ CSysString MyLoadString(HINSTANCE hInstance, UINT resourceID)
return s;
}
CSysString MyLoadString(UINT resourceID)
{
return MyLoadString(g_hInstance, resourceID);
}
#ifndef _UNICODE
UString MyLoadStringW(HINSTANCE hInstance, UINT resourceID)
{
if (g_IsNT)
{
UString s;
int size = 256;
int len;
do
{
size += 256;
len = ::LoadStringW(hInstance, resourceID, s.GetBuffer(size - 1), size);
}
while (size - len <= 1);
s.ReleaseBuffer();
return s;
}
return GetUnicodeString(MyLoadString(hInstance, resourceID));
}
UString MyLoadStringW(UINT resourceID)
{
return MyLoadStringW(g_hInstance, resourceID);
}
#endif
static const int kStartSize = 256;
static void MyLoadString2(HINSTANCE hInstance, UINT resourceID, UString &s)
{
int size = kStartSize;
int len;
do
{
size <<= 1;
len = ::LoadStringW(hInstance, resourceID, s.GetBuffer(size - 1), size);
}
while (size - len <= 1);
s.ReleaseBuffer();
}
// NT4 doesn't support LoadStringW(,,, 0) to get pointer to resource string. So we don't use it.
UString MyLoadString(UINT resourceID)
{
#ifndef _UNICODE
if (!g_IsNT)
return GetUnicodeString(MyLoadStringA(g_hInstance, resourceID));
else
#endif
{
{
wchar_t s[kStartSize];
s[0] = 0;
int len = ::LoadStringW(g_hInstance, resourceID, s, kStartSize);
if (kStartSize - len > 1)
return s;
}
UString dest;
MyLoadString2(g_hInstance, resourceID, dest);
return dest;
}
}
void MyLoadString(HINSTANCE hInstance, UINT resourceID, UString &dest)
{
dest.Empty();
#ifndef _UNICODE
if (!g_IsNT)
MultiByteToUnicodeString2(dest, MyLoadStringA(hInstance, resourceID));
else
#endif
{
{
wchar_t s[kStartSize];
s[0] = 0;
int len = ::LoadStringW(hInstance, resourceID, s, kStartSize);
if (kStartSize - len > 1)
{
dest = s;
return;
}
}
MyLoadString2(hInstance, resourceID, dest);
}
}
void MyLoadString(UINT resourceID, UString &dest)
{
MyLoadString(g_hInstance, resourceID, dest);
}
}
Executable → Regular
+6 -12
View File
@@ -1,21 +1,15 @@
// Windows/ResourceString.h
#ifndef __WINDOWS_RESOURCESTRING_H
#define __WINDOWS_RESOURCESTRING_H
#ifndef __WINDOWS_RESOURCE_STRING_H
#define __WINDOWS_RESOURCE_STRING_H
#include "Common/MyString.h"
#include "../Common/MyString.h"
namespace NWindows {
CSysString MyLoadString(HINSTANCE hInstance, UINT resourceID);
CSysString MyLoadString(UINT resourceID);
#ifdef _UNICODE
inline UString MyLoadStringW(HINSTANCE hInstance, UINT resourceID) { return MyLoadString(hInstance, resourceID); }
inline UString MyLoadStringW(UINT resourceID) { return MyLoadString(resourceID); }
#else
UString MyLoadStringW(HINSTANCE hInstance, UINT resourceID);
UString MyLoadStringW(UINT resourceID);
#endif
UString MyLoadString(UINT resourceID);
void MyLoadString(HINSTANCE hInstance, UINT resourceID, UString &dest);
void MyLoadString(UINT resourceID, UString &dest);
}
+2 -2
View File
@@ -1,8 +1,8 @@
// Windows/Security.cpp
// Windows/SecurityUtils.cpp
#include "StdAfx.h"
#include "Security.h"
#include "SecurityUtils.h"
namespace NWindows {
namespace NSecurity {
+3 -3
View File
@@ -1,7 +1,7 @@
// Windows/Security.h
// Windows/SecurityUtils.h
#ifndef __WINDOWS_SECURITY_H
#define __WINDOWS_SECURITY_H
#ifndef __WINDOWS_SECURITY_UTILS_H
#define __WINDOWS_SECURITY_UTILS_H
#include <NTSecAPI.h>
Executable → Regular
+8 -9
View File
@@ -2,13 +2,13 @@
#include "StdAfx.h"
#include "Common/MyCom.h"
#include "../Common/MyCom.h"
#ifndef _UNICODE
#include "Common/StringConvert.h"
#include "../Common/StringConvert.h"
#endif
#include "Windows/COM.h"
#include "Windows/Shell.h"
#include "COM.h"
#include "Shell.h"
#ifndef _UNICODE
extern bool g_IsNT;
@@ -111,11 +111,10 @@ UString CDrop::QueryFileName(UINT fileIndex)
void CDrop::QueryFileNames(UStringVector &fileNames)
{
fileNames.Clear();
UINT numFiles = QueryCountOfFiles();
fileNames.Reserve(numFiles);
fileNames.ClearAndReserve(numFiles);
for (UINT i = 0; i < numFiles; i++)
fileNames.Add(QueryFileName(i));
fileNames.AddInReserved(QueryFileName(i));
}
@@ -140,8 +139,8 @@ bool BrowseForFolder(HWND, LPCTSTR, UINT, LPCTSTR, CSysString &)
return false;
}
bool BrowseForFolder(HWND owner, LPCTSTR title,
LPCTSTR initialFolder, CSysString &resultPath)
bool BrowseForFolder(HWND /* owner */, LPCTSTR /* title */,
LPCTSTR /* initialFolder */, CSysString & /* resultPath */)
{
/*
// SHBrowseForFolder doesn't work before CE 6.0 ?
Executable → Regular
+3 -2
View File
@@ -6,8 +6,9 @@
#include <windows.h>
#include <shlobj.h>
#include "Common/MyString.h"
#include "Windows/Defs.h"
#include "../Common/MyString.h"
#include "Defs.h"
namespace NWindows{
namespace NShell{
Executable → Regular
+1 -2
View File
@@ -3,7 +3,6 @@
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../Common/MyWindows.h"
#include "../Common/NewHandler.h"
#include "../Common/Common.h"
#endif
Executable → Regular
View File
Executable → Regular
View File
Executable → Regular
View File
Executable → Regular
+1 -1
View File
@@ -3,7 +3,7 @@
#ifndef __WINDOWS_SYSTEM_H
#define __WINDOWS_SYSTEM_H
#include "../Common/Types.h"
#include "../Common/MyTypes.h"
namespace NWindows {
namespace NSystem {
Executable → Regular
View File
-23
View File
@@ -1,23 +0,0 @@
// Windows/Time.h
#ifndef __WINDOWS_TIME_H
#define __WINDOWS_TIME_H
#include "Common/Types.h"
namespace NWindows {
namespace NTime {
bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime);
bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime);
void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime);
bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &fileTime);
bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime);
Int64 FileTimeToUnixTime64(const FILETIME &ft);
bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds);
void GetCurUtcFileTime(FILETIME &ft);
}}
#endif
+10 -4
View File
@@ -1,10 +1,9 @@
// Windows/Time.cpp
// Windows/TimeUtils.cpp
#include "StdAfx.h"
#include "Windows/Defs.h"
#include "Time.h"
#include "Defs.h"
#include "TimeUtils.h"
namespace NWindows {
namespace NTime {
@@ -195,9 +194,16 @@ bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
void GetCurUtcFileTime(FILETIME &ft)
{
// Both variants provide same low resolution on WinXP: about 15 ms.
// But GetSystemTimeAsFileTime is much faster.
#ifdef UNDER_CE
SYSTEMTIME st;
GetSystemTime(&st);
SystemTimeToFileTime(&st, &ft);
#else
GetSystemTimeAsFileTime(&ft);
#endif
}
}}
+23
View File
@@ -0,0 +1,23 @@
// Windows/TimeUtils.h
#ifndef __WINDOWS_TIME_UTILS_H
#define __WINDOWS_TIME_UTILS_H
#include "../Common/MyTypes.h"
namespace NWindows {
namespace NTime {
bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime) throw();
bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime) throw();
void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime) throw();
bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &fileTime) throw();
bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime) throw();
Int64 FileTimeToUnixTime64(const FILETIME &ft) throw();
bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds) throw();
void GetCurUtcFileTime(FILETIME &ft) throw();
}}
#endif
Executable → Regular
+2 -2
View File
@@ -3,9 +3,9 @@
#include "StdAfx.h"
#ifndef _UNICODE
#include "Common/StringConvert.h"
#include "../Common/StringConvert.h"
#endif
#include "Windows/Window.h"
#include "Window.h"
#ifndef _UNICODE
extern bool g_IsNT;
Executable → Regular
+24 -2
View File
@@ -3,8 +3,27 @@
#ifndef __WINDOWS_WINDOW_H
#define __WINDOWS_WINDOW_H
#include "../Common/MyString.h"
#include "Defs.h"
#include "Common/MyString.h"
#ifndef UNDER_CE
#define MY__WM_CHANGEUISTATE 0x0127
#define MY__WM_UPDATEUISTATE 0x0128
#define MY__WM_QUERYUISTATE 0x0129
// LOWORD(wParam) values in WM_*UISTATE
#define MY__UIS_SET 1
#define MY__UIS_CLEAR 2
#define MY__UIS_INITIALIZE 3
// HIWORD(wParam) values in WM_*UISTATE
#define MY__UISF_HIDEFOCUS 0x1
#define MY__UISF_HIDEACCEL 0x2
#define MY__UISF_ACTIVE 0x4
#endif
namespace NWindows {
@@ -142,6 +161,8 @@ public:
bool GetClientRect(LPRECT rect) { return BOOLToBool(::GetClientRect(_window, rect)); }
bool Show(int cmdShow) { return BOOLToBool(::ShowWindow(_window, cmdShow)); }
bool Show_Bool(bool show) { return Show(show ? SW_SHOW: SW_HIDE); }
#ifndef UNDER_CE
bool SetPlacement(CONST WINDOWPLACEMENT *placement) { return BOOLToBool(::SetWindowPlacement(_window, placement)); }
bool GetPlacement(WINDOWPLACEMENT *placement) { return BOOLToBool(::GetWindowPlacement(_window, placement)); }
@@ -255,7 +276,8 @@ public:
#define RECT_SIZE_X(r) ((r).right - (r).left)
#define RECT_SIZE_Y(r) ((r).bottom - (r).top)
inline bool IsKeyDown(int virtKey) { return (::GetKeyState(virtKey) & 0x8000) != 0; }
}
#endif