mirror of
https://github.com/pbatard/rufus.git
synced 2025-05-25 04:04:26 -04:00
[vds] improve VDS calls
* Make sure that instantiated objects are released. * Factorize the instantiating of disk interfaces. * Allow the provision of an offset to delete a single partition. * Add a ListVdsVolumes() call (which is pointless since Microsoft *CRIPPLED* its VDS implementation).
This commit is contained in:
parent
8085a2846d
commit
3758f84b17
5 changed files with 277 additions and 108 deletions
350
src/drive.c
350
src/drive.c
|
@ -445,8 +445,8 @@ BOOL RefreshLayout(DWORD DriveIndex)
|
||||||
BOOL r = FALSE;
|
BOOL r = FALSE;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
wchar_t wPhysicalName[24];
|
wchar_t wPhysicalName[24];
|
||||||
IVdsServiceLoader *pLoader;
|
IVdsServiceLoader* pLoader = NULL;
|
||||||
IVdsService *pService;
|
IVdsService* pService = NULL;
|
||||||
IEnumVdsObject *pEnum;
|
IEnumVdsObject *pEnum;
|
||||||
|
|
||||||
CheckDriveIndex(DriveIndex);
|
CheckDriveIndex(DriveIndex);
|
||||||
|
@ -468,7 +468,6 @@ BOOL RefreshLayout(DWORD DriveIndex)
|
||||||
|
|
||||||
// Load the VDS Service
|
// Load the VDS Service
|
||||||
hr = IVdsServiceLoader_LoadService(pLoader, L"", &pService);
|
hr = IVdsServiceLoader_LoadService(pLoader, L"", &pService);
|
||||||
IVdsServiceLoader_Release(pLoader);
|
|
||||||
if (hr != S_OK) {
|
if (hr != S_OK) {
|
||||||
VDS_SET_ERROR(hr);
|
VDS_SET_ERROR(hr);
|
||||||
uprintf("Could not load VDS Service: %s", WindowsErrorString());
|
uprintf("Could not load VDS Service: %s", WindowsErrorString());
|
||||||
|
@ -516,25 +515,30 @@ BOOL RefreshLayout(DWORD DriveIndex)
|
||||||
}
|
}
|
||||||
r = TRUE;
|
r = TRUE;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
if (pService != NULL)
|
||||||
|
IVdsService_Release(pService);
|
||||||
|
if (pLoader != NULL)
|
||||||
|
IVdsServiceLoader_Release(pLoader);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Delete all the partitions from a disk, using VDS
|
* Generic call to instantiate a VDS Disk Interface. Mostly copied from:
|
||||||
* 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
|
* https://social.msdn.microsoft.com/Forums/vstudio/en-US/b90482ae-4e44-4b08-8731-81915030b32a/createpartition-using-vds-interface-throw-error-enointerface-dcom?forum=vcgeneral
|
||||||
|
* See also: https://docs.microsoft.com/en-us/windows/win32/vds/working-with-enumeration-objects
|
||||||
*/
|
*/
|
||||||
BOOL DeletePartitions(DWORD DriveIndex)
|
static BOOL GetVdsDiskInterface(DWORD DriveIndex, const IID* InterfaceIID, void** pInterfaceInstance, BOOL bSilent)
|
||||||
{
|
{
|
||||||
BOOL r = FALSE, bNeverFound = TRUE;
|
HRESULT hr = S_FALSE;
|
||||||
HRESULT hr;
|
|
||||||
ULONG ulFetched;
|
ULONG ulFetched;
|
||||||
wchar_t wPhysicalName[24];
|
wchar_t wPhysicalName[24];
|
||||||
IVdsServiceLoader *pLoader;
|
IVdsServiceLoader* pLoader;
|
||||||
IVdsService *pService;
|
IVdsService* pService;
|
||||||
IEnumVdsObject *pEnum;
|
IEnumVdsObject* pEnum;
|
||||||
IUnknown *pUnk;
|
IUnknown* pUnk;
|
||||||
|
|
||||||
|
*pInterfaceInstance = NULL;
|
||||||
CheckDriveIndex(DriveIndex);
|
CheckDriveIndex(DriveIndex);
|
||||||
wnsprintf(wPhysicalName, ARRAYSIZE(wPhysicalName), L"\\\\?\\PhysicalDrive%lu", DriveIndex);
|
wnsprintf(wPhysicalName, ARRAYSIZE(wPhysicalName), L"\\\\?\\PhysicalDrive%lu", DriveIndex);
|
||||||
|
|
||||||
|
@ -545,10 +549,10 @@ BOOL DeletePartitions(DWORD DriveIndex)
|
||||||
|
|
||||||
// Create a VDS Loader Instance
|
// Create a VDS Loader Instance
|
||||||
hr = CoCreateInstance(&CLSID_VdsLoader, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,
|
hr = CoCreateInstance(&CLSID_VdsLoader, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,
|
||||||
&IID_IVdsServiceLoader, (void **)&pLoader);
|
&IID_IVdsServiceLoader, (void**)&pLoader);
|
||||||
if (hr != S_OK) {
|
if (hr != S_OK) {
|
||||||
VDS_SET_ERROR(hr);
|
VDS_SET_ERROR(hr);
|
||||||
uprintf("Could not create VDS Loader Instance: %s", WindowsErrorString());
|
suprintf("Could not create VDS Loader Instance: %s", WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,7 +561,7 @@ BOOL DeletePartitions(DWORD DriveIndex)
|
||||||
IVdsServiceLoader_Release(pLoader);
|
IVdsServiceLoader_Release(pLoader);
|
||||||
if (hr != S_OK) {
|
if (hr != S_OK) {
|
||||||
VDS_SET_ERROR(hr);
|
VDS_SET_ERROR(hr);
|
||||||
uprintf("Could not load VDS Service: %s", WindowsErrorString());
|
suprintf("Could not load VDS Service: %s", WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,39 +569,40 @@ BOOL DeletePartitions(DWORD DriveIndex)
|
||||||
hr = IVdsService_WaitForServiceReady(pService);
|
hr = IVdsService_WaitForServiceReady(pService);
|
||||||
if (hr != S_OK) {
|
if (hr != S_OK) {
|
||||||
VDS_SET_ERROR(hr);
|
VDS_SET_ERROR(hr);
|
||||||
uprintf("VDS Service is not ready: %s", WindowsErrorString());
|
suprintf("VDS Service is not ready: %s", WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query the VDS Service Providers
|
// Query the VDS Service Providers
|
||||||
hr = IVdsService_QueryProviders(pService, VDS_QUERY_SOFTWARE_PROVIDERS, &pEnum);
|
hr = IVdsService_QueryProviders(pService, VDS_QUERY_SOFTWARE_PROVIDERS, &pEnum);
|
||||||
|
IVdsService_Release(pService);
|
||||||
if (hr != S_OK) {
|
if (hr != S_OK) {
|
||||||
VDS_SET_ERROR(hr);
|
VDS_SET_ERROR(hr);
|
||||||
uprintf("Could not query VDS Service Providers: %s", WindowsErrorString());
|
suprintf("Could not query VDS Service Providers: %s", WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (IEnumVdsObject_Next(pEnum, 1, &pUnk, &ulFetched) == S_OK) {
|
while (IEnumVdsObject_Next(pEnum, 1, &pUnk, &ulFetched) == S_OK) {
|
||||||
IVdsProvider *pProvider;
|
IVdsProvider* pProvider;
|
||||||
IVdsSwProvider *pSwProvider;
|
IVdsSwProvider* pSwProvider;
|
||||||
IEnumVdsObject *pEnumPack;
|
IEnumVdsObject* pEnumPack;
|
||||||
IUnknown *pPackUnk;
|
IUnknown* pPackUnk;
|
||||||
|
|
||||||
// Get VDS Provider
|
// Get VDS Provider
|
||||||
hr = IUnknown_QueryInterface(pUnk, &IID_IVdsProvider, (void **)&pProvider);
|
hr = IUnknown_QueryInterface(pUnk, &IID_IVdsProvider, (void**)&pProvider);
|
||||||
IUnknown_Release(pUnk);
|
IUnknown_Release(pUnk);
|
||||||
if (hr != S_OK) {
|
if (hr != S_OK) {
|
||||||
VDS_SET_ERROR(hr);
|
VDS_SET_ERROR(hr);
|
||||||
uprintf("Could not get VDS Provider: %s", WindowsErrorString());
|
suprintf("Could not get VDS Provider: %s", WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get VDS Software Provider
|
// Get VDS Software Provider
|
||||||
hr = IVdsSwProvider_QueryInterface(pProvider, &IID_IVdsSwProvider, (void **)&pSwProvider);
|
hr = IVdsSwProvider_QueryInterface(pProvider, &IID_IVdsSwProvider, (void**)&pSwProvider);
|
||||||
IVdsProvider_Release(pProvider);
|
IVdsProvider_Release(pProvider);
|
||||||
if (hr != S_OK) {
|
if (hr != S_OK) {
|
||||||
VDS_SET_ERROR(hr);
|
VDS_SET_ERROR(hr);
|
||||||
uprintf("Could not get VDS Software Provider: %s", WindowsErrorString());
|
suprintf("Could not get VDS Software Provider: %s", WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,132 +611,292 @@ BOOL DeletePartitions(DWORD DriveIndex)
|
||||||
IVdsSwProvider_Release(pSwProvider);
|
IVdsSwProvider_Release(pSwProvider);
|
||||||
if (hr != S_OK) {
|
if (hr != S_OK) {
|
||||||
VDS_SET_ERROR(hr);
|
VDS_SET_ERROR(hr);
|
||||||
uprintf("Could not get VDS Software Provider Packs: %s", WindowsErrorString());
|
suprintf("Could not get VDS Software Provider Packs: %s", WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enumerate Provider Packs
|
// Enumerate Provider Packs
|
||||||
while (IEnumVdsObject_Next(pEnumPack, 1, &pPackUnk, &ulFetched) == S_OK) {
|
while (IEnumVdsObject_Next(pEnumPack, 1, &pPackUnk, &ulFetched) == S_OK) {
|
||||||
IVdsPack *pPack;
|
IVdsPack* pPack;
|
||||||
IEnumVdsObject *pEnumDisk;
|
IEnumVdsObject* pEnumDisk;
|
||||||
IUnknown *pDiskUnk;
|
IUnknown* pDiskUnk;
|
||||||
|
|
||||||
hr = IUnknown_QueryInterface(pPackUnk, &IID_IVdsPack, (void **)&pPack);
|
hr = IUnknown_QueryInterface(pPackUnk, &IID_IVdsPack, (void**)&pPack);
|
||||||
IUnknown_Release(pPackUnk);
|
IUnknown_Release(pPackUnk);
|
||||||
if (hr != S_OK) {
|
if (hr != S_OK) {
|
||||||
VDS_SET_ERROR(hr);
|
VDS_SET_ERROR(hr);
|
||||||
uprintf("Could not query VDS Software Provider Pack: %s", WindowsErrorString());
|
suprintf("Could not query VDS Software Provider Pack: %s", WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the pack interface to access the disks
|
// Use the pack interface to access the disks
|
||||||
hr = IVdsPack_QueryDisks(pPack, &pEnumDisk);
|
hr = IVdsPack_QueryDisks(pPack, &pEnumDisk);
|
||||||
|
IVdsPack_Release(pPack);
|
||||||
if (hr != S_OK) {
|
if (hr != S_OK) {
|
||||||
VDS_SET_ERROR(hr);
|
VDS_SET_ERROR(hr);
|
||||||
uprintf("Could not query VDS disks: %s", WindowsErrorString());
|
suprintf("Could not query VDS disks: %s", WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// List disks
|
// List disks
|
||||||
while (IEnumVdsObject_Next(pEnumDisk, 1, &pDiskUnk, &ulFetched) == S_OK) {
|
while (IEnumVdsObject_Next(pEnumDisk, 1, &pDiskUnk, &ulFetched) == S_OK) {
|
||||||
VDS_DISK_PROP diskprop;
|
VDS_DISK_PROP prop;
|
||||||
VDS_PARTITION_PROP* prop_array;
|
IVdsDisk* pDisk;
|
||||||
LONG i, prop_array_size;
|
|
||||||
IVdsDisk *pDisk;
|
|
||||||
IVdsAdvancedDisk *pAdvancedDisk;
|
|
||||||
|
|
||||||
// Get the disk interface.
|
// Get the disk interface.
|
||||||
hr = IUnknown_QueryInterface(pDiskUnk, &IID_IVdsDisk, (void **)&pDisk);
|
hr = IUnknown_QueryInterface(pDiskUnk, &IID_IVdsDisk, (void**)&pDisk);
|
||||||
|
IUnknown_Release(pDiskUnk);
|
||||||
if (hr != S_OK) {
|
if (hr != S_OK) {
|
||||||
VDS_SET_ERROR(hr);
|
VDS_SET_ERROR(hr);
|
||||||
uprintf("Could not query VDS Disk Interface: %s", WindowsErrorString());
|
suprintf("Could not query VDS Disk Interface: %s", WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the disk properties
|
// Get the disk properties
|
||||||
hr = IVdsDisk_GetProperties(pDisk, &diskprop);
|
hr = IVdsDisk_GetProperties(pDisk, &prop);
|
||||||
if (hr != S_OK) {
|
if ((hr != S_OK) && (hr != VDS_S_PROPERTIES_INCOMPLETE)) {
|
||||||
|
IVdsDisk_Release(pDisk);
|
||||||
VDS_SET_ERROR(hr);
|
VDS_SET_ERROR(hr);
|
||||||
uprintf("Could not query VDS Disk Properties: %s", WindowsErrorString());
|
suprintf("Could not query VDS Disk Properties: %s", WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Isolate the disk we want
|
// Check if we are on the target disk
|
||||||
if (_wcsicmp(wPhysicalName, diskprop.pwszName) != 0) {
|
hr = (HRESULT)_wcsicmp(wPhysicalName, prop.pwszName);
|
||||||
|
CoTaskMemFree(prop.pwszName);
|
||||||
|
if (hr != S_OK) {
|
||||||
IVdsDisk_Release(pDisk);
|
IVdsDisk_Release(pDisk);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bNeverFound = FALSE;
|
|
||||||
|
|
||||||
// Instantiate the AdvanceDisk interface for our disk.
|
// Instantiate the requested VDS disk interface
|
||||||
hr = IVdsDisk_QueryInterface(pDisk, &IID_IVdsAdvancedDisk, (void **)&pAdvancedDisk);
|
hr = IVdsDisk_QueryInterface(pDisk, InterfaceIID, pInterfaceInstance);
|
||||||
IVdsDisk_Release(pDisk);
|
IVdsDisk_Release(pDisk);
|
||||||
if (hr != S_OK) {
|
if (hr != S_OK) {
|
||||||
VDS_SET_ERROR(hr);
|
VDS_SET_ERROR(hr);
|
||||||
uprintf("Could not access VDS Advanced Disk interface: %s", WindowsErrorString());
|
suprintf("Could not access the requested Disk interface: %s", WindowsErrorString());
|
||||||
|
}
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
IEnumVdsObject_Release(pEnumDisk);
|
||||||
|
}
|
||||||
|
IEnumVdsObject_Release(pEnumPack);
|
||||||
|
}
|
||||||
|
IEnumVdsObject_Release(pEnum);
|
||||||
|
|
||||||
|
out:
|
||||||
|
return (hr == S_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Delete one partition at offset PartitionOffset, or all partitions if the offset is 0.
|
||||||
|
*/
|
||||||
|
BOOL DeletePartition(DWORD DriveIndex, ULONGLONG PartitionOffset, BOOL bSilent)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_FALSE;
|
||||||
|
VDS_PARTITION_PROP* prop_array;
|
||||||
|
LONG i, prop_array_size;
|
||||||
|
IVdsAdvancedDisk *pAdvancedDisk;
|
||||||
|
|
||||||
|
if (!GetVdsDiskInterface(DriveIndex, &IID_IVdsAdvancedDisk, (void**)&pAdvancedDisk, bSilent))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
// Query the partition data, so we can get the start offset, which we need for deletion
|
// 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);
|
hr = IVdsAdvancedDisk_QueryPartitions(pAdvancedDisk, &prop_array, &prop_array_size);
|
||||||
if (hr == S_OK) {
|
if (hr == S_OK) {
|
||||||
uprintf("Deleting ALL partition(s) from disk '%S':", diskprop.pwszName);
|
suprintf("Deleting partition%s:", (PartitionOffset == 0) ? "s" : "");
|
||||||
// Now go through each partition
|
// Now go through each partition
|
||||||
for (i = 0; i < prop_array_size; i++) {
|
for (i = 0; i < prop_array_size; i++) {
|
||||||
uprintf("● Partition %d (offset: %lld, size: %s)", prop_array[i].ulPartitionNumber,
|
if ((PartitionOffset != 0) && (prop_array[i].ullOffset != PartitionOffset))
|
||||||
|
continue;
|
||||||
|
suprintf("● Partition %d (offset: %lld, size: %s)", prop_array[i].ulPartitionNumber,
|
||||||
prop_array[i].ullOffset, SizeToHumanReadable(prop_array[i].ullSize, FALSE, FALSE));
|
prop_array[i].ullOffset, SizeToHumanReadable(prop_array[i].ullSize, FALSE, FALSE));
|
||||||
hr = IVdsAdvancedDisk_DeletePartition(pAdvancedDisk, prop_array[i].ullOffset, TRUE, TRUE);
|
hr = IVdsAdvancedDisk_DeletePartition(pAdvancedDisk, prop_array[i].ullOffset, TRUE, TRUE);
|
||||||
if (hr != S_OK) {
|
if (hr != S_OK) {
|
||||||
r = FALSE;
|
|
||||||
VDS_SET_ERROR(hr);
|
VDS_SET_ERROR(hr);
|
||||||
uprintf("Could not delete partitions: %s", WindowsErrorString());
|
suprintf("Could not delete partition: %s", WindowsErrorString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r = TRUE;
|
|
||||||
} else {
|
} else {
|
||||||
uprintf("No partition to delete on disk '%S'", diskprop.pwszName);
|
suprintf("No partition to delete on disk");
|
||||||
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;
|
hr = S_OK;
|
||||||
}
|
}
|
||||||
Sleep(500);
|
CoTaskMemFree(prop_array);
|
||||||
}
|
|
||||||
if (hr != S_OK) {
|
|
||||||
VDS_SET_ERROR(hr);
|
|
||||||
uprintf("Could not clean disk: %s", WindowsErrorString());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
IVdsAdvancedDisk_Release(pAdvancedDisk);
|
IVdsAdvancedDisk_Release(pAdvancedDisk);
|
||||||
goto out;
|
return (hr == S_OK);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (bNeverFound)
|
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_PATH_NOT_FOUND;
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Count on Microsoft for *COMPLETELY CRIPPLING* an API when alledgedly upgrading it...
|
||||||
|
* As illustrated when you do so with diskpart (which uses VDS behind the scenes), VDS
|
||||||
|
* simply *DOES NOT* list all the volumes that the system can see, especially compared
|
||||||
|
* to what mountvol (which uses FindFirstVolume()/FindNextVolume()) and other APIs do.
|
||||||
|
* Also for reference, if you want to list volumes through WMI in PowerShell:
|
||||||
|
* Get-WmiObject win32_volume | Format-Table -Property DeviceID,Name,Label,Capacity
|
||||||
|
*/
|
||||||
|
BOOL ListVdsVolumes(BOOL bSilent)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_FALSE;
|
||||||
|
ULONG ulFetched;
|
||||||
|
IVdsServiceLoader* pLoader;
|
||||||
|
IVdsService* pService;
|
||||||
|
IEnumVdsObject* pEnum;
|
||||||
|
IUnknown* pUnk;
|
||||||
|
|
||||||
|
// Initialize COM
|
||||||
|
IGNORE_RETVAL(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED));
|
||||||
|
IGNORE_RETVAL(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);
|
||||||
|
suprintf("Could not create VDS Loader Instance: %s", WindowsErrorString());
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the VDS Service
|
||||||
|
hr = IVdsServiceLoader_LoadService(pLoader, L"", &pService);
|
||||||
|
IVdsServiceLoader_Release(pLoader);
|
||||||
|
if (hr != S_OK) {
|
||||||
|
VDS_SET_ERROR(hr);
|
||||||
|
suprintf("Could not load VDS Service: %s", WindowsErrorString());
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for the Service to become ready if needed
|
||||||
|
hr = IVdsService_WaitForServiceReady(pService);
|
||||||
|
if (hr != S_OK) {
|
||||||
|
VDS_SET_ERROR(hr);
|
||||||
|
suprintf("VDS Service is not ready: %s", WindowsErrorString());
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query the VDS Service Providers
|
||||||
|
hr = IVdsService_QueryProviders(pService, VDS_QUERY_SOFTWARE_PROVIDERS, &pEnum);
|
||||||
|
IVdsService_Release(pService);
|
||||||
|
if (hr != S_OK) {
|
||||||
|
VDS_SET_ERROR(hr);
|
||||||
|
suprintf("Could not query VDS Service Providers: %s", WindowsErrorString());
|
||||||
|
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);
|
||||||
|
suprintf("Could not get VDS Provider: %s", WindowsErrorString());
|
||||||
|
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);
|
||||||
|
suprintf("Could not get VDS Software Provider: %s", WindowsErrorString());
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get VDS Software Provider Packs
|
||||||
|
hr = IVdsSwProvider_QueryPacks(pSwProvider, &pEnumPack);
|
||||||
|
IVdsSwProvider_Release(pSwProvider);
|
||||||
|
if (hr != S_OK) {
|
||||||
|
VDS_SET_ERROR(hr);
|
||||||
|
suprintf("Could not get VDS Software Provider Packs: %s", WindowsErrorString());
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enumerate Provider Packs
|
||||||
|
while (IEnumVdsObject_Next(pEnumPack, 1, &pPackUnk, &ulFetched) == S_OK) {
|
||||||
|
IVdsPack* pPack;
|
||||||
|
IEnumVdsObject* pEnumVolume;
|
||||||
|
IUnknown* pVolumeUnk;
|
||||||
|
|
||||||
|
hr = IUnknown_QueryInterface(pPackUnk, &IID_IVdsPack, (void**)&pPack);
|
||||||
|
IUnknown_Release(pPackUnk);
|
||||||
|
if (hr != S_OK) {
|
||||||
|
VDS_SET_ERROR(hr);
|
||||||
|
suprintf("Could not query VDS Software Provider Pack: %s", WindowsErrorString());
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the pack interface to access the disks
|
||||||
|
hr = IVdsPack_QueryVolumes(pPack, &pEnumVolume);
|
||||||
|
if (hr != S_OK) {
|
||||||
|
VDS_SET_ERROR(hr);
|
||||||
|
suprintf("Could not query VDS volumes: %s", WindowsErrorString());
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// List volumes
|
||||||
|
while (IEnumVdsObject_Next(pEnumVolume, 1, &pVolumeUnk, &ulFetched) == S_OK) {
|
||||||
|
IVdsVolume* pVolume;
|
||||||
|
IVdsVolumeMF3* pVolumeMF3;
|
||||||
|
VDS_VOLUME_PROP prop;
|
||||||
|
LPWSTR* wszPathArray;
|
||||||
|
ULONG i, ulNumberOfPaths;
|
||||||
|
|
||||||
|
// Get the volume interface.
|
||||||
|
hr = IUnknown_QueryInterface(pVolumeUnk, &IID_IVdsVolume, (void**)&pVolume);
|
||||||
|
if (hr != S_OK) {
|
||||||
|
VDS_SET_ERROR(hr);
|
||||||
|
suprintf("Could not query VDS Volume Interface: %s", WindowsErrorString());
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the volume properties
|
||||||
|
hr = IVdsVolume_GetProperties(pVolume, &prop);
|
||||||
|
if ((hr != S_OK) && (hr != VDS_S_PROPERTIES_INCOMPLETE)) {
|
||||||
|
VDS_SET_ERROR(hr);
|
||||||
|
suprintf("Could not query VDS Volume Properties: %s", WindowsErrorString());
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
uprintf("FOUND VOLUME: '%S'", prop.pwszName);
|
||||||
|
CoTaskMemFree(prop.pwszName);
|
||||||
|
IVdsVolume_Release(pVolume);
|
||||||
|
|
||||||
|
// Get the volume MF3 interface.
|
||||||
|
hr = IUnknown_QueryInterface(pVolumeUnk, &IID_IVdsVolumeMF3, (void**)&pVolumeMF3);
|
||||||
|
if (hr != S_OK) {
|
||||||
|
VDS_SET_ERROR(hr);
|
||||||
|
suprintf("Could not query VDS VolumeMF3 Interface: %s", WindowsErrorString());
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the volume properties
|
||||||
|
hr = IVdsVolumeMF3_QueryVolumeGuidPathnames(pVolumeMF3, &wszPathArray, &ulNumberOfPaths);
|
||||||
|
if ((hr != S_OK) && (hr != VDS_S_PROPERTIES_INCOMPLETE)) {
|
||||||
|
VDS_SET_ERROR(hr);
|
||||||
|
suprintf("Could not query VDS VolumeMF3 GUID PathNames: %s", WindowsErrorString());
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ulNumberOfPaths; i++)
|
||||||
|
uprintf(" VOL GUID: '%S'", wszPathArray[i]);
|
||||||
|
CoTaskMemFree(wszPathArray);
|
||||||
|
IVdsVolume_Release(pVolumeMF3);
|
||||||
|
IUnknown_Release(pVolumeUnk);
|
||||||
|
}
|
||||||
|
IEnumVdsObject_Release(pEnumVolume);
|
||||||
|
}
|
||||||
|
IEnumVdsObject_Release(pEnumPack);
|
||||||
|
}
|
||||||
|
IEnumVdsObject_Release(pEnum);
|
||||||
|
|
||||||
|
out:
|
||||||
|
return (hr == S_OK);
|
||||||
|
}
|
||||||
|
|
||||||
/* Wait for a logical drive to reappear - Used when a drive has just been repartitioned */
|
/* Wait for a logical drive to reappear - Used when a drive has just been repartitioned */
|
||||||
BOOL WaitForLogical(DWORD DriveIndex, uint64_t PartitionOffset)
|
BOOL WaitForLogical(DWORD DriveIndex, uint64_t PartitionOffset)
|
||||||
|
@ -1695,7 +1860,6 @@ BOOL RemountVolume(char* drive_name)
|
||||||
* properly reset Windows's cached view of a drive partitioning short of cycling the USB port
|
* properly reset Windows's cached view of a drive partitioning short of cycling the USB port
|
||||||
* (especially IOCTL_DISK_UPDATE_PROPERTIES is *USELESS*), and therefore the OS will try to
|
* (especially IOCTL_DISK_UPDATE_PROPERTIES is *USELESS*), and therefore the OS will try to
|
||||||
* read the file system data at an old location, even if the partition has just been deleted.
|
* read the file system data at an old location, even if the partition has just been deleted.
|
||||||
* TODO: We should do something like this in DeletePartitions() too.
|
|
||||||
*/
|
*/
|
||||||
static BOOL ClearPartition(HANDLE hDrive, LARGE_INTEGER offset, DWORD size)
|
static BOOL ClearPartition(HANDLE hDrive, LARGE_INTEGER offset, DWORD size)
|
||||||
{
|
{
|
||||||
|
|
|
@ -298,11 +298,13 @@ interface IVdsAsync {
|
||||||
#define IVdsService_CleanupObsoleteMountPoints(This) ((This)->lpVtbl->CleanupObsoleteMountPoints(This))
|
#define IVdsService_CleanupObsoleteMountPoints(This) ((This)->lpVtbl->CleanupObsoleteMountPoints(This))
|
||||||
#define IVdsService_Refresh(This) ((This)->lpVtbl->Refresh(This))
|
#define IVdsService_Refresh(This) ((This)->lpVtbl->Refresh(This))
|
||||||
#define IVdsService_Reenumerate(This) ((This)->lpVtbl->Reenumerate(This))
|
#define IVdsService_Reenumerate(This) ((This)->lpVtbl->Reenumerate(This))
|
||||||
|
#define IVdsService_Release(This) (This)->lpVtbl->Release(This)
|
||||||
#define IVdsSwProvider_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
|
#define IVdsSwProvider_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
|
||||||
#define IVdsProvider_Release(This) (This)->lpVtbl->Release(This)
|
#define IVdsProvider_Release(This) (This)->lpVtbl->Release(This)
|
||||||
#define IVdsSwProvider_QueryPacks(This, ppEnum) (This)->lpVtbl->QueryPacks(This, ppEnum)
|
#define IVdsSwProvider_QueryPacks(This, ppEnum) (This)->lpVtbl->QueryPacks(This, ppEnum)
|
||||||
#define IVdsSwProvider_Release(This) (This)->lpVtbl->Release(This)
|
#define IVdsSwProvider_Release(This) (This)->lpVtbl->Release(This)
|
||||||
#define IVdsPack_QueryDisks(This, ppEnum) (This)->lpVtbl->QueryDisks(This, ppEnum)
|
#define IVdsPack_QueryDisks(This, ppEnum) (This)->lpVtbl->QueryDisks(This, ppEnum)
|
||||||
|
#define IVdsPack_Release(This) (This)->lpVtbl->Release(This)
|
||||||
#define IVdsDisk_GetProperties(This, pDiskProperties) (This)->lpVtbl->GetProperties(This, pDiskProperties)
|
#define IVdsDisk_GetProperties(This, pDiskProperties) (This)->lpVtbl->GetProperties(This, pDiskProperties)
|
||||||
#define IVdsDisk_Release(This) (This)->lpVtbl->Release(This)
|
#define IVdsDisk_Release(This) (This)->lpVtbl->Release(This)
|
||||||
#define IVdsDisk_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
|
#define IVdsDisk_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
|
||||||
|
@ -311,6 +313,7 @@ interface IVdsAsync {
|
||||||
#define IVdsAdvancedDisk_Clean(This, bForce, bForceOEM, bFullClean, ppAsync) (This)->lpVtbl->Clean(This, bForce, bForceOEM, bFullClean, 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 IVdsAdvancedDisk_Release(This) (This)->lpVtbl->Release(This)
|
||||||
#define IEnumVdsObject_Next(This, celt, ppObjectArray, pcFetched) (This)->lpVtbl->Next(This, celt, ppObjectArray, pcFetched)
|
#define IEnumVdsObject_Next(This, celt, ppObjectArray, pcFetched) (This)->lpVtbl->Next(This, celt, ppObjectArray, pcFetched)
|
||||||
|
#define IEnumVdsObject_Release(This) (This)->lpVtbl->Release(This)
|
||||||
#define IVdsPack_QueryVolumes(This, ppEnum) (This)->lpVtbl->QueryVolumes(This, ppEnum)
|
#define IVdsPack_QueryVolumes(This, ppEnum) (This)->lpVtbl->QueryVolumes(This, ppEnum)
|
||||||
#define IVdsVolume_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
|
#define IVdsVolume_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
|
||||||
#define IVdsVolume_Release(This) (This)->lpVtbl->Release(This)
|
#define IVdsVolume_Release(This) (This)->lpVtbl->Release(This)
|
||||||
|
@ -368,7 +371,8 @@ extern uint64_t partition_offset[PI_MAX];
|
||||||
BOOL SetAutoMount(BOOL enable);
|
BOOL SetAutoMount(BOOL enable);
|
||||||
BOOL GetAutoMount(BOOL* enabled);
|
BOOL GetAutoMount(BOOL* enabled);
|
||||||
char* GetPhysicalName(DWORD DriveIndex);
|
char* GetPhysicalName(DWORD DriveIndex);
|
||||||
BOOL DeletePartitions(DWORD DriveIndex);
|
BOOL DeletePartition(DWORD DriveIndex, ULONGLONG PartitionOffset, BOOL bSilent);
|
||||||
|
BOOL ListVdsVolumes(BOOL bSilent);
|
||||||
HANDLE GetPhysicalHandle(DWORD DriveIndex, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare);
|
HANDLE GetPhysicalHandle(DWORD DriveIndex, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare);
|
||||||
char* GetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrailingBackslash, BOOL bSilent);
|
char* GetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrailingBackslash, BOOL bSilent);
|
||||||
char* AltGetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrailingBackslash, BOOL bSilent);
|
char* AltGetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrailingBackslash, BOOL bSilent);
|
||||||
|
|
|
@ -1747,7 +1747,7 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
// for VDS to be able to delete the partitions that reside on it...
|
// for VDS to be able to delete the partitions that reside on it...
|
||||||
safe_unlockclose(hPhysicalDrive);
|
safe_unlockclose(hPhysicalDrive);
|
||||||
PrintInfo(0, MSG_239, lmprintf(MSG_307));
|
PrintInfo(0, MSG_239, lmprintf(MSG_307));
|
||||||
if (!DeletePartitions(DriveIndex)) {
|
if (!DeletePartition(DriveIndex, 0, FALSE)) {
|
||||||
SetLastError(FormatStatus);
|
SetLastError(FormatStatus);
|
||||||
uprintf("Notice: Could not delete partitions: %s", WindowsErrorString());
|
uprintf("Notice: Could not delete partitions: %s", WindowsErrorString());
|
||||||
FormatStatus = 0;
|
FormatStatus = 0;
|
||||||
|
|
|
@ -3502,6 +3502,7 @@ relaunch:
|
||||||
&& (msg.wParam == 'T')) {
|
&& (msg.wParam == 'T')) {
|
||||||
//extern int TestChecksum(void);
|
//extern int TestChecksum(void);
|
||||||
//TestChecksum();
|
//TestChecksum();
|
||||||
|
ListVdsVolumes(FALSE);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
10
src/rufus.rc
10
src/rufus.rc
|
@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||||
IDD_DIALOG DIALOGEX 12, 12, 232, 326
|
IDD_DIALOG DIALOGEX 12, 12, 232, 326
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
EXSTYLE WS_EX_ACCEPTFILES
|
EXSTYLE WS_EX_ACCEPTFILES
|
||||||
CAPTION "Rufus 3.12.1712"
|
CAPTION "Rufus 3.12.1713"
|
||||||
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
|
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
|
||||||
BEGIN
|
BEGIN
|
||||||
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
|
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
|
||||||
|
@ -395,8 +395,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 3,12,1712,0
|
FILEVERSION 3,12,1713,0
|
||||||
PRODUCTVERSION 3,12,1712,0
|
PRODUCTVERSION 3,12,1713,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -414,13 +414,13 @@ BEGIN
|
||||||
VALUE "Comments", "https://rufus.ie"
|
VALUE "Comments", "https://rufus.ie"
|
||||||
VALUE "CompanyName", "Akeo Consulting"
|
VALUE "CompanyName", "Akeo Consulting"
|
||||||
VALUE "FileDescription", "Rufus"
|
VALUE "FileDescription", "Rufus"
|
||||||
VALUE "FileVersion", "3.12.1712"
|
VALUE "FileVersion", "3.12.1713"
|
||||||
VALUE "InternalName", "Rufus"
|
VALUE "InternalName", "Rufus"
|
||||||
VALUE "LegalCopyright", "© 2011-2020 Pete Batard (GPL v3)"
|
VALUE "LegalCopyright", "© 2011-2020 Pete Batard (GPL v3)"
|
||||||
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
|
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
|
||||||
VALUE "OriginalFilename", "rufus-3.12.exe"
|
VALUE "OriginalFilename", "rufus-3.12.exe"
|
||||||
VALUE "ProductName", "Rufus"
|
VALUE "ProductName", "Rufus"
|
||||||
VALUE "ProductVersion", "3.12.1712"
|
VALUE "ProductVersion", "3.12.1713"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue