mirror of
https://github.com/love2d/love-android.git
synced 2026-08-21 05:00:22 +02:00
added dependencies and build files (loosely inspired by Sebastian Dorda's love-native-android)
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
// Windows/DLL.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "DLL.h"
|
||||
#include "Defs.h"
|
||||
#ifndef _UNICODE
|
||||
#include "../Common/StringConvert.h"
|
||||
#endif
|
||||
|
||||
#ifndef _UNICODE
|
||||
extern bool g_IsNT;
|
||||
#endif
|
||||
|
||||
namespace NWindows {
|
||||
namespace NDLL {
|
||||
|
||||
CLibrary::~CLibrary()
|
||||
{
|
||||
Free();
|
||||
}
|
||||
|
||||
bool CLibrary::Free()
|
||||
{
|
||||
if (_module == 0)
|
||||
return true;
|
||||
// MessageBox(0, TEXT(""), TEXT("Free"), 0);
|
||||
// Sleep(5000);
|
||||
if (!::FreeLibrary(_module))
|
||||
return false;
|
||||
_module = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CLibrary::LoadOperations(HMODULE newModule)
|
||||
{
|
||||
if (newModule == NULL)
|
||||
return false;
|
||||
if(!Free())
|
||||
return false;
|
||||
_module = newModule;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CLibrary::LoadEx(LPCTSTR fileName, DWORD flags)
|
||||
{
|
||||
// MessageBox(0, fileName, TEXT("LoadEx"), 0);
|
||||
return LoadOperations(::LoadLibraryEx(fileName, NULL, flags));
|
||||
}
|
||||
|
||||
bool CLibrary::Load(LPCTSTR fileName)
|
||||
{
|
||||
// MessageBox(0, fileName, TEXT("Load"), 0);
|
||||
// Sleep(5000);
|
||||
// OutputDebugString(fileName);
|
||||
// OutputDebugString(TEXT("\n"));
|
||||
return LoadOperations(::LoadLibrary(fileName));
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
|
||||
CSysString GetSysPath(LPCWSTR sysPath)
|
||||
{ return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); }
|
||||
|
||||
bool CLibrary::LoadEx(LPCWSTR fileName, DWORD flags)
|
||||
{
|
||||
if (g_IsNT)
|
||||
return LoadOperations(::LoadLibraryExW(fileName, NULL, flags));
|
||||
return LoadEx(GetSysPath(fileName), flags);
|
||||
}
|
||||
bool CLibrary::Load(LPCWSTR fileName)
|
||||
{
|
||||
if (g_IsNT)
|
||||
return LoadOperations(::LoadLibraryW(fileName));
|
||||
return Load(GetSysPath(fileName));
|
||||
}
|
||||
#endif
|
||||
|
||||
bool MyGetModuleFileName(HMODULE hModule, CSysString &result)
|
||||
{
|
||||
result.Empty();
|
||||
TCHAR fullPath[MAX_PATH + 2];
|
||||
DWORD size = ::GetModuleFileName(hModule, fullPath, MAX_PATH + 1);
|
||||
if (size <= MAX_PATH && size != 0)
|
||||
{
|
||||
result = fullPath;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool MyGetModuleFileName(HMODULE hModule, UString &result)
|
||||
{
|
||||
result.Empty();
|
||||
if (g_IsNT)
|
||||
{
|
||||
wchar_t fullPath[MAX_PATH + 2];
|
||||
DWORD size = ::GetModuleFileNameW(hModule, fullPath, MAX_PATH + 1);
|
||||
if (size <= MAX_PATH && size != 0)
|
||||
{
|
||||
result = fullPath;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
CSysString resultSys;
|
||||
if (!MyGetModuleFileName(hModule, resultSys))
|
||||
return false;
|
||||
result = MultiByteToUnicodeString(resultSys, GetCurrentCodePage());
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,54 @@
|
||||
// Windows/DLL.h
|
||||
|
||||
#ifndef __WINDOWS_DLL_H
|
||||
#define __WINDOWS_DLL_H
|
||||
|
||||
#include "../Common/MyString.h"
|
||||
|
||||
namespace NWindows {
|
||||
namespace NDLL {
|
||||
|
||||
class CLibrary
|
||||
{
|
||||
bool LoadOperations(HMODULE newModule);
|
||||
protected:
|
||||
HMODULE _module;
|
||||
public:
|
||||
operator HMODULE() const { return _module; }
|
||||
HMODULE* operator&() { return &_module; }
|
||||
|
||||
CLibrary():_module(NULL) {};
|
||||
~CLibrary();
|
||||
void Attach(HMODULE m)
|
||||
{
|
||||
Free();
|
||||
_module = m;
|
||||
}
|
||||
HMODULE Detach()
|
||||
{
|
||||
HMODULE m = _module;
|
||||
_module = NULL;
|
||||
return m;
|
||||
}
|
||||
|
||||
// operator HMODULE() const { return _module; };
|
||||
bool IsLoaded() const { return (_module != NULL); };
|
||||
bool Free();
|
||||
bool LoadEx(LPCTSTR fileName, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);
|
||||
bool Load(LPCTSTR fileName);
|
||||
#ifndef _UNICODE
|
||||
bool LoadEx(LPCWSTR fileName, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);
|
||||
bool Load(LPCWSTR fileName);
|
||||
#endif
|
||||
FARPROC GetProcAddress(LPCSTR procName) const
|
||||
{ return ::GetProcAddress(_module, procName); }
|
||||
};
|
||||
|
||||
bool MyGetModuleFileName(HMODULE hModule, CSysString &result);
|
||||
#ifndef _UNICODE
|
||||
bool MyGetModuleFileName(HMODULE hModule, UString &result);
|
||||
#endif
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,23 @@
|
||||
// Windows/Defs.h
|
||||
|
||||
#ifndef __WINDOWS_DEFS_H
|
||||
#define __WINDOWS_DEFS_H
|
||||
|
||||
inline bool BOOLToBool(BOOL value)
|
||||
{ return (value != FALSE); }
|
||||
|
||||
#ifdef _WIN32
|
||||
inline bool LRESULTToBool(LRESULT value)
|
||||
{ return (value != FALSE); }
|
||||
#endif
|
||||
|
||||
inline BOOL BoolToBOOL(bool value)
|
||||
{ return (value ? TRUE: FALSE); }
|
||||
|
||||
inline VARIANT_BOOL BoolToVARIANT_BOOL(bool value)
|
||||
{ return (value ? VARIANT_TRUE: VARIANT_FALSE); }
|
||||
|
||||
inline bool VARIANT_BOOLToBool(VARIANT_BOOL value)
|
||||
{ return (value != VARIANT_FALSE); }
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,50 @@
|
||||
// Windows/Error.h
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Windows/Error.h"
|
||||
#ifndef _UNICODE
|
||||
#include "Common/StringConvert.h"
|
||||
#endif
|
||||
|
||||
#ifndef _UNICODE
|
||||
extern bool g_IsNT;
|
||||
#endif
|
||||
|
||||
namespace NWindows {
|
||||
namespace NError {
|
||||
|
||||
bool MyFormatMessage(DWORD messageID, CSysString &message)
|
||||
{
|
||||
LPVOID msgBuf;
|
||||
if(::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,messageID, 0, (LPTSTR) &msgBuf,0, NULL) == 0)
|
||||
return false;
|
||||
message = (LPCTSTR)msgBuf;
|
||||
::LocalFree(msgBuf);
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool MyFormatMessage(DWORD messageID, UString &message)
|
||||
{
|
||||
if (g_IsNT)
|
||||
{
|
||||
LPVOID msgBuf;
|
||||
if(::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, messageID, 0, (LPWSTR) &msgBuf, 0, NULL) == 0)
|
||||
return false;
|
||||
message = (LPCWSTR)msgBuf;
|
||||
::LocalFree(msgBuf);
|
||||
return true;
|
||||
}
|
||||
CSysString messageSys;
|
||||
bool result = MyFormatMessage(messageID, messageSys);
|
||||
message = GetUnicodeString(messageSys);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Windows/Error.h
|
||||
|
||||
#ifndef __WINDOWS_ERROR_H
|
||||
#define __WINDOWS_ERROR_H
|
||||
|
||||
#include "Common/MyString.h"
|
||||
|
||||
namespace NWindows {
|
||||
namespace NError {
|
||||
|
||||
bool MyFormatMessage(DWORD messageID, CSysString &message);
|
||||
inline CSysString MyFormatMessage(DWORD messageID)
|
||||
{
|
||||
CSysString message;
|
||||
MyFormatMessage(messageID, message);
|
||||
return message;
|
||||
}
|
||||
#ifdef _UNICODE
|
||||
inline UString MyFormatMessageW(DWORD messageID)
|
||||
{ return MyFormatMessage(messageID); }
|
||||
#else
|
||||
bool MyFormatMessage(DWORD messageID, UString &message);
|
||||
inline UString MyFormatMessageW(DWORD messageID)
|
||||
{
|
||||
UString message;
|
||||
MyFormatMessage(messageID, message);
|
||||
return message;
|
||||
}
|
||||
#endif
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,841 @@
|
||||
// Windows/FileDir.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "FileDir.h"
|
||||
#include "FileName.h"
|
||||
#include "FileFind.h"
|
||||
#include "Defs.h"
|
||||
#ifndef _UNICODE
|
||||
#include "../Common/StringConvert.h"
|
||||
#endif
|
||||
|
||||
#ifndef _UNICODE
|
||||
extern bool g_IsNT;
|
||||
#endif
|
||||
|
||||
namespace NWindows {
|
||||
namespace NFile {
|
||||
|
||||
#if defined(WIN_LONG_PATH) && defined(_UNICODE)
|
||||
#define WIN_LONG_PATH2
|
||||
#endif
|
||||
|
||||
// SetCurrentDirectory doesn't support \\?\ prefix
|
||||
|
||||
#ifdef WIN_LONG_PATH
|
||||
bool GetLongPathBase(LPCWSTR fileName, UString &res);
|
||||
bool GetLongPath(LPCWSTR fileName, UString &res);
|
||||
#endif
|
||||
|
||||
namespace NDirectory {
|
||||
|
||||
#ifndef _UNICODE
|
||||
static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
|
||||
static UString GetUnicodePath(const CSysString &sysPath)
|
||||
{ return MultiByteToUnicodeString(sysPath, GetCurrentCodePage()); }
|
||||
static CSysString GetSysPath(LPCWSTR sysPath)
|
||||
{ return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); }
|
||||
#endif
|
||||
|
||||
bool MyGetWindowsDirectory(CSysString &path)
|
||||
{
|
||||
UINT needLength = ::GetWindowsDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
|
||||
path.ReleaseBuffer();
|
||||
return (needLength > 0 && needLength <= MAX_PATH);
|
||||
}
|
||||
|
||||
bool MyGetSystemDirectory(CSysString &path)
|
||||
{
|
||||
UINT needLength = ::GetSystemDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
|
||||
path.ReleaseBuffer();
|
||||
return (needLength > 0 && needLength <= MAX_PATH);
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool MyGetWindowsDirectory(UString &path)
|
||||
{
|
||||
if (g_IsNT)
|
||||
{
|
||||
UINT needLength = ::GetWindowsDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
|
||||
path.ReleaseBuffer();
|
||||
return (needLength > 0 && needLength <= MAX_PATH);
|
||||
}
|
||||
CSysString sysPath;
|
||||
if (!MyGetWindowsDirectory(sysPath))
|
||||
return false;
|
||||
path = GetUnicodePath(sysPath);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MyGetSystemDirectory(UString &path)
|
||||
{
|
||||
if (g_IsNT)
|
||||
{
|
||||
UINT needLength = ::GetSystemDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
|
||||
path.ReleaseBuffer();
|
||||
return (needLength > 0 && needLength <= MAX_PATH);
|
||||
}
|
||||
CSysString sysPath;
|
||||
if (!MyGetSystemDirectory(sysPath))
|
||||
return false;
|
||||
path = GetUnicodePath(sysPath);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool SetDirTime(LPCWSTR fileName, const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime)
|
||||
{
|
||||
#ifndef _UNICODE
|
||||
if (!g_IsNT)
|
||||
{
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
HANDLE hDir = ::CreateFileW(fileName, GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
#ifdef WIN_LONG_PATH
|
||||
if (hDir == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
UString longPath;
|
||||
if (GetLongPath(fileName, longPath))
|
||||
hDir = ::CreateFileW(longPath, GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool res = false;
|
||||
if (hDir != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
res = BOOLToBool(::SetFileTime(hDir, creationTime, lastAccessTime, lastWriteTime));
|
||||
::CloseHandle(hDir);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes)
|
||||
{
|
||||
if (::SetFileAttributes(fileName, fileAttributes))
|
||||
return true;
|
||||
#ifdef WIN_LONG_PATH2
|
||||
UString longPath;
|
||||
if (GetLongPath(fileName, longPath))
|
||||
return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MyRemoveDirectory(LPCTSTR pathName)
|
||||
{
|
||||
if (::RemoveDirectory(pathName))
|
||||
return true;
|
||||
#ifdef WIN_LONG_PATH2
|
||||
UString longPath;
|
||||
if (GetLongPath(pathName, longPath))
|
||||
return BOOLToBool(::RemoveDirectoryW(longPath));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef WIN_LONG_PATH
|
||||
bool GetLongPaths(LPCWSTR s1, LPCWSTR s2, UString &d1, UString &d2)
|
||||
{
|
||||
if (!GetLongPathBase(s1, d1) || !GetLongPathBase(s2, d2))
|
||||
return false;
|
||||
if (d1.IsEmpty() && d2.IsEmpty()) return false;
|
||||
if (d1.IsEmpty()) d1 = s1;
|
||||
if (d2.IsEmpty()) d2 = s2;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName)
|
||||
{
|
||||
if (::MoveFile(existFileName, newFileName))
|
||||
return true;
|
||||
#ifdef WIN_LONG_PATH2
|
||||
UString d1, d2;
|
||||
if (GetLongPaths(existFileName, newFileName, d1, d2))
|
||||
return BOOLToBool(::MoveFileW(d1, d2));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes)
|
||||
{
|
||||
if (!g_IsNT)
|
||||
return MySetFileAttributes(GetSysPath(fileName), fileAttributes);
|
||||
if (::SetFileAttributesW(fileName, fileAttributes))
|
||||
return true;
|
||||
#ifdef WIN_LONG_PATH
|
||||
UString longPath;
|
||||
if (GetLongPath(fileName, longPath))
|
||||
return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool MyRemoveDirectory(LPCWSTR pathName)
|
||||
{
|
||||
if (!g_IsNT)
|
||||
return MyRemoveDirectory(GetSysPath(pathName));
|
||||
if (::RemoveDirectoryW(pathName))
|
||||
return true;
|
||||
#ifdef WIN_LONG_PATH
|
||||
UString longPath;
|
||||
if (GetLongPath(pathName, longPath))
|
||||
return BOOLToBool(::RemoveDirectoryW(longPath));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName)
|
||||
{
|
||||
if (!g_IsNT)
|
||||
return MyMoveFile(GetSysPath(existFileName), GetSysPath(newFileName));
|
||||
if (::MoveFileW(existFileName, newFileName))
|
||||
return true;
|
||||
#ifdef WIN_LONG_PATH
|
||||
UString d1, d2;
|
||||
if (GetLongPaths(existFileName, newFileName, d1, d2))
|
||||
return BOOLToBool(::MoveFileW(d1, d2));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool MyCreateDirectory(LPCTSTR pathName)
|
||||
{
|
||||
if (::CreateDirectory(pathName, NULL))
|
||||
return true;
|
||||
#ifdef WIN_LONG_PATH2
|
||||
if (::GetLastError() != ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
UString longPath;
|
||||
if (GetLongPath(pathName, longPath))
|
||||
return BOOLToBool(::CreateDirectoryW(longPath, NULL));
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool MyCreateDirectory(LPCWSTR pathName)
|
||||
{
|
||||
if (!g_IsNT)
|
||||
return MyCreateDirectory(GetSysPath(pathName));
|
||||
if (::CreateDirectoryW(pathName, NULL))
|
||||
return true;
|
||||
#ifdef WIN_LONG_PATH
|
||||
if (::GetLastError() != ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
UString longPath;
|
||||
if (GetLongPath(pathName, longPath))
|
||||
return BOOLToBool(::CreateDirectoryW(longPath, NULL));
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
bool CreateComplexDirectory(LPCTSTR pathName)
|
||||
{
|
||||
NName::CParsedPath path;
|
||||
path.ParsePath(pathName);
|
||||
CSysString fullPath = path.Prefix;
|
||||
DWORD errorCode = ERROR_SUCCESS;
|
||||
for(int i = 0; i < path.PathParts.Size(); i++)
|
||||
{
|
||||
const CSysString &string = path.PathParts[i];
|
||||
if(string.IsEmpty())
|
||||
{
|
||||
if(i != path.PathParts.Size() - 1)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
fullPath += path.PathParts[i];
|
||||
if (!MyCreateDirectory(fullPath))
|
||||
{
|
||||
DWORD errorCode = GetLastError();
|
||||
if(errorCode != ERROR_ALREADY_EXISTS)
|
||||
return false;
|
||||
}
|
||||
fullPath += NName::kDirDelimiter;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
bool CreateComplexDirectory(LPCTSTR _aPathName)
|
||||
{
|
||||
CSysString pathName = _aPathName;
|
||||
int pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
|
||||
if (pos > 0 && pos == pathName.Length() - 1)
|
||||
{
|
||||
if (pathName.Length() == 3 && pathName[1] == ':')
|
||||
return true; // Disk folder;
|
||||
pathName.Delete(pos);
|
||||
}
|
||||
CSysString pathName2 = pathName;
|
||||
pos = pathName.Length();
|
||||
for (;;)
|
||||
{
|
||||
if(MyCreateDirectory(pathName))
|
||||
break;
|
||||
if (::GetLastError() == ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
NFind::CFileInfo fileInfo;
|
||||
if (!NFind::FindFile(pathName, fileInfo)) // For network folders
|
||||
return true;
|
||||
if (!fileInfo.IsDirectory())
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
|
||||
if (pos < 0 || pos == 0)
|
||||
return false;
|
||||
if (pathName[pos - 1] == ':')
|
||||
return false;
|
||||
pathName = pathName.Left(pos);
|
||||
}
|
||||
pathName = pathName2;
|
||||
while(pos < pathName.Length())
|
||||
{
|
||||
pos = pathName.Find(TEXT(CHAR_PATH_SEPARATOR), pos + 1);
|
||||
if (pos < 0)
|
||||
pos = pathName.Length();
|
||||
if (!MyCreateDirectory(pathName.Left(pos)))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
|
||||
bool CreateComplexDirectory(LPCWSTR _aPathName)
|
||||
{
|
||||
UString pathName = _aPathName;
|
||||
int pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
|
||||
if (pos > 0 && pos == pathName.Length() - 1)
|
||||
{
|
||||
if (pathName.Length() == 3 && pathName[1] == L':')
|
||||
return true; // Disk folder;
|
||||
pathName.Delete(pos);
|
||||
}
|
||||
UString pathName2 = pathName;
|
||||
pos = pathName.Length();
|
||||
for (;;)
|
||||
{
|
||||
if(MyCreateDirectory(pathName))
|
||||
break;
|
||||
if (::GetLastError() == ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
NFind::CFileInfoW fileInfo;
|
||||
if (!NFind::FindFile(pathName, fileInfo)) // For network folders
|
||||
return true;
|
||||
if (!fileInfo.IsDirectory())
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
|
||||
if (pos < 0 || pos == 0)
|
||||
return false;
|
||||
if (pathName[pos - 1] == L':')
|
||||
return false;
|
||||
pathName = pathName.Left(pos);
|
||||
}
|
||||
pathName = pathName2;
|
||||
while(pos < pathName.Length())
|
||||
{
|
||||
pos = pathName.Find(WCHAR_PATH_SEPARATOR, pos + 1);
|
||||
if (pos < 0)
|
||||
pos = pathName.Length();
|
||||
if (!MyCreateDirectory(pathName.Left(pos)))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool DeleteFileAlways(LPCTSTR name)
|
||||
{
|
||||
if (!MySetFileAttributes(name, 0))
|
||||
return false;
|
||||
if (::DeleteFile(name))
|
||||
return true;
|
||||
#ifdef WIN_LONG_PATH2
|
||||
UString longPath;
|
||||
if (GetLongPath(name, longPath))
|
||||
return BOOLToBool(::DeleteFileW(longPath));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool DeleteFileAlways(LPCWSTR name)
|
||||
{
|
||||
if (!g_IsNT)
|
||||
return DeleteFileAlways(GetSysPath(name));
|
||||
if (!MySetFileAttributes(name, 0))
|
||||
return false;
|
||||
if (::DeleteFileW(name))
|
||||
return true;
|
||||
#ifdef WIN_LONG_PATH
|
||||
UString longPath;
|
||||
if (GetLongPath(name, longPath))
|
||||
return BOOLToBool(::DeleteFileW(longPath));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool RemoveDirectorySubItems2(const CSysString pathPrefix, const NFind::CFileInfo &fileInfo)
|
||||
{
|
||||
if(fileInfo.IsDirectory())
|
||||
return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
|
||||
return DeleteFileAlways(pathPrefix + fileInfo.Name);
|
||||
}
|
||||
|
||||
bool RemoveDirectoryWithSubItems(const CSysString &path)
|
||||
{
|
||||
NFind::CFileInfo fileInfo;
|
||||
CSysString pathPrefix = path + NName::kDirDelimiter;
|
||||
{
|
||||
NFind::CEnumerator enumerator(pathPrefix + TCHAR(NName::kAnyStringWildcard));
|
||||
while(enumerator.Next(fileInfo))
|
||||
if (!RemoveDirectorySubItems2(pathPrefix, fileInfo))
|
||||
return false;
|
||||
}
|
||||
if (!MySetFileAttributes(path, 0))
|
||||
return false;
|
||||
return MyRemoveDirectory(path);
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
static bool RemoveDirectorySubItems2(const UString pathPrefix, const NFind::CFileInfoW &fileInfo)
|
||||
{
|
||||
if(fileInfo.IsDirectory())
|
||||
return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
|
||||
return DeleteFileAlways(pathPrefix + fileInfo.Name);
|
||||
}
|
||||
bool RemoveDirectoryWithSubItems(const UString &path)
|
||||
{
|
||||
NFind::CFileInfoW fileInfo;
|
||||
UString pathPrefix = path + UString(NName::kDirDelimiter);
|
||||
{
|
||||
NFind::CEnumeratorW enumerator(pathPrefix + UString(NName::kAnyStringWildcard));
|
||||
while(enumerator.Next(fileInfo))
|
||||
if (!RemoveDirectorySubItems2(pathPrefix, fileInfo))
|
||||
return false;
|
||||
}
|
||||
if (!MySetFileAttributes(path, 0))
|
||||
return false;
|
||||
return MyRemoveDirectory(path);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
|
||||
bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath)
|
||||
{
|
||||
DWORD needLength = ::GetShortPathName(longPath, shortPath.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
|
||||
shortPath.ReleaseBuffer();
|
||||
return (needLength > 0 && needLength < MAX_PATH);
|
||||
}
|
||||
|
||||
bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex)
|
||||
{
|
||||
resultPath.Empty();
|
||||
LPTSTR fileNamePointer = 0;
|
||||
LPTSTR buffer = resultPath.GetBuffer(MAX_PATH);
|
||||
DWORD needLength = ::GetFullPathName(fileName, MAX_PATH + 1, buffer, &fileNamePointer);
|
||||
resultPath.ReleaseBuffer();
|
||||
if (needLength == 0)
|
||||
return false;
|
||||
if (needLength >= MAX_PATH)
|
||||
{
|
||||
#ifdef WIN_LONG_PATH2
|
||||
needLength++;
|
||||
buffer = resultPath.GetBuffer(needLength + 1);
|
||||
DWORD needLength2 = ::GetFullPathNameW(fileName, needLength, buffer, &fileNamePointer);
|
||||
resultPath.ReleaseBuffer();
|
||||
if (needLength2 == 0 || needLength2 > needLength)
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
if (fileNamePointer == 0)
|
||||
fileNamePartStartIndex = lstrlen(fileName);
|
||||
else
|
||||
fileNamePartStartIndex = (int)(fileNamePointer - buffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex)
|
||||
{
|
||||
resultPath.Empty();
|
||||
if (g_IsNT)
|
||||
{
|
||||
LPWSTR fileNamePointer = 0;
|
||||
LPWSTR buffer = resultPath.GetBuffer(MAX_PATH);
|
||||
DWORD needLength = ::GetFullPathNameW(fileName, MAX_PATH + 1, buffer, &fileNamePointer);
|
||||
resultPath.ReleaseBuffer();
|
||||
if (needLength == 0)
|
||||
return false;
|
||||
if (needLength >= MAX_PATH)
|
||||
{
|
||||
#ifdef WIN_LONG_PATH
|
||||
needLength++;
|
||||
buffer = resultPath.GetBuffer(needLength + 1);
|
||||
DWORD needLength2 = ::GetFullPathNameW(fileName, needLength, buffer, &fileNamePointer);
|
||||
resultPath.ReleaseBuffer();
|
||||
if (needLength2 == 0 || needLength2 > needLength)
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
if (fileNamePointer == 0)
|
||||
fileNamePartStartIndex = MyStringLen(fileName);
|
||||
else
|
||||
fileNamePartStartIndex = (int)(fileNamePointer - buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
CSysString sysPath;
|
||||
if (!MyGetFullPathName(GetSysPath(fileName), sysPath, fileNamePartStartIndex))
|
||||
return false;
|
||||
UString resultPath1 = GetUnicodePath(sysPath.Left(fileNamePartStartIndex));
|
||||
UString resultPath2 = GetUnicodePath(sysPath.Mid(fileNamePartStartIndex));
|
||||
fileNamePartStartIndex = resultPath1.Length();
|
||||
resultPath = resultPath1 + resultPath2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool MyGetFullPathName(LPCTSTR fileName, CSysString &path)
|
||||
{
|
||||
int index;
|
||||
return MyGetFullPathName(fileName, path, index);
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool MyGetFullPathName(LPCWSTR fileName, UString &path)
|
||||
{
|
||||
int index;
|
||||
return MyGetFullPathName(fileName, path, index);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool GetOnlyName(LPCTSTR fileName, CSysString &resultName)
|
||||
{
|
||||
int index;
|
||||
if (!MyGetFullPathName(fileName, resultName, index))
|
||||
return false;
|
||||
resultName = resultName.Mid(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool GetOnlyName(LPCWSTR fileName, UString &resultName)
|
||||
{
|
||||
int index;
|
||||
if (!MyGetFullPathName(fileName, resultName, index))
|
||||
return false;
|
||||
resultName = resultName.Mid(index);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName)
|
||||
{
|
||||
int index;
|
||||
if (!MyGetFullPathName(fileName, resultName, index))
|
||||
return false;
|
||||
resultName = resultName.Left(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName)
|
||||
{
|
||||
int index;
|
||||
if (!MyGetFullPathName(fileName, resultName, index))
|
||||
return false;
|
||||
resultName = resultName.Left(index);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool MyGetCurrentDirectory(CSysString &path)
|
||||
{
|
||||
DWORD needLength = ::GetCurrentDirectory(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
|
||||
path.ReleaseBuffer();
|
||||
return (needLength > 0 && needLength <= MAX_PATH);
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool MySetCurrentDirectory(LPCWSTR path)
|
||||
{
|
||||
if (g_IsNT)
|
||||
return BOOLToBool(::SetCurrentDirectoryW(path));
|
||||
return MySetCurrentDirectory(GetSysPath(path));
|
||||
}
|
||||
bool MyGetCurrentDirectory(UString &path)
|
||||
{
|
||||
if (g_IsNT)
|
||||
{
|
||||
DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
|
||||
path.ReleaseBuffer();
|
||||
return (needLength > 0 && needLength <= MAX_PATH);
|
||||
}
|
||||
CSysString sysPath;
|
||||
if (!MyGetCurrentDirectory(sysPath))
|
||||
return false;
|
||||
path = GetUnicodePath(sysPath);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension,
|
||||
CSysString &resultPath, UINT32 &filePart)
|
||||
{
|
||||
LPTSTR filePartPointer;
|
||||
DWORD value = ::SearchPath(path, fileName, extension,
|
||||
MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);
|
||||
filePart = (UINT32)(filePartPointer - (LPCTSTR)resultPath);
|
||||
resultPath.ReleaseBuffer();
|
||||
return (value > 0 && value <= MAX_PATH);
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension,
|
||||
UString &resultPath, UINT32 &filePart)
|
||||
{
|
||||
if (g_IsNT)
|
||||
{
|
||||
LPWSTR filePartPointer = 0;
|
||||
DWORD value = ::SearchPathW(path, fileName, extension,
|
||||
MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);
|
||||
filePart = (UINT32)(filePartPointer - (LPCWSTR)resultPath);
|
||||
resultPath.ReleaseBuffer();
|
||||
return (value > 0 && value <= MAX_PATH);
|
||||
}
|
||||
|
||||
CSysString sysPath;
|
||||
if (!MySearchPath(
|
||||
path != 0 ? (LPCTSTR)GetSysPath(path): 0,
|
||||
fileName != 0 ? (LPCTSTR)GetSysPath(fileName): 0,
|
||||
extension != 0 ? (LPCTSTR)GetSysPath(extension): 0,
|
||||
sysPath, filePart))
|
||||
return false;
|
||||
UString resultPath1 = GetUnicodePath(sysPath.Left(filePart));
|
||||
UString resultPath2 = GetUnicodePath(sysPath.Mid(filePart));
|
||||
filePart = resultPath1.Length();
|
||||
resultPath = resultPath1 + resultPath2;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool MyGetTempPath(CSysString &path)
|
||||
{
|
||||
DWORD needLength = ::GetTempPath(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
|
||||
path.ReleaseBuffer();
|
||||
return (needLength > 0 && needLength <= MAX_PATH);
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool MyGetTempPath(UString &path)
|
||||
{
|
||||
path.Empty();
|
||||
if (g_IsNT)
|
||||
{
|
||||
DWORD needLength = ::GetTempPathW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
|
||||
path.ReleaseBuffer();
|
||||
return (needLength > 0 && needLength <= MAX_PATH);
|
||||
}
|
||||
CSysString sysPath;
|
||||
if (!MyGetTempPath(sysPath))
|
||||
return false;
|
||||
path = GetUnicodePath(sysPath);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &path)
|
||||
{
|
||||
UINT number = ::GetTempFileName(dirPath, prefix, 0, path.GetBuffer(MAX_PATH + 1));
|
||||
path.ReleaseBuffer();
|
||||
return number;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &path)
|
||||
{
|
||||
if (g_IsNT)
|
||||
{
|
||||
UINT number = ::GetTempFileNameW(dirPath, prefix, 0, path.GetBuffer(MAX_PATH));
|
||||
path.ReleaseBuffer();
|
||||
return number;
|
||||
}
|
||||
CSysString sysPath;
|
||||
UINT number = MyGetTempFileName(
|
||||
dirPath ? (LPCTSTR)GetSysPath(dirPath): 0,
|
||||
prefix ? (LPCTSTR)GetSysPath(prefix): 0,
|
||||
sysPath);
|
||||
path = GetUnicodePath(sysPath);
|
||||
return number;
|
||||
}
|
||||
#endif
|
||||
|
||||
UINT CTempFile::Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath)
|
||||
{
|
||||
Remove();
|
||||
UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
|
||||
if(number != 0)
|
||||
{
|
||||
_fileName = resultPath;
|
||||
_mustBeDeleted = true;
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
bool CTempFile::Create(LPCTSTR prefix, CSysString &resultPath)
|
||||
{
|
||||
CSysString tempPath;
|
||||
if (!MyGetTempPath(tempPath))
|
||||
return false;
|
||||
if (Create(tempPath, prefix, resultPath) != 0)
|
||||
return true;
|
||||
if (!MyGetWindowsDirectory(tempPath))
|
||||
return false;
|
||||
return (Create(tempPath, prefix, resultPath) != 0);
|
||||
}
|
||||
|
||||
bool CTempFile::Remove()
|
||||
{
|
||||
if (!_mustBeDeleted)
|
||||
return true;
|
||||
_mustBeDeleted = !DeleteFileAlways(_fileName);
|
||||
return !_mustBeDeleted;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
|
||||
UINT CTempFileW::Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath)
|
||||
{
|
||||
Remove();
|
||||
UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
|
||||
if(number != 0)
|
||||
{
|
||||
_fileName = resultPath;
|
||||
_mustBeDeleted = true;
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
bool CTempFileW::Create(LPCWSTR prefix, UString &resultPath)
|
||||
{
|
||||
UString tempPath;
|
||||
if (!MyGetTempPath(tempPath))
|
||||
return false;
|
||||
if (Create(tempPath, prefix, resultPath) != 0)
|
||||
return true;
|
||||
if (!MyGetWindowsDirectory(tempPath))
|
||||
return false;
|
||||
return (Create(tempPath, prefix, resultPath) != 0);
|
||||
}
|
||||
|
||||
bool CTempFileW::Remove()
|
||||
{
|
||||
if (!_mustBeDeleted)
|
||||
return true;
|
||||
_mustBeDeleted = !DeleteFileAlways(_fileName);
|
||||
return !_mustBeDeleted;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool CreateTempDirectory(LPCTSTR prefix, CSysString &dirName)
|
||||
{
|
||||
/*
|
||||
CSysString prefix = tempPath + prefixChars;
|
||||
CRandom random;
|
||||
random.Init();
|
||||
*/
|
||||
for (;;)
|
||||
{
|
||||
CTempFile tempFile;
|
||||
if (!tempFile.Create(prefix, dirName))
|
||||
return false;
|
||||
if (!::DeleteFile(dirName))
|
||||
return false;
|
||||
/*
|
||||
UINT32 randomNumber = random.Generate();
|
||||
TCHAR randomNumberString[32];
|
||||
_stprintf(randomNumberString, _T("%04X"), randomNumber);
|
||||
dirName = prefix + randomNumberString;
|
||||
*/
|
||||
if(NFind::DoesFileExist(dirName))
|
||||
continue;
|
||||
if (MyCreateDirectory(dirName))
|
||||
return true;
|
||||
if (::GetLastError() != ERROR_ALREADY_EXISTS)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CTempDirectory::Create(LPCTSTR prefix)
|
||||
{
|
||||
Remove();
|
||||
return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
|
||||
bool CreateTempDirectory(LPCWSTR prefix, UString &dirName)
|
||||
{
|
||||
/*
|
||||
CSysString prefix = tempPath + prefixChars;
|
||||
CRandom random;
|
||||
random.Init();
|
||||
*/
|
||||
for (;;)
|
||||
{
|
||||
CTempFileW tempFile;
|
||||
if (!tempFile.Create(prefix, dirName))
|
||||
return false;
|
||||
if (!DeleteFileAlways(dirName))
|
||||
return false;
|
||||
/*
|
||||
UINT32 randomNumber = random.Generate();
|
||||
TCHAR randomNumberString[32];
|
||||
_stprintf(randomNumberString, _T("%04X"), randomNumber);
|
||||
dirName = prefix + randomNumberString;
|
||||
*/
|
||||
if(NFind::DoesFileExist(dirName))
|
||||
continue;
|
||||
if (MyCreateDirectory(dirName))
|
||||
return true;
|
||||
if (::GetLastError() != ERROR_ALREADY_EXISTS)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CTempDirectoryW::Create(LPCWSTR prefix)
|
||||
{
|
||||
Remove();
|
||||
return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}}}
|
||||
@@ -0,0 +1,178 @@
|
||||
// Windows/FileDir.h
|
||||
|
||||
#ifndef __WINDOWS_FILEDIR_H
|
||||
#define __WINDOWS_FILEDIR_H
|
||||
|
||||
#include "../Common/MyString.h"
|
||||
#include "Defs.h"
|
||||
|
||||
namespace NWindows {
|
||||
namespace NFile {
|
||||
namespace NDirectory {
|
||||
|
||||
#ifdef WIN_LONG_PATH
|
||||
bool GetLongPaths(LPCWSTR s1, LPCWSTR s2, UString &d1, UString &d2);
|
||||
#endif
|
||||
|
||||
bool MyGetWindowsDirectory(CSysString &path);
|
||||
bool MyGetSystemDirectory(CSysString &path);
|
||||
#ifndef _UNICODE
|
||||
bool MyGetWindowsDirectory(UString &path);
|
||||
bool MyGetSystemDirectory(UString &path);
|
||||
#endif
|
||||
|
||||
bool SetDirTime(LPCWSTR fileName, const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime);
|
||||
|
||||
bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes);
|
||||
bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName);
|
||||
bool MyRemoveDirectory(LPCTSTR pathName);
|
||||
bool MyCreateDirectory(LPCTSTR pathName);
|
||||
bool CreateComplexDirectory(LPCTSTR pathName);
|
||||
bool DeleteFileAlways(LPCTSTR name);
|
||||
bool RemoveDirectoryWithSubItems(const CSysString &path);
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes);
|
||||
bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName);
|
||||
bool MyRemoveDirectory(LPCWSTR pathName);
|
||||
bool MyCreateDirectory(LPCWSTR pathName);
|
||||
bool CreateComplexDirectory(LPCWSTR pathName);
|
||||
bool DeleteFileAlways(LPCWSTR name);
|
||||
bool RemoveDirectoryWithSubItems(const UString &path);
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath);
|
||||
|
||||
bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath,
|
||||
int &fileNamePartStartIndex);
|
||||
bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath);
|
||||
bool GetOnlyName(LPCTSTR fileName, CSysString &resultName);
|
||||
bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName);
|
||||
#ifndef _UNICODE
|
||||
bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath,
|
||||
int &fileNamePartStartIndex);
|
||||
bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath);
|
||||
bool GetOnlyName(LPCWSTR fileName, UString &resultName);
|
||||
bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName);
|
||||
#endif
|
||||
|
||||
inline bool MySetCurrentDirectory(LPCTSTR path)
|
||||
{ return BOOLToBool(::SetCurrentDirectory(path)); }
|
||||
bool MyGetCurrentDirectory(CSysString &resultPath);
|
||||
#ifndef _UNICODE
|
||||
bool MySetCurrentDirectory(LPCWSTR path);
|
||||
bool MyGetCurrentDirectory(UString &resultPath);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension,
|
||||
CSysString &resultPath, UINT32 &filePart);
|
||||
#ifndef _UNICODE
|
||||
bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension,
|
||||
UString &resultPath, UINT32 &filePart);
|
||||
#endif
|
||||
|
||||
inline bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension,
|
||||
CSysString &resultPath)
|
||||
{
|
||||
UINT32 value;
|
||||
return MySearchPath(path, fileName, extension, resultPath, value);
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
inline bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension,
|
||||
UString &resultPath)
|
||||
{
|
||||
UINT32 value;
|
||||
return MySearchPath(path, fileName, extension, resultPath, value);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool MyGetTempPath(CSysString &resultPath);
|
||||
#ifndef _UNICODE
|
||||
bool MyGetTempPath(UString &resultPath);
|
||||
#endif
|
||||
|
||||
UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath);
|
||||
#ifndef _UNICODE
|
||||
UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath);
|
||||
#endif
|
||||
|
||||
class CTempFile
|
||||
{
|
||||
bool _mustBeDeleted;
|
||||
CSysString _fileName;
|
||||
public:
|
||||
CTempFile(): _mustBeDeleted(false) {}
|
||||
~CTempFile() { Remove(); }
|
||||
void DisableDeleting() { _mustBeDeleted = false; }
|
||||
UINT Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath);
|
||||
bool Create(LPCTSTR prefix, CSysString &resultPath);
|
||||
bool Remove();
|
||||
};
|
||||
|
||||
#ifdef _UNICODE
|
||||
typedef CTempFile CTempFileW;
|
||||
#else
|
||||
class CTempFileW
|
||||
{
|
||||
bool _mustBeDeleted;
|
||||
UString _fileName;
|
||||
public:
|
||||
CTempFileW(): _mustBeDeleted(false) {}
|
||||
~CTempFileW() { Remove(); }
|
||||
void DisableDeleting() { _mustBeDeleted = false; }
|
||||
UINT Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath);
|
||||
bool Create(LPCWSTR prefix, UString &resultPath);
|
||||
bool Remove();
|
||||
};
|
||||
#endif
|
||||
|
||||
bool CreateTempDirectory(LPCTSTR prefixChars, CSysString &dirName);
|
||||
|
||||
class CTempDirectory
|
||||
{
|
||||
bool _mustBeDeleted;
|
||||
CSysString _tempDir;
|
||||
public:
|
||||
const CSysString &GetPath() const { return _tempDir; }
|
||||
CTempDirectory(): _mustBeDeleted(false) {}
|
||||
~CTempDirectory() { Remove(); }
|
||||
bool Create(LPCTSTR prefix) ;
|
||||
bool Remove()
|
||||
{
|
||||
if (!_mustBeDeleted)
|
||||
return true;
|
||||
_mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);
|
||||
return (!_mustBeDeleted);
|
||||
}
|
||||
void DisableDeleting() { _mustBeDeleted = false; }
|
||||
};
|
||||
|
||||
#ifdef _UNICODE
|
||||
typedef CTempDirectory CTempDirectoryW;
|
||||
#else
|
||||
class CTempDirectoryW
|
||||
{
|
||||
bool _mustBeDeleted;
|
||||
UString _tempDir;
|
||||
public:
|
||||
const UString &GetPath() const { return _tempDir; }
|
||||
CTempDirectoryW(): _mustBeDeleted(false) {}
|
||||
~CTempDirectoryW() { Remove(); }
|
||||
bool Create(LPCWSTR prefix) ;
|
||||
bool Remove()
|
||||
{
|
||||
if (!_mustBeDeleted)
|
||||
return true;
|
||||
_mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);
|
||||
return (!_mustBeDeleted);
|
||||
}
|
||||
void DisableDeleting() { _mustBeDeleted = false; }
|
||||
};
|
||||
#endif
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,408 @@
|
||||
// Windows/FileFind.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "FileFind.h"
|
||||
#ifndef _UNICODE
|
||||
#include "../Common/StringConvert.h"
|
||||
#endif
|
||||
|
||||
#ifndef _UNICODE
|
||||
extern bool g_IsNT;
|
||||
#endif
|
||||
|
||||
namespace NWindows {
|
||||
namespace NFile {
|
||||
|
||||
#if defined(WIN_LONG_PATH) && defined(_UNICODE)
|
||||
#define WIN_LONG_PATH2
|
||||
#endif
|
||||
|
||||
bool GetLongPath(LPCWSTR fileName, UString &res);
|
||||
|
||||
namespace NFind {
|
||||
|
||||
static const TCHAR kDot = TEXT('.');
|
||||
|
||||
bool CFileInfo::IsDots() const
|
||||
{
|
||||
if (!IsDirectory() || Name.IsEmpty())
|
||||
return false;
|
||||
if (Name[0] != kDot)
|
||||
return false;
|
||||
return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool CFileInfoW::IsDots() const
|
||||
{
|
||||
if (!IsDirectory() || Name.IsEmpty())
|
||||
return false;
|
||||
if (Name[0] != kDot)
|
||||
return false;
|
||||
return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void ConvertWIN32_FIND_DATA_To_FileInfo(
|
||||
const WIN32_FIND_DATA &findData,
|
||||
CFileInfo &fileInfo)
|
||||
{
|
||||
fileInfo.Attributes = findData.dwFileAttributes;
|
||||
fileInfo.CreationTime = findData.ftCreationTime;
|
||||
fileInfo.LastAccessTime = findData.ftLastAccessTime;
|
||||
fileInfo.LastWriteTime = findData.ftLastWriteTime;
|
||||
fileInfo.Size = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
|
||||
fileInfo.Name = findData.cFileName;
|
||||
#ifndef _WIN32_WCE
|
||||
fileInfo.ReparseTag = findData.dwReserved0;
|
||||
#else
|
||||
fileInfo.ObjectID = findData.dwOID;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
|
||||
static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
|
||||
|
||||
static void ConvertWIN32_FIND_DATA_To_FileInfo(
|
||||
const WIN32_FIND_DATAW &findData,
|
||||
CFileInfoW &fileInfo)
|
||||
{
|
||||
fileInfo.Attributes = findData.dwFileAttributes;
|
||||
fileInfo.CreationTime = findData.ftCreationTime;
|
||||
fileInfo.LastAccessTime = findData.ftLastAccessTime;
|
||||
fileInfo.LastWriteTime = findData.ftLastWriteTime;
|
||||
fileInfo.Size = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
|
||||
fileInfo.Name = findData.cFileName;
|
||||
#ifndef _WIN32_WCE
|
||||
fileInfo.ReparseTag = findData.dwReserved0;
|
||||
#else
|
||||
fileInfo.ObjectID = findData.dwOID;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ConvertWIN32_FIND_DATA_To_FileInfo(
|
||||
const WIN32_FIND_DATA &findData,
|
||||
CFileInfoW &fileInfo)
|
||||
{
|
||||
fileInfo.Attributes = findData.dwFileAttributes;
|
||||
fileInfo.CreationTime = findData.ftCreationTime;
|
||||
fileInfo.LastAccessTime = findData.ftLastAccessTime;
|
||||
fileInfo.LastWriteTime = findData.ftLastWriteTime;
|
||||
fileInfo.Size = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
|
||||
fileInfo.Name = GetUnicodeString(findData.cFileName, GetCurrentCodePage());
|
||||
#ifndef _WIN32_WCE
|
||||
fileInfo.ReparseTag = findData.dwReserved0;
|
||||
#else
|
||||
fileInfo.ObjectID = findData.dwOID;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
// CFindFile
|
||||
|
||||
bool CFindFile::Close()
|
||||
{
|
||||
if (_handle == INVALID_HANDLE_VALUE)
|
||||
return true;
|
||||
if (!::FindClose(_handle))
|
||||
return false;
|
||||
_handle = INVALID_HANDLE_VALUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CFindFile::FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo)
|
||||
{
|
||||
if (!Close())
|
||||
return false;
|
||||
WIN32_FIND_DATA findData;
|
||||
_handle = ::FindFirstFile(wildcard, &findData);
|
||||
#ifdef WIN_LONG_PATH2
|
||||
if (_handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
UString longPath;
|
||||
if (GetLongPath(wildcard, longPath))
|
||||
_handle = ::FindFirstFileW(longPath, &findData);
|
||||
}
|
||||
#endif
|
||||
if (_handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool CFindFile::FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo)
|
||||
{
|
||||
if (!Close())
|
||||
return false;
|
||||
if (g_IsNT)
|
||||
{
|
||||
WIN32_FIND_DATAW findData;
|
||||
_handle = ::FindFirstFileW(wildcard, &findData);
|
||||
#ifdef WIN_LONG_PATH
|
||||
if (_handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
UString longPath;
|
||||
if (GetLongPath(wildcard, longPath))
|
||||
_handle = ::FindFirstFileW(longPath, &findData);
|
||||
}
|
||||
#endif
|
||||
if (_handle != INVALID_HANDLE_VALUE)
|
||||
ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
WIN32_FIND_DATAA findData;
|
||||
_handle = ::FindFirstFileA(UnicodeStringToMultiByte(wildcard,
|
||||
GetCurrentCodePage()), &findData);
|
||||
if (_handle != INVALID_HANDLE_VALUE)
|
||||
ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
|
||||
}
|
||||
return (_handle != INVALID_HANDLE_VALUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool CFindFile::FindNext(CFileInfo &fileInfo)
|
||||
{
|
||||
WIN32_FIND_DATA findData;
|
||||
bool result = BOOLToBool(::FindNextFile(_handle, &findData));
|
||||
if (result)
|
||||
ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool CFindFile::FindNext(CFileInfoW &fileInfo)
|
||||
{
|
||||
if (g_IsNT)
|
||||
{
|
||||
WIN32_FIND_DATAW findData;
|
||||
if (!::FindNextFileW(_handle, &findData))
|
||||
return false;
|
||||
ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
WIN32_FIND_DATAA findData;
|
||||
if (!::FindNextFileA(_handle, &findData))
|
||||
return false;
|
||||
ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool FindFile(LPCTSTR wildcard, CFileInfo &fileInfo)
|
||||
{
|
||||
CFindFile finder;
|
||||
return finder.FindFirst(wildcard, fileInfo);
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool FindFile(LPCWSTR wildcard, CFileInfoW &fileInfo)
|
||||
{
|
||||
CFindFile finder;
|
||||
return finder.FindFirst(wildcard, fileInfo);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool DoesFileExist(LPCTSTR name)
|
||||
{
|
||||
CFileInfo fileInfo;
|
||||
return FindFile(name, fileInfo);
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool DoesFileExist(LPCWSTR name)
|
||||
{
|
||||
CFileInfoW fileInfo;
|
||||
return FindFile(name, fileInfo);
|
||||
}
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////
|
||||
// CEnumerator
|
||||
|
||||
bool CEnumerator::NextAny(CFileInfo &fileInfo)
|
||||
{
|
||||
if (_findFile.IsHandleAllocated())
|
||||
return _findFile.FindNext(fileInfo);
|
||||
else
|
||||
return _findFile.FindFirst(_wildcard, fileInfo);
|
||||
}
|
||||
|
||||
bool CEnumerator::Next(CFileInfo &fileInfo)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (!NextAny(fileInfo))
|
||||
return false;
|
||||
if (!fileInfo.IsDots())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool CEnumerator::Next(CFileInfo &fileInfo, bool &found)
|
||||
{
|
||||
if (Next(fileInfo))
|
||||
{
|
||||
found = true;
|
||||
return true;
|
||||
}
|
||||
found = false;
|
||||
return (::GetLastError() == ERROR_NO_MORE_FILES);
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool CEnumeratorW::NextAny(CFileInfoW &fileInfo)
|
||||
{
|
||||
if (_findFile.IsHandleAllocated())
|
||||
return _findFile.FindNext(fileInfo);
|
||||
else
|
||||
return _findFile.FindFirst(_wildcard, fileInfo);
|
||||
}
|
||||
|
||||
bool CEnumeratorW::Next(CFileInfoW &fileInfo)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (!NextAny(fileInfo))
|
||||
return false;
|
||||
if (!fileInfo.IsDots())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool CEnumeratorW::Next(CFileInfoW &fileInfo, bool &found)
|
||||
{
|
||||
if (Next(fileInfo))
|
||||
{
|
||||
found = true;
|
||||
return true;
|
||||
}
|
||||
found = false;
|
||||
return (::GetLastError() == ERROR_NO_MORE_FILES);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
// CFindChangeNotification
|
||||
// FindFirstChangeNotification can return 0. MSDN doesn't tell about it.
|
||||
|
||||
bool CFindChangeNotification::Close()
|
||||
{
|
||||
if (!IsHandleAllocated())
|
||||
return true;
|
||||
if (!::FindCloseChangeNotification(_handle))
|
||||
return false;
|
||||
_handle = INVALID_HANDLE_VALUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
HANDLE CFindChangeNotification::FindFirst(LPCTSTR pathName, bool watchSubtree, DWORD notifyFilter)
|
||||
{
|
||||
_handle = ::FindFirstChangeNotification(pathName, BoolToBOOL(watchSubtree), notifyFilter);
|
||||
#ifdef WIN_LONG_PATH2
|
||||
if (!IsHandleAllocated())
|
||||
{
|
||||
UString longPath;
|
||||
if (GetLongPath(pathName, longPath))
|
||||
_handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
|
||||
}
|
||||
#endif
|
||||
return _handle;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
HANDLE CFindChangeNotification::FindFirst(LPCWSTR pathName, bool watchSubtree, DWORD notifyFilter)
|
||||
{
|
||||
if (!g_IsNT)
|
||||
return FindFirst(UnicodeStringToMultiByte(pathName, GetCurrentCodePage()), watchSubtree, notifyFilter);
|
||||
_handle = ::FindFirstChangeNotificationW(pathName, BoolToBOOL(watchSubtree), notifyFilter);
|
||||
#ifdef WIN_LONG_PATH
|
||||
if (!IsHandleAllocated())
|
||||
{
|
||||
UString longPath;
|
||||
if (GetLongPath(pathName, longPath))
|
||||
_handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
|
||||
}
|
||||
#endif
|
||||
return _handle;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings)
|
||||
{
|
||||
driveStrings.Clear();
|
||||
UINT32 size = GetLogicalDriveStrings(0, NULL);
|
||||
if (size == 0)
|
||||
return false;
|
||||
CSysString buffer;
|
||||
UINT32 newSize = GetLogicalDriveStrings(size, buffer.GetBuffer(size));
|
||||
if (newSize == 0)
|
||||
return false;
|
||||
if (newSize > size)
|
||||
return false;
|
||||
CSysString string;
|
||||
for(UINT32 i = 0; i < newSize; i++)
|
||||
{
|
||||
TCHAR c = buffer[i];
|
||||
if (c == TEXT('\0'))
|
||||
{
|
||||
driveStrings.Add(string);
|
||||
string.Empty();
|
||||
}
|
||||
else
|
||||
string += c;
|
||||
}
|
||||
if (!string.IsEmpty())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool MyGetLogicalDriveStrings(UStringVector &driveStrings)
|
||||
{
|
||||
driveStrings.Clear();
|
||||
if (g_IsNT)
|
||||
{
|
||||
UINT32 size = GetLogicalDriveStringsW(0, NULL);
|
||||
if (size == 0)
|
||||
return false;
|
||||
UString buffer;
|
||||
UINT32 newSize = GetLogicalDriveStringsW(size, buffer.GetBuffer(size));
|
||||
if (newSize == 0)
|
||||
return false;
|
||||
if (newSize > size)
|
||||
return false;
|
||||
UString string;
|
||||
for(UINT32 i = 0; i < newSize; i++)
|
||||
{
|
||||
WCHAR c = buffer[i];
|
||||
if (c == L'\0')
|
||||
{
|
||||
driveStrings.Add(string);
|
||||
string.Empty();
|
||||
}
|
||||
else
|
||||
string += c;
|
||||
}
|
||||
return string.IsEmpty();
|
||||
}
|
||||
CSysStringVector driveStringsA;
|
||||
bool res = MyGetLogicalDriveStrings(driveStringsA);
|
||||
for (int i = 0; i < driveStringsA.Size(); i++)
|
||||
driveStrings.Add(GetUnicodeString(driveStringsA[i]));
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
}}}
|
||||
@@ -0,0 +1,153 @@
|
||||
// Windows/FileFind.h
|
||||
|
||||
#ifndef __WINDOWS_FILEFIND_H
|
||||
#define __WINDOWS_FILEFIND_H
|
||||
|
||||
#include "../Common/MyString.h"
|
||||
#include "../Common/Types.h"
|
||||
#include "FileName.h"
|
||||
#include "Defs.h"
|
||||
|
||||
namespace NWindows {
|
||||
namespace NFile {
|
||||
namespace NFind {
|
||||
|
||||
namespace NAttributes
|
||||
{
|
||||
inline bool IsReadOnly(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_READONLY) != 0; }
|
||||
inline bool IsHidden(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_HIDDEN) != 0; }
|
||||
inline bool IsSystem(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_SYSTEM) != 0; }
|
||||
inline bool IsDirectory(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; }
|
||||
inline bool IsArchived(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_ARCHIVE) != 0; }
|
||||
inline bool IsCompressed(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_COMPRESSED) != 0; }
|
||||
inline bool IsEncrypted(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_ENCRYPTED) != 0; }
|
||||
}
|
||||
|
||||
class CFileInfoBase
|
||||
{
|
||||
bool MatchesMask(UINT32 mask) const { return ((Attributes & mask) != 0); }
|
||||
public:
|
||||
DWORD Attributes;
|
||||
FILETIME CreationTime;
|
||||
FILETIME LastAccessTime;
|
||||
FILETIME LastWriteTime;
|
||||
UInt64 Size;
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
UINT32 ReparseTag;
|
||||
#else
|
||||
DWORD ObjectID;
|
||||
#endif
|
||||
|
||||
bool IsArchived() const { return MatchesMask(FILE_ATTRIBUTE_ARCHIVE); }
|
||||
bool IsCompressed() const { return MatchesMask(FILE_ATTRIBUTE_COMPRESSED); }
|
||||
bool IsDirectory() const { return MatchesMask(FILE_ATTRIBUTE_DIRECTORY); }
|
||||
bool IsEncrypted() const { return MatchesMask(FILE_ATTRIBUTE_ENCRYPTED); }
|
||||
bool IsHidden() const { return MatchesMask(FILE_ATTRIBUTE_HIDDEN); }
|
||||
bool IsNormal() const { return MatchesMask(FILE_ATTRIBUTE_NORMAL); }
|
||||
bool IsOffline() const { return MatchesMask(FILE_ATTRIBUTE_OFFLINE); }
|
||||
bool IsReadOnly() const { return MatchesMask(FILE_ATTRIBUTE_READONLY); }
|
||||
bool HasReparsePoint() const { return MatchesMask(FILE_ATTRIBUTE_REPARSE_POINT); }
|
||||
bool IsSparse() const { return MatchesMask(FILE_ATTRIBUTE_SPARSE_FILE); }
|
||||
bool IsSystem() const { return MatchesMask(FILE_ATTRIBUTE_SYSTEM); }
|
||||
bool IsTemporary() const { return MatchesMask(FILE_ATTRIBUTE_TEMPORARY); }
|
||||
};
|
||||
|
||||
class CFileInfo: public CFileInfoBase
|
||||
{
|
||||
public:
|
||||
CSysString Name;
|
||||
bool IsDots() const;
|
||||
};
|
||||
|
||||
#ifdef _UNICODE
|
||||
typedef CFileInfo CFileInfoW;
|
||||
#else
|
||||
class CFileInfoW: public CFileInfoBase
|
||||
{
|
||||
public:
|
||||
UString Name;
|
||||
bool IsDots() const;
|
||||
};
|
||||
#endif
|
||||
|
||||
class CFindFile
|
||||
{
|
||||
friend class CEnumerator;
|
||||
HANDLE _handle;
|
||||
public:
|
||||
bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE; }
|
||||
CFindFile(): _handle(INVALID_HANDLE_VALUE) {}
|
||||
~CFindFile() { Close(); }
|
||||
bool FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo);
|
||||
bool FindNext(CFileInfo &fileInfo);
|
||||
#ifndef _UNICODE
|
||||
bool FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo);
|
||||
bool FindNext(CFileInfoW &fileInfo);
|
||||
#endif
|
||||
bool Close();
|
||||
};
|
||||
|
||||
bool FindFile(LPCTSTR wildcard, CFileInfo &fileInfo);
|
||||
|
||||
bool DoesFileExist(LPCTSTR name);
|
||||
#ifndef _UNICODE
|
||||
bool FindFile(LPCWSTR wildcard, CFileInfoW &fileInfo);
|
||||
bool DoesFileExist(LPCWSTR name);
|
||||
#endif
|
||||
|
||||
class CEnumerator
|
||||
{
|
||||
CFindFile _findFile;
|
||||
CSysString _wildcard;
|
||||
bool NextAny(CFileInfo &fileInfo);
|
||||
public:
|
||||
CEnumerator(): _wildcard(NName::kAnyStringWildcard) {}
|
||||
CEnumerator(const CSysString &wildcard): _wildcard(wildcard) {}
|
||||
bool Next(CFileInfo &fileInfo);
|
||||
bool Next(CFileInfo &fileInfo, bool &found);
|
||||
};
|
||||
|
||||
#ifdef _UNICODE
|
||||
typedef CEnumerator CEnumeratorW;
|
||||
#else
|
||||
class CEnumeratorW
|
||||
{
|
||||
CFindFile _findFile;
|
||||
UString _wildcard;
|
||||
bool NextAny(CFileInfoW &fileInfo);
|
||||
public:
|
||||
CEnumeratorW(): _wildcard(NName::kAnyStringWildcard) {}
|
||||
CEnumeratorW(const UString &wildcard): _wildcard(wildcard) {}
|
||||
bool Next(CFileInfoW &fileInfo);
|
||||
bool Next(CFileInfoW &fileInfo, bool &found);
|
||||
};
|
||||
#endif
|
||||
|
||||
class CFindChangeNotification
|
||||
{
|
||||
HANDLE _handle;
|
||||
public:
|
||||
operator HANDLE () { return _handle; }
|
||||
bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE && _handle != 0; }
|
||||
CFindChangeNotification(): _handle(INVALID_HANDLE_VALUE) {}
|
||||
~CFindChangeNotification() { Close(); }
|
||||
bool Close();
|
||||
HANDLE FindFirst(LPCTSTR pathName, bool watchSubtree, DWORD notifyFilter);
|
||||
#ifndef _UNICODE
|
||||
HANDLE FindFirst(LPCWSTR pathName, bool watchSubtree, DWORD notifyFilter);
|
||||
#endif
|
||||
bool FindNext() { return BOOLToBool(::FindNextChangeNotification(_handle)); }
|
||||
};
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings);
|
||||
#ifndef _UNICODE
|
||||
bool MyGetLogicalDriveStrings(UStringVector &driveStrings);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,318 @@
|
||||
// Windows/FileIO.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "FileIO.h"
|
||||
#include "Defs.h"
|
||||
#ifdef WIN_LONG_PATH
|
||||
#include "../Common/MyString.h"
|
||||
#endif
|
||||
#ifndef _UNICODE
|
||||
#include "../Common/StringConvert.h"
|
||||
#endif
|
||||
|
||||
#ifndef _UNICODE
|
||||
extern bool g_IsNT;
|
||||
#endif
|
||||
|
||||
namespace NWindows {
|
||||
namespace NFile {
|
||||
|
||||
#if defined(WIN_LONG_PATH) && defined(_UNICODE)
|
||||
#define WIN_LONG_PATH2
|
||||
#endif
|
||||
|
||||
#ifdef WIN_LONG_PATH
|
||||
bool GetLongPathBase(LPCWSTR s, UString &res)
|
||||
{
|
||||
res.Empty();
|
||||
int len = MyStringLen(s);
|
||||
wchar_t c = s[0];
|
||||
if (len < 1 || c == L'\\' || c == L'.' && (len == 1 || len == 2 && s[1] == L'.'))
|
||||
return true;
|
||||
UString curDir;
|
||||
bool isAbs = false;
|
||||
if (len > 3)
|
||||
isAbs = (s[1] == L':' && s[2] == L'\\' && (c >= L'a' && c <= L'z' || c >= L'A' && c <= L'Z'));
|
||||
|
||||
if (!isAbs)
|
||||
{
|
||||
DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, curDir.GetBuffer(MAX_PATH + 1));
|
||||
curDir.ReleaseBuffer();
|
||||
if (needLength == 0 || needLength > MAX_PATH)
|
||||
return false;
|
||||
if (curDir[curDir.Length() - 1] != L'\\')
|
||||
curDir += L'\\';
|
||||
}
|
||||
res = UString(L"\\\\?\\") + curDir + s;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetLongPath(LPCWSTR path, UString &longPath)
|
||||
{
|
||||
if (GetLongPathBase(path, longPath))
|
||||
return !longPath.IsEmpty();
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace NIO {
|
||||
|
||||
CFileBase::~CFileBase() { Close(); }
|
||||
|
||||
bool CFileBase::Create(LPCTSTR fileName, DWORD desiredAccess,
|
||||
DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
|
||||
{
|
||||
if (!Close())
|
||||
return false;
|
||||
_handle = ::CreateFile(fileName, desiredAccess, shareMode,
|
||||
(LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
|
||||
flagsAndAttributes, (HANDLE)NULL);
|
||||
#ifdef WIN_LONG_PATH2
|
||||
if (_handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
UString longPath;
|
||||
if (GetLongPath(fileName, longPath))
|
||||
_handle = ::CreateFileW(longPath, desiredAccess, shareMode,
|
||||
(LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
|
||||
flagsAndAttributes, (HANDLE)NULL);
|
||||
}
|
||||
#endif
|
||||
return (_handle != INVALID_HANDLE_VALUE);
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool CFileBase::Create(LPCWSTR fileName, DWORD desiredAccess,
|
||||
DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
|
||||
{
|
||||
if (!g_IsNT)
|
||||
return Create(UnicodeStringToMultiByte(fileName, ::AreFileApisANSI() ? CP_ACP : CP_OEMCP),
|
||||
desiredAccess, shareMode, creationDisposition, flagsAndAttributes);
|
||||
if (!Close())
|
||||
return false;
|
||||
_handle = ::CreateFileW(fileName, desiredAccess, shareMode,
|
||||
(LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
|
||||
flagsAndAttributes, (HANDLE)NULL);
|
||||
#ifdef WIN_LONG_PATH
|
||||
if (_handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
UString longPath;
|
||||
if (GetLongPath(fileName, longPath))
|
||||
_handle = ::CreateFileW(longPath, desiredAccess, shareMode,
|
||||
(LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
|
||||
flagsAndAttributes, (HANDLE)NULL);
|
||||
}
|
||||
#endif
|
||||
return (_handle != INVALID_HANDLE_VALUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool CFileBase::Close()
|
||||
{
|
||||
if (_handle == INVALID_HANDLE_VALUE)
|
||||
return true;
|
||||
if (!::CloseHandle(_handle))
|
||||
return false;
|
||||
_handle = INVALID_HANDLE_VALUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CFileBase::GetPosition(UInt64 &position) const
|
||||
{
|
||||
return Seek(0, FILE_CURRENT, position);
|
||||
}
|
||||
|
||||
bool CFileBase::GetLength(UInt64 &length) const
|
||||
{
|
||||
DWORD sizeHigh;
|
||||
DWORD sizeLow = ::GetFileSize(_handle, &sizeHigh);
|
||||
if(sizeLow == 0xFFFFFFFF)
|
||||
if(::GetLastError() != NO_ERROR)
|
||||
return false;
|
||||
length = (((UInt64)sizeHigh) << 32) + sizeLow;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CFileBase::Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const
|
||||
{
|
||||
LARGE_INTEGER value;
|
||||
value.QuadPart = distanceToMove;
|
||||
value.LowPart = ::SetFilePointer(_handle, value.LowPart, &value.HighPart, moveMethod);
|
||||
if (value.LowPart == 0xFFFFFFFF)
|
||||
if(::GetLastError() != NO_ERROR)
|
||||
return false;
|
||||
newPosition = value.QuadPart;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CFileBase::Seek(UInt64 position, UInt64 &newPosition)
|
||||
{
|
||||
return Seek(position, FILE_BEGIN, newPosition);
|
||||
}
|
||||
|
||||
bool CFileBase::SeekToBegin()
|
||||
{
|
||||
UInt64 newPosition;
|
||||
return Seek(0, newPosition);
|
||||
}
|
||||
|
||||
bool CFileBase::SeekToEnd(UInt64 &newPosition)
|
||||
{
|
||||
return Seek(0, FILE_END, newPosition);
|
||||
}
|
||||
|
||||
bool CFileBase::GetFileInformation(CByHandleFileInfo &fileInfo) const
|
||||
{
|
||||
BY_HANDLE_FILE_INFORMATION winFileInfo;
|
||||
if(!::GetFileInformationByHandle(_handle, &winFileInfo))
|
||||
return false;
|
||||
fileInfo.Attributes = winFileInfo.dwFileAttributes;
|
||||
fileInfo.CreationTime = winFileInfo.ftCreationTime;
|
||||
fileInfo.LastAccessTime = winFileInfo.ftLastAccessTime;
|
||||
fileInfo.LastWriteTime = winFileInfo.ftLastWriteTime;
|
||||
fileInfo.VolumeSerialNumber = winFileInfo.dwFileAttributes;
|
||||
fileInfo.Size = (((UInt64)winFileInfo.nFileSizeHigh) << 32) + winFileInfo.nFileSizeLow;
|
||||
fileInfo.NumberOfLinks = winFileInfo.nNumberOfLinks;
|
||||
fileInfo.FileIndex = (((UInt64)winFileInfo.nFileIndexHigh) << 32) + winFileInfo.nFileIndexLow;
|
||||
return true;
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// CInFile
|
||||
|
||||
bool CInFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
|
||||
{ return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); }
|
||||
|
||||
bool CInFile::OpenShared(LPCTSTR fileName, bool shareForWrite)
|
||||
{ return Open(fileName, FILE_SHARE_READ | (shareForWrite ? FILE_SHARE_WRITE : 0), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
|
||||
|
||||
bool CInFile::Open(LPCTSTR fileName)
|
||||
{ return OpenShared(fileName, false); }
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool CInFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
|
||||
{ return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); }
|
||||
|
||||
bool CInFile::OpenShared(LPCWSTR fileName, bool shareForWrite)
|
||||
{ return Open(fileName, FILE_SHARE_READ | (shareForWrite ? FILE_SHARE_WRITE : 0), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
|
||||
|
||||
bool CInFile::Open(LPCWSTR fileName)
|
||||
{ return OpenShared(fileName, false); }
|
||||
#endif
|
||||
|
||||
// ReadFile and WriteFile functions in Windows have BUG:
|
||||
// If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
|
||||
// from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
|
||||
// (Insufficient system resources exist to complete the requested service).
|
||||
|
||||
// Probably in some version of Windows there are problems with other sizes:
|
||||
// for 32 MB (maybe also for 16 MB).
|
||||
// And message can be "Network connection was lost"
|
||||
|
||||
static UInt32 kChunkSizeMax = (1 << 22);
|
||||
|
||||
bool CInFile::ReadPart(void *data, UInt32 size, UInt32 &processedSize)
|
||||
{
|
||||
if (size > kChunkSizeMax)
|
||||
size = kChunkSizeMax;
|
||||
DWORD processedLoc = 0;
|
||||
bool res = BOOLToBool(::ReadFile(_handle, data, size, &processedLoc, NULL));
|
||||
processedSize = (UInt32)processedLoc;
|
||||
return res;
|
||||
}
|
||||
|
||||
bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize)
|
||||
{
|
||||
processedSize = 0;
|
||||
do
|
||||
{
|
||||
UInt32 processedLoc = 0;
|
||||
bool res = ReadPart(data, size, processedLoc);
|
||||
processedSize += processedLoc;
|
||||
if (!res)
|
||||
return false;
|
||||
if (processedLoc == 0)
|
||||
return true;
|
||||
data = (void *)((unsigned char *)data + processedLoc);
|
||||
size -= processedLoc;
|
||||
}
|
||||
while (size > 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// COutFile
|
||||
|
||||
bool COutFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
|
||||
{ return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); }
|
||||
|
||||
static inline DWORD GetCreationDisposition(bool createAlways)
|
||||
{ return createAlways? CREATE_ALWAYS: CREATE_NEW; }
|
||||
|
||||
bool COutFile::Open(LPCTSTR fileName, DWORD creationDisposition)
|
||||
{ return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); }
|
||||
|
||||
bool COutFile::Create(LPCTSTR fileName, bool createAlways)
|
||||
{ return Open(fileName, GetCreationDisposition(createAlways)); }
|
||||
|
||||
#ifndef _UNICODE
|
||||
|
||||
bool COutFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
|
||||
{ return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); }
|
||||
|
||||
bool COutFile::Open(LPCWSTR fileName, DWORD creationDisposition)
|
||||
{ return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); }
|
||||
|
||||
bool COutFile::Create(LPCWSTR fileName, bool createAlways)
|
||||
{ return Open(fileName, GetCreationDisposition(createAlways)); }
|
||||
|
||||
#endif
|
||||
|
||||
bool COutFile::SetTime(const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime)
|
||||
{ return BOOLToBool(::SetFileTime(_handle, creationTime, lastAccessTime, lastWriteTime)); }
|
||||
|
||||
bool COutFile::SetLastWriteTime(const FILETIME *lastWriteTime)
|
||||
{ return SetTime(NULL, NULL, lastWriteTime); }
|
||||
|
||||
bool COutFile::WritePart(const void *data, UInt32 size, UInt32 &processedSize)
|
||||
{
|
||||
if (size > kChunkSizeMax)
|
||||
size = kChunkSizeMax;
|
||||
DWORD processedLoc = 0;
|
||||
bool res = BOOLToBool(::WriteFile(_handle, data, size, &processedLoc, NULL));
|
||||
processedSize = (UInt32)processedLoc;
|
||||
return res;
|
||||
}
|
||||
|
||||
bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize)
|
||||
{
|
||||
processedSize = 0;
|
||||
do
|
||||
{
|
||||
UInt32 processedLoc = 0;
|
||||
bool res = WritePart(data, size, processedLoc);
|
||||
processedSize += processedLoc;
|
||||
if (!res)
|
||||
return false;
|
||||
if (processedLoc == 0)
|
||||
return true;
|
||||
data = (const void *)((const unsigned char *)data + processedLoc);
|
||||
size -= processedLoc;
|
||||
}
|
||||
while (size > 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool COutFile::SetEndOfFile() { return BOOLToBool(::SetEndOfFile(_handle)); }
|
||||
|
||||
bool COutFile::SetLength(UInt64 length)
|
||||
{
|
||||
UInt64 newPosition;
|
||||
if(!Seek(length, newPosition))
|
||||
return false;
|
||||
if(newPosition != length)
|
||||
return false;
|
||||
return SetEndOfFile();
|
||||
}
|
||||
|
||||
}}}
|
||||
@@ -0,0 +1,99 @@
|
||||
// Windows/FileIO.h
|
||||
|
||||
#ifndef __WINDOWS_FILEIO_H
|
||||
#define __WINDOWS_FILEIO_H
|
||||
|
||||
#include "../Common/Types.h"
|
||||
|
||||
namespace NWindows {
|
||||
namespace NFile {
|
||||
namespace NIO {
|
||||
|
||||
struct CByHandleFileInfo
|
||||
{
|
||||
DWORD Attributes;
|
||||
FILETIME CreationTime;
|
||||
FILETIME LastAccessTime;
|
||||
FILETIME LastWriteTime;
|
||||
DWORD VolumeSerialNumber;
|
||||
UInt64 Size;
|
||||
DWORD NumberOfLinks;
|
||||
UInt64 FileIndex;
|
||||
};
|
||||
|
||||
class CFileBase
|
||||
{
|
||||
protected:
|
||||
HANDLE _handle;
|
||||
bool Create(LPCTSTR fileName, DWORD desiredAccess,
|
||||
DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
|
||||
#ifndef _UNICODE
|
||||
bool Create(LPCWSTR fileName, DWORD desiredAccess,
|
||||
DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
|
||||
#endif
|
||||
|
||||
public:
|
||||
CFileBase(): _handle(INVALID_HANDLE_VALUE){};
|
||||
~CFileBase();
|
||||
|
||||
bool Close();
|
||||
|
||||
bool GetPosition(UInt64 &position) const;
|
||||
bool GetLength(UInt64 &length) const;
|
||||
|
||||
bool Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const;
|
||||
bool Seek(UInt64 position, UInt64 &newPosition);
|
||||
bool SeekToBegin();
|
||||
bool SeekToEnd(UInt64 &newPosition);
|
||||
|
||||
bool GetFileInformation(CByHandleFileInfo &fileInfo) const;
|
||||
};
|
||||
|
||||
class CInFile: public CFileBase
|
||||
{
|
||||
public:
|
||||
bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
|
||||
bool OpenShared(LPCTSTR fileName, bool shareForWrite);
|
||||
bool Open(LPCTSTR fileName);
|
||||
#ifndef _UNICODE
|
||||
bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
|
||||
bool OpenShared(LPCWSTR fileName, bool shareForWrite);
|
||||
bool Open(LPCWSTR fileName);
|
||||
#endif
|
||||
bool ReadPart(void *data, UInt32 size, UInt32 &processedSize);
|
||||
bool Read(void *data, UInt32 size, UInt32 &processedSize);
|
||||
};
|
||||
|
||||
class COutFile: public CFileBase
|
||||
{
|
||||
// DWORD m_CreationDisposition;
|
||||
public:
|
||||
// COutFile(): m_CreationDisposition(CREATE_NEW){};
|
||||
bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
|
||||
bool Open(LPCTSTR fileName, DWORD creationDisposition);
|
||||
bool Create(LPCTSTR fileName, bool createAlways);
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
|
||||
bool Open(LPCWSTR fileName, DWORD creationDisposition);
|
||||
bool Create(LPCWSTR fileName, bool createAlways);
|
||||
#endif
|
||||
|
||||
/*
|
||||
void SetOpenCreationDisposition(DWORD creationDisposition)
|
||||
{ m_CreationDisposition = creationDisposition; }
|
||||
void SetOpenCreationDispositionCreateAlways()
|
||||
{ m_CreationDisposition = CREATE_ALWAYS; }
|
||||
*/
|
||||
|
||||
bool SetTime(const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime);
|
||||
bool SetLastWriteTime(const FILETIME *lastWriteTime);
|
||||
bool WritePart(const void *data, UInt32 size, UInt32 &processedSize);
|
||||
bool Write(const void *data, UInt32 size, UInt32 &processedSize);
|
||||
bool SetEndOfFile();
|
||||
bool SetLength(UInt64 length);
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,14 @@
|
||||
// Windows/FileMapping.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Windows/FileMapping.h"
|
||||
|
||||
namespace NWindows {
|
||||
namespace NFile {
|
||||
namespace NMapping {
|
||||
|
||||
|
||||
|
||||
|
||||
}}}
|
||||
@@ -0,0 +1,50 @@
|
||||
// Windows/FileMapping.h
|
||||
|
||||
#ifndef __WINDOWS_FILEMAPPING_H
|
||||
#define __WINDOWS_FILEMAPPING_H
|
||||
|
||||
#include "Windows/Handle.h"
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
namespace NWindows {
|
||||
// namespace NFile {
|
||||
// namespace NMapping {
|
||||
|
||||
class CFileMapping: public CHandle
|
||||
{
|
||||
public:
|
||||
bool Create(HANDLE file, LPSECURITY_ATTRIBUTES attributes,
|
||||
DWORD protect, UINT64 maximumSize, LPCTSTR name)
|
||||
{
|
||||
_handle = ::CreateFileMapping(file, attributes,
|
||||
protect, DWORD(maximumSize >> 32), DWORD(maximumSize), name);
|
||||
return (_handle != NULL);
|
||||
}
|
||||
|
||||
bool Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
|
||||
{
|
||||
_handle = ::OpenFileMapping(desiredAccess, BoolToBOOL(inheritHandle), name);
|
||||
return (_handle != NULL);
|
||||
}
|
||||
|
||||
LPVOID MapViewOfFile(DWORD desiredAccess, UINT64 fileOffset,
|
||||
SIZE_T numberOfBytesToMap)
|
||||
{
|
||||
return ::MapViewOfFile(_handle, desiredAccess,
|
||||
DWORD(fileOffset >> 32), DWORD(fileOffset), numberOfBytesToMap);
|
||||
}
|
||||
|
||||
LPVOID MapViewOfFileEx(DWORD desiredAccess, UINT64 fileOffset,
|
||||
SIZE_T numberOfBytesToMap, LPVOID baseAddress)
|
||||
{
|
||||
return ::MapViewOfFileEx(_handle, desiredAccess,
|
||||
DWORD(fileOffset >> 32), DWORD(fileOffset),
|
||||
numberOfBytesToMap, baseAddress);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,54 @@
|
||||
// Windows/FileName.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Windows/FileName.h"
|
||||
#include "Common/Wildcard.h"
|
||||
|
||||
namespace NWindows {
|
||||
namespace NFile {
|
||||
namespace NName {
|
||||
|
||||
void NormalizeDirPathPrefix(CSysString &dirPath)
|
||||
{
|
||||
if (dirPath.IsEmpty())
|
||||
return;
|
||||
if (dirPath.ReverseFind(kDirDelimiter) != dirPath.Length() - 1)
|
||||
dirPath += kDirDelimiter;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
void NormalizeDirPathPrefix(UString &dirPath)
|
||||
{
|
||||
if (dirPath.IsEmpty())
|
||||
return;
|
||||
if (dirPath.ReverseFind(wchar_t(kDirDelimiter)) != dirPath.Length() - 1)
|
||||
dirPath += wchar_t(kDirDelimiter);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
const wchar_t kExtensionDelimiter = L'.';
|
||||
|
||||
void SplitNameToPureNameAndExtension(const UString &fullName,
|
||||
UString &pureName, UString &extensionDelimiter, UString &extension)
|
||||
{
|
||||
int index = fullName.ReverseFind(kExtensionDelimiter);
|
||||
if (index < 0)
|
||||
{
|
||||
pureName = fullName;
|
||||
extensionDelimiter.Empty();
|
||||
extension.Empty();
|
||||
}
|
||||
else
|
||||
{
|
||||
pureName = fullName.Left(index);
|
||||
extensionDelimiter = kExtensionDelimiter;
|
||||
extension = fullName.Mid(index + 1);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}}}
|
||||
@@ -0,0 +1,27 @@
|
||||
// Windows/FileName.h
|
||||
|
||||
#ifndef __WINDOWS_FILENAME_H
|
||||
#define __WINDOWS_FILENAME_H
|
||||
|
||||
#include "../Common/MyString.h"
|
||||
|
||||
namespace NWindows {
|
||||
namespace NFile {
|
||||
namespace NName {
|
||||
|
||||
const TCHAR kDirDelimiter = CHAR_PATH_SEPARATOR;
|
||||
const TCHAR kAnyStringWildcard = '*';
|
||||
|
||||
void NormalizeDirPathPrefix(CSysString &dirPath); // ensures that it ended with '\\'
|
||||
#ifndef _UNICODE
|
||||
void NormalizeDirPathPrefix(UString &dirPath); // ensures that it ended with '\\'
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
void SplitNameToPureNameAndExtension(const UString &fullName,
|
||||
UString &pureName, UString &extensionDelimiter, UString &extension);
|
||||
#endif
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
// Windows/Handle.h
|
||||
|
||||
#ifndef __WINDOWS_HANDLE_H
|
||||
#define __WINDOWS_HANDLE_H
|
||||
|
||||
namespace NWindows {
|
||||
|
||||
class CHandle
|
||||
{
|
||||
protected:
|
||||
HANDLE _handle;
|
||||
public:
|
||||
operator HANDLE() { return _handle; }
|
||||
CHandle(): _handle(NULL) {}
|
||||
~CHandle() { Close(); }
|
||||
bool Close()
|
||||
{
|
||||
if (_handle == NULL)
|
||||
return true;
|
||||
if (!::CloseHandle(_handle))
|
||||
return false;
|
||||
_handle = NULL;
|
||||
return true;
|
||||
}
|
||||
void Attach(HANDLE handle)
|
||||
{ _handle = handle; }
|
||||
HANDLE Detach()
|
||||
{
|
||||
HANDLE handle = _handle;
|
||||
_handle = NULL;
|
||||
return handle;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,78 @@
|
||||
// Common/MemoryLock.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
namespace NWindows {
|
||||
namespace NSecurity {
|
||||
|
||||
#ifndef _UNICODE
|
||||
typedef BOOL (WINAPI * OpenProcessTokenP)(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);
|
||||
typedef BOOL (WINAPI * LookupPrivilegeValueP)(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid);
|
||||
typedef BOOL (WINAPI * AdjustTokenPrivilegesP)(HANDLE TokenHandle, BOOL DisableAllPrivileges,
|
||||
PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState,PDWORD ReturnLength);
|
||||
#endif
|
||||
|
||||
#ifdef _UNICODE
|
||||
bool EnableLockMemoryPrivilege(
|
||||
#else
|
||||
static bool EnableLockMemoryPrivilege2(HMODULE hModule,
|
||||
#endif
|
||||
bool enable)
|
||||
{
|
||||
#ifndef _UNICODE
|
||||
if (hModule == NULL)
|
||||
return false;
|
||||
OpenProcessTokenP openProcessToken = (OpenProcessTokenP)GetProcAddress(hModule, "OpenProcessToken");
|
||||
LookupPrivilegeValueP lookupPrivilegeValue = (LookupPrivilegeValueP)GetProcAddress(hModule, "LookupPrivilegeValueA" );
|
||||
AdjustTokenPrivilegesP adjustTokenPrivileges = (AdjustTokenPrivilegesP)GetProcAddress(hModule, "AdjustTokenPrivileges");
|
||||
if (openProcessToken == NULL || adjustTokenPrivileges == NULL || lookupPrivilegeValue == NULL)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
HANDLE token;
|
||||
if (!
|
||||
#ifdef _UNICODE
|
||||
::OpenProcessToken
|
||||
#else
|
||||
openProcessToken
|
||||
#endif
|
||||
(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
|
||||
return false;
|
||||
TOKEN_PRIVILEGES tp;
|
||||
bool res = false;
|
||||
if (
|
||||
#ifdef _UNICODE
|
||||
::LookupPrivilegeValue
|
||||
#else
|
||||
lookupPrivilegeValue
|
||||
#endif
|
||||
(NULL, SE_LOCK_MEMORY_NAME, &(tp.Privileges[0].Luid)))
|
||||
{
|
||||
tp.PrivilegeCount = 1;
|
||||
tp.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED: 0;
|
||||
if (
|
||||
#ifdef _UNICODE
|
||||
::AdjustTokenPrivileges
|
||||
#else
|
||||
adjustTokenPrivileges
|
||||
#endif
|
||||
(token, FALSE, &tp, 0, NULL, NULL))
|
||||
res = (GetLastError() == ERROR_SUCCESS);
|
||||
}
|
||||
::CloseHandle(token);
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
bool EnableLockMemoryPrivilege(bool enable)
|
||||
{
|
||||
HMODULE hModule = LoadLibrary(TEXT("Advapi32.dll"));
|
||||
if(hModule == NULL)
|
||||
return false;
|
||||
bool res = EnableLockMemoryPrivilege2(hModule, enable);
|
||||
::FreeLibrary(hModule);
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,13 @@
|
||||
// Windows/MemoryLock.h
|
||||
|
||||
#ifndef __WINDOWS_MEMORYLOCK_H
|
||||
#define __WINDOWS_MEMORYLOCK_H
|
||||
|
||||
namespace NWindows {
|
||||
namespace NSecurity {
|
||||
|
||||
bool EnableLockMemoryPrivilege(bool enable = true);
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,312 @@
|
||||
// Windows/PropVariant.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "PropVariant.h"
|
||||
|
||||
#include "../Common/Defs.h"
|
||||
|
||||
namespace NWindows {
|
||||
namespace NCOM {
|
||||
|
||||
CPropVariant::CPropVariant(const PROPVARIANT& varSrc)
|
||||
{
|
||||
vt = VT_EMPTY;
|
||||
InternalCopy(&varSrc);
|
||||
}
|
||||
|
||||
CPropVariant::CPropVariant(const CPropVariant& varSrc)
|
||||
{
|
||||
vt = VT_EMPTY;
|
||||
InternalCopy(&varSrc);
|
||||
}
|
||||
|
||||
CPropVariant::CPropVariant(BSTR bstrSrc)
|
||||
{
|
||||
vt = VT_EMPTY;
|
||||
*this = bstrSrc;
|
||||
}
|
||||
|
||||
CPropVariant::CPropVariant(LPCOLESTR lpszSrc)
|
||||
{
|
||||
vt = VT_EMPTY;
|
||||
*this = lpszSrc;
|
||||
}
|
||||
|
||||
CPropVariant& CPropVariant::operator=(const CPropVariant& varSrc)
|
||||
{
|
||||
InternalCopy(&varSrc);
|
||||
return *this;
|
||||
}
|
||||
CPropVariant& CPropVariant::operator=(const PROPVARIANT& varSrc)
|
||||
{
|
||||
InternalCopy(&varSrc);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CPropVariant& CPropVariant::operator=(BSTR bstrSrc)
|
||||
{
|
||||
*this = (LPCOLESTR)bstrSrc;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
|
||||
{
|
||||
InternalClear();
|
||||
vt = VT_BSTR;
|
||||
wReserved1 = 0;
|
||||
bstrVal = ::SysAllocString(lpszSrc);
|
||||
if (bstrVal == NULL && lpszSrc != NULL)
|
||||
{
|
||||
vt = VT_ERROR;
|
||||
scode = E_OUTOFMEMORY;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
CPropVariant& CPropVariant::operator=(bool bSrc)
|
||||
{
|
||||
if (vt != VT_BOOL)
|
||||
{
|
||||
InternalClear();
|
||||
vt = VT_BOOL;
|
||||
}
|
||||
boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CPropVariant& CPropVariant::operator=(UInt32 value)
|
||||
{
|
||||
if (vt != VT_UI4)
|
||||
{
|
||||
InternalClear();
|
||||
vt = VT_UI4;
|
||||
}
|
||||
ulVal = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CPropVariant& CPropVariant::operator=(UInt64 value)
|
||||
{
|
||||
if (vt != VT_UI8)
|
||||
{
|
||||
InternalClear();
|
||||
vt = VT_UI8;
|
||||
}
|
||||
uhVal.QuadPart = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CPropVariant& CPropVariant::operator=(const FILETIME &value)
|
||||
{
|
||||
if (vt != VT_FILETIME)
|
||||
{
|
||||
InternalClear();
|
||||
vt = VT_FILETIME;
|
||||
}
|
||||
filetime = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CPropVariant& CPropVariant::operator=(Int32 value)
|
||||
{
|
||||
if (vt != VT_I4)
|
||||
{
|
||||
InternalClear();
|
||||
vt = VT_I4;
|
||||
}
|
||||
lVal = value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
CPropVariant& CPropVariant::operator=(Byte value)
|
||||
{
|
||||
if (vt != VT_UI1)
|
||||
{
|
||||
InternalClear();
|
||||
vt = VT_UI1;
|
||||
}
|
||||
bVal = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CPropVariant& CPropVariant::operator=(Int16 value)
|
||||
{
|
||||
if (vt != VT_I2)
|
||||
{
|
||||
InternalClear();
|
||||
vt = VT_I2;
|
||||
}
|
||||
iVal = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*
|
||||
CPropVariant& CPropVariant::operator=(LONG value)
|
||||
{
|
||||
if (vt != VT_I4)
|
||||
{
|
||||
InternalClear();
|
||||
vt = VT_I4;
|
||||
}
|
||||
lVal = value;
|
||||
return *this;
|
||||
}
|
||||
*/
|
||||
|
||||
static HRESULT MyPropVariantClear(PROPVARIANT *propVariant)
|
||||
{
|
||||
switch(propVariant->vt)
|
||||
{
|
||||
case VT_UI1:
|
||||
case VT_I1:
|
||||
case VT_I2:
|
||||
case VT_UI2:
|
||||
case VT_BOOL:
|
||||
case VT_I4:
|
||||
case VT_UI4:
|
||||
case VT_R4:
|
||||
case VT_INT:
|
||||
case VT_UINT:
|
||||
case VT_ERROR:
|
||||
case VT_FILETIME:
|
||||
case VT_UI8:
|
||||
case VT_R8:
|
||||
case VT_CY:
|
||||
case VT_DATE:
|
||||
propVariant->vt = VT_EMPTY;
|
||||
propVariant->wReserved1 = 0;
|
||||
return S_OK;
|
||||
}
|
||||
return ::VariantClear((VARIANTARG *)propVariant);
|
||||
}
|
||||
|
||||
HRESULT CPropVariant::Clear()
|
||||
{
|
||||
return MyPropVariantClear(this);
|
||||
}
|
||||
|
||||
HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc)
|
||||
{
|
||||
::VariantClear((tagVARIANT *)this);
|
||||
switch(pSrc->vt)
|
||||
{
|
||||
case VT_UI1:
|
||||
case VT_I1:
|
||||
case VT_I2:
|
||||
case VT_UI2:
|
||||
case VT_BOOL:
|
||||
case VT_I4:
|
||||
case VT_UI4:
|
||||
case VT_R4:
|
||||
case VT_INT:
|
||||
case VT_UINT:
|
||||
case VT_ERROR:
|
||||
case VT_FILETIME:
|
||||
case VT_UI8:
|
||||
case VT_R8:
|
||||
case VT_CY:
|
||||
case VT_DATE:
|
||||
memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT));
|
||||
return S_OK;
|
||||
}
|
||||
return ::VariantCopy((tagVARIANT *)this, (tagVARIANT *)(pSrc));
|
||||
}
|
||||
|
||||
|
||||
HRESULT CPropVariant::Attach(PROPVARIANT* pSrc)
|
||||
{
|
||||
HRESULT hr = Clear();
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
memcpy(this, pSrc, sizeof(PROPVARIANT));
|
||||
pSrc->vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CPropVariant::Detach(PROPVARIANT* pDest)
|
||||
{
|
||||
HRESULT hr = MyPropVariantClear(pDest);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
memcpy(pDest, this, sizeof(PROPVARIANT));
|
||||
vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CPropVariant::InternalClear()
|
||||
{
|
||||
HRESULT hr = Clear();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
vt = VT_ERROR;
|
||||
scode = hr;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
void CPropVariant::InternalCopy(const PROPVARIANT* pSrc)
|
||||
{
|
||||
HRESULT hr = Copy(pSrc);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
vt = VT_ERROR;
|
||||
scode = hr;
|
||||
}
|
||||
}
|
||||
|
||||
int CPropVariant::Compare(const CPropVariant &a)
|
||||
{
|
||||
if(vt != a.vt)
|
||||
return 0; // it's mean some bug
|
||||
switch (vt)
|
||||
{
|
||||
case VT_EMPTY:
|
||||
return 0;
|
||||
|
||||
/*
|
||||
case VT_I1:
|
||||
return MyCompare(cVal, a.cVal);
|
||||
*/
|
||||
case VT_UI1:
|
||||
return MyCompare(bVal, a.bVal);
|
||||
|
||||
case VT_I2:
|
||||
return MyCompare(iVal, a.iVal);
|
||||
case VT_UI2:
|
||||
return MyCompare(uiVal, a.uiVal);
|
||||
|
||||
case VT_I4:
|
||||
return MyCompare(lVal, a.lVal);
|
||||
/*
|
||||
case VT_INT:
|
||||
return MyCompare(intVal, a.intVal);
|
||||
*/
|
||||
case VT_UI4:
|
||||
return MyCompare(ulVal, a.ulVal);
|
||||
/*
|
||||
case VT_UINT:
|
||||
return MyCompare(uintVal, a.uintVal);
|
||||
*/
|
||||
case VT_I8:
|
||||
return MyCompare(hVal.QuadPart, a.hVal.QuadPart);
|
||||
case VT_UI8:
|
||||
return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart);
|
||||
|
||||
case VT_BOOL:
|
||||
return -MyCompare(boolVal, a.boolVal);
|
||||
|
||||
case VT_FILETIME:
|
||||
return ::CompareFileTime(&filetime, &a.filetime);
|
||||
case VT_BSTR:
|
||||
return 0; // Not implemented
|
||||
// return MyCompare(aPropVarint.cVal);
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,57 @@
|
||||
// Windows/PropVariant.h
|
||||
|
||||
#ifndef __WINDOWS_PROPVARIANT_H
|
||||
#define __WINDOWS_PROPVARIANT_H
|
||||
|
||||
#include "../Common/MyWindows.h"
|
||||
#include "../Common/Types.h"
|
||||
|
||||
namespace NWindows {
|
||||
namespace NCOM {
|
||||
|
||||
class CPropVariant : public tagPROPVARIANT
|
||||
{
|
||||
public:
|
||||
CPropVariant() { vt = VT_EMPTY; wReserved1 = 0; }
|
||||
~CPropVariant() { Clear(); }
|
||||
CPropVariant(const PROPVARIANT& varSrc);
|
||||
CPropVariant(const CPropVariant& varSrc);
|
||||
CPropVariant(BSTR bstrSrc);
|
||||
CPropVariant(LPCOLESTR lpszSrc);
|
||||
CPropVariant(bool bSrc) { vt = VT_BOOL; wReserved1 = 0; boolVal = (bSrc ? VARIANT_TRUE : VARIANT_FALSE); };
|
||||
CPropVariant(UInt32 value) { vt = VT_UI4; wReserved1 = 0; ulVal = value; }
|
||||
CPropVariant(UInt64 value) { vt = VT_UI8; wReserved1 = 0; uhVal = *(ULARGE_INTEGER*)&value; }
|
||||
CPropVariant(const FILETIME &value) { vt = VT_FILETIME; wReserved1 = 0; filetime = value; }
|
||||
CPropVariant(Int32 value) { vt = VT_I4; wReserved1 = 0; lVal = value; }
|
||||
CPropVariant(Byte value) { vt = VT_UI1; wReserved1 = 0; bVal = value; }
|
||||
CPropVariant(Int16 value) { vt = VT_I2; wReserved1 = 0; iVal = value; }
|
||||
// CPropVariant(LONG value, VARTYPE vtSrc = VT_I4) { vt = vtSrc; lVal = value; }
|
||||
|
||||
CPropVariant& operator=(const CPropVariant& varSrc);
|
||||
CPropVariant& operator=(const PROPVARIANT& varSrc);
|
||||
CPropVariant& operator=(BSTR bstrSrc);
|
||||
CPropVariant& operator=(LPCOLESTR lpszSrc);
|
||||
CPropVariant& operator=(bool bSrc);
|
||||
CPropVariant& operator=(UInt32 value);
|
||||
CPropVariant& operator=(UInt64 value);
|
||||
CPropVariant& operator=(const FILETIME &value);
|
||||
|
||||
CPropVariant& operator=(Int32 value);
|
||||
CPropVariant& operator=(Byte value);
|
||||
CPropVariant& operator=(Int16 value);
|
||||
// CPropVariant& operator=(LONG value);
|
||||
|
||||
HRESULT Clear();
|
||||
HRESULT Copy(const PROPVARIANT* pSrc);
|
||||
HRESULT Attach(PROPVARIANT* pSrc);
|
||||
HRESULT Detach(PROPVARIANT* pDest);
|
||||
|
||||
HRESULT InternalClear();
|
||||
void InternalCopy(const PROPVARIANT* pSrc);
|
||||
|
||||
int Compare(const CPropVariant &a1);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,150 @@
|
||||
// PropVariantConversions.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
// #include <stdio.h>
|
||||
|
||||
#include "PropVariantConversions.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/IntToString.h"
|
||||
|
||||
static UString ConvertUInt64ToString(UInt64 value)
|
||||
{
|
||||
wchar_t buffer[32];
|
||||
ConvertUInt64ToString(value, buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static UString ConvertInt64ToString(Int64 value)
|
||||
{
|
||||
wchar_t buffer[32];
|
||||
ConvertInt64ToString(value, buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static char *UIntToStringSpec(UInt32 value, char *s, int numPos)
|
||||
{
|
||||
char temp[16];
|
||||
int pos = 0;
|
||||
do
|
||||
{
|
||||
temp[pos++] = (char)('0' + value % 10);
|
||||
value /= 10;
|
||||
}
|
||||
while (value != 0);
|
||||
int i;
|
||||
for (i = 0; i < numPos - pos; i++)
|
||||
*s++ = '0';
|
||||
do
|
||||
*s++ = temp[--pos];
|
||||
while (pos > 0);
|
||||
*s = '\0';
|
||||
return s;
|
||||
}
|
||||
|
||||
bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime, bool includeSeconds)
|
||||
{
|
||||
s[0] = '\0';
|
||||
SYSTEMTIME st;
|
||||
if(!BOOLToBool(FileTimeToSystemTime(&ft, &st)))
|
||||
return false;
|
||||
s = UIntToStringSpec(st.wYear, s, 4);
|
||||
*s++ = '-';
|
||||
s = UIntToStringSpec(st.wMonth, s, 2);
|
||||
*s++ = '-';
|
||||
s = UIntToStringSpec(st.wDay, s, 2);
|
||||
if (includeTime)
|
||||
{
|
||||
*s++ = ' ';
|
||||
s = UIntToStringSpec(st.wHour, s, 2);
|
||||
*s++ = ':';
|
||||
s = UIntToStringSpec(st.wMinute, s, 2);
|
||||
if (includeSeconds)
|
||||
{
|
||||
*s++ = ':';
|
||||
UIntToStringSpec(st.wSecond, s, 2);
|
||||
}
|
||||
}
|
||||
/*
|
||||
sprintf(s, "%04d-%02d-%02d", st.wYear, st.wMonth, st.wDay);
|
||||
if (includeTime)
|
||||
{
|
||||
sprintf(s + strlen(s), " %02d:%02d", st.wHour, st.wMinute);
|
||||
if (includeSeconds)
|
||||
sprintf(s + strlen(s), ":%02d", st.wSecond);
|
||||
}
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
UString ConvertFileTimeToString(const FILETIME &fileTime, bool includeTime, bool includeSeconds)
|
||||
{
|
||||
char s[32];
|
||||
ConvertFileTimeToString(fileTime, s, includeTime, includeSeconds);
|
||||
return GetUnicodeString(s);
|
||||
}
|
||||
|
||||
|
||||
UString ConvertPropVariantToString(const PROPVARIANT &propVariant)
|
||||
{
|
||||
switch (propVariant.vt)
|
||||
{
|
||||
case VT_EMPTY:
|
||||
return UString();
|
||||
case VT_BSTR:
|
||||
return propVariant.bstrVal;
|
||||
case VT_UI1:
|
||||
return ConvertUInt64ToString(propVariant.bVal);
|
||||
case VT_UI2:
|
||||
return ConvertUInt64ToString(propVariant.uiVal);
|
||||
case VT_UI4:
|
||||
return ConvertUInt64ToString(propVariant.ulVal);
|
||||
case VT_UI8:
|
||||
return ConvertUInt64ToString(propVariant.uhVal.QuadPart);
|
||||
case VT_FILETIME:
|
||||
return ConvertFileTimeToString(propVariant.filetime, true, true);
|
||||
/*
|
||||
case VT_I1:
|
||||
return ConvertInt64ToString(propVariant.cVal);
|
||||
*/
|
||||
case VT_I2:
|
||||
return ConvertInt64ToString(propVariant.iVal);
|
||||
case VT_I4:
|
||||
return ConvertInt64ToString(propVariant.lVal);
|
||||
case VT_I8:
|
||||
return ConvertInt64ToString(propVariant.hVal.QuadPart);
|
||||
|
||||
case VT_BOOL:
|
||||
return VARIANT_BOOLToBool(propVariant.boolVal) ? L"+" : L"-";
|
||||
default:
|
||||
#ifndef _WIN32_WCE
|
||||
throw 150245;
|
||||
#else
|
||||
return UString();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &propVariant)
|
||||
{
|
||||
switch (propVariant.vt)
|
||||
{
|
||||
case VT_UI1:
|
||||
return propVariant.bVal;
|
||||
case VT_UI2:
|
||||
return propVariant.uiVal;
|
||||
case VT_UI4:
|
||||
return propVariant.ulVal;
|
||||
case VT_UI8:
|
||||
return (UInt64)propVariant.uhVal.QuadPart;
|
||||
default:
|
||||
#ifndef _WIN32_WCE
|
||||
throw 151199;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// Windows/PropVariantConversions.h
|
||||
|
||||
#ifndef __PROPVARIANTCONVERSIONS_H
|
||||
#define __PROPVARIANTCONVERSIONS_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
#include "Common/MyString.h"
|
||||
|
||||
bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime = true, bool includeSeconds = true);
|
||||
UString ConvertFileTimeToString(const FILETIME &ft, bool includeTime = true, bool includeSeconds = true);
|
||||
UString ConvertPropVariantToString(const PROPVARIANT &propVariant);
|
||||
UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &propVariant);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../Common/MyWindows.h"
|
||||
#include "../Common/NewHandler.h"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
// Windows/Synchronization.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Synchronization.h"
|
||||
|
||||
namespace NWindows {
|
||||
namespace NSynchronization {
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,168 @@
|
||||
// Windows/Synchronization.h
|
||||
|
||||
#ifndef __WINDOWS_SYNCHRONIZATION_H
|
||||
#define __WINDOWS_SYNCHRONIZATION_H
|
||||
|
||||
#include "Defs.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../C/Threads.h"
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "Handle.h"
|
||||
#endif
|
||||
|
||||
namespace NWindows {
|
||||
namespace NSynchronization {
|
||||
|
||||
class CBaseEvent
|
||||
{
|
||||
protected:
|
||||
::CEvent _object;
|
||||
public:
|
||||
bool IsCreated() { return Event_IsCreated(&_object) != 0; }
|
||||
operator HANDLE() { return _object.handle; }
|
||||
CBaseEvent() { Event_Construct(&_object); }
|
||||
~CBaseEvent() { Close(); }
|
||||
HRes Close() { return Event_Close(&_object); }
|
||||
#ifdef _WIN32
|
||||
HRes Create(bool manualReset, bool initiallyOwn, LPCTSTR name = NULL,
|
||||
LPSECURITY_ATTRIBUTES securityAttributes = NULL)
|
||||
{
|
||||
_object.handle = ::CreateEvent(securityAttributes, BoolToBOOL(manualReset),
|
||||
BoolToBOOL(initiallyOwn), name);
|
||||
if (_object.handle != 0)
|
||||
return 0;
|
||||
return ::GetLastError();
|
||||
}
|
||||
HRes Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
|
||||
{
|
||||
_object.handle = ::OpenEvent(desiredAccess, BoolToBOOL(inheritHandle), name);
|
||||
if (_object.handle != 0)
|
||||
return 0;
|
||||
return ::GetLastError();
|
||||
}
|
||||
#endif
|
||||
|
||||
HRes Set() { return Event_Set(&_object); }
|
||||
// bool Pulse() { return BOOLToBool(::PulseEvent(_handle)); }
|
||||
HRes Reset() { return Event_Reset(&_object); }
|
||||
HRes Lock() { return Event_Wait(&_object); }
|
||||
};
|
||||
|
||||
class CManualResetEvent: public CBaseEvent
|
||||
{
|
||||
public:
|
||||
HRes Create(bool initiallyOwn = false)
|
||||
{
|
||||
return ManualResetEvent_Create(&_object, initiallyOwn ? 1: 0);
|
||||
}
|
||||
HRes CreateIfNotCreated()
|
||||
{
|
||||
if (IsCreated())
|
||||
return 0;
|
||||
return ManualResetEvent_CreateNotSignaled(&_object);
|
||||
}
|
||||
#ifdef _WIN32
|
||||
HRes CreateWithName(bool initiallyOwn, LPCTSTR name)
|
||||
{
|
||||
return CBaseEvent::Create(true, initiallyOwn, name);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
class CAutoResetEvent: public CBaseEvent
|
||||
{
|
||||
public:
|
||||
HRes Create()
|
||||
{
|
||||
return AutoResetEvent_CreateNotSignaled(&_object);
|
||||
}
|
||||
HRes CreateIfNotCreated()
|
||||
{
|
||||
if (IsCreated())
|
||||
return 0;
|
||||
return AutoResetEvent_CreateNotSignaled(&_object);
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
class CObject: public CHandle
|
||||
{
|
||||
public:
|
||||
HRes Lock(DWORD timeoutInterval = INFINITE)
|
||||
{ return (::WaitForSingleObject(_handle, timeoutInterval) == WAIT_OBJECT_0 ? 0 : ::GetLastError()); }
|
||||
};
|
||||
class CMutex: public CObject
|
||||
{
|
||||
public:
|
||||
HRes Create(bool initiallyOwn, LPCTSTR name = NULL,
|
||||
LPSECURITY_ATTRIBUTES securityAttributes = NULL)
|
||||
{
|
||||
_handle = ::CreateMutex(securityAttributes, BoolToBOOL(initiallyOwn), name);
|
||||
if (_handle != 0)
|
||||
return 0;
|
||||
return ::GetLastError();
|
||||
}
|
||||
HRes Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
|
||||
{
|
||||
_handle = ::OpenMutex(desiredAccess, BoolToBOOL(inheritHandle), name);
|
||||
if (_handle != 0)
|
||||
return 0;
|
||||
return ::GetLastError();
|
||||
}
|
||||
HRes Release()
|
||||
{
|
||||
return ::ReleaseMutex(_handle) ? 0 : ::GetLastError();
|
||||
}
|
||||
};
|
||||
class CMutexLock
|
||||
{
|
||||
CMutex *_object;
|
||||
public:
|
||||
CMutexLock(CMutex &object): _object(&object) { _object->Lock(); }
|
||||
~CMutexLock() { _object->Release(); }
|
||||
};
|
||||
#endif
|
||||
|
||||
class CSemaphore
|
||||
{
|
||||
::CSemaphore _object;
|
||||
public:
|
||||
CSemaphore() { Semaphore_Construct(&_object); }
|
||||
~CSemaphore() { Close(); }
|
||||
HRes Close() { return Semaphore_Close(&_object); }
|
||||
operator HANDLE() { return _object.handle; }
|
||||
HRes Create(UInt32 initiallyCount, UInt32 maxCount)
|
||||
{
|
||||
return Semaphore_Create(&_object, initiallyCount, maxCount);
|
||||
}
|
||||
HRes Release() { return Semaphore_Release1(&_object); }
|
||||
HRes Release(UInt32 releaseCount) { return Semaphore_ReleaseN(&_object, releaseCount); }
|
||||
HRes Lock() { return Semaphore_Wait(&_object); }
|
||||
};
|
||||
|
||||
class CCriticalSection
|
||||
{
|
||||
::CCriticalSection _object;
|
||||
public:
|
||||
CCriticalSection() { CriticalSection_Init(&_object); }
|
||||
~CCriticalSection() { CriticalSection_Delete(&_object); }
|
||||
void Enter() { CriticalSection_Enter(&_object); }
|
||||
void Leave() { CriticalSection_Leave(&_object); }
|
||||
};
|
||||
|
||||
class CCriticalSectionLock
|
||||
{
|
||||
CCriticalSection *_object;
|
||||
void Unlock() { _object->Leave(); }
|
||||
public:
|
||||
CCriticalSectionLock(CCriticalSection &object): _object(&object) {_object->Enter(); }
|
||||
~CCriticalSectionLock() { Unlock(); }
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,64 @@
|
||||
// Windows/System.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "System.h"
|
||||
|
||||
namespace NWindows {
|
||||
namespace NSystem {
|
||||
|
||||
UInt32 GetNumberOfProcessors()
|
||||
{
|
||||
SYSTEM_INFO systemInfo;
|
||||
GetSystemInfo(&systemInfo);
|
||||
return (UInt32)systemInfo.dwNumberOfProcessors;
|
||||
}
|
||||
|
||||
#if !defined(_WIN64) && defined(__GNUC__)
|
||||
|
||||
typedef struct _MY_MEMORYSTATUSEX {
|
||||
DWORD dwLength;
|
||||
DWORD dwMemoryLoad;
|
||||
DWORDLONG ullTotalPhys;
|
||||
DWORDLONG ullAvailPhys;
|
||||
DWORDLONG ullTotalPageFile;
|
||||
DWORDLONG ullAvailPageFile;
|
||||
DWORDLONG ullTotalVirtual;
|
||||
DWORDLONG ullAvailVirtual;
|
||||
DWORDLONG ullAvailExtendedVirtual;
|
||||
} MY_MEMORYSTATUSEX, *MY_LPMEMORYSTATUSEX;
|
||||
|
||||
#else
|
||||
|
||||
#define MY_MEMORYSTATUSEX MEMORYSTATUSEX
|
||||
#define MY_LPMEMORYSTATUSEX LPMEMORYSTATUSEX
|
||||
|
||||
#endif
|
||||
|
||||
typedef BOOL (WINAPI *GlobalMemoryStatusExP)(MY_LPMEMORYSTATUSEX lpBuffer);
|
||||
|
||||
UInt64 GetRamSize()
|
||||
{
|
||||
MY_MEMORYSTATUSEX stat;
|
||||
stat.dwLength = sizeof(stat);
|
||||
#ifdef _WIN64
|
||||
if (!::GlobalMemoryStatusEx(&stat))
|
||||
return 0;
|
||||
return stat.ullTotalPhys;
|
||||
#else
|
||||
GlobalMemoryStatusExP globalMemoryStatusEx = (GlobalMemoryStatusExP)
|
||||
::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")),
|
||||
"GlobalMemoryStatusEx");
|
||||
if (globalMemoryStatusEx != 0)
|
||||
if (globalMemoryStatusEx(&stat))
|
||||
return stat.ullTotalPhys;
|
||||
{
|
||||
MEMORYSTATUS stat;
|
||||
stat.dwLength = sizeof(stat);
|
||||
GlobalMemoryStatus(&stat);
|
||||
return stat.dwTotalPhys;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Windows/System.h
|
||||
|
||||
#ifndef __WINDOWS_SYSTEM_H
|
||||
#define __WINDOWS_SYSTEM_H
|
||||
|
||||
#include "../Common/Types.h"
|
||||
|
||||
namespace NWindows {
|
||||
namespace NSystem {
|
||||
|
||||
UInt32 GetNumberOfProcessors();
|
||||
UInt64 GetRamSize();
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
// Windows/Thread.h
|
||||
|
||||
#ifndef __WINDOWS_THREAD_H
|
||||
#define __WINDOWS_THREAD_H
|
||||
|
||||
#include "Defs.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../C/Threads.h"
|
||||
}
|
||||
|
||||
namespace NWindows {
|
||||
|
||||
class CThread
|
||||
{
|
||||
::CThread thread;
|
||||
public:
|
||||
CThread() { Thread_Construct(&thread); }
|
||||
~CThread() { Close(); }
|
||||
bool IsCreated() { return Thread_WasCreated(&thread) != 0; }
|
||||
HRes Close() { return Thread_Close(&thread); }
|
||||
HRes Create(THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter)
|
||||
{ return Thread_Create(&thread, startAddress, parameter); }
|
||||
HRes Wait() { return Thread_Wait(&thread); }
|
||||
|
||||
#ifdef _WIN32
|
||||
DWORD Resume() { return ::ResumeThread(thread.handle); }
|
||||
DWORD Suspend() { return ::SuspendThread(thread.handle); }
|
||||
bool Terminate(DWORD exitCode) { return BOOLToBool(::TerminateThread(thread.handle, exitCode)); }
|
||||
int GetPriority() { return ::GetThreadPriority(thread.handle); }
|
||||
bool SetPriority(int priority) { return BOOLToBool(::SetThreadPriority(thread.handle, priority)); }
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,66 @@
|
||||
// Windows/Time.h
|
||||
|
||||
#ifndef __WINDOWS_TIME_H
|
||||
#define __WINDOWS_TIME_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
namespace NWindows {
|
||||
namespace NTime {
|
||||
|
||||
inline bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime)
|
||||
{
|
||||
return BOOLToBool(::DosDateTimeToFileTime(UInt16(dosTime >> 16),
|
||||
UInt16(dosTime & 0xFFFF), &fileTime));
|
||||
}
|
||||
|
||||
const UInt32 kHighDosTime = 0xFF9FBF7D;
|
||||
const UInt32 kLowDosTime = 0x210000;
|
||||
|
||||
inline bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime)
|
||||
{
|
||||
WORD datePart, timePart;
|
||||
if (!::FileTimeToDosDateTime(&fileTime, &datePart, &timePart))
|
||||
{
|
||||
if (fileTime.dwHighDateTime >= 0x01C00000) // 2000
|
||||
dosTime = kHighDosTime;
|
||||
else
|
||||
dosTime = kLowDosTime;
|
||||
return false;
|
||||
}
|
||||
dosTime = (((UInt32)datePart) << 16) + timePart;
|
||||
return true;
|
||||
}
|
||||
|
||||
const UInt32 kNumTimeQuantumsInSecond = 10000000;
|
||||
const UInt64 kUnixTimeStartValue = ((UInt64)kNumTimeQuantumsInSecond) * 60 * 60 * 24 * 134774;
|
||||
|
||||
inline void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime)
|
||||
{
|
||||
UInt64 v = kUnixTimeStartValue + ((UInt64)unixTime) * kNumTimeQuantumsInSecond;
|
||||
fileTime.dwLowDateTime = (DWORD)v;
|
||||
fileTime.dwHighDateTime = (DWORD)(v >> 32);
|
||||
}
|
||||
|
||||
inline bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime)
|
||||
{
|
||||
UInt64 winTime = (((UInt64)fileTime.dwHighDateTime) << 32) + fileTime.dwLowDateTime;
|
||||
if (winTime < kUnixTimeStartValue)
|
||||
{
|
||||
unixTime = 0;
|
||||
return false;
|
||||
}
|
||||
winTime = (winTime - kUnixTimeStartValue) / kNumTimeQuantumsInSecond;
|
||||
if (winTime > 0xFFFFFFFF)
|
||||
{
|
||||
unixTime = 0xFFFFFFFF;
|
||||
return false;
|
||||
}
|
||||
unixTime = (UInt32)winTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user