mirror of https://github.com/ventoy/Ventoy
Improve the success rate of Ventoy2Disk.exe installation and upgrade
parent
cd9aa16b20
commit
1473be0e4c
Binary file not shown.
@ -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
|
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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"
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue