]> glassweightruler.freedombox.rocks Git - Ventoy.git/blobdiff - Ventoy2Disk/Ventoy2Disk/DiskService_vds.c
Fix French language (#2850)
[Ventoy.git] / Ventoy2Disk / Ventoy2Disk / DiskService_vds.c
index c53cc44aff952fa135382cd46d45d34b28661968..e2a1fab7f4e96cc2a696c35b730b3be1e7abe578 100644 (file)
@@ -390,6 +390,10 @@ static const char *GetVdsError(DWORD error_code)
                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
@@ -586,6 +590,7 @@ const char *WindowsErrorString(DWORD error_code)
 #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
@@ -601,6 +606,13 @@ const char *WindowsErrorString(DWORD error_code)
 \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
@@ -627,6 +639,7 @@ STATIC IVdsService * VDS_InitService(void)
     {\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
@@ -640,6 +653,7 @@ STATIC IVdsService * VDS_InitService(void)
     }\r
 \r
     Log("VDS init OK, service %p", pService);\r
+       g_vds_available = TRUE;\r
     return pService;\r
 }\r
 \r
@@ -1061,16 +1075,16 @@ STATIC BOOL VDS_CallBack_DeletePartition(void *pInterface, VDS_DISK_PROP *pDiskP
     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
@@ -1080,7 +1094,7 @@ STATIC BOOL VDS_CallBack_DeletePartition(void *pInterface, VDS_DISK_PROP *pDiskP
                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
@@ -1127,9 +1141,9 @@ BOOL VDS_DeleteAllPartitions(int DriveIndex)
     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
@@ -1138,6 +1152,7 @@ STATIC BOOL VDS_CallBack_ChangeEFIAttr(void *pInterface, VDS_DISK_PROP *pDiskPro
 {\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
@@ -1151,12 +1166,13 @@ STATIC BOOL VDS_CallBack_ChangeEFIAttr(void *pInterface, VDS_DISK_PROP *pDiskPro
         {\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
@@ -1164,7 +1180,7 @@ STATIC BOOL VDS_CallBack_ChangeEFIAttr(void *pInterface, VDS_DISK_PROP *pDiskPro
                 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
@@ -1191,10 +1207,15 @@ STATIC BOOL VDS_CallBack_ChangeEFIAttr(void *pInterface, VDS_DISK_PROP *pDiskPro
     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
@@ -1238,6 +1259,7 @@ BOOL VDS_ChangeVtoyEFI2ESP(int DriveIndex, UINT64 Offset)
        return ret;\r
 }\r
 \r
+\r
 BOOL VDS_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset)\r
 {\r
        VDS_PARA Para;\r
@@ -1251,93 +1273,50 @@ BOOL VDS_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset)
        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(&para, 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, &para, &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
@@ -1346,59 +1325,112 @@ STATIC BOOL VDS_CallBack_FormatVtoyEFI(void *pInterface, VDS_DISK_PROP *pDiskPro
                        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
@@ -1407,17 +1439,17 @@ STATIC BOOL VDS_CallBack_ShrinkVolume(void* pInterface, VDS_DISK_PROP* pDiskProp
                        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
@@ -1426,23 +1458,33 @@ STATIC BOOL VDS_CallBack_ShrinkVolume(void* pInterface, VDS_DISK_PROP* pDiskProp
        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
@@ -1450,8 +1492,14 @@ BOOL VDS_ShrinkVolume(const char* VolumeGuid, UINT64 ReduceBytes)
        {\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