This commit is contained in:
Igor Pavlov
2015-06-15 00:00:00 +00:00
committed by Kornel Lesiński
parent 0713a3ab80
commit 54490d51d5
591 changed files with 34932 additions and 16390 deletions
+5 -5
View File
@@ -14,11 +14,11 @@ namespace NCOM {
UString GUIDToStringW(REFGUID guid)
{
UString string;
const int kStringSize = 48;
StringFromGUID2(guid, string.GetBuffer(kStringSize), kStringSize);
string.ReleaseBuffer();
return string;
UString s;
const unsigned kSize = 48;
StringFromGUID2(guid, s.GetBuf(kSize), kSize);
s.ReleaseBuf_CalcLen(kSize);
return s;
}
AString GUIDToStringA(REFGUID guid)
+3 -1
View File
@@ -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
*/
}}
+1 -1
View File
@@ -13,7 +13,7 @@ class CBase
protected:
HANDLE m_Object;
public:
void Attach(HANDLE handle) { m_Object = handle; };
void Attach(HANDLE handle) { m_Object = handle; }
bool GetMode(DWORD &mode)
{ return BOOLToBool(::GetConsoleMode(m_Object, &mode)); }
bool SetMode(DWORD mode)
+13 -5
View File
@@ -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;
}
@@ -42,8 +46,12 @@ LRESULT CComboBox::GetLBText(int index, UString &s)
LRESULT len = SendMessageW(CB_GETLBTEXTLEN, index, 0);
if (len == CB_ERR)
return len;
len = SendMessageW(CB_GETLBTEXT, index, (LPARAM)s.GetBuffer((int)len + 1));
s.ReleaseBuffer();
LRESULT len2 = SendMessageW(CB_GETLBTEXT, index, (LPARAM)s.GetBuf((unsigned)len));
if (len2 == CB_ERR)
return len;
if (len > len2)
len = len2;
s.ReleaseBuf_CalcLen(len);
return len;
}
AString sa;
+2 -2
View File
@@ -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() {};
+1 -1
View File
@@ -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() {};
+1 -1
View File
@@ -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);
+8 -2
View File
@@ -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)
{
+12 -7
View File
@@ -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;
}
}}
+154 -47
View File
@@ -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;
}
const FString pathName2 = pathName;
pos = pathName.Len();
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
}
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;
pathName.DeleteFrom(pos);
if (prefixSize >= (unsigned)pos + 1)
return false;
#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)
+7
View File
@@ -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);
+236 -81
View File
@@ -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,32 @@ 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_FILE_NOT_FOUND
\\?\UNC\Server\Share - ERROR_INVALID_NAME
\\?\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 +164,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 +216,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 +272,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 +283,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 +333,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 +344,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
static int FindAltStreamColon(CFSTR path)
\ - OK
C:\ - OK, if there is such drive,
D:\ - ERROR_PATH_NOT_FOUND, if there is no such drive,
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 +445,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] == '\\'))
{
// if (IsDir())
Attrib &= ~FILE_ATTRIBUTE_DIRECTORY;
// 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)
{
Attrib &= ~(FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
Size = 0;
CStreamEnumerator enumerator(filePath);
for (;;)
@@ -373,10 +489,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;
@@ -390,7 +508,8 @@ bool CFileInfo::Find(CFSTR path)
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 ||
@@ -398,33 +517,68 @@ bool CFileInfo::Find(CFSTR path)
lastError == ERROR_INVALID_NAME // for "\\SERVER\shared" paths that are translated to "\\?\UNC\SERVER\shared"
)
{
unsigned len = MyStringLen(path);
if (len > 2 && path[0] == '\\' && path[1] == '\\')
unsigned rootSize = 0;
if (IsSuperPath(path))
rootSize = kSuperPathPrefixSize;
if (IS_PATH_SEPAR(path[0]) && path[1] == 0)
{
int startPos = 2;
if (len > kSuperUncPathPrefixSize && IsSuperUncPath(path))
startPos = kSuperUncPathPrefixSize;
int pos = FindCharPosInString(path + startPos, FTEXT('\\'));
if (pos >= 0)
DWORD attrib = GetFileAttrib(path);
if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0)
{
pos += startPos + 1;
len -= pos;
int pos2 = FindCharPosInString(path + pos, FTEXT('\\'));
if (pos2 < 0 || pos2 == (int)len - 1)
ClearBase();
Name.Empty();
Attrib = attrib;
return true;
}
}
else if (NName::IsDrivePath(path + rootSize) && path[rootSize + 3] == 0)
{
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
{
unsigned prefixSize = GetNetworkServerPrefixSize(path);
if (prefixSize > 0 && path[prefixSize] != 0)
{
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);
}
}
@@ -432,6 +586,7 @@ bool CFileInfo::Find(CFSTR path)
}
}
#endif
return false;
}
@@ -446,12 +601,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 +666,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 +687,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 +710,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;
}
}
+7 -4
View File
@@ -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;
+1 -1
View File
@@ -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;
}
+16 -6
View File
@@ -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
+217 -75
View File
@@ -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')
#ifdef _WIN32
bool IsDrivePath(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && IS_SEPAR(s[2]); }
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 IsDrivePath(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == '\\'; }
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)); }
#ifndef USE_UNICODE_FSTRING
bool IsDrivePath(CFSTR s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && 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 IsAbsolutePath(const wchar_t *s) throw()
bool IsNetworkPath(CFSTR s) throw()
{
return s[0] == WCHAR_PATH_SEPARATOR || IsDrivePath(s);
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;
}
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) throw() { return (IS_SUPER_PREFIX(s) && IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)); }
#ifndef USE_UNICODE_FSTRING
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 IS_SEPAR(s[0]) || IsDrivePath2(s);
}
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,26 +372,26 @@ 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];
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];
if (c1 == '.')
{
wchar_t c2 = s[i + 2];
if (c2 == WCHAR_PATH_SEPARATOR || c2 == 0)
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)
if (IS_SEPAR(s[(unsigned)k]))
break;
unsigned num;
if (k >= 0)
@@ -272,7 +410,7 @@ static bool ResolveDotsFolders(UString &s)
}
else
{
if (c1 == WCHAR_PATH_SEPARATOR || c1 == 0)
if (IS_SEPAR(c1) || c1 == 0)
{
unsigned num = 2;
if (i != 0)
@@ -308,11 +446,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 +498,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 +569,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 +592,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 +612,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 +632,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 +643,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 +727,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 +757,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 +771,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 +789,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 +801,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);
}
+46 -5
View File
@@ -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 */
bool IsDrivePath(const wchar_t *s) throw();
/* GetNetworkServerPrefixSize() returns size of server prefix:
\\?\UNC\SERVER\
\\SERVER\
in another cases it returns 0
*/
unsigned GetNetworkServerPrefixSize(CFSTR 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)
+1 -1
View File
@@ -12,7 +12,7 @@ class CGlobal
public:
CGlobal(): _global(NULL){};
~CGlobal() { Free(); }
operator HGLOBAL() const { return _global; };
operator HGLOBAL() const { return _global; }
void Attach(HGLOBAL hGlobal)
{
Free();
+6 -2
View File
@@ -81,14 +81,18 @@ public:
HMENU GetSubMenu(int pos) { return ::GetSubMenu(_menu, pos); }
#ifndef UNDER_CE
/*
bool GetItemString(UINT idItem, UINT flag, CSysString &result)
{
result.Empty();
int len = ::GetMenuString(_menu, idItem, 0, 0, flag);
len = ::GetMenuString(_menu, idItem, result.GetBuffer(len + 2), len + 1, flag);
result.ReleaseBuffer();
int len2 = ::GetMenuString(_menu, idItem, result.GetBuf(len + 2), len + 1, flag);
if (len > len2)
len = len2;
result.ReleaseBuf_CalcLen(len + 2);
return (len != 0);
}
*/
UINT GetItemID(int pos) { return ::GetMenuItemID(_menu, pos); }
UINT GetItemState(UINT id, UINT flags) { return ::GetMenuState(_menu, id, flags); }
#endif
+4 -4
View File
@@ -16,8 +16,8 @@ bool MyGetTimeFormat(LCID locale, DWORD flags, CONST SYSTEMTIME *time,
if (numChars == 0)
return false;
numChars = ::GetTimeFormat(locale, flags, time, format,
resultString.GetBuffer(numChars), numChars + 1);
resultString.ReleaseBuffer();
resultString.GetBuf(numChars), numChars + 1);
resultString.ReleaseBuf_CalcLen(numChars);
return (numChars != 0);
}
@@ -29,8 +29,8 @@ bool MyGetDateFormat(LCID locale, DWORD flags, CONST SYSTEMTIME *time,
if (numChars == 0)
return false;
numChars = ::GetDateFormat(locale, flags, time, format,
resultString.GetBuffer(numChars), numChars + 1);
resultString.ReleaseBuffer();
resultString.GetBuf(numChars), numChars + 1);
resultString.ReleaseBuf_CalcLen(numChars);
return (numChars != 0);
}
+6 -6
View File
@@ -65,9 +65,9 @@ public:
{ return ::GetModuleBaseName(_handle, hModule, baseName, size); }
bool MyGetModuleBaseName(HMODULE hModule, CSysString &name)
{
const int length = 1000;
DWORD resultLen = MyGetModuleBaseName(hModule, name.GetBuffer(length), length);
name.ReleaseBuffer();
const unsigned len = MAX_PATH + 100;
DWORD resultLen = MyGetModuleBaseName(hModule, name.GetBuf(len), len);
name.ReleaseBuf_CalcLen(len);
return (resultLen != 0);
}
@@ -75,9 +75,9 @@ public:
{ return ::GetModuleFileNameEx(_handle, hModule, baseName, size); }
bool MyGetModuleFileNameEx(HMODULE hModule, CSysString &name)
{
const int length = MAX_PATH + 100;
DWORD resultLen = MyGetModuleFileNameEx(hModule, name.GetBuffer(length), length);
name.ReleaseBuffer();
const unsigned len = MAX_PATH + 100;
DWORD resultLen = MyGetModuleFileNameEx(hModule, name.GetBuf(len), len);
name.ReleaseBuf_CalcLen(len);
return (resultLen != 0);
}
+45 -2
View File
@@ -35,7 +35,7 @@ HRESULT PropVarEm_Set_Str(PROPVARIANT *p, const char *s) throw()
p->vt = VT_BSTR;
BSTR dest = p->bstrVal;
for (UINT i = 0; i <= len; i++)
dest[i] = s[i];
dest[i] = (Byte)s[i];
return S_OK;
}
@@ -97,6 +97,48 @@ 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();
@@ -112,8 +154,9 @@ CPropVariant& CPropVariant::operator=(const char *s)
}
else
{
BSTR dest = bstrVal;
for (UINT i = 0; i <= len; i++)
bstrVal[i] = s[i];
dest[i] = (Byte)s[i];
}
return *this;
}
+4 -1
View File
@@ -5,6 +5,7 @@
#include "../Common/MyTypes.h"
#include "../Common/MyWindows.h"
#include "../Common/MyString.h"
namespace NWindows {
namespace NCOM {
@@ -57,7 +58,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 +75,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();
+1 -1
View File
@@ -93,7 +93,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);
}
}
+3 -3
View File
@@ -37,20 +37,20 @@ void PairToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 value, NCOM:
}
AString TypeToString(const char *table[], unsigned num, UInt32 value)
AString TypeToString(const char * const table[], unsigned num, UInt32 value)
{
if (value < num)
return table[value];
return GetHex(value);
}
void TypeToProp(const char *table[], unsigned num, UInt32 value, NCOM::CPropVariant &prop)
void TypeToProp(const char * const table[], unsigned num, UInt32 value, NCOM::CPropVariant &prop)
{
prop = TypeToString(table, num, value);
}
AString FlagsToString(const char **names, unsigned num, UInt32 flags)
AString FlagsToString(const char * const *names, unsigned num, UInt32 flags)
{
AString s;
for (unsigned i = 0; i < num; i++)
+3 -3
View File
@@ -16,12 +16,12 @@ struct CUInt32PCharPair
AString TypePairToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 value);
void PairToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 value, NWindows::NCOM::CPropVariant &prop);
AString FlagsToString(const char **names, unsigned num, UInt32 flags);
AString FlagsToString(const char * const *names, unsigned num, UInt32 flags);
AString FlagsToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags);
void FlagsToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags, NWindows::NCOM::CPropVariant &prop);
AString TypeToString(const char *table[], unsigned num, UInt32 value);
void TypeToProp(const char *table[], unsigned num, UInt32 value, NWindows::NCOM::CPropVariant &prop);
AString TypeToString(const char * const table[], unsigned num, UInt32 value);
void TypeToProp(const char * const table[], unsigned num, UInt32 value, NWindows::NCOM::CPropVariant &prop);
#define PAIR_TO_PROP(pairs, value, prop) PairToProp(pairs, ARRAY_SIZE(pairs), value, prop)
#define FLAGS_TO_PROP(pairs, value, prop) FlagsToProp(pairs, ARRAY_SIZE(pairs), value, prop)
+56 -34
View File
@@ -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;
}
+1 -1
View File
@@ -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();
+4 -4
View File
@@ -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.
+9 -6
View File
@@ -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;
}
*/
+19 -13
View File
@@ -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;
}
@@ -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;
}
@@ -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;
+22 -12
View File
@@ -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