mirror of
https://github.com/Xevion/easy7zip.git
synced 2026-01-31 02:24:11 -06:00
9.34
This commit is contained in:
committed by
Kornel Lesiński
parent
83f8ddcc5b
commit
f08f4dcc3c
Executable → Regular
Executable → Regular
+1
-2
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
Executable → Regular
+24
-24
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 {
|
||||
|
||||
Executable → Regular
Executable → Regular
+1
-1
@@ -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
@@ -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
@@ -3,7 +3,7 @@
|
||||
#ifndef __WINDOWS_CONTROL_LISTVIEW_H
|
||||
#define __WINDOWS_CONTROL_LISTVIEW_H
|
||||
|
||||
#include "Windows/Window.h"
|
||||
#include "../Window.h"
|
||||
|
||||
#include <commctrl.h>
|
||||
|
||||
|
||||
Executable → Regular
Executable → Regular
+3
-2
@@ -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));
|
||||
|
||||
Executable → Regular
Executable → Regular
+3
-4
@@ -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
Executable → Regular
+10
-11
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
Executable → Regular
+6
-5
@@ -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)));
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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();
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
@@ -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
Executable → Regular
+6
-2
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
Executable → Regular
+8
-8
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
Executable → Regular
Executable → Regular
+10
-14
@@ -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
@@ -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
Executable → Regular
Executable → Regular
Executable → Regular
+8
-3
@@ -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 ¶ms, LPCWSTR curDir)
|
||||
{
|
||||
Executable → Regular
+3
-3
@@ -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
@@ -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
@@ -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();
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
Executable → Regular
+2
-2
@@ -1,8 +1,8 @@
|
||||
// Windows/Security.cpp
|
||||
// Windows/SecurityUtils.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Security.h"
|
||||
#include "SecurityUtils.h"
|
||||
|
||||
namespace NWindows {
|
||||
namespace NSecurity {
|
||||
Executable → Regular
+3
-3
@@ -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
@@ -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
@@ -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
@@ -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
Executable → Regular
Executable → Regular
Executable → Regular
+1
-1
@@ -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
@@ -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
|
||||
Executable → Regular
+10
-4
@@ -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
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user