|
|
|
@ -390,6 +390,10 @@ static const char *GetVdsError(DWORD error_code)
|
|
|
|
|
return "The offline operation failed.";
|
|
|
|
|
case 0x80042598: // VDS_E_BAD_REVISION_NUMBER
|
|
|
|
|
return "The operation could not be completed because the specified revision number is not supported.";
|
|
|
|
|
case 0x80042599: // VDS_E_SHRINK_USER_CANCELLED
|
|
|
|
|
return "The shrink operation was cancelled by the user.";
|
|
|
|
|
case 0x8004259a: // VDS_E_SHRINK_DIRTY_VOLUME
|
|
|
|
|
return "The volume you have selected to shrink may be corrupted. Use Chkdsk to fix the corruption problem, and then try again.";
|
|
|
|
|
case 0x00042700: // VDS_S_NAME_TRUNCATED
|
|
|
|
|
return "The name was set successfully but had to be truncated.";
|
|
|
|
|
case 0x80042701: // VDS_E_NAME_NOT_UNIQUE
|
|
|
|
@ -601,6 +605,13 @@ const char *WindowsErrorString(DWORD error_code)
|
|
|
|
|
|
|
|
|
|
typedef BOOL(*VDS_Callback_PF)(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data);
|
|
|
|
|
|
|
|
|
|
static BOOL g_vds_available = TRUE;
|
|
|
|
|
|
|
|
|
|
BOOL VDS_IsLastAvaliable(void)
|
|
|
|
|
{
|
|
|
|
|
return g_vds_available;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC IVdsService * VDS_InitService(void)
|
|
|
|
|
{
|
|
|
|
|
HRESULT hr;
|
|
|
|
@ -627,6 +638,7 @@ STATIC IVdsService * VDS_InitService(void)
|
|
|
|
|
{
|
|
|
|
|
VDS_SET_ERROR(hr);
|
|
|
|
|
Log("Could not load VDS Service: 0x%x", LASTERR);
|
|
|
|
|
g_vds_available = FALSE;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -640,6 +652,7 @@ STATIC IVdsService * VDS_InitService(void)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Log("VDS init OK, service %p", pService);
|
|
|
|
|
g_vds_available = TRUE;
|
|
|
|
|
return pService;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1061,16 +1074,16 @@ STATIC BOOL VDS_CallBack_DeletePartition(void *pInterface, VDS_DISK_PROP *pDiskP
|
|
|
|
|
HRESULT hr;
|
|
|
|
|
VDS_PARTITION_PROP* prop_array = NULL;
|
|
|
|
|
LONG i, prop_array_size;
|
|
|
|
|
ULONG PartNumber = (ULONG)data;
|
|
|
|
|
UINT64 PartOffset = data;
|
|
|
|
|
IVdsAdvancedDisk *pAdvancedDisk = (IVdsAdvancedDisk *)pInterface;
|
|
|
|
|
|
|
|
|
|
if (PartNumber == 0)
|
|
|
|
|
if (PartOffset == 0)
|
|
|
|
|
{
|
|
|
|
|
Log("Deleting ALL partitions from disk '%S':", pDiskProp->pwszName);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Log("Deleting partition(%ld) from disk '%S':", PartNumber, pDiskProp->pwszName);
|
|
|
|
|
Log("Deleting partition(offset=%llu) from disk '%S':", PartOffset, pDiskProp->pwszName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Query the partition data, so we can get the start offset, which we need for deletion
|
|
|
|
@ -1080,7 +1093,7 @@ STATIC BOOL VDS_CallBack_DeletePartition(void *pInterface, VDS_DISK_PROP *pDiskP
|
|
|
|
|
r = TRUE;
|
|
|
|
|
for (i = 0; i < prop_array_size; i++)
|
|
|
|
|
{
|
|
|
|
|
if (PartNumber == 0 || PartNumber == prop_array[i].ulPartitionNumber)
|
|
|
|
|
if (PartOffset == 0 || PartOffset == prop_array[i].ullOffset)
|
|
|
|
|
{
|
|
|
|
|
Log("* Partition %d (offset: %lld, size: %llu) delete it.",
|
|
|
|
|
prop_array[i].ulPartitionNumber, prop_array[i].ullOffset, (ULONGLONG)prop_array[i].ullSize);
|
|
|
|
@ -1127,9 +1140,9 @@ BOOL VDS_DeleteAllPartitions(int DriveIndex)
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL VDS_DeleteVtoyEFIPartition(int DriveIndex)
|
|
|
|
|
BOOL VDS_DeleteVtoyEFIPartition(int DriveIndex, UINT64 EfiPartOffset)
|
|
|
|
|
{
|
|
|
|
|
BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK, DriveIndex, VDS_CallBack_DeletePartition, 2);
|
|
|
|
|
BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK, DriveIndex, VDS_CallBack_DeletePartition, EfiPartOffset);
|
|
|
|
|
Log("VDS_DeleteVtoyEFIPartition %d ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL");
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
@ -1138,6 +1151,7 @@ STATIC BOOL VDS_CallBack_ChangeEFIAttr(void *pInterface, VDS_DISK_PROP *pDiskPro
|
|
|
|
|
{
|
|
|
|
|
BOOL r = FALSE;
|
|
|
|
|
HRESULT hr;
|
|
|
|
|
VDS_PARA *VdsPara = (VDS_PARA *)data;
|
|
|
|
|
VDS_PARTITION_PROP* prop_array = NULL;
|
|
|
|
|
LONG i, prop_array_size;
|
|
|
|
|
CHANGE_ATTRIBUTES_PARAMETERS AttrPara;
|
|
|
|
@ -1151,12 +1165,13 @@ STATIC BOOL VDS_CallBack_ChangeEFIAttr(void *pInterface, VDS_DISK_PROP *pDiskPro
|
|
|
|
|
{
|
|
|
|
|
if (prop_array[i].ullSize == VENTOY_EFI_PART_SIZE &&
|
|
|
|
|
prop_array[i].PartitionStyle == VDS_PST_GPT &&
|
|
|
|
|
memcmp(prop_array[i].Gpt.name, L"VTOYEFI", 7 * 2) == 0)
|
|
|
|
|
memcmp(prop_array[i].Gpt.name, L"VTOYEFI", 7 * 2) == 0 &&
|
|
|
|
|
VdsPara->Offset == prop_array[i].ullOffset)
|
|
|
|
|
{
|
|
|
|
|
Log("* Partition %d (offset: %lld, size: %llu, Attr:0x%llx)", prop_array[i].ulPartitionNumber,
|
|
|
|
|
Log("** Partition %d (offset: %lld, size: %llu, Attr:0x%llx)", prop_array[i].ulPartitionNumber,
|
|
|
|
|
prop_array[i].ullOffset, (ULONGLONG)prop_array[i].ullSize, prop_array[i].Gpt.attributes);
|
|
|
|
|
|
|
|
|
|
if (prop_array[i].Gpt.attributes == data)
|
|
|
|
|
if (prop_array[i].Gpt.attributes == VdsPara->Attr)
|
|
|
|
|
{
|
|
|
|
|
Log("Attribute match, No need to change.");
|
|
|
|
|
r = TRUE;
|
|
|
|
@ -1164,7 +1179,7 @@ STATIC BOOL VDS_CallBack_ChangeEFIAttr(void *pInterface, VDS_DISK_PROP *pDiskPro
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
AttrPara.style = VDS_PST_GPT;
|
|
|
|
|
AttrPara.GptPartInfo.attributes = data;
|
|
|
|
|
AttrPara.GptPartInfo.attributes = VdsPara->Attr;
|
|
|
|
|
hr = IVdsAdvancedDisk_ChangeAttributes(pAdvancedDisk, prop_array[i].ullOffset, &AttrPara);
|
|
|
|
|
if (hr == S_OK)
|
|
|
|
|
{
|
|
|
|
@ -1191,10 +1206,15 @@ STATIC BOOL VDS_CallBack_ChangeEFIAttr(void *pInterface, VDS_DISK_PROP *pDiskPro
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL VDS_ChangeVtoyEFIAttr(int DriveIndex, UINT64 Attr)
|
|
|
|
|
BOOL VDS_ChangeVtoyEFIAttr(int DriveIndex, UINT64 Offset, UINT64 Attr)
|
|
|
|
|
{
|
|
|
|
|
BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK, DriveIndex, VDS_CallBack_ChangeEFIAttr, Attr);
|
|
|
|
|
Log("VDS_ChangeVtoyEFIAttr %d ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL");
|
|
|
|
|
VDS_PARA Para;
|
|
|
|
|
|
|
|
|
|
Para.Attr = Attr;
|
|
|
|
|
Para.Offset = Offset;
|
|
|
|
|
|
|
|
|
|
BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK, DriveIndex, VDS_CallBack_ChangeEFIAttr, (UINT64)&Para);
|
|
|
|
|
Log("VDS_ChangeVtoyEFIAttr %d (offset:%llu) ret:%d (%s)", DriveIndex, Offset, ret, ret ? "SUCCESS" : "FAIL");
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1238,6 +1258,7 @@ BOOL VDS_ChangeVtoyEFI2ESP(int DriveIndex, UINT64 Offset)
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BOOL VDS_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset)
|
|
|
|
|
{
|
|
|
|
|
VDS_PARA Para;
|
|
|
|
@ -1251,154 +1272,70 @@ BOOL VDS_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset)
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
STATIC BOOL VDS_CallBack_CreateVtoyEFI(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data)
|
|
|
|
|
STATIC BOOL CHKDSK_Volume(CHAR LogicalDrive)
|
|
|
|
|
{
|
|
|
|
|
HRESULT hr, hr2;
|
|
|
|
|
ULONG completed;
|
|
|
|
|
IVdsAsync* pAsync;
|
|
|
|
|
CREATE_PARTITION_PARAMETERS para;
|
|
|
|
|
IVdsCreatePartitionEx *pCreatePartitionEx = (IVdsCreatePartitionEx *)pInterface;
|
|
|
|
|
VDS_PARA *VdsPara = (VDS_PARA *)data;
|
|
|
|
|
|
|
|
|
|
(void)pDiskProp;
|
|
|
|
|
|
|
|
|
|
memset(¶, 0, sizeof(para));
|
|
|
|
|
para.style = VDS_PST_GPT;
|
|
|
|
|
memcpy(&(para.GptPartInfo.partitionType), &VdsPara->Type, sizeof(GUID));
|
|
|
|
|
memcpy(&(para.GptPartInfo.partitionId), &VdsPara->Id, sizeof(GUID));
|
|
|
|
|
para.GptPartInfo.attributes = VdsPara->Attr;
|
|
|
|
|
memcpy(para.GptPartInfo.name, VdsPara->Name, sizeof(WCHAR)* VdsPara->NameLen);
|
|
|
|
|
CHAR CmdBuf[1024];
|
|
|
|
|
STARTUPINFOA Si;
|
|
|
|
|
PROCESS_INFORMATION Pi;
|
|
|
|
|
|
|
|
|
|
hr = IVdsCreatePartitionEx_CreatePartitionEx(pCreatePartitionEx, VdsPara->Offset, VENTOY_EFI_PART_SIZE, 512, ¶, &pAsync);
|
|
|
|
|
while (SUCCEEDED(hr))
|
|
|
|
|
{
|
|
|
|
|
hr = IVdsAsync_QueryStatus(pAsync, &hr2, &completed);
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
|
{
|
|
|
|
|
hr = hr2;
|
|
|
|
|
if (hr == S_OK)
|
|
|
|
|
{
|
|
|
|
|
Log("Disk create partition QueryStatus OK, %lu%%", completed);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else if (hr == VDS_E_OPERATION_PENDING)
|
|
|
|
|
{
|
|
|
|
|
Log("Disk partition finish: %lu%%", completed);
|
|
|
|
|
hr = S_OK;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Log("QueryStatus invalid status:0x%lx", hr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Sleep(1000);
|
|
|
|
|
}
|
|
|
|
|
if ((!IsFileExist("C:\\Windows\\System32\\chkdsk.exe")) || (LogicalDrive == 0))
|
|
|
|
|
{
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hr != S_OK)
|
|
|
|
|
{
|
|
|
|
|
VDS_SET_ERROR(hr);
|
|
|
|
|
Log("Could not create partition, err:0x%lx(%s)", LASTERR, WindowsErrorString(hr));
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
GetStartupInfoA(&Si);
|
|
|
|
|
Si.dwFlags |= STARTF_USESHOWWINDOW;
|
|
|
|
|
Si.wShowWindow = SW_HIDE;
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
sprintf_s(CmdBuf, sizeof(CmdBuf), "C:\\Windows\\System32\\chkdsk.exe %C: /f", LogicalDrive);
|
|
|
|
|
|
|
|
|
|
BOOL VDS_CreateVtoyEFIPart(int DriveIndex, UINT64 Offset)
|
|
|
|
|
{
|
|
|
|
|
VDS_PARA Para;
|
|
|
|
|
GUID WindowsDataPartType = { 0xebd0a0a2, 0xb9e5, 0x4433, { 0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7 } };
|
|
|
|
|
GUID EspPartType = { 0xc12a7328, 0xf81f, 0x11d2, { 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } };
|
|
|
|
|
Log("CreateProcess <%s>", CmdBuf);
|
|
|
|
|
CreateProcessA(NULL, CmdBuf, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);
|
|
|
|
|
|
|
|
|
|
Log("VDS_CreateVtoyEFIPart %u Offset:%llu Sector:%llu", DriveIndex, Offset, Offset / 512);
|
|
|
|
|
Log("Wair process ...");
|
|
|
|
|
WaitForSingleObject(Pi.hProcess, INFINITE);
|
|
|
|
|
Log("Process finished...");
|
|
|
|
|
|
|
|
|
|
memset(&Para, 0, sizeof(Para));
|
|
|
|
|
Para.Attr = 0x8000000000000000ULL;
|
|
|
|
|
Para.Offset = Offset;
|
|
|
|
|
memcpy(Para.Name, L"VTOYEFI", 7 * 2);
|
|
|
|
|
Para.NameLen = 7;
|
|
|
|
|
memcpy(&(Para.Type), &EspPartType, sizeof(GUID));
|
|
|
|
|
CoCreateGuid(&(Para.Id));
|
|
|
|
|
CHECK_CLOSE_HANDLE(Pi.hProcess);
|
|
|
|
|
CHECK_CLOSE_HANDLE(Pi.hThread);
|
|
|
|
|
|
|
|
|
|
BOOL ret = VDS_DiskCommProc(INTF_CREATEPARTITIONEX, DriveIndex, VDS_CallBack_CreateVtoyEFI, (UINT64)&Para);
|
|
|
|
|
Log("VDS_CreateVtoyEFIPart %d ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL");
|
|
|
|
|
return ret;
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
STATIC BOOL VDS_CallBack_FormatVtoyEFI(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data)
|
|
|
|
|
STATIC BOOL VDS_CallBack_ShrinkVolume(void* pInterface, VDS_DISK_PROP* pDiskProp, UINT64 data)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
HRESULT hr, hr2;
|
|
|
|
|
IVdsVolume* pVolume = (IVdsVolume*)pInterface;
|
|
|
|
|
ULONG completed;
|
|
|
|
|
IVdsAsync* pAsync;
|
|
|
|
|
IVdsDiskPartitionMF *pPartitionMF = (IVdsDiskPartitionMF *)pInterface;
|
|
|
|
|
IVdsAsync* pAsync;
|
|
|
|
|
VDS_PARA *VdsPara = (VDS_PARA *)data;
|
|
|
|
|
|
|
|
|
|
(void)pDiskProp;
|
|
|
|
|
|
|
|
|
|
hr = IVdsPartitionMF_FormatPartitionEx(pPartitionMF, VdsPara->Offset, L"FAT", 0x0100, 0, VdsPara->Name, TRUE, TRUE, FALSE, &pAsync);
|
|
|
|
|
while (SUCCEEDED(hr))
|
|
|
|
|
|
|
|
|
|
Log("VDS_CallBack_ShrinkVolume (%C:) (%llu) ...", VdsPara->DriveLetter, (ULONGLONG)VdsPara->Offset);
|
|
|
|
|
|
|
|
|
|
hr = IVdsVolume_Shrink(pVolume, (ULONGLONG)VdsPara->Offset, &pAsync);
|
|
|
|
|
if (hr == VDS_E_SHRINK_DIRTY_VOLUME)
|
|
|
|
|
{
|
|
|
|
|
hr = IVdsAsync_QueryStatus(pAsync, &hr2, &completed);
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
|
Log("Volume %C: is dirty, run chkdsk and retry.", VdsPara->DriveLetter);
|
|
|
|
|
CHKDSK_Volume(VdsPara->DriveLetter);
|
|
|
|
|
|
|
|
|
|
hr = IVdsVolume_Shrink(pVolume, (ULONGLONG)VdsPara->Offset, &pAsync);
|
|
|
|
|
if (hr == VDS_E_SHRINK_DIRTY_VOLUME)
|
|
|
|
|
{
|
|
|
|
|
hr = hr2;
|
|
|
|
|
if (hr == S_OK)
|
|
|
|
|
{
|
|
|
|
|
Log("Disk format partition QueryStatus OK, %lu%%", completed);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else if (hr == VDS_E_OPERATION_PENDING)
|
|
|
|
|
Log("################################################################");
|
|
|
|
|
Log("################################################################");
|
|
|
|
|
for (i = 0; i < 20; i++)
|
|
|
|
|
{
|
|
|
|
|
Log("Disk format finish: %lu%%", completed);
|
|
|
|
|
hr = S_OK;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Log("QueryStatus invalid status:0x%lx", hr);
|
|
|
|
|
Log("###### Volume dirty, Please run \"chkdsk /f %C:\" and retry. ######", VdsPara->Name[0]);
|
|
|
|
|
}
|
|
|
|
|
Log("################################################################");
|
|
|
|
|
Log("################################################################");
|
|
|
|
|
}
|
|
|
|
|
Sleep(1000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hr != S_OK)
|
|
|
|
|
{
|
|
|
|
|
VDS_SET_ERROR(hr);
|
|
|
|
|
Log("Could not format partition, err:0x%lx (%s)", LASTERR, WindowsErrorString(hr));
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Not supported for removable disk
|
|
|
|
|
BOOL VDS_FormatVtoyEFIPart(int DriveIndex, UINT64 Offset)
|
|
|
|
|
{
|
|
|
|
|
VDS_PARA Para;
|
|
|
|
|
|
|
|
|
|
memset(&Para, 0, sizeof(Para));
|
|
|
|
|
Para.Offset = Offset;
|
|
|
|
|
memcpy(Para.Name, L"VTOYEFI", 7 * 2);
|
|
|
|
|
|
|
|
|
|
BOOL ret = VDS_DiskCommProc(INTF_PARTITIONMF, DriveIndex, VDS_CallBack_FormatVtoyEFI, (UINT64)&Para);
|
|
|
|
|
Log("VDS_FormatVtoyEFIPart %d ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL");
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC BOOL VDS_CallBack_ShrinkVolume(void* pInterface, VDS_DISK_PROP* pDiskProp, UINT64 data)
|
|
|
|
|
{
|
|
|
|
|
HRESULT hr, hr2;
|
|
|
|
|
IVdsVolume* pVolume = (IVdsVolume*)pInterface;
|
|
|
|
|
ULONG completed;
|
|
|
|
|
IVdsAsync* pAsync;
|
|
|
|
|
|
|
|
|
|
(void)pDiskProp;
|
|
|
|
|
|
|
|
|
|
Log("VDS_CallBack_ShrinkVolume (%llu) ...", (ULONGLONG)data);
|
|
|
|
|
|
|
|
|
|
hr = IVdsVolume_Shrink(pVolume, (ULONGLONG)data, &pAsync);
|
|
|
|
|
|
|
|
|
|
while (SUCCEEDED(hr))
|
|
|
|
|
{
|
|
|
|
|
hr = IVdsAsync_QueryStatus(pAsync, &hr2, &completed);
|
|
|
|
@ -1427,18 +1364,24 @@ STATIC BOOL VDS_CallBack_ShrinkVolume(void* pInterface, VDS_DISK_PROP* pDiskProp
|
|
|
|
|
{
|
|
|
|
|
VDS_SET_ERROR(hr);
|
|
|
|
|
Log("Could not ShrinkVolume, 0x%x err:0x%lx (%s)", hr, LASTERR, WindowsErrorString(hr));
|
|
|
|
|
|
|
|
|
|
VDS_SET_ERROR(hr);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL VDS_ShrinkVolume(const char* VolumeGuid, UINT64 ReduceBytes)
|
|
|
|
|
BOOL VDS_ShrinkVolume(int DriveIndex, const char* VolumeGuid, CHAR DriveLetter, UINT64 OldBytes, UINT64 ReduceBytes)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
BOOL ret = FALSE;
|
|
|
|
|
WCHAR wGuid[128] = { 0 };
|
|
|
|
|
const char *guid = NULL;
|
|
|
|
|
VDS_PARA Para;
|
|
|
|
|
|
|
|
|
|
(VOID)DriveIndex;
|
|
|
|
|
(VOID)OldBytes;
|
|
|
|
|
|
|
|
|
|
guid = strstr(VolumeGuid, "{");
|
|
|
|
|
if (!guid)
|
|
|
|
@ -1451,7 +1394,10 @@ BOOL VDS_ShrinkVolume(const char* VolumeGuid, UINT64 ReduceBytes)
|
|
|
|
|
wGuid[i] = guid[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = VDS_VolumeCommProc(INTF_VOLUME, wGuid, VDS_CallBack_ShrinkVolume, ReduceBytes);
|
|
|
|
|
Log("VDS_ShrinkVolume ret:%d (%s)", ret, ret ? "SUCCESS" : "FAIL");
|
|
|
|
|
Para.Offset = ReduceBytes;
|
|
|
|
|
Para.DriveLetter = DriveLetter;
|
|
|
|
|
|
|
|
|
|
ret = VDS_VolumeCommProc(INTF_VOLUME, wGuid, VDS_CallBack_ShrinkVolume, (UINT64)&Para);
|
|
|
|
|
Log("VDS_ShrinkVolume %C: ret:%d (%s)", DriveLetter, ret, ret ? "SUCCESS" : "FAIL");
|
|
|
|
|
return ret;
|
|
|
|
|
}
|