"Fossies" - the Fresh Open Source Software Archive

Member "rufus-3.13/src/drive.h" (20 Nov 2020, 24966 Bytes) of package /linux/misc/rufus-3.13.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "drive.h" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.12_vs_3.13.

    1 /*
    2  * Rufus: The Reliable USB Formatting Utility
    3  * Drive access function calls
    4  * Copyright © 2011-2020 Pete Batard <pete@akeo.ie>
    5  *
    6  * This program is free software: you can redistribute it and/or modify
    7  * it under the terms of the GNU General Public License as published by
    8  * the Free Software Foundation, either version 3 of the License, or
    9  * (at your option) any later version.
   10  *
   11  * This program is distributed in the hope that it will be useful,
   12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14  * GNU General Public License for more details.
   15  *
   16  * You should have received a copy of the GNU General Public License
   17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   18  */
   19 
   20 #include <windows.h>
   21 #include <stdint.h>
   22 #include <winioctl.h>   // for DISK_GEOMETRY
   23 #include <winternl.h>
   24 
   25 #pragma once
   26 
   27 #define RUFUS_EXTRA_PARTITION_TYPE          0xea
   28 #define MOUNTMGRCONTROLTYPE                 ((ULONG)'m')
   29 #define MOUNTMGR_DOS_DEVICE_NAME            "\\\\.\\MountPointManager"
   30 #define IOCTL_MOUNTMGR_QUERY_AUTO_MOUNT     \
   31     CTL_CODE(MOUNTMGRCONTROLTYPE, 15, METHOD_BUFFERED, FILE_ANY_ACCESS)
   32 #define IOCTL_MOUNTMGR_SET_AUTO_MOUNT       \
   33     CTL_CODE(MOUNTMGRCONTROLTYPE, 16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
   34 
   35 #define XP_MSR                              0x01
   36 #define XP_ESP                              0x02
   37 #define XP_UEFI_NTFS                        0x04
   38 #define XP_COMPAT                           0x08
   39 #define XP_CASPER                           0x10
   40 
   41 #define PI_MAIN                             0
   42 #define PI_ESP                              1
   43 #define PI_CASPER                           2
   44 #define PI_MAX                              3
   45 
   46 // The following should match VDS_FSOF_FLAGS as much as possible
   47 #define FP_FORCE                            0x00000001
   48 #define FP_QUICK                            0x00000002
   49 #define FP_COMPRESSION                      0x00000004
   50 #define FP_DUPLICATE_METADATA               0x00000008
   51 #define FP_LARGE_FAT32                      0x00010000
   52 #define FP_NO_BOOT                          0x00020000
   53 #define FP_CREATE_PERSISTENCE_CONF          0x00040000
   54 
   55 #define FILE_FLOPPY_DISKETTE                0x00000004
   56 
   57 #define VDS_SET_ERROR(hr) do { if (hr != S_OK) { SetLastError(hr); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_GEN_FAILURE; } } while(0)
   58 
   59 #if !defined(__MINGW32__)
   60 typedef enum _FSINFOCLASS {
   61     FileFsVolumeInformation = 1,
   62     FileFsLabelInformation,
   63     FileFsSizeInformation,
   64     FileFsDeviceInformation,
   65     FileFsAttributeInformation,
   66     FileFsControlInformation,
   67     FileFsFullSizeInformation,
   68     FileFsObjectIdInformation,
   69     FileFsDriverPathInformation,
   70     FileFsVolumeFlagsInformation,
   71     FileFsMaximumInformation
   72 } FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;
   73 #endif
   74 
   75 /* We need a redef of these MS structure */
   76 typedef struct {
   77     DWORD DeviceType;
   78     ULONG DeviceNumber;
   79     ULONG PartitionNumber;
   80 } STORAGE_DEVICE_NUMBER_REDEF;
   81 
   82 typedef struct {
   83     DWORD NumberOfDiskExtents;
   84     // The one from MS uses ANYSIZE_ARRAY, which can lead to all kind of problems
   85     DISK_EXTENT Extents[8];
   86 } VOLUME_DISK_EXTENTS_REDEF;
   87 
   88 #if !defined(__MINGW32__)
   89 typedef struct _FILE_FS_DEVICE_INFORMATION {
   90     DEVICE_TYPE DeviceType;
   91     ULONG Characteristics;
   92 } FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION;
   93 #else
   94 /* MinGW is currently missing all the VDS COM stuff */
   95 #include <vds.h>
   96 typedef interface IVdsServiceLoader IVdsServiceLoader;
   97 typedef interface IVdsService IVdsService;
   98 typedef interface IVdsProvider IVdsProvider;
   99 typedef interface IVdsSwProvider IVdsSwProvider;
  100 typedef interface IEnumVdsObject IEnumVdsObject;
  101 typedef interface IVdsPack IVdsPack;
  102 typedef interface IVdsDisk IVdsDisk;
  103 typedef interface IVdsAdvancedDisk IVdsAdvancedDisk;
  104 typedef interface IVdsAdviseSink IVdsAdviseSink;
  105 typedef interface IVdsAsync IVdsAsync;
  106 typedef interface IVdsVolume IVdsVolume;
  107 typedef interface IVdsVolumeMF3 IVdsVolumeMF3;
  108 
  109 extern const IID CLSID_VdsLoader;
  110 extern const IID IID_IVdsServiceLoader;
  111 extern const IID IID_IVdsProvider;
  112 extern const IID IID_IVdsSwProvider;
  113 extern const IID IID_IVdsPack;
  114 extern const IID IID_IVdsDisk;
  115 extern const IID IID_IVdsAdvancedDisk;
  116 extern const IID IID_IVdsVolume;
  117 extern const IID IID_IVdsVolumeMF3;
  118 
  119 #ifndef VDS_S_PROPERTIES_INCOMPLETE
  120 #define VDS_S_PROPERTIES_INCOMPLETE ((HRESULT)0x00042715L)
  121 #endif
  122 #ifndef VDS_E_OPERATION_PENDING
  123 #define VDS_E_OPERATION_PENDING ((HRESULT)0x80042409L)
  124 #endif
  125 
  126 typedef struct IVdsServiceLoaderVtbl {
  127     HRESULT(STDMETHODCALLTYPE *QueryInterface)(__RPC__in IVdsServiceLoader *This, __RPC__in REFIID riid, _COM_Outptr_ void **ppvObject);
  128     ULONG(STDMETHODCALLTYPE *AddRef)(__RPC__in IVdsServiceLoader *This);
  129     ULONG(STDMETHODCALLTYPE *Release)(__RPC__in IVdsServiceLoader *This);
  130     HRESULT(STDMETHODCALLTYPE *LoadService)(__RPC__in IVdsServiceLoader *This, __RPC__in_opt_string LPWSTR pwszMachineName, __RPC__deref_out_opt IVdsService **ppService);
  131 } IVdsServiceLoaderVtbl;
  132 interface IVdsServiceLoader {
  133     CONST_VTBL struct IVdsServiceLoaderVtbl *lpVtbl;
  134 };
  135 
  136 typedef struct IVdsServiceVtbl {
  137     HRESULT(STDMETHODCALLTYPE *QueryInterface)(__RPC__in IVdsService *This, __RPC__in REFIID riid, _COM_Outptr_ void **ppvObject);
  138     ULONG(STDMETHODCALLTYPE *AddRef)(__RPC__in IVdsService *This);
  139     ULONG(STDMETHODCALLTYPE *Release)(__RPC__in IVdsService *This);
  140     HRESULT(STDMETHODCALLTYPE *IsServiceReady)(__RPC__in IVdsService *This);
  141     HRESULT(STDMETHODCALLTYPE *WaitForServiceReady)(__RPC__in IVdsService *This);
  142     HRESULT(STDMETHODCALLTYPE *GetProperties)(__RPC__in IVdsService *This, __RPC__out VDS_SERVICE_PROP *pServiceProp);
  143     HRESULT(STDMETHODCALLTYPE *QueryProviders)(__RPC__in IVdsService *This, DWORD masks, __RPC__deref_out_opt IEnumVdsObject **ppEnum);
  144     HRESULT(STDMETHODCALLTYPE *QueryMaskedDisks)(__RPC__in IVdsService *This, __RPC__deref_out_opt IEnumVdsObject **ppEnum);
  145     HRESULT(STDMETHODCALLTYPE *QueryUnallocatedDisks)(__RPC__in IVdsService *This, __RPC__deref_out_opt IEnumVdsObject **ppEnum);
  146     HRESULT(STDMETHODCALLTYPE *GetObject)(__RPC__in IVdsService *This, VDS_OBJECT_ID ObjectId, VDS_OBJECT_TYPE type, __RPC__deref_out_opt IUnknown **ppObjectUnk);
  147     HRESULT(STDMETHODCALLTYPE *QueryDriveLetters)(__RPC__in IVdsService *This, WCHAR wcFirstLetter, DWORD count, __RPC__out_ecount_full(count) VDS_DRIVE_LETTER_PROP *pDriveLetterPropArray);
  148     HRESULT(STDMETHODCALLTYPE *QueryFileSystemTypes)(__RPC__in IVdsService *This, __RPC__deref_out_ecount_full_opt(*plNumberOfFileSystems) VDS_FILE_SYSTEM_TYPE_PROP **ppFileSystemTypeProps, __RPC__out LONG *plNumberOfFileSystems);
  149     HRESULT(STDMETHODCALLTYPE *Reenumerate)(__RPC__in IVdsService *This);
  150     HRESULT(STDMETHODCALLTYPE *Refresh)(__RPC__in IVdsService *This);
  151     HRESULT(STDMETHODCALLTYPE *CleanupObsoleteMountPoints)(__RPC__in IVdsService *This);
  152     HRESULT(STDMETHODCALLTYPE *Advise)(__RPC__in IVdsService *This, __RPC__in_opt IVdsAdviseSink *pSink, __RPC__out DWORD *pdwCookie);
  153     HRESULT(STDMETHODCALLTYPE *Unadvise)(__RPC__in IVdsService *This, DWORD dwCookie);
  154     HRESULT(STDMETHODCALLTYPE *Reboot)(__RPC__in IVdsService *This);
  155     HRESULT(STDMETHODCALLTYPE *SetFlags)(__RPC__in IVdsService *This, ULONG ulFlags);
  156     HRESULT(STDMETHODCALLTYPE *ClearFlags)(__RPC__in IVdsService *This, ULONG ulFlags);
  157 } IVdsServiceVtbl;
  158 interface IVdsService {
  159     CONST_VTBL struct IVdsServiceVtbl *lpVtbl;
  160 };
  161 
  162 typedef struct IEnumVdsObjectVtbl {
  163     HRESULT(STDMETHODCALLTYPE *QueryInterface)(__RPC__in IEnumVdsObject *This, __RPC__in REFIID riid, _COM_Outptr_ void **ppvObject);
  164     ULONG(STDMETHODCALLTYPE *AddRef)(__RPC__in IEnumVdsObject *This);
  165     ULONG(STDMETHODCALLTYPE *Release)(__RPC__in IEnumVdsObject *This);
  166     HRESULT(STDMETHODCALLTYPE *Next)(__RPC__in IEnumVdsObject *This, ULONG celt, __RPC__out_ecount_part(celt, *pcFetched) IUnknown **ppObjectArray, __RPC__out ULONG *pcFetched);
  167     HRESULT(STDMETHODCALLTYPE *Skip)(__RPC__in IEnumVdsObject *This, ULONG celt);
  168     HRESULT(STDMETHODCALLTYPE *Reset)(__RPC__in IEnumVdsObject *This);
  169     HRESULT(STDMETHODCALLTYPE *Clone)(__RPC__in IEnumVdsObject *This, __RPC__deref_out_opt IEnumVdsObject **ppEnum);
  170 } IEnumVdsObjectVtbl;
  171 interface IEnumVdsObject {
  172     CONST_VTBL struct IEnumVdsObjectVtbl *lpVtbl;
  173 };
  174 
  175 typedef struct IVdsProviderVtbl {
  176     HRESULT(STDMETHODCALLTYPE *QueryInterface)(__RPC__in IVdsProvider *This, __RPC__in REFIID riid, _COM_Outptr_ void **ppvObject);
  177     ULONG(STDMETHODCALLTYPE *AddRef)(__RPC__in IVdsProvider *This);
  178     ULONG(STDMETHODCALLTYPE *Release)(__RPC__in IVdsProvider *This);
  179     HRESULT(STDMETHODCALLTYPE *GetProperties)(__RPC__in IVdsProvider *This, __RPC__out VDS_PROVIDER_PROP *pProviderProp);
  180 } IVdsProviderVtbl;
  181 interface IVdsProvider {
  182     CONST_VTBL struct IVdsProviderVtbl *lpVtbl;
  183 };
  184 
  185 typedef struct IVdsSwProviderVtbl {
  186     HRESULT(STDMETHODCALLTYPE *QueryInterface)(__RPC__in IVdsSwProvider *This, __RPC__in REFIID riid, _COM_Outptr_ void **ppvObject);
  187     ULONG(STDMETHODCALLTYPE *AddRef)(__RPC__in IVdsSwProvider *This);
  188     ULONG(STDMETHODCALLTYPE *Release)(__RPC__in IVdsSwProvider *This);
  189     HRESULT(STDMETHODCALLTYPE *QueryPacks)(__RPC__in IVdsSwProvider *This, __RPC__deref_out_opt IEnumVdsObject **ppEnum);
  190     HRESULT(STDMETHODCALLTYPE *CreatePack)(__RPC__in IVdsSwProvider *This, __RPC__deref_out_opt IVdsPack **ppPack);
  191 } IVdsSwProviderVtbl;
  192 interface IVdsSwProvider {
  193     CONST_VTBL struct IVdsSwProviderVtbl *lpVtbl;
  194 };
  195 
  196 typedef struct IVdsPackVtbl {
  197     HRESULT(STDMETHODCALLTYPE *QueryInterface)(__RPC__in IVdsPack *This, __RPC__in REFIID riid, _COM_Outptr_ void **ppvObject);
  198     ULONG(STDMETHODCALLTYPE *AddRef)(__RPC__in IVdsPack *This);
  199     ULONG(STDMETHODCALLTYPE *Release)(__RPC__in IVdsPack *This);
  200     HRESULT(STDMETHODCALLTYPE *GetProperties)(__RPC__in IVdsPack *This, __RPC__out VDS_PACK_PROP *pPackProp);
  201     HRESULT(STDMETHODCALLTYPE *GetProvider)(__RPC__in IVdsPack *This, __RPC__deref_out_opt IVdsProvider **ppProvider);
  202     HRESULT(STDMETHODCALLTYPE *QueryVolumes)(__RPC__in IVdsPack *This, __RPC__deref_out_opt IEnumVdsObject **ppEnum);
  203     HRESULT(STDMETHODCALLTYPE *QueryDisks)(__RPC__in IVdsPack *This, __RPC__deref_out_opt IEnumVdsObject **ppEnum);
  204     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);
  205     HRESULT(STDMETHODCALLTYPE *AddDisk)(__RPC__in IVdsPack *This, VDS_OBJECT_ID DiskId, VDS_PARTITION_STYLE PartitionStyle, BOOL bAsHotSpare);
  206     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);
  207     HRESULT(STDMETHODCALLTYPE *ReplaceDisk)(__RPC__in IVdsPack *This, VDS_OBJECT_ID OldDiskId, VDS_OBJECT_ID NewDiskId, __RPC__deref_out_opt IVdsAsync **ppAsync);
  208     HRESULT(STDMETHODCALLTYPE *RemoveMissingDisk)(__RPC__in IVdsPack *This, VDS_OBJECT_ID DiskId);
  209     HRESULT(STDMETHODCALLTYPE *Recover)(__RPC__in IVdsPack *This, __RPC__deref_out_opt IVdsAsync **ppAsync);
  210 } IVdsPackVtbl;
  211 interface IVdsPack {
  212     CONST_VTBL struct IVdsPackVtbl *lpVtbl;
  213 };
  214 
  215 typedef struct IVdsDiskVtbl {
  216     HRESULT(STDMETHODCALLTYPE *QueryInterface)(__RPC__in IVdsDisk *This, __RPC__in REFIID riid, _COM_Outptr_ void **ppvObject);
  217     ULONG(STDMETHODCALLTYPE *AddRef)(__RPC__in IVdsDisk *This);
  218     ULONG(STDMETHODCALLTYPE *Release)(__RPC__in IVdsDisk *This);
  219     HRESULT(STDMETHODCALLTYPE *GetProperties)(__RPC__in IVdsDisk *This, __RPC__out VDS_DISK_PROP *pDiskProperties);
  220     HRESULT(STDMETHODCALLTYPE *GetPack)(__RPC__in IVdsDisk *This, __RPC__deref_out_opt IVdsPack **ppPack);
  221     HRESULT(STDMETHODCALLTYPE *GetIdentificationData)(__RPC__in IVdsDisk *This, __RPC__out VDS_LUN_INFORMATION *pLunInfo);
  222     HRESULT(STDMETHODCALLTYPE *QueryExtents)(__RPC__in IVdsDisk *This, __RPC__deref_out_ecount_full_opt(*plNumberOfExtents) VDS_DISK_EXTENT **ppExtentArray, __RPC__out LONG *plNumberOfExtents);
  223     HRESULT(STDMETHODCALLTYPE *ConvertStyle)(__RPC__in IVdsDisk *This, VDS_PARTITION_STYLE NewStyle);
  224     HRESULT(STDMETHODCALLTYPE *SetFlags)(__RPC__in IVdsDisk *This, ULONG ulFlags);
  225     HRESULT(STDMETHODCALLTYPE *ClearFlags)(__RPC__in IVdsDisk *This, ULONG ulFlags);
  226 } IVdsDiskVtbl;
  227 interface IVdsDisk {
  228     CONST_VTBL struct IVdsDiskVtbl *lpVtbl;
  229 };
  230 
  231 typedef struct IVdsAdvancedDiskVtbl {
  232     HRESULT(STDMETHODCALLTYPE *QueryInterface)(__RPC__in IVdsAdvancedDisk *This, __RPC__in REFIID riid, _COM_Outptr_ void **ppvObject);
  233     ULONG(STDMETHODCALLTYPE *AddRef)(__RPC__in IVdsAdvancedDisk *This);
  234     ULONG(STDMETHODCALLTYPE *Release)(__RPC__in IVdsAdvancedDisk *This);
  235     HRESULT(STDMETHODCALLTYPE *GetPartitionProperties)(__RPC__in IVdsAdvancedDisk *This, ULONGLONG ullOffset, __RPC__out VDS_PARTITION_PROP *pPartitionProp);
  236     HRESULT(STDMETHODCALLTYPE *QueryPartitions)(__RPC__in IVdsAdvancedDisk *This, __RPC__deref_out_ecount_full_opt(*plNumberOfPartitions) VDS_PARTITION_PROP **ppPartitionPropArray, __RPC__out LONG *plNumberOfPartitions);
  237     HRESULT(STDMETHODCALLTYPE *CreatePartition)(__RPC__in IVdsAdvancedDisk *This, ULONGLONG ullOffset, ULONGLONG ullSize, __RPC__in CREATE_PARTITION_PARAMETERS *para, __RPC__deref_out_opt IVdsAsync **ppAsync);
  238     HRESULT(STDMETHODCALLTYPE *DeletePartition)(__RPC__in IVdsAdvancedDisk *This, ULONGLONG ullOffset, BOOL bForce, BOOL bForceProtected);
  239     HRESULT(STDMETHODCALLTYPE *ChangeAttributes)(__RPC__in IVdsAdvancedDisk *This, ULONGLONG ullOffset, __RPC__in CHANGE_ATTRIBUTES_PARAMETERS *para);
  240     HRESULT(STDMETHODCALLTYPE *AssignDriveLetter)(__RPC__in IVdsAdvancedDisk *This, ULONGLONG ullOffset, WCHAR wcLetter);
  241     HRESULT(STDMETHODCALLTYPE *DeleteDriveLetter)(__RPC__in IVdsAdvancedDisk *This, ULONGLONG ullOffset, WCHAR wcLetter);
  242     HRESULT(STDMETHODCALLTYPE *GetDriveLetter)(__RPC__in IVdsAdvancedDisk *This, ULONGLONG ullOffset, __RPC__out WCHAR *pwcLetter);
  243     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);
  244     HRESULT(STDMETHODCALLTYPE *Clean)(__RPC__in IVdsAdvancedDisk *This, BOOL bForce, BOOL bForceOEM, BOOL bFullClean, __RPC__deref_out_opt IVdsAsync **ppAsync);
  245 } IVdsAdvancedDiskVtbl;
  246 interface IVdsAdvancedDisk {
  247     CONST_VTBL struct IVdsAdvancedDiskVtbl *lpVtbl;
  248 };
  249 
  250 typedef struct IVdsVolumeVtbl {
  251     HRESULT (STDMETHODCALLTYPE *QueryInterface)(__RPC__in IVdsVolume *This, __RPC__in REFIID riid, _COM_Outptr_  void **ppvObject);
  252     ULONG (STDMETHODCALLTYPE *AddRef)(__RPC__in IVdsVolume *This);
  253     ULONG (STDMETHODCALLTYPE *Release)(__RPC__in IVdsVolume *This);
  254     HRESULT (STDMETHODCALLTYPE *GetProperties)(__RPC__in IVdsVolume *This, __RPC__out VDS_VOLUME_PROP *pVolumeProperties);
  255     HRESULT (STDMETHODCALLTYPE *GetPack)(__RPC__in IVdsVolume *This, __RPC__deref_out_opt IVdsPack **ppPack);
  256     HRESULT (STDMETHODCALLTYPE *QueryPlexes)(__RPC__in IVdsVolume *This, __RPC__deref_out_opt IEnumVdsObject **ppEnum);
  257     HRESULT (STDMETHODCALLTYPE *Extend)(__RPC__in IVdsVolume *This, __RPC__in_ecount_full_opt(lNumberOfDisks) VDS_INPUT_DISK *pInputDiskArray, LONG lNumberOfDisks, __RPC__deref_out_opt IVdsAsync **ppAsync);
  258     HRESULT (STDMETHODCALLTYPE *Shrink)(__RPC__in IVdsVolume *This, ULONGLONG ullNumberOfBytesToRemove, __RPC__deref_out_opt IVdsAsync **ppAsync);
  259     HRESULT (STDMETHODCALLTYPE *AddPlex)(__RPC__in IVdsVolume *This, VDS_OBJECT_ID VolumeId,__RPC__deref_out_opt IVdsAsync **ppAsync);
  260     HRESULT (STDMETHODCALLTYPE *BreakPlex)(__RPC__in IVdsVolume *This, VDS_OBJECT_ID plexId, __RPC__deref_out_opt IVdsAsync **ppAsync);
  261     HRESULT (STDMETHODCALLTYPE *RemovePlex)(__RPC__in IVdsVolume *This, VDS_OBJECT_ID plexId, __RPC__deref_out_opt IVdsAsync **ppAsync);
  262     HRESULT (STDMETHODCALLTYPE *Delete)(__RPC__in IVdsVolume *This, BOOL bForce);
  263     HRESULT (STDMETHODCALLTYPE *SetFlags)(__RPC__in IVdsVolume *This, ULONG ulFlags, BOOL bRevertOnClose);
  264     HRESULT (STDMETHODCALLTYPE *ClearFlags)(__RPC__in IVdsVolume *This, ULONG ulFlags);
  265 } IVdsVolumeVtbl;
  266 interface IVdsVolume {
  267     CONST_VTBL struct IVdsVolumeVtbl *lpVtbl;
  268 };
  269 
  270 typedef struct IVdsVolumeMF3Vtbl {
  271     HRESULT (STDMETHODCALLTYPE *QueryInterface)(__RPC__in IVdsVolumeMF3 *This, __RPC__in REFIID riid, _COM_Outptr_ void **ppvObject);
  272     ULONG (STDMETHODCALLTYPE *AddRef)(__RPC__in IVdsVolumeMF3 *This);
  273     ULONG (STDMETHODCALLTYPE *Release)(__RPC__in IVdsVolumeMF3 *This);
  274     HRESULT (STDMETHODCALLTYPE *QueryVolumeGuidPathnames)(__RPC__in IVdsVolumeMF3 *This, __RPC__deref_out_ecount_full_opt_string(*pulNumberOfPaths) LPWSTR **pwszPathArray, __RPC__out ULONG *pulNumberOfPaths);
  275     HRESULT (STDMETHODCALLTYPE *FormatEx2)(__RPC__in IVdsVolumeMF3 *This, __RPC__in_opt_string LPWSTR pwszFileSystemTypeName, USHORT usFileSystemRevision, ULONG ulDesiredUnitAllocationSize, __RPC__in_opt_string LPWSTR pwszLabel, DWORD Options, __RPC__deref_out_opt IVdsAsync **ppAsync);
  276     HRESULT (STDMETHODCALLTYPE *OfflineVolume)(__RPC__in IVdsVolumeMF3 *This);
  277 } IVdsVolumeMF3Vtbl;
  278 interface IVdsVolumeMF3 {
  279     CONST_VTBL struct IVdsVolumeMF3Vtbl *lpVtbl;
  280 };
  281 
  282 typedef struct IVdsAsyncVtbl {
  283     HRESULT (STDMETHODCALLTYPE *QueryInterface)(__RPC__in IVdsAsync *This, __RPC__in REFIID riid, _COM_Outptr_ void **ppvObject);
  284     ULONG (STDMETHODCALLTYPE *AddRef)(__RPC__in IVdsAsync *This);
  285     ULONG (STDMETHODCALLTYPE *Release)(__RPC__in IVdsAsync *This);
  286     HRESULT (STDMETHODCALLTYPE *Cancel)(__RPC__in IVdsAsync *This);
  287     HRESULT (STDMETHODCALLTYPE *Wait)(__RPC__in IVdsAsync *This, __RPC__out HRESULT *pHrResult, __RPC__out VDS_ASYNC_OUTPUT *pAsyncOut);
  288     HRESULT (STDMETHODCALLTYPE *QueryStatus)(__RPC__in IVdsAsync *This, __RPC__out HRESULT *pHrResult, __RPC__out ULONG *pulPercentCompleted);
  289 } IVdsAsyncVtbl;
  290 interface IVdsAsync {
  291     CONST_VTBL struct IVdsAsyncVtbl *lpVtbl;
  292 };
  293 
  294 #define IVdsServiceLoader_LoadService(This, pwszMachineName, ppService) (This)->lpVtbl->LoadService(This, pwszMachineName, ppService)
  295 #define IVdsServiceLoader_Release(This) (This)->lpVtbl->Release(This)
  296 #define IVdsService_QueryProviders(This, masks, ppEnum) (This)->lpVtbl->QueryProviders(This, masks, ppEnum)
  297 #define IVdsService_WaitForServiceReady(This) ((This)->lpVtbl->WaitForServiceReady(This))
  298 #define IVdsService_CleanupObsoleteMountPoints(This) ((This)->lpVtbl->CleanupObsoleteMountPoints(This))
  299 #define IVdsService_Refresh(This) ((This)->lpVtbl->Refresh(This))
  300 #define IVdsService_Reenumerate(This) ((This)->lpVtbl->Reenumerate(This))
  301 #define IVdsService_Release(This) (This)->lpVtbl->Release(This)
  302 #define IVdsSwProvider_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
  303 #define IVdsProvider_Release(This) (This)->lpVtbl->Release(This)
  304 #define IVdsSwProvider_QueryPacks(This, ppEnum) (This)->lpVtbl->QueryPacks(This, ppEnum)
  305 #define IVdsSwProvider_Release(This) (This)->lpVtbl->Release(This)
  306 #define IVdsPack_QueryDisks(This, ppEnum) (This)->lpVtbl->QueryDisks(This, ppEnum)
  307 #define IVdsPack_Release(This) (This)->lpVtbl->Release(This)
  308 #define IVdsDisk_GetProperties(This, pDiskProperties) (This)->lpVtbl->GetProperties(This, pDiskProperties)
  309 #define IVdsDisk_Release(This) (This)->lpVtbl->Release(This)
  310 #define IVdsDisk_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
  311 #define IVdsAdvancedDisk_QueryPartitions(This, ppPartitionPropArray, plNumberOfPartitions) (This)->lpVtbl->QueryPartitions(This, ppPartitionPropArray, plNumberOfPartitions)
  312 #define IVdsAdvancedDisk_DeletePartition(This, ullOffset, bForce, bForceProtected) (This)->lpVtbl->DeletePartition(This, ullOffset, bForce, bForceProtected)
  313 #define IVdsAdvancedDisk_Clean(This, bForce, bForceOEM, bFullClean, ppAsync) (This)->lpVtbl->Clean(This, bForce, bForceOEM, bFullClean, ppAsync)
  314 #define IVdsAdvancedDisk_Release(This) (This)->lpVtbl->Release(This)
  315 #define IEnumVdsObject_Next(This, celt, ppObjectArray, pcFetched) (This)->lpVtbl->Next(This, celt, ppObjectArray, pcFetched)
  316 #define IEnumVdsObject_Release(This) (This)->lpVtbl->Release(This)
  317 #define IVdsPack_QueryVolumes(This, ppEnum) (This)->lpVtbl->QueryVolumes(This, ppEnum)
  318 #define IVdsVolume_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
  319 #define IVdsVolume_Release(This) (This)->lpVtbl->Release(This)
  320 #define IVdsVolumeMF3_QueryVolumeGuidPathnames(This, pwszPathArray, pulNumberOfPaths) (This)->lpVtbl->QueryVolumeGuidPathnames(This,pwszPathArray,pulNumberOfPaths)
  321 #define IVdsVolumeMF3_FormatEx2(This, pwszFileSystemTypeName, usFileSystemRevision, ulDesiredUnitAllocationSize, pwszLabel, Options, ppAsync) (This)->lpVtbl->FormatEx2(This, pwszFileSystemTypeName, usFileSystemRevision, ulDesiredUnitAllocationSize, pwszLabel, Options, ppAsync)
  322 #define IVdsVolumeMF3_Release(This) (This)->lpVtbl->Release(This)
  323 #define IVdsVolume_GetProperties(This, pVolumeProperties) (This)->lpVtbl->GetProperties(This,pVolumeProperties)
  324 #define IVdsAsync_Cancel(This) (This)->lpVtbl->Cancel(This)
  325 #define IVdsAsync_QueryStatus(This,pHrResult,pulPercentCompleted) (This)->lpVtbl->QueryStatus(This,pHrResult,pulPercentCompleted)
  326 #define IVdsAsync_Wait(This,pHrResult,pAsyncOut) (This)->lpVtbl->Wait(This,pHrResult,pAsyncOut)
  327 #define IVdsAsync_Release(This) (This)->lpVtbl->Release(This)
  328 #endif
  329 
  330 /* MinGW is unhappy about accessing partitions beside the first unless we redef */
  331 typedef struct _DRIVE_LAYOUT_INFORMATION_EX4 {
  332     DWORD PartitionStyle;
  333     DWORD PartitionCount;
  334     union {
  335         DRIVE_LAYOUT_INFORMATION_MBR Mbr;
  336         DRIVE_LAYOUT_INFORMATION_GPT Gpt;
  337     } Type;
  338     PARTITION_INFORMATION_EX PartitionEntry[MAX_PARTITIONS];
  339 } DRIVE_LAYOUT_INFORMATION_EX4, *PDRIVE_LAYOUT_INFORMATION_EX4;
  340 
  341 static __inline BOOL UnlockDrive(HANDLE hDrive) {
  342     DWORD size;
  343     return DeviceIoControl(hDrive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &size, NULL);
  344 }
  345 #define safe_unlockclose(h) do {if ((h != INVALID_HANDLE_VALUE) && (h != NULL)) {UnlockDrive(h); CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0)
  346 
  347 /* Current drive info */
  348 typedef struct {
  349     LONGLONG DiskSize;
  350     DWORD DeviceNumber;
  351     DWORD SectorsPerTrack;
  352     DWORD SectorSize;
  353     DWORD FirstDataSector;
  354     MEDIA_TYPE MediaType;
  355     int PartitionStyle;
  356     int nPartitions;    // number of partitions we actually care about
  357     uint64_t PartitionOffset[MAX_PARTITIONS];
  358     uint64_t PartitionSize[MAX_PARTITIONS];
  359     int FSType;
  360     char proposed_label[16];
  361     BOOL has_protective_mbr;
  362     BOOL has_mbr_uefi_marker;
  363     struct {
  364         ULONG Allowed;
  365         ULONG Default;
  366     } ClusterSize[FS_MAX];
  367 } RUFUS_DRIVE_INFO;
  368 extern RUFUS_DRIVE_INFO SelectedDrive;
  369 extern uint64_t partition_offset[PI_MAX];
  370 
  371 BOOL SetAutoMount(BOOL enable);
  372 BOOL GetAutoMount(BOOL* enabled);
  373 char* GetPhysicalName(DWORD DriveIndex);
  374 BOOL DeletePartition(DWORD DriveIndex, ULONGLONG PartitionOffset, BOOL bSilent);
  375 BOOL ListVdsVolumes(BOOL bSilent);
  376 HANDLE GetPhysicalHandle(DWORD DriveIndex, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare);
  377 char* GetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrailingBackslash, BOOL bSilent);
  378 char* AltGetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrailingBackslash, BOOL bSilent);
  379 char* GetExtPartitionName(DWORD DriveIndex, uint64_t PartitionOffset);
  380 BOOL WaitForLogical(DWORD DriveIndex, uint64_t PartitionOffset);
  381 HANDLE GetLogicalHandle(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare);
  382 int GetDriveNumber(HANDLE hDrive, char* path);
  383 BOOL GetDriveLetters(DWORD DriveIndex, char* drive_letters);
  384 UINT GetDriveTypeFromIndex(DWORD DriveIndex);
  385 char GetUnusedDriveLetter(void);
  386 BOOL IsDriveLetterInUse(const char drive_letter);
  387 char RemoveDriveLetters(DWORD DriveIndex, BOOL bUseLast, BOOL bSilent);
  388 BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label);
  389 uint64_t GetDriveSize(DWORD DriveIndex);
  390 BOOL IsMediaPresent(DWORD DriveIndex);
  391 BOOL AnalyzeMBR(HANDLE hPhysicalDrive, const char* TargetName, BOOL bSilent);
  392 BOOL AnalyzePBR(HANDLE hLogicalVolume);
  393 BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSystemNameSize, BOOL bSilent);
  394 BOOL UnmountVolume(HANDLE hDrive);
  395 BOOL MountVolume(char* drive_name, char *drive_guid);
  396 BOOL AltUnmountVolume(const char* drive_name, BOOL bSilent);
  397 char* AltMountVolume(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bSilent);
  398 BOOL RemountVolume(char* drive_name, BOOL bSilent);
  399 BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL mbr_uefi_marker, uint8_t extra_partitions);
  400 BOOL InitializeDisk(HANDLE hDrive);
  401 BOOL RefreshDriveLayout(HANDLE hDrive);
  402 const char* GetMBRPartitionType(const uint8_t type);
  403 const char* GetGPTPartitionType(const GUID* guid);
  404 const char* GetExtFsLabel(DWORD DriveIndex, uint64_t PartitionOffset);
  405 BOOL GetDevices(DWORD devnum);
  406 BOOL CyclePort(int index);
  407 int CycleDevice(int index);
  408 BOOL RefreshLayout(DWORD DriveIndex);
  409 BOOL GetOpticalMedia(IMG_SAVE* img_save);
  410 BOOL ToggleEsp(DWORD DriveIndex, uint64_t PartitionOffset);