mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[togo] Add Windows To Go support - part 2
* Enable the creation of MSR and MS EFI partition in GPT mode * Closes #432
This commit is contained in:
		
							parent
							
								
									ec761dfb41
								
							
						
					
					
						commit
						ed9fae7c81
					
				
					 5 changed files with 205 additions and 51 deletions
				
			
		
							
								
								
									
										153
									
								
								src/drive.c
									
										
									
									
									
								
							
							
						
						
									
										153
									
								
								src/drive.c
									
										
									
									
									
								
							|  | @ -45,6 +45,10 @@ const GUID PARTITION_BASIC_DATA_GUID = | |||
| const GUID PARTITION_MSFT_RESERVED_GUID = | ||||
| 	{ 0xe3c9e316L, 0x0b5c, 0x4db8, {0x81, 0x7d, 0xf9, 0x2d, 0xf0, 0x02, 0x15, 0xae} }; | ||||
| #endif | ||||
| #if !defined(PARTITION_SYSTEM_GUID) | ||||
| const GUID PARTITION_SYSTEM_GUID = | ||||
| 	{ 0xc12a7328L, 0xf81f, 0x11d2, {0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b} }; | ||||
| #endif | ||||
| 
 | ||||
| /*
 | ||||
|  * Globals | ||||
|  | @ -102,7 +106,7 @@ BOOL GetAutoMount(BOOL* enabled) | |||
|  */ | ||||
| #define CheckDriveIndex(DriveIndex) do { \ | ||||
| 	if ((DriveIndex < DRIVE_INDEX_MIN) || (DriveIndex > DRIVE_INDEX_MAX)) { \ | ||||
| 		uprintf("WARNING: Bad index value. Please check the code!\n"); \ | ||||
| 		uprintf("ERROR: Bad index value. Please check the code!\n"); \ | ||||
| 		goto out; \ | ||||
| 	} \ | ||||
| 	DriveIndex -= DRIVE_INDEX_MIN; } while (0) | ||||
|  | @ -403,7 +407,7 @@ static BOOL _GetDriveLettersAndType(DWORD DriveIndex, char* drive_letters, UINT* | |||
| 		hDrive = CreateFileA(logical_drive, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, | ||||
| 			NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); | ||||
| 		if (hDrive == INVALID_HANDLE_VALUE) { | ||||
| 			uprintf("Warning: could not open drive %c: %s\n", drive[0], WindowsErrorString()); | ||||
| //			uprintf("Warning: could not open drive %c: %s\n", drive[0], WindowsErrorString());
 | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
|  | @ -684,7 +688,7 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys | |||
| 		return 0; | ||||
| 	} | ||||
| 	if (DiskGeometry->Geometry.BytesPerSector < 512) { | ||||
| 		suprintf("WARNING: Drive 0x%02x reports a sector size of %d - Correcting to 512 bytes.\n", | ||||
| 		suprintf("Warning: Drive 0x%02x reports a sector size of %d - Correcting to 512 bytes.\n", | ||||
| 			DriveIndex, DiskGeometry->Geometry.BytesPerSector); | ||||
| 		DiskGeometry->Geometry.BytesPerSector = 512; | ||||
| 	} | ||||
|  | @ -863,6 +867,102 @@ BOOL MountVolume(char* drive_name, char *drive_guid) | |||
| 	return TRUE; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Mount partition #part_nr, residing on the same disk as drive_name to an available | ||||
|  * drive letter. Returns the newly allocated drive string. | ||||
|  * We need to do this because, for instance, EFI System partitions are not assigned | ||||
|  * Volume GUIDs by the OS, and we need to have a letter assigned, for when we invoke | ||||
|  * bcdtool for Windows To Go. All in all, the process looks like this: | ||||
|  * 1. F: = \Device\HarddiskVolume9 (SINGLE LOOKUP) | ||||
|  * 2. Harddisk5Partition1 = \Device\HarddiskVolume9 (FULL LOOKUP) | ||||
|  * 3. Harddisk5Partition2 = \Device\HarddiskVolume10 (SINGLE LOOKUP) | ||||
|  * 4. DefineDosDevice(letter, \Device\HarddiskVolume10) | ||||
|  */ | ||||
| char* AltMountVolume(const char* drive_name, uint8_t part_nr) | ||||
| { | ||||
| 	static char mounted_drive[] = "?:"; | ||||
| 	const size_t bufsize = 65536; | ||||
| 	char *buffer = NULL, *p, target[2][MAX_PATH], *ret = NULL; | ||||
| 	int i; | ||||
| 
 | ||||
| 	mounted_drive[0] = GetUnusedDriveLetter(); | ||||
| 	if (mounted_drive[0] == 0) { | ||||
| 		uprintf("Could not find an unused drive letter"); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	target[0][0] = 0; | ||||
| 	// Convert our drive letter to something like "\Device\HarddiskVolume9"
 | ||||
| 	if (!QueryDosDeviceA(drive_name, target[0], MAX_PATH) && (strlen(target[0]) == 0)) { | ||||
| 		uprintf("Could not get the DOS device name for '%s': %s", drive_name, WindowsErrorString()); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	// Now parse the whole DOS device list to find the 'Harddisk#Partition#' that matches the above
 | ||||
| 	// TODO: realloc if someone ever manages to burst through 64K of DOS devices
 | ||||
| 	buffer = malloc(bufsize); | ||||
| 	if (buffer == NULL) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	buffer[0] = 0; | ||||
| 	if (!QueryDosDeviceA(NULL, buffer, bufsize)) { | ||||
| 		uprintf("Could not get the DOS device list: %s", WindowsErrorString()); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	p = buffer; | ||||
| 	while (strlen(p) != 0) { | ||||
| 		if ((strncmp("Harddisk", p, 8) == 0) && (strstr(&p[9], "Partition") != NULL)) { | ||||
| 			target[1][0] = 0; | ||||
| 			if (QueryDosDeviceA(p, target[1], MAX_PATH) && (strlen(target[1]) != 0)) | ||||
| 				if ((strcmp(target[1], target[0]) == 0) && (p[1] != ':')) | ||||
| 					break; | ||||
| 		} | ||||
| 		p += strlen(p) + 1; | ||||
| 	} | ||||
| 
 | ||||
| 	i = strlen(p); | ||||
| 	if (i == 0) { | ||||
| 		uprintf("Could not find partition mapping for %s", target[0]); | ||||
| 		goto out; | ||||
| 	} | ||||
| 	 | ||||
| 	while ((--i > 0) && (isdigit(p[i]))); | ||||
| 	p[++i] = '0' + part_nr; | ||||
| 	p[++i] = 0; | ||||
| 
 | ||||
| 	target[0][0] = 0; | ||||
| 	if (!QueryDosDeviceA(p, target[0], MAX_PATH) && (strlen(target[0]) == 0)) { | ||||
| 		uprintf("Could not get DOS device name for partition '%s': %s", drive_name, WindowsErrorString()); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!DefineDosDeviceA(DDD_RAW_TARGET_PATH | DDD_NO_BROADCAST_SYSTEM, mounted_drive, target[0])) { | ||||
| 		uprintf("Could not mount '%s' to '%s': %s", target[0], mounted_drive, WindowsErrorString()); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	uprintf("Successfully mounted '%s' (USB partition %d) as '%s'", target[0], part_nr, mounted_drive); | ||||
| 	ret = mounted_drive; | ||||
| 
 | ||||
| out: | ||||
| 	safe_free(buffer); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Unmount a volume that was mounted by AltmountVolume() | ||||
|  */ | ||||
| BOOL AltUnmountVolume(const char* drive_name) | ||||
| { | ||||
| 	if (!DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_NO_BROADCAST_SYSTEM, drive_name, NULL)) { | ||||
| 		uprintf("Could not unmount '%s': %s", drive_name, WindowsErrorString()); | ||||
| 		return FALSE; | ||||
| 	} | ||||
| 	uprintf("Successfully unmounted '%s'", drive_name); | ||||
| 	return TRUE; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Issue a complete remount of the volume | ||||
|  */ | ||||
|  | @ -909,7 +1009,7 @@ typedef struct _DRIVE_LAYOUT_INFORMATION_EX4 { | |||
|  * copy it got from the last IOCTL, and ignores your changes until you replug the drive | ||||
|  * or issue an IOCTL_DISK_UPDATE_PROPERTIES. | ||||
|  */ | ||||
| BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL mbr_uefi_marker, BOOL add_uefi_togo) | ||||
| BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL mbr_uefi_marker, uint8_t extra_partitions) | ||||
| { | ||||
| 	const char* PartitionTypeName[2] = { "MBR", "GPT" }; | ||||
| 	unsigned char* buffer; | ||||
|  | @ -917,12 +1017,11 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m | |||
| 	DRIVE_LAYOUT_INFORMATION_EX4 DriveLayoutEx = {0}; | ||||
| 	BOOL r; | ||||
| 	DWORD i, size, bufsize, pn = 0; | ||||
| 	LONGLONG size_in_sectors, extra_part_size_in_tracks = 0; | ||||
| 	BOOL add_msr = FALSE; //TRUE;
 | ||||
| 	LONGLONG main_part_size_in_sectors, extra_part_size_in_tracks = 0; | ||||
| 
 | ||||
| 	PrintInfoDebug(0, MSG_238, PartitionTypeName[partition_style]); | ||||
| 
 | ||||
| 	if (uefi_togo_size == 0) | ||||
| 	if ((extra_partitions & XP_UEFI_TOGO) && (uefi_togo_size == 0)) | ||||
| 		uefi_togo_size = GetResourceSize(hMainInstance, MAKEINTRESOURCEA(IDR_UEFI_TOGO), _RT_RCDATA, "uefi-togo.img"); | ||||
| 
 | ||||
| 	// Compute the start offset of our first partition
 | ||||
|  | @ -936,7 +1035,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m | |||
| 	} | ||||
| 
 | ||||
| 	// If required, set the MSR partition (GPT only - must be created before the data part)
 | ||||
| 	if ((partition_style == PARTITION_STYLE_GPT) && (add_msr)) { | ||||
| 	if ((partition_style == PARTITION_STYLE_GPT) && (extra_partitions & XP_MSR)) { | ||||
| 		uprintf("Adding MSR partition"); | ||||
| 		DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = 128*1024*1024; | ||||
| 		DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_MSFT_RESERVED_GUID; | ||||
|  | @ -948,24 +1047,27 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m | |||
| 	} | ||||
| 
 | ||||
| 	// Set our main data partition
 | ||||
| 	size_in_sectors = (SelectedDrive.DiskSize - DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart) / | ||||
| 	main_part_size_in_sectors = (SelectedDrive.DiskSize - DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart) / | ||||
| 		// Need 33 sectors at the end for secondary GPT
 | ||||
| 		SelectedDrive.Geometry.BytesPerSector - ((partition_style == PARTITION_STYLE_GPT)?33:0); | ||||
| 	// Adjust the size according to extra partitions
 | ||||
| 	if ((add_uefi_togo) || ((partition_style == PARTITION_STYLE_MBR) && (IsChecked(IDC_EXTRA_PARTITION)))) { | ||||
| 		if (add_uefi_togo)	{ | ||||
| 			extra_part_size_in_tracks = (MIN_EXTRA_PART_SIZE + SelectedDrive.Geometry.SectorsPerTrack - 1) / | ||||
| 				SelectedDrive.Geometry.SectorsPerTrack; | ||||
| 	if (extra_partitions) { | ||||
| 		if (extra_partitions & (XP_UEFI_TOGO | XP_EFI)) { | ||||
| 			// TODO: this will explode to 800MB instead of 100MB on 4K sectors...
 | ||||
| 			extra_part_size_in_tracks = ((MIN_EXTRA_PART_SIZE*((extra_partitions & XP_EFI)?100:1)) | ||||
| 				+ SelectedDrive.Geometry.SectorsPerTrack - 1) / SelectedDrive.Geometry.SectorsPerTrack; | ||||
| 		} else { | ||||
| 			extra_part_size_in_tracks = 1;	// One track for the extra part in non togo mode
 | ||||
| 			extra_part_size_in_tracks = 1;	// One track for the extra partition
 | ||||
| 		} | ||||
| 		uprintf("Reserving %d tracks for extra partition", extra_part_size_in_tracks); | ||||
| 		size_in_sectors = ((size_in_sectors / SelectedDrive.Geometry.SectorsPerTrack) - extra_part_size_in_tracks) * | ||||
| 			SelectedDrive.Geometry.SectorsPerTrack; | ||||
| 		if (size_in_sectors <= 0) | ||||
| 		uprintf("Reserving %lld tracks (%s) for extra partition", extra_part_size_in_tracks, | ||||
| 			SizeToHumanReadable(extra_part_size_in_tracks * SelectedDrive.Geometry.SectorsPerTrack * | ||||
| 			SelectedDrive.Geometry.BytesPerSector, TRUE, FALSE)); | ||||
| 		main_part_size_in_sectors = ((main_part_size_in_sectors / SelectedDrive.Geometry.SectorsPerTrack) - | ||||
| 			extra_part_size_in_tracks) * SelectedDrive.Geometry.SectorsPerTrack; | ||||
| 		if (main_part_size_in_sectors <= 0) | ||||
| 			return FALSE; | ||||
| 	} | ||||
| 	DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = size_in_sectors * SelectedDrive.Geometry.BytesPerSector; | ||||
| 	DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = main_part_size_in_sectors * SelectedDrive.Geometry.BytesPerSector; | ||||
| 	if (partition_style == PARTITION_STYLE_MBR) { | ||||
| 		DriveLayoutEx.PartitionEntry[pn].Mbr.BootIndicator = IsChecked(IDC_BOOT); | ||||
| 		DriveLayoutEx.PartitionEntry[pn].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack; | ||||
|  | @ -994,24 +1096,23 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m | |||
| 	pn++; | ||||
| 
 | ||||
| 	// Set the optional extra partition
 | ||||
| 	if (IsChecked(IDC_EXTRA_PARTITION) || (add_uefi_togo)) { | ||||
| 	if (extra_partitions) { | ||||
| 		// Should end on a track boundary
 | ||||
| 		DriveLayoutEx.PartitionEntry[pn].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[pn-1].StartingOffset.QuadPart + | ||||
| 			DriveLayoutEx.PartitionEntry[pn-1].PartitionLength.QuadPart; | ||||
| 		DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = (add_uefi_togo)?uefi_togo_size: | ||||
| 		DriveLayoutEx.PartitionEntry[pn].PartitionLength.QuadPart = (extra_partitions & XP_UEFI_TOGO)?uefi_togo_size: | ||||
| 			extra_part_size_in_tracks * SelectedDrive.Geometry.SectorsPerTrack * SelectedDrive.Geometry.BytesPerSector; | ||||
| 		if (partition_style == PARTITION_STYLE_GPT) { | ||||
| 			if (add_uefi_togo)	// already set to UNUSED GUID (000...000) otherwise
 | ||||
| 				DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_BASIC_DATA_GUID; | ||||
| 			DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionType = PARTITION_SYSTEM_GUID; | ||||
| 			IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[pn].Gpt.PartitionId)); | ||||
| 			wcscpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, (add_uefi_togo)?L"UEFI:TOGO":L"Rufus Extra Partition"); | ||||
| 			wcscpy(DriveLayoutEx.PartitionEntry[pn].Gpt.Name, (extra_partitions & XP_UEFI_TOGO)?L"UEFI:TOGO":L"EFI system partition"); | ||||
| 		} else { | ||||
| 			DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = (add_uefi_togo)?0x01:RUFUS_EXTRA_PARTITION_TYPE; | ||||
| 			DriveLayoutEx.PartitionEntry[pn].Mbr.PartitionType = (extra_partitions & XP_UEFI_TOGO)?0x01:RUFUS_EXTRA_PARTITION_TYPE; | ||||
| 			DriveLayoutEx.PartitionEntry[pn].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack; | ||||
| 		} | ||||
| 
 | ||||
| 		// We need to write the TOGO partition before we refresh the disk
 | ||||
| 		if (add_uefi_togo) { | ||||
| 		if (extra_partitions & XP_UEFI_TOGO) { | ||||
| 			uprintf("Writing UEFI:TOGO partition..."); | ||||
| 			if (!SetFilePointerEx(hDrive, DriveLayoutEx.PartitionEntry[pn].StartingOffset, NULL, FILE_BEGIN)) { | ||||
| 				uprintf("Unable to set position"); | ||||
|  |  | |||
|  | @ -30,6 +30,10 @@ | |||
| #define IOCTL_MOUNTMGR_SET_AUTO_MOUNT       \ | ||||
| 	CTL_CODE(MOUNTMGRCONTROLTYPE, 16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) | ||||
| 
 | ||||
| #define XP_MSR       0x01 | ||||
| #define XP_EFI       0x02 | ||||
| #define XP_UEFI_TOGO 0x04 | ||||
| 
 | ||||
| /* We need a redef of these MS structure */ | ||||
| typedef struct { | ||||
| 	DWORD DeviceType; | ||||
|  | @ -62,8 +66,10 @@ BOOL AnalyzePBR(HANDLE hLogicalVolume); | |||
| BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSystemNameSize, BOOL bSilent); | ||||
| BOOL UnmountVolume(HANDLE hDrive); | ||||
| BOOL MountVolume(char* drive_name, char *drive_guid); | ||||
| BOOL AltUnmountVolume(const char* drive_name); | ||||
| char* AltMountVolume(const char* drive_name, uint8_t part_nr); | ||||
| BOOL RemountVolume(char* drive_name); | ||||
| BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL mbr_uefi_marker, BOOL add_uefi_togo); | ||||
| BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL mbr_uefi_marker, uint8_t extra_partitions); | ||||
| BOOL DeletePartitions(HANDLE hDrive); | ||||
| BOOL RefreshDriveLayout(HANDLE hDrive); | ||||
| const char* GetPartitionType(BYTE Type); | ||||
|  |  | |||
							
								
								
									
										73
									
								
								src/format.c
									
										
									
									
									
								
							
							
						
						
									
										73
									
								
								src/format.c
									
										
									
									
									
								
							|  | @ -1226,15 +1226,24 @@ out: | |||
| } | ||||
| 
 | ||||
| // http://technet.microsoft.com/en-ie/library/jj721578.aspx
 | ||||
| static BOOL SetupWinToGo(const char* drive_name) | ||||
| BOOL SetupWinToGo(const char* drive_name, BOOL use_ms_efi) | ||||
| { | ||||
| 	char san_policy_path[] = "?:\\san_policy.xml", unattend_path[] = "?:\\Windows\\System32\\sysprep\\unattend.xml"; | ||||
| 	char *mounted_iso, image[128], cmd[128]; | ||||
| 	char *mounted_iso, *ms_efi, image[128], cmd[128]; | ||||
| 	wchar_t wVolumeName[] = L"?:"; | ||||
| 	unsigned char *buffer; | ||||
| 	DWORD bufsize; | ||||
| 	FILE* fd; | ||||
| 	PF_DECL(FormatEx); | ||||
| 	PF_INIT(FormatEx, Fmifs); | ||||
| 
 | ||||
| 	uprintf("Windows To Go mode selected"); | ||||
| 	if ((use_ms_efi) && (SelectedDrive.Geometry.MediaType != FixedMedia)) { | ||||
| 		// Arthur's Theme: "♫ I know it's stupid... but it's true. ♫"
 | ||||
| 		uprintf("Cannot set 'Windows To Go' for a GPT target unless it is a fixed drive"); | ||||
| 		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); | ||||
|  | @ -1256,15 +1265,46 @@ static BOOL SetupWinToGo(const char* drive_name) | |||
| 	} | ||||
| 	UnMountISO(); | ||||
| 
 | ||||
| 	uprintf("Setting up boot for Windows To Go..."); | ||||
| 	static_sprintf(cmd, "%C:\\Windows\\System32\\bcdboot.exe %C:\\Windows /f ALL /s %C:", | ||||
| 		drive_name[0], drive_name[0], drive_name[0]); | ||||
| 	if (use_ms_efi) { | ||||
| 		uprintf("Setting up MS EFI system partition"); | ||||
| 		if (pfFormatEx == NULL) | ||||
| 			return FALSE; | ||||
| 		ms_efi = AltMountVolume(drive_name, 3);	// MSR, main, EFI
 | ||||
| 		if (ms_efi == NULL) { | ||||
| 			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_ASSIGN_LETTER); | ||||
| 			return FALSE; | ||||
| 		} | ||||
| 		fs_index = 0; | ||||
| 		task_number = 0; | ||||
| 		wVolumeName[0] = ms_efi[0]; | ||||
| 		// Boy do you *NOT* want to specify a label here, and spend
 | ||||
| 		// HOURS figuring out why your EFI partition cannot boot...
 | ||||
| 		pfFormatEx(wVolumeName, SelectedDrive.Geometry.MediaType, L"FAT32", L"", | ||||
| 			TRUE, 1024, FormatExCallback); | ||||
| 		if (IS_ERROR(FormatStatus)) { | ||||
| 			uprintf("Failed to format EFI partition"); | ||||
| 			AltUnmountVolume(ms_efi); | ||||
| 			return FALSE; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// TODO: Don't use ALL but adjust to what we effectively support
 | ||||
| 	static_sprintf(cmd, "%s\\Windows\\System32\\bcdboot.exe %s\\Windows /f ALL /s %s", | ||||
| 		drive_name, drive_name, (use_ms_efi)?ms_efi:drive_name); | ||||
| 	uprintf("Enabling boot: '%s'", cmd); | ||||
| 	if (RunCommand(cmd, NULL, TRUE) != 0) { | ||||
| 		// Fatal, as the UFD is unlikely to boot then
 | ||||
| 		uprintf("Command '%s' failed to run", cmd); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT); | ||||
| 		if (use_ms_efi)  | ||||
| 			AltUnmountVolume(ms_efi); | ||||
| 		return FALSE; | ||||
| 	} | ||||
| 
 | ||||
| 	if (use_ms_efi) { | ||||
| 		Sleep(200); | ||||
| 		AltUnmountVolume(ms_efi); | ||||
| 	} | ||||
| 	UpdateProgress(OP_DOS, 99.0f); | ||||
| 
 | ||||
| 	// The following are non fatal if they fail
 | ||||
|  | @ -1279,7 +1319,7 @@ static BOOL SetupWinToGo(const char* drive_name) | |||
| 			fclose(fd); | ||||
| 	} else { | ||||
| 		fclose(fd); | ||||
| 		static_sprintf(cmd, "dism /Image:%C:\\ /Apply-Unattend:%s", drive_name[0], san_policy_path); | ||||
| 		static_sprintf(cmd, "dism /Image:%s\\ /Apply-Unattend:%s", drive_name, san_policy_path); | ||||
| 		if (RunCommand(cmd, NULL, TRUE) != 0) | ||||
| 			uprintf("Command '%s' failed to run"); | ||||
| 	} | ||||
|  | @ -1367,7 +1407,7 @@ void update_progress(const uint64_t processed_bytes) | |||
| DWORD WINAPI FormatThread(void* param) | ||||
| { | ||||
| 	int i, r, pt, bt, fs, dt; | ||||
| 	BOOL s, ret, use_large_fat32, add_uefi_togo; | ||||
| 	BOOL s, ret, use_large_fat32, windows_to_go; | ||||
| 	const DWORD SectorSize = SelectedDrive.Geometry.BytesPerSector; | ||||
| 	DWORD rSize, wSize, BufSize, DriveIndex = (DWORD)(uintptr_t)param; | ||||
| 	HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE; | ||||
|  | @ -1377,7 +1417,7 @@ DWORD WINAPI FormatThread(void* param) | |||
| 	FILE* log_fd; | ||||
| 	LARGE_INTEGER li; | ||||
| 	uint64_t wb; | ||||
| 	uint8_t *buffer = NULL, *aligned_buffer; | ||||
| 	uint8_t *buffer = NULL, *aligned_buffer, extra_partitions = 0; | ||||
| 	char *bb_msg, *guid_volume = NULL; | ||||
| 	char drive_name[] = "?:\\"; | ||||
| 	char drive_letters[27]; | ||||
|  | @ -1397,7 +1437,14 @@ DWORD WINAPI FormatThread(void* param) | |||
| 	pt = GETPARTTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme))); | ||||
| 	bt = GETBIOSTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme))); | ||||
| 	use_large_fat32 = (fs == FS_FAT32) && ((SelectedDrive.DiskSize > LARGE_FAT32_SIZE) || (force_large_fat32)); | ||||
| 	add_uefi_togo = (fs == FS_NTFS) && (dt == DT_ISO) && (iso_report.has_efi) && (bt == BT_UEFI); | ||||
| 	windows_to_go = HAS_TOGO(iso_report) && (Button_GetCheck(GetDlgItem(hMainDialog, IDC_WINDOWS_TO_GO)) == BST_CHECKED); | ||||
| 	// Find out if we need to add any extra partitions
 | ||||
| 	if ((windows_to_go) && (bt == BT_UEFI) && (pt == PARTITION_STYLE_GPT)) | ||||
| 		// According to Microsoft, every GPT disk (we RUN Windows from) must have an MSR due to not having hidden sectors
 | ||||
| 		// http://msdn.microsoft.com/en-us/library/windows/hardware/dn640535.aspx#gpt_faq_what_disk_require_msr
 | ||||
| 		extra_partitions = XP_MSR | XP_EFI; | ||||
| 	else if ((fs == FS_NTFS) && (dt == DT_ISO) && (iso_report.has_efi) && ((bt == BT_UEFI) || (windows_to_go))) | ||||
| 		extra_partitions = XP_UEFI_TOGO; | ||||
| 
 | ||||
| 	PrintInfoDebug(0, MSG_225); | ||||
| 	hPhysicalDrive = GetPhysicalHandle(DriveIndex, TRUE, TRUE); | ||||
|  | @ -1636,7 +1683,7 @@ DWORD WINAPI FormatThread(void* param) | |||
| 	UpdateProgress(OP_ZERO_MBR, -1.0f); | ||||
| 	CHECK_FOR_USER_CANCEL; | ||||
| 
 | ||||
| 	if (!CreatePartition(hPhysicalDrive, pt, fs, (pt==PARTITION_STYLE_MBR) && (bt==BT_UEFI), add_uefi_togo)) { | ||||
| 	if (!CreatePartition(hPhysicalDrive, pt, fs, (pt==PARTITION_STYLE_MBR) && (bt==BT_UEFI), extra_partitions)) { | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_PARTITION_FAILURE; | ||||
| 		goto out; | ||||
| 	} | ||||
|  | @ -1765,8 +1812,8 @@ DWORD WINAPI FormatThread(void* param) | |||
| 			if (image_path != NULL) { | ||||
| 				UpdateProgress(OP_DOS, 0.0f); | ||||
| 				PrintInfoDebug(0, MSG_231); | ||||
| 				drive_name[2] = 0; | ||||
| 				if (HAS_TOGO(iso_report) && (Button_GetCheck(GetDlgItem(hMainDialog, IDC_WINDOWS_TO_GO)) == BST_CHECKED)) { | ||||
| 				drive_name[2] = 0;	// Ensure our drive is something like 'D:'
 | ||||
| 				if (windows_to_go) { | ||||
| 					// Sanity checks
 | ||||
| 					if (fs != FS_NTFS) { | ||||
| 						FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_INCOMPATIBLE_FS); | ||||
|  | @ -1776,7 +1823,7 @@ DWORD WINAPI FormatThread(void* param) | |||
| 						FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_SUPPORTED; | ||||
| 						goto out; | ||||
| 					} | ||||
| 					if (!SetupWinToGo(drive_name)) { | ||||
| 					if (!SetupWinToGo(drive_name, (extra_partitions & XP_EFI))) { | ||||
| 						if (!IS_ERROR(FormatStatus)) | ||||
| 							FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT); | ||||
| 						goto out; | ||||
|  |  | |||
							
								
								
									
										16
									
								
								src/rufus.rc
									
										
									
									
									
								
							
							
						
						
									
										16
									
								
								src/rufus.rc
									
										
									
									
									
								
							|  | @ -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.578" | ||||
| CAPTION "Rufus 2.0.0.579" | ||||
| 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.578" | ||||
| CAPTION "Rufus 2.0.0.579" | ||||
| 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.578" | ||||
| CAPTION "Rufus 2.0.0.579" | ||||
| 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.578" | ||||
| CAPTION "Rufus 2.0.0.579" | ||||
| FONT 8, "MS Shell Dlg", 400, 0, 0x1 | ||||
| BEGIN | ||||
|     DEFPUSHBUTTON   "Start",IDC_START,127,339,50,14 | ||||
|  | @ -671,8 +671,8 @@ END | |||
| // | ||||
| 
 | ||||
| VS_VERSION_INFO VERSIONINFO | ||||
|  FILEVERSION 2,0,0,578 | ||||
|  PRODUCTVERSION 2,0,0,578 | ||||
|  FILEVERSION 2,0,0,579 | ||||
|  PRODUCTVERSION 2,0,0,579 | ||||
|  FILEFLAGSMASK 0x3fL | ||||
| #ifdef _DEBUG | ||||
|  FILEFLAGS 0x1L | ||||
|  | @ -689,13 +689,13 @@ BEGIN | |||
|         BEGIN | ||||
|             VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" | ||||
|             VALUE "FileDescription", "Rufus" | ||||
|             VALUE "FileVersion", "2.0.0.578" | ||||
|             VALUE "FileVersion", "2.0.0.579" | ||||
|             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.578" | ||||
|             VALUE "ProductVersion", "2.0.0.579" | ||||
|         END | ||||
|     END | ||||
|     BLOCK "VarFileInfo" | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| /*
 | ||||
|  * Rufus: The Reliable USB Formatting Utility | ||||
|  * Standard User I/O Routines (logging, status, etc.) | ||||
|  * Copyright © 2011-2013 Pete Batard <pete@akeo.ie> | ||||
|  * Copyright © 2011-2015 Pete Batard <pete@akeo.ie> | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue