#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
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
}
--- /dev/null
+/******************************************************************************\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
--- /dev/null
+/******************************************************************************\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
--- /dev/null
+/******************************************************************************\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, ¶);\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(¶, 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, ¶, &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
--- /dev/null
+/******************************************************************************\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
#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
-\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
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
+ BYTE *CheckBuf = NULL;\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
+ free(CheckBuf);\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
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
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
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
- 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
End:\r
\r
if (data) free(data);\r
+ if (CheckBuf)free(CheckBuf);\r
\r
if (partwrite)\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
\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
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
\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
return rc;\r
}\r
\r
-int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)\r
+\r
+int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId)\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
- 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
- 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
- PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN);\r
+ PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN);\r
\r
- Log("Lock disk for umount ............................ ");\r
+ Log("Lock disk for umount ............................ ");\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
- 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
- memset(pGptInfo, 0, sizeof(VTOY_GPT_INFO));\r
+ memset(pGptInfo, 0, sizeof(VTOY_GPT_INFO));\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
- //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
- 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
- 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
- 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
- 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
- //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
- GetLettersBelongPhyDrive(pPhyDrive->PhyDrive, DriveLetters, sizeof(DriveLetters));\r
+ GetLettersBelongPhyDrive(pPhyDrive->PhyDrive, DriveLetters, sizeof(DriveLetters));\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
- // 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
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
- 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
- rc = 1;\r
- goto End;\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
- 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
goto End;\r
}\r
\r
-\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
+ Log("Try write failed, now delete partition 2 for MBR...");\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
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
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
/******************************************************************************\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
#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
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
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
- 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
- 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
- }\r
}\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
- 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
- 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
+ if (vi.dwMajorVersion < major) {\r
+ vi.dwMajorVersion = major; vi.dwMinorVersion = 0;\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
- 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
- }\r
- \r
- Ver1.dwMinorVersion = Minor;\r
+ vi.dwMinorVersion = minor;\r
break;\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
+ 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
- Bit = IsWow64() ? 64 : 32;\r
+ if (is_x64())\r
+ w64 = "64-bit";\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
- 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
- {\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
+void DumpWindowsVersion(void)\r
+{\r
+ GetWindowsVersion();\r
+ Log("Windows Version: <<Windows %s>>", WindowsVersionStr);\r
return;\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
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
+ *GptPart2Attr = pGpt->PartTbl[1].Attr;\r
*Part2StartSector = pGpt->PartTbl[1].StartLBA;\r
\r
memcpy(pMBR, &(pGpt->MBR), sizeof(MBR_HEAD));\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
\r
for (i = 0; i < DriveCount; i++)\r
{\r
+ Part2GPTAttr = 0;\r
CurDrive = pDriveList + i;\r
\r
CurDrive->Id = -1;\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
+ 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
}\r
\r
#define LASTERR GetLastError()\r
+#define RET_LASTERR (ret ? 0 : LASTERR)\r
\r
#pragma pack(1)\r
typedef struct PART_TABLE\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
- 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
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
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 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
</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="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" />
<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">
<ClInclude Include="VentoyJson.h">
<Filter>头文件</Filter>
</ClInclude>
+ <ClInclude Include="DiskService.h">
+ <Filter>头文件</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Ventoy2Disk.rc">