// 3. Filter out the crap we don't need.\r
static const char *GetVdsError(DWORD error_code)\r
{\r
+ static char code[32];\r
+\r
+ sprintf_s(code, sizeof(code), "[0x%08x]", error_code);\r
+\r
switch (error_code) {\r
case 0x80042400: // VDS_E_NOT_SUPPORTED\r
return "The operation is not supported by the object.";\r
return "The offline operation failed.";\r
case 0x80042598: // VDS_E_BAD_REVISION_NUMBER\r
return "The operation could not be completed because the specified revision number is not supported.";\r
+ case 0x80042599: // VDS_E_SHRINK_USER_CANCELLED\r
+ return "The shrink operation was cancelled by the user.";\r
+ case 0x8004259a: // VDS_E_SHRINK_DIRTY_VOLUME\r
+ return "The volume you have selected to shrink may be corrupted. Use Chkdsk to fix the corruption problem, and then try again.";\r
case 0x00042700: // VDS_S_NAME_TRUNCATED\r
return "The name was set successfully but had to be truncated.";\r
case 0x80042701: // VDS_E_NAME_NOT_UNIQUE\r
case 0x80042918: // VDS_E_COMPRESSION_NOT_SUPPORTED\r
return "The specified file system does not support compression.";\r
default:\r
- return NULL;\r
+ return code;\r
}\r
}\r
\r
#define INTF_ADVANCEDDISK2 2\r
#define INTF_CREATEPARTITIONEX 3\r
#define INTF_PARTITIONMF 4\r
+#define INTF_VOLUME 5\r
+#define INTF_VOLUME_MF3 6\r
\r
/* \r
* Some code and functions in the file are copied from rufus.\r
#define IVdsVolume_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)\r
#define IVdsVolume_Release(This) (This)->lpVtbl->Release(This)\r
#define IVdsVolumeMF3_QueryVolumeGuidPathnames(This, pwszPathArray, pulNumberOfPaths) (This)->lpVtbl->QueryVolumeGuidPathnames(This,pwszPathArray,pulNumberOfPaths)\r
+#define IVdsVolumeMF_Format(This, type, pwsszLabel, dwUnitAllocationSize, bForce, bQuickFormat, bEnableCompression, ppAsync) (This)->lpVtbl->Format(This, type, pwsszLabel, dwUnitAllocationSize, bForce, bQuickFormat, bEnableCompression, ppAsync)\r
#define IVdsVolumeMF3_FormatEx2(This, pwszFileSystemTypeName, usFileSystemRevision, ulDesiredUnitAllocationSize, pwszLabel, Options, ppAsync) (This)->lpVtbl->FormatEx2(This, pwszFileSystemTypeName, usFileSystemRevision, ulDesiredUnitAllocationSize, pwszLabel, Options, ppAsync)\r
#define IVdsVolumeMF3_Release(This) (This)->lpVtbl->Release(This)\r
#define IVdsVolume_GetProperties(This, pVolumeProperties) (This)->lpVtbl->GetProperties(This,pVolumeProperties)\r
#define IVdsAsync_Wait(This,pHrResult,pAsyncOut) (This)->lpVtbl->Wait(This,pHrResult,pAsyncOut)\r
#define IVdsAsync_Release(This) (This)->lpVtbl->Release(This)\r
\r
+#define IVdsVolume_Shrink(This, ullNumberOfBytesToRemove, ppAsync) (This)->lpVtbl->Shrink(This, ullNumberOfBytesToRemove, ppAsync)\r
+\r
#define IUnknown_QueryInterface(This, a, b) (This)->lpVtbl->QueryInterface(This,a,b)\r
#define IUnknown_Release(This) (This)->lpVtbl->Release(This)\r
\r
typedef BOOL(*VDS_Callback_PF)(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data);\r
\r
+static BOOL g_vds_available = TRUE;\r
+\r
+BOOL VDS_IsLastAvaliable(void)\r
+{\r
+ return g_vds_available;\r
+}\r
+\r
STATIC IVdsService * VDS_InitService(void)\r
{\r
HRESULT hr;\r
{\r
VDS_SET_ERROR(hr);\r
Log("Could not load VDS Service: 0x%x", LASTERR);\r
+ g_vds_available = FALSE;\r
return NULL;\r
}\r
\r
}\r
\r
Log("VDS init OK, service %p", pService);\r
+ g_vds_available = TRUE;\r
return pService;\r
}\r
\r
+STATIC BOOL VDS_VolumeCommProc(int intf, const WCHAR* wVolumeGuid, VDS_Callback_PF callback, UINT64 data)\r
+{\r
+ int Pos = 0;\r
+ BOOL Find = FALSE;\r
+ BOOL r = FALSE;\r
+ HRESULT hr;\r
+ ULONG ulFetched;\r
+ IUnknown* pUnk = NULL;\r
+ IEnumVdsObject* pEnum = NULL;\r
+ IVdsService* pService = NULL;\r
+\r
+ pService = VDS_InitService();\r
+ if (!pService)\r
+ {\r
+ Log("Could not query VDS Service");\r
+ goto out;\r
+ }\r
+\r
+ // Query the VDS Service Providers\r
+ hr = IVdsService_QueryProviders(pService, VDS_QUERY_SOFTWARE_PROVIDERS, &pEnum);\r
+ if (hr != S_OK)\r
+ {\r
+ VDS_SET_ERROR(hr);\r
+ Log("Could not query VDS Service Providers: 0x%lx %u", hr, LASTERR);\r
+ goto out;\r
+ }\r
+\r
+ while (IEnumVdsObject_Next(pEnum, 1, &pUnk, &ulFetched) == S_OK)\r
+ {\r
+ IVdsProvider* pProvider;\r
+ IVdsSwProvider* pSwProvider;\r
+ IEnumVdsObject* pEnumPack;\r
+ IUnknown* pPackUnk;\r
+\r
+ // Get VDS Provider\r
+ hr = IUnknown_QueryInterface(pUnk, &IID_IVdsProvider, (void**)&pProvider);\r
+ IUnknown_Release(pUnk);\r
+ if (hr != S_OK)\r
+ {\r
+ VDS_SET_ERROR(hr);\r
+ Log("Could not get VDS Provider: %u", LASTERR);\r
+ goto out;\r
+ }\r
+\r
+ // Get VDS Software Provider\r
+ hr = IVdsSwProvider_QueryInterface(pProvider, &IID_IVdsSwProvider, (void**)&pSwProvider);\r
+ IVdsProvider_Release(pProvider);\r
+ if (hr != S_OK)\r
+ {\r
+ VDS_SET_ERROR(hr);\r
+ Log("Could not get VDS Software Provider: %u", LASTERR);\r
+ goto out;\r
+ }\r
+\r
+ // Get VDS Software Provider Packs\r
+ hr = IVdsSwProvider_QueryPacks(pSwProvider, &pEnumPack);\r
+ IVdsSwProvider_Release(pSwProvider);\r
+ if (hr != S_OK)\r
+ {\r
+ VDS_SET_ERROR(hr);\r
+ Log("Could not get VDS Software Provider Packs: %u", LASTERR);\r
+ goto out;\r
+ }\r
+\r
+ // Enumerate Provider Packs\r
+ while (IEnumVdsObject_Next(pEnumPack, 1, &pPackUnk, &ulFetched) == S_OK)\r
+ {\r
+ IVdsPack* pPack;\r
+ IEnumVdsObject* pEnumVolume;\r
+ IUnknown* pVolumeUnk;\r
+\r
+ hr = IUnknown_QueryInterface(pPackUnk, &IID_IVdsPack, (void**)&pPack);\r
+ IUnknown_Release(pPackUnk);\r
+ if (hr != S_OK)\r
+ {\r
+ VDS_SET_ERROR(hr);\r
+ Log("Could not query VDS Software Provider Pack: %u", LASTERR);\r
+ goto out;\r
+ }\r
+\r
+ // Use the pack interface to access the volume\r
+ hr = IVdsPack_QueryVolumes(pPack, &pEnumVolume);;\r
+ if (hr != S_OK) {\r
+ VDS_SET_ERROR(hr);\r
+ Log("Could not query VDS volume: %u", LASTERR);\r
+ goto out;\r
+ }\r
+\r
+ // List disks\r
+ while (IEnumVdsObject_Next(pEnumVolume, 1, &pVolumeUnk, &ulFetched) == S_OK)\r
+ {\r
+ IVdsVolume* pVolume;\r
+ IVdsVolumeMF3* pVolumeMF3;\r
+ LPWSTR* wszPathArray;\r
+ ULONG ulNumberOfPaths;\r
+\r
+ // Get the disk interface.\r
+ hr = IUnknown_QueryInterface(pVolumeUnk, &IID_IVdsVolumeMF3, (void**)&pVolumeMF3);\r
+ if (hr != S_OK) {\r
+ VDS_SET_ERROR(hr);\r
+ Log("Could not query VDS Volume Interface: %u", LASTERR);\r
+ goto out;\r
+ }\r
+\r
+ // Get the volume properties\r
+ hr = IVdsVolumeMF3_QueryVolumeGuidPathnames(pVolumeMF3, &wszPathArray, &ulNumberOfPaths);\r
+ if ((hr != S_OK) && (hr != VDS_S_PROPERTIES_INCOMPLETE)) \r
+ {\r
+ Log("Could not query VDS VolumeMF3 GUID PathNames: %s", GetVdsError(hr));\r
+ IVdsVolume_Release(pVolumeMF3);\r
+ IUnknown_Release(pVolumeUnk);\r
+ continue;\r
+ }\r
+\r
+ Log("Get Volume %d %lu <%S>", intf, ulNumberOfPaths, wszPathArray[0]);\r
+\r
+ if ((ulNumberOfPaths >= 1) && wcsstr(wszPathArray[0], wVolumeGuid))\r
+ {\r
+ Find = TRUE;\r
+ Log("Call back for this Volume %d <%S>", intf, wVolumeGuid);\r
+\r
+ if (INTF_VOLUME_MF3 == intf)\r
+ {\r
+ r = callback(pVolumeMF3, NULL, data);\r
+ }\r
+ else if (INTF_VOLUME == intf)\r
+ {\r
+ // Get the disk interface.\r
+ hr = IUnknown_QueryInterface(pVolumeUnk, &IID_IVdsVolume, (void**)&pVolume);\r
+ if (hr != S_OK) {\r
+ VDS_SET_ERROR(hr);\r
+ Log("Could not query VDS Volume Interface: %u", LASTERR);\r
+ }\r
+ else {\r
+ r = callback(pVolume, NULL, data);\r
+ IVdsVolume_Release(pVolume);\r
+ }\r
+ }\r
+ }\r
+\r
+ CoTaskMemFree(wszPathArray);\r
+ IVdsVolume_Release(pVolumeMF3);\r
+ IUnknown_Release(pVolumeUnk);\r
+\r
+ if (Find)\r
+ {\r
+ goto out;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+out:\r
+ return r;\r
+}\r
+\r
\r
STATIC BOOL VDS_DiskCommProc(int intf, int DriveIndex, VDS_Callback_PF callback, UINT64 data)\r
{\r
HRESULT hr;\r
VDS_PARTITION_PROP* prop_array = NULL;\r
LONG i, prop_array_size;\r
- ULONG PartNumber = (ULONG)data;\r
+ UINT64 PartOffset = data;\r
IVdsAdvancedDisk *pAdvancedDisk = (IVdsAdvancedDisk *)pInterface;\r
\r
- if (PartNumber == 0)\r
+ if (PartOffset == 0)\r
{\r
Log("Deleting ALL partitions from disk '%S':", pDiskProp->pwszName);\r
}\r
else\r
{\r
- Log("Deleting partition(%ld) from disk '%S':", PartNumber, pDiskProp->pwszName);\r
+ Log("Deleting partition(offset=%llu) from disk '%S':", PartOffset, pDiskProp->pwszName);\r
}\r
\r
// Query the partition data, so we can get the start offset, which we need for deletion\r
r = TRUE;\r
for (i = 0; i < prop_array_size; i++) \r
{\r
- if (PartNumber == 0 || PartNumber == prop_array[i].ulPartitionNumber)\r
+ if (PartOffset == 0 || PartOffset == prop_array[i].ullOffset)\r
{\r
Log("* Partition %d (offset: %lld, size: %llu) delete it.",\r
prop_array[i].ulPartitionNumber, prop_array[i].ullOffset, (ULONGLONG)prop_array[i].ullSize);\r
return ret;\r
}\r
\r
-BOOL VDS_DeleteVtoyEFIPartition(int DriveIndex)\r
+BOOL VDS_DeleteVtoyEFIPartition(int DriveIndex, UINT64 EfiPartOffset)\r
{\r
- BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK, DriveIndex, VDS_CallBack_DeletePartition, 2);\r
+ BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK, DriveIndex, VDS_CallBack_DeletePartition, EfiPartOffset);\r
Log("VDS_DeleteVtoyEFIPartition %d ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL");\r
return ret;\r
}\r
{\r
BOOL r = FALSE;\r
HRESULT hr;\r
+ VDS_PARA *VdsPara = (VDS_PARA *)data;\r
VDS_PARTITION_PROP* prop_array = NULL;\r
LONG i, prop_array_size;\r
CHANGE_ATTRIBUTES_PARAMETERS AttrPara;\r
{\r
if (prop_array[i].ullSize == VENTOY_EFI_PART_SIZE &&\r
prop_array[i].PartitionStyle == VDS_PST_GPT &&\r
- memcmp(prop_array[i].Gpt.name, L"VTOYEFI", 7 * 2) == 0)\r
+ memcmp(prop_array[i].Gpt.name, L"VTOYEFI", 7 * 2) == 0 &&\r
+ VdsPara->Offset == prop_array[i].ullOffset)\r
{\r
- Log("* Partition %d (offset: %lld, size: %llu, Attr:0x%llx)", prop_array[i].ulPartitionNumber,\r
+ Log("** Partition %d (offset: %lld, size: %llu, Attr:0x%llx)", prop_array[i].ulPartitionNumber,\r
prop_array[i].ullOffset, (ULONGLONG)prop_array[i].ullSize, prop_array[i].Gpt.attributes);\r
\r
- if (prop_array[i].Gpt.attributes == data)\r
+ if (prop_array[i].Gpt.attributes == VdsPara->Attr)\r
{\r
Log("Attribute match, No need to change.");\r
r = TRUE;\r
else\r
{\r
AttrPara.style = VDS_PST_GPT;\r
- AttrPara.GptPartInfo.attributes = data;\r
+ AttrPara.GptPartInfo.attributes = VdsPara->Attr;\r
hr = IVdsAdvancedDisk_ChangeAttributes(pAdvancedDisk, prop_array[i].ullOffset, &AttrPara);\r
if (hr == S_OK)\r
{\r
return r;\r
}\r
\r
-BOOL VDS_ChangeVtoyEFIAttr(int DriveIndex, UINT64 Attr)\r
+BOOL VDS_ChangeVtoyEFIAttr(int DriveIndex, UINT64 Offset, UINT64 Attr)\r
{\r
- BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK, DriveIndex, VDS_CallBack_ChangeEFIAttr, Attr); \r
- Log("VDS_ChangeVtoyEFIAttr %d ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL");\r
+ VDS_PARA Para;\r
+\r
+ Para.Attr = Attr;\r
+ Para.Offset = Offset;\r
+\r
+ BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK, DriveIndex, VDS_CallBack_ChangeEFIAttr, (UINT64)&Para);\r
+ Log("VDS_ChangeVtoyEFIAttr %d (offset:%llu) ret:%d (%s)", DriveIndex, Offset, ret, ret ? "SUCCESS" : "FAIL");\r
return ret;\r
}\r
\r
BOOL r = FALSE;\r
HRESULT hr;\r
IVdsAdvancedDisk2 *pAdvancedDisk2 = (IVdsAdvancedDisk2 *)pInterface;\r
- VDS_PARA *VdsPara = (VDS_PARA *)(ULONG)data;\r
+ VDS_PARA *VdsPara = (VDS_PARA *)data;\r
CHANGE_PARTITION_TYPE_PARAMETERS para;\r
\r
para.style = VDS_PST_GPT;\r
memcpy(&(Para.Type), &EspPartType, sizeof(GUID));\r
Para.Offset = Offset;\r
\r
- BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK2, DriveIndex, VDS_CallBack_ChangeEFIType, (ULONG)&Para);\r
+ BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK2, DriveIndex, VDS_CallBack_ChangeEFIType, (UINT64)&Para);\r
Log("VDS_ChangeVtoyEFI2ESP %d ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL");\r
return ret;\r
}\r
\r
+\r
BOOL VDS_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset)\r
{\r
VDS_PARA Para;\r
memcpy(&(Para.Type), &WindowsDataPartType, sizeof(GUID));\r
Para.Offset = Offset;\r
\r
- BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK2, DriveIndex, VDS_CallBack_ChangeEFIType, (ULONG)&Para);\r
+ BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK2, DriveIndex, VDS_CallBack_ChangeEFIType, (UINT64)&Para);\r
Log("VDS_ChangeVtoyEFI2Basic %d ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL");\r
return ret;\r
}\r
\r
+STATIC BOOL CHKDSK_Volume(CHAR LogicalDrive)\r
+{\r
+ CHAR CmdBuf[1024];\r
+ STARTUPINFOA Si;\r
+ PROCESS_INFORMATION Pi;\r
\r
-STATIC BOOL VDS_CallBack_CreateVtoyEFI(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data)\r
+ if ((!IsFileExist("C:\\Windows\\System32\\chkdsk.exe")) || (LogicalDrive == 0))\r
+ {\r
+ return FALSE;\r
+ }\r
+\r
+ GetStartupInfoA(&Si);\r
+ Si.dwFlags |= STARTF_USESHOWWINDOW;\r
+ Si.wShowWindow = SW_HIDE;\r
+\r
+ sprintf_s(CmdBuf, sizeof(CmdBuf), "C:\\Windows\\System32\\chkdsk.exe %C: /f", LogicalDrive);\r
+\r
+ Log("CreateProcess <%s>", CmdBuf);\r
+ CreateProcessA(NULL, CmdBuf, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);\r
+\r
+ Log("Wair process ...");\r
+ WaitForSingleObject(Pi.hProcess, INFINITE);\r
+ Log("Process finished...");\r
+\r
+ CHECK_CLOSE_HANDLE(Pi.hProcess);\r
+ CHECK_CLOSE_HANDLE(Pi.hThread);\r
+\r
+ return TRUE;\r
+}\r
+\r
+STATIC HRESULT VDS_RealShrinkVolume(void* pInterface, VDS_DISK_PROP* pDiskProp, UINT64 data)\r
{\r
- HRESULT hr, hr2;\r
- ULONG completed;\r
- IVdsAsync* pAsync;\r
- CREATE_PARTITION_PARAMETERS para;\r
- IVdsCreatePartitionEx *pCreatePartitionEx = (IVdsCreatePartitionEx *)pInterface;\r
- VDS_PARA *VdsPara = (VDS_PARA *)(ULONG)data;\r
+ HRESULT hr, hr2;\r
+ IVdsVolume* pVolume = (IVdsVolume*)pInterface;\r
+ ULONG completed;\r
+ IVdsAsync* pAsync;\r
+ VDS_PARA* VdsPara = (VDS_PARA*)data;\r
\r
- (void)pDiskProp;\r
+ (void)pDiskProp;\r
\r
- memset(¶, 0, sizeof(para));\r
- para.style = VDS_PST_GPT;\r
- memcpy(&(para.GptPartInfo.partitionType), &VdsPara->Type, sizeof(GUID));\r
- memcpy(&(para.GptPartInfo.partitionId), &VdsPara->Id, sizeof(GUID));\r
- para.GptPartInfo.attributes = VdsPara->Attr;\r
- memcpy(para.GptPartInfo.name, VdsPara->Name, sizeof(WCHAR)* VdsPara->NameLen);\r
+ Log("VDS_ShrinkVolume (%C:) (%llu) ...", VdsPara->DriveLetter, (ULONGLONG)VdsPara->Offset);\r
\r
- hr = IVdsCreatePartitionEx_CreatePartitionEx(pCreatePartitionEx, VdsPara->Offset, VENTOY_EFI_PART_SIZE, 512, ¶, &pAsync);\r
- while (SUCCEEDED(hr))\r
- {\r
- hr = IVdsAsync_QueryStatus(pAsync, &hr2, &completed);\r
- if (SUCCEEDED(hr))\r
- {\r
- hr = hr2;\r
- if (hr == S_OK)\r
- {\r
- Log("Disk create partition QueryStatus OK, %lu%%", completed);\r
- break;\r
- }\r
- else if (hr == VDS_E_OPERATION_PENDING)\r
- {\r
- Log("Disk partition finish: %lu%%", completed);\r
- hr = S_OK;\r
- }\r
- else\r
- {\r
- Log("QueryStatus invalid status:0x%lx", hr);\r
- }\r
- }\r
- Sleep(1000);\r
- }\r
+ hr = IVdsVolume_Shrink(pVolume, (ULONGLONG)VdsPara->Offset, &pAsync);\r
\r
- if (hr != S_OK)\r
- {\r
- VDS_SET_ERROR(hr);\r
- Log("Could not create partition, err:0x%lx(%s)", LASTERR, WindowsErrorString(hr));\r
- return FALSE;\r
- }\r
+ while (SUCCEEDED(hr))\r
+ {\r
+ hr = IVdsAsync_QueryStatus(pAsync, &hr2, &completed);\r
+ if (SUCCEEDED(hr))\r
+ {\r
+ hr = hr2;\r
+ if (hr == S_OK)\r
+ {\r
+ Log("ShrinkVolume QueryStatus OK, %lu%%", completed);\r
+ break;\r
+ }\r
+ else if (hr == VDS_E_OPERATION_PENDING)\r
+ {\r
+ Log("ShrinkVolume: %lu%%", completed);\r
+ hr = S_OK;\r
+ }\r
+ else\r
+ {\r
+ Log("ShrinkVolume invalid status:0x%lx", hr);\r
+ }\r
+ }\r
+ Sleep(1000);\r
+ }\r
\r
- return TRUE;\r
+ return hr;\r
}\r
\r
-BOOL VDS_CreateVtoyEFIPart(int DriveIndex, UINT64 Offset)\r
+STATIC BOOL VDS_CallBack_ShrinkVolume(void* pInterface, VDS_DISK_PROP* pDiskProp, UINT64 data)\r
{\r
- VDS_PARA Para;\r
- GUID WindowsDataPartType = { 0xebd0a0a2, 0xb9e5, 0x4433, { 0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7 } };\r
- GUID EspPartType = { 0xc12a7328, 0xf81f, 0x11d2, { 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } };\r
+ int i;\r
+ HRESULT hr;\r
+ VDS_PARA *VdsPara = (VDS_PARA *)data;\r
\r
- Log("VDS_CreateVtoyEFIPart %u Offset:%llu Sector:%llu", DriveIndex, Offset, Offset / 512);\r
+ Log("VDS_CallBack_ShrinkVolume (%C:) (%llu) ...", VdsPara->DriveLetter, (ULONGLONG)VdsPara->Offset);\r
\r
- memset(&Para, 0, sizeof(Para));\r
- Para.Attr = 0x8000000000000000ULL;\r
- Para.Offset = Offset;\r
- memcpy(Para.Name, L"VTOYEFI", 7 * 2);\r
- Para.NameLen = 7;\r
- memcpy(&(Para.Type), &EspPartType, sizeof(GUID));\r
- CoCreateGuid(&(Para.Id));\r
+ hr = VDS_RealShrinkVolume(pInterface, pDiskProp, data);\r
+ if (hr == VDS_E_SHRINK_DIRTY_VOLUME)\r
+ {\r
+ Log("Volume %C: is dirty, run chkdsk and retry.", VdsPara->DriveLetter);\r
+ CHKDSK_Volume(VdsPara->DriveLetter);\r
\r
- BOOL ret = VDS_DiskCommProc(INTF_CREATEPARTITIONEX, DriveIndex, VDS_CallBack_CreateVtoyEFI, (ULONG)&Para); \r
- Log("VDS_CreateVtoyEFIPart %d ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL");\r
- return ret; \r
+ hr = VDS_RealShrinkVolume(pInterface, pDiskProp, data);\r
+ if (hr == VDS_E_SHRINK_DIRTY_VOLUME)\r
+ {\r
+ Log("################################################################");\r
+ Log("################################################################");\r
+ for (i = 0; i < 20; i++)\r
+ {\r
+ Log("###### Volume dirty, Please run \"chkdsk /f %C:\" and retry. ######", VdsPara->Name[0]);\r
+ }\r
+ Log("################################################################");\r
+ Log("################################################################");\r
+ }\r
+ }\r
+\r
+ if (hr != S_OK)\r
+ {\r
+ VDS_SET_ERROR(hr);\r
+ Log("Could not ShrinkVolume, 0x%x err:0x%lx (%s)", hr, LASTERR, WindowsErrorString(hr));\r
+\r
+ VDS_SET_ERROR(hr);\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
}\r
\r
+BOOL VDS_ShrinkVolume(int DriveIndex, const char* VolumeGuid, CHAR DriveLetter, UINT64 OldBytes, UINT64 ReduceBytes)\r
+{\r
+ int i;\r
+ BOOL ret = FALSE;\r
+ WCHAR wGuid[128] = { 0 };\r
+ const char *guid = NULL;\r
+ VDS_PARA Para;\r
+\r
+ (VOID)DriveIndex;\r
+ (VOID)OldBytes;\r
+\r
+ guid = strstr(VolumeGuid, "{");\r
+ if (!guid)\r
+ {\r
+ return FALSE;\r
+ }\r
+\r
+ for (i = 0; i < 128 && guid[i]; i++)\r
+ {\r
+ wGuid[i] = guid[i];\r
+ }\r
+\r
+ Para.Offset = ReduceBytes;\r
+ Para.DriveLetter = DriveLetter;\r
\r
-STATIC BOOL VDS_CallBack_FormatVtoyEFI(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data)\r
+ ret = VDS_VolumeCommProc(INTF_VOLUME, wGuid, VDS_CallBack_ShrinkVolume, (UINT64)&Para);\r
+ Log("VDS_ShrinkVolume %C: ret:%d (%s)", DriveLetter, ret, ret ? "SUCCESS" : "FAIL");\r
+ return ret;\r
+}\r
+\r
+\r
+STATIC BOOL VDS_CallBack_FormatVolume(void* pInterface, VDS_DISK_PROP* pDiskProp, UINT64 data)\r
{\r
+ int fs;\r
HRESULT hr, hr2;\r
ULONG completed;\r
- IVdsAsync* pAsync; \r
- IVdsDiskPartitionMF *pPartitionMF = (IVdsDiskPartitionMF *)pInterface;\r
- VDS_PARA *VdsPara = (VDS_PARA *)(ULONG)data;\r
-\r
- (void)pDiskProp;\r
+ IVdsAsync* pAsync;\r
+ IVdsVolumeMF3* pVolume = (IVdsVolumeMF3*)pInterface;\r
+ WCHAR* pFs = NULL;\r
+ VDS_PARA* VdsPara = (VDS_PARA*)data;\r
\r
- hr = IVdsPartitionMF_FormatPartitionEx(pPartitionMF, VdsPara->Offset, L"FAT", 0x0100, 0, VdsPara->Name, TRUE, TRUE, FALSE, &pAsync);\r
+ fs = (int)VdsPara->Attr;\r
+ pFs = GetVentoyFsFmtNameByTypeW(fs);\r
+ \r
+ Log("VDS_CallBack_FormatVolume (%C:) (%s) ClusterSize:%u ...", VdsPara->DriveLetter, GetVentoyFsFmtNameByTypeA(fs), VdsPara->ClusterSize);\r
+\r
+ hr = IVdsVolumeMF3_FormatEx2(pVolume, pFs, 0, VdsPara->ClusterSize, L"Ventoy", VDS_FSOF_FORCE | VDS_FSOF_QUICK, &pAsync);\r
while (SUCCEEDED(hr))\r
{\r
hr = IVdsAsync_QueryStatus(pAsync, &hr2, &completed);\r
hr = hr2;\r
if (hr == S_OK)\r
{\r
- Log("Disk format partition QueryStatus OK, %lu%%", completed);\r
+ Log("FormatVolume QueryStatus OK, %lu%%", completed);\r
break;\r
}\r
else if (hr == VDS_E_OPERATION_PENDING)\r
{\r
- Log("Disk format finish: %lu%%", completed);\r
+ Log("FormatVolume: %lu%%", completed);\r
hr = S_OK;\r
}\r
else\r
{\r
- Log("QueryStatus invalid status:0x%lx", hr);\r
+ Log("FormatVolume invalid status:0x%lx", hr);\r
}\r
}\r
Sleep(1000);\r
if (hr != S_OK)\r
{\r
VDS_SET_ERROR(hr);\r
- Log("Could not format partition, err:0x%lx (%s)", LASTERR, WindowsErrorString(hr));\r
+ Log("Could not FormatVolume, 0x%x err:0x%lx (%s)", hr, LASTERR, WindowsErrorString(hr));\r
+\r
+ VDS_SET_ERROR(hr);\r
return FALSE;\r
}\r
\r
return TRUE;\r
}\r
-\r
-// Not supported for removable disk\r
-BOOL VDS_FormatVtoyEFIPart(int DriveIndex, UINT64 Offset)\r
+BOOL VDS_FormatVolume(char DriveLetter, int fs, DWORD ClusterSize)\r
{\r
+ int i;\r
+ BOOL ret = FALSE;\r
+ const char* guid = NULL;\r
+ CHAR Drive[32] = { 0 };\r
+ WCHAR wGuid[128] = { 0 };\r
+ CHAR VolumeGuid[128] = { 0 };\r
VDS_PARA Para;\r
\r
- memset(&Para, 0, sizeof(Para));\r
- Para.Offset = Offset;\r
- memcpy(Para.Name, L"VTOYEFI", 7 * 2);\r
+ Drive[0] = DriveLetter;\r
+ Drive[1] = ':';\r
+ Drive[2] = '\\';\r
+ GetVolumeNameForVolumeMountPointA(Drive, VolumeGuid, sizeof(VolumeGuid) / 2);\r
+\r
+ guid = strstr(VolumeGuid, "{");\r
+ if (!guid)\r
+ {\r
+ Log("Can not find volume GUID for %s:", Drive);\r
+ return FALSE;\r
+ }\r
+\r
+ for (i = 0; i < 128 && guid[i]; i++)\r
+ {\r
+ wGuid[i] = guid[i];\r
+ }\r
+ Log("VDS_FormatVolume find GUID %C: <%s> ", DriveLetter, VolumeGuid);\r
+\r
+ Para.Attr = fs;\r
+ Para.DriveLetter = DriveLetter;\r
+ Para.ClusterSize = ClusterSize;\r
+\r
+ ret = VDS_VolumeCommProc(INTF_VOLUME_MF3, wGuid, VDS_CallBack_FormatVolume, (UINT64)&Para);\r
+ Log("VDS_FormatVolume %C: <%s> ret:%d (%s)", DriveLetter, VolumeGuid, ret, ret ? "SUCCESS" : "FAIL");\r
\r
- BOOL ret = VDS_DiskCommProc(INTF_PARTITIONMF, DriveIndex, VDS_CallBack_FormatVtoyEFI, (ULONG)&Para); \r
- Log("VDS_FormatVtoyEFIPart %d ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL");\r
return ret;\r
}\r
-\r