[iso] add ISO mounting capabilities for Windows 8 or later

This commit is contained in:
Pete Batard 2015-01-14 00:51:41 +00:00
parent 3444a48fce
commit 99c24d6c88
4 changed files with 166 additions and 8 deletions

152
src/iso.c
View File

@ -920,3 +920,155 @@ out:
udf_close(p_udf);
return r;
}
/*
* The following is used for native ISO mounting in Windows 8 or later
*/
const GUID VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT =
{ 0xEC984AECL, 0xA0F9, 0x47e9, { 0x90, 0x1F, 0x71, 0x41, 0x5A, 0x66, 0x34, 0x5B } };
typedef enum _VIRTUAL_DISK_ACCESS_MASK {
VIRTUAL_DISK_ACCESS_NONE = 0x00000000,
VIRTUAL_DISK_ACCESS_ATTACH_RO = 0x00010000,
VIRTUAL_DISK_ACCESS_ATTACH_RW = 0x00020000,
VIRTUAL_DISK_ACCESS_DETACH = 0x00040000,
VIRTUAL_DISK_ACCESS_GET_INFO = 0x00080000,
VIRTUAL_DISK_ACCESS_CREATE = 0x00100000,
VIRTUAL_DISK_ACCESS_METAOPS = 0x00200000,
VIRTUAL_DISK_ACCESS_READ = 0x000d0000,
VIRTUAL_DISK_ACCESS_ALL = 0x003f0000,
VIRTUAL_DISK_ACCESS_WRITABLE = 0x00320000
} VIRTUAL_DISK_ACCESS_MASK;
typedef enum _OPEN_VIRTUAL_DISK_FLAG {
OPEN_VIRTUAL_DISK_FLAG_NONE = 0x00000000,
OPEN_VIRTUAL_DISK_FLAG_NO_PARENTS = 0x00000001,
OPEN_VIRTUAL_DISK_FLAG_BLANK_FILE = 0x00000002,
OPEN_VIRTUAL_DISK_FLAG_BOOT_DRIVE = 0x00000004,
OPEN_VIRTUAL_DISK_FLAG_CACHED_IO = 0x00000008,
OPEN_VIRTUAL_DISK_FLAG_CUSTOM_DIFF_CHAIN = 0x00000010
} OPEN_VIRTUAL_DISK_FLAG;
typedef enum _OPEN_VIRTUAL_DISK_VERSION {
OPEN_VIRTUAL_DISK_VERSION_UNSPECIFIED = 0,
OPEN_VIRTUAL_DISK_VERSION_1 = 1,
OPEN_VIRTUAL_DISK_VERSION_2 = 2
} OPEN_VIRTUAL_DISK_VERSION;
typedef enum _ATTACH_VIRTUAL_DISK_FLAG {
ATTACH_VIRTUAL_DISK_FLAG_NONE = 0x00000000,
ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY = 0x00000001,
ATTACH_VIRTUAL_DISK_FLAG_NO_DRIVE_LETTER = 0x00000002,
ATTACH_VIRTUAL_DISK_FLAG_PERMANENT_LIFETIME = 0x00000004,
ATTACH_VIRTUAL_DISK_FLAG_NO_LOCAL_HOST = 0x00000008
} ATTACH_VIRTUAL_DISK_FLAG;
typedef enum _ATTACH_VIRTUAL_DISK_VERSION {
ATTACH_VIRTUAL_DISK_VERSION_UNSPECIFIED = 0,
ATTACH_VIRTUAL_DISK_VERSION_1 = 1
} ATTACH_VIRTUAL_DISK_VERSION;
typedef enum _DETACH_VIRTUAL_DISK_FLAG {
DETACH_VIRTUAL_DISK_FLAG_NONE = 0x00000000
} DETACH_VIRTUAL_DISK_FLAG;
typedef struct _VIRTUAL_STORAGE_TYPE {
ULONG DeviceId;
GUID VendorId;
} VIRTUAL_STORAGE_TYPE, *PVIRTUAL_STORAGE_TYPE;
typedef struct _OPEN_VIRTUAL_DISK_PARAMETERS {
OPEN_VIRTUAL_DISK_VERSION Version;
union {
struct {
ULONG RWDepth;
} Version1;
struct {
BOOL GetInfoOnly;
BOOL ReadOnly;
GUID ResiliencyGuid;
} Version2;
};
} OPEN_VIRTUAL_DISK_PARAMETERS, *POPEN_VIRTUAL_DISK_PARAMETERS;
typedef struct _ATTACH_VIRTUAL_DISK_PARAMETERS {
ATTACH_VIRTUAL_DISK_VERSION Version;
union {
struct {
ULONG Reserved;
} Version1;
};
} ATTACH_VIRTUAL_DISK_PARAMETERS, *PATTACH_VIRTUAL_DISK_PARAMETERS;
// VirtDisk API Prototypes - Only available for Windows 8 or later
PF_TYPE_DECL(WINAPI, DWORD, OpenVirtualDisk, (PVIRTUAL_STORAGE_TYPE, PCWSTR,
VIRTUAL_DISK_ACCESS_MASK, OPEN_VIRTUAL_DISK_FLAG, POPEN_VIRTUAL_DISK_PARAMETERS, PHANDLE));
PF_TYPE_DECL(WINAPI, DWORD, AttachVirtualDisk, (HANDLE, PSECURITY_DESCRIPTOR,
ATTACH_VIRTUAL_DISK_FLAG, ULONG, PATTACH_VIRTUAL_DISK_PARAMETERS, LPOVERLAPPED));
PF_TYPE_DECL(WINAPI, DWORD, DetachVirtualDisk, (HANDLE, DETACH_VIRTUAL_DISK_FLAG, ULONG));
PF_TYPE_DECL(WINAPI, DWORD, GetVirtualDiskPhysicalPath, (HANDLE, PULONG, PWSTR));
static char physical_path[128] = "";
static HANDLE mounted_handle = INVALID_HANDLE_VALUE;
char* MountISO(const char* path)
{
VIRTUAL_STORAGE_TYPE vtype = { 1, VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT };
ATTACH_VIRTUAL_DISK_PARAMETERS vparams = { ATTACH_VIRTUAL_DISK_VERSION_1, 0 };
DWORD r;
wchar_t wtmp[128];
ULONG size = ARRAYSIZE(wtmp);
wconvert(path);
char* ret = NULL;
PF_INIT_OR_OUT(OpenVirtualDisk, VirtDisk);
PF_INIT_OR_OUT(AttachVirtualDisk, VirtDisk);
PF_INIT_OR_OUT(GetVirtualDiskPhysicalPath, VirtDisk);
if ((mounted_handle != NULL) && (mounted_handle != INVALID_HANDLE_VALUE))
UnMountISO();
r = pfOpenVirtualDisk(&vtype, wpath, VIRTUAL_DISK_ACCESS_READ | VIRTUAL_DISK_ACCESS_GET_INFO,
OPEN_VIRTUAL_DISK_FLAG_NONE, NULL, &mounted_handle);
if (r != ERROR_SUCCESS) {
SetLastError(r);
uprintf("Could not open ISO '%s': %s", path, WindowsErrorString());
goto out;
}
r = pfAttachVirtualDisk(mounted_handle, NULL, ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY |
ATTACH_VIRTUAL_DISK_FLAG_NO_DRIVE_LETTER, 0, &vparams, NULL);
if (r != ERROR_SUCCESS) {
SetLastError(r);
uprintf("Could not mount ISO '%s': %s", path, WindowsErrorString());
goto out;
}
r = pfGetVirtualDiskPhysicalPath(mounted_handle, &size, wtmp);
if (r != ERROR_SUCCESS) {
SetLastError(r);
uprintf("Could not obtain physical path for mounted ISO '%s': %s", path, WindowsErrorString());
goto out;
}
wchar_to_utf8_no_alloc(wtmp, physical_path, sizeof(physical_path));
ret = physical_path;
out:
if (ret == NULL)
UnMountISO();
wfree(path);
return ret;
}
void UnMountISO(void)
{
PF_INIT_OR_OUT(DetachVirtualDisk, VirtDisk);
if ((mounted_handle == NULL) || (mounted_handle == INVALID_HANDLE_VALUE))
goto out;
pfDetachVirtualDisk(mounted_handle, DETACH_VIRTUAL_DISK_FLAG_NONE, 0);
safe_closehandle(mounted_handle);
out:
physical_path[0] = 0;
}

View File

@ -1959,6 +1959,9 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
ShowWindow(hLogDlg, log_displayed?SW_SHOW:SW_HIDE);
break;
#ifdef RUFUS_TEST
case IDC_TEST:
uprintf("Mounted ISO: '%s'", MountISO("D:\\ISOs\\archlinux-2012.08.04-dual.iso"));
#if 0
if (format_thid != NULL) {
return (INT_PTR)TRUE;
}
@ -2006,6 +2009,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
}
if (format_thid == NULL)
format_op_in_progress = FALSE;
#endif
break;
#endif
case IDC_LANG:

View File

@ -385,6 +385,8 @@ extern SIZE GetTextSize(HWND hCtrl);
extern BOOL ExtractDOS(const char* path);
extern BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan);
extern int64_t ExtractISOFile(const char* iso, const char* iso_file, const char* dest_file, DWORD attributes);
extern char* MountISO(const char* path);
extern void UnMountISO(void);
extern BOOL InstallSyslinux(DWORD drive_index, char drive_letter, int fs);
extern uint16_t GetSyslinuxVersion(char* buf, size_t buf_size, char** ext);
extern BOOL CreateProgress(void);

View File

@ -32,7 +32,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Rufus 2.0.0.572"
CAPTION "Rufus 2.0.0.573"
FONT 8, "Segoe UI", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
@ -157,7 +157,7 @@ END
IDD_DIALOG_XP DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Rufus 2.0.0.572"
CAPTION "Rufus 2.0.0.573"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
@ -283,7 +283,7 @@ END
IDD_DIALOG_RTL DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL
CAPTION "Rufus 2.0.0.572"
CAPTION "Rufus 2.0.0.573"
FONT 8, "Segoe UI", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
@ -415,7 +415,7 @@ END
IDD_DIALOG_RTL_XP DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL
CAPTION "Rufus 2.0.0.572"
CAPTION "Rufus 2.0.0.573"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
@ -669,8 +669,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,0,0,572
PRODUCTVERSION 2,0,0,572
FILEVERSION 2,0,0,573
PRODUCTVERSION 2,0,0,573
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -687,13 +687,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "2.0.0.572"
VALUE "FileVersion", "2.0.0.573"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2015 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "2.0.0.572"
VALUE "ProductVersion", "2.0.0.573"
END
END
BLOCK "VarFileInfo"