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