]> glassweightruler.freedombox.rocks Git - Ventoy.git/commitdiff
Improve the success rate of Ventoy2Disk.exe installation and upgrade
authorlongpanda <admin@ventoy.net>
Sat, 16 Oct 2021 15:34:20 +0000 (23:34 +0800)
committerlongpanda <admin@ventoy.net>
Sat, 16 Oct 2021 15:34:20 +0000 (23:34 +0800)
15 files changed:
INSTALL/Ventoy2Disk.exe
INSTALL/grub/grub.cfg
Ventoy2Disk/Ventoy2Disk/DiskService.h [new file with mode: 0644]
Ventoy2Disk/Ventoy2Disk/DiskService_diskpart.c [new file with mode: 0644]
Ventoy2Disk/Ventoy2Disk/DiskService_vds.c [new file with mode: 0644]
Ventoy2Disk/Ventoy2Disk/DiskService_wmsa.c [new file with mode: 0644]
Ventoy2Disk/Ventoy2Disk/PhyDrive.c
Ventoy2Disk/Ventoy2Disk/Utility.c
Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c
Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h
Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.rc
Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj
Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj.filters
Ventoy2Disk/Ventoy2Disk/WinDialog.c
Ventoy2Disk/Ventoy2Disk/resource.h

index d207ffdb7a360cdda4358c653e0a8ad3bfa692b2..90b024faac71d0ca024deece66e130127409a3f6 100644 (file)
Binary files a/INSTALL/Ventoy2Disk.exe and b/INSTALL/Ventoy2Disk.exe differ
index f180475e6732d183c849695d024b02f2c5b08190..5c6797a9ae447a43380fddcba28425cee5798ab8 100644 (file)
@@ -133,6 +133,8 @@ function vt_check_compatible_pe {
     #set compatible if ISO file is less than 80MB
     if [ $vt_chosen_size -gt 33554432 -a $vt_chosen_size -le 83886080 ]; then
         set ventoy_compatible=YES
     #set compatible if ISO file is less than 80MB
     if [ $vt_chosen_size -gt 33554432 -a $vt_chosen_size -le 83886080 ]; then
         set ventoy_compatible=YES
+    elif [ -e $1/WEPE/WEPE.INI ]; then
+        set ventoy_compatible=YES
     fi
 
     return
     fi
 
     return
@@ -328,6 +330,8 @@ function distro_specify_initrd_file_phase2 {
         vt_linux_specify_initrd_file /360Disk/initrd.gz
     elif [ -f (loop)/porteus/initrd.xz ]; then
         vt_linux_specify_initrd_file /porteus/initrd.xz
         vt_linux_specify_initrd_file /360Disk/initrd.gz
     elif [ -f (loop)/porteus/initrd.xz ]; then
         vt_linux_specify_initrd_file /porteus/initrd.xz
+    elif [ -f (loop)/pyabr/boot/initrfs.img ]; then
+        vt_linux_specify_initrd_file /pyabr/boot/initrfs.img
     
     fi
 }
     
     fi
 }
diff --git a/Ventoy2Disk/Ventoy2Disk/DiskService.h b/Ventoy2Disk/Ventoy2Disk/DiskService.h
new file mode 100644 (file)
index 0000000..a8b68af
--- /dev/null
@@ -0,0 +1,57 @@
+/******************************************************************************\r
+ * DiskService.h\r
+ *\r
+ * Copyright (c) 2021, longpanda <admin@ventoy.net>\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License as\r
+ * published by the Free Software Foundation; either version 3 of the\r
+ * License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful, but\r
+ * WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+\r
+#ifndef __DISKSERVICE_H__\r
+#define __DISKSERVICE_H__\r
+\r
+typedef struct VDS_PARA\r
+{\r
+    UINT64 Attr;\r
+    GUID Type;\r
+    GUID Id;\r
+    WCHAR Name[36];\r
+       ULONG NameLen;\r
+    ULONGLONG Offset;\r
+}VDS_PARA;\r
+\r
+\r
+//VDS com\r
+int  VDS_Init(void);\r
+BOOL VDS_CleanDisk(int DriveIndex);\r
+BOOL VDS_DeleteAllPartitions(int DriveIndex);\r
+BOOL VDS_DeleteVtoyEFIPartition(int DriveIndex);\r
+BOOL VDS_ChangeVtoyEFIAttr(int DriveIndex, UINT64 Attr);\r
+BOOL VDS_CreateVtoyEFIPart(int DriveIndex, UINT64 Offset);\r
+BOOL VDS_ChangeVtoyEFI2ESP(int DriveIndex, UINT64 Offset);\r
+BOOL VDS_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset);\r
+\r
+\r
+//diskpart.exe\r
+BOOL DSPT_CleanDisk(int DriveIndex);\r
+\r
+\r
+//\r
+// Internel define\r
+//\r
+\r
+\r
+\r
+\r
+#endif\r
diff --git a/Ventoy2Disk/Ventoy2Disk/DiskService_diskpart.c b/Ventoy2Disk/Ventoy2Disk/DiskService_diskpart.c
new file mode 100644 (file)
index 0000000..7a55395
--- /dev/null
@@ -0,0 +1,84 @@
+/******************************************************************************\r
+ * DiskService_diskpart.c\r
+ *\r
+ * Copyright (c) 2021, longpanda <admin@ventoy.net>\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License as\r
+ * published by the Free Software Foundation; either version 3 of the\r
+ * License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful, but\r
+ * WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
\r
+#include <Windows.h>\r
+#include <winternl.h>\r
+#include <commctrl.h>\r
+#include <initguid.h>\r
+#include <vds.h>\r
+#include "Ventoy2Disk.h"\r
+#include "DiskService.h"\r
+\r
+STATIC BOOL IsDiskpartExist(void)\r
+{\r
+    BOOL ret;\r
+\r
+    ret = IsFileExist("C:\\Windows\\system32\\diskpart.exe");\r
+    if (!ret)\r
+    {\r
+        Log("diskpart.exe not exist");\r
+    }\r
+\r
+    return ret;\r
+}\r
+\r
+STATIC BOOL DSPT_CommProc(const char *Cmd)\r
+{\r
+    CHAR CmdBuf[MAX_PATH];\r
+    CHAR CmdFile[MAX_PATH];\r
+    STARTUPINFOA Si;\r
+    PROCESS_INFORMATION Pi;\r
+\r
+    GetCurrentDirectoryA(sizeof(CmdBuf), CmdBuf);\r
+    sprintf_s(CmdFile, sizeof(CmdFile), "%s\\ventoy\\diskpart_%u.txt", CmdBuf, GetCurrentProcessId());\r
+    \r
+    SaveBufToFile(CmdFile, Cmd, strlen(Cmd));\r
+\r
+    GetStartupInfoA(&Si);\r
+    Si.dwFlags |= STARTF_USESHOWWINDOW;\r
+    Si.wShowWindow = SW_HIDE;\r
+\r
+    sprintf_s(CmdBuf, sizeof(CmdBuf), "C:\\Windows\\system32\\diskpart.exe /s \"%s\"", CmdFile);\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
+    DeleteFileA(CmdFile);\r
+    return TRUE;\r
+}\r
+\r
+BOOL DSPT_CleanDisk(int DriveIndex)\r
+{\r
+    CHAR CmdBuf[128];\r
+\r
+    Log("CleanDiskByDiskpart <%d>", DriveIndex);\r
+\r
+    if (!IsDiskpartExist())\r
+    {\r
+        return FALSE;\r
+    }\r
+\r
+    sprintf_s(CmdBuf, sizeof(CmdBuf), "select disk %d\r\nclean\r\n", DriveIndex);\r
+    return DSPT_CommProc(CmdBuf);\r
+}\r
diff --git a/Ventoy2Disk/Ventoy2Disk/DiskService_vds.c b/Ventoy2Disk/Ventoy2Disk/DiskService_vds.c
new file mode 100644 (file)
index 0000000..38800c6
--- /dev/null
@@ -0,0 +1,629 @@
+/******************************************************************************\r
+ * DiskService_vds.c\r
+ *\r
+ * Copyright (c) 2021, longpanda <admin@ventoy.net>\r
+ * Copyright (c) 2011-2020, Pete Batard <pete@akeo.ie>\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License as\r
+ * published by the Free Software Foundation; either version 3 of the\r
+ * License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful, but\r
+ * WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
\r
+#include <Windows.h>\r
+#include <winternl.h>\r
+#include <commctrl.h>\r
+#include <initguid.h>\r
+#include <vds.h>\r
+#include "Ventoy2Disk.h"\r
+#include "DiskService.h"\r
+\r
+\r
+#define INTF_ADVANCEDDISK  1\r
+#define INTF_ADVANCEDDISK2  2\r
+#define INTF_CREATEPARTITIONEX  3\r
+\r
+/* \r
+ * Some code and functions in the file are copied from rufus.\r
+ * https://github.com/pbatard/rufus\r
+ */\r
+#define VDS_SET_ERROR SetLastError\r
+#define IVdsServiceLoader_LoadService(This, pwszMachineName, ppService) (This)->lpVtbl->LoadService(This, pwszMachineName, ppService)\r
+#define IVdsServiceLoader_Release(This) (This)->lpVtbl->Release(This)\r
+#define IVdsService_QueryProviders(This, masks, ppEnum) (This)->lpVtbl->QueryProviders(This, masks, ppEnum)\r
+#define IVdsService_WaitForServiceReady(This) ((This)->lpVtbl->WaitForServiceReady(This))\r
+#define IVdsService_CleanupObsoleteMountPoints(This) ((This)->lpVtbl->CleanupObsoleteMountPoints(This))\r
+#define IVdsService_Refresh(This) ((This)->lpVtbl->Refresh(This))\r
+#define IVdsService_Reenumerate(This) ((This)->lpVtbl->Reenumerate(This)) \r
+#define IVdsSwProvider_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)\r
+#define IVdsProvider_Release(This) (This)->lpVtbl->Release(This)\r
+#define IVdsSwProvider_QueryPacks(This, ppEnum) (This)->lpVtbl->QueryPacks(This, ppEnum)\r
+#define IVdsSwProvider_Release(This) (This)->lpVtbl->Release(This)\r
+#define IVdsPack_QueryDisks(This, ppEnum) (This)->lpVtbl->QueryDisks(This, ppEnum)\r
+#define IVdsDisk_GetProperties(This, pDiskProperties) (This)->lpVtbl->GetProperties(This, pDiskProperties)\r
+#define IVdsDisk_Release(This) (This)->lpVtbl->Release(This)\r
+#define IVdsDisk_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)\r
+#define IVdsAdvancedDisk_QueryPartitions(This, ppPartitionPropArray, plNumberOfPartitions) (This)->lpVtbl->QueryPartitions(This, ppPartitionPropArray, plNumberOfPartitions)\r
+#define IVdsAdvancedDisk_DeletePartition(This, ullOffset, bForce, bForceProtected) (This)->lpVtbl->DeletePartition(This, ullOffset, bForce, bForceProtected)\r
+#define IVdsAdvancedDisk_ChangeAttributes(This, ullOffset, para) (This)->lpVtbl->ChangeAttributes(This, ullOffset, para)\r
+#define IVdsAdvancedDisk_CreatePartition(This, ullOffset, ullSize, para, ppAsync) (This)->lpVtbl->CreatePartition(This, ullOffset, ullSize, para, ppAsync)\r
+#define IVdsAdvancedDisk_Clean(This, bForce, bForceOEM, bFullClean, ppAsync) (This)->lpVtbl->Clean(This, bForce, bForceOEM, bFullClean, ppAsync)\r
+#define IVdsAdvancedDisk_Release(This) (This)->lpVtbl->Release(This)\r
+\r
+#define IVdsAdvancedDisk2_ChangePartitionType(This, ullOffset, bForce, para) (This)->lpVtbl->ChangePartitionType(This, ullOffset, bForce, para)\r
+#define IVdsAdvancedDisk2_Release(This) (This)->lpVtbl->Release(This)\r
+\r
+#define IVdsCreatePartitionEx_CreatePartitionEx(This, ullOffset, ullSize, ulAlign, para, ppAsync) (This)->lpVtbl->CreatePartitionEx(This, ullOffset, ullSize, ulAlign, para, ppAsync)\r
+#define IVdsCreatePartitionEx_Release(This) (This)->lpVtbl->Release(This)\r
+#define IEnumVdsObject_Next(This, celt, ppObjectArray, pcFetched) (This)->lpVtbl->Next(This, celt, ppObjectArray, pcFetched)\r
+#define IVdsPack_QueryVolumes(This, ppEnum) (This)->lpVtbl->QueryVolumes(This, ppEnum)\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 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_Cancel(This) (This)->lpVtbl->Cancel(This)\r
+#define IVdsAsync_QueryStatus(This,pHrResult,pulPercentCompleted) (This)->lpVtbl->QueryStatus(This,pHrResult,pulPercentCompleted)\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 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 IVdsService * VDS_InitService(void)\r
+{\r
+    HRESULT hr;\r
+    IVdsServiceLoader *pLoader;\r
+    IVdsService *pService;\r
+\r
+    // Initialize COM\r
+    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);\r
+    CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0, NULL);\r
+\r
+    // Create a VDS Loader Instance\r
+    hr = CoCreateInstance(&CLSID_VdsLoader, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, &IID_IVdsServiceLoader, (void **)&pLoader);\r
+    if (hr != S_OK) \r
+    {\r
+        VDS_SET_ERROR(hr);\r
+        Log("Could not create VDS Loader Instance: %u", LASTERR);\r
+        return NULL;\r
+    }\r
+\r
+    // Load the VDS Service\r
+    hr = IVdsServiceLoader_LoadService(pLoader, L"", &pService);\r
+    IVdsServiceLoader_Release(pLoader);\r
+    if (hr != S_OK) \r
+    {\r
+        VDS_SET_ERROR(hr);\r
+        Log("Could not load VDS Service: %u", LASTERR);\r
+        return NULL;\r
+    }\r
+\r
+    // Wait for the Service to become ready if needed\r
+    hr = IVdsService_WaitForServiceReady(pService);\r
+    if (hr != S_OK) \r
+    {\r
+        VDS_SET_ERROR(hr);\r
+        Log("VDS Service is not ready: %u", LASTERR);\r
+        return NULL;\r
+    }\r
+\r
+    Log("VDS init OK, service %p", pService);\r
+    return pService;\r
+}\r
+\r
+\r
+STATIC BOOL VDS_DiskCommProc(int intf, int DriveIndex, VDS_Callback_PF callback, UINT64 data)\r
+{\r
+    BOOL r = FALSE;\r
+    HRESULT hr;\r
+    ULONG ulFetched;\r
+    IUnknown *pUnk = NULL;\r
+    IEnumVdsObject *pEnum = NULL;    \r
+    IVdsService *pService = NULL;\r
+    wchar_t wPhysicalName[48];\r
+\r
+    swprintf_s(wPhysicalName, ARRAYSIZE(wPhysicalName), L"\\\\?\\PhysicalDrive%d", DriveIndex);\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 *pEnumDisk;\r
+            IUnknown *pDiskUnk;\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 disks\r
+            hr = IVdsPack_QueryDisks(pPack, &pEnumDisk);\r
+            if (hr != S_OK) {\r
+                VDS_SET_ERROR(hr);\r
+                Log("Could not query VDS disks: %u", LASTERR);\r
+                goto out;\r
+            }\r
+\r
+            // List disks\r
+            while (IEnumVdsObject_Next(pEnumDisk, 1, &pDiskUnk, &ulFetched) == S_OK) \r
+            {\r
+                VDS_DISK_PROP diskprop;\r
+                IVdsDisk *pDisk;\r
+                IVdsAdvancedDisk *pAdvancedDisk;\r
+                               IVdsAdvancedDisk2 *pAdvancedDisk2;\r
+                               IVdsCreatePartitionEx *pCreatePartitionEx;\r
+\r
+                // Get the disk interface.\r
+                hr = IUnknown_QueryInterface(pDiskUnk, &IID_IVdsDisk, (void **)&pDisk);\r
+                if (hr != S_OK) {\r
+                    VDS_SET_ERROR(hr);\r
+                    Log("Could not query VDS Disk Interface: %u", LASTERR);\r
+                    goto out;\r
+                }\r
+\r
+                // Get the disk properties\r
+                hr = IVdsDisk_GetProperties(pDisk, &diskprop);\r
+                if (hr != S_OK) {\r
+                    VDS_SET_ERROR(hr);\r
+                    Log("Could not query VDS Disk Properties: %u", LASTERR);\r
+                    goto out;\r
+                }\r
+\r
+                // Isolate the disk we want\r
+                if (_wcsicmp(wPhysicalName, diskprop.pwszName) != 0) \r
+                {\r
+                    IVdsDisk_Release(pDisk);\r
+                    continue;\r
+                }\r
+\r
+                               if (intf == INTF_ADVANCEDDISK)\r
+                               {\r
+                                       // Instantiate the AdvanceDisk interface for our disk.\r
+                                       hr = IVdsDisk_QueryInterface(pDisk, &IID_IVdsAdvancedDisk, (void **)&pAdvancedDisk);\r
+                                       IVdsDisk_Release(pDisk);\r
+                                       if (hr != S_OK)\r
+                                       {\r
+                                               VDS_SET_ERROR(hr);\r
+                                               Log("Could not access VDS Advanced Disk interface: %u", LASTERR);\r
+                                               goto out;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               Log("Callback %d process for disk <%S>", intf, diskprop.pwszName);\r
+                                               r = callback(pAdvancedDisk, &diskprop, data);\r
+                                       }\r
+                                       IVdsAdvancedDisk_Release(pAdvancedDisk);\r
+                               }\r
+                               else if (intf == INTF_ADVANCEDDISK2)\r
+                               {\r
+                                       // Instantiate the AdvanceDisk interface for our disk.\r
+                                       hr = IVdsDisk_QueryInterface(pDisk, &IID_IVdsAdvancedDisk2, (void **)&pAdvancedDisk2);\r
+                                       IVdsDisk_Release(pDisk);\r
+                                       if (hr != S_OK)\r
+                                       {\r
+                                               VDS_SET_ERROR(hr);\r
+                                               Log("Could not access VDS Advanced Disk2 interface: %u", LASTERR);\r
+                                               goto out;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               Log("Callback %d process for disk2 <%S>", intf, diskprop.pwszName);\r
+                                               r = callback(pAdvancedDisk2, &diskprop, data);\r
+                                       }\r
+                                       IVdsAdvancedDisk2_Release(pAdvancedDisk2);\r
+                               }\r
+                               else if (intf == INTF_CREATEPARTITIONEX)\r
+                               {\r
+                                       // Instantiate the CreatePartitionEx interface for our disk.\r
+                                       hr = IVdsDisk_QueryInterface(pDisk, &IID_IVdsCreatePartitionEx, (void **)&pCreatePartitionEx);\r
+                                       IVdsDisk_Release(pDisk);\r
+                                       if (hr != S_OK)\r
+                                       {\r
+                                               VDS_SET_ERROR(hr);\r
+                                               Log("Could not access VDS CreatePartitionEx interface: %u", LASTERR);\r
+                                               goto out;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               Log("Callback %d process for disk <%S>", intf, diskprop.pwszName);\r
+                                               r = callback(pCreatePartitionEx, &diskprop, data);\r
+                                       }\r
+                                       IVdsCreatePartitionEx_Release(pCreatePartitionEx);\r
+                               }\r
+\r
+                goto out;\r
+            }\r
+        }\r
+    }\r
+\r
+out:\r
+    return r;\r
+}\r
+\r
+STATIC BOOL VDS_CallBack_CleanDisk(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data)\r
+{    \r
+    HRESULT hr, hr2;\r
+    ULONG completed;\r
+    IVdsAsync* pAsync;\r
+       IVdsAdvancedDisk *pAdvancedDisk = (IVdsAdvancedDisk *)pInterface;\r
+\r
+    (void)pDiskProp;\r
+    (void)data;\r
+\r
+    hr = IVdsAdvancedDisk_Clean(pAdvancedDisk, TRUE, TRUE, FALSE, &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 clean QueryStatus OK");\r
+                break;\r
+            }\r
+            else if (hr == VDS_E_OPERATION_PENDING)\r
+            {\r
+                hr = S_OK;\r
+            }\r
+            else\r
+            {\r
+                Log("QueryStatus invalid status:%u", hr);\r
+            }\r
+        }\r
+        Sleep(500);\r
+    }\r
+\r
+    if (hr != S_OK) \r
+    {\r
+        VDS_SET_ERROR(hr);\r
+        Log("Could not clean disk 0x%lx err:%u", hr, LASTERR);\r
+        return FALSE;\r
+    }\r
+\r
+    return TRUE;\r
+}\r
+\r
+BOOL VDS_CleanDisk(int DriveIndex)\r
+{\r
+       BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK, DriveIndex, VDS_CallBack_CleanDisk, 0);\r
+    Log("VDS_CleanDisk %d ret:%d", DriveIndex, ret);\r
+    return ret;\r
+}\r
+\r
+STATIC BOOL VDS_CallBack_DeletePartition(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data)\r
+{\r
+    BOOL r = FALSE;\r
+    HRESULT hr;\r
+    VDS_PARTITION_PROP* prop_array = NULL;\r
+    LONG i, prop_array_size;\r
+    ULONG PartNumber = (ULONG)data;\r
+       IVdsAdvancedDisk *pAdvancedDisk = (IVdsAdvancedDisk *)pInterface;\r
+\r
+    if (PartNumber == 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
+    }\r
+\r
+    // Query the partition data, so we can get the start offset, which we need for deletion\r
+    hr = IVdsAdvancedDisk_QueryPartitions(pAdvancedDisk, &prop_array, &prop_array_size);\r
+    if (hr == S_OK) \r
+    {\r
+        for (i = 0; i < prop_array_size; i++) \r
+        {\r
+            if (PartNumber == 0 || PartNumber == prop_array[i].ulPartitionNumber)\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
+            }\r
+            else\r
+            {\r
+                Log("  Partition %d (offset: %lld, size: %llu) skip it.",\r
+                    prop_array[i].ulPartitionNumber, prop_array[i].ullOffset, (ULONGLONG)prop_array[i].ullSize);\r
+                continue;\r
+            }\r
+\r
+            hr = IVdsAdvancedDisk_DeletePartition(pAdvancedDisk, prop_array[i].ullOffset, TRUE, TRUE);\r
+            if (hr != S_OK) \r
+            {\r
+                r = FALSE;\r
+                VDS_SET_ERROR(hr);\r
+                Log("Could not delete partitions: %u", LASTERR);\r
+            }\r
+            else \r
+            {\r
+                Log("Delete this partitions success");\r
+            }\r
+        }\r
+        r = TRUE;\r
+    }\r
+    else \r
+    {\r
+        Log("No partition to delete on disk '%S'", pDiskProp->pwszName);\r
+        r = TRUE;\r
+    }\r
+    CoTaskMemFree(prop_array);\r
+\r
+    return r;\r
+}\r
+\r
+BOOL VDS_DeleteAllPartitions(int DriveIndex)\r
+{\r
+       BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK, DriveIndex, VDS_CallBack_DeletePartition, 0);\r
+    Log("VDS_DeleteAllPartitions %d ret:%d", DriveIndex, ret);\r
+    return ret;\r
+}\r
+\r
+BOOL VDS_DeleteVtoyEFIPartition(int DriveIndex)\r
+{\r
+       BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK, DriveIndex, VDS_CallBack_DeletePartition, 2);\r
+    Log("VDS_DeleteVtoyEFIPartition %d ret:%d", DriveIndex, ret);\r
+    return ret;\r
+}\r
+\r
+STATIC BOOL VDS_CallBack_ChangeEFIAttr(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data)\r
+{\r
+    BOOL r = FALSE;\r
+    HRESULT hr;\r
+    VDS_PARTITION_PROP* prop_array = NULL;\r
+    LONG i, prop_array_size;\r
+    CHANGE_ATTRIBUTES_PARAMETERS AttrPara;\r
+       IVdsAdvancedDisk *pAdvancedDisk = (IVdsAdvancedDisk *)pInterface;\r
+\r
+    // Query the partition data, so we can get the start offset, which we need for deletion\r
+    hr = IVdsAdvancedDisk_QueryPartitions(pAdvancedDisk, &prop_array, &prop_array_size);\r
+    if (hr == S_OK)\r
+    {\r
+        for (i = 0; i < prop_array_size; i++)\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
+            {\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
+                {\r
+                    Log("Attribute match, No need to change.");\r
+                    r = TRUE;\r
+                }\r
+                else\r
+                {\r
+                    AttrPara.style = VDS_PST_GPT;\r
+                    AttrPara.GptPartInfo.attributes = data;\r
+                    hr = IVdsAdvancedDisk_ChangeAttributes(pAdvancedDisk, prop_array[i].ullOffset, &AttrPara);\r
+                    if (hr == S_OK)\r
+                    {\r
+                        r = TRUE;\r
+                        Log("Change this partitions attribute success");\r
+                    }\r
+                    else\r
+                    {\r
+                        r = FALSE;\r
+                        VDS_SET_ERROR(hr);\r
+                        Log("Could not change partitions attr: %u", LASTERR);\r
+                    }\r
+                }\r
+                break;\r
+            }\r
+        }\r
+    }\r
+    else\r
+    {\r
+        Log("No partition found on disk '%S'", pDiskProp->pwszName);\r
+    }\r
+    CoTaskMemFree(prop_array);\r
+\r
+    return r;\r
+}\r
+\r
+BOOL VDS_ChangeVtoyEFIAttr(int DriveIndex, UINT64 Attr)\r
+{\r
+       BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK, DriveIndex, VDS_CallBack_ChangeEFIAttr, Attr);\r
+    Log("VDS_ChangeVtoyEFIAttr %d ret:%d", DriveIndex, ret);\r
+    return ret;\r
+}\r
+\r
+\r
+\r
+STATIC BOOL VDS_CallBack_ChangeEFIType(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data)\r
+{\r
+       BOOL r = FALSE;\r
+       HRESULT hr;\r
+       IVdsAdvancedDisk2 *pAdvancedDisk2 = (IVdsAdvancedDisk2 *)pInterface;\r
+       VDS_PARA *VdsPara = (VDS_PARA *)(ULONG)data;\r
+       CHANGE_PARTITION_TYPE_PARAMETERS para;\r
+\r
+       para.style = VDS_PST_GPT;\r
+       memcpy(&(para.GptPartInfo.partitionType), &VdsPara->Type, sizeof(GUID));\r
+\r
+       hr = IVdsAdvancedDisk2_ChangePartitionType(pAdvancedDisk2, VdsPara->Offset, TRUE, &para);\r
+       if (hr == S_OK)\r
+       {\r
+               r = TRUE;\r
+       }\r
+       else\r
+       {\r
+               Log("Failed to change partition type 0x%lx", hr);\r
+       }\r
+\r
+       return r;\r
+}\r
+\r
+\r
+BOOL VDS_ChangeVtoyEFI2ESP(int DriveIndex, UINT64 Offset)\r
+{\r
+       VDS_PARA Para;  \r
+       GUID EspPartType = { 0xc12a7328, 0xf81f, 0x11d2, { 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } };\r
+\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
+       Log("VDS_ChangeVtoyEFI2ESP %d ret:%d", DriveIndex, ret);\r
+       return ret;\r
+}\r
+\r
+BOOL VDS_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset)\r
+{\r
+       VDS_PARA Para;\r
+       GUID WindowsDataPartType = { 0xebd0a0a2, 0xb9e5, 0x4433, { 0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7 } };\r
+\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
+       Log("VDS_ChangeVtoyEFI2ESP %d ret:%d", DriveIndex, ret);\r
+       return ret;\r
+}\r
+\r
+\r
+STATIC BOOL VDS_CallBack_CreateVtoyEFI(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
+\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
+\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
+\r
+    if (hr != S_OK)\r
+    {\r
+        VDS_SET_ERROR(hr);\r
+        Log("Could not create partition, err:0x%lx", LASTERR);\r
+        return FALSE;\r
+    }\r
+\r
+    return TRUE;\r
+}\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
+\r
+       Log("VDS_CreateVtoyEFIPart %u Offset:%llu Sector:%llu", DriveIndex, Offset, Offset / 512);\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
+\r
+       BOOL ret = VDS_DiskCommProc(INTF_CREATEPARTITIONEX, DriveIndex, VDS_CallBack_CreateVtoyEFI, (ULONG)&Para);\r
+    Log("VDS_CreateVtoyEFIPart %d ret:%d", DriveIndex, ret);\r
+    return ret; \r
+}\r
+\r
diff --git a/Ventoy2Disk/Ventoy2Disk/DiskService_wmsa.c b/Ventoy2Disk/Ventoy2Disk/DiskService_wmsa.c
new file mode 100644 (file)
index 0000000..c5af4cc
--- /dev/null
@@ -0,0 +1,27 @@
+/******************************************************************************\r
+* DiskService_wsma.c\r
+*\r
+* Copyright (c) 2021, longpanda <admin@ventoy.net>\r
+*\r
+* This program is free software; you can redistribute it and/or\r
+* modify it under the terms of the GNU General Public License as\r
+* published by the Free Software Foundation; either version 3 of the\r
+* License, or (at your option) any later version.\r
+*\r
+* This program is distributed in the hope that it will be useful, but\r
+* WITHOUT ANY WARRANTY; without even the implied warranty of\r
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+* General Public License for more details.\r
+*\r
+* You should have received a copy of the GNU General Public License\r
+* along with this program; if not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
+\r
+#include <Windows.h>\r
+#include <winternl.h>\r
+#include <commctrl.h>\r
+#include <initguid.h>\r
+#include <vds.h>\r
+#include "Ventoy2Disk.h"\r
+#include "DiskService.h"\r
index 8d4e9bb44f2f379e9f5219644032542a050538f9..a916d155a345dd7f78ca9bb3f0d4fb4bd6a69c9a 100644 (file)
 #include <winternl.h>\r
 #include <commctrl.h>\r
 #include <initguid.h>\r
 #include <winternl.h>\r
 #include <commctrl.h>\r
 #include <initguid.h>\r
-#include <vds.h>\r
 #include "resource.h"\r
 #include "Language.h"\r
 #include "Ventoy2Disk.h"\r
 #include "fat_filelib.h"\r
 #include "ff.h"\r
 #include "resource.h"\r
 #include "Language.h"\r
 #include "Ventoy2Disk.h"\r
 #include "fat_filelib.h"\r
 #include "ff.h"\r
-\r
-/* \r
- * Some code and functions in the file are copied from rufus.\r
- * https://github.com/pbatard/rufus\r
- */\r
-#define VDS_SET_ERROR SetLastError\r
-#define IVdsServiceLoader_LoadService(This, pwszMachineName, ppService) (This)->lpVtbl->LoadService(This, pwszMachineName, ppService)\r
-#define IVdsServiceLoader_Release(This) (This)->lpVtbl->Release(This)\r
-#define IVdsService_QueryProviders(This, masks, ppEnum) (This)->lpVtbl->QueryProviders(This, masks, ppEnum)\r
-#define IVdsService_WaitForServiceReady(This) ((This)->lpVtbl->WaitForServiceReady(This))\r
-#define IVdsService_CleanupObsoleteMountPoints(This) ((This)->lpVtbl->CleanupObsoleteMountPoints(This))\r
-#define IVdsService_Refresh(This) ((This)->lpVtbl->Refresh(This))\r
-#define IVdsService_Reenumerate(This) ((This)->lpVtbl->Reenumerate(This)) \r
-#define IVdsSwProvider_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)\r
-#define IVdsProvider_Release(This) (This)->lpVtbl->Release(This)\r
-#define IVdsSwProvider_QueryPacks(This, ppEnum) (This)->lpVtbl->QueryPacks(This, ppEnum)\r
-#define IVdsSwProvider_Release(This) (This)->lpVtbl->Release(This)\r
-#define IVdsPack_QueryDisks(This, ppEnum) (This)->lpVtbl->QueryDisks(This, ppEnum)\r
-#define IVdsDisk_GetProperties(This, pDiskProperties) (This)->lpVtbl->GetProperties(This, pDiskProperties)\r
-#define IVdsDisk_Release(This) (This)->lpVtbl->Release(This)\r
-#define IVdsDisk_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)\r
-#define IVdsAdvancedDisk_QueryPartitions(This, ppPartitionPropArray, plNumberOfPartitions) (This)->lpVtbl->QueryPartitions(This, ppPartitionPropArray, plNumberOfPartitions)\r
-#define IVdsAdvancedDisk_DeletePartition(This, ullOffset, bForce, bForceProtected) (This)->lpVtbl->DeletePartition(This, ullOffset, bForce, bForceProtected)\r
-#define IVdsAdvancedDisk_Clean(This, bForce, bForceOEM, bFullClean, ppAsync) (This)->lpVtbl->Clean(This, bForce, bForceOEM, bFullClean, ppAsync)\r
-#define IVdsAdvancedDisk_Release(This) (This)->lpVtbl->Release(This)\r
-#define IEnumVdsObject_Next(This, celt, ppObjectArray, pcFetched) (This)->lpVtbl->Next(This, celt, ppObjectArray, pcFetched)\r
-#define IVdsPack_QueryVolumes(This, ppEnum) (This)->lpVtbl->QueryVolumes(This, ppEnum)\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 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_Cancel(This) (This)->lpVtbl->Cancel(This)\r
-#define IVdsAsync_QueryStatus(This,pHrResult,pulPercentCompleted) (This)->lpVtbl->QueryStatus(This,pHrResult,pulPercentCompleted)\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 IUnknown_QueryInterface(This, a, b) (This)->lpVtbl->QueryInterface(This,a,b)\r
-#define IUnknown_Release(This) (This)->lpVtbl->Release(This)\r
-\r
-/*\r
-* Delete all the partitions from a disk, using VDS\r
-* Mostly copied from https://social.msdn.microsoft.com/Forums/vstudio/en-US/b90482ae-4e44-4b08-8731-81915030b32a/createpartition-using-vds-interface-throw-error-enointerface-dcom?forum=vcgeneral\r
-*/\r
-BOOL DeletePartitions(DWORD DriveIndex, BOOL OnlyPart2)\r
-{\r
-    BOOL r = FALSE;\r
-    HRESULT hr;\r
-    ULONG ulFetched;\r
-    wchar_t wPhysicalName[48];\r
-    IVdsServiceLoader *pLoader;\r
-    IVdsService *pService;\r
-    IEnumVdsObject *pEnum;\r
-    IUnknown *pUnk;\r
-\r
-    swprintf_s(wPhysicalName, ARRAYSIZE(wPhysicalName), L"\\\\?\\PhysicalDrive%lu", DriveIndex);\r
-\r
-    // Initialize COM\r
-    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);\r
-    CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT,\r
-        RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0, NULL);\r
-\r
-    // Create a VDS Loader Instance\r
-    hr = CoCreateInstance(&CLSID_VdsLoader, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,\r
-        &IID_IVdsServiceLoader, (void **)&pLoader);\r
-    if (hr != S_OK) {\r
-        VDS_SET_ERROR(hr);\r
-        Log("Could not create VDS Loader Instance: %u", LASTERR);\r
-        goto out;\r
-    }\r
-\r
-    // Load the VDS Service\r
-    hr = IVdsServiceLoader_LoadService(pLoader, L"", &pService);\r
-    IVdsServiceLoader_Release(pLoader);\r
-    if (hr != S_OK) {\r
-        VDS_SET_ERROR(hr);\r
-        Log("Could not load VDS Service: %u", LASTERR);\r
-        goto out;\r
-    }\r
-\r
-    // Wait for the Service to become ready if needed\r
-    hr = IVdsService_WaitForServiceReady(pService);\r
-    if (hr != S_OK) {\r
-        VDS_SET_ERROR(hr);\r
-        Log("VDS Service is not ready: %u", LASTERR);\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
-        VDS_SET_ERROR(hr);\r
-        Log("Could not query VDS Service Providers: %u", LASTERR);\r
-        goto out;\r
-    }\r
-\r
-    while (IEnumVdsObject_Next(pEnum, 1, &pUnk, &ulFetched) == S_OK) {\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
-            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
-            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
-            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
-            IVdsPack *pPack;\r
-            IEnumVdsObject *pEnumDisk;\r
-            IUnknown *pDiskUnk;\r
-\r
-            hr = IUnknown_QueryInterface(pPackUnk, &IID_IVdsPack, (void **)&pPack);\r
-            IUnknown_Release(pPackUnk);\r
-            if (hr != S_OK) {\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 disks\r
-            hr = IVdsPack_QueryDisks(pPack, &pEnumDisk);\r
-            if (hr != S_OK) {\r
-                VDS_SET_ERROR(hr);\r
-                Log("Could not query VDS disks: %u", LASTERR);\r
-                goto out;\r
-            }\r
-\r
-            // List disks\r
-            while (IEnumVdsObject_Next(pEnumDisk, 1, &pDiskUnk, &ulFetched) == S_OK) {\r
-                VDS_DISK_PROP diskprop;\r
-                VDS_PARTITION_PROP* prop_array;\r
-                LONG i, prop_array_size;\r
-                IVdsDisk *pDisk;\r
-                IVdsAdvancedDisk *pAdvancedDisk;\r
-\r
-                // Get the disk interface.\r
-                hr = IUnknown_QueryInterface(pDiskUnk, &IID_IVdsDisk, (void **)&pDisk);\r
-                if (hr != S_OK) {\r
-                    VDS_SET_ERROR(hr);\r
-                    Log("Could not query VDS Disk Interface: %u", LASTERR);\r
-                    goto out;\r
-                }\r
-\r
-                // Get the disk properties\r
-                hr = IVdsDisk_GetProperties(pDisk, &diskprop);\r
-                if (hr != S_OK) {\r
-                    VDS_SET_ERROR(hr);\r
-                    Log("Could not query VDS Disk Properties: %u", LASTERR);\r
-                    goto out;\r
-                }\r
-\r
-                // Isolate the disk we want\r
-                if (_wcsicmp(wPhysicalName, diskprop.pwszName) != 0) {\r
-                    IVdsDisk_Release(pDisk);\r
-                    continue;\r
-                }\r
-\r
-                // Instantiate the AdvanceDisk interface for our disk.\r
-                hr = IVdsDisk_QueryInterface(pDisk, &IID_IVdsAdvancedDisk, (void **)&pAdvancedDisk);\r
-                IVdsDisk_Release(pDisk);\r
-                if (hr != S_OK) {\r
-                    VDS_SET_ERROR(hr);\r
-                    Log("Could not access VDS Advanced Disk interface: %u", LASTERR);\r
-                    goto out;\r
-                }\r
-\r
-                // Query the partition data, so we can get the start offset, which we need for deletion\r
-                hr = IVdsAdvancedDisk_QueryPartitions(pAdvancedDisk, &prop_array, &prop_array_size);\r
-                if (hr == S_OK) {\r
-                    Log("Deleting ALL partition(s) from disk '%S':", diskprop.pwszName);\r
-                    // Now go through each partition\r
-                    for (i = 0; i < prop_array_size; i++) {\r
-                        \r
-                        Log("* Partition %d (offset: %lld, size: %llu)", prop_array[i].ulPartitionNumber,\r
-                            prop_array[i].ullOffset, (ULONGLONG)prop_array[i].ullSize);\r
-\r
-                        if (OnlyPart2)\r
-                        {\r
-                            if (prop_array[i].ullOffset == 2048 * 512 || prop_array[i].ullSize != 32 * 1024 * 1024)\r
-                            {\r
-                                Log("Skip this partition...");\r
-                                continue;\r
-                            }\r
-                        }\r
-\r
-                        hr = IVdsAdvancedDisk_DeletePartition(pAdvancedDisk, prop_array[i].ullOffset, TRUE, TRUE);\r
-                        if (hr != S_OK) {\r
-                            r = FALSE;\r
-                            VDS_SET_ERROR(hr);\r
-                            Log("Could not delete partitions: %u", LASTERR);\r
-                        }\r
-                        else {\r
-                            Log("Delete this partitions success");\r
-                        }\r
-                    }\r
-                    r = TRUE;\r
-                }\r
-                else {\r
-                    Log("No partition to delete on disk '%S'", diskprop.pwszName);\r
-                    r = TRUE;\r
-                }\r
-                CoTaskMemFree(prop_array);\r
-\r
-#if 0\r
-                // Issue a Clean while we're at it\r
-                HRESULT hr2 = E_FAIL;\r
-                ULONG completed;\r
-                IVdsAsync* pAsync;\r
-                hr = IVdsAdvancedDisk_Clean(pAdvancedDisk, TRUE, FALSE, FALSE, &pAsync);\r
-                while (SUCCEEDED(hr)) {\r
-                    if (IS_ERROR(FormatStatus)) {\r
-                        IVdsAsync_Cancel(pAsync);\r
-                        break;\r
-                    }\r
-                    hr = IVdsAsync_QueryStatus(pAsync, &hr2, &completed);\r
-                    if (SUCCEEDED(hr)) {\r
-                        hr = hr2;\r
-                        if (hr == S_OK)\r
-                            break;\r
-                        if (hr == VDS_E_OPERATION_PENDING)\r
-                            hr = S_OK;\r
-                    }\r
-                    Sleep(500);\r
-                }\r
-                if (hr != S_OK) {\r
-                    VDS_SET_ERROR(hr);\r
-                    Log("Could not clean disk: %s", LASTERR);\r
-                }\r
-#endif\r
-                IVdsAdvancedDisk_Release(pAdvancedDisk);\r
-                goto out;\r
-            }\r
-        }\r
-    }\r
-\r
-out:\r
-    return r;\r
-}\r
-\r
+#include "DiskService.h"\r
 \r
 static DWORD GetVentoyVolumeName(int PhyDrive, UINT64 StartSectorId, CHAR *NameBuf, UINT32 BufLen, BOOL DelSlash)\r
 {\r
 \r
 static DWORD GetVentoyVolumeName(int PhyDrive, UINT64 StartSectorId, CHAR *NameBuf, UINT32 BufLen, BOOL DelSlash)\r
 {\r
@@ -1095,25 +831,33 @@ static int FormatPart2Fat(HANDLE hDrive, UINT64 StartSectorId)
     int len = 0;\r
     int writelen = 0;\r
     int partwrite = 0;\r
     int len = 0;\r
     int writelen = 0;\r
     int partwrite = 0;\r
+    int Pos = PT_WRITE_VENTOY_START;\r
     DWORD dwSize = 0;\r
     BOOL bRet;\r
     unsigned char *data = NULL;\r
     LARGE_INTEGER liCurrentPosition;\r
        LARGE_INTEGER liNewPosition;\r
     DWORD dwSize = 0;\r
     BOOL bRet;\r
     unsigned char *data = NULL;\r
     LARGE_INTEGER liCurrentPosition;\r
        LARGE_INTEGER liNewPosition;\r
+    BYTE *CheckBuf = NULL;\r
 \r
        Log("FormatPart2Fat %llu...", StartSectorId);\r
 \r
 \r
        Log("FormatPart2Fat %llu...", StartSectorId);\r
 \r
+    CheckBuf = malloc(SIZE_1MB);\r
+    if (!CheckBuf)\r
+    {\r
+        Log("Failed to malloc check buf");\r
+        return 1;\r
+    }\r
+\r
     rc = ReadWholeFileToBuf(VENTOY_FILE_DISK_IMG, 0, (void **)&data, &len);\r
     if (rc)\r
     {\r
         Log("Failed to read img file %p %u", data, len);\r
     rc = ReadWholeFileToBuf(VENTOY_FILE_DISK_IMG, 0, (void **)&data, &len);\r
     if (rc)\r
     {\r
         Log("Failed to read img file %p %u", data, len);\r
+        free(CheckBuf);\r
         return 1;\r
     }\r
 \r
     liCurrentPosition.QuadPart = StartSectorId * 512;\r
         return 1;\r
     }\r
 \r
     liCurrentPosition.QuadPart = StartSectorId * 512;\r
-       SetFilePointerEx(hDrive, liCurrentPosition, &liNewPosition, FILE_BEGIN);\r
-\r
-       Log("Set file pointer: %llu  New pointer:%llu", liCurrentPosition.QuadPart, liNewPosition.QuadPart);\r
+    SetFilePointerEx(hDrive, liCurrentPosition, &liNewPosition, FILE_BEGIN);\r
 \r
     memset(g_part_img_buf, 0, sizeof(g_part_img_buf));\r
 \r
 \r
     memset(g_part_img_buf, 0, sizeof(g_part_img_buf));\r
 \r
@@ -1141,7 +885,34 @@ static int FormatPart2Fat(HANDLE hDrive, UINT64 StartSectorId)
                     goto End;\r
                 }\r
 \r
                     goto End;\r
                 }\r
 \r
-                PROGRESS_BAR_SET_POS(PT_WRITE_VENTOY_START + i);                \r
+                PROGRESS_BAR_SET_POS(Pos);\r
+                if (i % 2 == 0)\r
+                {\r
+                    Pos++;\r
+                }\r
+            }\r
+\r
+            //Read and check the data\r
+            liCurrentPosition.QuadPart = StartSectorId * 512;\r
+            SetFilePointerEx(hDrive, liCurrentPosition, &liNewPosition, FILE_BEGIN);\r
+\r
+            for (i = 0; i < VENTOY_EFI_PART_SIZE / SIZE_1MB; i++)\r
+            {\r
+                bRet = ReadFile(hDrive, CheckBuf, SIZE_1MB, &dwSize, NULL);\r
+                Log("Read part data bRet:%u dwSize:%u code:%u", bRet, dwSize, LASTERR);\r
+\r
+                if (!bRet || memcmp(CheckBuf, g_part_img_buf[0] + i * SIZE_1MB, SIZE_1MB))\r
+                {\r
+                    Log("### [Check Fail] The data write and read does not match");\r
+                    rc = 1;\r
+                    goto End;\r
+                }\r
+\r
+                PROGRESS_BAR_SET_POS(Pos);\r
+                if (i % 2 == 0)\r
+                {\r
+                    Pos++;\r
+                }\r
             }\r
         }\r
         else\r
             }\r
         }\r
         else\r
@@ -1178,7 +949,7 @@ static int FormatPart2Fat(HANDLE hDrive, UINT64 StartSectorId)
                        \r
                        VentoyProcSecureBoot(g_SecureBoot);\r
 \r
                        \r
                        VentoyProcSecureBoot(g_SecureBoot);\r
 \r
-            for (int i = 0; i < VENTOY_EFI_PART_SIZE / SIZE_1MB; i++)\r
+            for (i = 0; i < VENTOY_EFI_PART_SIZE / SIZE_1MB; i++)\r
             {\r
                 dwSize = 0;\r
                 bRet = WriteFile(hDrive, g_part_img_buf[i], SIZE_1MB, &dwSize, NULL);\r
             {\r
                 dwSize = 0;\r
                 bRet = WriteFile(hDrive, g_part_img_buf[i], SIZE_1MB, &dwSize, NULL);\r
@@ -1189,8 +960,35 @@ static int FormatPart2Fat(HANDLE hDrive, UINT64 StartSectorId)
                     rc = 1;\r
                     goto End;\r
                 }\r
                     rc = 1;\r
                     goto End;\r
                 }\r
+                \r
+                PROGRESS_BAR_SET_POS(Pos);\r
+                if (i % 2 == 0)\r
+                {\r
+                    Pos++;\r
+                }\r
+            }\r
+\r
+            //Read and check the data\r
+            liCurrentPosition.QuadPart = StartSectorId * 512;\r
+            SetFilePointerEx(hDrive, liCurrentPosition, &liNewPosition, FILE_BEGIN);\r
+\r
+            for (i = 0; i < VENTOY_EFI_PART_SIZE / SIZE_1MB; i++)\r
+            {\r
+                bRet = ReadFile(hDrive, CheckBuf, SIZE_1MB, &dwSize, NULL);\r
+                Log("Read part data bRet:%u dwSize:%u code:%u", bRet, dwSize, LASTERR);\r
+\r
+                if (!bRet || memcmp(CheckBuf, g_part_img_buf[i], SIZE_1MB))\r
+                {\r
+                    Log("### [Check Fail] The data write and read does not match");\r
+                    rc = 1;\r
+                    goto End;\r
+                }\r
 \r
 \r
-                PROGRESS_BAR_SET_POS(PT_WRITE_VENTOY_START + i);\r
+                PROGRESS_BAR_SET_POS(Pos);\r
+                if (i % 2 == 0)\r
+                {\r
+                    Pos++;\r
+                }\r
             }\r
         }\r
         else\r
             }\r
         }\r
         else\r
@@ -1204,6 +1002,7 @@ static int FormatPart2Fat(HANDLE hDrive, UINT64 StartSectorId)
 End:\r
 \r
     if (data) free(data);\r
 End:\r
 \r
     if (data) free(data);\r
+    if (CheckBuf)free(CheckBuf);\r
 \r
     if (partwrite)\r
     {\r
 \r
     if (partwrite)\r
     {\r
@@ -1369,7 +1168,7 @@ int ClearVentoyFromPhyDrive(HWND hWnd, PHY_DRIVE_INFO *pPhyDrive, char *pDrvLett
 \r
     PROGRESS_BAR_SET_POS(PT_DEL_ALL_PART);\r
 \r
 \r
     PROGRESS_BAR_SET_POS(PT_DEL_ALL_PART);\r
 \r
-    if (!DeletePartitions(pPhyDrive->PhyDrive, FALSE))\r
+    if (!VDS_DeleteAllPartitions(pPhyDrive->PhyDrive))\r
     {\r
         Log("Notice: Could not delete partitions: %u", GetLastError());\r
     }\r
     {\r
         Log("Notice: Could not delete partitions: %u", GetLastError());\r
     }\r
@@ -1772,7 +1571,7 @@ End:
 }\r
 \r
 \r
 }\r
 \r
 \r
-int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle)\r
+int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle, int TryId)\r
 {\r
     int i;\r
     int rc = 0;\r
 {\r
     int i;\r
     int rc = 0;\r
@@ -1789,7 +1588,7 @@ int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle)
     UINT64 Part1SectorCount = 0;\r
     UINT64 Part2StartSector = 0;\r
 \r
     UINT64 Part1SectorCount = 0;\r
     UINT64 Part2StartSector = 0;\r
 \r
-    Log("InstallVentoy2PhyDrive %s PhyDrive%d <<%s %s %dGB>>",\r
+    Log("InstallVentoy2PhyDrive try%d %s PhyDrive%d <<%s %s %dGB>>", TryId,\r
         PartStyle ? "GPT" : "MBR", pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId,\r
         GetHumanReadableGBSize(pPhyDrive->SizeInBytes));\r
 \r
         PartStyle ? "GPT" : "MBR", pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId,\r
         GetHumanReadableGBSize(pPhyDrive->SizeInBytes));\r
 \r
@@ -1856,7 +1655,7 @@ int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle)
 \r
     PROGRESS_BAR_SET_POS(PT_DEL_ALL_PART);\r
 \r
 \r
     PROGRESS_BAR_SET_POS(PT_DEL_ALL_PART);\r
 \r
-    if (!DeletePartitions(pPhyDrive->PhyDrive, FALSE))\r
+    if (!VDS_DeleteAllPartitions(pPhyDrive->PhyDrive))\r
     {\r
         Log("Notice: Could not delete partitions: %u", GetLastError());\r
     }\r
     {\r
         Log("Notice: Could not delete partitions: %u", GetLastError());\r
     }\r
@@ -2026,107 +1825,127 @@ End:
     return rc;\r
 }\r
 \r
     return rc;\r
 }\r
 \r
