mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[gpt] add support for GPT partitioning and EFI boot
* Contains the bulk of the code required to address #11 * Tested with Windows 8 Pro x64 (en-gb_windows_8_x64_dvd_915412.iso) and Arch Linux (archlinux-2013.01.04-dual.iso) against an UEFI 2.1 BIOS * Also fixes missing status report beta versions check
This commit is contained in:
		
							parent
							
								
									6b8833bcfb
								
							
						
					
					
						commit
						997c0a0f28
					
				
					 8 changed files with 257 additions and 114 deletions
				
			
		
							
								
								
									
										45
									
								
								src/format.c
									
										
									
									
									
								
							
							
						
						
									
										45
									
								
								src/format.c
									
										
									
									
									
								
							|  | @ -2,7 +2,7 @@ | ||||||
|  * Rufus: The Reliable USB Formatting Utility |  * Rufus: The Reliable USB Formatting Utility | ||||||
|  * Formatting function calls |  * Formatting function calls | ||||||
|  * Copyright (c) 2007-2009 Tom Thornhill/Ridgecrop |  * Copyright (c) 2007-2009 Tom Thornhill/Ridgecrop | ||||||
|  * Copyright (c) 2011-2012 Pete Batard <pete@akeo.ie> |  * Copyright (c) 2011-2013 Pete Batard <pete@akeo.ie> | ||||||
|  * |  * | ||||||
|  * This program is free software: you can redistribute it and/or modify |  * 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 |  * it under the terms of the GNU General Public License as published by | ||||||
|  | @ -743,21 +743,30 @@ static BOOL AnalyzePBR(HANDLE hLogicalVolume) | ||||||
| 	return TRUE; | 	return TRUE; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static BOOL ClearMBR(HANDLE hPhysicalDrive) | static BOOL ClearMBRGPT(HANDLE hPhysicalDrive, LONGLONG DiskSize, DWORD SectorSize) | ||||||
| { | { | ||||||
| 	BOOL r = FALSE; | 	BOOL r = FALSE; | ||||||
| 	// Clearing the first 64K seems to help with reluctant access to large drive
 | 	uint64_t i, last_sector = DiskSize/SectorSize; | ||||||
| 	size_t SectorSize = 65536; |  | ||||||
| 	unsigned char* pBuf = (unsigned char*) calloc(SectorSize, 1); | 	unsigned char* pBuf = (unsigned char*) calloc(SectorSize, 1); | ||||||
| 
 | 
 | ||||||
| 	PrintStatus(0, TRUE, "Clearing MBR..."); | 	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; | ||||||
| 	} | 	} | ||||||
| 	if ((IS_ERROR(FormatStatus)) || (write_sectors(hPhysicalDrive, SectorSize, 0, 1, pBuf) != SectorSize)) { | 	// http://en.wikipedia.org/wiki/GUID_Partition_Table tells us we should clear 34 sectors at the
 | ||||||
|  | 	// beginning and 33 at the end. We bump these values to MAX_SECTORS_TO_CLEAR each end to help
 | ||||||
|  | 	// with reluctant access to large drive.
 | ||||||
|  | 	for (i=0; i<MAX_SECTORS_TO_CLEAR; i++) { | ||||||
|  | 		if ((IS_ERROR(FormatStatus)) || (write_sectors(hPhysicalDrive, SectorSize, i, 1, pBuf) != SectorSize)) { | ||||||
| 			goto out; | 			goto out; | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
|  | 	for (i=last_sector-MAX_SECTORS_TO_CLEAR; i<last_sector; i++) { | ||||||
|  | 		if ((IS_ERROR(FormatStatus)) || (write_sectors(hPhysicalDrive, SectorSize, i, 1, pBuf) != SectorSize)) { | ||||||
|  | 			goto out; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 	r = TRUE; | 	r = TRUE; | ||||||
| 
 | 
 | ||||||
| out: | out: | ||||||
|  | @ -1104,6 +1113,7 @@ DWORD WINAPI FormatThread(LPVOID param) | ||||||
| 	int r; | 	int r; | ||||||
| 	int fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); | 	int fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); | ||||||
| 	int dt = (int)ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)); | 	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; | ||||||
|  | @ -1161,7 +1171,7 @@ DWORD WINAPI FormatThread(LPVOID param) | ||||||
| 				if (!FormatStatus) | 				if (!FormatStatus) | ||||||
| 					FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)| | 					FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)| | ||||||
| 						APPERR(ERROR_BADBLOCKS_FAILURE); | 						APPERR(ERROR_BADBLOCKS_FAILURE); | ||||||
| 				ClearMBR(hPhysicalDrive); | 				ClearMBRGPT(hPhysicalDrive, SelectedDrive.DiskSize, SelectedDrive.Geometry.BytesPerSector); | ||||||
| 				fclose(log_fd); | 				fclose(log_fd); | ||||||
| 				_unlink(logfile); | 				_unlink(logfile); | ||||||
| 				goto out; | 				goto out; | ||||||
|  | @ -1198,10 +1208,10 @@ DWORD WINAPI FormatThread(LPVOID param) | ||||||
| 	// Close the (unmounted) volume before formatting, but keep the lock
 | 	// Close the (unmounted) volume before formatting, but keep the lock
 | ||||||
| 	safe_closehandle(hLogicalVolume); | 	safe_closehandle(hLogicalVolume); | ||||||
| 
 | 
 | ||||||
| 	// Especially after destructive badblocks test, you must zero the MBR completely
 | 	// Especially after destructive badblocks test, you must zero the MBR/GPT completely
 | ||||||
| 	// before repartitioning. Else, all kind of bad things happen
 | 	// before repartitioning. Else, all kind of bad things can happen.
 | ||||||
