diff --git a/src/format.c b/src/format.c index f7619929..933d157a 100644 --- a/src/format.c +++ b/src/format.c @@ -60,7 +60,7 @@ static float format_percent = 0.0f; static int task_number = 0; extern const int nb_steps[FS_MAX]; extern uint32_t dur_mins, dur_secs; -static int fs_index = 0; +static int fs_index = 0, wintogo_index = -1; extern BOOL force_large_fat32, enable_ntfs_compression, lock_drive, zero_drive, disable_file_indexing; uint8_t *grub2_buf = NULL; long grub2_len; @@ -1264,55 +1264,31 @@ out: return r; } -// http://technet.microsoft.com/en-ie/library/jj721578.aspx - -// As opposed to the technet guide above, we no longer set internal drives offline, -// due to people wondering why they can't see them by default, and also due to dism -// incompatibilities from one version of Windows to the next. -// Maybe when we use wimlib we'll review this, but for now just turn it off. -//#define SET_INTERNAL_DRIVES_OFFLINE -static BOOL SetupWinToGo(const char* drive_name, BOOL use_ms_efi) +// Checks which versions of Windows are available in an install.wim image +// to set our extraction index. Asks the user to select one if needed. +BOOL SetWinToGoIndex(void) { -#ifdef SET_INTERNAL_DRIVES_OFFLINE - static char san_policy_path[] = "?:\\san_policy.xml"; -#endif - static char unattend_path[] = "?:\\Windows\\System32\\sysprep\\unattend.xml"; - StrArray version_name, version_index; - char *mounted_iso, *ms_efi = NULL, image[128], cmd[MAX_PATH]; + char *mounted_iso, image[128]; char tmp_path[MAX_PATH] = "", xml_file[MAX_PATH] = ""; - unsigned char *buffer; - int i, index; - wchar_t wVolumeName[] = L"?:"; - DWORD bufsize; - ULONG cluster_size; - FILE* fd; - PF_DECL(FormatEx); - PF_INIT(FormatEx, Fmifs); + StrArray version_name, version_index; + int i; - uprintf("Windows To Go mode selected"); - // Additional sanity checks - if ( ((use_ms_efi) && (SelectedDrive.MediaType != FixedMedia)) || - ((nWindowsVersion < WINDOWS_8) || ((WimExtractCheck() & 4) == 0)) ) { - FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_SUPPORTED; + // Sanity checks + if ((nWindowsVersion < WINDOWS_8) || ((WimExtractCheck() & 4) == 0) || + (ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)) != FS_NTFS)) { + wintogo_index = -1; return FALSE; } - if (ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)) != FS_NTFS) { - FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_INCOMPATIBLE_FS); - return FALSE; - } - - // First, we need to access the install.wim image, that resides on the ISO + // Mount the install.wim image, that resides on the ISO mounted_iso = MountISO(image_path); if (mounted_iso == NULL) { - uprintf("Could not mount ISO for Windows To Go installation"); - FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT); + uprintf("Could not mount ISO for Windows To Go selection"); + wintogo_index = -1; return FALSE; } static_sprintf(image, "%s%s", mounted_iso, &img_report.install_wim_path[2]); - uprintf("Mounted ISO as '%s'", mounted_iso); - // Then we need to take a look at the XML file in install.wim to allow users - // to select the version they want to extract + // Now take a look at the XML file in install.wim to list our versions if ((GetTempPathU(sizeof(tmp_path), tmp_path) == 0) || (GetTempFileNameU(tmp_path, APPLICATION_NAME, 0, xml_file) == 0) || (xml_file[0] == 0)) { @@ -1328,30 +1304,67 @@ static BOOL SetupWinToGo(const char* drive_name, BOOL use_ms_efi) } StrArrayCreate(&version_name, 16); StrArrayCreate(&version_index, 16); - for (i = 0; (StrArrayAdd(&version_name, get_token_data_file_indexed("DISPLAYNAME", xml_file, i+1), FALSE) >= 0) && - (StrArrayAdd(&version_index, get_token_data_file_indexed("IMAGE INDEX", xml_file, i+1), FALSE) >= 0); i++); + for (i = 0; (StrArrayAdd(&version_name, get_token_data_file_indexed("DISPLAYNAME", xml_file, i + 1), FALSE) >= 0) && + (StrArrayAdd(&version_index, get_token_data_file_indexed("IMAGE INDEX", xml_file, i + 1), FALSE) >= 0); i++); DeleteFileU(xml_file); + UnMountISO(); if (i > 1) i = Selection(lmprintf(MSG_291), lmprintf(MSG_292), version_name.String, i); - if (i <= 0) { - uprintf("Cancelled by user"); - FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANCELLED; - UnMountISO(); - StrArrayDestroy(&version_name); - StrArrayDestroy(&version_index); - return FALSE; + if (i < 0) { + wintogo_index = -1; } else if (i == 0) { - index = 1; + wintogo_index = 1; } else { - index = atoi(version_index.String[i - 1]); + wintogo_index = atoi(version_index.String[i - 1]); } - uprintf("Selected: '%s' (index %s)", version_name.String[i - 1], version_index.String[i - 1]); + if (i >= 1) + uprintf("Will use '%s' (index %s) for Windows To Go", version_name.String[i - 1], version_index.String[i - 1]); StrArrayDestroy(&version_name); StrArrayDestroy(&version_index); + return (wintogo_index >= 0); +} + +// http://technet.microsoft.com/en-ie/library/jj721578.aspx +// As opposed to the technet guide above, we no longer set internal drives offline, +// due to people wondering why they can't see them by default, and also due to dism +// incompatibilities from one version of Windows to the next. +// Maybe when we use wimlib we'll review this, but for now just turn it off. +//#define SET_INTERNAL_DRIVES_OFFLINE +static BOOL SetupWinToGo(const char* drive_name, BOOL use_ms_efi) +{ +#ifdef SET_INTERNAL_DRIVES_OFFLINE + static char san_policy_path[] = "?:\\san_policy.xml"; +#endif + static char unattend_path[] = "?:\\Windows\\System32\\sysprep\\unattend.xml"; + char *mounted_iso, *ms_efi = NULL, image[128], cmd[MAX_PATH]; + unsigned char *buffer; + wchar_t wVolumeName[] = L"?:"; + DWORD bufsize; + ULONG cluster_size; + FILE* fd; + PF_DECL(FormatEx); + PF_INIT(FormatEx, Fmifs); + + uprintf("Windows To Go mode selected"); + // Additional sanity checks + if ( (use_ms_efi) && (SelectedDrive.MediaType != FixedMedia) ) { + FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_SUPPORTED; + return FALSE; + } + + // First, we need to access the install.wim image, that resides on the ISO + mounted_iso = MountISO(image_path); + if (mounted_iso == NULL) { + uprintf("Could not mount ISO for Windows To Go installation"); + FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT); + return FALSE; + } + static_sprintf(image, "%s%s", mounted_iso, &img_report.install_wim_path[2]); + uprintf("Mounted ISO as '%s'", mounted_iso); // Now we use the WIM API to apply that image - if (!WimApplyImage(image, index, drive_name)) { + if (!WimApplyImage(image, wintogo_index, drive_name)) { uprintf("Failed to apply Windows To Go image"); if (!IS_ERROR(FormatStatus)) FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT); diff --git a/src/rufus.c b/src/rufus.c index 3aaa343f..b9a06b7f 100644 --- a/src/rufus.c +++ b/src/rufus.c @@ -1304,6 +1304,9 @@ static BOOL BootCheck(void) if (MessageBoxExU(hMainDialog, lmprintf(MSG_098), lmprintf(MSG_190), MB_YESNO|MB_ICONWARNING|MB_IS_RTL, selected_langid) != IDYES) return FALSE; } + // If multiple versions are available, asks the user to select one before we commit to format the drive + if (!SetWinToGoIndex()) + return FALSE; } else if (tt == TT_UEFI) { if (!IS_EFI_BOOTABLE(img_report)) { // Unsupported ISO diff --git a/src/rufus.h b/src/rufus.h index 4bbdcfa4..c9f0fa7a 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -470,6 +470,7 @@ extern BOOL WimExtractFile_7z(const char* image, int index, const char* src, con extern BOOL WimApplyImage(const char* image, int index, const char* dst); extern BOOL IsBootableImage(const char* path); extern BOOL AppendVHDFooter(const char* vhd_path); +extern BOOL SetWinToGoIndex(void); extern int IsHDD(DWORD DriveIndex, uint16_t vid, uint16_t pid, const char* strid); extern LONG ValidateSignature(HWND hDlg, const char* path); extern BOOL IsFontAvailable(const char* font_name); diff --git a/src/rufus.rc b/src/rufus.rc index 176c89b7..19182b54 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,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 EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 2.12.1009" +CAPTION "Rufus 2.12.1010" FONT 8, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 @@ -334,8 +334,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,12,1009,0 - PRODUCTVERSION 2,12,1009,0 + FILEVERSION 2,12,1010,0 + PRODUCTVERSION 2,12,1010,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -352,13 +352,13 @@ BEGIN BEGIN VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "2.12.1009" + VALUE "FileVersion", "2.12.1010" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2016 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "OriginalFilename", "rufus.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "2.12.1009" + VALUE "ProductVersion", "2.12.1010" END END BLOCK "VarFileInfo"