mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[efi] add Windows 7 EFI support for XP and Vista
* Requires 7-Zip for WIM extraction as wimgapi.dll is not available * Also add more comprehensive choice between MBR/GPT and BIOS/UEFI
This commit is contained in:
		
							parent
							
								
									84e4aecfcd
								
							
						
					
					
						commit
						0196de6f4d
					
				
					 6 changed files with 233 additions and 88 deletions
				
			
		
							
								
								
									
										23
									
								
								src/format.c
									
										
									
									
									
								
							
							
						
						
									
										23
									
								
								src/format.c
									
										
									
									
									
								
							|  | @ -749,7 +749,7 @@ static BOOL ClearMBRGPT(HANDLE hPhysicalDrive, LONGLONG DiskSize, DWORD SectorSi | ||||||
| 	uint64_t i, last_sector = DiskSize/SectorSize; | 	uint64_t i, last_sector = DiskSize/SectorSize; | ||||||
| 	unsigned char* pBuf = (unsigned char*) calloc(SectorSize, 1); | 	unsigned char* pBuf = (unsigned char*) calloc(SectorSize, 1); | ||||||
| 
 | 
 | ||||||
| 	PrintStatus(0, TRUE, "Clearing MBR & GPT structures..."); | 	PrintStatus(0, TRUE, "Clearing MBR/GPT structures..."); | ||||||
| 	if (pBuf == NULL) { | 	if (pBuf == NULL) { | ||||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_ENOUGH_MEMORY; | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_ENOUGH_MEMORY; | ||||||
| 		goto out; | 		goto out; | ||||||
|  | @ -818,7 +818,6 @@ static BOOL WriteMBR(HANDLE hPhysicalDrive) | ||||||
| 
 | 
 | ||||||
| 	// FormatEx rewrites the MBR and removes the LBA attribute of FAT16
 | 	// FormatEx rewrites the MBR and removes the LBA attribute of FAT16
 | ||||||
| 	// and FAT32 partitions - we need to correct this in the MBR
 | 	// and FAT32 partitions - we need to correct this in the MBR
 | ||||||
| 	// TODO: Something else for bootable GPT
 |  | ||||||
| 	buf = (unsigned char*)malloc(SecSize * nSecs); | 	buf = (unsigned char*)malloc(SecSize * nSecs); | ||||||
| 	if (buf == NULL) { | 	if (buf == NULL) { | ||||||
| 		uprintf("Could not allocate memory for MBR"); | 		uprintf("Could not allocate memory for MBR"); | ||||||
|  | @ -1110,10 +1109,7 @@ static BOOL RemountVolume(char drive_letter) | ||||||
|  */ |  */ | ||||||
| DWORD WINAPI FormatThread(LPVOID param) | DWORD WINAPI FormatThread(LPVOID param) | ||||||
| { | { | ||||||
| 	int r; | 	int r, pt, bt, fs, dt; | ||||||
| 	int fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); |  | ||||||
| 	int dt = (int)ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)); |  | ||||||
| 	int pt = (int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme)); |  | ||||||
| 	BOOL ret; | 	BOOL ret; | ||||||
| 	DWORD num = (DWORD)(uintptr_t)param; | 	DWORD num = (DWORD)(uintptr_t)param; | ||||||
| 	HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE; | 	HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE; | ||||||
|  | @ -1126,6 +1122,11 @@ DWORD WINAPI FormatThread(LPVOID param) | ||||||
| 	char efi_dst[] = "?:\\efi\\boot\\bootx64.efi"; | 	char efi_dst[] = "?:\\efi\\boot\\bootx64.efi"; | ||||||
| 	FILE* log_fd; | 	FILE* log_fd; | ||||||
| 
 | 
 | ||||||
|  | 	fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); | ||||||
|  | 	dt = (int)ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)); | ||||||
|  | 	pt = GETPARTTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme))); | ||||||
|  | 	bt = GETBIOSTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme))); | ||||||
|  | 
 | ||||||
| 	hPhysicalDrive = GetDriveHandle(num, NULL, TRUE, TRUE); | 	hPhysicalDrive = GetDriveHandle(num, NULL, TRUE, TRUE); | ||||||
| 	if (hPhysicalDrive == INVALID_HANDLE_VALUE) { | 	if (hPhysicalDrive == INVALID_HANDLE_VALUE) { | ||||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; | ||||||
|  | @ -1239,7 +1240,7 @@ DWORD WINAPI FormatThread(LPVOID param) | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (pt == PT_MBR) { | 	if (pt == PARTITION_STYLE_MBR) { | ||||||
| 		PrintStatus(0, TRUE, "Writing master boot record..."); | 		PrintStatus(0, TRUE, "Writing master boot record..."); | ||||||
| 		if (!WriteMBR(hPhysicalDrive)) { | 		if (!WriteMBR(hPhysicalDrive)) { | ||||||
| 			if (!FormatStatus) | 			if (!FormatStatus) | ||||||
|  | @ -1250,7 +1251,7 @@ DWORD WINAPI FormatThread(LPVOID param) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (IsChecked(IDC_DOS)) { | 	if (IsChecked(IDC_DOS)) { | ||||||
| 		if (pt == PT_GPT) { | 		if (bt == BT_UEFI) { | ||||||
| 			// For once, no need to do anything - just check our sanity
 | 			// For once, no need to do anything - just check our sanity
 | ||||||
| 			if ( (dt != DT_ISO) || (!IS_EFI(iso_report)) || (fs > FS_FAT32) ) { | 			if ( (dt != DT_ISO) || (!IS_EFI(iso_report)) || (fs > FS_FAT32) ) { | ||||||
| 				uprintf("Spock gone crazy error!\n"); | 				uprintf("Spock gone crazy error!\n"); | ||||||
|  | @ -1312,7 +1313,7 @@ DWORD WINAPI FormatThread(LPVOID param) | ||||||
| 						FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANNOT_COPY; | 						FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANNOT_COPY; | ||||||
| 					goto out; | 					goto out; | ||||||
| 				} | 				} | ||||||
| 				if ((pt == PT_GPT) && (!iso_report.has_efi) && (iso_report.has_win7_efi)) { | 				if ((bt == BT_UEFI) && (!iso_report.has_efi) && (iso_report.has_win7_efi)) { | ||||||
| 					// TODO: progress
 | 					// TODO: progress
 | ||||||
| 					PrintStatus(0, TRUE, "Win7 EFI boot setup (this may take a while)..."); | 					PrintStatus(0, TRUE, "Win7 EFI boot setup (this may take a while)..."); | ||||||
| 					wim_image[0] = drive_name[0]; | 					wim_image[0] = drive_name[0]; | ||||||
|  | @ -1323,14 +1324,14 @@ DWORD WINAPI FormatThread(LPVOID param) | ||||||
| 						FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH); | 						FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH); | ||||||
| 					} else { | 					} else { | ||||||
| 						efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = '\\'; | 						efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = '\\'; | ||||||
| 						if (!WIMExtractFile(wim_image, 1, "Windows\\Boot\\EFI\\bootmgfw.efi", efi_dst)) { | 						if (!WimExtractFile(wim_image, 1, "Windows\\Boot\\EFI\\bootmgfw.efi", efi_dst)) { | ||||||
| 							uprintf("Failed to setup Win7 EFI boot\n"); | 							uprintf("Failed to setup Win7 EFI boot\n"); | ||||||
| 							FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH); | 							FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH); | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			if ( (pt == PT_MBR) && (IS_WINPE(iso_report.winpe)) ) { | 			if ( (bt == BT_BIOS) && (IS_WINPE(iso_report.winpe)) ) { | ||||||
| 				// Apply WinPe fixup
 | 				// Apply WinPe fixup
 | ||||||
| 				if (!SetupWinPE(drive_name[0])) | 				if (!SetupWinPE(drive_name[0])) | ||||||
| 					FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH); | 					FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH); | ||||||
|  |  | ||||||
|  | @ -57,24 +57,39 @@ static __inline BOOL DeleteRegistryKey(const char* key_name) | ||||||
| 	return ((s == ERROR_SUCCESS) || (s == ERROR_FILE_NOT_FOUND)); | 	return ((s == ERROR_SUCCESS) || (s == ERROR_FILE_NOT_FOUND)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Read a generic registry key value (create the key if it doesn't exist) */ | /* Read a generic registry key value. If a short key_name is used, assume that it belongs to
 | ||||||
|  |    the application and create the app subkey if required */ | ||||||
| static __inline BOOL _GetRegistryKey(const char* key_name, DWORD reg_type, LPBYTE dest, DWORD dest_size) | static __inline BOOL _GetRegistryKey(const char* key_name, DWORD reg_type, LPBYTE dest, DWORD dest_size) | ||||||
| { | { | ||||||
| 	BOOL r = FALSE; | 	BOOL r = FALSE; | ||||||
|  | 	size_t i = 0; | ||||||
| 	LONG s; | 	LONG s; | ||||||
| 	HKEY hSoftware = NULL, hApp = NULL; | 	HKEY hSoftware = NULL, hApp = NULL; | ||||||
| 	DWORD dwDisp, dwType = -1, dwSize = dest_size; | 	DWORD dwDisp, dwType = -1, dwSize = dest_size; | ||||||
|  | 	char long_key_name[256] = "SOFTWARE\\"; | ||||||
| 	memset(dest, 0, dest_size); | 	memset(dest, 0, dest_size); | ||||||
| 
 | 
 | ||||||
|  | 	for (i=safe_strlen(key_name); i>0; i--) { | ||||||
|  | 		if (key_name[i] == '\\') | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (i != 0) { | ||||||
|  | 		safe_strcat(long_key_name, sizeof(long_key_name), key_name); | ||||||
|  | 		long_key_name[sizeof("SOFTWARE\\") + i-1] = 0; | ||||||
|  | 		i++; | ||||||
|  | 		if (RegOpenKeyExA(HKEY_CURRENT_USER, long_key_name, 0, KEY_READ, &hApp) != ERROR_SUCCESS) | ||||||
|  | 			goto out; | ||||||
|  | 	} else { | ||||||
| 		if ( (RegOpenKeyExA(HKEY_CURRENT_USER, "SOFTWARE", 0, KEY_READ|KEY_CREATE_SUB_KEY, &hSoftware) != ERROR_SUCCESS) | 		if ( (RegOpenKeyExA(HKEY_CURRENT_USER, "SOFTWARE", 0, KEY_READ|KEY_CREATE_SUB_KEY, &hSoftware) != ERROR_SUCCESS) | ||||||
| 			 || (RegCreateKeyExA(hSoftware, COMPANY_NAME "\\" APPLICATION_NAME, 0, NULL, 0, | 			 || (RegCreateKeyExA(hSoftware, COMPANY_NAME "\\" APPLICATION_NAME, 0, NULL, 0, | ||||||
| 		KEY_SET_VALUE|KEY_QUERY_VALUE|KEY_CREATE_SUB_KEY, NULL, &hApp, &dwDisp) != ERROR_SUCCESS) ) { | 				KEY_SET_VALUE|KEY_QUERY_VALUE|KEY_CREATE_SUB_KEY, NULL, &hApp, &dwDisp) != ERROR_SUCCESS) ) | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	s = RegQueryValueExA(hApp, key_name, NULL, &dwType, (LPBYTE)dest, &dwSize); | 	s = RegQueryValueExA(hApp, &key_name[i], NULL, &dwType, (LPBYTE)dest, &dwSize); | ||||||
| 	// No key means default value of 0 or empty string
 | 	// No key means default value of 0 or empty string
 | ||||||
| 	if ((s == ERROR_FILE_NOT_FOUND) || ((s == ERROR_SUCCESS) && (dwType = reg_type) && (dwSize = dest_size))) { | 	if ((s == ERROR_FILE_NOT_FOUND) || ((s == ERROR_SUCCESS) && (dwType = reg_type) && (dwSize > 0))) { | ||||||
| 		r = TRUE; | 		r = TRUE; | ||||||
| 	} | 	} | ||||||
| out: | out: | ||||||
|  |  | ||||||
							
								
								
									
										113
									
								
								src/rufus.c
									
										
									
									
									
								
							
							
						
						
									
										113
									
								
								src/rufus.c
									
										
									
									
									
								
							|  | @ -86,7 +86,8 @@ static const char* FileSystemLabel[FS_MAX] = { "FAT", "FAT32", "NTFS", "exFAT" } | ||||||
| static const char* ClusterSizeLabel[] = { "512 bytes", "1024 bytes","2048 bytes","4096 bytes","8192 bytes", | static const char* ClusterSizeLabel[] = { "512 bytes", "1024 bytes","2048 bytes","4096 bytes","8192 bytes", | ||||||
| 	"16 kilobytes", "32 kilobytes", "64 kilobytes", "128 kilobytes", "256 kilobytes", "512 kilobytes", | 	"16 kilobytes", "32 kilobytes", "64 kilobytes", "128 kilobytes", "256 kilobytes", "512 kilobytes", | ||||||
| 	"1024 kilobytes","2048 kilobytes","4096 kilobytes","8192 kilobytes","16 megabytes","32 megabytes" }; | 	"1024 kilobytes","2048 kilobytes","4096 kilobytes","8192 kilobytes","16 megabytes","32 megabytes" }; | ||||||
| static const char* PartitionSchemeName[PT_MAX] = { "MBR", "GPT" }; | static const char* BiosTypeName[BT_MAX] = { "BIOS", "UEFI" }; | ||||||
|  | static const char* PartitionTypeName[2] = { "MBR", "GPT" }; | ||||||
| static BOOL existing_key = FALSE;	// For LGP set/restore
 | static BOOL existing_key = FALSE;	// For LGP set/restore
 | ||||||
| static BOOL iso_size_check = TRUE; | static BOOL iso_size_check = TRUE; | ||||||
| static BOOL log_displayed = FALSE; | static BOOL log_displayed = FALSE; | ||||||
|  | @ -350,7 +351,7 @@ static __inline char* size_to_hr(LARGE_INTEGER size) | ||||||
| /*
 | /*
 | ||||||
|  * Fill the drive properties (size, FS, etc) |  * Fill the drive properties (size, FS, etc) | ||||||
|  */ |  */ | ||||||
| static BOOL GetDriveInfo(void) | static BOOL GetDriveInfo(DWORD DeviceNumber) | ||||||
| { | { | ||||||
| 	BOOL r; | 	BOOL r; | ||||||
| 	HANDLE hDrive; | 	HANDLE hDrive; | ||||||
|  | @ -363,7 +364,8 @@ static BOOL GetDriveInfo(void) | ||||||
| 	char DrivePath[] = "#:\\", tmp[256], fs_type[32]; | 	char DrivePath[] = "#:\\", tmp[256], fs_type[32]; | ||||||
| 	DWORD i, nb_partitions = 0; | 	DWORD i, nb_partitions = 0; | ||||||
| 
 | 
 | ||||||
| 	SelectedDrive.DiskSize = 0; | 	memset(&SelectedDrive, 0, sizeof(SelectedDrive)); | ||||||
|  | 	SelectedDrive.DeviceNumber = DeviceNumber; | ||||||
| 
 | 
 | ||||||
| 	hDrive = GetDriveHandle(SelectedDrive.DeviceNumber, DrivePath, FALSE, FALSE); | 	hDrive = GetDriveHandle(SelectedDrive.DeviceNumber, DrivePath, FALSE, FALSE); | ||||||
| 	if (hDrive == INVALID_HANDLE_VALUE) | 	if (hDrive == INVALID_HANDLE_VALUE) | ||||||
|  | @ -389,7 +391,7 @@ static BOOL GetDriveInfo(void) | ||||||
| 	} else { | 	} else { | ||||||
| 		switch (DriveLayout->PartitionStyle) { | 		switch (DriveLayout->PartitionStyle) { | ||||||
| 		case PARTITION_STYLE_MBR: | 		case PARTITION_STYLE_MBR: | ||||||
| 			SelectedDrive.PartitionType = PT_MBR; | 			SelectedDrive.PartitionType = PARTITION_STYLE_MBR; | ||||||
| 			for (i=0; i<DriveLayout->PartitionCount; i++) { | 			for (i=0; i<DriveLayout->PartitionCount; i++) { | ||||||
| 				if (DriveLayout->PartitionEntry[i].Mbr.PartitionType != PARTITION_ENTRY_UNUSED) { | 				if (DriveLayout->PartitionEntry[i].Mbr.PartitionType != PARTITION_ENTRY_UNUSED) { | ||||||
| 					nb_partitions++; | 					nb_partitions++; | ||||||
|  | @ -406,11 +408,13 @@ static BOOL GetDriveInfo(void) | ||||||
| 						DriveLayout->PartitionEntry[i].PartitionLength, DriveLayout->PartitionEntry[i].Mbr.HiddenSectors, | 						DriveLayout->PartitionEntry[i].PartitionLength, DriveLayout->PartitionEntry[i].Mbr.HiddenSectors, | ||||||
| 						DriveLayout->PartitionEntry[i].Mbr.BootIndicator?"Yes":"No", | 						DriveLayout->PartitionEntry[i].Mbr.BootIndicator?"Yes":"No", | ||||||
| 						DriveLayout->PartitionEntry[i].Mbr.RecognizedPartition?"Yes":"No"); | 						DriveLayout->PartitionEntry[i].Mbr.RecognizedPartition?"Yes":"No"); | ||||||
|  | 					if (part_type == 0xee)	// Flag a protective MBR for non GPT platforms (XP)
 | ||||||
|  | 						SelectedDrive.has_protective_mbr = TRUE; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
| 		case PARTITION_STYLE_GPT: | 		case PARTITION_STYLE_GPT: | ||||||
| 			SelectedDrive.PartitionType = PT_GPT; | 			SelectedDrive.PartitionType = PARTITION_STYLE_GPT; | ||||||
| 			uprintf("Partition type: GPT, NB Partitions: %d\n", DriveLayout->PartitionCount); | 			uprintf("Partition type: GPT, NB Partitions: %d\n", DriveLayout->PartitionCount); | ||||||
| 			uprintf("Disk GUID: %s\n", GuidToString(&DriveLayout->Gpt.DiskId)); | 			uprintf("Disk GUID: %s\n", GuidToString(&DriveLayout->Gpt.DiskId)); | ||||||
| 			uprintf("Max parts: %d, Start Offset: %lld, Usable = %lld bytes\n", | 			uprintf("Max parts: %d, Start Offset: %lld, Usable = %lld bytes\n", | ||||||
|  | @ -428,7 +432,7 @@ static BOOL GetDriveInfo(void) | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
| 		default: | 		default: | ||||||
| 			SelectedDrive.PartitionType = PT_MBR; | 			SelectedDrive.PartitionType = PARTITION_STYLE_MBR; | ||||||
| 			uprintf("Partition type: RAW\n"); | 			uprintf("Partition type: RAW\n"); | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
|  | @ -480,6 +484,7 @@ static void SetFSFromISO(void) | ||||||
| { | { | ||||||
| 	int i, fs, selected_fs = FS_UNKNOWN; | 	int i, fs, selected_fs = FS_UNKNOWN; | ||||||
| 	uint32_t fs_mask = 0; | 	uint32_t fs_mask = 0; | ||||||
|  | 	int bt = GETBIOSTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme))); | ||||||
| 
 | 
 | ||||||
| 	if (iso_path == NULL) | 	if (iso_path == NULL) | ||||||
| 		return; | 		return; | ||||||
|  | @ -490,8 +495,8 @@ static void SetFSFromISO(void) | ||||||
| 		fs_mask |= 1<<fs; | 		fs_mask |= 1<<fs; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Syslinux and EFI have precedence over bootmgr
 | 	// Syslinux and EFI have precedence over bootmgr (unless the user selected BIOS as target type)
 | ||||||
| 	if ((iso_report.has_isolinux) || (IS_EFI(iso_report))) { | 	if ((iso_report.has_isolinux) || ( (IS_EFI(iso_report)) && (bt == BT_UEFI))) { | ||||||
| 		if (fs_mask & (1<<FS_FAT32)) { | 		if (fs_mask & (1<<FS_FAT32)) { | ||||||
| 			selected_fs = FS_FAT32; | 			selected_fs = FS_FAT32; | ||||||
| 		} else if (fs_mask & (1<<FS_FAT16)) { | 		} else if (fs_mask & (1<<FS_FAT16)) { | ||||||
|  | @ -549,7 +554,7 @@ static BOOL PopulateProperties(int ComboIndex) | ||||||
| 	char capacity[64]; | 	char capacity[64]; | ||||||
| 	static char* suffix[] = { "B", "KB", "MB", "GB", "TB", "PB"}; | 	static char* suffix[] = { "B", "KB", "MB", "GB", "TB", "PB"}; | ||||||
| 	char no_label[] = STR_NO_LABEL; | 	char no_label[] = STR_NO_LABEL; | ||||||
| 	int i, j, fs; | 	int i, j, pt, bt, fs; | ||||||
| 
 | 
 | ||||||
| 	IGNORE_RETVAL(ComboBox_ResetContent(hPartitionScheme)); | 	IGNORE_RETVAL(ComboBox_ResetContent(hPartitionScheme)); | ||||||
| 	IGNORE_RETVAL(ComboBox_ResetContent(hFileSystem)); | 	IGNORE_RETVAL(ComboBox_ResetContent(hFileSystem)); | ||||||
|  | @ -561,8 +566,7 @@ static BOOL PopulateProperties(int ComboIndex) | ||||||
| 	if (ComboIndex < 0) | 	if (ComboIndex < 0) | ||||||
| 		return TRUE; | 		return TRUE; | ||||||
| 
 | 
 | ||||||
| 	SelectedDrive.DeviceNumber = (DWORD)ComboBox_GetItemData(hDeviceList, ComboIndex); | 	if (!GetDriveInfo((DWORD)ComboBox_GetItemData(hDeviceList, ComboIndex)))	// This also populates FS
 | ||||||
| 	if (!GetDriveInfo())	// This also populates FS
 |  | ||||||
| 		return FALSE; | 		return FALSE; | ||||||
| 	SetFSFromISO(); | 	SetFSFromISO(); | ||||||
| 	fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); | 	fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); | ||||||
|  | @ -572,17 +576,31 @@ static BOOL PopulateProperties(int ComboIndex) | ||||||
| 	for (i=1; i<ARRAYSIZE(suffix); i++) { | 	for (i=1; i<ARRAYSIZE(suffix); i++) { | ||||||
| 		HumanReadableSize /= 1024.0; | 		HumanReadableSize /= 1024.0; | ||||||
| 		if (HumanReadableSize < 512.0) { | 		if (HumanReadableSize < 512.0) { | ||||||
| 			for (j=0; j<PT_MAX; j++) { | 			for (j=0; j<3; j++) { | ||||||
| 				safe_sprintf(capacity, sizeof(capacity), "%s (1 Partition of %0.2f %s)", | 				// Populate BIOS/MBR, UEFI/MBR and UEFI/GPT targets, with an exception
 | ||||||
| 					PartitionSchemeName[j], HumanReadableSize, suffix[i]); | 				// for XP, as it doesn't support GPT at all
 | ||||||
| 				IGNORE_RETVAL(ComboBox_SetItemData(hPartitionScheme, ComboBox_AddStringU(hPartitionScheme, capacity), j)); | 				if ((j == 2) && (nWindowsVersion <= WINDOWS_XP)) | ||||||
|  | 					continue; | ||||||
|  | 				bt = (j==0)?BT_BIOS:BT_UEFI; | ||||||
|  | 				pt = (j==2)?PARTITION_STYLE_GPT:PARTITION_STYLE_MBR; | ||||||
|  | 				safe_sprintf(capacity, sizeof(capacity), "%s/%s (1 Partition of %0.2f %s)", | ||||||
|  | 					PartitionTypeName[pt], BiosTypeName[bt], HumanReadableSize, suffix[i]); | ||||||
|  | 				IGNORE_RETVAL(ComboBox_SetItemData(hPartitionScheme, ComboBox_AddStringU(hPartitionScheme, capacity), (bt<<16)|pt)); | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if (i >= ARRAYSIZE(suffix)) | 	if (i >= ARRAYSIZE(suffix)) | ||||||
| 		uprintf("Could not populate partition scheme data\n"); | 		uprintf("Could not populate partition scheme data\n"); | ||||||
| 	IGNORE_RETVAL(ComboBox_SetCurSel(hPartitionScheme, SelectedDrive.PartitionType)); | 	if (SelectedDrive.PartitionType == PARTITION_STYLE_GPT) { | ||||||
|  | 		j = 2; | ||||||
|  | 	} else if (SelectedDrive.has_protective_mbr) { | ||||||
|  | 		j = 1; | ||||||
|  | 	} else { | ||||||
|  | 		j = 0; | ||||||
|  | 	} | ||||||
|  | 	IGNORE_RETVAL(ComboBox_SetCurSel(hPartitionScheme, j)); | ||||||
|  | 	// TODO: create a tooltip for hPartitionScheme
 | ||||||
| 	CreateTooltip(hDeviceList, DriveID.Table[ComboIndex], -1); | 	CreateTooltip(hDeviceList, DriveID.Table[ComboIndex], -1); | ||||||
| 
 | 
 | ||||||
| 	// Set a proposed label according to the size (eg: "256MB", "8GB")
 | 	// Set a proposed label according to the size (eg: "256MB", "8GB")
 | ||||||
|  | @ -638,11 +656,11 @@ BOOL CreatePartition(HANDLE hDrive) | ||||||
| 	BOOL r; | 	BOOL r; | ||||||
| 	DWORD size; | 	DWORD size; | ||||||
| 	LONGLONG size_in_sectors; | 	LONGLONG size_in_sectors; | ||||||
| 	int pt = (int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme)); | 	int pt = GETPARTTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme))); | ||||||
| 
 | 
 | ||||||
| 	PrintStatus(0, TRUE, "Partitioning (%s)...",  PartitionSchemeName[pt]); | 	PrintStatus(0, TRUE, "Partitioning (%s)...",  PartitionTypeName[pt]); | ||||||
| 
 | 
 | ||||||
| 	if ((pt == PT_GPT) || (!IsChecked(IDC_EXTRA_PARTITION))) { | 	if ((pt == PARTITION_STYLE_GPT) || (!IsChecked(IDC_EXTRA_PARTITION))) { | ||||||
| 		// Go with the MS 1 MB wastage at the beginning...
 | 		// Go with the MS 1 MB wastage at the beginning...
 | ||||||
| 		DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart = 1024*1024; | 		DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart = 1024*1024; | ||||||
| 	} else { | 	} else { | ||||||
|  | @ -653,7 +671,7 @@ BOOL CreatePartition(HANDLE hDrive) | ||||||
| 	size_in_sectors = (SelectedDrive.DiskSize - DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart) / SelectedDrive.Geometry.BytesPerSector; | 	size_in_sectors = (SelectedDrive.DiskSize - DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart) / SelectedDrive.Geometry.BytesPerSector; | ||||||
| 
 | 
 | ||||||
| 	switch (pt) { | 	switch (pt) { | ||||||
| 	case PT_MBR: | 	case PARTITION_STYLE_MBR: | ||||||
| 		CreateDisk.PartitionStyle = PARTITION_STYLE_MBR; | 		CreateDisk.PartitionStyle = PARTITION_STYLE_MBR; | ||||||
| 		CreateDisk.Mbr.Signature = GetTickCount(); | 		CreateDisk.Mbr.Signature = GetTickCount(); | ||||||
| 
 | 
 | ||||||
|  | @ -672,7 +690,7 @@ BOOL CreatePartition(HANDLE hDrive) | ||||||
| 				return FALSE; | 				return FALSE; | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 	case PT_GPT: | 	case PARTITION_STYLE_GPT: | ||||||
| 		CreateDisk.PartitionStyle = PARTITION_STYLE_GPT; | 		CreateDisk.PartitionStyle = PARTITION_STYLE_GPT; | ||||||
| 		IGNORE_RETVAL(CoCreateGuid(&CreateDisk.Gpt.DiskId)); | 		IGNORE_RETVAL(CoCreateGuid(&CreateDisk.Gpt.DiskId)); | ||||||
| 		CreateDisk.Gpt.MaxPartitionCount = MAX_GPT_PARTITIONS; | 		CreateDisk.Gpt.MaxPartitionCount = MAX_GPT_PARTITIONS; | ||||||
|  | @ -698,7 +716,7 @@ BOOL CreatePartition(HANDLE hDrive) | ||||||
| 	DriveLayoutEx.PartitionEntry[0].RewritePartition = TRUE; | 	DriveLayoutEx.PartitionEntry[0].RewritePartition = TRUE; | ||||||
| 
 | 
 | ||||||
| 	switch (pt) { | 	switch (pt) { | ||||||
| 	case PT_MBR: | 	case PARTITION_STYLE_MBR: | ||||||
| 		DriveLayoutEx.PartitionEntry[0].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack; | 		DriveLayoutEx.PartitionEntry[0].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack; | ||||||
| 		switch (ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem))) { | 		switch (ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem))) { | ||||||
| 		case FS_FAT16: | 		case FS_FAT16: | ||||||
|  | @ -730,7 +748,7 @@ BOOL CreatePartition(HANDLE hDrive) | ||||||
| 		// For the remaining partitions, PartitionStyle & PartitionType have already
 | 		// For the remaining partitions, PartitionStyle & PartitionType have already
 | ||||||
| 		// been zeroed => already set to MBR/unused
 | 		// been zeroed => already set to MBR/unused
 | ||||||
| 		break; | 		break; | ||||||
| 	case PT_GPT: | 	case PARTITION_STYLE_GPT: | ||||||
| 		DriveLayoutEx.PartitionEntry[0].Gpt.PartitionType = PARTITION_BASIC_DATA_GUID; | 		DriveLayoutEx.PartitionEntry[0].Gpt.PartitionType = PARTITION_BASIC_DATA_GUID; | ||||||
| 		wcscpy(DriveLayoutEx.PartitionEntry[0].Gpt.Name, L"Microsoft Basic Data"); | 		wcscpy(DriveLayoutEx.PartitionEntry[0].Gpt.Name, L"Microsoft Basic Data"); | ||||||
| 		IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[0].Gpt.PartitionId)); | 		IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[0].Gpt.PartitionId)); | ||||||
|  | @ -749,7 +767,7 @@ BOOL CreatePartition(HANDLE hDrive) | ||||||
| 		return FALSE; | 		return FALSE; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	size = sizeof(DriveLayoutEx) - ((pt == PT_GPT)?(3*sizeof(PARTITION_INFORMATION_EX)):0); | 	size = sizeof(DriveLayoutEx) - ((pt == PARTITION_STYLE_GPT)?(3*sizeof(PARTITION_INFORMATION_EX)):0); | ||||||
| 	r = DeviceIoControl(hDrive, IOCTL_DISK_SET_DRIVE_LAYOUT_EX, | 	r = DeviceIoControl(hDrive, IOCTL_DISK_SET_DRIVE_LAYOUT_EX, | ||||||
| 			(BYTE*)&DriveLayoutEx, size, NULL, 0, &size, NULL ); | 			(BYTE*)&DriveLayoutEx, size, NULL, 0, &size, NULL ); | ||||||
| 	if (!r) { | 	if (!r) { | ||||||
|  | @ -1241,10 +1259,6 @@ BOOL CALLBACK LogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| //	case WM_SHOWWINDOW:
 |  | ||||||
| //		if (wParam)
 |  | ||||||
| //			SendMessage(hLog, EM_LINESCROLL, 0, SendMessage(hLog, EM_GETLINECOUNT, 0, 0));
 |  | ||||||
| //		return FALSE;
 |  | ||||||
| 	case WM_CLOSE: | 	case WM_CLOSE: | ||||||
| 		ShowWindow(hDlg, SW_HIDE); | 		ShowWindow(hDlg, SW_HIDE); | ||||||
| 		log_displayed = FALSE; | 		log_displayed = FALSE; | ||||||
|  | @ -1637,7 +1651,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 	DRAWITEMSTRUCT* pDI; | 	DRAWITEMSTRUCT* pDI; | ||||||
| 	POINT Point; | 	POINT Point; | ||||||
| 	RECT DialogRect, DesktopRect; | 	RECT DialogRect, DesktopRect; | ||||||
| 	int nDeviceIndex, fs, pt, i, nWidth, nHeight; | 	int nDeviceIndex, fs, bt, i, nWidth, nHeight; | ||||||
| 	static DWORD DeviceNum = 0; | 	static DWORD DeviceNum = 0; | ||||||
| 	wchar_t wtmp[128], wstr[MAX_PATH]; | 	wchar_t wtmp[128], wstr[MAX_PATH]; | ||||||
| 	static UINT uDOSChecked = BST_CHECKED, uQFChecked; | 	static UINT uDOSChecked = BST_CHECKED, uQFChecked; | ||||||
|  | @ -1787,7 +1801,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 			if (HIWORD(wParam) != CBN_SELCHANGE) | 			if (HIWORD(wParam) != CBN_SELCHANGE) | ||||||
| 				break; | 				break; | ||||||
| 			fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); | 			fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); | ||||||
| 			pt = (int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme)); | 			bt = GETBIOSTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme))); | ||||||
| 			SetClusterSizes(fs); | 			SetClusterSizes(fs); | ||||||
| 			// Disable/restore the quick format control depending on large FAT32
 | 			// Disable/restore the quick format control depending on large FAT32
 | ||||||
| 			if ((fs == FS_FAT32) && (SelectedDrive.DiskSize > LARGE_FAT32_SIZE)) { | 			if ((fs == FS_FAT32) && (SelectedDrive.DiskSize > LARGE_FAT32_SIZE)) { | ||||||
|  | @ -1812,7 +1826,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| 			if ((fs == FS_EXFAT) || ((pt == PT_GPT) && (fs == FS_NTFS)))  { | 			if (fs == FS_EXFAT) { | ||||||
| 				if (IsWindowEnabled(hDOS)) { | 				if (IsWindowEnabled(hDOS)) { | ||||||
| 					// unlikely to be supported by BIOSes => don't bother
 | 					// unlikely to be supported by BIOSes => don't bother
 | ||||||
| 					IGNORE_RETVAL(ComboBox_SetCurSel(hDOSType, 0)); | 					IGNORE_RETVAL(ComboBox_SetCurSel(hDOSType, 0)); | ||||||
|  | @ -1824,13 +1838,13 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| 			IGNORE_RETVAL(ComboBox_ResetContent(hDOSType)); | 			IGNORE_RETVAL(ComboBox_ResetContent(hDOSType)); | ||||||
| 			if ((pt == PT_MBR) && ((fs == FS_FAT16) || (fs == FS_FAT32))) { | 			if ((bt == BT_BIOS) && ((fs == FS_FAT16) || (fs == FS_FAT32))) { | ||||||
| 				IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "MS-DOS"), DT_WINME)); | 				IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "MS-DOS"), DT_WINME)); | ||||||
| 				IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "FreeDOS"), DT_FREEDOS)); | 				IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "FreeDOS"), DT_FREEDOS)); | ||||||
| 			} | 			} | ||||||
| 			IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "ISO Image"), DT_ISO)); | 			IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "ISO Image"), DT_ISO)); | ||||||
| 			// If needed (advanced mode) also append a Syslinux option
 | 			// If needed (advanced mode) also append a Syslinux option
 | ||||||
| 			if ( (pt == PT_MBR) && (((fs == FS_FAT16) || (fs == FS_FAT32)) && (advanced_mode)) ) | 			if ( (bt == BT_BIOS) && (((fs == FS_FAT16) || (fs == FS_FAT32)) && (advanced_mode)) ) | ||||||
| 				IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "SysLinux"), DT_SYSLINUX)); | 				IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "SysLinux"), DT_SYSLINUX)); | ||||||
| 			if ( ((!advanced_mode) && (selection_default == DT_SYSLINUX)) ) { | 			if ( ((!advanced_mode) && (selection_default == DT_SYSLINUX)) ) { | ||||||
| 				selection_default = DT_FREEDOS; | 				selection_default = DT_FREEDOS; | ||||||
|  | @ -1923,24 +1937,37 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 							break; | 							break; | ||||||
| 						} | 						} | ||||||
| 						fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); | 						fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); | ||||||
| 						pt = (int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme)); | 						bt = GETBIOSTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme))); | ||||||
| 						if ((pt == PT_GPT) && ((!IS_EFI(iso_report)) || ((fs > FS_FAT32)))) { | 						if (bt == BT_UEFI) { | ||||||
| 							MessageBoxA(hMainDialog, "When using GPT, only EFI bootable ISOs are supported. " | 							if (!IS_EFI(iso_report)) { | ||||||
| 								"Please select an EFI bootable ISO or change the Partition Scheme to MBR.", "Unsupported GPT ISO...", MB_OK|MB_ICONERROR); | 								MessageBoxA(hMainDialog, "When using UEFI Target Type, only EFI bootable ISO images are supported. " | ||||||
|  | 									"Please select an EFI bootable ISO or set the Target Type to BIOS.", "Unsupported ISO...", MB_OK|MB_ICONERROR); | ||||||
|  | 								break; | ||||||
|  | 							} else if (fs > FS_FAT32) { | ||||||
|  | 								MessageBoxA(hMainDialog, "When using UEFI Target Type, only FAT/FAT32 is supported. " | ||||||
|  | 									"Please select FAT/FAT32 as the File system or set the Target Type to BIOS.", "Unsupported filesystem...", MB_OK|MB_ICONERROR); | ||||||
| 								break; | 								break; | ||||||
| 							} | 							} | ||||||
| 						else if ((fs == FS_NTFS) && (!iso_report.has_bootmgr) && (!IS_WINPE(iso_report.winpe))) { | 						} else if ((fs == FS_NTFS) && (!iso_report.has_bootmgr) && (!IS_WINPE(iso_report.winpe))) { | ||||||
| 							if (iso_report.has_isolinux) { | 							if (iso_report.has_isolinux) { | ||||||
| 								MessageBoxA(hMainDialog, "Only FAT32 is supported for this type of ISO. " | 								MessageBoxA(hMainDialog, "Only FAT/FAT32 is supported for this type of ISO. " | ||||||
| 									"Please revert the filesystem back from NTFS to FAT32.", "Unsupported filesystem...", MB_OK|MB_ICONERROR); | 									"Please select FAT/FAT32 as the File system.", "Unsupported filesystem...", MB_OK|MB_ICONERROR); | ||||||
| 							} else { | 							} else { | ||||||
| 								MessageBoxA(hMainDialog, "Only 'bootmgr' or 'WinPE' based ISO " | 								MessageBoxA(hMainDialog, "Only 'bootmgr' or 'WinPE' based ISO " | ||||||
| 									"images can currently be used with NTFS.", "Unsupported ISO...", MB_OK|MB_ICONERROR); | 									"images can currently be used with NTFS.", "Unsupported ISO...", MB_OK|MB_ICONERROR); | ||||||
| 							} | 							} | ||||||
| 							break; | 							break; | ||||||
| 						} else if (((fs == FS_FAT16)||(fs == FS_FAT32)) && ((!iso_report.has_isolinux) && (pt != PT_GPT))) { | 						} else if (((fs == FS_FAT16)||(fs == FS_FAT32)) && (!iso_report.has_isolinux)) { | ||||||
| 							MessageBoxA(hMainDialog, "Only isolinux or EFI based ISO " | 							MessageBoxA(hMainDialog, "FAT/FAT32 can only be used for isolinux based ISO images " | ||||||
| 								"images can currently be used with FAT/FAT32.", "Unsupported ISO...", MB_OK|MB_ICONERROR); | 								"or when the Target Type is UEFI.", "Unsupported ISO...", MB_OK|MB_ICONERROR); | ||||||
|  | 							break; | ||||||
|  | 						} | ||||||
|  | 						if ((bt == BT_UEFI) && (iso_report.has_win7_efi) && (!WimExtractCheck())) { | ||||||
|  | 							if (MessageBoxA(hMainDialog, "Your platform cannot extract files from WIM archives. WIM extraction " | ||||||
|  | 								"is required to create EFI bootable Windows 7 and Windows Vista USB drives. You can fix that " | ||||||
|  | 								"by installing a recent version of 7-Zip.\r\nDo you want to visit the 7-zip download page?", | ||||||
|  | 								"Missing WIM support...", MB_YESNO|MB_ICONERROR) == IDYES) | ||||||
|  | 								ShellExecuteA(hDlg, "open", SEVENZIP_URL, NULL, NULL, SW_SHOWNORMAL); | ||||||
| 							break; | 							break; | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
							
								
								
									
										16
									
								
								src/rufus.h
									
										
									
									
									
								
							
							
						
						
									
										16
									
								
								src/rufus.h
									
										
									
									
									
								
							|  | @ -51,6 +51,7 @@ | ||||||
| #define WHITE                       RGB(255,255,255) | #define WHITE                       RGB(255,255,255) | ||||||
| #define SEPARATOR_GREY              RGB(223,223,223) | #define SEPARATOR_GREY              RGB(223,223,223) | ||||||
| #define RUFUS_URL                   "http://rufus.akeo.ie"
 | #define RUFUS_URL                   "http://rufus.akeo.ie"
 | ||||||
|  | #define SEVENZIP_URL                "http://sourceforge.net/projects/sevenzip/files/7-Zip/"
 | ||||||
| #define IGNORE_RETVAL(expr)         do { (void)(expr); } while(0) | #define IGNORE_RETVAL(expr)         do { (void)(expr); } while(0) | ||||||
| #ifndef ARRAYSIZE | #ifndef ARRAYSIZE | ||||||
| #define ARRAYSIZE(A)                (sizeof(A)/sizeof((A)[0])) | #define ARRAYSIZE(A)                (sizeof(A)/sizeof((A)[0])) | ||||||
|  | @ -150,11 +151,14 @@ enum dos_type { | ||||||
| 	DT_MAX | 	DT_MAX | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| enum part_type { | enum bios_type { | ||||||
| 	PT_MBR = 0, | 	BT_BIOS = 0, | ||||||
| 	PT_GPT, | 	BT_UEFI, | ||||||
| 	PT_MAX | 	BT_MAX | ||||||
| }; | }; | ||||||
|  | // For the partition types we'll use Microsoft's PARTITION_STYLE_### constants
 | ||||||
|  | #define GETBIOSTYPE(x) (((x) >> 16) & 0xFFFF) | ||||||
|  | #define GETPARTTYPE(x) ((x) & 0xFFFF); | ||||||
| 
 | 
 | ||||||
| /* Current drive info */ | /* Current drive info */ | ||||||
| typedef struct { | typedef struct { | ||||||
|  | @ -165,6 +169,7 @@ typedef struct { | ||||||
| 	char proposed_label[16]; | 	char proposed_label[16]; | ||||||
| 	int PartitionType; | 	int PartitionType; | ||||||
| 	int FSType; | 	int FSType; | ||||||
|  | 	BOOL has_protective_mbr; | ||||||
| 	struct { | 	struct { | ||||||
| 		ULONG Allowed; | 		ULONG Allowed; | ||||||
| 		ULONG Default; | 		ULONG Default; | ||||||
|  | @ -298,7 +303,8 @@ extern char* get_token_data_buffer(const char* token, unsigned int n, const char | ||||||
| extern char* insert_section_data(const char* filename, const char* section, const char* data, BOOL dos2unix); | extern char* insert_section_data(const char* filename, const char* section, const char* data, BOOL dos2unix); | ||||||
| extern char* replace_in_token_data(const char* filename, const char* token, const char* src, const char* rep, BOOL dos2unix); | extern char* replace_in_token_data(const char* filename, const char* token, const char* src, const char* rep, BOOL dos2unix); | ||||||
| extern void parse_update(char* buf, size_t len); | extern void parse_update(char* buf, size_t len); | ||||||
| extern BOOL WIMExtractFile(const char* wim_image, int index, const char* src, const char* dst); | extern BOOL WimExtractCheck(void); | ||||||
|  | extern BOOL WimExtractFile(const char* wim_image, int index, const char* src, const char* dst); | ||||||
| 
 | 
 | ||||||
| __inline static BOOL UnlockDrive(HANDLE hDrive) | __inline static BOOL UnlockDrive(HANDLE hDrive) | ||||||
| { | { | ||||||
|  |  | ||||||
							
								
								
									
										12
									
								
								src/rufus.rc
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								src/rufus.rc
									
										
									
									
									
								
							|  | @ -30,7 +30,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL | ||||||
| IDD_DIALOG DIALOGEX 12, 12, 206, 316 | IDD_DIALOG DIALOGEX 12, 12, 206, 316 | ||||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | ||||||
| EXSTYLE WS_EX_APPWINDOW | EXSTYLE WS_EX_APPWINDOW | ||||||
| CAPTION "Rufus v1.3.1.224" | CAPTION "Rufus v1.3.1.225" | ||||||
| FONT 8, "MS Shell Dlg", 400, 0, 0x1 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 | ||||||
| BEGIN | BEGIN | ||||||
|     DEFPUSHBUTTON   "Start",IDC_START,94,278,50,14 |     DEFPUSHBUTTON   "Start",IDC_START,94,278,50,14 | ||||||
|  | @ -40,7 +40,7 @@ BEGIN | ||||||
|     COMBOBOX        IDC_FILESYSTEM,8,75,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP |     COMBOBOX        IDC_FILESYSTEM,8,75,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP | ||||||
|     LTEXT           "File system",IDC_STATIC,9,64,51,10 |     LTEXT           "File system",IDC_STATIC,9,64,51,10 | ||||||
|     COMBOBOX        IDC_PARTITION_SCHEME,8,46,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP |     COMBOBOX        IDC_PARTITION_SCHEME,8,46,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP | ||||||
|     LTEXT           "Partition Scheme",IDC_STATIC,9,35,75,8 |     LTEXT           "Partition Scheme and Target Type",IDC_STATIC,9,35,176,8 | ||||||
|     COMBOBOX        IDC_CLUSTERSIZE,8,104,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP |     COMBOBOX        IDC_CLUSTERSIZE,8,104,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP | ||||||
|     LTEXT           "Cluster size",IDC_STATIC,9,93,105,10 |     LTEXT           "Cluster size",IDC_STATIC,9,93,105,10 | ||||||
|     PUSHBUTTON      "About...",IDC_ABOUT,8,278,50,14 |     PUSHBUTTON      "About...",IDC_ABOUT,8,278,50,14 | ||||||
|  | @ -274,8 +274,8 @@ END | ||||||
| // | // | ||||||
| 
 | 
 | ||||||
| VS_VERSION_INFO VERSIONINFO | VS_VERSION_INFO VERSIONINFO | ||||||
|  FILEVERSION 1,3,1,224 |  FILEVERSION 1,3,1,225 | ||||||
|  PRODUCTVERSION 1,3,1,224 |  PRODUCTVERSION 1,3,1,225 | ||||||
|  FILEFLAGSMASK 0x3fL |  FILEFLAGSMASK 0x3fL | ||||||
| #ifdef _DEBUG | #ifdef _DEBUG | ||||||
|  FILEFLAGS 0x1L |  FILEFLAGS 0x1L | ||||||
|  | @ -292,13 +292,13 @@ BEGIN | ||||||
|         BEGIN |         BEGIN | ||||||
|             VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" |             VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" | ||||||
|             VALUE "FileDescription", "Rufus" |             VALUE "FileDescription", "Rufus" | ||||||
|             VALUE "FileVersion", "1.3.1.224" |             VALUE "FileVersion", "1.3.1.225" | ||||||
|             VALUE "InternalName", "Rufus" |             VALUE "InternalName", "Rufus" | ||||||
|             VALUE "LegalCopyright", "(c) 2011-2012 Pete Batard (GPL v3)" |             VALUE "LegalCopyright", "(c) 2011-2012 Pete Batard (GPL v3)" | ||||||
|             VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" |             VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" | ||||||
|             VALUE "OriginalFilename", "rufus.exe" |             VALUE "OriginalFilename", "rufus.exe" | ||||||
|             VALUE "ProductName", "Rufus" |             VALUE "ProductName", "Rufus" | ||||||
|             VALUE "ProductVersion", "1.3.1.224" |             VALUE "ProductVersion", "1.3.1.225" | ||||||
|         END |         END | ||||||
|     END |     END | ||||||
|     BLOCK "VarFileInfo" |     BLOCK "VarFileInfo" | ||||||
|  |  | ||||||
							
								
								
									
										126
									
								
								src/vhd.c
									
										
									
									
									
								
							
							
						
						
									
										126
									
								
								src/vhd.c
									
										
									
									
									
								
							|  | @ -17,8 +17,14 @@ | ||||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | #include <windows.h> | ||||||
|  | #include <io.h> | ||||||
|  | 
 | ||||||
| #include "rufus.h" | #include "rufus.h" | ||||||
| #include "msapi_utf8.h" | #include "msapi_utf8.h" | ||||||
|  | #include "registry.h" | ||||||
|  | 
 | ||||||
|  | static BOOL has_wimgapi = FALSE, has_7z = FALSE; | ||||||
| 
 | 
 | ||||||
| #define WIM_GENERIC_READ	GENERIC_READ | #define WIM_GENERIC_READ	GENERIC_READ | ||||||
| #define WIM_OPEN_EXISTING	OPEN_EXISTING | #define WIM_OPEN_EXISTING	OPEN_EXISTING | ||||||
|  | @ -53,9 +59,39 @@ typedef BOOL (WINAPI *WIMCloseHandle_t)( | ||||||
| 	HANDLE  hObj | 	HANDLE  hObj | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| // Extract a file from a WIM image
 | // WIM API Prototypes
 | ||||||
|  | static PF_DECL(WIMCreateFile); | ||||||
|  | static PF_DECL(WIMSetTemporaryPath); | ||||||
|  | static PF_DECL(WIMLoadImage); | ||||||
|  | static PF_DECL(WIMExtractImagePath); | ||||||
|  | static PF_DECL(WIMCloseHandle); | ||||||
|  | 
 | ||||||
|  | // Find out if we have any way to extraxt WIM files on this platform
 | ||||||
|  | BOOL WimExtractCheck(void) | ||||||
|  | { | ||||||
|  | 	char sevenzip_path[MAX_PATH]; | ||||||
|  | 
 | ||||||
|  | 	PF_INIT(WIMCreateFile, wimgapi); | ||||||
|  | 	PF_INIT(WIMSetTemporaryPath, wimgapi); | ||||||
|  | 	PF_INIT(WIMLoadImage, wimgapi); | ||||||
|  | 	PF_INIT(WIMExtractImagePath, wimgapi); | ||||||
|  | 	PF_INIT(WIMCloseHandle, wimgapi); | ||||||
|  | 
 | ||||||
|  | 	has_wimgapi = (pfWIMCreateFile && pfWIMSetTemporaryPath && pfWIMLoadImage && pfWIMExtractImagePath && pfWIMCloseHandle); | ||||||
|  | 	if (GetRegistryKeyStr("7-Zip\\Path", sevenzip_path, sizeof(sevenzip_path))) { | ||||||
|  | 		safe_strcat(sevenzip_path, sizeof(sevenzip_path), "\\7z.exe"); | ||||||
|  | 		has_7z = (_access(sevenzip_path, 0) != -1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	uprintf("WIM extraction method(s) supported: %s%s%s\n", has_7z?"7z":(has_wimgapi?"":"NONE"), | ||||||
|  | 		(has_wimgapi && has_7z)?", ":"", has_wimgapi?"wimgapi.dll":""); | ||||||
|  | 	return (has_wimgapi || has_7z); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // Extract a file from a WIM image using wimgapi.dll (Windows 7 or later)
 | ||||||
| // NB: Don't bother trying to get progress from a WIM callback - it doesn't work!
 | // NB: Don't bother trying to get progress from a WIM callback - it doesn't work!
 | ||||||
| BOOL WIMExtractFile(const char* image, int index, const char* src, const char* dst) | static BOOL WimExtractFile_API(const char* image, int index, const char* src, const char* dst) | ||||||
| { | { | ||||||
| 	BOOL r = FALSE; | 	BOOL r = FALSE; | ||||||
| 	DWORD dw = 0; | 	DWORD dw = 0; | ||||||
|  | @ -65,11 +101,6 @@ BOOL WIMExtractFile(const char* image, int index, const char* src, const char* d | ||||||
| 	wchar_t* wimage = utf8_to_wchar(image); | 	wchar_t* wimage = utf8_to_wchar(image); | ||||||
| 	wchar_t* wsrc = utf8_to_wchar(src); | 	wchar_t* wsrc = utf8_to_wchar(src); | ||||||
| 	wchar_t* wdst = utf8_to_wchar(dst); | 	wchar_t* wdst = utf8_to_wchar(dst); | ||||||
| 	PF_DECL(WIMCreateFile); |  | ||||||
| 	PF_DECL(WIMSetTemporaryPath); |  | ||||||
| 	PF_DECL(WIMLoadImage); |  | ||||||
| 	PF_DECL(WIMExtractImagePath); |  | ||||||
| 	PF_DECL(WIMCloseHandle); |  | ||||||
| 
 | 
 | ||||||
| 	PF_INIT_OR_OUT(WIMCreateFile, wimgapi); | 	PF_INIT_OR_OUT(WIMCreateFile, wimgapi); | ||||||
| 	PF_INIT_OR_OUT(WIMSetTemporaryPath, wimgapi); | 	PF_INIT_OR_OUT(WIMSetTemporaryPath, wimgapi); | ||||||
|  | @ -77,37 +108,36 @@ BOOL WIMExtractFile(const char* image, int index, const char* src, const char* d | ||||||
| 	PF_INIT_OR_OUT(WIMExtractImagePath, wimgapi); | 	PF_INIT_OR_OUT(WIMExtractImagePath, wimgapi); | ||||||
| 	PF_INIT_OR_OUT(WIMCloseHandle, wimgapi); | 	PF_INIT_OR_OUT(WIMCloseHandle, wimgapi); | ||||||
| 
 | 
 | ||||||
| 	// TODO: check for NULL and missing wimgapi.dll
 | 	uprintf("Opening: %s:[%d] (API)\n", image, index); | ||||||
| 
 |  | ||||||
| 	if (GetTempPathW(ARRAYSIZE(wtemp), wtemp) == 0) { | 	if (GetTempPathW(ARRAYSIZE(wtemp), wtemp) == 0) { | ||||||
| 		uprintf("Could not fetch temp path: %s\n", WindowsErrorString()); | 		uprintf("  Could not fetch temp path: %s\n", WindowsErrorString()); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	uprintf("Opening: %s (index #%d)\n", image, index); |  | ||||||
| 	hWim = pfWIMCreateFile(wimage, WIM_GENERIC_READ, WIM_OPEN_EXISTING, 0, 0, &dw); | 	hWim = pfWIMCreateFile(wimage, WIM_GENERIC_READ, WIM_OPEN_EXISTING, 0, 0, &dw); | ||||||
| 	if (hWim == NULL) { | 	if (hWim == NULL) { | ||||||
| 		uprintf("  Error: '%s': %s\n", WindowsErrorString()); | 		uprintf("  Could not access image: %s\n", WindowsErrorString()); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (!pfWIMSetTemporaryPath(hWim, wtemp)) { | 	if (!pfWIMSetTemporaryPath(hWim, wtemp)) { | ||||||
| 		uprintf("  Error setting temp path: %s\n", WindowsErrorString()); | 		uprintf("  Could not set temp path: %s\n", WindowsErrorString()); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	hImage = pfWIMLoadImage(hWim, (DWORD)index); | 	hImage = pfWIMLoadImage(hWim, (DWORD)index); | ||||||
| 	if (hImage == NULL) { | 	if (hImage == NULL) { | ||||||
| 		uprintf("  Error setting index: %s.\n", WindowsErrorString()); | 		uprintf("  Could not set index: %s\n", WindowsErrorString()); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	uprintf("Extracting: %s (From \\%s)\n", dst, src); | 	uprintf("Extracting: %s (From \\%s)\n", dst, src); | ||||||
| 	if (!pfWIMExtractImagePath(hImage, wsrc, wdst, 0)) { | 	if (!pfWIMExtractImagePath(hImage, wsrc, wdst, 0)) { | ||||||
| 		uprintf("  Could not extract file: %s.\n", WindowsErrorString()); | 		uprintf("  Could not extract file: %s\n", WindowsErrorString()); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 	r = TRUE; | 	r = TRUE; | ||||||
|  | 	UpdateProgress(OP_FINALIZE, -1.0f); | ||||||
| 
 | 
 | ||||||
| out: | out: | ||||||
| 	if ((hImage != NULL) || (hWim != NULL)) { | 	if ((hImage != NULL) || (hWim != NULL)) { | ||||||
|  | @ -120,3 +150,69 @@ out: | ||||||
| 	safe_free(wdst); | 	safe_free(wdst); | ||||||
| 	return r; | 	return r; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // Extract a file from a WIM image using 7-Zip
 | ||||||
|  | static BOOL WimExtractFile_7z(const char* image, int index, const char* src, const char* dst) | ||||||
|  | { | ||||||
|  | 	size_t i; | ||||||
|  | 	STARTUPINFOA si = {0}; | ||||||
|  | 	PROCESS_INFORMATION pi = {0}; | ||||||
|  | 	char sevenzip_path[MAX_PATH]; | ||||||
|  | 	char cmdline[MAX_PATH]; | ||||||
|  | 	char tmpdst[MAX_PATH]; | ||||||
|  | 
 | ||||||
|  | 	uprintf("Opening: %s:[%d] (7-Zip)\n", image, index); | ||||||
|  | 	if (!GetRegistryKeyStr("7-Zip\\Path", sevenzip_path, sizeof(sevenzip_path))) { | ||||||
|  | 		uprintf("  Could not read 7-Zip path from registry\n"); | ||||||
|  | 		return FALSE; | ||||||
|  | 	} | ||||||
|  | 	safe_strcat(sevenzip_path, sizeof(sevenzip_path), "\\7z.exe"); | ||||||
|  | 	 | ||||||
|  | 	if (_access(sevenzip_path, 0) == -1) { | ||||||
|  | 		uprintf("  Could not locate 7z.exe at '%s'\n", sevenzip_path); | ||||||
|  | 		return FALSE; | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	safe_strcpy(tmpdst, sizeof(tmpdst), dst); | ||||||
|  | 	for (i=safe_strlen(tmpdst); i>0; i--) { | ||||||
|  | 		if (tmpdst[i] == '\\') | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | 	tmpdst[i] = 0; | ||||||
|  | 
 | ||||||
|  | 	si.cb = sizeof(si); | ||||||
|  | 	safe_sprintf(cmdline, sizeof(cmdline), "7z -y e \"%s\" %d\\Windows\\Boot\\EFI\\bootmgfw.efi", image, index); | ||||||
|  | 	uprintf("Extracting: %s (From \\%s)\n", dst, src); | ||||||
|  | 	if (!CreateProcessU(sevenzip_path, cmdline, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, tmpdst, &si, &pi)) { | ||||||
|  | 		uprintf("  Could not launch 7z.exe: %s\n", WindowsErrorString()); | ||||||
|  | 		return FALSE; | ||||||
|  | 	} | ||||||
|  | 	WaitForSingleObject(pi.hProcess, INFINITE); | ||||||
|  | 	UpdateProgress(OP_FINALIZE, -1.0f); | ||||||
|  | 	CloseHandle(pi.hProcess); | ||||||
|  | 	CloseHandle(pi.hThread); | ||||||
|  | 
 | ||||||
|  | 	safe_strcat(tmpdst, sizeof(tmpdst), "\\bootmgfw.efi"); | ||||||
|  | 	if (_access(tmpdst, 0) == -1) { | ||||||
|  | 		uprintf("  7z.exe did not extract %s\n", tmpdst); | ||||||
|  | 		return FALSE; | ||||||
|  | 	} | ||||||
|  | 	if (rename(tmpdst, dst) != 0) { | ||||||
|  | 		uprintf("  Could not rename %s to %s\n", tmpdst, dst); | ||||||
|  | 		return FALSE; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return TRUE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Extract a file from a WIM image
 | ||||||
|  | BOOL WimExtractFile(const char* image, int index, const char* src, const char* dst) | ||||||
|  | { | ||||||
|  | 	if ((!has_wimgapi) && (!has_7z) && (!WimExtractCheck())) | ||||||
|  | 		return FALSE; | ||||||
|  | 
 | ||||||
|  | 	// Prefer 7-Zip as, unsurprisingly, it's faster than the Microsoft way,
 | ||||||
|  | 	// but allow fallback if 7-Zip doesn't succeed
 | ||||||
|  | 	return ( (has_7z && WimExtractFile_7z(image, index, src, dst)) | ||||||
|  | 		  || (has_wimgapi && WimExtractFile_API(image, index, src, dst)) ); | ||||||
|  | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue