mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[core] invoke VDS to delete all partitions before format/write
This commit is contained in:
		
							parent
							
								
									7745edbb92
								
							
						
					
					
						commit
						c0526b3e8b
					
				
					 6 changed files with 397 additions and 17 deletions
				
			
		|  | @ -2,6 +2,7 @@ o Version 3.4 (2018.12.??) | |||
|     Set the default image selection directory to Downloads\ instead of My Documents\ | ||||
|     Add ARM/ARM64 automatic update support | ||||
|     Improve UEFI:NTFS compatibility | ||||
|     Improve access issues by using VDS to delete all partitions | ||||
|     Update the .appx to include all architectures as well as request elevation | ||||
|     Fix broken detection of some EFI based images | ||||
|     Fix broken update check due to new server | ||||
|  |  | |||
							
								
								
									
										226
									
								
								src/drive.c
									
										
									
									
									
								
							
							
						
						
									
										226
									
								
								src/drive.c
									
										
									
									
									
								
							|  | @ -26,6 +26,10 @@ | |||
| #include <string.h> | ||||
| #include <ctype.h> | ||||
| #include <assert.h> | ||||
| #if !defined(__MINGW32__) | ||||
| #include <initguid.h> | ||||
| #endif | ||||
| #include <vds.h> | ||||
| 
 | ||||
| #include "rufus.h" | ||||
| #include "missing.h" | ||||
|  | @ -54,6 +58,16 @@ const GUID PARTITION_SYSTEM_GUID = | |||
| 	{ 0xc12a7328L, 0xf81f, 0x11d2, {0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b} }; | ||||
| #endif | ||||
| 
 | ||||
| #if defined(__MINGW32__) | ||||
| const IID CLSID_VdsLoader = { 0x9c38ed61, 0xd565, 0x4728, { 0xae, 0xee, 0xc8, 0x09, 0x52, 0xf0, 0xec, 0xde } }; | ||||
| const IID IID_IVdsServiceLoader = { 0xe0393303, 0x90d4, 0x4a97, { 0xab, 0x71, 0xe9, 0xb6, 0x71, 0xee, 0x27, 0x29 } }; | ||||
| const IID IID_IVdsProvider = { 0x10c5e575, 0x7984, 0x4e81, { 0xa5, 0x6b, 0x43, 0x1f, 0x5f, 0x92, 0xae, 0x42 } }; | ||||
| const IID IID_IVdsSwProvider = { 0x9aa58360, 0xce33, 0x4f92, { 0xb6, 0x58, 0xed, 0x24, 0xb1, 0x44, 0x25, 0xb8 } }; | ||||
| const IID IID_IVdsPack = { 0x3b69d7f5, 0x9d94, 0x4648, { 0x91, 0xca, 0x79, 0x93, 0x9b, 0xa2, 0x63, 0xbf } }; | ||||
| const IID IID_IVdsDisk = { 0x07e5c822, 0xf00c, 0x47a1, { 0x8f, 0xce, 0xb2, 0x44, 0xda, 0x56, 0xfd, 0x06 } }; | ||||
| const IID IID_IVdsAdvancedDisk = { 0x6e6f6b40, 0x977c, 0x4069, { 0xbd, 0xdd, 0xac, 0x71, 0x00, 0x59, 0xf8, 0xc0 } }; | ||||
| #endif | ||||
| 
 | ||||
| PF_TYPE_DECL(NTAPI, NTSTATUS, NtQueryVolumeInformationFile, (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FS_INFORMATION_CLASS)); | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -112,6 +126,7 @@ BOOL GetAutoMount(BOOL* enabled) | |||
|  * the specific range [DRIVE_INDEX_MIN; DRIVE_INDEX_MAX]. | ||||
|  */ | ||||
| #define CheckDriveIndex(DriveIndex) do {                                            \ | ||||
| 	if ((int)DriveIndex < 0) goto out;                                              \ | ||||
| 	assert((DriveIndex >= DRIVE_INDEX_MIN) && (DriveIndex <= DRIVE_INDEX_MAX));     \ | ||||
| 	if ((DriveIndex < DRIVE_INDEX_MIN) || (DriveIndex > DRIVE_INDEX_MAX)) goto out; \ | ||||
| 	DriveIndex -= DRIVE_INDEX_MIN; } while (0) | ||||
|  | @ -175,7 +190,6 @@ static HANDLE GetHandle(char* Path, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWr | |||
| 			uprintf("I/O boundary checks disabled"); | ||||
| 		} | ||||
| 
 | ||||
| 		uprintf("Requesting lock..."); | ||||
| 		EndTime = GetTickCount64() + DRIVE_ACCESS_TIMEOUT; | ||||
| 		do { | ||||
| 			if (DeviceIoControl(hDrive, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &size, NULL)) | ||||
|  | @ -208,7 +222,7 @@ char* GetPhysicalName(DWORD DriveIndex) | |||
| 	char physical_name[24]; | ||||
| 
 | ||||
| 	CheckDriveIndex(DriveIndex); | ||||
| 	static_sprintf(physical_name, "\\\\.\\PHYSICALDRIVE%lu", DriveIndex); | ||||
| 	static_sprintf(physical_name, "\\\\.\\PhysicalDrive%lu", DriveIndex); | ||||
| 	success = TRUE; | ||||
| out: | ||||
| 	return (success)?safe_strdup(physical_name):NULL; | ||||
|  | @ -247,7 +261,7 @@ char* GetLogicalName(DWORD DriveIndex, BOOL bKeepTrailingBackslash, BOOL bSilent | |||
| 
 | ||||
| 	CheckDriveIndex(DriveIndex); | ||||
| 
 | ||||
| 	for (i=0; hDrive == INVALID_HANDLE_VALUE; i++) { | ||||
| 	for (i = 0; hDrive == INVALID_HANDLE_VALUE; i++) { | ||||
| 		if (i == 0) { | ||||
| 			hVolume = FindFirstVolumeA(volume_name, sizeof(volume_name)); | ||||
| 			if (hVolume == INVALID_HANDLE_VALUE) { | ||||
|  | @ -265,10 +279,9 @@ char* GetLogicalName(DWORD DriveIndex, BOOL bKeepTrailingBackslash, BOOL bSilent | |||
| 
 | ||||
| 		// Sanity checks
 | ||||
| 		len = safe_strlen(volume_name); | ||||
| 		if ((len <= 1) || (safe_strnicmp(volume_name, volume_start, 4) != 0) || (volume_name[len-1] != '\\')) { | ||||
| 			suprintf("'%s' is not a GUID volume name", volume_name); | ||||
| 			continue; | ||||
| 		} | ||||
| 		assert(len > 4); | ||||
| 		assert(safe_strnicmp(volume_name, volume_start, 4) == 0); | ||||
| 		assert(volume_name[len - 1] == '\\'); | ||||
| 
 | ||||
| 		drive_type = GetDriveTypeA(volume_name); | ||||
| 		if ((drive_type != DRIVE_REMOVABLE) && (drive_type != DRIVE_FIXED)) | ||||
|  | @ -316,6 +329,205 @@ out: | |||
| 	return (success)?safe_strdup(volume_name):NULL; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * 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 r = FALSE; | ||||
| 	HRESULT hr; | ||||
| 	ULONG ulFetched; | ||||
| 	wchar_t wPhysicalName[24]; | ||||
| 	IVdsServiceLoader *pLoader; | ||||
| 	IVdsService *pService; | ||||
| 	IEnumVdsObject *pEnum; | ||||
| 	IUnknown *pUnk; | ||||
| 
 | ||||
| 	CheckDriveIndex(DriveIndex); | ||||
| 	wnsprintf(wPhysicalName, ARRAYSIZE(wPhysicalName), L"\\\\?\\PhysicalDrive%lu", DriveIndex); | ||||
| 
 | ||||
| 	// 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) { | ||||
| 		uprintf("Could not create VDS Loader Instance: hr=%X\n", hr); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	// Load the VDS Service
 | ||||
| 	hr = IVdsServiceLoader_LoadService(pLoader, L"", &pService); | ||||
| 	IVdsServiceLoader_Release(pLoader); | ||||
| 	if (hr != S_OK) { | ||||
| 		uprintf("Could not load VDS Service: 0x%08X", hr); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	// Query the VDS Service Providers
 | ||||
| 	hr = IVdsService_QueryProviders(pService, VDS_QUERY_SOFTWARE_PROVIDERS, &pEnum); | ||||
| 	if (hr != S_OK) { | ||||
| 		uprintf("Could not query VDS Service Providers: 0x%08X", hr); | ||||
| 		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) { | ||||
| 			uprintf("Could not get VDS Provider: 0x%08X", hr); | ||||
| 			goto out; | ||||
| 		} | ||||
| 
 | ||||
| 		// Get VDS Software Provider
 | ||||
| 		hr = IVdsSwProvider_QueryInterface(pProvider, &IID_IVdsSwProvider, (void **)&pSwProvider); | ||||
| 		IVdsProvider_Release(pProvider); | ||||
| 		if (hr != S_OK) { | ||||
| 			uprintf("Could not get VDS Software Provider: 0x%08X", hr); | ||||
| 			goto out; | ||||
| 		} | ||||
| 
 | ||||
| 		// Get VDS Software Provider Packs
 | ||||
| 		hr = IVdsSwProvider_QueryPacks(pSwProvider, &pEnumPack); | ||||
| 		IVdsSwProvider_Release(pSwProvider); | ||||
| 		if (hr != S_OK) { | ||||
| 			uprintf("Could not get VDS Software Provider Packs: 0x%08X", hr); | ||||
| 			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) { | ||||
| 				uprintf("Could not query VDS Software Provider Pack: 0x%08X", hr); | ||||
| 				goto out; | ||||
| 			} | ||||
| 
 | ||||
| 			// Use the pack interface to access the disks
 | ||||
| 			hr = IVdsPack_QueryDisks(pPack, &pEnumDisk); | ||||
| 			if (hr != S_OK) { | ||||
| 				uprintf("Could not query VDS disks: 0x%08X", hr); | ||||
| 				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) { | ||||
| 					uprintf("Could not query VDS Disk Interface: 0x%08X", hr); | ||||
| 					goto out; | ||||
| 				} | ||||
| 
 | ||||
| 				// Get the disk properties
 | ||||
| 				hr = IVdsDisk_GetProperties(pDisk, &diskprop); | ||||
| 				if (hr != S_OK) { | ||||
| 					uprintf("Could not query VDS Disk Properties: 0x%08X", hr); | ||||
| 					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) { | ||||
| 					uprintf("Could not access VDS Advanced Disk interface: 0x%08X", hr); | ||||
| 					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) { | ||||
| 					uprintf("No partition to delete on disk '%ws'", diskprop.pwszName); | ||||
| 					goto out; | ||||
| 				} | ||||
| 
 | ||||
| 				uprintf("Deleting ALL partitions from disk '%ws':", diskprop.pwszName); | ||||
| 
 | ||||
| 				// Now go through each partition
 | ||||
| 				r = (prop_array_size >= 1); | ||||
| 				for (i = 0; i < prop_array_size; i++) { | ||||
| 					uprintf("● Partition %d (offset: %lld, size: %s)", prop_array[i].ulPartitionNumber, | ||||
| 						prop_array[i].ullOffset, SizeToHumanReadable(prop_array[i].ullSize, FALSE, FALSE)); | ||||
| 					hr = IVdsAdvancedDisk_DeletePartition(pAdvancedDisk, prop_array[i].ullOffset, TRUE, TRUE); | ||||
| 					if (hr != S_OK) { | ||||
| 						r = FALSE; | ||||
| 						uprintf("Could not delete partitions: 0x%08X", hr); | ||||
| 					} | ||||
| 				} | ||||
| 				CoTaskMemFree(prop_array); | ||||
| 
 | ||||
| // NB: In the future, we could try something like this to format partitions:
 | ||||
| #if 0 | ||||
| 				// Initiate formatting and wait for completion.
 | ||||
| 				LPWSTR pwszLabel[8] = L"TEST"; | ||||
| 				ULONGLONG Offset = 1024 * 1024; | ||||
| 				BOOL QuickFormat = TRUE; | ||||
| 				BOOL EnableCompression = FALSE; | ||||
| 				IVdsAsync* pAsync; | ||||
| 				hr = IVdsAdvancedDisk_FormatPartition(pAdvancedDisk, Offset, FileSystemType, | ||||
| 					pwszLabel, 0, TRUE, QuickFormat, EnableCompression, &pAsync); | ||||
| 				if (hr != S_OK) { | ||||
| 					uprintf("Could not start formatting: 0x%08X", hr); | ||||
| 					goto out; | ||||
| 				} | ||||
| 				VDS_ASYNC_OUTPUT AsyncOut; | ||||
| 				ULONG ulPercentCompleted; | ||||
| 				HRESULT hr2 = E_FAIL; | ||||
| 				do { | ||||
| 					hr = IVdsAsync_QueryStatus(pAsync, &hr2, &ulPercentCompleted); | ||||
| 					if (SUCCEEDED(hr)) { | ||||
| 						printf("%ld%%", ulPercentCompleted); | ||||
| 						if ((hr2 != S_OK) && (hr2 != VDS_E_OPERATION_PENDING)) { | ||||
| 							uprintf("hr2: %X", hr2); | ||||
| 							break; | ||||
| 						} | ||||
| 						if (hr2 == S_OK) { | ||||
| 							break; | ||||
| 						} | ||||
| 					} | ||||
| 					Sleep(500); | ||||
| 				} while (SUCCEEDED(hr)); | ||||
| 				hr = IVdsAsync_Wait(pAsync, &hr2, &AsyncOut); | ||||
| 				IVdsAsync_Release(pAsync); | ||||
| #endif | ||||
| 				IVdsAdvancedDisk_Release(pAdvancedDisk); | ||||
| 				goto out; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| out: | ||||
| 	return r; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* Wait for a logical drive to reappear - Used when a drive has just been repartitioned */ | ||||
| BOOL WaitForLogical(DWORD DriveIndex) | ||||
| { | ||||
|  |  | |||
							
								
								
									
										154
									
								
								src/drive.h
									
										
									
									
									
								
							
							
						
						
									
										154
									
								
								src/drive.h
									
										
									
									
									
								
							|  | @ -73,6 +73,159 @@ typedef struct _FILE_FS_DEVICE_INFORMATION { | |||
| 	DEVICE_TYPE DeviceType; | ||||
| 	ULONG Characteristics; | ||||
| } FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION; | ||||
| #else | ||||
| /* MinGW is currently missing all the VDS COM stuff */ | ||||
| #include <vds.h> | ||||
| typedef interface IVdsServiceLoader IVdsServiceLoader; | ||||
| typedef interface IVdsService IVdsService; | ||||
| typedef interface IVdsProvider IVdsProvider; | ||||
| typedef interface IVdsSwProvider IVdsSwProvider; | ||||
| typedef interface IEnumVdsObject IEnumVdsObject; | ||||
| typedef interface IVdsPack IVdsPack; | ||||
| typedef interface IVdsDisk IVdsDisk; | ||||
| typedef interface IVdsAdvancedDisk IVdsAdvancedDisk; | ||||
| typedef interface IVdsAdviseSink IVdsAdviseSink; | ||||
| typedef interface IVdsAsync IVdsAsync; | ||||
| 
 | ||||
| typedef struct IVdsServiceLoaderVtbl { | ||||
| 	HRESULT(STDMETHODCALLTYPE *QueryInterface)(__RPC__in IVdsServiceLoader *This, __RPC__in REFIID riid, _COM_Outptr_ void **ppvObject); | ||||
| 	ULONG(STDMETHODCALLTYPE *AddRef)(__RPC__in IVdsServiceLoader *This); | ||||
| 	ULONG(STDMETHODCALLTYPE *Release)(__RPC__in IVdsServiceLoader *This); | ||||
| 	HRESULT(STDMETHODCALLTYPE *LoadService)(__RPC__in IVdsServiceLoader *This, __RPC__in_opt_string LPWSTR pwszMachineName, __RPC__deref_out_opt IVdsService **ppService); | ||||
| } IVdsServiceLoaderVtbl; | ||||
| interface IVdsServiceLoader { | ||||
| 	CONST_VTBL struct IVdsServiceLoaderVtbl *lpVtbl; | ||||
| }; | ||||
| 
 | ||||
| typedef struct IVdsServiceVtbl { | ||||
| 	HRESULT(STDMETHODCALLTYPE *QueryInterface)(__RPC__in IVdsService *This, __RPC__in REFIID riid, _COM_Outptr_ void **ppvObject); | ||||
| 	ULONG(STDMETHODCALLTYPE *AddRef)(__RPC__in IVdsService *This); | ||||
| 	ULONG(STDMETHODCALLTYPE *Release)(__RPC__in IVdsService *This); | ||||
| 	HRESULT(STDMETHODCALLTYPE *IsServiceReady)(__RPC__in IVdsService *This); | ||||
| 	HRESULT(STDMETHODCALLTYPE *WaitForServiceReady)(__RPC__in IVdsService *This); | ||||
| 	HRESULT(STDMETHODCALLTYPE *GetProperties)(__RPC__in IVdsService *This, __RPC__out VDS_SERVICE_PROP *pServiceProp); | ||||
| 	HRESULT(STDMETHODCALLTYPE *QueryProviders)(__RPC__in IVdsService *This, DWORD masks, __RPC__deref_out_opt IEnumVdsObject **ppEnum); | ||||
| 	HRESULT(STDMETHODCALLTYPE *QueryMaskedDisks)(__RPC__in IVdsService *This, __RPC__deref_out_opt IEnumVdsObject **ppEnum); | ||||
| 	HRESULT(STDMETHODCALLTYPE *QueryUnallocatedDisks)(__RPC__in IVdsService *This, __RPC__deref_out_opt IEnumVdsObject **ppEnum); | ||||
| 	HRESULT(STDMETHODCALLTYPE *GetObject)(__RPC__in IVdsService *This, VDS_OBJECT_ID ObjectId, VDS_OBJECT_TYPE type, __RPC__deref_out_opt IUnknown **ppObjectUnk); | ||||
| 	HRESULT(STDMETHODCALLTYPE *QueryDriveLetters)(__RPC__in IVdsService *This, WCHAR wcFirstLetter, DWORD count, __RPC__out_ecount_full(count) VDS_DRIVE_LETTER_PROP *pDriveLetterPropArray); | ||||
| 	HRESULT(STDMETHODCALLTYPE *QueryFileSystemTypes)(__RPC__in IVdsService *This, __RPC__deref_out_ecount_full_opt(*plNumberOfFileSystems) VDS_FILE_SYSTEM_TYPE_PROP **ppFileSystemTypeProps, __RPC__out LONG *plNumberOfFileSystems); | ||||
| 	HRESULT(STDMETHODCALLTYPE *Reenumerate)(__RPC__in IVdsService *This); | ||||
| 	HRESULT(STDMETHODCALLTYPE *Refresh)(__RPC__in IVdsService *This); | ||||
| 	HRESULT(STDMETHODCALLTYPE *CleanupObsoleteMountPoints)(__RPC__in IVdsService *This); | ||||
| 	HRESULT(STDMETHODCALLTYPE *Advise)(__RPC__in IVdsService *This, __RPC__in_opt IVdsAdviseSink *pSink, __RPC__out DWORD *pdwCookie); | ||||
| 	HRESULT(STDMETHODCALLTYPE *Unadvise)(__RPC__in IVdsService *This, DWORD dwCookie); | ||||
| 	HRESULT(STDMETHODCALLTYPE *Reboot)(__RPC__in IVdsService *This); | ||||
| 	HRESULT(STDMETHODCALLTYPE *SetFlags)(__RPC__in IVdsService *This, ULONG ulFlags); | ||||
| 	HRESULT(STDMETHODCALLTYPE *ClearFlags)(__RPC__in IVdsService *This, ULONG ulFlags); | ||||
| } IVdsServiceVtbl; | ||||
| interface IVdsService { | ||||
| 	CONST_VTBL struct IVdsServiceVtbl *lpVtbl; | ||||
| }; | ||||
| 
 | ||||
| typedef struct IEnumVdsObjectVtbl { | ||||
| 	HRESULT(STDMETHODCALLTYPE *QueryInterface)(__RPC__in IEnumVdsObject *This, __RPC__in REFIID riid, _COM_Outptr_ void **ppvObject); | ||||
| 	ULONG(STDMETHODCALLTYPE *AddRef)(__RPC__in IEnumVdsObject *This); | ||||
| 	ULONG(STDMETHODCALLTYPE *Release)(__RPC__in IEnumVdsObject *This); | ||||
| 	HRESULT(STDMETHODCALLTYPE *Next)(__RPC__in IEnumVdsObject *This, ULONG celt, __RPC__out_ecount_part(celt, *pcFetched) IUnknown **ppObjectArray, __RPC__out ULONG *pcFetched); | ||||
| 	HRESULT(STDMETHODCALLTYPE *Skip)(__RPC__in IEnumVdsObject *This, ULONG celt); | ||||
| 	HRESULT(STDMETHODCALLTYPE *Reset)(__RPC__in IEnumVdsObject *This); | ||||
| 	HRESULT(STDMETHODCALLTYPE *Clone)(__RPC__in IEnumVdsObject *This, __RPC__deref_out_opt IEnumVdsObject **ppEnum); | ||||
| } IEnumVdsObjectVtbl; | ||||
| interface IEnumVdsObject { | ||||
| 	CONST_VTBL struct IEnumVdsObjectVtbl *lpVtbl; | ||||
| }; | ||||
| 
 | ||||
| typedef struct IVdsProviderVtbl { | ||||
| 	HRESULT(STDMETHODCALLTYPE *QueryInterface)(__RPC__in IVdsProvider *This, __RPC__in REFIID riid, _COM_Outptr_ void **ppvObject); | ||||
| 	ULONG(STDMETHODCALLTYPE *AddRef)(__RPC__in IVdsProvider *This); | ||||
| 	ULONG(STDMETHODCALLTYPE *Release)(__RPC__in IVdsProvider *This); | ||||
| 	HRESULT(STDMETHODCALLTYPE *GetProperties)(__RPC__in IVdsProvider *This, __RPC__out VDS_PROVIDER_PROP *pProviderProp); | ||||
| } IVdsProviderVtbl; | ||||
| interface IVdsProvider { | ||||
| 	CONST_VTBL struct IVdsProviderVtbl *lpVtbl; | ||||
| }; | ||||
| 
 | ||||
| typedef struct IVdsSwProviderVtbl { | ||||
| 	HRESULT(STDMETHODCALLTYPE *QueryInterface)(__RPC__in IVdsSwProvider *This, __RPC__in REFIID riid, _COM_Outptr_ void **ppvObject); | ||||
| 	ULONG(STDMETHODCALLTYPE *AddRef)(__RPC__in IVdsSwProvider *This); | ||||
| 	ULONG(STDMETHODCALLTYPE *Release)(__RPC__in IVdsSwProvider *This); | ||||
| 	HRESULT(STDMETHODCALLTYPE *QueryPacks)(__RPC__in IVdsSwProvider *This, __RPC__deref_out_opt IEnumVdsObject **ppEnum); | ||||
| 	HRESULT(STDMETHODCALLTYPE *CreatePack)(__RPC__in IVdsSwProvider *This, __RPC__deref_out_opt IVdsPack **ppPack); | ||||
| } IVdsSwProviderVtbl; | ||||
| interface IVdsSwProvider { | ||||
| 	CONST_VTBL struct IVdsSwProviderVtbl *lpVtbl; | ||||
| }; | ||||
| 
 | ||||
| typedef struct IVdsPackVtbl { | ||||
| 	HRESULT(STDMETHODCALLTYPE *QueryInterface)(__RPC__in IVdsPack *This, __RPC__in REFIID riid, _COM_Outptr_ void **ppvObject); | ||||
| 	ULONG(STDMETHODCALLTYPE *AddRef)(__RPC__in IVdsPack *This); | ||||
| 	ULONG(STDMETHODCALLTYPE *Release)(__RPC__in IVdsPack *This); | ||||
| 	HRESULT(STDMETHODCALLTYPE *GetProperties)(__RPC__in IVdsPack *This, __RPC__out VDS_PACK_PROP *pPackProp); | ||||
| 	HRESULT(STDMETHODCALLTYPE *GetProvider)(__RPC__in IVdsPack *This, __RPC__deref_out_opt IVdsProvider **ppProvider); | ||||
| 	HRESULT(STDMETHODCALLTYPE *QueryVolumes)(__RPC__in IVdsPack *This, __RPC__deref_out_opt IEnumVdsObject **ppEnum); | ||||
| 	HRESULT(STDMETHODCALLTYPE *QueryDisks)(__RPC__in IVdsPack *This, __RPC__deref_out_opt IEnumVdsObject **ppEnum); | ||||
| 	HRESULT(STDMETHODCALLTYPE *CreateVolume)(__RPC__in IVdsPack *This, VDS_VOLUME_TYPE type, __RPC__in_ecount_full(lNumberOfDisks) VDS_INPUT_DISK *pInputDiskArray, LONG lNumberOfDisks, ULONG ulStripeSize, __RPC__deref_out_opt IVdsAsync **ppAsync); | ||||
| 	HRESULT(STDMETHODCALLTYPE *AddDisk)(__RPC__in IVdsPack *This, VDS_OBJECT_ID DiskId, VDS_PARTITION_STYLE PartitionStyle, BOOL bAsHotSpare); | ||||
| 	HRESULT(STDMETHODCALLTYPE *MigrateDisks)(__RPC__in IVdsPack *This, __RPC__in_ecount_full(lNumberOfDisks) VDS_OBJECT_ID *pDiskArray, LONG lNumberOfDisks, VDS_OBJECT_ID TargetPack, BOOL bForce, BOOL bQueryOnly, __RPC__out_ecount_full(lNumberOfDisks) HRESULT *pResults, __RPC__out BOOL *pbRebootNeeded); | ||||
| 	HRESULT(STDMETHODCALLTYPE *ReplaceDisk)(__RPC__in IVdsPack *This, VDS_OBJECT_ID OldDiskId, VDS_OBJECT_ID NewDiskId, __RPC__deref_out_opt IVdsAsync **ppAsync); | ||||
| 	HRESULT(STDMETHODCALLTYPE *RemoveMissingDisk)(__RPC__in IVdsPack *This, VDS_OBJECT_ID DiskId); | ||||
| 	HRESULT(STDMETHODCALLTYPE *Recover)(__RPC__in IVdsPack *This, __RPC__deref_out_opt IVdsAsync **ppAsync); | ||||
| } IVdsPackVtbl; | ||||
| interface IVdsPack { | ||||
| 	CONST_VTBL struct IVdsPackVtbl *lpVtbl; | ||||
| }; | ||||
| 
 | ||||
| typedef struct IVdsDiskVtbl { | ||||
| 	HRESULT(STDMETHODCALLTYPE *QueryInterface)(__RPC__in IVdsDisk *This, __RPC__in REFIID riid, _COM_Outptr_ void **ppvObject); | ||||
| 	ULONG(STDMETHODCALLTYPE *AddRef)(__RPC__in IVdsDisk *This); | ||||
| 	ULONG(STDMETHODCALLTYPE *Release)(__RPC__in IVdsDisk *This); | ||||
| 	HRESULT(STDMETHODCALLTYPE *GetProperties)(__RPC__in IVdsDisk *This, __RPC__out VDS_DISK_PROP *pDiskProperties); | ||||
| 	HRESULT(STDMETHODCALLTYPE *GetPack)(__RPC__in IVdsDisk *This, __RPC__deref_out_opt IVdsPack **ppPack); | ||||
| 	HRESULT(STDMETHODCALLTYPE *GetIdentificationData)(__RPC__in IVdsDisk *This, __RPC__out VDS_LUN_INFORMATION *pLunInfo); | ||||
| 	HRESULT(STDMETHODCALLTYPE *QueryExtents)(__RPC__in IVdsDisk *This, __RPC__deref_out_ecount_full_opt(*plNumberOfExtents) VDS_DISK_EXTENT **ppExtentArray, __RPC__out LONG *plNumberOfExtents); | ||||
| 	HRESULT(STDMETHODCALLTYPE *ConvertStyle)(__RPC__in IVdsDisk *This, VDS_PARTITION_STYLE NewStyle); | ||||
| 	HRESULT(STDMETHODCALLTYPE *SetFlags)(__RPC__in IVdsDisk *This, ULONG ulFlags); | ||||
| 	HRESULT(STDMETHODCALLTYPE *ClearFlags)(__RPC__in IVdsDisk *This, ULONG ulFlags); | ||||
| } IVdsDiskVtbl; | ||||
| interface IVdsDisk { | ||||
| 	CONST_VTBL struct IVdsDiskVtbl *lpVtbl; | ||||
| }; | ||||
| 
 | ||||
| typedef struct IVdsAdvancedDiskVtbl { | ||||
| 	HRESULT(STDMETHODCALLTYPE *QueryInterface)(__RPC__in IVdsAdvancedDisk *This, __RPC__in REFIID riid, _COM_Outptr_ void **ppvObject); | ||||
| 	ULONG(STDMETHODCALLTYPE *AddRef)(__RPC__in IVdsAdvancedDisk *This); | ||||
| 	ULONG(STDMETHODCALLTYPE *Release)(__RPC__in IVdsAdvancedDisk *This); | ||||
| 	HRESULT(STDMETHODCALLTYPE *GetPartitionProperties)(__RPC__in IVdsAdvancedDisk *This, ULONGLONG ullOffset, __RPC__out VDS_PARTITION_PROP *pPartitionProp); | ||||
| 	HRESULT(STDMETHODCALLTYPE *QueryPartitions)(__RPC__in IVdsAdvancedDisk *This, __RPC__deref_out_ecount_full_opt(*plNumberOfPartitions) VDS_PARTITION_PROP **ppPartitionPropArray, __RPC__out LONG *plNumberOfPartitions); | ||||
| 	HRESULT(STDMETHODCALLTYPE *CreatePartition)(__RPC__in IVdsAdvancedDisk *This, ULONGLONG ullOffset, ULONGLONG ullSize, __RPC__in CREATE_PARTITION_PARAMETERS *para, __RPC__deref_out_opt IVdsAsync **ppAsync); | ||||
| 	HRESULT(STDMETHODCALLTYPE *DeletePartition)(__RPC__in IVdsAdvancedDisk *This, ULONGLONG ullOffset, BOOL bForce, BOOL bForceProtected); | ||||
| 	HRESULT(STDMETHODCALLTYPE *ChangeAttributes)(__RPC__in IVdsAdvancedDisk *This, ULONGLONG ullOffset, __RPC__in CHANGE_ATTRIBUTES_PARAMETERS *para); | ||||
| 	HRESULT(STDMETHODCALLTYPE *AssignDriveLetter)(__RPC__in IVdsAdvancedDisk *This, ULONGLONG ullOffset, WCHAR wcLetter); | ||||
| 	HRESULT(STDMETHODCALLTYPE *DeleteDriveLetter)(__RPC__in IVdsAdvancedDisk *This, ULONGLONG ullOffset, WCHAR wcLetter); | ||||
| 	HRESULT(STDMETHODCALLTYPE *GetDriveLetter)(__RPC__in IVdsAdvancedDisk *This, ULONGLONG ullOffset, __RPC__out WCHAR *pwcLetter); | ||||
| 	HRESULT(STDMETHODCALLTYPE *FormatPartition)(__RPC__in IVdsAdvancedDisk *This, ULONGLONG ullOffset, VDS_FILE_SYSTEM_TYPE type, __RPC__in_string LPWSTR pwszLabel, DWORD dwUnitAllocationSize, BOOL bForce, BOOL bQuickFormat, BOOL bEnableCompression, __RPC__deref_out_opt IVdsAsync **ppAsync); | ||||
| 	HRESULT(STDMETHODCALLTYPE *Clean)(__RPC__in IVdsAdvancedDisk *This, BOOL bForce, BOOL bForceOEM, BOOL bFullClean, __RPC__deref_out_opt IVdsAsync **ppAsync); | ||||
| } IVdsAdvancedDiskVtbl; | ||||
| interface IVdsAdvancedDisk { | ||||
| 	CONST_VTBL struct IVdsAdvancedDiskVtbl *lpVtbl; | ||||
| }; | ||||
| 
 | ||||
| #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 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_Release(This) (This)->lpVtbl->Release(This) | ||||
| #define IEnumVdsObject_Next(This,celt,ppObjectArray,pcFetched) (This)->lpVtbl->Next(This,celt,ppObjectArray,pcFetched) | ||||
| #endif | ||||
| 
 | ||||
| static __inline BOOL UnlockDrive(HANDLE hDrive) { | ||||
|  | @ -105,6 +258,7 @@ extern RUFUS_DRIVE_INFO SelectedDrive; | |||
| BOOL SetAutoMount(BOOL enable); | ||||
| BOOL GetAutoMount(BOOL* enabled); | ||||
| char* GetPhysicalName(DWORD DriveIndex); | ||||
| BOOL DeletePartitions(DWORD DriveIndex); | ||||
| HANDLE GetPhysicalHandle(DWORD DriveIndex, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare); | ||||
| char* GetLogicalName(DWORD DriveIndex, BOOL bKeepTrailingBackslash, BOOL bSilent); | ||||
| BOOL WaitForLogical(DWORD DriveIndex); | ||||
|  |  | |||
							
								
								
									
										21
									
								
								src/format.c
									
										
									
									
									
								
							
							
						
						
									
										21
									
								
								src/format.c
									
										
									
									
									
								
							|  | @ -1760,13 +1760,13 @@ DWORD WINAPI FormatThread(void* param) | |||
| 		extra_partitions = XP_COMPAT; | ||||
| 
 | ||||
| 	PrintInfoDebug(0, MSG_225); | ||||
| 	hPhysicalDrive = GetPhysicalHandle(DriveIndex, lock_drive, TRUE, !lock_drive); | ||||
| 	hPhysicalDrive = GetPhysicalHandle(DriveIndex, lock_drive, FALSE, !lock_drive); | ||||
| 	if (hPhysicalDrive == INVALID_HANDLE_VALUE) { | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	// At this stage we should have both a handle and a lock to the physical drive...
 | ||||
| 	// At this stage we have both a handle and a lock to the physical drive
 | ||||
| 	if (!GetDriveLetters(DriveIndex, drive_letters)) { | ||||
| 		uprintf("Failed to get a drive letter\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_ASSIGN_LETTER); | ||||
|  | @ -1783,7 +1783,7 @@ DWORD WINAPI FormatThread(void* param) | |||
| 	} else { | ||||
| 		// Unmount all mounted volumes that belong to this drive
 | ||||
| 		// Do it in reverse so that we always end on the first volume letter
 | ||||
| 		for (i=(int)safe_strlen(drive_letters); i>0; i--) { | ||||
| 		for (i = (int)safe_strlen(drive_letters); i > 0; i--) { | ||||
| 			drive_name[0] = drive_letters[i-1]; | ||||
| 			if (bt == BT_IMAGE) { | ||||
| 				// If we are using an image, check that it isn't located on the drive we are trying to format
 | ||||
|  | @ -1801,7 +1801,20 @@ DWORD WINAPI FormatThread(void* param) | |||
| 	} | ||||
| 	uprintf("Will use '%c:' as volume mountpoint\n", drive_name[0]); | ||||
| 
 | ||||
| 	// ...but we need a lock to the logical drive to be able to write anything to it
 | ||||
| 	// It kind of blows, but we have to relinquish access to the physical drive
 | ||||
| 	// for VDS to be able to delete the partitions that reside on it...
 | ||||
| 	safe_unlockclose(hPhysicalDrive); | ||||
| 	PrintInfoDebug(0, MSG_239); | ||||
| 	DeletePartitions(DriveIndex); | ||||
| 
 | ||||
| 	// Now get RW access to the physical drive...
 | ||||
| 	hPhysicalDrive = GetPhysicalHandle(DriveIndex, lock_drive, TRUE, !lock_drive); | ||||
| 	if (hPhysicalDrive == INVALID_HANDLE_VALUE) { | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_OPEN_FAILED; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	// ...and get a lock to the logical drive so that we can actually write something
 | ||||
| 	hLogicalVolume = GetLogicalHandle(DriveIndex, TRUE, FALSE, !lock_drive); | ||||
| 	if (hLogicalVolume == INVALID_HANDLE_VALUE) { | ||||
| 		uprintf("Could not lock volume\n"); | ||||
|  |  | |||
|  | @ -1884,7 +1884,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | |||
| 	case WM_COMMAND: | ||||
| #ifdef RUFUS_TEST | ||||
| 		if (LOWORD(wParam) == IDC_TEST) { | ||||
| 			assert(1 == 0); | ||||
| 			DeletePartitions((DWORD)ComboBox_GetItemData(hDeviceList, ComboBox_GetCurSel(hDeviceList))); | ||||
| 			break; | ||||
| 		} | ||||
| #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 | ||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | ||||
| EXSTYLE WS_EX_ACCEPTFILES | ||||
| CAPTION "Rufus 3.4.1427" | ||||
| CAPTION "Rufus 3.4.1428" | ||||
| FONT 9, "Segoe UI Symbol", 400, 0, 0x0 | ||||
| BEGIN | ||||
|     LTEXT           "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP | ||||
|  | @ -394,8 +394,8 @@ END | |||
| // | ||||
| 
 | ||||
| VS_VERSION_INFO VERSIONINFO | ||||
|  FILEVERSION 3,4,1427,0 | ||||
|  PRODUCTVERSION 3,4,1427,0 | ||||
|  FILEVERSION 3,4,1428,0 | ||||
|  PRODUCTVERSION 3,4,1428,0 | ||||
|  FILEFLAGSMASK 0x3fL | ||||
| #ifdef _DEBUG | ||||
|  FILEFLAGS 0x1L | ||||
|  | @ -413,13 +413,13 @@ BEGIN | |||
|             VALUE "Comments", "https://akeo.ie" | ||||
|             VALUE "CompanyName", "Akeo Consulting" | ||||
|             VALUE "FileDescription", "Rufus" | ||||
|             VALUE "FileVersion", "3.4.1427" | ||||
|             VALUE "FileVersion", "3.4.1428" | ||||
|             VALUE "InternalName", "Rufus" | ||||
|             VALUE "LegalCopyright", "© 2011-2018 Pete Batard (GPL v3)" | ||||
|             VALUE "LegalTrademarks", "https://www.gnu.org/copyleft/gpl.html" | ||||
|             VALUE "OriginalFilename", "rufus-3.4.exe" | ||||
|             VALUE "ProductName", "Rufus" | ||||
|             VALUE "ProductVersion", "3.4.1427" | ||||
|             VALUE "ProductVersion", "3.4.1428" | ||||
|         END | ||||
|     END | ||||
|     BLOCK "VarFileInfo" | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue