aboutsummaryrefslogtreecommitdiff
path: root/CPP/Windows
diff options
context:
space:
mode:
authorTetsuo Osaka <tetsugit@gmail.com>2016-10-18 15:12:28 +0200
committerTetsuo Osaka <tetsugit@gmail.com>2017-04-18 10:07:58 +0200
commitf955a79a9fffb09826cf7547f70d08c3798a2f50 (patch)
tree7ba3acdf7ba22cb749ffd9e6a868630e5a8382f2 /CPP/Windows
parent462f68aa279e25fda265a87c6d3c4da3318314f8 (diff)
downloadlzma-f955a79a9fffb09826cf7547f70d08c3798a2f50.tar.gz
Rebase LZMA SDK on 16.04 stable
This was downloaded from http://www.7-zip.org/a/lzma1604.7z The bin folder was excluded like in previous updates All files were deleted and replaced with those from the SDK. The embedded projects Tukaani, xz-embedded and android build files where not touched. The changelog since the 9.38 beta is: 16.04 2016-10-04 ------------------------- - The bug was fixed in DllSecur.c. 16.03 2016-09-28 ------------------------- - SFX modules now use some protection against DLL preloading attack. - Some bugs in 7z code were fixed. 16.02 2016-05-21 ------------------------- - The BUG in 16.00 - 16.01 was fixed: Split Handler (SplitHandler.cpp) returned incorrect total size value (kpidSize) for split archives. 16.01 2016-05-19 ------------------------- - Some internal changes to reduce the number of compiler warnings. 16.00 2016-05-10 ------------------------- - Some bugs were fixed. 15.12 2015-11-19 ------------------------- - The BUG in C version of 7z decoder was fixed: 7zDec.c : SzDecodeLzma2() 7z decoder could mistakenly report about decoding error for some 7z archives that use LZMA2 compression method. The probability to get that mistaken decoding error report was about one error per 16384 solid blocks for solid blocks larger than 16 KB (compressed size). - The BUG (in 9.26-15.11) in C version of 7z decoder was fixed: 7zArcIn.c : SzReadHeader2() 7z decoder worked incorrectly for 7z archives that contain empty solid blocks, that can be placed to 7z archive, if some file is unavailable for reading during archive creation. 15.09 beta 2015-10-16 ------------------------- - The BUG in LZMA / LZMA2 encoding code was fixed. The BUG in LzFind.c::MatchFinder_ReadBlock() function. If input data size is larger than (4 GiB - dictionary_size), the following code worked incorrectly: - LZMA : LzmaEnc_MemEncode(), LzmaEncode() : LZMA encoding functions for compressing from memory to memory. That BUG is not related to LZMA encoder version that works via streams. - LZMA2 : multi-threaded version of LZMA2 encoder worked incorrectly, if default value of chunk size (CLzma2EncProps::blockSize) is changed to value larger than (4 GiB - dictionary_size). Change-Id: I6b3974015c605fba3c0d4d897fab5a166174f441
Diffstat (limited to 'CPP/Windows')
-rw-r--r--CPP/Windows/COM.h4
-rw-r--r--CPP/Windows/CommonDialog.cpp2
-rw-r--r--CPP/Windows/Control/ComboBox.cpp22
-rw-r--r--CPP/Windows/Control/ComboBox.h38
-rw-r--r--CPP/Windows/Control/CommandBar.h12
-rw-r--r--CPP/Windows/Control/Dialog.h4
-rw-r--r--CPP/Windows/Control/Edit.h2
-rw-r--r--CPP/Windows/Control/ListView.h22
-rw-r--r--CPP/Windows/Control/ProgressBar.h24
-rw-r--r--CPP/Windows/Control/PropertyPage.h2
-rw-r--r--CPP/Windows/Control/ReBar.h16
-rw-r--r--CPP/Windows/Control/Static.h8
-rw-r--r--CPP/Windows/Control/StatusBar.h8
-rw-r--r--CPP/Windows/Control/ToolBar.h16
-rw-r--r--CPP/Windows/Control/Trackbar.h11
-rw-r--r--CPP/Windows/Control/Window2.cpp2
-rw-r--r--CPP/Windows/Control/Window2.h2
-rw-r--r--CPP/Windows/DLL.cpp2
-rw-r--r--CPP/Windows/DLL.h10
-rw-r--r--CPP/Windows/ErrorMsg.cpp19
-rw-r--r--CPP/Windows/FileDir.cpp201
-rw-r--r--CPP/Windows/FileDir.h7
-rw-r--r--CPP/Windows/FileFind.cpp342
-rw-r--r--CPP/Windows/FileFind.h11
-rw-r--r--CPP/Windows/FileIO.cpp2
-rw-r--r--CPP/Windows/FileIO.h2
-rw-r--r--CPP/Windows/FileLink.cpp22
-rw-r--r--CPP/Windows/FileName.cpp318
-rw-r--r--CPP/Windows/FileName.h51
-rw-r--r--CPP/Windows/MemoryLock.cpp2
-rw-r--r--CPP/Windows/MemoryLock.h4
-rw-r--r--CPP/Windows/NtCheck.h2
-rw-r--r--CPP/Windows/PropVariant.cpp89
-rw-r--r--CPP/Windows/PropVariant.h7
-rw-r--r--CPP/Windows/PropVariantConv.cpp12
-rw-r--r--CPP/Windows/Registry.cpp90
-rw-r--r--CPP/Windows/Registry.h2
-rw-r--r--CPP/Windows/ResourceString.cpp8
-rw-r--r--CPP/Windows/SecurityUtils.cpp16
-rw-r--r--CPP/Windows/Shell.cpp36
-rw-r--r--CPP/Windows/System.cpp74
-rw-r--r--CPP/Windows/System.h3
-rw-r--r--CPP/Windows/TimeUtils.h1
-rw-r--r--CPP/Windows/Window.cpp34
-rw-r--r--CPP/Windows/Window.h21
45 files changed, 1135 insertions, 448 deletions
diff --git a/CPP/Windows/COM.h b/CPP/Windows/COM.h
index 8aa6d28..e2cb002 100644
--- a/CPP/Windows/COM.h
+++ b/CPP/Windows/COM.h
@@ -22,7 +22,7 @@ public:
CoInitialize(NULL);
#endif
};
- ~CComInitializer() { CoUninitialize(); };
+ ~CComInitializer() { CoUninitialize(); }
};
class CStgMedium
@@ -45,6 +45,7 @@ public:
#endif
+/*
//////////////////////////////////
// GUID <--> String Conversions
UString GUIDToStringW(REFGUID guid);
@@ -62,6 +63,7 @@ HRESULT StringToGUIDA(const char *string, GUID &classID);
#else
#define StringToGUID StringToGUIDA
#endif
+*/
}}
diff --git a/CPP/Windows/CommonDialog.cpp b/CPP/Windows/CommonDialog.cpp
index 60b5b26..8b3828c 100644
--- a/CPP/Windows/CommonDialog.cpp
+++ b/CPP/Windows/CommonDialog.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include "../Common/MyWindows.h"
+
#ifdef UNDER_CE
#include <commdlg.h>
#endif
diff --git a/CPP/Windows/Control/ComboBox.cpp b/CPP/Windows/Control/ComboBox.cpp
index ca102f3..6ab4717 100644
--- a/CPP/Windows/Control/ComboBox.cpp
+++ b/CPP/Windows/Control/ComboBox.cpp
@@ -18,11 +18,15 @@ namespace NControl {
LRESULT CComboBox::GetLBText(int index, CSysString &s)
{
s.Empty();
- LRESULT len = GetLBTextLen(index);
+ LRESULT len = GetLBTextLen(index); // length, excluding the terminating null character
if (len == CB_ERR)
return len;
- len = GetLBText(index, s.GetBuffer((int)len + 1));
- s.ReleaseBuffer();
+ LRESULT len2 = GetLBText(index, s.GetBuf((unsigned)len));
+ if (len2 == CB_ERR)
+ return len;
+ if (len > len2)
+ len = len2;
+ s.ReleaseBuf_CalcLen((unsigned)len);
return len;
}
@@ -30,7 +34,7 @@ LRESULT CComboBox::GetLBText(int index, CSysString &s)
LRESULT CComboBox::AddString(LPCWSTR s)
{
if (g_IsNT)
- return SendMessageW(CB_ADDSTRING, 0, (LPARAM)s);
+ return SendMsgW(CB_ADDSTRING, 0, (LPARAM)s);
return AddString(GetSystemString(s));
}
@@ -39,11 +43,15 @@ LRESULT CComboBox::GetLBText(int index, UString &s)
s.Empty();
if (g_IsNT)
{
- LRESULT len = SendMessageW(CB_GETLBTEXTLEN, index, 0);
+ LRESULT len = SendMsgW(CB_GETLBTEXTLEN, index, 0);
if (len == CB_ERR)
return len;
- len = SendMessageW(CB_GETLBTEXT, index, (LPARAM)s.GetBuffer((int)len + 1));
- s.ReleaseBuffer();
+ LRESULT len2 = SendMsgW(CB_GETLBTEXT, index, (LPARAM)s.GetBuf((unsigned)len));
+ if (len2 == CB_ERR)
+ return len;
+ if (len > len2)
+ len = len2;
+ s.ReleaseBuf_CalcLen((unsigned)len);
return len;
}
AString sa;
diff --git a/CPP/Windows/Control/ComboBox.h b/CPP/Windows/Control/ComboBox.h
index 25e1730..3439655 100644
--- a/CPP/Windows/Control/ComboBox.h
+++ b/CPP/Windows/Control/ComboBox.h
@@ -3,6 +3,8 @@
#ifndef __WINDOWS_CONTROL_COMBOBOX_H
#define __WINDOWS_CONTROL_COMBOBOX_H
+#include "../../Common/MyWindows.h"
+
#include <commctrl.h>
#include "../Window.h"
@@ -13,28 +15,28 @@ namespace NControl {
class CComboBox: public CWindow
{
public:
- void ResetContent() { SendMessage(CB_RESETCONTENT, 0, 0); }
- LRESULT AddString(LPCTSTR s) { return SendMessage(CB_ADDSTRING, 0, (LPARAM)s); }
+ void ResetContent() { SendMsg(CB_RESETCONTENT, 0, 0); }
+ LRESULT AddString(LPCTSTR s) { return SendMsg(CB_ADDSTRING, 0, (LPARAM)s); }
#ifndef _UNICODE
LRESULT AddString(LPCWSTR s);
#endif
- LRESULT SetCurSel(int index) { return SendMessage(CB_SETCURSEL, index, 0); }
- int GetCurSel() { return (int)SendMessage(CB_GETCURSEL, 0, 0); }
- int GetCount() { return (int)SendMessage(CB_GETCOUNT, 0, 0); }
+ LRESULT SetCurSel(int index) { return SendMsg(CB_SETCURSEL, index, 0); }
+ int GetCurSel() { return (int)SendMsg(CB_GETCURSEL, 0, 0); }
+ int GetCount() { return (int)SendMsg(CB_GETCOUNT, 0, 0); }
- LRESULT GetLBTextLen(int index) { return SendMessage(CB_GETLBTEXTLEN, index, 0); }
- LRESULT GetLBText(int index, LPTSTR s) { return SendMessage(CB_GETLBTEXT, index, (LPARAM)s); }
+ LRESULT GetLBTextLen(int index) { return SendMsg(CB_GETLBTEXTLEN, index, 0); }
+ LRESULT GetLBText(int index, LPTSTR s) { return SendMsg(CB_GETLBTEXT, index, (LPARAM)s); }
LRESULT GetLBText(int index, CSysString &s);
#ifndef _UNICODE
LRESULT GetLBText(int index, UString &s);
#endif
- LRESULT SetItemData(int index, LPARAM lParam) { return SendMessage(CB_SETITEMDATA, index, lParam); }
- LRESULT GetItemData(int index) { return SendMessage(CB_GETITEMDATA, index, 0); }
+ LRESULT SetItemData(int index, LPARAM lParam) { return SendMsg(CB_SETITEMDATA, index, lParam); }
+ LRESULT GetItemData(int index) { return SendMsg(CB_GETITEMDATA, index, 0); }
LRESULT GetItemData_of_CurSel() { return GetItemData(GetCurSel()); }
- void ShowDropDown(bool show = true) { SendMessage(CB_SHOWDROPDOWN, show ? TRUE : FALSE, 0); }
+ void ShowDropDown(bool show = true) { SendMsg(CB_SHOWDROPDOWN, show ? TRUE : FALSE, 0); }
};
#ifndef UNDER_CE
@@ -42,18 +44,18 @@ public:
class CComboBoxEx: public CComboBox
{
public:
- bool SetUnicodeFormat(bool fUnicode) { return LRESULTToBool(SendMessage(CBEM_SETUNICODEFORMAT, BOOLToBool(fUnicode), 0)); }
+ bool SetUnicodeFormat(bool fUnicode) { return LRESULTToBool(SendMsg(CBEM_SETUNICODEFORMAT, BOOLToBool(fUnicode), 0)); }
- LRESULT DeleteItem(int index) { return SendMessage(CBEM_DELETEITEM, index, 0); }
- LRESULT InsertItem(COMBOBOXEXITEM *item) { return SendMessage(CBEM_INSERTITEM, 0, (LPARAM)item); }
+ LRESULT DeleteItem(int index) { return SendMsg(CBEM_DELETEITEM, index, 0); }
+ LRESULT InsertItem(COMBOBOXEXITEM *item) { return SendMsg(CBEM_INSERTITEM, 0, (LPARAM)item); }
#ifndef _UNICODE
- LRESULT InsertItem(COMBOBOXEXITEMW *item) { return SendMessage(CBEM_INSERTITEMW, 0, (LPARAM)item); }
+ LRESULT InsertItem(COMBOBOXEXITEMW *item) { return SendMsg(CBEM_INSERTITEMW, 0, (LPARAM)item); }
#endif
- LRESULT SetItem(COMBOBOXEXITEM *item) { return SendMessage(CBEM_SETITEM, 0, (LPARAM)item); }
- DWORD SetExtendedStyle(DWORD exMask, DWORD exStyle) { return (DWORD)SendMessage(CBEM_SETEXTENDEDSTYLE, exMask, exStyle); }
- HWND GetEditControl() { return (HWND)SendMessage(CBEM_GETEDITCONTROL, 0, 0); }
- HIMAGELIST SetImageList(HIMAGELIST imageList) { return (HIMAGELIST)SendMessage(CBEM_SETIMAGELIST, 0, (LPARAM)imageList); }
+ LRESULT SetItem(COMBOBOXEXITEM *item) { return SendMsg(CBEM_SETITEM, 0, (LPARAM)item); }
+ DWORD SetExtendedStyle(DWORD exMask, DWORD exStyle) { return (DWORD)SendMsg(CBEM_SETEXTENDEDSTYLE, exMask, exStyle); }
+ HWND GetEditControl() { return (HWND)SendMsg(CBEM_GETEDITCONTROL, 0, 0); }
+ HIMAGELIST SetImageList(HIMAGELIST imageList) { return (HIMAGELIST)SendMsg(CBEM_SETIMAGELIST, 0, (LPARAM)imageList); }
};
#endif
diff --git a/CPP/Windows/Control/CommandBar.h b/CPP/Windows/Control/CommandBar.h
index 00c5df7..c435568 100644
--- a/CPP/Windows/Control/CommandBar.h
+++ b/CPP/Windows/Control/CommandBar.h
@@ -5,6 +5,10 @@
#ifdef UNDER_CE
+#include "../../Common/MyWindows.h"
+
+#include <commctrl.h>
+
#include "../Window.h"
namespace NWindows {
@@ -21,10 +25,10 @@ public:
// Macros
// void Destroy() { CommandBar_Destroy(_window); }
- // 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); }
+ // bool AddButtons(UINT numButtons, LPTBBUTTON buttons) { return BOOLToBool(SendMsg(TB_ADDBUTTONS, (WPARAM)numButtons, (LPARAM)buttons)); }
+ bool InsertButton(int iButton, LPTBBUTTON button) { return BOOLToBool(SendMsg(TB_INSERTBUTTON, (WPARAM)iButton, (LPARAM)button)); }
+ BOOL AddToolTips(UINT numToolTips, LPTSTR toolTips) { return BOOLToBool(SendMsg(TB_SETTOOLTIPS, (WPARAM)numToolTips, (LPARAM)toolTips)); }
+ void AutoSize() { SendMsg(TB_AUTOSIZE, 0, 0); }
bool AddAdornments(DWORD dwFlags) { return BOOLToBool(::CommandBar_AddAdornments(_window, dwFlags, 0)); }
int AddBitmap(HINSTANCE hInst, int idBitmap, int iNumImages, int iImageWidth, int iImageHeight) { return ::CommandBar_AddBitmap(_window, hInst, idBitmap, iNumImages, iImageWidth, iImageHeight); }
diff --git a/CPP/Windows/Control/Dialog.h b/CPP/Windows/Control/Dialog.h
index 66530e5..b160958 100644
--- a/CPP/Windows/Control/Dialog.h
+++ b/CPP/Windows/Control/Dialog.h
@@ -95,9 +95,9 @@ public:
/*
#ifdef UNDER_CE
- virtual void OnHelp(void *) { OnHelp(); };
+ virtual void OnHelp(void *) { OnHelp(); }
#else
- virtual void OnHelp(LPHELPINFO) { OnHelp(); };
+ virtual void OnHelp(LPHELPINFO) { OnHelp(); }
#endif
*/
virtual void OnHelp() {};
diff --git a/CPP/Windows/Control/Edit.h b/CPP/Windows/Control/Edit.h
index 40e3899..4f503aa 100644
--- a/CPP/Windows/Control/Edit.h
+++ b/CPP/Windows/Control/Edit.h
@@ -11,7 +11,7 @@ namespace NControl {
class CEdit: public CWindow
{
public:
- void SetPasswordChar(WPARAM c) { SendMessage(EM_SETPASSWORDCHAR, c); }
+ void SetPasswordChar(WPARAM c) { SendMsg(EM_SETPASSWORDCHAR, c); }
};
}}
diff --git a/CPP/Windows/Control/ListView.h b/CPP/Windows/Control/ListView.h
index 6897c81..1ed496d 100644
--- a/CPP/Windows/Control/ListView.h
+++ b/CPP/Windows/Control/ListView.h
@@ -3,10 +3,12 @@
#ifndef __WINDOWS_CONTROL_LISTVIEW_H
#define __WINDOWS_CONTROL_LISTVIEW_H
-#include "../Window.h"
+#include "../../Common/MyWindows.h"
#include <commctrl.h>
+#include "../Window.h"
+
namespace NWindows {
namespace NControl {
@@ -30,6 +32,18 @@ public:
int InsertColumn(int columnIndex, const LVCOLUMN *columnInfo) { return ListView_InsertColumn(_window, columnIndex, columnInfo); }
int InsertColumn(int columnIndex, LPCTSTR text, int width);
+ bool SetColumnOrderArray(int count, const int *columns) { return BOOLToBool(ListView_SetColumnOrderArray(_window, count, columns)); }
+
+ /*
+ int GetNumColumns()
+ {
+ HWND header = ListView_GetHeader(_window);
+ if (!header)
+ return -1;
+ return Header_GetItemCount(header);
+ }
+ */
+
int InsertItem(const LVITEM* item) { return ListView_InsertItem(_window, item); }
int InsertItem(int index, LPCTSTR text);
bool SetItem(const LVITEM* item) { return BOOLToBool(ListView_SetItem(_window, item)); }
@@ -37,11 +51,11 @@ public:
#ifndef _UNICODE
- int InsertColumn(int columnIndex, const LVCOLUMNW *columnInfo) { return (int)SendMessage(LVM_INSERTCOLUMNW, (WPARAM)columnIndex, (LPARAM)columnInfo); }
+ int InsertColumn(int columnIndex, const LVCOLUMNW *columnInfo) { return (int)SendMsg(LVM_INSERTCOLUMNW, (WPARAM)columnIndex, (LPARAM)columnInfo); }
int InsertColumn(int columnIndex, LPCWSTR text, int width);
- int InsertItem(const LV_ITEMW* item) { return (int)SendMessage(LVM_INSERTITEMW, 0, (LPARAM)item); }
+ int InsertItem(const LV_ITEMW* item) { return (int)SendMsg(LVM_INSERTITEMW, 0, (LPARAM)item); }
int InsertItem(int index, LPCWSTR text);
- bool SetItem(const LV_ITEMW* item) { return BOOLToBool((BOOL)SendMessage(LVM_SETITEMW, 0, (LPARAM)item)); }
+ bool SetItem(const LV_ITEMW* item) { return BOOLToBool((BOOL)SendMsg(LVM_SETITEMW, 0, (LPARAM)item)); }
int SetSubItem(int index, int subIndex, LPCWSTR text);
#endif
diff --git a/CPP/Windows/Control/ProgressBar.h b/CPP/Windows/Control/ProgressBar.h
index 71dc912..f18d89c 100644
--- a/CPP/Windows/Control/ProgressBar.h
+++ b/CPP/Windows/Control/ProgressBar.h
@@ -3,6 +3,10 @@
#ifndef __WINDOWS_CONTROL_PROGRESSBAR_H
#define __WINDOWS_CONTROL_PROGRESSBAR_H
+#include "../../Common/MyWindows.h"
+
+#include <commctrl.h>
+
#include "../Window.h"
namespace NWindows {
@@ -11,18 +15,18 @@ namespace NControl {
class CProgressBar: public CWindow
{
public:
- LRESULT SetPos(int pos) { return SendMessage(PBM_SETPOS, pos, 0); }
- LRESULT DeltaPos(int increment) { return SendMessage(PBM_DELTAPOS, increment, 0); }
- UINT GetPos() { return (UINT)SendMessage(PBM_GETPOS, 0, 0); }
- LRESULT SetRange(unsigned short minValue, unsigned short maxValue) { return SendMessage(PBM_SETRANGE, 0, MAKELPARAM(minValue, maxValue)); }
- DWORD SetRange32(int minValue, int maxValue) { return (DWORD)SendMessage(PBM_SETRANGE32, minValue, maxValue); }
- int SetStep(int step) { return (int)SendMessage(PBM_SETSTEP, step, 0); }
- LRESULT StepIt() { return SendMessage(PBM_STEPIT, 0, 0); }
- INT GetRange(bool minValue, PPBRANGE range) { return (INT)SendMessage(PBM_GETRANGE, BoolToBOOL(minValue), (LPARAM)range); }
+ LRESULT SetPos(int pos) { return SendMsg(PBM_SETPOS, pos, 0); }
+ LRESULT DeltaPos(int increment) { return SendMsg(PBM_DELTAPOS, increment, 0); }
+ UINT GetPos() { return (UINT)SendMsg(PBM_GETPOS, 0, 0); }
+ LRESULT SetRange(unsigned short minValue, unsigned short maxValue) { return SendMsg(PBM_SETRANGE, 0, MAKELPARAM(minValue, maxValue)); }
+ DWORD SetRange32(int minValue, int maxValue) { return (DWORD)SendMsg(PBM_SETRANGE32, minValue, maxValue); }
+ int SetStep(int step) { return (int)SendMsg(PBM_SETSTEP, step, 0); }
+ LRESULT StepIt() { return SendMsg(PBM_STEPIT, 0, 0); }
+ INT GetRange(bool minValue, PPBRANGE range) { return (INT)SendMsg(PBM_GETRANGE, BoolToBOOL(minValue), (LPARAM)range); }
#ifndef UNDER_CE
- COLORREF SetBarColor(COLORREF color) { return (COLORREF)SendMessage(PBM_SETBARCOLOR, 0, color); }
- COLORREF SetBackgroundColor(COLORREF color) { return (COLORREF)SendMessage(PBM_SETBKCOLOR, 0, color); }
+ COLORREF SetBarColor(COLORREF color) { return (COLORREF)SendMsg(PBM_SETBARCOLOR, 0, color); }
+ COLORREF SetBackgroundColor(COLORREF color) { return (COLORREF)SendMsg(PBM_SETBKCOLOR, 0, color); }
#endif
};
diff --git a/CPP/Windows/Control/PropertyPage.h b/CPP/Windows/Control/PropertyPage.h
index 053de09..551c959 100644
--- a/CPP/Windows/Control/PropertyPage.h
+++ b/CPP/Windows/Control/PropertyPage.h
@@ -3,6 +3,8 @@
#ifndef __WINDOWS_CONTROL_PROPERTYPAGE_H
#define __WINDOWS_CONTROL_PROPERTYPAGE_H
+#include "../../Common/MyWindows.h"
+
#include <prsht.h>
#include "Dialog.h"
diff --git a/CPP/Windows/Control/ReBar.h b/CPP/Windows/Control/ReBar.h
index cf47bf4..26fa311 100644
--- a/CPP/Windows/Control/ReBar.h
+++ b/CPP/Windows/Control/ReBar.h
@@ -12,21 +12,21 @@ class CReBar: public NWindows::CWindow
{
public:
bool SetBarInfo(LPREBARINFO barInfo)
- { return LRESULTToBool(SendMessage(RB_SETBARINFO, 0, (LPARAM)barInfo)); }
+ { return LRESULTToBool(SendMsg(RB_SETBARINFO, 0, (LPARAM)barInfo)); }
bool InsertBand(int index, LPREBARBANDINFO bandInfo)
- { return LRESULTToBool(SendMessage(RB_INSERTBAND, index, (LPARAM)bandInfo)); }
+ { return LRESULTToBool(SendMsg(RB_INSERTBAND, index, (LPARAM)bandInfo)); }
bool SetBandInfo(unsigned index, LPREBARBANDINFO bandInfo)
- { return LRESULTToBool(SendMessage(RB_SETBANDINFO, index, (LPARAM)bandInfo)); }
+ { return LRESULTToBool(SendMsg(RB_SETBANDINFO, index, (LPARAM)bandInfo)); }
void MaximizeBand(unsigned index, bool ideal)
- { SendMessage(RB_MAXIMIZEBAND, index, BoolToBOOL(ideal)); }
+ { SendMsg(RB_MAXIMIZEBAND, index, BoolToBOOL(ideal)); }
bool SizeToRect(LPRECT rect)
- { return LRESULTToBool(SendMessage(RB_SIZETORECT, 0, (LPARAM)rect)); }
+ { return LRESULTToBool(SendMsg(RB_SIZETORECT, 0, (LPARAM)rect)); }
UINT GetHeight()
- { return (UINT)SendMessage(RB_GETBARHEIGHT); }
+ { return (UINT)SendMsg(RB_GETBARHEIGHT); }
UINT GetBandCount()
- { return (UINT)SendMessage(RB_GETBANDCOUNT); }
+ { return (UINT)SendMsg(RB_GETBANDCOUNT); }
bool DeleteBand(UINT index)
- { return LRESULTToBool(SendMessage(RB_DELETEBAND, index)); }
+ { return LRESULTToBool(SendMsg(RB_DELETEBAND, index)); }
};
}}
diff --git a/CPP/Windows/Control/Static.h b/CPP/Windows/Control/Static.h
index 355b9e8..936dd3c 100644
--- a/CPP/Windows/Control/Static.h
+++ b/CPP/Windows/Control/Static.h
@@ -11,15 +11,15 @@ namespace NControl {
class CStatic: public CWindow
{
public:
- HANDLE SetImage(WPARAM imageType, HANDLE handle) { return (HANDLE)SendMessage(STM_SETIMAGE, imageType, (LPARAM)handle); }
- HANDLE GetImage(WPARAM imageType) { return (HANDLE)SendMessage(STM_GETIMAGE, imageType, 0); }
+ HANDLE SetImage(WPARAM imageType, HANDLE handle) { return (HANDLE)SendMsg(STM_SETIMAGE, imageType, (LPARAM)handle); }
+ HANDLE GetImage(WPARAM imageType) { return (HANDLE)SendMsg(STM_GETIMAGE, imageType, 0); }
#ifdef UNDER_CE
HICON SetIcon(HICON icon) { return (HICON)SetImage(IMAGE_ICON, icon); }
HICON GetIcon() { return (HICON)GetImage(IMAGE_ICON); }
#else
- HICON SetIcon(HICON icon) { return (HICON)SendMessage(STM_SETICON, (WPARAM)icon, 0); }
- HICON GetIcon() { return (HICON)SendMessage(STM_GETICON, 0, 0); }
+ HICON SetIcon(HICON icon) { return (HICON)SendMsg(STM_SETICON, (WPARAM)icon, 0); }
+ HICON GetIcon() { return (HICON)SendMsg(STM_GETICON, 0, 0); }
#endif
};
diff --git a/CPP/Windows/Control/StatusBar.h b/CPP/Windows/Control/StatusBar.h
index 9185c42..7f7d66b 100644
--- a/CPP/Windows/Control/StatusBar.h
+++ b/CPP/Windows/Control/StatusBar.h
@@ -16,7 +16,7 @@ public:
bool SetText(LPCTSTR text)
{ return CWindow::SetText(text); }
bool SetText(unsigned index, LPCTSTR text, UINT type)
- { return LRESULTToBool(SendMessage(SB_SETTEXT, index | type, (LPARAM)text)); }
+ { return LRESULTToBool(SendMsg(SB_SETTEXT, index | type, (LPARAM)text)); }
bool SetText(unsigned index, LPCTSTR text)
{ return SetText(index, text, 0); }
@@ -26,15 +26,15 @@ public:
bool SetText(LPCWSTR text)
{ return CWindow::SetText(text); }
bool SetText(unsigned index, LPCWSTR text, UINT type)
- { return LRESULTToBool(SendMessage(SB_SETTEXTW, index | type, (LPARAM)text)); }
+ { return LRESULTToBool(SendMsg(SB_SETTEXTW, index | type, (LPARAM)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)); }
+ { return LRESULTToBool(SendMsg(SB_SETPARTS, numParts, (LPARAM)edgePostions)); }
void Simple(bool simple)
- { SendMessage(SB_SIMPLE, BoolToBOOL(simple), 0); }
+ { SendMsg(SB_SIMPLE, BoolToBOOL(simple), 0); }
};
}}
diff --git a/CPP/Windows/Control/ToolBar.h b/CPP/Windows/Control/ToolBar.h
index 6bc4443..02ed9a1 100644
--- a/CPP/Windows/Control/ToolBar.h
+++ b/CPP/Windows/Control/ToolBar.h
@@ -11,8 +11,8 @@ namespace NControl {
class CToolBar: public NWindows::CWindow
{
public:
- void AutoSize() { SendMessage(TB_AUTOSIZE, 0, 0); }
- DWORD GetButtonSize() { return (DWORD)SendMessage(TB_GETBUTTONSIZE, 0, 0); }
+ void AutoSize() { SendMsg(TB_AUTOSIZE, 0, 0); }
+ DWORD GetButtonSize() { return (DWORD)SendMsg(TB_GETBUTTONSIZE, 0, 0); }
bool GetMaxSize(LPSIZE size)
#ifdef UNDER_CE
@@ -25,16 +25,16 @@ public:
}
#else
{
- return LRESULTToBool(SendMessage(TB_GETMAXSIZE, 0, (LPARAM)size));
+ return LRESULTToBool(SendMsg(TB_GETMAXSIZE, 0, (LPARAM)size));
}
#endif
- bool EnableButton(UINT buttonID, bool enable) { return LRESULTToBool(SendMessage(TB_ENABLEBUTTON, buttonID, MAKELONG(BoolToBOOL(enable), 0))); }
- void ButtonStructSize() { SendMessage(TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON)); }
- HIMAGELIST SetImageList(UINT listIndex, HIMAGELIST imageList) { return HIMAGELIST(SendMessage(TB_SETIMAGELIST, listIndex, (LPARAM)imageList)); }
- bool AddButton(UINT numButtons, LPTBBUTTON buttons) { return LRESULTToBool(SendMessage(TB_ADDBUTTONS, numButtons, (LPARAM)buttons)); }
+ bool EnableButton(UINT buttonID, bool enable) { return LRESULTToBool(SendMsg(TB_ENABLEBUTTON, buttonID, MAKELONG(BoolToBOOL(enable), 0))); }
+ void ButtonStructSize() { SendMsg(TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON)); }
+ HIMAGELIST SetImageList(UINT listIndex, HIMAGELIST imageList) { return HIMAGELIST(SendMsg(TB_SETIMAGELIST, listIndex, (LPARAM)imageList)); }
+ bool AddButton(UINT numButtons, LPTBBUTTON buttons) { return LRESULTToBool(SendMsg(TB_ADDBUTTONS, numButtons, (LPARAM)buttons)); }
#ifndef _UNICODE
- bool AddButtonW(UINT numButtons, LPTBBUTTON buttons) { return LRESULTToBool(SendMessage(TB_ADDBUTTONSW, numButtons, (LPARAM)buttons)); }
+ bool AddButtonW(UINT numButtons, LPTBBUTTON buttons) { return LRESULTToBool(SendMsg(TB_ADDBUTTONSW, numButtons, (LPARAM)buttons)); }
#endif
};
diff --git a/CPP/Windows/Control/Trackbar.h b/CPP/Windows/Control/Trackbar.h
index da1936b..afc9bf2 100644
--- a/CPP/Windows/Control/Trackbar.h
+++ b/CPP/Windows/Control/Trackbar.h
@@ -4,23 +4,22 @@
#define __WINDOWS_CONTROL_TRACKBAR_H
#include "../Window.h"
-#include "../Defs.h"
namespace NWindows {
namespace NControl {
-class CTrackbar1: public CWindow
+class CTrackbar: public CWindow
{
public:
void SetRange(int minimum, int maximum, bool redraw = true)
- { SendMessage(TBM_SETRANGE, BoolToBOOL(redraw), MAKELONG(minimum, maximum)); }
+ { SendMsg(TBM_SETRANGE, BoolToBOOL(redraw), MAKELONG(minimum, maximum)); }
void SetPos(int pos, bool redraw = true)
- { SendMessage(TBM_SETPOS, BoolToBOOL(redraw), pos); }
+ { SendMsg(TBM_SETPOS, BoolToBOOL(redraw), pos); }
void SetTicFreq(int freq)
- { SendMessage(TBM_SETTICFREQ, freq); }
+ { SendMsg(TBM_SETTICFREQ, freq); }
int GetPos()
- { return (int)SendMessage(TBM_GETPOS); }
+ { return (int)SendMsg(TBM_GETPOS); }
};
}}
diff --git a/CPP/Windows/Control/Window2.cpp b/CPP/Windows/Control/Window2.cpp
index 2588c3a..b6e6d67 100644
--- a/CPP/Windows/Control/Window2.cpp
+++ b/CPP/Windows/Control/Window2.cpp
@@ -178,7 +178,7 @@ bool CWindow2::OnCommand(int /* code */, int /* itemID */, LPARAM /* lParam */,
/*
bool CDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
{
- switch(aButtonID)
+ switch (buttonID)
{
case IDOK:
OnOK();
diff --git a/CPP/Windows/Control/Window2.h b/CPP/Windows/Control/Window2.h
index f565daa..d632b86 100644
--- a/CPP/Windows/Control/Window2.h
+++ b/CPP/Windows/Control/Window2.h
@@ -35,7 +35,7 @@ public:
virtual void OnDestroy() { PostQuitMessage(0); }
virtual void OnClose() { Destroy(); }
/*
- virtual LRESULT OnHelp(LPHELPINFO helpInfo) { OnHelp(); };
+ virtual LRESULT OnHelp(LPHELPINFO helpInfo) { OnHelp(); }
virtual LRESULT OnHelp() {};
virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
virtual void OnOK() {};
diff --git a/CPP/Windows/DLL.cpp b/CPP/Windows/DLL.cpp
index 5485ba3..988b66f 100644
--- a/CPP/Windows/DLL.cpp
+++ b/CPP/Windows/DLL.cpp
@@ -95,7 +95,7 @@ FString GetModuleDirPrefix()
FString s;
if (MyGetModuleFileName(s))
{
- int pos = s.ReverseFind(FCHAR_PATH_SEPARATOR);
+ int pos = s.ReverseFind_PathSepar();
if (pos >= 0)
{
s.DeleteFrom(pos + 1);
diff --git a/CPP/Windows/DLL.h b/CPP/Windows/DLL.h
index e61cf89..58bcf19 100644
--- a/CPP/Windows/DLL.h
+++ b/CPP/Windows/DLL.h
@@ -13,17 +13,23 @@ namespace NDLL {
#else
#define My_GetProcAddress(module, procName) ::GetProcAddress(module, procName)
#endif
-
+
+/* Win32: Don't call CLibrary::Free() and FreeLibrary() from another
+ FreeLibrary() code: detaching code in DLL entry-point or in
+ destructors of global objects in DLL module. */
+
class CLibrary
{
HMODULE _module;
+
+ // CLASS_NO_COPY(CLibrary);
public:
CLibrary(): _module(NULL) {};
~CLibrary() { Free(); }
operator HMODULE() const { return _module; }
HMODULE* operator&() { return &_module; }
- bool IsLoaded() const { return (_module != NULL); };
+ bool IsLoaded() const { return (_module != NULL); }
void Attach(HMODULE m)
{
diff --git a/CPP/Windows/ErrorMsg.cpp b/CPP/Windows/ErrorMsg.cpp
index e929e75..c252afd 100644
--- a/CPP/Windows/ErrorMsg.cpp
+++ b/CPP/Windows/ErrorMsg.cpp
@@ -42,20 +42,25 @@ static bool MyFormatMessage(DWORD errorCode, UString &message)
UString MyFormatMessage(DWORD errorCode)
{
- UString message;
- if (!MyFormatMessage(errorCode, message))
+ UString m;
+ if (!MyFormatMessage(errorCode, m) || m.IsEmpty())
{
- wchar_t s[16];
+ char s[16];
for (int i = 0; i < 8; i++)
{
unsigned t = errorCode & 0xF;
errorCode >>= 4;
- s[7 - i] = (wchar_t)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
+ s[7 - i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
}
- s[8] = '\0';
- message = (UString)L"Error #" + s;
+ s[8] = 0;
+ m.AddAscii("Error #");
+ m.AddAscii(s);
}
- return message;
+ else if (m.Len() >= 2
+ && m[m.Len() - 1] == 0x0A
+ && m[m.Len() - 2] == 0x0D)
+ m.DeleteFrom(m.Len() - 2);
+ return m;
}
}}
diff --git a/CPP/Windows/FileDir.cpp b/CPP/Windows/FileDir.cpp
index c215657..6b70a47 100644
--- a/CPP/Windows/FileDir.cpp
+++ b/CPP/Windows/FileDir.cpp
@@ -86,9 +86,9 @@ bool SetDirTime(CFSTR path, const FILETIME *cTime, const FILETIME *aTime, const
#ifdef WIN_LONG_PATH
if (hDir == INVALID_HANDLE_VALUE && USE_SUPER_PATH)
{
- UString longPath;
- if (GetSuperPath(path, longPath, USE_MAIN_PATH))
- hDir = ::CreateFileW(longPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ hDir = ::CreateFileW(superPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
}
#endif
@@ -119,9 +119,9 @@ bool SetFileAttrib(CFSTR path, DWORD attrib)
#ifdef WIN_LONG_PATH
if (USE_SUPER_PATH)
{
- UString longPath;
- if (GetSuperPath(path, longPath, USE_MAIN_PATH))
- return BOOLToBool(::SetFileAttributesW(longPath, attrib));
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ return BOOLToBool(::SetFileAttributesW(superPath, attrib));
}
#endif
}
@@ -145,9 +145,9 @@ bool RemoveDir(CFSTR path)
#ifdef WIN_LONG_PATH
if (USE_SUPER_PATH)
{
- UString longPath;
- if (GetSuperPath(path, longPath, USE_MAIN_PATH))
- return BOOLToBool(::RemoveDirectoryW(longPath));
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ return BOOLToBool(::RemoveDirectoryW(superPath));
}
#endif
}
@@ -226,6 +226,29 @@ bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName)
#endif
+/*
+WinXP-64 CreateDir():
+ "" - ERROR_PATH_NOT_FOUND
+ \ - ERROR_ACCESS_DENIED
+ C:\ - ERROR_ACCESS_DENIED, if there is such drive,
+
+ D:\folder - ERROR_PATH_NOT_FOUND, if there is no such drive,
+ C:\nonExistent\folder - ERROR_PATH_NOT_FOUND
+
+ C:\existFolder - ERROR_ALREADY_EXISTS
+ C:\existFolder\ - ERROR_ALREADY_EXISTS
+
+ C:\folder - OK
+ C:\folder\ - OK
+
+ \\Server\nonExistent - ERROR_BAD_NETPATH
+ \\Server\Share_Readonly - ERROR_ACCESS_DENIED
+ \\Server\Share - ERROR_ALREADY_EXISTS
+
+ \\Server\Share_NTFS_drive - ERROR_ACCESS_DENIED
+ \\Server\Share_FAT_drive - ERROR_ALREADY_EXISTS
+*/
+
bool CreateDir(CFSTR path)
{
#ifndef _UNICODE
@@ -243,56 +266,127 @@ bool CreateDir(CFSTR path)
#ifdef WIN_LONG_PATH
if ((!USE_MAIN_PATH || ::GetLastError() != ERROR_ALREADY_EXISTS) && USE_SUPER_PATH)
{
- UString longPath;
- if (GetSuperPath(path, longPath, USE_MAIN_PATH))
- return BOOLToBool(::CreateDirectoryW(longPath, NULL));
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ return BOOLToBool(::CreateDirectoryW(superPath, NULL));
}
#endif
}
return false;
}
-bool CreateComplexDir(CFSTR _aPathName)
+/*
+ CreateDir2 returns true, if directory can contain files after the call (two cases):
+ 1) the directory already exists
+ 2) the directory was created
+ path must be WITHOUT trailing path separator.
+
+ We need CreateDir2, since fileInfo.Find() for reserved names like "com8"
+ returns FILE instead of DIRECTORY. And we need to use SuperPath */
+
+static bool CreateDir2(CFSTR path)
{
- FString pathName = _aPathName;
- int pos = pathName.ReverseFind(FCHAR_PATH_SEPARATOR);
- if (pos > 0 && (unsigned)pos == pathName.Len() - 1)
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- if (pathName.Len() == 3 && pathName[1] == L':')
- return true; // Disk folder;
- pathName.Delete(pos);
+ if (::CreateDirectory(fs2fas(path), NULL))
+ return true;
+ }
+ else
+ #endif
+ {
+ IF_USE_MAIN_PATH
+ if (::CreateDirectoryW(fs2us(path), NULL))
+ return true;
+ #ifdef WIN_LONG_PATH
+ if ((!USE_MAIN_PATH || ::GetLastError() != ERROR_ALREADY_EXISTS) && USE_SUPER_PATH)
+ {
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ {
+ if (::CreateDirectoryW(superPath, NULL))
+ return true;
+ if (::GetLastError() != ERROR_ALREADY_EXISTS)
+ return false;
+ NFind::CFileInfo fi;
+ if (!fi.Find(us2fs(superPath)))
+ return false;
+ return fi.IsDir();
+ }
+ }
+ #endif
}
- const FString pathName2 = pathName;
- pos = pathName.Len();
+ if (::GetLastError() != ERROR_ALREADY_EXISTS)
+ return false;
+ NFind::CFileInfo fi;
+ if (!fi.Find(path))
+ return false;
+ return fi.IsDir();
+}
+
+bool CreateComplexDir(CFSTR _path)
+{
+ #ifdef _WIN32
+
+ {
+ DWORD attrib = NFind::GetFileAttrib(_path);
+ if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0)
+ return true;
+ }
+
+ #ifndef UNDER_CE
+
+ if (IsDriveRootPath_SuperAllowed(_path))
+ return false;
+
+ unsigned prefixSize = GetRootPrefixSize(_path);
+
+ #endif
+
+ #endif
+
+ FString path = _path;
+
+ int pos = path.ReverseFind_PathSepar();
+ if (pos >= 0 && (unsigned)pos == path.Len() - 1)
+ {
+ if (path.Len() == 1)
+ return true;
+ path.DeleteBack();
+ }
+
+ const FString path2 = path;
+ pos = path.Len();
for (;;)
{
- if (CreateDir(pathName))
+ if (CreateDir2(path))
break;
if (::GetLastError() == ERROR_ALREADY_EXISTS)
- {
- NFind::CFileInfo fileInfo;
- if (!fileInfo.Find(pathName)) // For network folders
- return true;
- if (!fileInfo.IsDir())
- return false;
- break;
- }
- pos = pathName.ReverseFind(FCHAR_PATH_SEPARATOR);
+ return false;
+ pos = path.ReverseFind_PathSepar();
if (pos < 0 || pos == 0)
return false;
- if (pathName[pos - 1] == L':')
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ if (pos == 1 && IS_PATH_SEPAR(path[0]))
+ return false;
+ if (prefixSize >= (unsigned)pos + 1)
return false;
- pathName.DeleteFrom(pos);
+ #endif
+
+ path.DeleteFrom(pos);
}
- while (pos < (int)pathName2.Len())
+ while (pos < (int)path2.Len())
{
- pos = pathName2.Find(FCHAR_PATH_SEPARATOR, pos + 1);
- if (pos < 0)
- pos = pathName2.Len();
- pathName.SetFrom(pathName2, pos);
- if (!CreateDir(pathName))
+ int pos2 = NName::FindSepar(path2.Ptr(pos + 1));
+ if (pos2 < 0)
+ pos = path2.Len();
+ else
+ pos += 1 + pos2;
+ path.SetFrom(path2, pos);
+ if (!CreateDir(path))
return false;
}
@@ -301,8 +395,19 @@ bool CreateComplexDir(CFSTR _aPathName)
bool DeleteFileAlways(CFSTR path)
{
- if (!SetFileAttrib(path, 0))
- return false;
+ /* If alt stream, we also need to clear READ-ONLY attribute of main file before delete.
+ SetFileAttrib("name:stream", ) changes attributes of main file. */
+ {
+ DWORD attrib = NFind::GetFileAttrib(path);
+ if (attrib != INVALID_FILE_ATTRIBUTES
+ && (attrib & FILE_ATTRIBUTE_DIRECTORY) == 0
+ && (attrib & FILE_ATTRIBUTE_READONLY) != 0)
+ {
+ if (!SetFileAttrib(path, attrib & ~FILE_ATTRIBUTE_READONLY))
+ return false;
+ }
+ }
+
#ifndef _UNICODE
if (!g_IsNT)
{
@@ -312,15 +417,17 @@ bool DeleteFileAlways(CFSTR path)
else
#endif
{
+ /* DeleteFile("name::$DATA") deletes all alt streams (same as delete DeleteFile("name")).
+ Maybe it's better to open "name::$DATA" and clear data for unnamed stream? */
IF_USE_MAIN_PATH
if (::DeleteFileW(fs2us(path)))
return true;
#ifdef WIN_LONG_PATH
if (USE_SUPER_PATH)
{
- UString longPath;
- if (GetSuperPath(path, longPath, USE_MAIN_PATH))
- return BOOLToBool(::DeleteFileW(longPath));
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ return BOOLToBool(::DeleteFileW(superPath));
}
#endif
}
@@ -346,7 +453,7 @@ bool RemoveDirWithSubItems(const FString &path)
if (needRemoveSubItems)
{
FString s = path;
- s += FCHAR_PATH_SEPARATOR;
+ s.Add_PathSepar();
unsigned prefixSize = s.Len();
s += FCHAR_ANY_MASK;
NFind::CEnumerator enumerator(s);
@@ -430,7 +537,7 @@ bool GetFullPathAndSplit(CFSTR path, FString &resDirPrefix, FString &resFileName
bool res = MyGetFullPathName(path, resDirPrefix);
if (!res)
resDirPrefix = path;
- int pos = resDirPrefix.ReverseFind(FCHAR_PATH_SEPARATOR);
+ int pos = resDirPrefix.ReverseFind_PathSepar();
resFileName = resDirPrefix.Ptr(pos + 1);
resDirPrefix.DeleteFrom(pos + 1);
return res;
@@ -480,7 +587,7 @@ static bool CreateTempFile(CFSTR prefix, bool addRandom, FString &path, NIO::COu
{
unsigned t = value & 0xF;
value >>= 4;
- s[k] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
+ s[k] = (FChar)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
}
s[k] = '\0';
if (outFile)
diff --git a/CPP/Windows/FileDir.h b/CPP/Windows/FileDir.h
index 1c75788..35f6957 100644
--- a/CPP/Windows/FileDir.h
+++ b/CPP/Windows/FileDir.h
@@ -24,7 +24,14 @@ bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName);
bool RemoveDir(CFSTR path);
bool CreateDir(CFSTR path);
+
+/* CreateComplexDir returns true, if directory can contain files after the call (two cases):
+ 1) the directory already exists (network shares and drive paths are supported)
+ 2) the directory was created
+ path can be WITH or WITHOUT trailing path separator. */
+
bool CreateComplexDir(CFSTR path);
+
bool DeleteFileAlways(CFSTR name);
bool RemoveDirWithSubItems(const FString &path);
diff --git a/CPP/Windows/FileFind.cpp b/CPP/Windows/FileFind.cpp
index 35c0bf6..2ab189d 100644
--- a/CPP/Windows/FileFind.cpp
+++ b/CPP/Windows/FileFind.cpp
@@ -2,13 +2,14 @@
#include "StdAfx.h"
-#include "FileFind.h"
-#include "FileIO.h"
-#include "FileName.h"
#ifndef _UNICODE
#include "../Common/StringConvert.h"
#endif
+#include "FileFind.h"
+#include "FileIO.h"
+#include "FileName.h"
+
#ifndef _UNICODE
extern bool g_IsNT;
#endif
@@ -58,9 +59,9 @@ bool CFileInfo::IsDots() const throw()
{
if (!IsDir() || Name.IsEmpty())
return false;
- if (Name[0] != FTEXT('.'))
+ if (Name[0] != '.')
return false;
- return Name.Len() == 1 || (Name.Len() == 2 && Name[1] == FTEXT('.'));
+ return Name.Len() == 1 || (Name.Len() == 2 && Name[1] == '.');
}
#define WIN_FD_TO_MY_FI(fi, fd) \
@@ -114,6 +115,37 @@ bool CFindFileBase::Close() throw()
return true;
}
+/*
+WinXP-64 FindFirstFile():
+ "" - ERROR_PATH_NOT_FOUND
+ folder\ - ERROR_FILE_NOT_FOUND
+ \ - ERROR_FILE_NOT_FOUND
+ c:\ - ERROR_FILE_NOT_FOUND
+ c: - ERROR_FILE_NOT_FOUND, if current dir is ROOT ( c:\ )
+ c: - OK, if current dir is NOT ROOT ( c:\folder )
+ folder - OK
+
+ \\ - ERROR_INVALID_NAME
+ \\Server - ERROR_INVALID_NAME
+ \\Server\ - ERROR_INVALID_NAME
+
+ \\Server\Share - ERROR_BAD_NETPATH
+ \\Server\Share - ERROR_BAD_NET_NAME (Win7).
+ !!! There is problem : Win7 makes some requests for "\\Server\Shar" (look in Procmon),
+ when we call it for "\\Server\Share"
+
+ \\Server\Share\ - ERROR_FILE_NOT_FOUND
+
+ \\?\UNC\Server\Share - ERROR_INVALID_NAME
+ \\?\UNC\Server\Share - ERROR_BAD_PATHNAME (Win7)
+ \\?\UNC\Server\Share\ - ERROR_FILE_NOT_FOUND
+
+ \\Server\Share_RootDrive - ERROR_INVALID_NAME
+ \\Server\Share_RootDrive\ - ERROR_INVALID_NAME
+
+ c:\* - ERROR_FILE_NOT_FOUND, if thare are no item in that folder
+*/
+
bool CFindFile::FindFirst(CFSTR path, CFileInfo &fi)
{
if (!Close())
@@ -137,9 +169,9 @@ bool CFindFile::FindFirst(CFSTR path, CFileInfo &fi)
#ifdef WIN_LONG_PATH
if (_handle == INVALID_HANDLE_VALUE && USE_SUPER_PATH)
{
- UString longPath;
- if (GetSuperPath(path, longPath, USE_MAIN_PATH))
- _handle = ::FindFirstFileW(longPath, &fd);
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ _handle = ::FindFirstFileW(superPath, &fd);
}
#endif
if (_handle == INVALID_HANDLE_VALUE)
@@ -189,24 +221,51 @@ struct CFindStreamLoader
bool CStreamInfo::IsMainStream() const throw()
{
- return Name == L"::$DATA";
+ return StringsAreEqualNoCase_Ascii(Name, "::$DATA");
};
UString CStreamInfo::GetReducedName() const
{
+ // remove ":$DATA" postfix, but keep postfix, if Name is "::$DATA"
UString s = Name;
- if (s.Len() >= 6)
- if (wcscmp(s.RightPtr(6), L":$DATA") == 0)
- s.DeleteFrom(s.Len() - 6);
+ if (s.Len() > 6 + 1 && StringsAreEqualNoCase_Ascii(s.RightPtr(6), ":$DATA"))
+ s.DeleteFrom(s.Len() - 6);
return s;
}
+/*
+UString CStreamInfo::GetReducedName2() const
+{
+ UString s = GetReducedName();
+ if (!s.IsEmpty() && s[0] == ':')
+ s.Delete(0);
+ 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;
}
+/*
+ WinXP-64 FindFirstStream():
+ "" - ERROR_PATH_NOT_FOUND
+ folder\ - OK
+ folder - OK
+ \ - OK
+ c:\ - OK
+ c: - OK, if current dir is ROOT ( c:\ )
+ c: - OK, if current dir is NOT ROOT ( c:\folder )
+ \\Server\Share - OK
+ \\Server\Share\ - OK
+
+ \\ - ERROR_INVALID_NAME
+ \\Server - ERROR_INVALID_NAME
+ \\Server\ - ERROR_INVALID_NAME
+*/
+
bool CFindStream::FindFirst(CFSTR path, CStreamInfo &si)
{
if (!Close())
@@ -218,6 +277,7 @@ bool CFindStream::FindFirst(CFSTR path, CStreamInfo &si)
}
{
MY_WIN32_FIND_STREAM_DATA sd;
+ SetLastError(0);
IF_USE_MAIN_PATH
_handle = g_FindFirstStreamW(fs2us(path), My_FindStreamInfoStandard, &sd, 0);
if (_handle == INVALID_HANDLE_VALUE)
@@ -228,9 +288,9 @@ bool CFindStream::FindFirst(CFSTR path, CStreamInfo &si)
#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);
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ _handle = g_FindFirstStreamW(superPath, My_FindStreamInfoStandard, &sd, 0);
}
#endif
}
@@ -278,7 +338,7 @@ bool CStreamEnumerator::Next(CStreamInfo &si, bool &found)
#define MY_CLEAR_FILETIME(ft) ft.dwLowDateTime = ft.dwHighDateTime = 0;
-void CFileInfoBase::Clear() throw()
+void CFileInfoBase::ClearBase() throw()
{
Size = 0;
MY_CLEAR_FILETIME(CTime);
@@ -289,43 +349,83 @@ void CFileInfoBase::Clear() throw()
IsDevice = false;
}
-#if defined(_WIN32) && !defined(UNDER_CE)
+/*
+WinXP-64 GetFileAttributes():
+ If the function fails, it returns INVALID_FILE_ATTRIBUTES and use GetLastError() to get error code
+
+ \ - OK
+ C:\ - OK, if there is such drive,
+ D:\ - ERROR_PATH_NOT_FOUND, if there is no such drive,
-static int FindAltStreamColon(CFSTR path)
+ C:\folder - OK
+ C:\folder\ - OK
+ C:\folderBad - ERROR_FILE_NOT_FOUND
+
+ \\Server\BadShare - ERROR_BAD_NETPATH
+ \\Server\Share - WORKS OK, but MSDN says:
+ GetFileAttributes for a network share, the function fails, and GetLastError
+ returns ERROR_BAD_NETPATH. You must specify a path to a subfolder on that share.
+*/
+
+DWORD GetFileAttrib(CFSTR path)
{
- for (int i = 0;; i++)
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ return ::GetFileAttributes(fs2fas(path));
+ else
+ #endif
{
- FChar c = path[i];
- if (c == 0)
- return -1;
- if (c == ':')
+ IF_USE_MAIN_PATH
{
- 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;
+ DWORD dw = ::GetFileAttributesW(fs2us(path));
+ if (dw != INVALID_FILE_ATTRIBUTES)
+ return dw;
}
+ #ifdef WIN_LONG_PATH
+ if (USE_SUPER_PATH)
+ {
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ return ::GetFileAttributesW(superPath);
+ }
+ #endif
+ return INVALID_FILE_ATTRIBUTES;
}
}
-#endif
+/* if path is "c:" or "c::" then CFileInfo::Find() returns name of current folder for that disk
+ so instead of absolute path we have relative path in Name. That is not good in some calls */
+
+/* In CFileInfo::Find() we want to support same names for alt streams as in CreateFile(). */
+
+/* CFileInfo::Find()
+We alow the following paths (as FindFirstFile):
+ C:\folder
+ c: - if current dir is NOT ROOT ( c:\folder )
+
+also we support paths that are not supported by FindFirstFile:
+ \
+ \\.\c:
+ c:\ - Name will be without tail slash ( c: )
+ \\?\c:\ - Name will be without tail slash ( c: )
+ \\Server\Share
+ \\?\UNC\Server\Share
+
+ c:\folder:stream - Name = folder:stream
+ c:\:stream - Name = :stream
+ c::stream - Name = c::stream
+*/
bool CFileInfo::Find(CFSTR path)
{
#ifdef SUPPORT_DEVICE_FILE
if (IsDevicePath(path))
{
- Clear();
+ ClearBase();
Name = path + 4;
-
IsDevice = true;
- if (/* path[0] == '\\' && path[1] == '\\' && path[2] == '.' && path[3] == '\\' && */
- path[5] == ':' && path[6] == 0)
+
+ if (NName::IsDrivePath2(path + 4) && path[6] == 0)
{
FChar drive[4] = { path[4], ':', '\\', 0 };
UInt64 clusterSize, totalSize, freeSize;
@@ -350,16 +450,37 @@ bool CFileInfo::Find(CFSTR path)
#if defined(_WIN32) && !defined(UNDER_CE)
int colonPos = FindAltStreamColon(path);
- if (colonPos >= 0)
+ if (colonPos >= 0 && path[(unsigned)colonPos + 1] != 0)
{
UString streamName = fs2us(path + (unsigned)colonPos);
FString filePath = path;
filePath.DeleteFrom(colonPos);
- streamName += L":$DATA"; // change it!!!!
- if (Find(filePath))
+ /* we allow both cases:
+ name:stream
+ name:stream:$DATA
+ */
+ const unsigned kPostfixSize = 6;
+ if (streamName.Len() <= kPostfixSize
+ || !StringsAreEqualNoCase_Ascii(streamName.RightPtr(kPostfixSize), ":$DATA"))
+ streamName += L":$DATA";
+
+ bool isOk = true;
+
+ if (IsDrivePath2(filePath) &&
+ (colonPos == 2 || colonPos == 3 && filePath[2] == '\\'))
+ {
+ // FindFirstFile doesn't work for "c:\" and for "c:" (if current dir is ROOT)
+ ClearBase();
+ Name.Empty();
+ if (colonPos == 2)
+ Name = filePath;
+ }
+ else
+ isOk = Find(filePath);
+
+ if (isOk)
{
- // if (IsDir())
- Attrib &= ~FILE_ATTRIBUTE_DIRECTORY;
+ Attrib &= ~(FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
Size = 0;
CStreamEnumerator enumerator(filePath);
for (;;)
@@ -373,10 +494,12 @@ bool CFileInfo::Find(CFSTR path)
::SetLastError(ERROR_FILE_NOT_FOUND);
return false;
}
- if (si.Name.IsEqualToNoCase(streamName))
+ if (si.Name.IsEqualTo_NoCase(streamName))
{
+ // we delete postfix, if alt stream name is not "::$DATA"
+ if (si.Name.Len() > kPostfixSize + 1)
+ si.Name.DeleteFrom(si.Name.Len() - kPostfixSize);
Name += us2fs(si.Name);
- Name.DeleteFrom(Name.Len() - 6);
Size = si.Size;
IsAltStream = true;
return true;
@@ -388,53 +511,94 @@ bool CFileInfo::Find(CFSTR path)
#endif
CFindFile finder;
- if (finder.FindFirst(path, *this))
- return true;
- #ifdef _WIN32
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
{
+ /*
DWORD lastError = GetLastError();
- 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"
+ if (lastError == ERROR_FILE_NOT_FOUND
+ || lastError == ERROR_BAD_NETPATH // XP64: "\\Server\Share"
+ || lastError == ERROR_BAD_NET_NAME // Win7: "\\Server\Share"
+ || lastError == ERROR_INVALID_NAME // XP64: "\\?\UNC\Server\Share"
+ || lastError == ERROR_BAD_PATHNAME // Win7: "\\?\UNC\Server\Share"
)
+ */
+
+ unsigned rootSize = 0;
+ if (IsSuperPath(path))
+ rootSize = kSuperPathPrefixSize;
+
+ if (NName::IsDrivePath(path + rootSize) && path[rootSize + 3] == 0)
{
- unsigned len = MyStringLen(path);
- if (len > 2 && path[0] == '\\' && path[1] == '\\')
+ DWORD attrib = GetFileAttrib(path);
+ if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0)
+ {
+ ClearBase();
+ Attrib = attrib;
+ Name = path + rootSize;
+ Name.DeleteFrom(2); // we don't need backslash (C:)
+ return true;
+ }
+ }
+ else if (IS_PATH_SEPAR(path[0]))
+ if (path[1] == 0)
+ {
+ DWORD attrib = GetFileAttrib(path);
+ if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0)
+ {
+ ClearBase();
+ Name.Empty();
+ Attrib = attrib;
+ return true;
+ }
+ }
+ else
{
- int startPos = 2;
- if (len > kSuperUncPathPrefixSize && IsSuperUncPath(path))
- startPos = kSuperUncPathPrefixSize;
- int pos = FindCharPosInString(path + startPos, FTEXT('\\'));
- if (pos >= 0)
+ const unsigned prefixSize = GetNetworkServerPrefixSize(path);
+ if (prefixSize > 0 && path[prefixSize] != 0)
{
- pos += startPos + 1;
- len -= pos;
- int pos2 = FindCharPosInString(path + pos, FTEXT('\\'));
- if (pos2 < 0 || pos2 == (int)len - 1)
+ if (NName::FindSepar(path + prefixSize) < 0)
{
FString s = path;
- if (pos2 < 0)
- {
- pos2 = len;
- s += FTEXT('\\');
- }
+ s.Add_PathSepar();
s += FCHAR_ANY_MASK;
+
+ bool isOK = false;
if (finder.FindFirst(s, *this))
+ {
if (Name == FTEXT("."))
{
- Name.SetFrom(s.Ptr(pos), pos2);
+ Name = path + prefixSize;
+ return true;
+ }
+ isOK = true;
+ /* if "\\server\share" maps to root folder "d:\", there is no "." item.
+ But it's possible that there are another items */
+ }
+ {
+ DWORD attrib = GetFileAttrib(path);
+ if (isOK || attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0)
+ {
+ ClearBase();
+ if (attrib != INVALID_FILE_ATTRIBUTES)
+ Attrib = attrib;
+ else
+ SetAsDir();
+ Name = path + prefixSize;
return true;
}
- ::SetLastError(lastError);
+ }
+ // ::SetLastError(lastError);
}
}
}
- }
}
#endif
- return false;
+
+ return finder.FindFirst(path, *this);
}
+
bool DoesFileExist(CFSTR name)
{
CFileInfo fi;
@@ -446,12 +610,14 @@ bool DoesDirExist(CFSTR name)
CFileInfo fi;
return fi.Find(name) && fi.IsDir();
}
+
bool DoesFileOrDirExist(CFSTR name)
{
CFileInfo fi;
return fi.Find(name);
}
+
bool CEnumerator::NextAny(CFileInfo &fi)
{
if (_findFile.IsHandleAllocated())
@@ -509,9 +675,9 @@ HANDLE CFindChangeNotification::FindFirst(CFSTR path, bool watchSubtree, DWORD n
#ifdef WIN_LONG_PATH
if (!IsHandleAllocated())
{
- UString longPath;
- if (GetSuperPath(path, longPath, USE_MAIN_PATH))
- _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
+ UString superPath;
+ if (GetSuperPath(path, superPath, USE_MAIN_PATH))
+ _handle = ::FindFirstChangeNotificationW(superPath, BoolToBOOL(watchSubtree), notifyFilter);
}
#endif
}
@@ -530,23 +696,22 @@ bool MyGetLogicalDriveStrings(CObjectVector<FString> &driveStrings)
UINT32 size = GetLogicalDriveStrings(0, NULL);
if (size == 0)
return false;
- AString buf;
- UINT32 newSize = GetLogicalDriveStrings(size, buf.GetBuffer(size));
+ CObjArray<char> buf(size);
+ UINT32 newSize = GetLogicalDriveStrings(size, buf);
if (newSize == 0 || newSize > size)
return false;
AString s;
+ UINT32 prev = 0;
for (UINT32 i = 0; i < newSize; i++)
{
- char c = buf[i];
- if (c == '\0')
+ if (buf[i] == 0)
{
+ s = buf + prev;
+ prev = i + 1;
driveStrings.Add(fas2fs(s));
- s.Empty();
}
- else
- s += c;
}
- return s.IsEmpty();
+ return prev == newSize;
}
else
#endif
@@ -554,23 +719,22 @@ bool MyGetLogicalDriveStrings(CObjectVector<FString> &driveStrings)
UINT32 size = GetLogicalDriveStringsW(0, NULL);
if (size == 0)
return false;
- UString buf;
- UINT32 newSize = GetLogicalDriveStringsW(size, buf.GetBuffer(size));
+ CObjArray<wchar_t> buf(size);
+ UINT32 newSize = GetLogicalDriveStringsW(size, buf);
if (newSize == 0 || newSize > size)
return false;
UString s;
+ UINT32 prev = 0;
for (UINT32 i = 0; i < newSize; i++)
{
- WCHAR c = buf[i];
- if (c == L'\0')
+ if (buf[i] == 0)
{
+ s = buf + prev;
+ prev = i + 1;
driveStrings.Add(us2fs(s));
- s.Empty();
}
- else
- s += c;
}
- return s.IsEmpty();
+ return prev == newSize;
}
}
diff --git a/CPP/Windows/FileFind.h b/CPP/Windows/FileFind.h
index 1325253..fc1f387 100644
--- a/CPP/Windows/FileFind.h
+++ b/CPP/Windows/FileFind.h
@@ -41,8 +41,8 @@ public:
#endif
*/
- CFileInfoBase() { Clear(); }
- void Clear() throw();
+ CFileInfoBase() { ClearBase(); }
+ void ClearBase() throw();
void SetAsDir() { Attrib = FILE_ATTRIBUTE_DIRECTORY; }
@@ -68,7 +68,7 @@ struct CFileInfo: public CFileInfoBase
#endif
bool IsDots() const throw();
- bool Find(CFSTR wildcard);
+ bool Find(CFSTR path);
};
class CFindFileBase
@@ -96,7 +96,8 @@ struct CStreamInfo
UString Name;
UInt64 Size;
- UString GetReducedName() const;
+ UString GetReducedName() const; // returns ":Name"
+ // UString GetReducedName2() const; // returns "Name"
bool IsMainStream() const throw();
};
@@ -124,6 +125,8 @@ bool DoesFileExist(CFSTR name);
bool DoesDirExist(CFSTR name);
bool DoesFileOrDirExist(CFSTR name);
+DWORD GetFileAttrib(CFSTR path);
+
class CEnumerator
{
CFindFile _findFile;
diff --git a/CPP/Windows/FileIO.cpp b/CPP/Windows/FileIO.cpp
index 3dcf5c1..a1d52c0 100644
--- a/CPP/Windows/FileIO.cpp
+++ b/CPP/Windows/FileIO.cpp
@@ -130,7 +130,7 @@ bool CFileBase::Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition
if (low == 0xFFFFFFFF)
if (::GetLastError() != NO_ERROR)
return false;
- newPosition = (((UInt64)high) << 32) + low;
+ newPosition = (((UInt64)(UInt32)high) << 32) + low;
return true;
}
diff --git a/CPP/Windows/FileIO.h b/CPP/Windows/FileIO.h
index 96691b9..af4785f 100644
--- a/CPP/Windows/FileIO.h
+++ b/CPP/Windows/FileIO.h
@@ -3,6 +3,8 @@
#ifndef __WINDOWS_FILE_IO_H
#define __WINDOWS_FILE_IO_H
+#include "../Common/MyWindows.h"
+
#if defined(_WIN32) && !defined(UNDER_CE)
#include <winioctl.h>
#endif
diff --git a/CPP/Windows/FileLink.cpp b/CPP/Windows/FileLink.cpp
index 1bd1d52..f4c7081 100644
--- a/CPP/Windows/FileLink.cpp
+++ b/CPP/Windows/FileLink.cpp
@@ -102,6 +102,8 @@ void WriteString(Byte *dest, const wchar_t *path)
}
}
+#if defined(_WIN32) && !defined(UNDER_CE)
+
bool FillLinkData(CByteBuffer &dest, const wchar_t *path, bool isSymLink)
{
bool isAbs = IsAbsolutePath(path);
@@ -175,13 +177,21 @@ bool FillLinkData(CByteBuffer &dest, const wchar_t *path, bool isSymLink)
return true;
}
+#endif
+
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();
+ wchar_t *s = res.GetBuf(len);
+ unsigned i;
+ for (i = 0; i < len; i++)
+ {
+ wchar_t c = Get16(p + i * 2);
+ if (c == 0)
+ break;
+ s[i] = c;
+ }
+ s[i] = 0;
+ res.ReleaseBuf_SetLen(i);
}
bool CReparseAttr::Parse(const Byte *p, size_t size)
@@ -367,7 +377,7 @@ bool GetReparseData(CFSTR path, CByteBuffer &reparseData, BY_HANDLE_FILE_INFORMA
static bool CreatePrefixDirOfFile(CFSTR path)
{
FString path2 = path;
- int pos = path2.ReverseFind(FCHAR_PATH_SEPARATOR);
+ int pos = path2.ReverseFind_PathSepar();
if (pos < 0)
return true;
#ifdef _WIN32
diff --git a/CPP/Windows/FileName.cpp b/CPP/Windows/FileName.cpp
index 9189ceb..773b834 100644
--- a/CPP/Windows/FileName.cpp
+++ b/CPP/Windows/FileName.cpp
@@ -12,13 +12,41 @@ namespace NWindows {
namespace NFile {
namespace NName {
+#define IS_SEPAR(c) IS_PATH_SEPAR(c)
+
+int FindSepar(const wchar_t *s) throw()
+{
+ for (const wchar_t *p = s;; p++)
+ {
+ const wchar_t c = *p;
+ if (c == 0)
+ return -1;
+ if (IS_SEPAR(c))
+ return (int)(p - s);
+ }
+}
+
+#ifndef USE_UNICODE_FSTRING
+int FindSepar(const FChar *s) throw()
+{
+ for (const FChar *p = s;; p++)
+ {
+ const FChar c = *p;
+ if (c == 0)
+ return -1;
+ if (IS_SEPAR(c))
+ return (int)(p - s);
+ }
+}
+#endif
+
#ifndef USE_UNICODE_FSTRING
void NormalizeDirPathPrefix(FString &dirPath)
{
if (dirPath.IsEmpty())
return;
- if (dirPath.Back() != FCHAR_PATH_SEPARATOR)
- dirPath += FCHAR_PATH_SEPARATOR;
+ if (!IsPathSepar(dirPath.Back()))
+ dirPath.Add_PathSepar();
}
#endif
@@ -26,26 +54,51 @@ void NormalizeDirPathPrefix(UString &dirPath)
{
if (dirPath.IsEmpty())
return;
- if (dirPath.Back() != WCHAR_PATH_SEPARATOR)
- dirPath += WCHAR_PATH_SEPARATOR;
+ if (!IsPathSepar(dirPath.Back()))
+ dirPath.Add_PathSepar();
}
+#define IS_LETTER_CHAR(c) ((c) >= 'a' && (c) <= 'z' || (c) >= 'A' && (c) <= 'Z')
+
+bool IsDrivePath(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && IS_SEPAR(s[2]); }
-#ifdef _WIN32
+bool IsAltPathPrefix(CFSTR s) throw()
+{
+ unsigned len = MyStringLen(s);
+ if (len == 0)
+ return false;
+ if (s[len - 1] != ':')
+ return false;
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ if (IsDevicePath(s))
+ return false;
+ if (IsSuperPath(s))
+ {
+ s += kSuperPathPrefixSize;
+ len -= kSuperPathPrefixSize;
+ }
+ if (len == 2 && IsDrivePath2(s))
+ return false;
+ #endif
+
+ return true;
+}
+
+#if defined(_WIN32) && !defined(UNDER_CE)
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_DEVICE_PATH(s) (IS_SEPAR((s)[0]) && IS_SEPAR((s)[1]) && (s)[2] == '.' && IS_SEPAR((s)[3]))
+#define IS_SUPER_PREFIX(s) (IS_SEPAR((s)[0]) && IS_SEPAR((s)[1]) && (s)[2] == '?' && IS_SEPAR((s)[3]))
+#define IS_SUPER_OR_DEVICE_PATH(s) (IS_SEPAR((s)[0]) && IS_SEPAR((s)[1]) && ((s)[2] == '?' || (s)[2] == '.') && IS_SEPAR((s)[3]))
#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] == '\\')
+ ((s)[0] == 'U' || (s)[0] == 'u') \
+ && ((s)[1] == 'N' || (s)[1] == 'n') \
+ && ((s)[2] == 'C' || (s)[2] == 'c') \
+ && IS_SEPAR((s)[3]))
bool IsDevicePath(CFSTR s) throw()
{
@@ -81,50 +134,133 @@ bool IsDevicePath(CFSTR s) throw()
}
bool IsSuperUncPath(CFSTR s) throw() { return (IS_SUPER_PREFIX(s) && IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)); }
+bool IsNetworkPath(CFSTR s) throw()
+{
+ if (!IS_SEPAR(s[0]) || !IS_SEPAR(s[1]))
+ return false;
+ if (IsSuperUncPath(s))
+ return true;
+ FChar c = s[2];
+ return (c != '.' && c != '?');
+}
+
+unsigned GetNetworkServerPrefixSize(CFSTR s) throw()
+{
+ if (!IS_SEPAR(s[0]) || !IS_SEPAR(s[1]))
+ return 0;
+ unsigned prefixSize = 2;
+ if (IsSuperUncPath(s))
+ prefixSize = kSuperUncPathPrefixSize;
+ else
+ {
+ FChar c = s[2];
+ if (c == '.' || c == '?')
+ return 0;
+ }
+ int pos = FindSepar(s + prefixSize);
+ if (pos < 0)
+ return 0;
+ return prefixSize + pos + 1;
+}
+
+bool IsNetworkShareRootPath(CFSTR s) throw()
+{
+ unsigned prefixSize = GetNetworkServerPrefixSize(s);
+ if (prefixSize == 0)
+ return false;
+ s += prefixSize;
+ int pos = FindSepar(s);
+ if (pos < 0)
+ return true;
+ return s[(unsigned)pos + 1] == 0;
+}
-bool IsDrivePath(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == '\\'; }
+static const unsigned kDrivePrefixSize = 3; /* c:\ */
+
+bool IsDrivePath2(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':'; }
+// bool IsDriveName2(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == 0; }
bool IsSuperPath(const wchar_t *s) throw() { return IS_SUPER_PREFIX(s); }
bool IsSuperOrDevicePath(const wchar_t *s) throw() { return IS_SUPER_OR_DEVICE_PATH(s); }
-// bool IsSuperUncPath(const wchar_t *s) { return (IS_SUPER_PREFIX(s) && IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)); }
+// bool IsSuperUncPath(const wchar_t *s) throw() { return (IS_SUPER_PREFIX(s) && IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)); }
#ifndef USE_UNICODE_FSTRING
-bool IsDrivePath(CFSTR s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == '\\'; }
+bool IsDrivePath2(CFSTR s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':'; }
+// bool IsDriveName2(CFSTR s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == 0; }
+bool IsDrivePath(CFSTR s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && IS_SEPAR(s[2]); }
bool IsSuperPath(CFSTR s) throw() { return IS_SUPER_PREFIX(s); }
bool IsSuperOrDevicePath(CFSTR s) throw() { return IS_SUPER_OR_DEVICE_PATH(s); }
#endif // USE_UNICODE_FSTRING
+/*
+bool IsDrivePath_SuperAllowed(CFSTR s)
+{
+ if (IsSuperPath(s))
+ s += kSuperPathPrefixSize;
+ return IsDrivePath(s);
+}
+*/
+
+bool IsDriveRootPath_SuperAllowed(CFSTR s) throw()
+{
+ if (IsSuperPath(s))
+ s += kSuperPathPrefixSize;
+ return IsDrivePath(s) && s[kDrivePrefixSize] == 0;
+}
+
bool IsAbsolutePath(const wchar_t *s) throw()
{
- return s[0] == WCHAR_PATH_SEPARATOR || IsDrivePath(s);
+ return IS_SEPAR(s[0]) || IsDrivePath2(s);
}
-static const unsigned kDrivePrefixSize = 3; /* c:\ */
+int FindAltStreamColon(CFSTR path)
+{
+ unsigned i = 0;
+ if (IsDrivePath2(path))
+ i = 2;
+ int colonPos = -1;
+ for (;; i++)
+ {
+ FChar c = path[i];
+ if (c == 0)
+ return colonPos;
+ if (c == ':')
+ {
+ if (colonPos < 0)
+ colonPos = i;
+ continue;
+ }
+ if (IS_SEPAR(c))
+ colonPos = -1;
+ }
+}
#ifndef USE_UNICODE_FSTRING
-static unsigned GetRootPrefixSize_Of_NetworkPath(CFSTR s) throw()
+static unsigned GetRootPrefixSize_Of_NetworkPath(CFSTR s)
{
// Network path: we look "server\path\" as root prefix
- int pos = FindCharPosInString(s, '\\');
+ int pos = FindSepar(s);
if (pos < 0)
return 0;
- int pos2 = FindCharPosInString(s + pos + 1, '\\');
+ int pos2 = FindSepar(s + (unsigned)pos + 1);
if (pos2 < 0)
return 0;
return pos + pos2 + 2;
}
-static unsigned GetRootPrefixSize_Of_SimplePath(CFSTR s) throw()
+static unsigned GetRootPrefixSize_Of_SimplePath(CFSTR s)
{
if (IsDrivePath(s))
return kDrivePrefixSize;
- if (s[0] != '\\' || s[1] != '\\')
+ if (!IS_SEPAR(s[0]))
return 0;
+ if (s[1] == 0 || !IS_SEPAR(s[1]))
+ return 1;
unsigned size = GetRootPrefixSize_Of_NetworkPath(s + 2);
return (size == 0) ? 0 : 2 + size;
}
-static unsigned GetRootPrefixSize_Of_SuperPath(CFSTR s) throw()
+static unsigned GetRootPrefixSize_Of_SuperPath(CFSTR s)
{
if (IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize))
{
@@ -132,13 +268,13 @@ static unsigned GetRootPrefixSize_Of_SuperPath(CFSTR s) throw()
return (size == 0) ? 0 : kSuperUncPathPrefixSize + size;
}
// we support \\?\c:\ paths and volume GUID paths \\?\Volume{GUID}\"
- int pos = FindCharPosInString(s + kSuperPathPrefixSize, FCHAR_PATH_SEPARATOR);
+ int pos = FindSepar(s + kSuperPathPrefixSize);
if (pos < 0)
return 0;
return kSuperPathPrefixSize + pos + 1;
}
-unsigned GetRootPrefixSize(CFSTR s) throw()
+unsigned GetRootPrefixSize(CFSTR s)
{
if (IS_DEVICE_PATH(s))
return kDevicePathPrefixSize;
@@ -149,29 +285,31 @@ unsigned GetRootPrefixSize(CFSTR s) throw()
#endif // USE_UNICODE_FSTRING
-static unsigned GetRootPrefixSize_Of_NetworkPath(const wchar_t *s) throw()
+static unsigned GetRootPrefixSize_Of_NetworkPath(const wchar_t *s)
{
// Network path: we look "server\path\" as root prefix
- int pos = FindCharPosInString(s, L'\\');
+ int pos = FindSepar(s);
if (pos < 0)
return 0;
- int pos2 = FindCharPosInString(s + pos + 1, L'\\');
+ int pos2 = FindSepar(s + (unsigned)pos + 1);
if (pos2 < 0)
return 0;
return pos + pos2 + 2;
}
-static unsigned GetRootPrefixSize_Of_SimplePath(const wchar_t *s) throw()
+static unsigned GetRootPrefixSize_Of_SimplePath(const wchar_t *s)
{
if (IsDrivePath(s))
return kDrivePrefixSize;
- if (s[0] != '\\' || s[1] != '\\')
+ if (!IS_SEPAR(s[0]))
return 0;
+ if (s[1] == 0 || !IS_SEPAR(s[1]))
+ return 1;
unsigned size = GetRootPrefixSize_Of_NetworkPath(s + 2);
return (size == 0) ? 0 : 2 + size;
}
-static unsigned GetRootPrefixSize_Of_SuperPath(const wchar_t *s) throw()
+static unsigned GetRootPrefixSize_Of_SuperPath(const wchar_t *s)
{
if (IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize))
{
@@ -179,7 +317,7 @@ static unsigned GetRootPrefixSize_Of_SuperPath(const wchar_t *s) throw()
return (size == 0) ? 0 : kSuperUncPathPrefixSize + size;
}
// we support \\?\c:\ paths and volume GUID paths \\?\Volume{GUID}\"
- int pos = FindCharPosInString(s + kSuperPathPrefixSize, L'\\');
+ int pos = FindSepar(s + kSuperPathPrefixSize);
if (pos < 0)
return 0;
return kSuperPathPrefixSize + pos + 1;
@@ -196,12 +334,12 @@ unsigned GetRootPrefixSize(const wchar_t *s) throw()
#else // _WIN32
-bool IsAbsolutePath(const wchar_t *s) throw() { return s[0] == WCHAR_PATH_SEPARATOR }
+bool IsAbsolutePath(const wchar_t *s) { return IS_SEPAR(s[0]); }
#ifndef USE_UNICODE_FSTRING
-unsigned GetRootPrefixSize(CFSTR s) throw() { return s[0] == CHAR_PATH_SEPRATOR ? 1 : 0; }
+unsigned GetRootPrefixSize(CFSTR s) { return IS_SEPAR(s[0]) ? 1 : 0; }
#endif
-unsigned GetRootPrefixSize(const wchar_t *s) throw() { return s[0] == CHAR_PATH_SEPRATOR ? 1 : 0; }
+unsigned GetRootPrefixSize(const wchar_t *s) { return IS_SEPAR(s[0]) ? 1 : 0; }
#endif // _WIN32
@@ -234,56 +372,68 @@ static bool GetCurDir(UString &path)
static bool ResolveDotsFolders(UString &s)
{
#ifdef _WIN32
- s.Replace(L'/', WCHAR_PATH_SEPARATOR);
+ // s.Replace(L'/', WCHAR_PATH_SEPARATOR);
#endif
- for (int i = 0;;)
+
+ for (unsigned i = 0;;)
{
- wchar_t c = s[i];
+ const wchar_t c = s[i];
if (c == 0)
return true;
- if (c == '.' && (i == 0 || s[i - 1] == WCHAR_PATH_SEPARATOR))
+ if (c == '.' && (i == 0 || IS_SEPAR(s[i - 1])))
{
- wchar_t c1 = s[i + 1];
+ const wchar_t c1 = s[i + 1];
if (c1 == '.')
{
- wchar_t c2 = s[i + 2];
- if (c2 == WCHAR_PATH_SEPARATOR || c2 == 0)
+ const wchar_t c2 = s[i + 2];
+ if (IS_SEPAR(c2) || c2 == 0)
{
if (i == 0)
return false;
int k = i - 2;
- for (; k >= 0; k--)
- if (s[k] == WCHAR_PATH_SEPARATOR)
+ i += 2;
+
+ for (;; k--)
+ {
+ if (k < 0)
+ return false;
+ if (!IS_SEPAR(s[(unsigned)k]))
break;
+ }
+
+ do
+ k--;
+ while (k >= 0 && !IS_SEPAR(s[(unsigned)k]));
+
unsigned num;
+
if (k >= 0)
{
- num = i + 2 - k;
+ num = i - k;
i = k;
}
else
{
- num = (c2 == 0 ? (i + 2) : (i + 3));
+ num = (c2 == 0 ? i : (i + 1));
i = 0;
}
+
s.Delete(i, num);
continue;
}
}
- else
+ else if (IS_SEPAR(c1) || c1 == 0)
{
- 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;
- }
+ unsigned num = 2;
+ if (i != 0)
+ i--;
+ else if (c1 == 0)
+ num = 1;
+ s.Delete(i, num);
+ continue;
}
}
+
i++;
}
}
@@ -308,11 +458,11 @@ static bool AreThereDotsFolders(CFSTR s)
FChar c = s[i];
if (c == 0)
return false;
- if (c == '.' && (i == 0 || s[i - 1] == CHAR_PATH_SEPARATOR))
+ if (c == '.' && (i == 0 || IS_SEPAR(s[i - 1])))
{
FChar c1 = s[i + 1];
- if (c1 == 0 || c1 == CHAR_PATH_SEPARATOR ||
- (c1 == '.' && (s[i + 2] == 0 || s[i + 2] == CHAR_PATH_SEPARATOR)))
+ if (c1 == 0 || IS_SEPAR(c1) ||
+ (c1 == '.' && (s[i + 2] == 0 || IS_SEPAR(s[i + 2]))))
return true;
}
}
@@ -360,16 +510,16 @@ int GetUseSuperPathType(CFSTR s) throw()
if (c == '.' || c == ' ')
{
FChar c2 = s[i + 1];
- if (c2 == 0 || c2 == CHAR_PATH_SEPARATOR)
+ if (c2 == 0 || IS_SEPAR(c2))
{
// if it's "." or "..", it's not bad name.
if (c == '.')
{
- if (i == 0 || s[i - 1] == CHAR_PATH_SEPARATOR)
+ if (i == 0 || IS_SEPAR(s[i - 1]))
continue;
if (s[i - 1] == '.')
{
- if (i - 1 == 0 || s[i - 2] == CHAR_PATH_SEPARATOR)
+ if (i - 1 == 0 || IS_SEPAR(s[i - 2]))
continue;
}
}
@@ -431,14 +581,17 @@ static bool GetSuperPathBase(CFSTR s, UString &res)
return true;
}
- if (c == CHAR_PATH_SEPARATOR)
+ if (IS_SEPAR(c))
{
- if (s[1] == CHAR_PATH_SEPARATOR)
+ if (IS_SEPAR(s[1]))
{
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?
+ // we ignore that error to allow short network paths server\share?
+ /*
+ if (fixedSize == 0)
return false;
+ */
UString rem = &temp[fixedSize];
if (!ResolveDotsFolders(rem))
return false;
@@ -451,14 +604,17 @@ static bool GetSuperPathBase(CFSTR s, UString &res)
}
else
{
- if (IsDrivePath(s))
+ if (IsDrivePath2(s))
{
UString temp = fs2us(s);
- UString rem = &temp[kDrivePrefixSize];
+ unsigned prefixSize = 2;
+ if (IsDrivePath(s))
+ prefixSize = kDrivePrefixSize;
+ UString rem = temp.Ptr(prefixSize);
if (!ResolveDotsFolders(rem))
return true;
res += kSuperPathPrefix;
- temp.DeleteFrom(kDrivePrefixSize);
+ temp.DeleteFrom(prefixSize);
res += temp;
res += rem;
return true;
@@ -468,8 +624,7 @@ static bool GetSuperPathBase(CFSTR s, UString &res)
UString curDir;
if (!GetCurDir(curDir))
return false;
- if (curDir.Back() != WCHAR_PATH_SEPARATOR)
- curDir += WCHAR_PATH_SEPARATOR;
+ NormalizeDirPathPrefix(curDir);
unsigned fixedSizeStart = 0;
unsigned fixedSize = 0;
@@ -489,10 +644,10 @@ static bool GetSuperPathBase(CFSTR s, UString &res)
}
else
{
- if (curDir[0] != CHAR_PATH_SEPARATOR || curDir[1] != CHAR_PATH_SEPARATOR)
+ if (!IsPathSepar(curDir[0]) || !IsPathSepar(curDir[1]))
return false;
fixedSizeStart = 2;
- fixedSize = GetRootPrefixSize_Of_NetworkPath(&curDir[2]);
+ fixedSize = GetRootPrefixSize_Of_NetworkPath(curDir.Ptr(2));
if (fixedSize == 0)
return false;
superMarker = kSuperUncPrefix;
@@ -500,7 +655,7 @@ static bool GetSuperPathBase(CFSTR s, UString &res)
}
UString temp;
- if (c == CHAR_PATH_SEPARATOR)
+ if (IS_SEPAR(c))
{
temp = fs2us(s + 1);
}
@@ -584,7 +739,7 @@ bool GetFullPath(CFSTR dirPrefix, CFSTR s, FString &res)
#ifdef UNDER_CE
- if (s[0] != CHAR_PATH_SEPARATOR)
+ if (!IS_SEPAR(s[0]))
{
if (!dirPrefix)
return false;
@@ -614,7 +769,7 @@ bool GetFullPath(CFSTR dirPrefix, CFSTR s, FString &res)
return true;
if (c == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)))
return true;
- if (c == CHAR_PATH_SEPARATOR && s[1] == CHAR_PATH_SEPARATOR)
+ if (IS_SEPAR(c) && IS_SEPAR(s[1]))
return true;
if (IsDrivePath(s))
return true;
@@ -628,8 +783,7 @@ bool GetFullPath(CFSTR dirPrefix, CFSTR s, FString &res)
if (!GetCurDir(curDir))
return false;
}
- if (!curDir.IsEmpty() && curDir.Back() != WCHAR_PATH_SEPARATOR)
- curDir += WCHAR_PATH_SEPARATOR;
+ NormalizeDirPathPrefix(curDir);
unsigned fixedSize = 0;
@@ -647,9 +801,9 @@ bool GetFullPath(CFSTR dirPrefix, CFSTR s, FString &res)
fixedSize = kDrivePrefixSize;
else
{
- if (curDir[0] != WCHAR_PATH_SEPARATOR || curDir[1] != WCHAR_PATH_SEPARATOR)
+ if (!IsPathSepar(curDir[0]) || !IsPathSepar(curDir[1]))
return false;
- fixedSize = GetRootPrefixSize_Of_NetworkPath(&curDir[2]);
+ fixedSize = GetRootPrefixSize_Of_NetworkPath(curDir.Ptr(2));
if (fixedSize == 0)
return false;
fixedSize += 2;
@@ -659,7 +813,7 @@ bool GetFullPath(CFSTR dirPrefix, CFSTR s, FString &res)
#endif // _WIN32
UString temp;
- if (s[0] == CHAR_PATH_SEPARATOR)
+ if (IS_SEPAR(s[0]))
{
temp = fs2us(s + 1);
}
diff --git a/CPP/Windows/FileName.h b/CPP/Windows/FileName.h
index 7455654..e2720ff 100644
--- a/CPP/Windows/FileName.h
+++ b/CPP/Windows/FileName.h
@@ -9,29 +9,70 @@ namespace NWindows {
namespace NFile {
namespace NName {
+int FindSepar(const wchar_t *s) throw();
+#ifndef USE_UNICODE_FSTRING
+int FindSepar(const FChar *s) throw();
+#endif
+
void NormalizeDirPathPrefix(FString &dirPath); // ensures that it ended with '\\', if dirPath is not epmty
void NormalizeDirPathPrefix(UString &dirPath);
-#ifdef _WIN32
+bool IsDrivePath(const wchar_t *s) throw(); // first 3 chars are drive chars like "a:\\"
+
+bool IsAltPathPrefix(CFSTR s) throw(); /* name: */
+
+#if defined(_WIN32) && !defined(UNDER_CE)
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 IsDevicePath(CFSTR s) throw(); /* \\.\ */
+bool IsSuperUncPath(CFSTR s) throw(); /* \\?\UNC\ */
+bool IsNetworkPath(CFSTR s) throw(); /* \\?\UNC\ or \\SERVER */
+
+/* GetNetworkServerPrefixSize() returns size of server prefix:
+ \\?\UNC\SERVER\
+ \\SERVER\
+ in another cases it returns 0
+*/
+
+unsigned GetNetworkServerPrefixSize(CFSTR s) throw();
-bool IsDrivePath(const wchar_t *s) throw();
+bool IsNetworkShareRootPath(CFSTR s) throw(); /* \\?\UNC\SERVER\share or \\SERVER\share or with slash */
+
+// bool IsDrivePath_SuperAllowed(CFSTR s) throw(); // first chars are drive chars like "a:\" or "\\?\a:\"
+bool IsDriveRootPath_SuperAllowed(CFSTR s) throw(); // exact drive root path "a:\" or "\\?\a:\"
+
+bool IsDrivePath2(const wchar_t *s) throw(); // first 2 chars are drive chars like "a:"
+// bool IsDriveName2(const wchar_t *s) throw(); // is drive name like "a:"
bool IsSuperPath(const wchar_t *s) throw();
bool IsSuperOrDevicePath(const wchar_t *s) throw();
#ifndef USE_UNICODE_FSTRING
+bool IsDrivePath2(CFSTR s) throw(); // first 2 chars are drive chars like "a:"
+// bool IsDriveName2(CFSTR s) throw(); // is drive name like "a:"
bool IsDrivePath(CFSTR s) throw();
bool IsSuperPath(CFSTR s) throw();
bool IsSuperOrDevicePath(CFSTR s) throw();
+
+/* GetRootPrefixSize() returns size of ROOT PREFIX for cases:
+ \
+ \\.\
+ C:\
+ \\?\C:\
+ \\?\UNC\SERVER\Shared\
+ \\SERVER\Shared\
+ in another cases it returns 0
+*/
+
+unsigned GetRootPrefixSize(CFSTR s) throw();
+
#endif
+int FindAltStreamColon(CFSTR path);
+
#endif // _WIN32
bool IsAbsolutePath(const wchar_t *s) throw();
@@ -44,7 +85,7 @@ const int kSuperPathType_UseOnlySuper = 1;
const int kSuperPathType_UseMainAndSuper = 2;
int GetUseSuperPathType(CFSTR s) throw();
-bool GetSuperPath(CFSTR path, UString &longPath, bool onlyIfNew);
+bool GetSuperPath(CFSTR path, UString &superPath, bool onlyIfNew);
bool GetSuperPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2, bool onlyIfNew);
#define USE_MAIN_PATH (__useSuperPathType != kSuperPathType_UseOnlySuper)
diff --git a/CPP/Windows/MemoryLock.cpp b/CPP/Windows/MemoryLock.cpp
index 559b6b0..7a2cfd5 100644
--- a/CPP/Windows/MemoryLock.cpp
+++ b/CPP/Windows/MemoryLock.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include "MemoryLock.h"
+
namespace NWindows {
namespace NSecurity {
diff --git a/CPP/Windows/MemoryLock.h b/CPP/Windows/MemoryLock.h
index 45c6bcb..1336fe5 100644
--- a/CPP/Windows/MemoryLock.h
+++ b/CPP/Windows/MemoryLock.h
@@ -3,12 +3,14 @@
#ifndef __WINDOWS_MEMORY_LOCK_H
#define __WINDOWS_MEMORY_LOCK_H
+#include "../Common/MyWindows.h"
+
namespace NWindows {
namespace NSecurity {
#ifndef UNDER_CE
- bool EnablePrivilege(LPCTSTR privilegeName, bool enable = true);
+bool EnablePrivilege(LPCTSTR privilegeName, bool enable = true);
inline bool EnablePrivilege_LockMemory(bool enable = true)
{
diff --git a/CPP/Windows/NtCheck.h b/CPP/Windows/NtCheck.h
index b8fa99b..401e239 100644
--- a/CPP/Windows/NtCheck.h
+++ b/CPP/Windows/NtCheck.h
@@ -5,6 +5,8 @@
#ifdef _WIN32
+#include "../Common/MyWindows.h"
+
#if !defined(_WIN64) && !defined(UNDER_CE)
static inline bool IsItWindowsNT()
{
diff --git a/CPP/Windows/PropVariant.cpp b/CPP/Windows/PropVariant.cpp
index 6ab0e00..6b3f20b 100644
--- a/CPP/Windows/PropVariant.cpp
+++ b/CPP/Windows/PropVariant.cpp
@@ -9,9 +9,23 @@
namespace NWindows {
namespace NCOM {
+BSTR AllocBstrFromAscii(const char *s) throw()
+{
+ if (!s)
+ return NULL;
+ UINT len = (UINT)strlen(s);
+ BSTR p = ::SysAllocStringLen(NULL, len);
+ if (p)
+ {
+ for (UINT i = 0; i <= len; i++)
+ p[i] = (Byte)s[i];
+ }
+ return p;
+}
+
HRESULT PropVarEm_Alloc_Bstr(PROPVARIANT *p, unsigned numChars) throw()
{
- p->bstrVal = ::SysAllocStringLen(0, numChars);
+ p->bstrVal = ::SysAllocStringLen(NULL, numChars);
if (!p->bstrVal)
{
p->vt = VT_ERROR;
@@ -24,19 +38,15 @@ HRESULT PropVarEm_Alloc_Bstr(PROPVARIANT *p, unsigned numChars) throw()
HRESULT PropVarEm_Set_Str(PROPVARIANT *p, const char *s) throw()
{
- UINT len = (UINT)strlen(s);
- p->bstrVal = ::SysAllocStringLen(0, len);
- if (!p->bstrVal)
+ p->bstrVal = AllocBstrFromAscii(s);
+ if (p->bstrVal)
{
- p->vt = VT_ERROR;
- p->scode = E_OUTOFMEMORY;
- return E_OUTOFMEMORY;
+ p->vt = VT_BSTR;
+ return S_OK;
}
- p->vt = VT_BSTR;
- BSTR dest = p->bstrVal;
- for (UINT i = 0; i <= len; i++)
- dest[i] = s[i];
- return S_OK;
+ p->vt = VT_ERROR;
+ p->scode = E_OUTOFMEMORY;
+ return E_OUTOFMEMORY;
}
CPropVariant::CPropVariant(const PROPVARIANT &varSrc)
@@ -68,6 +78,7 @@ CPropVariant& CPropVariant::operator=(const CPropVariant &varSrc)
InternalCopy(&varSrc);
return *this;
}
+
CPropVariant& CPropVariant::operator=(const PROPVARIANT &varSrc)
{
InternalCopy(&varSrc);
@@ -97,24 +108,60 @@ CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
return *this;
}
+CPropVariant& CPropVariant::operator=(const UString &s)
+{
+ InternalClear();
+ vt = VT_BSTR;
+ wReserved1 = 0;
+ bstrVal = ::SysAllocStringLen(s, s.Len());
+ if (!bstrVal)
+ throw kMemException;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(const UString2 &s)
+{
+ /*
+ if (s.IsEmpty())
+ *this = L"";
+ else
+ */
+ {
+ InternalClear();
+ vt = VT_BSTR;
+ wReserved1 = 0;
+ bstrVal = ::SysAllocStringLen(s.GetRawPtr(), s.Len());
+ if (!bstrVal)
+ throw kMemException;
+ /* SysAllocStringLen probably appends a null-terminating character for NULL string.
+ But it doesn't specified in MSDN.
+ But we suppose that it works
+
+ if (!s.GetRawPtr())
+ {
+ *bstrVal = 0;
+ }
+ */
+
+ /* MSDN: Windows CE: SysAllocStringLen() : Passing invalid (and under some circumstances NULL)
+ pointers to this function causes an unexpected termination of the application.
+ Is it safe? Maybe we must chamnge the code for that case ? */
+ }
+ return *this;
+}
+
CPropVariant& CPropVariant::operator=(const char *s)
{
InternalClear();
vt = VT_BSTR;
wReserved1 = 0;
- UINT len = (UINT)strlen(s);
- bstrVal = ::SysAllocStringLen(0, len);
+ bstrVal = AllocBstrFromAscii(s);
if (!bstrVal)
{
throw kMemException;
// vt = VT_ERROR;
// scode = E_OUTOFMEMORY;
}
- else
- {
- for (UINT i = 0; i <= len; i++)
- bstrVal[i] = s[i];
- }
return *this;
}
@@ -135,7 +182,7 @@ BSTR CPropVariant::AllocBstr(unsigned numChars)
InternalClear();
vt = VT_BSTR;
wReserved1 = 0;
- bstrVal = ::SysAllocStringLen(0, numChars);
+ bstrVal = ::SysAllocStringLen(NULL, numChars);
if (!bstrVal)
{
throw kMemException;
@@ -201,7 +248,7 @@ HRESULT CPropVariant::Clear() throw()
HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) throw()
{
::VariantClear((tagVARIANT *)this);
- switch(pSrc->vt)
+ switch (pSrc->vt)
{
case VT_UI1:
case VT_I1:
diff --git a/CPP/Windows/PropVariant.h b/CPP/Windows/PropVariant.h
index 4757705..0304565 100644
--- a/CPP/Windows/PropVariant.h
+++ b/CPP/Windows/PropVariant.h
@@ -5,10 +5,13 @@
#include "../Common/MyTypes.h"
#include "../Common/MyWindows.h"
+#include "../Common/MyString.h"
namespace NWindows {
namespace NCOM {
+BSTR AllocBstrFromAscii(const char *s) throw();
+
HRESULT PropVariant_Clear(PROPVARIANT *p) throw();
HRESULT PropVarEm_Alloc_Bstr(PROPVARIANT *p, unsigned numChars) throw();
@@ -57,7 +60,7 @@ public:
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(bool bSrc) { vt = VT_BOOL; wReserved1 = 0; boolVal = (bSrc ? VARIANT_TRUE : VARIANT_FALSE); }
CPropVariant(Byte value) { vt = VT_UI1; wReserved1 = 0; bVal = value; }
private:
@@ -74,6 +77,8 @@ public:
CPropVariant& operator=(const PROPVARIANT &varSrc);
CPropVariant& operator=(BSTR bstrSrc);
CPropVariant& operator=(LPCOLESTR lpszSrc);
+ CPropVariant& operator=(const UString &s);
+ CPropVariant& operator=(const UString2 &s);
CPropVariant& operator=(const char *s);
CPropVariant& operator=(bool bSrc) throw();
diff --git a/CPP/Windows/PropVariantConv.cpp b/CPP/Windows/PropVariantConv.cpp
index a9a0d97..1501a49 100644
--- a/CPP/Windows/PropVariantConv.cpp
+++ b/CPP/Windows/PropVariantConv.cpp
@@ -37,7 +37,17 @@ bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime, bool
UINT_TO_STR_2(' ', st.wHour);
UINT_TO_STR_2(':', st.wMinute);
if (includeSeconds)
+ {
UINT_TO_STR_2(':', st.wSecond);
+ /*
+ *s++ = '.';
+ unsigned val = st.wMilliseconds;
+ s[2] = (char)('0' + val % 10); val /= 10;
+ s[1] = (char)('0' + val % 10);
+ s[0] = (char)('0' + val / 10);
+ s += 3;
+ */
+ }
}
*s = 0;
return true;
@@ -93,7 +103,7 @@ void ConvertPropVariantToShortString(const PROPVARIANT &prop, wchar_t *dest) thr
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;
+ case VT_BOOL: dest[0] = VARIANT_BOOLToBool(prop.boolVal) ? (wchar_t)'+' : (wchar_t)'-'; dest[1] = 0; return;
default: dest[0] = '?'; dest[1] = ':'; ConvertUInt32ToString(prop.vt, dest + 2);
}
}
diff --git a/CPP/Windows/Registry.cpp b/CPP/Windows/Registry.cpp
index 8c3a751..71ca17f 100644
--- a/CPP/Windows/Registry.cpp
+++ b/CPP/Windows/Registry.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include <wchar.h>
+
#ifndef _UNICODE
#include "../Common/StringConvert.h"
#endif
@@ -75,15 +77,15 @@ LONG CKey::RecurseDeleteKey(LPCTSTR subKeyName) throw()
if (res != ERROR_SUCCESS)
return res;
FILETIME fileTime;
- const UInt32 kBufferSize = MAX_PATH + 1; // 256 in ATL
- DWORD size = kBufferSize;
- TCHAR buffer[kBufferSize];
+ const UInt32 kBufSize = MAX_PATH + 1; // 256 in ATL
+ DWORD size = kBufSize;
+ TCHAR buffer[kBufSize];
while (RegEnumKeyEx(key._object, 0, buffer, &size, NULL, NULL, NULL, &fileTime) == ERROR_SUCCESS)
{
res = key.RecurseDeleteKey(buffer);
if (res != ERROR_SUCCESS)
return res;
- size = kBufferSize;
+ size = kBufSize;
}
key.Close();
return DeleteSubKey(subKeyName);
@@ -226,7 +228,6 @@ LONG CKey::GetValue_IfOk(LPCTSTR name, bool &value) throw()
LONG CKey::QueryValue(LPCTSTR name, LPTSTR value, UInt32 &count) throw()
{
- MYASSERT(count != NULL);
DWORD type = 0;
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));
@@ -237,38 +238,47 @@ LONG CKey::QueryValue(LPCTSTR name, CSysString &value)
{
value.Empty();
DWORD type = 0;
- UInt32 currentSize = 0;
- LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, NULL, (DWORD *)&currentSize);
+ UInt32 curSize = 0;
+ LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, NULL, (DWORD *)&curSize);
if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
return res;
- res = QueryValue(name, value.GetBuffer(currentSize), currentSize);
- value.ReleaseBuffer();
+ UInt32 curSize2 = curSize;
+ res = QueryValue(name, value.GetBuf(curSize), curSize2);
+ if (curSize > curSize2)
+ curSize = curSize2;
+ value.ReleaseBuf_CalcLen(curSize / sizeof(TCHAR));
return res;
}
+
#ifndef _UNICODE
+
LONG CKey::QueryValue(LPCWSTR name, LPWSTR value, UInt32 &count)
{
- MYASSERT(count != NULL);
DWORD type = 0;
LONG res = RegQueryValueExW(_object, name, NULL, &type, (LPBYTE)value, (DWORD *)&count);
MYASSERT((res != ERROR_SUCCESS) || (type == REG_SZ) || (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));
return res;
}
+
LONG CKey::QueryValue(LPCWSTR name, UString &value)
{
value.Empty();
DWORD type = 0;
- UInt32 currentSize = 0;
+ UInt32 curSize = 0;
LONG res;
+
if (g_IsNT)
{
- res = RegQueryValueExW(_object, name, NULL, &type, NULL, (DWORD *)&currentSize);
+ res = RegQueryValueExW(_object, name, NULL, &type, NULL, (DWORD *)&curSize);
if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
return res;
- res = QueryValue(name, value.GetBuffer(currentSize), currentSize);
- value.ReleaseBuffer();
+ UInt32 curSize2 = curSize;
+ res = QueryValue(name, value.GetBuf(curSize), curSize2);
+ if (curSize > curSize2)
+ curSize = curSize2;
+ value.ReleaseBuf_CalcLen(curSize / sizeof(wchar_t));
}
else
{
@@ -276,10 +286,13 @@ LONG CKey::QueryValue(LPCWSTR name, UString &value)
res = QueryValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name), vTemp);
value = GetUnicodeString(vTemp);
}
+
return res;
}
+
#endif
+
LONG CKey::QueryValue(LPCTSTR name, void *value, UInt32 &count) throw()
{
DWORD type = 0;
@@ -304,14 +317,14 @@ LONG CKey::EnumKeys(CSysStringVector &keyNames)
{
keyNames.Clear();
CSysString keyName;
- for (UInt32 index = 0; ; index++)
+ for (DWORD index = 0; ; index++)
{
- const UInt32 kBufferSize = MAX_PATH + 1; // 256 in ATL
+ const unsigned kBufSize = MAX_PATH + 1; // 256 in ATL
FILETIME lastWriteTime;
- UInt32 nameSize = kBufferSize;
- LONG result = ::RegEnumKeyEx(_object, index, keyName.GetBuffer(kBufferSize),
+ UInt32 nameSize = kBufSize;
+ LONG result = ::RegEnumKeyEx(_object, index, keyName.GetBuf(kBufSize),
(DWORD *)&nameSize, NULL, NULL, NULL, &lastWriteTime);
- keyName.ReleaseBuffer();
+ keyName.ReleaseBuf_CalcLen(kBufSize);
if (result == ERROR_NO_MORE_ITEMS)
break;
if (result != ERROR_SUCCESS)
@@ -321,47 +334,56 @@ LONG CKey::EnumKeys(CSysStringVector &keyNames)
return ERROR_SUCCESS;
}
-LONG CKey::SetValue_Strings(LPCTSTR valueName, const UStringVector &strings) throw()
+LONG CKey::SetValue_Strings(LPCTSTR valueName, const UStringVector &strings)
{
- UInt32 numChars = 0;
+ size_t numChars = 0;
+
unsigned i;
+
for (i = 0; i < strings.Size(); i++)
numChars += strings[i].Len() + 1;
- CBuffer<wchar_t> buffer(numChars);
- unsigned pos = 0;
+
+ CObjArray<wchar_t> buffer(numChars);
+ size_t 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.Len() + 1;
+ size_t size = s.Len() + 1;
+ wmemcpy(buffer + pos, s, size);
+ pos += size;
}
- return SetValue(valueName, buffer, numChars * sizeof(wchar_t));
+ return SetValue(valueName, buffer, (UInt32)numChars * sizeof(wchar_t));
}
LONG CKey::GetValue_Strings(LPCTSTR valueName, UStringVector &strings)
{
strings.Clear();
CByteBuffer buffer;
- UInt32 dataSize;
+ UInt32 dataSize = 0;
LONG res = QueryValue(valueName, buffer, dataSize);
if (res != ERROR_SUCCESS)
return res;
+ if (dataSize > buffer.Size())
+ return E_FAIL;
if (dataSize % sizeof(wchar_t) != 0)
return E_FAIL;
+
const wchar_t *data = (const wchar_t *)(const Byte *)buffer;
- unsigned numChars = dataSize / sizeof(wchar_t);
+ size_t numChars = dataSize / sizeof(wchar_t);
+ size_t prev = 0;
UString s;
- for (unsigned i = 0; i < numChars; i++)
+
+ for (size_t i = 0; i < numChars; i++)
{
- wchar_t c = data[i];
- if (c == 0)
+ if (data[i] == 0)
{
+ s = data + prev;
strings.Add(s);
- s.Empty();
+ prev = i + 1;
}
- else
- s += c;
}
+
return res;
}
diff --git a/CPP/Windows/Registry.h b/CPP/Windows/Registry.h
index 4ac6662..0a31230 100644
--- a/CPP/Windows/Registry.h
+++ b/CPP/Windows/Registry.h
@@ -55,7 +55,7 @@ public:
LONG SetValue(LPCTSTR name, const void *value, UInt32 size) throw();
- LONG SetValue_Strings(LPCTSTR valueName, const UStringVector &strings) throw();
+ LONG SetValue_Strings(LPCTSTR valueName, const UStringVector &strings);
LONG GetValue_Strings(LPCTSTR valueName, UStringVector &strings);
LONG SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value) throw();
diff --git a/CPP/Windows/ResourceString.cpp b/CPP/Windows/ResourceString.cpp
index d20e713..c28e60e 100644
--- a/CPP/Windows/ResourceString.cpp
+++ b/CPP/Windows/ResourceString.cpp
@@ -25,10 +25,10 @@ static CSysString MyLoadStringA(HINSTANCE hInstance, UINT resourceID)
do
{
size <<= 1;
- len = ::LoadString(hInstance, resourceID, s.GetBuffer(size - 1), size);
+ len = ::LoadString(hInstance, resourceID, s.GetBuf(size - 1), size);
}
while (size - len <= 1);
- s.ReleaseBuffer();
+ s.ReleaseBuf_CalcLen(len);
return s;
}
@@ -43,10 +43,10 @@ static void MyLoadString2(HINSTANCE hInstance, UINT resourceID, UString &s)
do
{
size <<= 1;
- len = ::LoadStringW(hInstance, resourceID, s.GetBuffer(size - 1), size);
+ len = ::LoadStringW(hInstance, resourceID, s.GetBuf(size - 1), size);
}
while (size - len <= 1);
- s.ReleaseBuffer();
+ s.ReleaseBuf_CalcLen(len);
}
// NT4 doesn't support LoadStringW(,,, 0) to get pointer to resource string. So we don't use it.
diff --git a/CPP/Windows/SecurityUtils.cpp b/CPP/Windows/SecurityUtils.cpp
index 69ef32c..8646cc9 100644
--- a/CPP/Windows/SecurityUtils.cpp
+++ b/CPP/Windows/SecurityUtils.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include "../Common/MyString.h"
+
#include "SecurityUtils.h"
namespace NWindows {
@@ -14,17 +16,18 @@ bool MyLookupAccountSid(LPCTSTR systemName, PSID sid,
DWORD accountNameSize = 0, domainNameSize = 0;
if (!::LookupAccountSid(systemName, sid,
- accountName.GetBuffer(0), &accountNameSize,
- domainName.GetBuffer(0), &domainNameSize, sidNameUse))
+ accountName.GetBuf(0), &accountNameSize,
+ domainName.GetBuf(0), &domainNameSize, sidNameUse))
{
if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return false;
}
+ DWORD accountNameSize2 = accountNameSize, domainNameSize2 = domainNameSize;
bool result = BOOLToBool(::LookupAccountSid(systemName, sid,
- accountName.GetBuffer(accountNameSize), &accountNameSize,
- domainName.GetBuffer(domainNameSize), &domainNameSize, sidNameUse));
- accountName.ReleaseBuffer();
- domainName.ReleaseBuffer();
+ accountName.GetBuf(accountNameSize), &accountNameSize2,
+ domainName.GetBuf(domainNameSize), &domainNameSize2, sidNameUse));
+ accountName.ReleaseBuf_CalcLen(accountNameSize);
+ domainName.ReleaseBuf_CalcLen(domainNameSize);
return result;
}
*/
@@ -176,4 +179,3 @@ bool AddLockMemoryPrivilege()
}
}}
-
diff --git a/CPP/Windows/Shell.cpp b/CPP/Windows/Shell.cpp
index d5d61a9..b3df199 100644
--- a/CPP/Windows/Shell.cpp
+++ b/CPP/Windows/Shell.cpp
@@ -95,16 +95,18 @@ UString CDrop::QueryFileName(UINT fileIndex)
{
AString fileNameA;
UINT bufferSize = QueryFile(fileIndex, (LPTSTR)NULL, 0);
- QueryFile(fileIndex, fileNameA.GetBuffer(bufferSize + 2), bufferSize + 1);
- fileNameA.ReleaseBuffer();
+ const unsigned len = bufferSize + 2;
+ QueryFile(fileIndex, fileNameA.GetBuf(len), bufferSize + 1);
+ fileNameA.ReleaseBuf_CalcLen(len);
fileName = GetUnicodeString(fileNameA);
}
else
#endif
{
UINT bufferSize = QueryFile(fileIndex, (LPWSTR)NULL, 0);
- QueryFile(fileIndex, fileName.GetBuffer(bufferSize + 2), bufferSize + 1);
- fileName.ReleaseBuffer();
+ const unsigned len = bufferSize + 2;
+ QueryFile(fileIndex, fileName.GetBuf(len), bufferSize + 1);
+ fileName.ReleaseBuf_CalcLen(len);
}
return fileName;
}
@@ -120,8 +122,9 @@ void CDrop::QueryFileNames(UStringVector &fileNames)
bool GetPathFromIDList(LPCITEMIDLIST itemIDList, CSysString &path)
{
- bool result = BOOLToBool(::SHGetPathFromIDList(itemIDList, path.GetBuffer(MAX_PATH * 2)));
- path.ReleaseBuffer();
+ const unsigned len = MAX_PATH * 2;
+ bool result = BOOLToBool(::SHGetPathFromIDList(itemIDList, path.GetBuf(len)));
+ path.ReleaseBuf_CalcLen(len);
return result;
}
@@ -174,7 +177,7 @@ bool BrowseForFolder(LPBROWSEINFO browseInfo, CSysString &resultPath)
int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM /* lp */, LPARAM data)
{
#ifndef UNDER_CE
- switch(uMsg)
+ switch (uMsg)
{
case BFFM_INITIALIZED:
{
@@ -208,14 +211,16 @@ bool BrowseForFolder(HWND owner, LPCTSTR title, UINT ulFlags,
browseInfo.hwndOwner = owner;
browseInfo.pidlRoot = NULL;
- // there are Unicode/astring problems in WinCE SDK!!!
+ // there are Unicode/Astring problems in some WinCE SDK ?
+ /*
#ifdef UNDER_CE
- browseInfo.pszDisplayName = (LPSTR)displayName.GetBuffer(MAX_PATH);
+ browseInfo.pszDisplayName = (LPSTR)displayName.GetBuf(MAX_PATH);
browseInfo.lpszTitle = (LPCSTR)title;
#else
- browseInfo.pszDisplayName = displayName.GetBuffer(MAX_PATH);
+ */
+ browseInfo.pszDisplayName = displayName.GetBuf(MAX_PATH);
browseInfo.lpszTitle = title;
- #endif
+ // #endif
browseInfo.ulFlags = ulFlags;
browseInfo.lpfn = (initialFolder != NULL) ? BrowseCallbackProc : NULL;
browseInfo.lParam = (LPARAM)initialFolder;
@@ -244,8 +249,9 @@ bool GetPathFromIDList(LPCITEMIDLIST itemIDList, UString &path)
::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHGetPathFromIDListW");
if (shGetPathFromIDListW == 0)
return false;
- bool result = BOOLToBool(shGetPathFromIDListW(itemIDList, path.GetBuffer(MAX_PATH * 2)));
- path.ReleaseBuffer();
+ const unsigned len = MAX_PATH * 2;
+ bool result = BOOLToBool(shGetPathFromIDListW(itemIDList, path.GetBuf(len)));
+ path.ReleaseBuf_CalcLen(len);
return result;
}
@@ -269,7 +275,7 @@ bool BrowseForFolder(LPBROWSEINFOW browseInfo, UString &resultPath)
int CALLBACK BrowseCallbackProc2(HWND hwnd, UINT uMsg, LPARAM /* lp */, LPARAM data)
{
- switch(uMsg)
+ switch (uMsg)
{
case BFFM_INITIALIZED:
{
@@ -302,7 +308,7 @@ static bool BrowseForFolder(HWND owner, LPCWSTR title, UINT ulFlags,
BROWSEINFOW browseInfo;
browseInfo.hwndOwner = owner;
browseInfo.pidlRoot = NULL;
- browseInfo.pszDisplayName = displayName.GetBuffer(MAX_PATH);
+ browseInfo.pszDisplayName = displayName.GetBuf(MAX_PATH);
browseInfo.lpszTitle = title;
browseInfo.ulFlags = ulFlags;
browseInfo.lpfn = (initialFolder != NULL) ? BrowseCallbackProc2 : NULL;
diff --git a/CPP/Windows/System.cpp b/CPP/Windows/System.cpp
index 545ea0e..5d894d1 100644
--- a/CPP/Windows/System.cpp
+++ b/CPP/Windows/System.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include "../Common/MyWindows.h"
+
#include "../Common/Defs.h"
#include "System.h"
@@ -9,6 +11,8 @@
namespace NWindows {
namespace NSystem {
+#ifdef _WIN32
+
UInt32 GetNumberOfProcessors()
{
SYSTEM_INFO systemInfo;
@@ -16,6 +20,18 @@ UInt32 GetNumberOfProcessors()
return (UInt32)systemInfo.dwNumberOfProcessors;
}
+#else
+
+UInt32 GetNumberOfProcessors()
+{
+ return 1;
+}
+
+#endif
+
+
+#ifdef _WIN32
+
#ifndef UNDER_CE
#if !defined(_WIN64) && defined(__GNUC__)
@@ -43,29 +59,53 @@ typedef BOOL (WINAPI *GlobalMemoryStatusExP)(MY_LPMEMORYSTATUSEX lpBuffer);
#endif
-UInt64 GetRamSize()
+#endif
+
+
+bool GetRamSize(UInt64 &size)
{
+ size = (UInt64)(sizeof(size_t)) << 29;
+
+ #ifdef _WIN32
+
#ifndef UNDER_CE
- MY_MEMORYSTATUSEX stat;
- stat.dwLength = sizeof(stat);
+ MY_MEMORYSTATUSEX stat;
+ stat.dwLength = sizeof(stat);
#endif
+
#ifdef _WIN64
- if (!::GlobalMemoryStatusEx(&stat))
- return 0;
- return MyMin(stat.ullTotalVirtual, stat.ullTotalPhys);
+
+ if (!::GlobalMemoryStatusEx(&stat))
+ return false;
+ size = MyMin(stat.ullTotalVirtual, stat.ullTotalPhys);
+ return true;
+
#else
- #ifndef UNDER_CE
- GlobalMemoryStatusExP globalMemoryStatusEx = (GlobalMemoryStatusExP)
- ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")), "GlobalMemoryStatusEx");
- if (globalMemoryStatusEx != 0 && globalMemoryStatusEx(&stat))
- return MyMin(stat.ullTotalVirtual, stat.ullTotalPhys);
+
+ #ifndef UNDER_CE
+ GlobalMemoryStatusExP globalMemoryStatusEx = (GlobalMemoryStatusExP)
+ ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")), "GlobalMemoryStatusEx");
+ if (globalMemoryStatusEx && globalMemoryStatusEx(&stat))
+ {
+ size = MyMin(stat.ullTotalVirtual, stat.ullTotalPhys);
+ return true;
+ }
+ #endif
+
+ {
+ MEMORYSTATUS stat2;
+ stat2.dwLength = sizeof(stat2);
+ ::GlobalMemoryStatus(&stat2);
+ size = MyMin(stat2.dwTotalVirtual, stat2.dwTotalPhys);
+ return true;
+ }
+
#endif
- {
- MEMORYSTATUS stat;
- stat.dwLength = sizeof(stat);
- ::GlobalMemoryStatus(&stat);
- return MyMin(stat.dwTotalVirtual, stat.dwTotalPhys);
- }
+
+ #else
+
+ return false;
+
#endif
}
diff --git a/CPP/Windows/System.h b/CPP/Windows/System.h
index 78a5e1d..845362f 100644
--- a/CPP/Windows/System.h
+++ b/CPP/Windows/System.h
@@ -9,7 +9,8 @@ namespace NWindows {
namespace NSystem {
UInt32 GetNumberOfProcessors();
-UInt64 GetRamSize();
+
+bool GetRamSize(UInt64 &size); // returns false, if unknown ram size
}}
diff --git a/CPP/Windows/TimeUtils.h b/CPP/Windows/TimeUtils.h
index 0b1f11f..011d2f5 100644
--- a/CPP/Windows/TimeUtils.h
+++ b/CPP/Windows/TimeUtils.h
@@ -4,6 +4,7 @@
#define __WINDOWS_TIME_UTILS_H
#include "../Common/MyTypes.h"
+#include "../Common/MyWindows.h"
namespace NWindows {
namespace NTime {
diff --git a/CPP/Windows/Window.cpp b/CPP/Windows/Window.cpp
index 98b0630..0c74222 100644
--- a/CPP/Windows/Window.cpp
+++ b/CPP/Windows/Window.cpp
@@ -114,13 +114,18 @@ bool MySetWindowText(HWND wnd, LPCWSTR s)
bool CWindow::GetText(CSysString &s)
{
s.Empty();
- int length = GetTextLength();
- if (length == 0)
+ int len = GetTextLength();
+ if (len == 0)
+ return (::GetLastError() == ERROR_SUCCESS);
+ TCHAR *p = s.GetBuf(len);
+ {
+ int len2 = GetText(p, len + 1);
+ if (len > len2)
+ len = len2;
+ }
+ s.ReleaseBuf_CalcLen(len);
+ if (len == 0)
return (::GetLastError() == ERROR_SUCCESS);
- length = GetText(s.GetBuffer(length), length + 1);
- s.ReleaseBuffer();
- if (length == 0)
- return (::GetLastError() != ERROR_SUCCESS);
return true;
}
@@ -130,18 +135,23 @@ bool CWindow::GetText(UString &s)
if (g_IsNT)
{
s.Empty();
- int length = GetWindowTextLengthW(_window);
- if (length == 0)
+ int len = GetWindowTextLengthW(_window);
+ if (len == 0)
return (::GetLastError() == ERROR_SUCCESS);
- length = GetWindowTextW(_window, s.GetBuffer(length), length + 1);
- s.ReleaseBuffer();
- if (length == 0)
+ wchar_t *p = s.GetBuf(len);
+ {
+ int len2 = GetWindowTextW(_window, p, len + 1);
+ if (len > len2)
+ len = len2;
+ }
+ s.ReleaseBuf_CalcLen(len);
+ if (len == 0)
return (::GetLastError() == ERROR_SUCCESS);
return true;
}
CSysString sysString;
bool result = GetText(sysString);
- s = GetUnicodeString(sysString);
+ MultiByteToUnicodeString2(s, sysString);
return result;
}
#endif
diff --git a/CPP/Windows/Window.h b/CPP/Windows/Window.h
index 3db239d..4c80a5b 100644
--- a/CPP/Windows/Window.h
+++ b/CPP/Windows/Window.h
@@ -3,6 +3,7 @@
#ifndef __WINDOWS_WINDOW_H
#define __WINDOWS_WINDOW_H
+#include "../Common/MyWindows.h"
#include "../Common/MyString.h"
#include "Defs.h"
@@ -170,7 +171,7 @@ public:
bool Update() { return BOOLToBool(::UpdateWindow(_window)); }
bool InvalidateRect(LPCRECT rect, bool backgroundErase = true)
{ return BOOLToBool(::InvalidateRect(_window, rect, BoolToBOOL(backgroundErase))); }
- void SetRedraw(bool redraw = true) { SendMessage(WM_SETREDRAW, BoolToBOOL(redraw), 0); }
+ void SetRedraw(bool redraw = true) { SendMsg(WM_SETREDRAW, BoolToBOOL(redraw), 0); }
LONG_PTR SetStyle(LONG_PTR style) { return SetLongPtr(GWL_STYLE, style); }
LONG_PTR GetStyle() const { return GetLongPtr(GWL_STYLE); }
@@ -222,18 +223,18 @@ public:
HWND SetFocus() { return ::SetFocus(_window); }
- LRESULT SendMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
- { return ::SendMessage(_window, message, wParam, lParam) ;}
+ LRESULT SendMsg(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
+ { return ::SendMessage(_window, message, wParam, lParam); }
#ifndef _UNICODE
- LRESULT SendMessageW(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
- { return ::SendMessageW(_window, message, wParam, lParam) ;}
+ LRESULT SendMsgW(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
+ { return ::SendMessageW(_window, message, wParam, lParam); }
#endif
- bool PostMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
- { return BOOLToBool(::PostMessage(_window, message, wParam, lParam)) ;}
+ bool PostMsg(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
+ { return BOOLToBool(::PostMessage(_window, message, wParam, lParam)); }
#ifndef _UNICODE
- LRESULT PostMessageW(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
- { return ::PostMessageW(_window, message, wParam, lParam) ;}
+ bool PostMsgW(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
+ { return BOOLToBool(::PostMessageW(_window, message, wParam, lParam)); }
#endif
bool SetText(LPCTSTR s) { return BOOLToBool(::SetWindowText(_window, s)); }
@@ -270,7 +271,7 @@ public:
bool KillTimer(UINT_PTR idEvent)
{return BOOLToBool(::KillTimer(_window, idEvent)); }
- HICON SetIcon(WPARAM sizeType, HICON icon) { return (HICON)SendMessage(WM_SETICON, sizeType, (LPARAM)icon); }
+ HICON SetIcon(WPARAM sizeType, HICON icon) { return (HICON)SendMsg(WM_SETICON, sizeType, (LPARAM)icon); }
};
#define RECT_SIZE_X(r) ((r).right - (r).left)