-int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)\r
+\r
+int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId)\r
 {\r
 {\r
-    int i;\r
-    int rc = 0;\r
-    BOOL ForceMBR = FALSE;\r
-    HANDLE hVolume;\r
-    HANDLE hDrive;\r
-    DWORD Status;\r
-    DWORD dwSize;\r
-    BOOL bRet;\r
-    CHAR DriveName[] = "?:\\";\r
-    CHAR DriveLetters[MAX_PATH] = { 0 };\r
-    UINT64 StartSector;\r
+       int i;\r
+       int rc = 0;\r
+       int MaxRetry = 3;\r
+       BOOL ForceMBR = FALSE;\r
+       BOOL Esp2Basic = FALSE;\r
+       HANDLE hVolume;\r
+       HANDLE hDrive;\r
+       DWORD Status;\r
+       DWORD dwSize;\r
+       BOOL bRet;\r
+       CHAR DriveName[] = "?:\\";\r
+       CHAR DriveLetters[MAX_PATH] = { 0 };\r
+       UINT64 StartSector;\r
        UINT64 ReservedMB = 0;\r
        UINT64 ReservedMB = 0;\r
-    MBR_HEAD BootImg;\r
-    MBR_HEAD MBR;\r
-    VTOY_GPT_INFO *pGptInfo = NULL;\r
-    UINT8 ReservedData[4096];\r
+       MBR_HEAD BootImg;\r
+       MBR_HEAD MBR;\r
+       VTOY_GPT_INFO *pGptInfo = NULL;\r
+       UINT8 ReservedData[4096];\r
 \r
 \r
-    Log("UpdateVentoy2PhyDrive %s PhyDrive%d <<%s %s %dGB>>",\r
-        pPhyDrive->PartStyle ? "GPT" : "MBR", pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId,\r
-        GetHumanReadableGBSize(pPhyDrive->SizeInBytes));\r
+       Log("UpdateVentoy2PhyDrive try%d %s PhyDrive%d <<%s %s %dGB>>", TryId,\r
+               pPhyDrive->PartStyle ? "GPT" : "MBR", pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId,\r
+               GetHumanReadableGBSize(pPhyDrive->SizeInBytes));\r
 \r
 \r
-    PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN);\r
+       PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN);\r
 \r
 \r
-    Log("Lock disk for umount ............................ ");\r
+       Log("Lock disk for umount ............................ ");\r
 \r
 \r
-    hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, FALSE, FALSE);\r
-    if (hDrive == INVALID_HANDLE_VALUE)\r
-    {\r
-        Log("Failed to open physical disk");\r
-        return 1;\r
-    }\r
+       hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, FALSE, FALSE);\r
+       if (hDrive == INVALID_HANDLE_VALUE)\r
+       {\r
+               Log("Failed to open physical disk");\r
+               return 1;\r
+       }\r
 \r
 \r
-    if (pPhyDrive->PartStyle)\r
-    {\r
-        pGptInfo = malloc(sizeof(VTOY_GPT_INFO));\r
-        if (!pGptInfo)\r
-        {\r
-            return 1;\r
-        }\r
+       if (pPhyDrive->PartStyle)\r
+       {\r
+               pGptInfo = malloc(sizeof(VTOY_GPT_INFO));\r
+               if (!pGptInfo)\r
+               {\r
+                       return 1;\r
+               }\r
 \r
 \r
-        memset(pGptInfo, 0, sizeof(VTOY_GPT_INFO));\r
+               memset(pGptInfo, 0, sizeof(VTOY_GPT_INFO));\r
 \r
 \r
-        // Read GPT Info\r
-        SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);\r
-        ReadFile(hDrive, pGptInfo, sizeof(VTOY_GPT_INFO), &dwSize, NULL);\r
+               // Read GPT Info\r
+               SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);\r
+               ReadFile(hDrive, pGptInfo, sizeof(VTOY_GPT_INFO), &dwSize, NULL);\r
 \r
 \r
-        //MBR will be used to compare with local boot image\r
-        memcpy(&MBR, &pGptInfo->MBR, sizeof(MBR_HEAD));\r
+               //MBR will be used to compare with local boot image\r
+               memcpy(&MBR, &pGptInfo->MBR, sizeof(MBR_HEAD));\r
 \r
 \r
-        StartSector = pGptInfo->PartTbl[1].StartLBA;\r
-        Log("GPT StartSector in PartTbl:%llu", (ULONGLONG)StartSector);\r
+               StartSector = pGptInfo->PartTbl[1].StartLBA;\r
+               Log("GPT StartSector in PartTbl:%llu", (ULONGLONG)StartSector);\r
 \r
 \r
-        ReservedMB = (pPhyDrive->SizeInBytes / 512 - (StartSector + VENTOY_EFI_PART_SIZE / 512) - 33) / 2048;\r
-        Log("GPT Reserved Disk Space:%llu MB", (ULONGLONG)ReservedMB);\r
-    }\r
-    else\r
-    {\r
-        // Read MBR\r
-        SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);\r
-        ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL);\r
+               ReservedMB = (pPhyDrive->SizeInBytes / 512 - (StartSector + VENTOY_EFI_PART_SIZE / 512) - 33) / 2048;\r
+               Log("GPT Reserved Disk Space:%llu MB", (ULONGLONG)ReservedMB);\r
+       }\r
+       else\r
+       {\r
+               // Read MBR\r
+               SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);\r
+               ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL);\r
 \r
 \r
-        StartSector = MBR.PartTbl[1].StartSectorId;\r
-        Log("MBR StartSector in PartTbl:%llu", (ULONGLONG)StartSector);\r
+               StartSector = MBR.PartTbl[1].StartSectorId;\r
+               Log("MBR StartSector in PartTbl:%llu", (ULONGLONG)StartSector);\r
 \r
 \r
-        ReservedMB = (pPhyDrive->SizeInBytes / 512 - (StartSector + VENTOY_EFI_PART_SIZE / 512)) / 2048;\r
-        Log("MBR Reserved Disk Space:%llu MB", (ULONGLONG)ReservedMB);\r
-    }\r
+               ReservedMB = (pPhyDrive->SizeInBytes / 512 - (StartSector + VENTOY_EFI_PART_SIZE / 512)) / 2048;\r
+               Log("MBR Reserved Disk Space:%llu MB", (ULONGLONG)ReservedMB);\r
+       }\r
 \r
 \r
-    //Read Reserved Data\r
-    SetFilePointer(hDrive, 512 * 2040, NULL, FILE_BEGIN);\r
-    ReadFile(hDrive, ReservedData, sizeof(ReservedData), &dwSize, NULL);\r
+       //Read Reserved Data\r
+       SetFilePointer(hDrive, 512 * 2040, NULL, FILE_BEGIN);\r
+       ReadFile(hDrive, ReservedData, sizeof(ReservedData), &dwSize, NULL);\r
 \r
 \r
-    GetLettersBelongPhyDrive(pPhyDrive->PhyDrive, DriveLetters, sizeof(DriveLetters));\r
+       GetLettersBelongPhyDrive(pPhyDrive->PhyDrive, DriveLetters, sizeof(DriveLetters));\r
 \r
 \r
-    if (DriveLetters[0] == 0)\r
-    {\r
-        Log("No drive letter was assigned...");\r
-    }\r
-    else\r
-    {\r
-        // Unmount all mounted volumes that belong to this drive\r
-        // Do it in reverse so that we always end on the first volume letter\r
-        for (i = (int)strlen(DriveLetters); i > 0; i--)\r
-        {\r
-            DriveName[0] = DriveLetters[i - 1];\r
-            if (IsVentoyLogicalDrive(DriveName[0]))\r
-            {\r
-                Log("%s is ventoy logical drive", DriveName);\r
-                bRet = DeleteVolumeMountPointA(DriveName);\r
-                Log("Delete mountpoint %s ret:%u code:%u", DriveName, bRet, LASTERR);\r
-                break;\r
-            }\r
-        }\r
-    }\r
+       if (DriveLetters[0] == 0)\r
+       {\r
+               Log("No drive letter was assigned...");\r
+       }\r
+       else\r
+       {\r
+               // Unmount all mounted volumes that belong to this drive\r
+               // Do it in reverse so that we always end on the first volume letter\r
+               for (i = (int)strlen(DriveLetters); i > 0; i--)\r
+               {\r
+                       DriveName[0] = DriveLetters[i - 1];\r
+                       if (IsVentoyLogicalDrive(DriveName[0]))\r
+                       {\r
+                               Log("%s is ventoy logical drive", DriveName);\r
+                               bRet = DeleteVolumeMountPointA(DriveName);\r
+                               Log("Delete mountpoint %s ret:%u code:%u", DriveName, bRet, LASTERR);\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
 \r
 \r
-    // It kind of blows, but we have to relinquish access to the physical drive\r
-    // for VDS to be able to delete the partitions that reside on it...\r
-    DeviceIoControl(hDrive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);\r
-    CHECK_CLOSE_HANDLE(hDrive);\r
+       // It kind of blows, but we have to relinquish access to the physical drive\r
+       // for VDS to be able to delete the partitions that reside on it...\r
+       DeviceIoControl(hDrive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);\r
+       CHECK_CLOSE_HANDLE(hDrive);\r
+\r
+       if (pPhyDrive->PartStyle == 1)\r
+       {\r
+               Log("TryId=%d EFI GPT partition type is 0x%llx", TryId, pPhyDrive->Part2GPTAttr);\r
+\r
+               if ((TryId == 1 && (pPhyDrive->Part2GPTAttr >> 56) == 0xC0) || TryId == 2)\r
+               {\r
+                       PROGRESS_BAR_SET_POS(PT_DEL_ALL_PART);\r
+                       Log("Change GPT partition type to ESP");\r
+\r
+                       if (VDS_ChangeVtoyEFI2ESP(pPhyDrive->PhyDrive, StartSector * 512))\r
+                       {\r
+                               Esp2Basic = TRUE;\r
+                               Sleep(1000);\r
+                       }\r
+               }\r
+       }\r
 \r
     PROGRESS_BAR_SET_POS(PT_LOCK_FOR_WRITE);\r
 \r
 \r
     PROGRESS_BAR_SET_POS(PT_LOCK_FOR_WRITE);\r
 \r
@@ -2143,30 +1962,66 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)
 \r
     Log("Lock volume for update .......................... ");\r
     hVolume = INVALID_HANDLE_VALUE;\r
 \r
     Log("Lock volume for update .......................... ");\r
     hVolume = INVALID_HANDLE_VALUE;\r
-       Status = GetVentoyVolumeName(pPhyDrive->PhyDrive, StartSector, DriveLetters, sizeof(DriveLetters), TRUE);\r
+\r
+       //If we change VTOYEFI to ESP, it can not have s volume name, so don't try to get it.\r
+       if (Esp2Basic)\r
+       {\r
+               Status = ERROR_NOT_FOUND;\r
+       }\r
+       else\r
+       {\r
+               for (i = 0; i < MaxRetry; i++)\r
+               {\r
+                       Status = GetVentoyVolumeName(pPhyDrive->PhyDrive, StartSector, DriveLetters, sizeof(DriveLetters), TRUE);\r
+                       if (ERROR_SUCCESS == Status)\r
+                       {\r
+                               break;\r
+                       }\r
+                       else\r
+                       {\r
+                               Log("==== Volume not found, wait and retry %d... ====", i);\r
+                               Sleep(2);\r
+                       }\r
+               }\r
+       }\r
+       \r
     if (ERROR_SUCCESS == Status)\r
     {\r
         Log("Now lock and dismount volume <%s>", DriveLetters);\r
     if (ERROR_SUCCESS == Status)\r
     {\r
         Log("Now lock and dismount volume <%s>", DriveLetters);\r
-        hVolume = CreateFileA(DriveLetters,\r
-            GENERIC_READ | GENERIC_WRITE,\r
-            FILE_SHARE_READ,\r
-            NULL,\r
-            OPEN_EXISTING,\r
-            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,\r
-            NULL);\r
+\r
+        for (i = 0; i < MaxRetry; i++)\r
+        {\r
+            hVolume = CreateFileA(DriveLetters,\r
+                GENERIC_READ | GENERIC_WRITE,\r
+                FILE_SHARE_READ,\r
+                NULL,\r
+                OPEN_EXISTING,\r
+                FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,\r
+                NULL);\r
+\r
+            if (hVolume == INVALID_HANDLE_VALUE)\r
+            {\r
+                Log("Failed to create file volume, errcode:%u, wait and retry ...", LASTERR);\r
+                Sleep(2000);\r
+            }\r
+            else\r
+            {\r
+                break;\r
+            }\r
+        }\r
 \r
         if (hVolume == INVALID_HANDLE_VALUE)\r
         {\r
             Log("Failed to create file volume, errcode:%u", LASTERR);\r
 \r
         if (hVolume == INVALID_HANDLE_VALUE)\r
         {\r
             Log("Failed to create file volume, errcode:%u", LASTERR);\r
-            rc = 1;\r
-            goto End;\r
         }\r
         }\r
+        else\r
+        {\r
+            bRet = DeviceIoControl(hVolume, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);\r
+            Log("FSCTL_LOCK_VOLUME bRet:%u code:%u", bRet, LASTERR);\r
 \r
 \r
-        bRet = DeviceIoControl(hVolume, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);\r
-        Log("FSCTL_LOCK_VOLUME bRet:%u code:%u", bRet, LASTERR);\r
-\r
-        bRet = DeviceIoControl(hVolume, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);\r
-        Log("FSCTL_DISMOUNT_VOLUME bRet:%u code:%u", bRet, LASTERR);\r
+            bRet = DeviceIoControl(hVolume, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);\r
+            Log("FSCTL_DISMOUNT_VOLUME bRet:%u code:%u", bRet, LASTERR);\r
+        }\r
     }\r
     else if (ERROR_NOT_FOUND == Status)\r
     {\r
     }\r
     else if (ERROR_NOT_FOUND == Status)\r
     {\r
@@ -2178,18 +2033,17 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)
         goto End;\r
     }\r
 \r
         goto End;\r
     }\r
 \r
-\r
     if (!TryWritePart2(hDrive, StartSector))\r
     {\r
                if (pPhyDrive->PartStyle == 0)\r
                {\r
                        ForceMBR = TRUE;\r
     if (!TryWritePart2(hDrive, StartSector))\r
     {\r
                if (pPhyDrive->PartStyle == 0)\r
                {\r
                        ForceMBR = TRUE;\r
-                       Log("Try write failed, now delete partition 2...");\r
 \r
 \r
+                       Log("Try write failed, now delete partition 2 for MBR...");\r
                        CHECK_CLOSE_HANDLE(hDrive);\r
 \r
                        Log("Now delete partition 2...");\r
                        CHECK_CLOSE_HANDLE(hDrive);\r
 \r
                        Log("Now delete partition 2...");\r
-                       DeletePartitions(pPhyDrive->PhyDrive, TRUE);\r
+                       VDS_DeleteVtoyEFIPartition(pPhyDrive->PhyDrive);\r
 \r
                        hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, TRUE, FALSE);\r
                        if (hDrive == INVALID_HANDLE_VALUE)\r
 \r
                        hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, TRUE, FALSE);\r
                        if (hDrive == INVALID_HANDLE_VALUE)\r
@@ -2199,6 +2053,12 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)
                                goto End;\r
                        }\r
                }\r
                                goto End;\r
                        }\r
                }\r
+               else\r
+               {\r
+                       Log("TryWritePart2 failed ....");\r
+                       rc = 1;\r
+                       goto End;\r
+               }\r
     }\r
 \r
     PROGRESS_BAR_SET_POS(PT_FORMAT_PART2);\r
     }\r
 \r
     PROGRESS_BAR_SET_POS(PT_FORMAT_PART2);\r
@@ -2285,6 +2145,12 @@ End:
 \r
     CHECK_CLOSE_HANDLE(hDrive);\r
 \r
 \r
     CHECK_CLOSE_HANDLE(hDrive);\r
 \r
+    if (Esp2Basic)\r
+    {\r
+               Log("Recover GPT partition type to basic");\r
+               VDS_ChangeVtoyEFI2Basic(pPhyDrive->PhyDrive, StartSector * 512);\r
+    }\r
+\r
     if (pGptInfo)\r
     {\r
         free(pGptInfo);\r
     if (pGptInfo)\r
     {\r
         free(pGptInfo);\r
index 6b4416076ace18a21b78293f7aae38bba3d03168..c9c32bd1b5557cc5ffae800a4ba147e2c75c27b8 100644 (file)
@@ -1,7 +1,8 @@
 /******************************************************************************\r
  * Utility.c\r
  *\r
 /******************************************************************************\r
  * Utility.c\r
  *\r
- * Copyright (c) 2020, longpanda <admin@ventoy.net>\r
+ * Copyright (c) 2021, longpanda <admin@ventoy.net>\r
+ * Copyright (c) 2011-2020, Pete Batard <pete@akeo.ie>\r
  *\r
  * This program is free software; you can redistribute it and/or\r
  * modify it under the terms of the GNU General Public License as\r
  *\r
  * This program is free software; you can redistribute it and/or\r
  * modify it under the terms of the GNU General Public License as\r
 #include <Windows.h>\r
 #include "Ventoy2Disk.h"\r
 \r
 #include <Windows.h>\r
 #include "Ventoy2Disk.h"\r
 \r
+void TraceOut(const char *Fmt, ...)\r
+{\r
+    va_list Arg;\r
+    int Len = 0;\r
+    FILE *File = NULL;\r
+    char szBuf[1024];\r
+\r
+    va_start(Arg, Fmt);\r
+    Len += vsnprintf_s(szBuf + Len, sizeof(szBuf)-Len, sizeof(szBuf)-Len, Fmt, Arg);\r
+    va_end(Arg);\r
+\r
+    fopen_s(&File, VENTOY_FILE_LOG, "a+");\r
+    if (File)\r
+    {\r
+        fwrite(szBuf, 1, Len, File);\r
+        fclose(File);\r
+    }\r
+}\r
+\r
 void Log(const char *Fmt, ...)\r
 {\r
     va_list Arg;\r
 void Log(const char *Fmt, ...)\r
 {\r
     va_list Arg;\r
@@ -92,6 +112,22 @@ BOOL IsPathExist(BOOL Dir, const char *Fmt, ...)
     return TRUE;\r
 }\r
 \r
     return TRUE;\r
 }\r
 \r
+int SaveBufToFile(const CHAR *FileName, const void *Buffer, int BufLen)\r
+{\r
+    FILE *File = NULL;\r
+    void *Data = NULL;\r
+\r
+    fopen_s(&File, FileName, "wb");\r
+    if (File == NULL)\r
+    {\r
+        Log("Failed to open file %s", FileName);\r
+        return 1;\r
+    }\r
+\r
+    fwrite(Buffer, 1, BufLen, File);\r
+    fclose(File);\r
+    return 0;\r
+}\r
 \r
 int ReadWholeFileToBuf(const CHAR *FileName, int ExtLen, void **Bufer, int *BufLen)\r
 {\r
 \r
 int ReadWholeFileToBuf(const CHAR *FileName, int ExtLen, void **Bufer, int *BufLen)\r
 {\r
@@ -205,73 +241,239 @@ BOOL IsWow64(void)
     return bIsWow64;\r
 }\r
 \r
     return bIsWow64;\r
 }\r
 \r
-void DumpWindowsVersion(void)\r
+/*\r
+* Some code and functions in the file are copied from rufus.\r
+* https://github.com/pbatard/rufus\r
+*/\r
+\r
+/* Windows versions */\r
+enum WindowsVersion {\r
+    WINDOWS_UNDEFINED = -1,\r
+    WINDOWS_UNSUPPORTED = 0,\r
+    WINDOWS_XP = 0x51,\r
+    WINDOWS_2003 = 0x52,       // Also XP_64\r
+    WINDOWS_VISTA = 0x60,      // Also Server 2008\r
+    WINDOWS_7 = 0x61,          // Also Server 2008_R2\r
+    WINDOWS_8 = 0x62,          // Also Server 2012\r
+    WINDOWS_8_1 = 0x63,                // Also Server 2012_R2\r
+    WINDOWS_10_PREVIEW1 = 0x64,\r
+    WINDOWS_10 = 0xA0,         // Also Server 2016, also Server 2019\r
+    WINDOWS_11 = 0xB0,         // Also Server 2022\r
+    WINDOWS_MAX\r
+};\r
+\r
+static const char* GetEdition(DWORD ProductType)\r
 {\r
 {\r
-    int Bit; \r
-    BOOL WsVer;    \r
-    DWORD Major, Minor;\r
-    ULONGLONG MajorEqual, MinorEqual;\r
-    OSVERSIONINFOEXA Ver1, Ver2;\r
-    const CHAR *Ver = NULL; \r
-    CHAR WinVer[256] = { 0 };\r
-\r
-    memset(&Ver1, 0, sizeof(Ver1));\r
-    memset(&Ver2, 0, sizeof(Ver2));\r
-\r
-    Ver1.dwOSVersionInfoSize = sizeof(Ver1);\r
-    \r
+    // From: https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getproductinfo\r
+    // These values can be found in the winnt.h header.\r
+    switch (ProductType) {\r
+    case 0x00000000: return "";        //  Undefined\r
+    case 0x00000001: return "Ultimate";\r
+    case 0x00000002: return "Home Basic";\r
+    case 0x00000003: return "Home Premium";\r
+    case 0x00000004: return "Enterprise";\r
+    case 0x00000005: return "Home Basic N";\r
+    case 0x00000006: return "Business";\r
+    case 0x00000007: return "Standard Server";\r
+    case 0x00000008: return "Datacenter Server";\r
+    case 0x00000009: return "Smallbusiness Server";\r
+    case 0x0000000A: return "Enterprise Server";\r
+    case 0x0000000B: return "Starter";\r
+    case 0x00000010: return "Business N";\r
+    case 0x00000011: return "Web Server";\r
+    case 0x00000012: return "Cluster Server";\r
+    case 0x00000013: return "Home Server";\r
+    case 0x0000001A: return "Home Premium N";\r
+    case 0x0000001B: return "Enterprise N";\r
+    case 0x0000001C: return "Ultimate N";\r
+    case 0x00000022: return "Home Premium Server";\r
+    case 0x0000002F: return "Starter N";\r
+    case 0x00000030: return "Pro";\r
+    case 0x00000031: return "Pro N";\r
+    case 0x00000042: return "Starter E";\r
+    case 0x00000043: return "Home Basic E";\r
+    case 0x00000044: return "Premium E";\r
+    case 0x00000045: return "Pro E";\r
+    case 0x00000046: return "Enterprise E";\r
+    case 0x00000047: return "Ultimate E";\r
+    case 0x00000048: return "Enterprise Eval";\r
+    case 0x00000054: return "Enterprise N Eval";\r
+    case 0x00000057: return "Thin PC";\r
+    case 0x0000006F: return "Core Connected";\r
+    case 0x00000070: return "Pro Student";\r
+    case 0x00000071: return "Core Connected N";\r
+    case 0x00000072: return "Pro Student N";\r
+    case 0x00000073: return "Core Connected Single Language";\r
+    case 0x00000074: return "Core Connected China";\r
+    case 0x00000079: return "Edu";\r
+    case 0x0000007A: return "Edu N";\r
+    case 0x0000007D: return "Enterprise S";\r
+    case 0x0000007E: return "Enterprise S N";\r
+    case 0x0000007F: return "Pro S";\r
+    case 0x00000080: return "Pro S N";\r
+    case 0x00000081: return "Enterprise S Eval";\r
+    case 0x00000082: return "Enterprise S N Eval";\r
+    case 0x0000008A: return "Pro Single Language";\r
+    case 0x0000008B: return "Pro China";\r
+    case 0x0000008C: return "Enterprise Subscription";\r
+    case 0x0000008D: return "Enterprise Subscription N";\r
+    case 0x00000095: return "Utility VM";\r
+    case 0x000000A1: return "Pro Workstation";\r
+    case 0x000000A2: return "Pro Workstation N";\r
+    case 0x000000A4: return "Pro for Education";\r
+    case 0x000000A5: return "Pro for Education N";\r
+    case 0x000000AB: return "Enterprise G";    // I swear Microsoft are just making up editions...\r
+    case 0x000000AC: return "Enterprise G N";\r
+    case 0x000000B6: return "Core OS";\r
+    case 0x000000B7: return "Cloud E";\r
+    case 0x000000B8: return "Cloud E N";\r
+    case 0x000000BD: return "Lite";\r
+    case 0xABCDABCD: return "(Unlicensed)";\r
+    default: return "(Unknown Edition)";\r
+    }\r
+}\r
+\r
+#define is_x64 IsWow64\r
+#define static_strcpy safe_strcpy \r
+#define REGKEY_HKCU HKEY_CURRENT_USER\r
+#define REGKEY_HKLM HKEY_LOCAL_MACHINE\r
+static int  nWindowsVersion = WINDOWS_UNDEFINED;\r
+static int  nWindowsBuildNumber = -1;\r
+static char WindowsVersionStr[128] = "";\r
+\r
+/* Helpers for 32 bit registry operations */\r
+\r
+/*\r
+* Read a generic registry key value. If a short key_name is used, assume that\r
+* it belongs to the application and create the app subkey if required\r
+*/\r
+static __inline BOOL _GetRegistryKey(HKEY key_root, const char* key_name, DWORD reg_type,\r
+    LPBYTE dest, DWORD dest_size)\r
+{\r
+    const char software_prefix[] = "SOFTWARE\\";\r
+    char long_key_name[MAX_PATH] = { 0 };\r
+    BOOL r = FALSE;\r
+    size_t i;\r
+    LONG s;\r
+    HKEY hSoftware = NULL, hApp = NULL;\r
+    DWORD dwType = -1, dwSize = dest_size;\r
+\r
+    memset(dest, 0, dest_size);\r
+\r
+    if (key_name == NULL)\r
+        return FALSE;\r
+\r
+    for (i = strlen(key_name); i>0; i--) {\r
+        if (key_name[i] == '\\')\r
+            break;\r
+    }\r
+\r
+    if (i > 0) {\r
+        // Prefix with "SOFTWARE" if needed\r
+        if (_strnicmp(key_name, software_prefix, sizeof(software_prefix)-1) != 0) {\r
+            if (i + sizeof(software_prefix) >= sizeof(long_key_name))\r
+                return FALSE;\r
+            strcpy_s(long_key_name, sizeof(long_key_name), software_prefix);\r
+            strcat_s(long_key_name, sizeof(long_key_name), key_name);\r
+            long_key_name[sizeof(software_prefix)+i - 1] = 0;\r
+        }\r
+        else {\r
+            if (i >= sizeof(long_key_name))\r
+                return FALSE;\r
+            static_strcpy(long_key_name, key_name);\r
+            long_key_name[i] = 0;\r
+        }\r
+        i++;\r
+        if (RegOpenKeyExA(key_root, long_key_name, 0, KEY_READ, &hApp) != ERROR_SUCCESS) {\r
+            hApp = NULL;\r
+            goto out;\r
+        }\r
+    }\r
+    else {\r
+        if (RegOpenKeyExA(key_root, "SOFTWARE", 0, KEY_READ | KEY_CREATE_SUB_KEY, &hSoftware) != ERROR_SUCCESS) {\r
+            hSoftware = NULL;\r
+            goto out;\r
+        }        \r
+    }\r
+\r
+    s = RegQueryValueExA(hApp, &key_name[i], NULL, &dwType, (LPBYTE)dest, &dwSize);\r
+    // No key means default value of 0 or empty string\r
+    if ((s == ERROR_FILE_NOT_FOUND) || ((s == ERROR_SUCCESS) && (dwType == reg_type) && (dwSize > 0))) {\r
+        r = TRUE;\r
+    }\r
+out:\r
+    if (hSoftware != NULL)\r
+        RegCloseKey(hSoftware);\r
+    if (hApp != NULL)\r
+        RegCloseKey(hApp);\r
+    return r;\r
+}\r
+\r
+#define GetRegistryKey32(root, key, pval) _GetRegistryKey(root, key, REG_DWORD, (LPBYTE)pval, sizeof(DWORD))\r
+static __inline INT32 ReadRegistryKey32(HKEY root, const char* key) {\r
+    DWORD val;\r
+    GetRegistryKey32(root, key, &val);\r
+    return (INT32)val;\r
+}\r
+\r
+/*\r
+* Modified from smartmontools' os_win32.cpp\r
+*/\r
+void GetWindowsVersion(void)\r
+{   \r
+    OSVERSIONINFOEXA vi, vi2;\r
+    DWORD dwProductType;\r
+    const char* w = 0;\r
+    const char* w64 = "32 bit";\r
+    char *vptr;\r
+    size_t vlen;\r
+    unsigned major, minor;\r
+    ULONGLONG major_equal, minor_equal;\r
+    BOOL ws;\r
+\r
+    nWindowsVersion = WINDOWS_UNDEFINED;\r
+    static_strcpy(WindowsVersionStr, "Windows Undefined");\r
+\r
     // suppress the C4996 warning for GetVersionExA\r
     #pragma warning(push)\r
     #pragma warning(disable:4996)\r
     // suppress the C4996 warning for GetVersionExA\r
     #pragma warning(push)\r
     #pragma warning(disable:4996)\r
-    if (!GetVersionExA((OSVERSIONINFOA *)&Ver1))\r
-    {\r
-        memset(&Ver1, 0, sizeof(Ver1));\r
-        Ver1.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);\r
-        if (!GetVersionExA((OSVERSIONINFOA *)&Ver1))\r
-        {\r
+\r
+    memset(&vi, 0, sizeof(vi));\r
+    vi.dwOSVersionInfoSize = sizeof(vi);\r
+    if (!GetVersionExA((OSVERSIONINFOA *)&vi)) {\r
+        memset(&vi, 0, sizeof(vi));\r
+        vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);\r
+        if (!GetVersionExA((OSVERSIONINFOA *)&vi))\r
             return;\r
             return;\r
-        }\r
     }\r
     }\r
+\r
     #pragma warning(pop)\r
 \r
     #pragma warning(pop)\r
 \r
-    if (Ver1.dwPlatformId == VER_PLATFORM_WIN32_NT)\r
-    {\r
-        if (Ver1.dwMajorVersion > 6 || (Ver1.dwMajorVersion == 6 && Ver1.dwMinorVersion >= 2))\r
-        {\r
-            // GetVersionEx() has problem on some Windows version \r
+    if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {\r
 \r
 \r
-            MajorEqual = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);\r
-            for (Major = Ver1.dwMajorVersion; Major <= 9; Major++) \r
-            {\r
-                memset(&Ver2, 0, sizeof(Ver2));\r
-                Ver2.dwOSVersionInfoSize = sizeof(Ver2);\r
-                Ver2.dwMajorVersion = Major;\r
+        if (vi.dwMajorVersion > 6 || (vi.dwMajorVersion == 6 && vi.dwMinorVersion >= 2)) {\r
+            // Starting with Windows 8.1 Preview, GetVersionEx() does no longer report the actual OS version\r
+            // See: http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx\r
+            // And starting with Windows 10 Preview 2, Windows enforces the use of the application/supportedOS\r
+            // manifest in order for VerSetConditionMask() to report the ACTUAL OS major and minor...\r
 \r
 \r
-                if (!VerifyVersionInfoA(&Ver2, VER_MAJORVERSION, MajorEqual))\r
-                {\r
+            major_equal = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);\r
+            for (major = vi.dwMajorVersion; major <= 9; major++) {\r
+                memset(&vi2, 0, sizeof(vi2));\r
+                vi2.dwOSVersionInfoSize = sizeof(vi2); vi2.dwMajorVersion = major;\r
+                if (!VerifyVersionInfoA(&vi2, VER_MAJORVERSION, major_equal))\r
                     continue;\r
                     continue;\r
+                if (vi.dwMajorVersion < major) {\r
+                    vi.dwMajorVersion = major; vi.dwMinorVersion = 0;\r
                 }\r
                 }\r
-                    \r
-                if (Ver1.dwMajorVersion < Major) \r
-                {\r
-                    Ver1.dwMajorVersion = Major;\r
-                    Ver1.dwMinorVersion = 0;\r
-                }\r
-\r
-                MinorEqual = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL);\r
-                for (Minor = Ver1.dwMinorVersion; Minor <= 9; Minor++) \r
-                {\r
-                    memset(&Ver2, 0, sizeof(Ver2)); \r
-                    \r
-                    Ver2.dwOSVersionInfoSize = sizeof(Ver2);\r
-                    Ver2.dwMinorVersion = Minor;\r
 \r
 \r
-                    if (!VerifyVersionInfoA(&Ver2, VER_MINORVERSION, MinorEqual))\r
-                    {\r
+                minor_equal = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL);\r
+                for (minor = vi.dwMinorVersion; minor <= 9; minor++) {\r
+                    memset(&vi2, 0, sizeof(vi2)); vi2.dwOSVersionInfoSize = sizeof(vi2);\r
+                    vi2.dwMinorVersion = minor;\r
+                    if (!VerifyVersionInfoA(&vi2, VER_MINORVERSION, minor_equal))\r
                         continue;\r
                         continue;\r
-                    }\r
-                        \r
-                    Ver1.dwMinorVersion = Minor;\r
+                    vi.dwMinorVersion = minor;\r
                     break;\r
                 }\r
 \r
                     break;\r
                 }\r
 \r
@@ -279,84 +481,81 @@ void DumpWindowsVersion(void)
             }\r
         }\r
 \r
             }\r
         }\r
 \r