| 	if (!ClearMBR(hPhysicalDrive)) { | 	if (!ClearMBRGPT(hPhysicalDrive, SelectedDrive.DiskSize, SelectedDrive.Geometry.BytesPerSector)) { | ||||||
| 		uprintf("unable to zero MBR\n"); | 		uprintf("unable to zero MBR/GPT\n"); | ||||||
| 		if (!FormatStatus) | 		if (!FormatStatus) | ||||||
| 			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT; | 			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT; | ||||||
| 		goto out; | 		goto out; | ||||||
|  | @ -1227,6 +1237,7 @@ DWORD WINAPI FormatThread(LPVOID param) | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if (pt == PT_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) | ||||||
|  | @ -1234,9 +1245,17 @@ DWORD WINAPI FormatThread(LPVOID param) | ||||||
| 			goto out; | 			goto out; | ||||||
| 		} | 		} | ||||||
| 		UpdateProgress(OP_FIX_MBR, -1.0f); | 		UpdateProgress(OP_FIX_MBR, -1.0f); | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	if (IsChecked(IDC_DOS)) { | 	if (IsChecked(IDC_DOS)) { | ||||||
| 		if ((dt == DT_WINME) || (dt == DT_FREEDOS) || ((dt == DT_ISO) && (fs == FS_NTFS))) { | 		if (pt == PT_GPT) { | ||||||
|  | 			// For once, no need to do anything - just check our sanity
 | ||||||
|  | 			if ( (dt != DT_ISO) || (!iso_report.has_efi) || (fs > FS_FAT32) ) { | ||||||
|  | 				uprintf("Spock gone crazy error!\n"); | ||||||
|  | 				FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INSTALL_FAILURE; | ||||||
|  | 				goto out; | ||||||
|  | 			} | ||||||
|  | 		} else if ((dt == DT_WINME) || (dt == DT_FREEDOS) || ((dt == DT_ISO) && (fs == FS_NTFS))) { | ||||||
| 			// We still have a lock, which we need to modify the volume boot record 
 | 			// We still have a lock, which we need to modify the volume boot record 
 | ||||||
| 			// => no need to reacquire the lock...
 | 			// => no need to reacquire the lock...
 | ||||||
| 			hLogicalVolume = GetDriveHandle(num, drive_name, TRUE, FALSE); | 			hLogicalVolume = GetDriveHandle(num, drive_name, TRUE, FALSE); | ||||||
|  | @ -1292,7 +1311,7 @@ DWORD WINAPI FormatThread(LPVOID param) | ||||||
| 					goto out; | 					goto out; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			if (IS_WINPE(iso_report.winpe)) { | 			if ( (pt == PT_MBR) && (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,6 +57,7 @@ int64_t iso_blocking_status = -1; | ||||||
| static const char* psz_extract_dir; | static const char* psz_extract_dir; | ||||||
| static const char* bootmgr_name = "bootmgr"; | static const char* bootmgr_name = "bootmgr"; | ||||||
| static const char* ldlinux_name = "ldlinux.sys"; | static const char* ldlinux_name = "ldlinux.sys"; | ||||||
|  | static const char* efi_dirname = "/efi/boot"; | ||||||
| static const char* isolinux_name[] = { "isolinux.cfg", "syslinux.cfg", "extlinux.conf"}; | static const char* isolinux_name[] = { "isolinux.cfg", "syslinux.cfg", "extlinux.conf"}; | ||||||
| static const char* pe_dirname[] = { "/i386", "/minint" }; | static const char* pe_dirname[] = { "/i386", "/minint" }; | ||||||
| static const char* pe_file[] = { "ntdetect.com", "setupldr.bin", "txtsetup.sif" }; | static const char* pe_file[] = { "ntdetect.com", "setupldr.bin", "txtsetup.sif" }; | ||||||
|  | @ -126,6 +127,10 @@ static __inline BOOL check_iso_props(const char* psz_dirname, BOOL* is_syslinux_ | ||||||
| 		if ((*psz_dirname == 0) && (safe_stricmp(psz_basename, bootmgr_name) == 0)) | 		if ((*psz_dirname == 0) && (safe_stricmp(psz_basename, bootmgr_name) == 0)) | ||||||
| 			iso_report.has_bootmgr = TRUE; | 			iso_report.has_bootmgr = TRUE; | ||||||
| 
 | 
 | ||||||
|  | 		// Check for the EFI boot directory
 | ||||||
|  | 		if (safe_stricmp(psz_dirname, efi_dirname) == 0) | ||||||
|  | 			iso_report.has_efi = TRUE; | ||||||
|  | 
 | ||||||
| 		// Check for PE (XP) specific files in "/i386" or "/minint"
 | 		// Check for PE (XP) specific files in "/i386" or "/minint"
 | ||||||
| 		for (i=0; i<ARRAYSIZE(pe_dirname); i++) | 		for (i=0; i<ARRAYSIZE(pe_dirname); i++) | ||||||
| 			if (safe_stricmp(psz_dirname, pe_dirname[i]) == 0) | 			if (safe_stricmp(psz_dirname, pe_dirname[i]) == 0) | ||||||
|  |  | ||||||
|  | @ -607,6 +607,7 @@ out: | ||||||
| 		PrintStatus(3000, TRUE, "Updates: Unable to access version data.\n"); | 		PrintStatus(3000, TRUE, "Updates: Unable to access version data.\n"); | ||||||
| 		break; | 		break; | ||||||
| 	case 3: | 	case 3: | ||||||
|  | 	case 4: | ||||||
| 		PrintStatus(3000, FALSE, "%s new version of " APPLICATION_NAME " %s\n", | 		PrintStatus(3000, FALSE, "%s new version of " APPLICATION_NAME " %s\n", | ||||||
| 		found_new_version?"A":"No", found_new_version?"is available!":"was found."); | 		found_new_version?"A":"No", found_new_version?"is available!":"was found."); | ||||||
| 	default: | 	default: | ||||||
|  |  | ||||||
|  | @ -48,7 +48,7 @@ | ||||||
| #define IDC_DEVICE                      1001 | #define IDC_DEVICE                      1001 | ||||||
| #define IDC_FILESYSTEM                  1002 | #define IDC_FILESYSTEM                  1002 | ||||||
| #define IDC_START                       1003 | #define IDC_START                       1003 | ||||||
| #define IDC_PARTITION                   1004 | #define IDC_PARTITION_SCHEME            1004 | ||||||
| #define IDC_CLUSTERSIZE                 1005 | #define IDC_CLUSTERSIZE                 1005 | ||||||
| #define IDC_STATUS                      1006 | #define IDC_STATUS                      1006 | ||||||
| #define IDC_ABOUT                       1007 | #define IDC_ABOUT                       1007 | ||||||
|  |  | ||||||
							
								
								
									
										190
									
								
								src/rufus.c
									
										
									
									
									
								
							
							
						
						
									
										190
									
								
								src/rufus.c
									
										
									
									
									
								
							|  | @ -86,6 +86,7 @@ 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 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; | ||||||
|  | @ -101,7 +102,7 @@ char szFolderPath[MAX_PATH], app_dir[MAX_PATH]; | ||||||
| char* iso_path = NULL; | char* iso_path = NULL; | ||||||
| float fScale = 1.0f; | float fScale = 1.0f; | ||||||
| int default_fs; | int default_fs; | ||||||
| HWND hDeviceList, hPartition, hFileSystem, hClusterSize, hLabel, hDOSType, hNBPasses, hLog = NULL; | HWND hDeviceList, hPartitionScheme, hFileSystem, hClusterSize, hLabel, hDOSType, hNBPasses, hLog = NULL; | ||||||
| HWND hISOProgressDlg = NULL, hLogDlg = NULL, hISOProgressBar, hISOFileName, hDiskID; | HWND hISOProgressDlg = NULL, hLogDlg = NULL, hISOProgressBar, hISOFileName, hDiskID; | ||||||
| BOOL use_own_c32[NB_OLD_C32] = {FALSE, FALSE}, detect_fakes = TRUE, mbr_selected_by_user = FALSE; | BOOL use_own_c32[NB_OLD_C32] = {FALSE, FALSE}, detect_fakes = TRUE, mbr_selected_by_user = FALSE; | ||||||
| BOOL iso_op_in_progress = FALSE, format_op_in_progress = FALSE; | BOOL iso_op_in_progress = FALSE, format_op_in_progress = FALSE; | ||||||
|  | @ -359,9 +360,8 @@ static BOOL GetDriveInfo(void) | ||||||
| 	void* drive_layout = (void*)layout; | 	void* drive_layout = (void*)layout; | ||||||
| 	PDISK_GEOMETRY_EX DiskGeometry = (PDISK_GEOMETRY_EX)disk_geometry; | 	PDISK_GEOMETRY_EX DiskGeometry = (PDISK_GEOMETRY_EX)disk_geometry; | ||||||
| 	PDRIVE_LAYOUT_INFORMATION_EX DriveLayout = (PDRIVE_LAYOUT_INFORMATION_EX)drive_layout; | 	PDRIVE_LAYOUT_INFORMATION_EX DriveLayout = (PDRIVE_LAYOUT_INFORMATION_EX)drive_layout; | ||||||
| 	char DrivePath[] = "#:\\", tmp[512], fs_type[32]; | 	char DrivePath[] = "#:\\", tmp[256], fs_type[32]; | ||||||
| 	DWORD i, nb_partitions = 0; | 	DWORD i, nb_partitions = 0; | ||||||
| 	int tmp_pos; |  | ||||||
| 
 | 
 | ||||||
| 	SelectedDrive.DiskSize = 0; | 	SelectedDrive.DiskSize = 0; | ||||||
| 
 | 
 | ||||||
|  | @ -378,9 +378,9 @@ static BOOL GetDriveInfo(void) | ||||||
| 	} | 	} | ||||||
| 	SelectedDrive.DiskSize = DiskGeometry->DiskSize.QuadPart; | 	SelectedDrive.DiskSize = DiskGeometry->DiskSize.QuadPart; | ||||||
| 	memcpy(&SelectedDrive.Geometry, &DiskGeometry->Geometry, sizeof(DISK_GEOMETRY)); | 	memcpy(&SelectedDrive.Geometry, &DiskGeometry->Geometry, sizeof(DISK_GEOMETRY)); | ||||||
| 	uprintf("Cylinders: %lld, TracksPerCylinder: %d, SectorsPerTrack: %d, BytesPerSector: %d\n", | 	uprintf("Sector Size: %d bytes\n", DiskGeometry->Geometry.BytesPerSector); | ||||||
| 		DiskGeometry->Geometry.Cylinders, DiskGeometry->Geometry.TracksPerCylinder, | 	uprintf("Cylinders: %lld, TracksPerCylinder: %d, SectorsPerTrack: %d\n", | ||||||
| 		DiskGeometry->Geometry.SectorsPerTrack, DiskGeometry->Geometry.BytesPerSector); | 		DiskGeometry->Geometry.Cylinders, DiskGeometry->Geometry.TracksPerCylinder, DiskGeometry->Geometry.SectorsPerTrack); | ||||||
| 
 | 
 | ||||||
| 	r = DeviceIoControl(hDrive, IOCTL_DISK_GET_DRIVE_LAYOUT_EX,  | 	r = DeviceIoControl(hDrive, IOCTL_DISK_GET_DRIVE_LAYOUT_EX,  | ||||||
| 			NULL, 0, layout, sizeof(layout), &size, NULL ); | 			NULL, 0, layout, sizeof(layout), &size, NULL ); | ||||||
|  | @ -389,28 +389,46 @@ static BOOL GetDriveInfo(void) | ||||||
| 	} else { | 	} else { | ||||||
| 		switch (DriveLayout->PartitionStyle) { | 		switch (DriveLayout->PartitionStyle) { | ||||||
| 		case PARTITION_STYLE_MBR: | 		case PARTITION_STYLE_MBR: | ||||||
| 			for (tmp_pos=0, i=0; (i<DriveLayout->PartitionCount)&&(tmp_pos>=0); i++) { | 			SelectedDrive.PartitionType = PT_MBR; | ||||||
|  | 			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++; | ||||||
| 					uprintf("Partition %d:\n", i+1); |  | ||||||
| 					part_type = DriveLayout->PartitionEntry[i].Mbr.PartitionType; |  | ||||||
| 					uprintf("  Type: %s (0x%02x)\r\n  Size: %s\r\n  Boot: %s\r\n  Recognized: %s\r\n  Hidden Sectors: %d\n", |  | ||||||
| 						GetPartitionType(part_type), part_type, size_to_hr(DriveLayout->PartitionEntry[i].PartitionLength), |  | ||||||
| 						DriveLayout->PartitionEntry[i].Mbr.BootIndicator?"Yes":"No", |  | ||||||
| 						DriveLayout->PartitionEntry[i].Mbr.RecognizedPartition?"Yes":"No", |  | ||||||
| 						DriveLayout->PartitionEntry[i].Mbr.HiddenSectors); |  | ||||||
| 					tmp_pos = _snprintf(&tmp[tmp_pos], sizeof(tmp)-tmp_pos, "Partition %d: %s (%s)\n", |  | ||||||
| 						i+1, GetPartitionType(part_type), size_to_hr(DriveLayout->PartitionEntry[i].PartitionLength)); |  | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			uprintf("Partition type: MBR, NB Partitions: %d\n", nb_partitions); | 			uprintf("Partition type: MBR, NB Partitions: %d\n", nb_partitions); | ||||||
| 			tmp[sizeof(tmp)-1] = 0; | 			uprintf("Disk ID: 0x%08X\n", DriveLayout->Mbr.Signature); | ||||||
| 			CreateTooltip(hPartition, tmp, -1); | 			for (i=0; i<DriveLayout->PartitionCount; i++) { | ||||||
|  | 				if (DriveLayout->PartitionEntry[i].Mbr.PartitionType != PARTITION_ENTRY_UNUSED) { | ||||||
|  | 					uprintf("Partition %d:\n", DriveLayout->PartitionEntry[i].PartitionNumber); | ||||||
|  | 					part_type = DriveLayout->PartitionEntry[i].Mbr.PartitionType; | ||||||
|  | 					uprintf("  Type: %s (0x%02x)\r\n  Size: %s (%lld bytes)\r\n  Start Sector: %d, Boot: %s, Recognized: %s\n", | ||||||
|  | 						GetPartitionType(part_type), part_type, size_to_hr(DriveLayout->PartitionEntry[i].PartitionLength), | ||||||
|  | 						DriveLayout->PartitionEntry[i].PartitionLength, DriveLayout->PartitionEntry[i].Mbr.HiddenSectors, | ||||||
|  | 						DriveLayout->PartitionEntry[i].Mbr.BootIndicator?"Yes":"No", | ||||||
|  | 						DriveLayout->PartitionEntry[i].Mbr.RecognizedPartition?"Yes":"No"); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
| 			break; | 			break; | ||||||
| 		case PARTITION_STYLE_GPT: | 		case PARTITION_STYLE_GPT: | ||||||
|  | 			SelectedDrive.PartitionType = PT_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("Max parts: %d, Start Offset: %lld, Usable = %lld bytes\n", | ||||||
|  | 				DriveLayout->Gpt.MaxPartitionCount, DriveLayout->Gpt.StartingUsableOffset.QuadPart, DriveLayout->Gpt.UsableLength.QuadPart); | ||||||
|  | 			for (i=0; i<DriveLayout->PartitionCount; i++) { | ||||||
|  | 				nb_partitions++; | ||||||
|  | 				tmp[0] = 0; | ||||||
|  | 				wchar_to_utf8_no_alloc(DriveLayout->PartitionEntry[i].Gpt.Name, tmp, sizeof(tmp)); | ||||||
|  | 				uprintf("Partition %d:\r\n  Type: %s\r\n  Name: '%s'\n", DriveLayout->PartitionEntry[i].PartitionNumber, | ||||||
|  | 					GuidToString(&DriveLayout->PartitionEntry[i].Gpt.PartitionType), tmp); | ||||||
|  | 				uprintf("  ID: %s\r\n  Size: %s (%lld bytes)\r\n  Start Sector: %lld, Attributes: 0x%016llX\n", | ||||||
|  | 					GuidToString(&DriveLayout->PartitionEntry[i].Gpt.PartitionId), size_to_hr(DriveLayout->PartitionEntry[i].PartitionLength), | ||||||
|  | 					DriveLayout->PartitionEntry[i].PartitionLength, DriveLayout->PartitionEntry[i].StartingOffset.QuadPart / DiskGeometry->Geometry.BytesPerSector, | ||||||
|  | 					DriveLayout->PartitionEntry[i].Gpt.Attributes); | ||||||
|  | 			} | ||||||
| 			break; | 			break; | ||||||
| 		default: | 		default: | ||||||
|  | 			SelectedDrive.PartitionType = PT_MBR; | ||||||
| 			uprintf("Partition type: RAW\n"); | 			uprintf("Partition type: RAW\n"); | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
|  | @ -472,8 +490,8 @@ static void SetFSFromISO(void) | ||||||
| 		fs_mask |= 1<<fs; | 		fs_mask |= 1<<fs; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Syslinux has precedence over bootmgr
 | 	// Syslinux and EFI have precedence over bootmgr
 | ||||||
| 	if (iso_report.has_isolinux) { | 	if ((iso_report.has_isolinux) || (iso_report.has_efi)) { | ||||||
| 		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)) { | ||||||
|  | @ -531,9 +549,9 @@ 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, fs; | 	int i, j, fs; | ||||||
| 
 | 
 | ||||||
| 	IGNORE_RETVAL(ComboBox_ResetContent(hPartition)); | 	IGNORE_RETVAL(ComboBox_ResetContent(hPartitionScheme)); | ||||||
| 	IGNORE_RETVAL(ComboBox_ResetContent(hFileSystem)); | 	IGNORE_RETVAL(ComboBox_ResetContent(hFileSystem)); | ||||||
| 	IGNORE_RETVAL(ComboBox_ResetContent(hClusterSize)); | 	IGNORE_RETVAL(ComboBox_ResetContent(hClusterSize)); | ||||||
| 	EnableWindow(GetDlgItem(hMainDialog, IDC_START), FALSE); | 	EnableWindow(GetDlgItem(hMainDialog, IDC_START), FALSE); | ||||||
|  | @ -554,12 +572,17 @@ 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) { | ||||||
| 			safe_sprintf(capacity, sizeof(capacity), "MBR (1 Partition of %0.2f %s)", HumanReadableSize, suffix[i]); | 			for (j=0; j<PT_MAX; j++) { | ||||||
|  | 				safe_sprintf(capacity, sizeof(capacity), "%s (1 Partition of %0.2f %s)", | ||||||
|  | 					PartitionSchemeName[j], HumanReadableSize, suffix[i]); | ||||||
|  | 				IGNORE_RETVAL(ComboBox_SetItemData(hPartitionScheme, ComboBox_AddStringU(hPartitionScheme, capacity), j)); | ||||||
|  | 			} | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	IGNORE_RETVAL(ComboBox_AddStringU(hPartition, capacity)); | 	if (i >= ARRAYSIZE(suffix)) | ||||||
| 	IGNORE_RETVAL(ComboBox_SetCurSel(hPartition, 0)); | 		uprintf("Could not populate partition scheme data\n"); | ||||||
|  | 	IGNORE_RETVAL(ComboBox_SetCurSel(hPartitionScheme, SelectedDrive.PartitionType)); | ||||||
| 	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")
 | ||||||
|  | @ -604,33 +627,78 @@ typedef struct _DRIVE_LAYOUT_INFORMATION_EX4 { | ||||||
| /*
 | /*
 | ||||||
|  * Create a partition table |  * Create a partition table | ||||||
|  */ |  */ | ||||||
|  | // See http://technet.microsoft.com/en-us/library/cc739412.aspx for some background info
 | ||||||
|  | #if !defined(PARTITION_BASIC_DATA_GUID) | ||||||
|  | const GUID PARTITION_BASIC_DATA_GUID = { 0xebd0a0a2, 0xb9e5, 0x4433, {0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7} }; | ||||||
|  | #endif | ||||||
| BOOL CreatePartition(HANDLE hDrive) | BOOL CreatePartition(HANDLE hDrive) | ||||||
| { | { | ||||||
|  | 	CREATE_DISK CreateDisk = {PARTITION_STYLE_RAW, {0}}; | ||||||
| 	DRIVE_LAYOUT_INFORMATION_EX4 DriveLayoutEx = {0}; | 	DRIVE_LAYOUT_INFORMATION_EX4 DriveLayoutEx = {0}; | ||||||
| 	BOOL r; | 	BOOL r; | ||||||
| 	DWORD size; | 	DWORD size; | ||||||
| 	LONGLONG sector_size; | 	LONGLONG size_in_sectors; | ||||||
|  | 	int pt = (int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme)); | ||||||
|  | 
 | ||||||
|  | 	PrintStatus(0, TRUE, "Partitioning (%s)...",  PartitionSchemeName[pt]); | ||||||
|  | 
 | ||||||
|  | 	if ((pt == PT_GPT) || (!IsChecked(IDC_EXTRA_PARTITION))) { | ||||||
|  | 		// Go with the MS 1 MB wastage at the beginning...
 | ||||||
|  | 		DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart = 1024*1024; | ||||||
|  | 	} else { | ||||||
|  | 		// Align on Cylinder
 | ||||||
|  | 		DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart =  | ||||||
|  | 			SelectedDrive.Geometry.BytesPerSector * SelectedDrive.Geometry.SectorsPerTrack; | ||||||
|  | 	} | ||||||
|  | 	size_in_sectors = (SelectedDrive.DiskSize - DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart) / SelectedDrive.Geometry.BytesPerSector; | ||||||
|  | 
 | ||||||
|  | 	switch (pt) { | ||||||
|  | 	case PT_MBR: | ||||||
|  | 		CreateDisk.PartitionStyle = PARTITION_STYLE_MBR; | ||||||
|  | 		CreateDisk.Mbr.Signature = GetTickCount(); | ||||||
| 
 | 
 | ||||||
| 	PrintStatus(0, TRUE, "Partitioning..."); |  | ||||||
| 		DriveLayoutEx.PartitionStyle = PARTITION_STYLE_MBR; | 		DriveLayoutEx.PartitionStyle = PARTITION_STYLE_MBR; | ||||||
| 		DriveLayoutEx.PartitionCount = 4;	// Must be multiple of 4 for MBR
 | 		DriveLayoutEx.PartitionCount = 4;	// Must be multiple of 4 for MBR
 | ||||||
| 	DriveLayoutEx.Type.Mbr.Signature = GetTickCount(); | 		DriveLayoutEx.Type.Mbr.Signature = CreateDisk.Mbr.Signature; | ||||||
| 		DriveLayoutEx.PartitionEntry[0].PartitionStyle = PARTITION_STYLE_MBR; | 		DriveLayoutEx.PartitionEntry[0].PartitionStyle = PARTITION_STYLE_MBR; | ||||||
| 		// TODO: CHS fixup (32 sectors/track) through a cheat mode, if requested
 | 		// TODO: CHS fixup (32 sectors/track) through a cheat mode, if requested
 | ||||||
| 		// NB: disk geometry is computed by BIOS & co. by finding a match between LBA and CHS value of first partition
 | 		// NB: disk geometry is computed by BIOS & co. by finding a match between LBA and CHS value of first partition
 | ||||||
| 		//     ms-sys's write_partition_number_of_heads() and write_partition_start_sector_number() can be used if needed
 | 		//     ms-sys's write_partition_number_of_heads() and write_partition_start_sector_number() can be used if needed
 | ||||||
| 
 | 
 | ||||||
| 	DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart =  |  | ||||||
| 		SelectedDrive.Geometry.BytesPerSector * SelectedDrive.Geometry.SectorsPerTrack; |  | ||||||
| 	sector_size = (SelectedDrive.DiskSize - DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart) / SelectedDrive.Geometry.BytesPerSector; |  | ||||||
| 		// Align on sector boundary if the extra part option is checked
 | 		// Align on sector boundary if the extra part option is checked
 | ||||||
| 		if (IsChecked(IDC_EXTRA_PARTITION)) { | 		if (IsChecked(IDC_EXTRA_PARTITION)) { | ||||||
| 		sector_size = ((sector_size / SelectedDrive.Geometry.SectorsPerTrack)-1) * SelectedDrive.Geometry.SectorsPerTrack; | 			size_in_sectors = ((size_in_sectors / SelectedDrive.Geometry.SectorsPerTrack)-1) * SelectedDrive.Geometry.SectorsPerTrack; | ||||||
| 		if (sector_size <= 0) return FALSE; | 			if (size_in_sectors <= 0) | ||||||
|  | 				return FALSE; | ||||||
| 		} | 		} | ||||||
| 	DriveLayoutEx.PartitionEntry[0].PartitionLength.QuadPart = sector_size * SelectedDrive.Geometry.BytesPerSector; | 		break; | ||||||
|  | 	case PT_GPT: | ||||||
|  | 		CreateDisk.PartitionStyle = PARTITION_STYLE_GPT; | ||||||
|  | 		IGNORE_RETVAL(CoCreateGuid(&CreateDisk.Gpt.DiskId)); | ||||||
|  | 		CreateDisk.Gpt.MaxPartitionCount = MAX_GPT_PARTITIONS; | ||||||
|  | 
 | ||||||
|  | 		DriveLayoutEx.PartitionStyle = PARTITION_STYLE_GPT; | ||||||
|  | 		DriveLayoutEx.PartitionCount = 1; | ||||||
|  | 		// At the very least, a GPT disk has atv least 34 reserved (512 bytes) blocks at the beginning
 | ||||||
|  | 		// and 33 at the end.
 | ||||||
|  | 		DriveLayoutEx.Type.Gpt.StartingUsableOffset.QuadPart = 34*512; | ||||||
|  | 		DriveLayoutEx.Type.Gpt.UsableLength.QuadPart = SelectedDrive.DiskSize - (34+33)*512; | ||||||
|  | 		DriveLayoutEx.Type.Gpt.MaxPartitionCount = MAX_GPT_PARTITIONS; | ||||||
|  | 		DriveLayoutEx.Type.Gpt.DiskId = CreateDisk.Gpt.DiskId; | ||||||
|  | 		DriveLayoutEx.PartitionEntry[0].PartitionStyle = PARTITION_STYLE_GPT; | ||||||
|  | 
 | ||||||
|  | 		size_in_sectors -= 33;	// Need 33 sectors at the end for secondary GPT
 | ||||||
|  | 		break; | ||||||
|  | 	default: | ||||||
|  | 		break; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	DriveLayoutEx.PartitionEntry[0].PartitionLength.QuadPart = size_in_sectors * SelectedDrive.Geometry.BytesPerSector; | ||||||
| 	DriveLayoutEx.PartitionEntry[0].PartitionNumber = 1; | 	DriveLayoutEx.PartitionEntry[0].PartitionNumber = 1; | ||||||
| 	DriveLayoutEx.PartitionEntry[0].RewritePartition = TRUE; | 	DriveLayoutEx.PartitionEntry[0].RewritePartition = TRUE; | ||||||
|  | 
 | ||||||
|  | 	switch (pt) { | ||||||
|  | 	case PT_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: | ||||||
|  | @ -647,7 +715,6 @@ BOOL CreatePartition(HANDLE hDrive) | ||||||
| 			uprintf("Unsupported file system\n"); | 			uprintf("Unsupported file system\n"); | ||||||
| 			return FALSE; | 			return FALSE; | ||||||
| 		} | 		} | ||||||
| 
 |  | ||||||
| 		// Create an extra partition on request - can improve BIOS detection as HDD for older BIOSes
 | 		// Create an extra partition on request - can improve BIOS detection as HDD for older BIOSes
 | ||||||
| 		if (IsChecked(IDC_EXTRA_PARTITION)) { | 		if (IsChecked(IDC_EXTRA_PARTITION)) { | ||||||
| 			DriveLayoutEx.PartitionEntry[1].PartitionStyle = PARTITION_STYLE_MBR; | 			DriveLayoutEx.PartitionEntry[1].PartitionStyle = PARTITION_STYLE_MBR; | ||||||
|  | @ -660,12 +727,31 @@ BOOL CreatePartition(HANDLE hDrive) | ||||||
| 			DriveLayoutEx.PartitionEntry[1].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack*SelectedDrive.Geometry.BytesPerSector; | 			DriveLayoutEx.PartitionEntry[1].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack*SelectedDrive.Geometry.BytesPerSector; | ||||||
| 			DriveLayoutEx.PartitionEntry[1].Mbr.PartitionType = DriveLayoutEx.PartitionEntry[0].Mbr.PartitionType + 0x10;	// Hidden whatever
 | 			DriveLayoutEx.PartitionEntry[1].Mbr.PartitionType = DriveLayoutEx.PartitionEntry[0].Mbr.PartitionType + 0x10;	// Hidden whatever
 | ||||||
| 		} | 		} | ||||||
| 
 |  | ||||||
| 		// For the remaining partitions, PartitionStyle & PartitionType have already
 | 		// For the remaining partitions, PartitionStyle & PartitionType have already
 | ||||||
| 	// been zeroed => set to MBR/unused
 | 		// been zeroed => already set to MBR/unused
 | ||||||
|  | 		break; | ||||||
|  | 	case PT_GPT: | ||||||
|  | 		DriveLayoutEx.PartitionEntry[0].Gpt.PartitionType = PARTITION_BASIC_DATA_GUID; | ||||||
|  | 		wcscpy(DriveLayoutEx.PartitionEntry[0].Gpt.Name, L"Microsoft Basic Data"); | ||||||
|  | 		IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[0].Gpt.PartitionId)); | ||||||
|  | 		break; | ||||||
|  | 	default: | ||||||
|  | 		break; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
|  | 	// If you don't call IOCTL_DISK_CREATE_DISK, the next call will fail
 | ||||||
|  | 	size = sizeof(CreateDisk); | ||||||
|  | 	r = DeviceIoControl(hDrive, IOCTL_DISK_CREATE_DISK, | ||||||
|  | 			(BYTE*)&CreateDisk, size, NULL, 0, &size, NULL ); | ||||||
|  | 	if (!r) { | ||||||
|  | 		uprintf("IOCTL_DISK_CREATE_DISK failed: %s\n", WindowsErrorString()); | ||||||
|  | 		safe_closehandle(hDrive); | ||||||
|  | 		return FALSE; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	size = sizeof(DriveLayoutEx) - ((pt == PT_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, sizeof(DriveLayoutEx), NULL, 0, &size, NULL ); | 			(BYTE*)&DriveLayoutEx, size, NULL, 0, &size, NULL ); | ||||||
| 	if (!r) { | 	if (!r) { | ||||||
| 		uprintf("IOCTL_DISK_SET_DRIVE_LAYOUT_EX failed: %s\n", WindowsErrorString()); | 		uprintf("IOCTL_DISK_SET_DRIVE_LAYOUT_EX failed: %s\n", WindowsErrorString()); | ||||||
| 		safe_closehandle(hDrive); | 		safe_closehandle(hDrive); | ||||||
|  | @ -1072,7 +1158,7 @@ static void EnableControls(BOOL bEnable) | ||||||
| 	int fs; | 	int fs; | ||||||
| 
 | 
 | ||||||
| 	EnableWindow(GetDlgItem(hMainDialog, IDC_DEVICE), bEnable); | 	EnableWindow(GetDlgItem(hMainDialog, IDC_DEVICE), bEnable); | ||||||
| 	EnableWindow(GetDlgItem(hMainDialog, IDC_PARTITION), bEnable); | 	EnableWindow(GetDlgItem(hMainDialog, IDC_PARTITION_SCHEME), bEnable); | ||||||
| 	EnableWindow(GetDlgItem(hMainDialog, IDC_FILESYSTEM), bEnable); | 	EnableWindow(GetDlgItem(hMainDialog, IDC_FILESYSTEM), bEnable); | ||||||
| 	EnableWindow(GetDlgItem(hMainDialog, IDC_CLUSTERSIZE), bEnable); | 	EnableWindow(GetDlgItem(hMainDialog, IDC_CLUSTERSIZE), bEnable); | ||||||
| 	EnableWindow(GetDlgItem(hMainDialog, IDC_LABEL), bEnable); | 	EnableWindow(GetDlgItem(hMainDialog, IDC_LABEL), bEnable); | ||||||
|  | @ -1268,8 +1354,8 @@ DWORD WINAPI ISOScanThread(LPVOID param) | ||||||
| 		safe_free(iso_path); | 		safe_free(iso_path); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 	uprintf("ISO label: '%s'\r\n  Size: %lld bytes\r\n  Has a >4GB file: %s\r\n  Uses Bootmgr: %s\r\n  Uses WinPE: %s%s\r\n  Uses isolinux: %s\n", | 	uprintf("ISO label: '%s'\r\n  Size: %lld bytes\r\n  Has a >4GB file: %s\r\n  Uses EFI: %s\r\n  Uses Bootmgr: %s\r\n  Uses WinPE: %s%s\r\n  Uses isolinux: %s\n", | ||||||
| 		iso_report.label, iso_report.projected_size, iso_report.has_4GB_file?"Yes":"No", iso_report.has_bootmgr?"Yes":"No", | 		iso_report.label, iso_report.projected_size, iso_report.has_4GB_file?"Yes":"No",  iso_report.has_efi?"Yes":"No", iso_report.has_bootmgr?"Yes":"No", | ||||||
| 		IS_WINPE(iso_report.winpe)?"Yes":"No", (iso_report.uses_minint)?" (with /minint)":"", iso_report.has_isolinux?"Yes":"No"); | 		IS_WINPE(iso_report.winpe)?"Yes":"No", (iso_report.uses_minint)?" (with /minint)":"", iso_report.has_isolinux?"Yes":"No"); | ||||||
| 	if (iso_report.has_isolinux) { | 	if (iso_report.has_isolinux) { | ||||||
| 		for (i=0; i<NB_OLD_C32; i++) { | 		for (i=0; i<NB_OLD_C32; i++) { | ||||||
|  | @ -1404,7 +1490,7 @@ void InitDialog(HWND hDlg) | ||||||
| 	// Quite a burden to carry around as parameters
 | 	// Quite a burden to carry around as parameters
 | ||||||
| 	hMainDialog = hDlg; | 	hMainDialog = hDlg; | ||||||
| 	hDeviceList = GetDlgItem(hDlg, IDC_DEVICE); | 	hDeviceList = GetDlgItem(hDlg, IDC_DEVICE); | ||||||
| 	hPartition = GetDlgItem(hDlg, IDC_PARTITION); | 	hPartitionScheme = GetDlgItem(hDlg, IDC_PARTITION_SCHEME); | ||||||
| 	hFileSystem = GetDlgItem(hDlg, IDC_FILESYSTEM); | 	hFileSystem = GetDlgItem(hDlg, IDC_FILESYSTEM); | ||||||
| 	hClusterSize = GetDlgItem(hDlg, IDC_CLUSTERSIZE); | 	hClusterSize = GetDlgItem(hDlg, IDC_CLUSTERSIZE); | ||||||
| 	hLabel = GetDlgItem(hDlg, IDC_LABEL); | 	hLabel = GetDlgItem(hDlg, IDC_LABEL); | ||||||
|  | @ -1549,7 +1635,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, i, nWidth, nHeight; | 	int nDeviceIndex, fs, pt, 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; | ||||||
|  | @ -1694,10 +1780,12 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
|  | 		case IDC_PARTITION_SCHEME: | ||||||
| 		case IDC_FILESYSTEM: | 		case IDC_FILESYSTEM: | ||||||
| 			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)); | ||||||
| 			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)) { | ||||||
|  | @ -1722,7 +1810,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| 			if (fs == FS_EXFAT) { | 			if ((fs == FS_EXFAT) || ((pt == PT_GPT) && (fs == FS_NTFS)))  { | ||||||
| 				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)); | ||||||
|  | @ -1734,13 +1822,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 ((fs == FS_FAT16) || (fs == FS_FAT32)) { | 			if ((pt == PT_MBR) && ((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 ( ((fs == FS_FAT16) || (fs == FS_FAT32)) && (advanced_mode) ) | 			if ( (pt == PT_MBR) && (((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; | ||||||
|  | @ -1833,7 +1921,13 @@ 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)); | ||||||
| 						if ((fs == FS_NTFS) && (!iso_report.has_bootmgr) && (!IS_WINPE(iso_report.winpe))) { | 						pt = (int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme)); | ||||||
|  | 						if ((pt == PT_GPT) && ((!iso_report.has_efi) || ((fs > FS_FAT32)))) { | ||||||
|  | 							MessageBoxA(hMainDialog, "When using GPT, only EFI bootable ISOs are supported. " | ||||||
|  | 								"Please select an EFI bootable ISO or change the Partition Scheme to MBR.", "Unsupported GPT ISO...", MB_OK|MB_ICONERROR); | ||||||
|  | 							break; | ||||||
|  | 						} | ||||||
|  | 						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 FAT32 is supported for this type of ISO. " | ||||||
| 									"Please revert the filesystem back from NTFS to FAT32.", "Unsupported filesystem...", MB_OK|MB_ICONERROR); | 									"Please revert the filesystem back from NTFS to FAT32.", "Unsupported filesystem...", MB_OK|MB_ICONERROR); | ||||||
|  | @ -1842,7 +1936,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 									"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)) { | 						} else if (((fs == FS_FAT16)||(fs == FS_FAT32)) && ((!iso_report.has_isolinux) && (pt != PT_GPT))) { | ||||||
| 							MessageBoxA(hMainDialog, "Only 'isolinux' based ISO " | 							MessageBoxA(hMainDialog, "Only 'isolinux' based ISO " | ||||||
| 								"images can currently be used with FAT.", "Unsupported ISO...", MB_OK|MB_ICONERROR); | 								"images can currently be used with FAT.", "Unsupported ISO...", MB_OK|MB_ICONERROR); | ||||||
| 							break; | 							break; | ||||||
|  |  | ||||||
							
								
								
									
										14
									
								
								src/rufus.h
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								src/rufus.h
									
										
									
									
									
								
							|  | @ -42,6 +42,9 @@ | ||||||
| #define MAX_TOOLTIPS                32 | #define MAX_TOOLTIPS                32 | ||||||
| #define MAX_PROGRESS                (0xFFFF-1)	// leave room for 1 more for insta-progress workaround
 | #define MAX_PROGRESS                (0xFFFF-1)	// leave room for 1 more for insta-progress workaround
 | ||||||
| #define MAX_LOG_SIZE                0x7FFFFFFE | #define MAX_LOG_SIZE                0x7FFFFFFE | ||||||
|  | #define MAX_GUID_STRING_LENGTH      40 | ||||||
|  | #define MAX_GPT_PARTITIONS          128 | ||||||
|  | #define MAX_SECTORS_TO_CLEAR        128			// nb sectors to zap when clearing the MBR/GPT (must be >34)
 | ||||||
| #define PROPOSEDLABEL_TOLERANCE     0.10 | #define PROPOSEDLABEL_TOLERANCE     0.10 | ||||||
| #define FS_DEFAULT                  FS_FAT32 | #define FS_DEFAULT                  FS_FAT32 | ||||||
| #define LARGE_FAT32_SIZE            (32*1073741824LL)	// Size at which we need to use fat32format
 | #define LARGE_FAT32_SIZE            (32*1073741824LL)	// Size at which we need to use fat32format
 | ||||||
|  | @ -147,6 +150,12 @@ enum dos_type { | ||||||
| 	DT_MAX | 	DT_MAX | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | enum part_type { | ||||||
|  | 	PT_MBR = 0, | ||||||
|  | 	PT_GPT, | ||||||
|  | 	PT_MAX | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| /* Current drive info */ | /* Current drive info */ | ||||||
| typedef struct { | typedef struct { | ||||||
| 	DWORD DeviceNumber; | 	DWORD DeviceNumber; | ||||||
|  | @ -154,6 +163,7 @@ typedef struct { | ||||||
| 	DISK_GEOMETRY Geometry; | 	DISK_GEOMETRY Geometry; | ||||||
| 	DWORD FirstSector; | 	DWORD FirstSector; | ||||||
| 	char proposed_label[16]; | 	char proposed_label[16]; | ||||||
|  | 	int PartitionType; | ||||||
| 	int FSType; | 	int FSType; | ||||||
| 	struct { | 	struct { | ||||||
| 		ULONG Allowed; | 		ULONG Allowed; | ||||||
|  | @ -180,6 +190,7 @@ typedef struct { | ||||||
| 	uint8_t winpe; | 	uint8_t winpe; | ||||||
| 	BOOL has_4GB_file; | 	BOOL has_4GB_file; | ||||||
| 	BOOL has_bootmgr; | 	BOOL has_bootmgr; | ||||||
|  | 	BOOL has_efi; | ||||||
| 	BOOL has_isolinux; | 	BOOL has_isolinux; | ||||||
| 	BOOL has_autorun; | 	BOOL has_autorun; | ||||||
| 	BOOL has_old_c32[NB_OLD_C32]; | 	BOOL has_old_c32[NB_OLD_C32]; | ||||||
|  | @ -221,7 +232,7 @@ enum WindowsVersion { | ||||||
|  */ |  */ | ||||||
| extern HINSTANCE hMainInstance; | extern HINSTANCE hMainInstance; | ||||||
| extern HWND hMainDialog, hLogDlg, hStatus, hDeviceList, hCapacity; | extern HWND hMainDialog, hLogDlg, hStatus, hDeviceList, hCapacity; | ||||||
| extern HWND hFileSystem, hClusterSize, hLabel, hDOSType, hNBPasses, hLog; | extern HWND hPartitionScheme, hFileSystem, hClusterSize, hLabel, hDOSType, hNBPasses, hLog; | ||||||
| extern HWND hISOProgressDlg, hISOProgressBar, hISOFileName, hDiskID; | extern HWND hISOProgressDlg, hISOProgressBar, hISOFileName, hDiskID; | ||||||
| extern float fScale; | extern float fScale; | ||||||
| extern char szFolderPath[MAX_PATH], app_dir[MAX_PATH]; | extern char szFolderPath[MAX_PATH], app_dir[MAX_PATH]; | ||||||
|  | @ -246,6 +257,7 @@ extern void DumpBufferHex(void *buf, size_t size); | ||||||
| extern void PrintStatus(unsigned int duration, BOOL debug, const char *format, ...); | extern void PrintStatus(unsigned int duration, BOOL debug, const char *format, ...); | ||||||
| extern void UpdateProgress(int op, float percent); | extern void UpdateProgress(int op, float percent); | ||||||
| extern const char* StrError(DWORD error_code); | extern const char* StrError(DWORD error_code); | ||||||
|  | extern char* GuidToString(const GUID* guid); | ||||||
| extern void CenterDialog(HWND hDlg); | extern void CenterDialog(HWND hDlg); | ||||||
| extern void CreateStatusBar(void); | extern void CreateStatusBar(void); | ||||||
| extern void SetTitleBarIcon(HWND hDlg); | extern void SetTitleBarIcon(HWND hDlg); | ||||||
|  |  | ||||||
							
								
								
									
										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.222" | CAPTION "Rufus v1.3.1.223" | ||||||
| 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 | ||||||
|  | @ -39,7 +39,7 @@ BEGIN | ||||||
|     CONTROL         "Device",IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,9,6,22,8 |     CONTROL         "Device",IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,9,6,22,8 | ||||||
|     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,8,46,190,30,CBS_DROPDOWNLIST | CBS_SORT | 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",IDC_STATIC,9,35,75,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 | ||||||
|  | @ -274,8 +274,8 @@ END | ||||||
| // | // | ||||||
| 
 | 
 | ||||||
| VS_VERSION_INFO VERSIONINFO | VS_VERSION_INFO VERSIONINFO | ||||||
|  FILEVERSION 1,3,1,222 |  FILEVERSION 1,3,1,223 | ||||||
|  PRODUCTVERSION 1,3,1,222 |  PRODUCTVERSION 1,3,1,223 | ||||||
|  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.222" |             VALUE "FileVersion", "1.3.1.223" | ||||||
|             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.222" |             VALUE "ProductVersion", "1.3.1.223" | ||||||
|         END |         END | ||||||
|     END |     END | ||||||
|     BLOCK "VarFileInfo" |     BLOCK "VarFileInfo" | ||||||
|  |  | ||||||
							
								
								
									
										12
									
								
								src/stdio.c
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								src/stdio.c
									
										
									
									
									
								
							|  | @ -177,6 +177,18 @@ void PrintStatus(unsigned int duration, BOOL debug, const char *format, ...) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | char* GuidToString(const GUID* guid) | ||||||
|  | { | ||||||
|  | 	static char guid_string[MAX_GUID_STRING_LENGTH]; | ||||||
|  | 
 | ||||||
|  | 	if (guid == NULL) return NULL; | ||||||
|  | 	sprintf(guid_string, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", | ||||||
|  | 		(unsigned int)guid->Data1, guid->Data2, guid->Data3, | ||||||
|  | 		guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], | ||||||
|  | 		guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); | ||||||
|  | 	return guid_string; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| const char* StrError(DWORD error_code) | const char* StrError(DWORD error_code) | ||||||
| { | { | ||||||
| 	if ( (!IS_ERROR(error_code)) || (SCODE_CODE(error_code) == ERROR_SUCCESS)) { | 	if ( (!IS_ERROR(error_code)) || (SCODE_CODE(error_code) == ERROR_SUCCESS)) { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue