const DWORD g_sysReserveBytes = 5 * 1024;
const tstring g_diskEmulatorFileName = _T("DiskEmulatorFile_1C14D9BC-3056-4fdf-9BE5-CEFC9C7EF074");
tstring GetDiskName(const char* disk)
{
tstring __disk;
if (NULL == disk)
{
tstring curDir;
GetMainModuleDir(curDir);
assert(curDir.size() >= 2);
__disk = curDir.substr(0, 2);
}
else
{
__disk = Utf8ToTStr(disk);
}
return __disk;
}
bool IsFreeSpaceEnough(DWORD freeSpaceBytes, const char* disk/* = NULL*/)
{
RemoveDiskEmulatorFile(disk);
bool result = false;
tstring __disk = GetDiskName(disk);
ULARGE_INTEGER avalBytes = {0};
if (GetDiskFreeSpaceEx(__disk.c_str(), &avalBytes, NULL, NULL))
{
result = (avalBytes.HighPart > 0) || ((__int64)avalBytes.LowPart > (__int64(freeSpaceBytes) + g_sysReserveBytes));
}
return result;
}
bool SetFreeSpaceBytes(DWORD freeSpaceBytes, const char* disk/* = NULL*/)
{
RemoveDiskEmulatorFile(disk);
bool result = false;
tstring __disk = GetDiskName(disk);
ULARGE_INTEGER avalBytes = {0};
if (GetDiskFreeSpaceEx(__disk.c_str(), &avalBytes, NULL, NULL))
{
__int64 totalSize = (((__int64)avalBytes.HighPart) << 32) + avalBytes.LowPart;
if (((__int64)freeSpaceBytes + g_sysReserveBytes) <= totalSize)
{
__int64 emulatorFileSize = totalSize - freeSpaceBytes;
DWORD high = (DWORD)(emulatorFileSize >> 32);
DWORD low = (DWORD)(emulatorFileSize & 0xffffffff);
HANDLE file = CreateFile(JoinPath(__disk, g_diskEmulatorFileName).c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (file != INVALID_HANDLE_VALUE)
{
SetFilePointer(file, low, (PLONG)&high, FILE_BEGIN);
if (SetEndOfFile(file) != FALSE)
{
result = true;
}
CloseHandle(file);
}
}
}
return result;
}
bool RemoveDiskEmulatorFile(const char* disk/* = NULL*/)
{
bool result = true;
tstring filePath = JoinPath(GetDiskName(disk), g_diskEmulatorFileName);
if (FileExists(filePath))
{
result = (_tremove(filePath.c_str()) == 0);
}
return result;
}