-        if (Ver1.dwMajorVersion <= 0xF && Ver1.dwMinorVersion <= 0xF)\r
-        {\r
-            WsVer = (Ver1.wProductType <= VER_NT_WORKSTATION);\r
-            switch ((Ver1.dwMajorVersion << 4) | Ver2.dwMinorVersion)\r
-            {\r
-                case 0x51:\r
-                {\r
-                    Ver = "XP";\r
-                    break;\r
-                }\r
-                case 0x52:\r
-                {\r
-                    Ver = GetSystemMetrics(89) ? "Server 2003 R2" : "Server 2003";\r
-                    break;\r
-                }\r
-                case 0x60:\r
-                {\r
-                    Ver = WsVer ? "Vista" : "Server 2008";\r
-                    break;\r
-                }\r
-                case 0x61:\r
-                {\r
-                    Ver = WsVer ? "7" : "Server 2008 R2";\r
-                    break;\r
-                }\r
-                case 0x62:\r
-                {\r
-                    Ver = WsVer ? "8" : "Server 2012";\r
-                    break;\r
-                }\r
-                case 0x63:\r
-                {\r
-                    Ver = WsVer ? "8.1" : "Server 2012 R2";\r
-                    break;\r
-                }\r
-                case 0x64:\r
-                {\r
-                    Ver = WsVer ? "10 (Preview 1)" : "Server 10 (Preview 1)";\r
-                    break;\r
-                }\r
-                case 0xA0:\r
-                {\r
-                    Ver = WsVer ? "10" : ((Ver1.dwBuildNumber > 15000) ? "Server 2019" : "Server 2016");\r
-                    break;\r
-                }\r
-                default:\r
-                {\r
-                    Ver = "10 or later";\r
+        if (vi.dwMajorVersion <= 0xf && vi.dwMinorVersion <= 0xf) {\r
+            ws = (vi.wProductType <= VER_NT_WORKSTATION);\r
+            nWindowsVersion = vi.dwMajorVersion << 4 | vi.dwMinorVersion;\r
+            switch (nWindowsVersion) {\r
+            case WINDOWS_XP: w = "XP";\r
+                break;\r
+            case WINDOWS_2003: w = (ws ? "XP_64" : (!GetSystemMetrics(89) ? "Server 2003" : "Server 2003_R2"));\r
+                break;\r
+            case WINDOWS_VISTA: w = (ws ? "Vista" : "Server 2008");\r
+                break;\r
+            case WINDOWS_7: w = (ws ? "7" : "Server 2008_R2");\r
+                break;\r
+            case WINDOWS_8: w = (ws ? "8" : "Server 2012");\r
+                break;\r
+            case WINDOWS_8_1: w = (ws ? "8.1" : "Server 2012_R2");\r
+                break;\r
+            case WINDOWS_10_PREVIEW1: w = (ws ? "10 (Preview 1)" : "Server 10 (Preview 1)");\r
+                break;\r
+                // Starting with Windows 10 Preview 2, the major is the same as the public-facing version\r
+            case WINDOWS_10:\r
+                if (vi.dwBuildNumber < 20000) {\r
+                    w = (ws ? "10" : ((vi.dwBuildNumber < 17763) ? "Server 2016" : "Server 2019"));\r
                     break;\r
                 }\r
                     break;\r
                 }\r
+                nWindowsVersion = WINDOWS_11;\r
+                // Fall through\r
+            case WINDOWS_11: w = (ws ? "11" : "Server 2022");\r
+                break;\r
+            default:\r
+                if (nWindowsVersion < WINDOWS_XP)\r
+                    nWindowsVersion = WINDOWS_UNSUPPORTED;\r
+                else\r
+                    w = "12 or later";\r
+                break;\r
             }\r
         }\r
     }\r
 \r
             }\r
         }\r
     }\r
 \r
-    Bit = IsWow64() ? 64 : 32;\r
+    if (is_x64())\r
+        w64 = "64-bit";\r
 \r
 \r
-    if (Ver1.wServicePackMinor)\r
-    {\r
-        safe_sprintf(WinVer, "Windows %s SP%u.%u %d-bit", Ver, Ver1.wServicePackMajor, Ver1.wServicePackMinor, Bit);\r
-    }\r
-    else if (Ver1.wServicePackMajor)\r
-    {\r
-        safe_sprintf(WinVer, "Windows %s SP%u %d-bit", Ver, Ver1.wServicePackMajor, Bit);\r
-    }\r
-    else\r
-    {\r
-        safe_sprintf(WinVer, "Windows %s %d-bit", Ver, Bit);\r
-    }\r
+    GetProductInfo(vi.dwMajorVersion, vi.dwMinorVersion, vi.wServicePackMajor, vi.wServicePackMinor, &dwProductType);\r
+    vptr = WindowsVersionStr;\r
+    vlen = sizeof(WindowsVersionStr) - 1;\r
 \r
 \r
-    if (((Ver1.dwMajorVersion << 4) | Ver2.dwMinorVersion) >= 0x62)\r
-    {\r
-        Log("Windows Version : %s (Build %u)", WinVer, Ver1.dwBuildNumber);\r
-    }\r
+    if (!w)\r
+        sprintf_s(vptr, vlen, "%s %u.%u %s", (vi.dwPlatformId == VER_PLATFORM_WIN32_NT ? "NT" : "??"),\r
+        (unsigned)vi.dwMajorVersion, (unsigned)vi.dwMinorVersion, w64);\r
+    else if (vi.wServicePackMinor)\r
+        sprintf_s(vptr, vlen, "%s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, w64);\r
+    else if (vi.wServicePackMajor)\r
+        sprintf_s(vptr, vlen, "%s SP%u %s", w, vi.wServicePackMajor, w64);\r
     else\r
     else\r
-    {\r
-        Log("Windows Version : %s", WinVer);\r
+        sprintf_s(vptr, vlen, "%s%s%s, %s",\r
+        w, (dwProductType != PRODUCT_UNDEFINED) ? " " : "", GetEdition(dwProductType), w64);\r
+\r
+    // Add the build number (including UBR if available) for Windows 8.0 and later\r
+    nWindowsBuildNumber = vi.dwBuildNumber;\r
+    if (nWindowsVersion >= 0x62) {\r
+        int nUbr = ReadRegistryKey32(REGKEY_HKLM, "Software\\Microsoft\\Windows NT\\CurrentVersion\\UBR");\r
+        vptr = WindowsVersionStr + strlen(WindowsVersionStr);\r
+        vlen = sizeof(WindowsVersionStr) - strlen(WindowsVersionStr) - 1;\r
+        if (nUbr > 0)\r
+            sprintf_s(vptr, vlen, " (Build %d.%d)", nWindowsBuildNumber, nUbr);\r
+        else\r
+            sprintf_s(vptr, vlen, " (Build %d)", nWindowsBuildNumber);\r
     }\r
     }\r
+}\r
+\r
 \r
 \r
