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
#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
\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
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
return ret;\r
}\r
\r
+\r
BOOL VDS_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset)\r
{\r
VDS_PARA Para;\r
return ret;\r
}\r
\r
-\r
-STATIC BOOL VDS_CallBack_CreateVtoyEFI(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data)\r
+STATIC BOOL CHKDSK_Volume(CHAR LogicalDrive)\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 *)data;\r
-\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
+ CHAR CmdBuf[1024];\r
+ STARTUPINFOA Si;\r
+ PROCESS_INFORMATION Pi;\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
+ if ((!IsFileExist("C:\\Windows\\System32\\chkdsk.exe")) || (LogicalDrive == 0))\r
+ {\r
+ return FALSE;\r
+ }\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
+ GetStartupInfoA(&Si);\r
+ Si.dwFlags |= STARTF_USESHOWWINDOW;\r
+ Si.wShowWindow = SW_HIDE;\r
\r
- return TRUE;\r
-}\r
+ sprintf_s(CmdBuf, sizeof(CmdBuf), "C:\\Windows\\System32\\chkdsk.exe %C: /f", LogicalDrive);\r
\r
-BOOL VDS_CreateVtoyEFIPart(int DriveIndex, UINT64 Offset)\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
+ Log("CreateProcess <%s>", CmdBuf);\r
+ CreateProcessA(NULL, CmdBuf, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);\r
\r
- Log("VDS_CreateVtoyEFIPart %u Offset:%llu Sector:%llu", DriveIndex, Offset, Offset / 512);\r
+ Log("Wair process ...");\r
+ WaitForSingleObject(Pi.hProcess, INFINITE);\r
+ Log("Process finished...");\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
+ CHECK_CLOSE_HANDLE(Pi.hProcess);\r
+ CHECK_CLOSE_HANDLE(Pi.hThread);\r
\r
- BOOL ret = VDS_DiskCommProc(INTF_CREATEPARTITIONEX, DriveIndex, VDS_CallBack_CreateVtoyEFI, (UINT64)&Para);\r
- Log("VDS_CreateVtoyEFIPart %d ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL");\r
- return ret; \r
+ return TRUE;\r
}\r
\r
-\r
-STATIC BOOL VDS_CallBack_FormatVtoyEFI(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data)\r
+STATIC HRESULT VDS_RealShrinkVolume(void* pInterface, VDS_DISK_PROP* pDiskProp, UINT64 data)\r
{\r
HRESULT hr, hr2;\r
+ IVdsVolume* pVolume = (IVdsVolume*)pInterface;\r
ULONG completed;\r
- IVdsAsync* pAsync; \r
- IVdsDiskPartitionMF *pPartitionMF = (IVdsDiskPartitionMF *)pInterface;\r
- VDS_PARA *VdsPara = (VDS_PARA *)data;\r
+ IVdsAsync* pAsync;\r
+ VDS_PARA* VdsPara = (VDS_PARA*)data;\r
\r
(void)pDiskProp;\r
- \r
- hr = IVdsPartitionMF_FormatPartitionEx(pPartitionMF, VdsPara->Offset, L"FAT", 0x0100, 0, VdsPara->Name, TRUE, TRUE, FALSE, &pAsync);\r
+\r
+ Log("VDS_ShrinkVolume (%C:) (%llu) ...", VdsPara->DriveLetter, (ULONGLONG)VdsPara->Offset);\r
+\r
+ hr = IVdsVolume_Shrink(pVolume, (ULONGLONG)VdsPara->Offset, &pAsync);\r
+\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("ShrinkVolume 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("ShrinkVolume: %lu%%", completed);\r
hr = S_OK;\r
}\r
else\r
{\r
- Log("QueryStatus invalid status:0x%lx", hr);\r
+ Log("ShrinkVolume invalid status:0x%lx", hr);\r
}\r
}\r
Sleep(1000);\r
}\r
\r
+ return hr;\r
+}\r
+\r
+STATIC BOOL VDS_CallBack_ShrinkVolume(void* pInterface, VDS_DISK_PROP* pDiskProp, UINT64 data)\r
+{\r
+ int i;\r
+ HRESULT hr;\r
+ VDS_PARA *VdsPara = (VDS_PARA *)data;\r
+\r
+ Log("VDS_CallBack_ShrinkVolume (%C:) (%llu) ...", VdsPara->DriveLetter, (ULONGLONG)VdsPara->Offset);\r
+\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
+ 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 format partition, err:0x%lx (%s)", LASTERR, WindowsErrorString(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
-// Not supported for removable disk\r
-BOOL VDS_FormatVtoyEFIPart(int DriveIndex, UINT64 Offset)\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
- memset(&Para, 0, sizeof(Para));\r
- Para.Offset = Offset;\r
- memcpy(Para.Name, L"VTOYEFI", 7 * 2);\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
- BOOL ret = VDS_DiskCommProc(INTF_PARTITIONMF, DriveIndex, VDS_CallBack_FormatVtoyEFI, (UINT64)&Para);\r
- Log("VDS_FormatVtoyEFIPart %d ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL");\r
+ Para.Offset = ReduceBytes;\r
+ Para.DriveLetter = DriveLetter;\r
+\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
-STATIC BOOL VDS_CallBack_ShrinkVolume(void* pInterface, VDS_DISK_PROP* pDiskProp, UINT64 data)\r
+\r
+STATIC BOOL VDS_CallBack_FormatVolume(void* pInterface, VDS_DISK_PROP* pDiskProp, UINT64 data)\r
{\r
+ int fs;\r
HRESULT hr, hr2;\r
- IVdsVolume* pVolume = (IVdsVolume*)pInterface;\r
ULONG completed;\r
IVdsAsync* pAsync;\r
+ IVdsVolumeMF3* pVolume = (IVdsVolumeMF3*)pInterface;\r
+ WCHAR* pFs = NULL;\r
+ VDS_PARA* VdsPara = (VDS_PARA*)data;\r
+ \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
- (void)pDiskProp;\r
-\r
- Log("VDS_CallBack_ShrinkVolume (%llu) ...", (ULONGLONG)data);\r
-\r
- hr = IVdsVolume_Shrink(pVolume, (ULONGLONG)data, &pAsync);\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("ShrinkVolume 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("ShrinkVolume: %lu%%", completed);\r
+ Log("FormatVolume: %lu%%", completed);\r
hr = S_OK;\r
}\r
else\r
{\r
- Log("ShrinkVolume 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 ShrinkVolume, 0x%x err:0x%lx (%s)", hr, 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
-BOOL VDS_ShrinkVolume(const char* VolumeGuid, UINT64 ReduceBytes)\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
- const char *guid = NULL;\r
+ CHAR VolumeGuid[128] = { 0 };\r
+ VDS_PARA Para;\r
+\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
{\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
- ret = VDS_VolumeCommProc(INTF_VOLUME, wGuid, VDS_CallBack_ShrinkVolume, ReduceBytes);\r
- Log("VDS_ShrinkVolume ret:%d (%s)", ret, ret ? "SUCCESS" : "FAIL");\r
return ret;\r
-}
\ No newline at end of file
+}\r