+\r
+void DumpWindowsVersion(void)\r
+{\r
+    GetWindowsVersion();\r
+    Log("Windows Version: <<Windows %s>>", WindowsVersionStr);\r
     return;\r
 }\r
 \r
     return;\r
 }\r
 \r
index 9eb257015f9813ec7ff654c192681b3f5763c35e..5ba9e71ae7f1adbb0fe1d8f72bc942462e4aa29b 100644 (file)
@@ -71,7 +71,7 @@ int ParseCmdLineOption(LPSTR lpCmdLine)
     return 0;\r
 }\r
 \r
     return 0;\r
 }\r
 \r
-static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UINT64 *Part2StartSector)\r
+static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UINT64 *Part2StartSector, UINT64 *GptPart2Attr)\r
 {\r
     int i;\r
     BOOL bRet;\r
 {\r
     int i;\r
     BOOL bRet;\r
@@ -149,7 +149,15 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UIN
 \r
                if (memcmp(pGpt->PartTbl[1].Name, L"VTOYEFI", 7 * 2))\r
                {\r
 \r
                if (memcmp(pGpt->PartTbl[1].Name, L"VTOYEFI", 7 * 2))\r
                {\r
-                       Log("Invalid ventoy efi part name");\r
+                       if (pGpt->PartTbl[1].Name[0])\r
+                       {\r
+                               Log("Invalid ventoy efi part name <%S>", pGpt->PartTbl[1].Name);\r
+                       }\r
+                       else\r
+                       {\r
+                               Log("Invalid ventoy efi part name <null>");\r
+                       }\r
+                       \r
                        return FALSE;\r
                }\r
 \r
                        return FALSE;\r
                }\r
 \r
@@ -170,6 +178,7 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UIN
             return FALSE;\r
         }\r
 \r
             return FALSE;\r
         }\r
 \r
+        *GptPart2Attr = pGpt->PartTbl[1].Attr;\r
                *Part2StartSector = pGpt->PartTbl[1].StartLBA;\r
 \r
         memcpy(pMBR, &(pGpt->MBR), sizeof(MBR_HEAD));\r
                *Part2StartSector = pGpt->PartTbl[1].StartLBA;\r
 \r
         memcpy(pMBR, &(pGpt->MBR), sizeof(MBR_HEAD));\r
@@ -225,6 +234,7 @@ static int FilterPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount)
     int Letter = 'A';\r
     int Id = 0;\r
     int LetterCount = 0;\r
     int Letter = 'A';\r
     int Id = 0;\r
     int LetterCount = 0;\r
+    UINT64 Part2GPTAttr = 0;\r
        UINT64 Part2StartSector = 0;\r
     PHY_DRIVE_INFO *CurDrive;\r
        MBR_HEAD MBR;\r
        UINT64 Part2StartSector = 0;\r
     PHY_DRIVE_INFO *CurDrive;\r
        MBR_HEAD MBR;\r
@@ -247,6 +257,7 @@ static int FilterPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount)
 \r
     for (i = 0; i < DriveCount; i++)\r
     {\r
 \r
     for (i = 0; i < DriveCount; i++)\r
     {\r
+        Part2GPTAttr = 0;\r
         CurDrive = pDriveList + i;\r
 \r
         CurDrive->Id = -1;\r
         CurDrive = pDriveList + i;\r
 \r
         CurDrive->Id = -1;\r
@@ -278,10 +289,11 @@ static int FilterPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount)
             }\r
         }\r
 \r
             }\r
         }\r
 \r
-               if (IsVentoyPhyDrive(CurDrive->PhyDrive, CurDrive->SizeInBytes, &MBR, &Part2StartSector))\r
+        if (IsVentoyPhyDrive(CurDrive->PhyDrive, CurDrive->SizeInBytes, &MBR, &Part2StartSector, &Part2GPTAttr))\r
         {\r
             memcpy(&(CurDrive->MBR), &MBR, sizeof(MBR));\r
             CurDrive->PartStyle = (MBR.PartTbl[0].FsFlag == 0xEE) ? 1 : 0;\r
         {\r
             memcpy(&(CurDrive->MBR), &MBR, sizeof(MBR));\r
             CurDrive->PartStyle = (MBR.PartTbl[0].FsFlag == 0xEE) ? 1 : 0;\r
+            CurDrive->Part2GPTAttr = Part2GPTAttr;\r
             GetVentoyVerInPhyDrive(CurDrive, Part2StartSector, CurDrive->VentoyVersion, sizeof(CurDrive->VentoyVersion), &(CurDrive->SecureBootSupport));\r
             Log("PhyDrive %d is Ventoy Disk ver:%s SecureBoot:%u", CurDrive->PhyDrive, CurDrive->VentoyVersion, CurDrive->SecureBootSupport);\r
 \r
             GetVentoyVerInPhyDrive(CurDrive, Part2StartSector, CurDrive->VentoyVersion, sizeof(CurDrive->VentoyVersion), &(CurDrive->SecureBootSupport));\r
             Log("PhyDrive %d is Ventoy Disk ver:%s SecureBoot:%u", CurDrive->PhyDrive, CurDrive->VentoyVersion, CurDrive->SecureBootSupport);\r
 \r
index 72c9a363a3996519de3dc1e784e0a28602c7fee4..dca9eb9fca96d411663ff857ea3997bdb4033188 100644 (file)
@@ -53,6 +53,7 @@
 }\r
 \r
 #define LASTERR     GetLastError()\r
 }\r
 \r
 #define LASTERR     GetLastError()\r
+#define RET_LASTERR (ret ? 0 : LASTERR)\r
 \r
 #pragma pack(1)\r
 typedef struct PART_TABLE\r
 \r
 #pragma pack(1)\r
 typedef struct PART_TABLE\r
@@ -153,12 +154,13 @@ typedef struct PHY_DRIVE_INFO
 \r
     BOOL SecureBootSupport;\r
     MBR_HEAD MBR;\r
 \r
     BOOL SecureBootSupport;\r
     MBR_HEAD MBR;\r
+    UINT64 Part2GPTAttr;\r
 }PHY_DRIVE_INFO;\r
 \r
 typedef enum PROGRESS_POINT\r
 {\r
     PT_START = 0,\r
 }PHY_DRIVE_INFO;\r
 \r
 typedef enum PROGRESS_POINT\r
 {\r
     PT_START = 0,\r
-    PT_LOCK_FOR_CLEAN,\r
+    PT_LOCK_FOR_CLEAN = 8,\r
     PT_DEL_ALL_PART,\r
     PT_LOCK_FOR_WRITE,\r
     PT_FORMAT_PART1,\r
     PT_DEL_ALL_PART,\r
     PT_LOCK_FOR_WRITE,\r
     PT_FORMAT_PART1,\r
@@ -185,6 +187,7 @@ extern HFONT g_language_normal_font;
 extern HFONT g_language_bold_font;\r
 extern int g_FilterUSB;\r
 \r
 extern HFONT g_language_bold_font;\r
 extern int g_FilterUSB;\r
 \r
+void TraceOut(const char *Fmt, ...);\r
 void Log(const char *Fmt, ...);\r
 BOOL IsPathExist(BOOL Dir, const char *Fmt, ...);\r
 void DumpWindowsVersion(void);\r
 void Log(const char *Fmt, ...);\r
 BOOL IsPathExist(BOOL Dir, const char *Fmt, ...);\r
 void DumpWindowsVersion(void);\r
@@ -207,11 +210,12 @@ int Ventoy2DiskInit(void);
 int Ventoy2DiskDestroy(void);\r
 PHY_DRIVE_INFO * GetPhyDriveInfoById(int Id);\r
 int ParseCmdLineOption(LPSTR lpCmdLine);\r
 int Ventoy2DiskDestroy(void);\r
 PHY_DRIVE_INFO * GetPhyDriveInfoById(int Id);\r
 int ParseCmdLineOption(LPSTR lpCmdLine);\r
-int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle);\r
-int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive);\r
+int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle, int TryId);\r
+int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId);\r
 int VentoyFillBackupGptHead(VTOY_GPT_INFO *pInfo, VTOY_GPT_HDR *pHead);\r
 int VentoyFillWholeGpt(UINT64 DiskSizeBytes, VTOY_GPT_INFO *pInfo);\r
 void SetProgressBarPos(int Pos);\r
 int VentoyFillBackupGptHead(VTOY_GPT_INFO *pInfo, VTOY_GPT_HDR *pHead);\r
 int VentoyFillWholeGpt(UINT64 DiskSizeBytes, VTOY_GPT_INFO *pInfo);\r
 void SetProgressBarPos(int Pos);\r
+int SaveBufToFile(const CHAR *FileName, const void *Buffer, int BufLen);\r
 int ReadWholeFileToBuf(const CHAR *FileName, int ExtLen, void **Bufer, int *BufLen);\r
 int INIT unxz(unsigned char *in, int in_size,\r
     int(*fill)(void *dest, unsigned int size),\r
 int ReadWholeFileToBuf(const CHAR *FileName, int ExtLen, void **Bufer, int *BufLen);\r
 int INIT unxz(unsigned char *in, int in_size,\r
     int(*fill)(void *dest, unsigned int size),\r
index 4cbe6228b7cac099f9e5a6415b2cc9d5330bc9f8..18c7d06bfafce5adaa85416cfc714e61434ab59e 100644 (file)
Binary files a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.rc and b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.rc differ
index e1276f2a9a520214b6ba2aebb136fce775eee970..8778b0f2c7bafa34021c1acf74ab85f8d1a9bd40 100644 (file)
@@ -92,6 +92,9 @@
   </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="crc32.c" />
   </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="crc32.c" />
+    <ClCompile Include="DiskService_diskpart.c" />
+    <ClCompile Include="DiskService_vds.c" />
+    <ClCompile Include="DiskService_wmsa.c" />
     <ClCompile Include="fat_io_lib\fat_access.c" />
     <ClCompile Include="fat_io_lib\fat_cache.c" />
     <ClCompile Include="fat_io_lib\fat_filelib.c" />
     <ClCompile Include="fat_io_lib\fat_access.c" />
     <ClCompile Include="fat_io_lib\fat_cache.c" />
     <ClCompile Include="fat_io_lib\fat_filelib.c" />
     <ClCompile Include="xz-embedded-20130513\linux\lib\decompress_unxz.c" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="xz-embedded-20130513\linux\lib\decompress_unxz.c" />
   </ItemGroup>
   <ItemGroup>
+    <ClInclude Include="DiskService.h" />
     <ClInclude Include="fat_io_lib\fat_access.h" />
     <ClInclude Include="fat_io_lib\fat_cache.h" />
     <ClInclude Include="fat_io_lib\fat_defs.h" />
     <ClInclude Include="fat_io_lib\fat_access.h" />
     <ClInclude Include="fat_io_lib\fat_cache.h" />
     <ClInclude Include="fat_io_lib\fat_defs.h" />
index 45f86ffe644eea4baaf0ef8f4e6f4021730f1f15..2be3bb285d475313c714be28660a629190a94458 100644 (file)
     <ClCompile Include="VentoyJson.c">
       <Filter>源文件</Filter>
     </ClCompile>
     <ClCompile Include="VentoyJson.c">
       <Filter>源文件</Filter>
     </ClCompile>
+    <ClCompile Include="DiskService_diskpart.c">
+      <Filter>源文件</Filter>
+    </ClCompile>
+    <ClCompile Include="DiskService_vds.c">
+      <Filter>源文件</Filter>
+    </ClCompile>
+    <ClCompile Include="DiskService_wmsa.c">
+      <Filter>源文件</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Ventoy2Disk.h">
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Ventoy2Disk.h">
     <ClInclude Include="VentoyJson.h">
       <Filter>头文件</Filter>
     </ClInclude>
     <ClInclude Include="VentoyJson.h">
       <Filter>头文件</Filter>
     </ClInclude>
+    <ClInclude Include="DiskService.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="Ventoy2Disk.rc">
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="Ventoy2Disk.rc">
index a5402338960afb4b4f4d4b1e4da87c446c95111f..a2c41acdd1804812247eedd5afecd1128cd2923e 100644 (file)
Binary files a/Ventoy2Disk/Ventoy2Disk/WinDialog.c and b/Ventoy2Disk/Ventoy2Disk/WinDialog.c differ
index 7f164998faccc04b86afabaa469dc37de89440af..5ca99e24fad4d45f8955031ffe661bd0ea2ce541 100644 (file)
Binary files a/Ventoy2Disk/Ventoy2Disk/resource.h and b/Ventoy2Disk/Ventoy2Disk/resource.h differ