mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[format] add large FAT32 support
* Based on fat32format from Ridgecrop Consultants Ltd: http://www.ridgecrop.demon.co.uk/index.htm?fat32format.htm * Initial implementation by Tom Ehlert of DriveSnapshot: http://www.drivesnapshot.de/en/index.htm * Closes #101
This commit is contained in:
		
							parent
							
								
									8dc5429d9f
								
							
						
					
					
						commit
						22800bb8a5
					
				
					 6 changed files with 473 additions and 29 deletions
				
			
		
							
								
								
									
										381
									
								
								src/format.c
									
										
									
									
									
								
							
							
						
						
									
										381
									
								
								src/format.c
									
										
									
									
									
								
							|  | @ -1,6 +1,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) 2011-2012 Pete Batard <pete@akeo.ie> |  * Copyright (c) 2011-2012 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 | ||||||
|  | @ -251,6 +252,349 @@ static void ToValidLabel(WCHAR* name, BOOL bFAT) | ||||||
| 	wchar_to_utf8_no_alloc(name, iso_report.usb_label, sizeof(iso_report.usb_label)); | 	wchar_to_utf8_no_alloc(name, iso_report.usb_label, sizeof(iso_report.usb_label)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * 28.2  CALCULATING THE VOLUME SERIAL NUMBER | ||||||
|  |  * | ||||||
|  |  * For example, say a disk was formatted on 26 Dec 95 at 9:55 PM and 41.94 | ||||||
|  |  * seconds.  DOS takes the date and time just before it writes it to the | ||||||
|  |  * disk. | ||||||
|  |  *  | ||||||
|  |  * Low order word is calculated:               Volume Serial Number is: | ||||||
|  |  * Month & Day         12/26   0c1ah | ||||||
|  |  * Sec & Hundrenths    41:94   295eh               3578:1d02 | ||||||
|  |  * ----- | ||||||
|  |  * 3578h | ||||||
|  |  *  | ||||||
|  |  * High order word is calculated: | ||||||
|  |  * Hours & Minutes     21:55   1537h | ||||||
|  |  * Year                1995    07cbh | ||||||
|  |  * ----- | ||||||
|  |  * 1d02h | ||||||
|  |  */ | ||||||
|  | static DWORD GetVolumeID(void) | ||||||
|  | { | ||||||
|  | 	SYSTEMTIME s; | ||||||
|  | 	DWORD d; | ||||||
|  | 	WORD lo,hi,tmp; | ||||||
|  | 
 | ||||||
|  | 	GetLocalTime(&s); | ||||||
|  | 
 | ||||||
|  | 	lo = s.wDay + (s.wMonth << 8); | ||||||
|  | 	tmp = (s.wMilliseconds/10) + (s.wSecond << 8); | ||||||
|  | 	lo += tmp; | ||||||
|  | 
 | ||||||
|  | 	hi = s.wMinute + (s.wHour << 8); | ||||||
|  | 	hi += s.wYear; | ||||||
|  | 
 | ||||||
|  | 	d = lo + (hi << 16); | ||||||
|  | 	return d; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * This is the Microsoft calculation from FATGEN | ||||||
|  |  *  | ||||||
|  |  * DWORD RootDirSectors = 0; | ||||||
|  |  * DWORD TmpVal1, TmpVal2, FATSz; | ||||||
|  |  * | ||||||
|  |  * TmpVal1 = DskSize - (ReservedSecCnt + RootDirSectors); | ||||||
|  |  * TmpVal2 = (256 * SecPerClus) + NumFATs; | ||||||
|  |  * TmpVal2 = TmpVal2 / 2; | ||||||
|  |  * FATSz = (TmpVal1 + (TmpVal2 - 1)) / TmpVal2; | ||||||
|  |  * | ||||||
|  |  * return( FatSz ); | ||||||
|  |  */ | ||||||
|  | static DWORD GetFATSizeSectors(DWORD DskSize, DWORD ReservedSecCnt, DWORD SecPerClus, DWORD NumFATs, DWORD BytesPerSect) | ||||||
|  | { | ||||||
|  | 	ULONGLONG Numerator, Denominator; | ||||||
|  | 	ULONGLONG FatElementSize = 4; | ||||||
|  | 	ULONGLONG FatSz; | ||||||
|  | 
 | ||||||
|  | 	// This is based on 
 | ||||||
|  | 	// http://hjem.get2net.dk/rune_moeller_barnkob/filesystems/fat.html
 | ||||||
|  | 	Numerator = FatElementSize * (DskSize - ReservedSecCnt); | ||||||
|  | 	Denominator = (SecPerClus * BytesPerSect) + (FatElementSize * NumFATs); | ||||||
|  | 	FatSz = Numerator / Denominator; | ||||||
|  | 	// round up
 | ||||||
|  | 	FatSz += 1; | ||||||
|  | 
 | ||||||
|  | 	return (DWORD)FatSz; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Large FAT32 volume formatting from fat32format by Tom Thornhill | ||||||
|  |  * http://www.ridgecrop.demon.co.uk/index.htm?fat32format.htm
 | ||||||
|  |  */ | ||||||
|  | // TODO: disable slow format for > 32 GB FAT32
 | ||||||
|  | static BOOL FormatFAT32(DWORD DriveIndex) | ||||||
|  | { | ||||||
|  | 	BOOL r = FALSE; | ||||||
|  | 	char DriveLetter; | ||||||
|  | 	DWORD i; | ||||||
|  | 	HANDLE hLogicalVolume; | ||||||
|  | 	DWORD cbRet; | ||||||
|  | 	DISK_GEOMETRY dgDrive; | ||||||
|  | 	PARTITION_INFORMATION piDrive; | ||||||
|  | 	// Recommended values
 | ||||||
|  | 	DWORD ReservedSectCount = 32; | ||||||
|  | 	DWORD NumFATs = 2; | ||||||
|  | 	DWORD BackupBootSect = 6; | ||||||
|  | 	DWORD VolumeId = 0; // calculated before format
 | ||||||
|  | 	WCHAR wLabel[64], wDriveName[] = L"#:\\"; | ||||||
|  | 	DWORD BurstSize = 128; // Zero in blocks of 64K typically
 | ||||||
|  | 
 | ||||||
|  | 	// Calculated later
 | ||||||
|  | 	DWORD FatSize = 0;  | ||||||
|  | 	DWORD BytesPerSect = 0; | ||||||
|  | 	DWORD ClusterSize = 0; | ||||||
|  | 	DWORD SectorsPerCluster = 0; | ||||||
|  | 	DWORD TotalSectors = 0; | ||||||
|  | 	DWORD SystemAreaSize = 0; | ||||||
|  | 	DWORD UserAreaSize = 0; | ||||||
|  | 	ULONGLONG qTotalSectors = 0; | ||||||
|  | 
 | ||||||
|  | 	// Structures to be written to the disk
 | ||||||
|  | 	FAT_BOOTSECTOR32 *pFAT32BootSect = NULL; | ||||||
|  | 	FAT_FSINFO *pFAT32FsInfo = NULL; | ||||||
|  | 	DWORD *pFirstSectOfFat = NULL; | ||||||
|  | 	BYTE* pZeroSect = NULL; | ||||||
|  | 	char VolId[12] = "NO NAME    "; | ||||||
|  | 
 | ||||||
|  | 	// Debug temp vars
 | ||||||
|  | 	ULONGLONG FatNeeded, ClusterCount; | ||||||
|  | 
 | ||||||
|  | 	PrintStatus(0, TRUE, "Formatting..."); | ||||||
|  | 	uprintf("Using large FAT32 format method\n"); | ||||||
|  | 	VolumeId = GetVolumeID(); | ||||||
|  | 
 | ||||||
|  | 	// Open the drive (volume should already be locked)
 | ||||||
|  | 	hLogicalVolume = GetDriveHandle(DriveIndex, &DriveLetter, TRUE, FALSE); | ||||||
|  | 	if (IS_ERROR(FormatStatus)) goto out; | ||||||
|  | 	if (hLogicalVolume == INVALID_HANDLE_VALUE) | ||||||
|  | 		die("Could not access logical volume\n", ERROR_OPEN_FAILED); | ||||||
|  | 
 | ||||||
|  | 	// Make sure we get exclusive access
 | ||||||
|  | 	if (!UnmountDrive(hLogicalVolume)) | ||||||
|  | 		return r; | ||||||
|  | 
 | ||||||
|  | 	// Work out drive params
 | ||||||
|  | 	if (!DeviceIoControl (hLogicalVolume, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &dgDrive, | ||||||
|  | 		sizeof(dgDrive), &cbRet, NULL)) { | ||||||
|  | 		die("Failed to get device geometry\n", ERROR_NOT_SUPPORTED); | ||||||
|  | 	} | ||||||
|  | 	if (IS_ERROR(FormatStatus)) goto out; | ||||||
|  | 	if (!DeviceIoControl (hLogicalVolume, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &piDrive, | ||||||
|  | 		sizeof(piDrive), &cbRet, NULL)) { | ||||||
|  | 		die("Failed to get parition info\n", ERROR_NOT_SUPPORTED); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	BytesPerSect = dgDrive.BytesPerSector; | ||||||
|  | 
 | ||||||
|  | 	// Checks on Disk Size
 | ||||||
|  | 	qTotalSectors = piDrive.PartitionLength.QuadPart/dgDrive.BytesPerSector; | ||||||
|  | 	// Low end limit - 65536 sectors
 | ||||||
|  | 	if (qTotalSectors < 65536) { | ||||||
|  | 		// Most FAT32 implementations would probably mount this volume just fine,
 | ||||||
|  | 		// but the spec says that we shouldn't do this, so we won't
 | ||||||
|  | 		die("This drive is too small for FAT32 - there must be at least 64K clusters\n", APPERR(ERROR_INVALID_CLUSTER_SIZE)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (qTotalSectors >= 0xffffffff) { | ||||||
|  | 		// This is a more fundamental limitation on FAT32 - the total sector count in the root dir
 | ||||||
|  | 		// ís 32bit. With a bit of creativity, FAT32 could be extended to handle at least 2^28 clusters
 | ||||||
|  | 		// There would need to be an extra field in the FSInfo sector, and the old sector count could
 | ||||||
|  | 		// be set to 0xffffffff. This is non standard though, the Windows FAT driver FASTFAT.SYS won't
 | ||||||
|  | 		// understand this. Perhaps a future version of FAT32 and FASTFAT will handle this.
 | ||||||
|  | 		die ("This drive is too big for FAT32 - max 2TB supported\n", APPERR(ERROR_INVALID_VOLUME_SIZE)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	pFAT32BootSect = (FAT_BOOTSECTOR32*) calloc(BytesPerSect, 1); | ||||||
|  | 	pFAT32FsInfo = (FAT_FSINFO*) calloc(BytesPerSect, 1); | ||||||
|  | 	pFirstSectOfFat = (DWORD*) calloc(BytesPerSect, 1); | ||||||
|  | 	if (!pFAT32BootSect || !pFAT32FsInfo || !pFirstSectOfFat) { | ||||||
|  | 		die("Failed to allocate memory\n", ERROR_NOT_ENOUGH_MEMORY); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// fill out the boot sector and fs info
 | ||||||
|  | 	pFAT32BootSect->sJmpBoot[0]=0xEB; | ||||||
|  | 	pFAT32BootSect->sJmpBoot[1]=0x5A; | ||||||
|  | 	pFAT32BootSect->sJmpBoot[2]=0x90; | ||||||
|  | 	strncpy((char*)pFAT32BootSect->sOEMName, "MSWIN4.1", 8); | ||||||
|  | 	pFAT32BootSect->wBytsPerSec = (WORD) BytesPerSect; | ||||||
|  | 
 | ||||||
|  | 	ClusterSize = ComboBox_GetItemData(hClusterSize, ComboBox_GetCurSel(hClusterSize)); | ||||||
|  | 	SectorsPerCluster = ClusterSize / BytesPerSect; | ||||||
|  | 
 | ||||||
|  | 	pFAT32BootSect->bSecPerClus = (BYTE) SectorsPerCluster ; | ||||||
|  | 	pFAT32BootSect->wRsvdSecCnt = (WORD) ReservedSectCount; | ||||||
|  | 	pFAT32BootSect->bNumFATs = (BYTE) NumFATs; | ||||||
|  | 	pFAT32BootSect->wRootEntCnt = 0; | ||||||
|  | 	pFAT32BootSect->wTotSec16 = 0; | ||||||
|  | 	pFAT32BootSect->bMedia = 0xF8; | ||||||
|  | 	pFAT32BootSect->wFATSz16 = 0; | ||||||
|  | 	pFAT32BootSect->wSecPerTrk = (WORD) dgDrive.SectorsPerTrack; | ||||||
|  | 	pFAT32BootSect->wNumHeads = (WORD) dgDrive.TracksPerCylinder; | ||||||
|  | 	pFAT32BootSect->dHiddSec = (DWORD) piDrive.HiddenSectors; | ||||||
|  | 	TotalSectors = (DWORD)  (piDrive.PartitionLength.QuadPart/dgDrive.BytesPerSector); | ||||||
|  | 	pFAT32BootSect->dTotSec32 = TotalSectors; | ||||||
|  | 
 | ||||||
|  | 	FatSize = GetFATSizeSectors(pFAT32BootSect->dTotSec32, pFAT32BootSect->wRsvdSecCnt,  | ||||||
|  | 		pFAT32BootSect->bSecPerClus, pFAT32BootSect->bNumFATs, BytesPerSect); | ||||||
|  | 
 | ||||||
|  | 	pFAT32BootSect->dFATSz32 = FatSize; | ||||||
|  | 	pFAT32BootSect->wExtFlags = 0; | ||||||
|  | 	pFAT32BootSect->wFSVer = 0; | ||||||
|  | 	pFAT32BootSect->dRootClus = 2; | ||||||
|  | 	pFAT32BootSect->wFSInfo = 1; | ||||||
|  | 	pFAT32BootSect->wBkBootSec = (WORD) BackupBootSect; | ||||||
|  | 	pFAT32BootSect->bDrvNum = 0x80; | ||||||
|  | 	pFAT32BootSect->Reserved1 = 0; | ||||||
|  | 	pFAT32BootSect->bBootSig = 0x29; | ||||||
|  | 
 | ||||||
|  | 	pFAT32BootSect->dBS_VolID = VolumeId; | ||||||
|  | 	memcpy(pFAT32BootSect->sVolLab, VolId, 11); | ||||||
|  | 	memcpy(pFAT32BootSect->sBS_FilSysType, "FAT32   ", 8); | ||||||
|  | 	((BYTE*)pFAT32BootSect)[510] = 0x55; | ||||||
|  | 	((BYTE*)pFAT32BootSect)[511] = 0xaa; | ||||||
|  | 
 | ||||||
|  | 	// FATGEN103.DOC says "NOTE: Many FAT documents mistakenly say that this 0xAA55 signature occupies the "last 2 bytes of 
 | ||||||
|  | 	// the boot sector". This statement is correct if - and only if - BPB_BytsPerSec is 512. If BPB_BytsPerSec is greater than 
 | ||||||
|  | 	// 512, the offsets of these signature bytes do not change (although it is perfectly OK for the last two bytes at the end 
 | ||||||
|  | 	// of the boot sector to also contain this signature)." 
 | ||||||
|  | 	// 
 | ||||||
|  | 	// Windows seems to only check the bytes at offsets 510 and 511. Other OSs might check the ones at the end of the sector,
 | ||||||
|  | 	// so we'll put them there too.
 | ||||||
|  | 	if (BytesPerSect != 512) { | ||||||
|  | 		((BYTE*)pFAT32BootSect)[BytesPerSect-2] = 0x55; | ||||||
|  | 		((BYTE*)pFAT32BootSect)[BytesPerSect-1] = 0xaa; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// FSInfo sect
 | ||||||
|  | 	pFAT32FsInfo->dLeadSig = 0x41615252; | ||||||
|  | 	pFAT32FsInfo->dStrucSig = 0x61417272; | ||||||
|  | 	pFAT32FsInfo->dFree_Count = (DWORD) -1; | ||||||
|  | 	pFAT32FsInfo->dNxt_Free = (DWORD) -1; | ||||||
|  | 	pFAT32FsInfo->dTrailSig = 0xaa550000; | ||||||
|  | 
 | ||||||
|  | 	// First FAT Sector
 | ||||||
|  | 	pFirstSectOfFat[0] = 0x0ffffff8;  // Reserved cluster 1 media id in low byte
 | ||||||
|  | 	pFirstSectOfFat[1] = 0x0fffffff;  // Reserved cluster 2 EOC
 | ||||||
|  | 	pFirstSectOfFat[2] = 0x0fffffff;  // end of cluster chain for root dir
 | ||||||
|  | 
 | ||||||
|  | 	// Write boot sector, fats
 | ||||||
|  | 	// Sector 0 Boot Sector
 | ||||||
|  | 	// Sector 1 FSInfo 
 | ||||||
|  | 	// Sector 2 More boot code - we write zeros here
 | ||||||
|  | 	// Sector 3 unused
 | ||||||
|  | 	// Sector 4 unused
 | ||||||
|  | 	// Sector 5 unused
 | ||||||
|  | 	// Sector 6 Backup boot sector
 | ||||||
|  | 	// Sector 7 Backup FSInfo sector
 | ||||||
|  | 	// Sector 8 Backup 'more boot code'
 | ||||||
|  | 	// zero'd sectors upto ReservedSectCount
 | ||||||
|  | 	// FAT1  ReservedSectCount to ReservedSectCount + FatSize
 | ||||||
|  | 	// ...
 | ||||||
|  | 	// FATn  ReservedSectCount to ReservedSectCount + FatSize
 | ||||||
|  | 	// RootDir - allocated to cluster2
 | ||||||
|  | 
 | ||||||
|  | 	UserAreaSize = TotalSectors - ReservedSectCount - (NumFATs*FatSize); | ||||||
|  | 	ClusterCount = UserAreaSize / SectorsPerCluster; | ||||||
|  | 
 | ||||||
|  | 	// Sanity check for a cluster count of >2^28, since the upper 4 bits of the cluster values in 
 | ||||||
|  | 	// the FAT are reserved.
 | ||||||
|  | 	if (ClusterCount > 0x0FFFFFFF) { | ||||||
|  | 		die("This drive has more than 2^28 clusters, try to specify a larger cluster size or use the default\n", | ||||||
|  | 			ERROR_INVALID_CLUSTER_SIZE); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Sanity check - < 64K clusters means that the volume will be misdetected as FAT16
 | ||||||
|  | 	if (ClusterCount < 65536) { | ||||||
|  | 		die("FAT32 must have at least 65536 clusters, try to specify a smaller cluster size or use the default\n", | ||||||
|  | 			ERROR_INVALID_CLUSTER_SIZE); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Sanity check, make sure the fat is big enough
 | ||||||
|  | 	// Convert the cluster count into a Fat sector count, and check the fat size value we calculated 
 | ||||||
|  | 	// earlier is OK.
 | ||||||
|  | 	FatNeeded = ClusterCount * 4; | ||||||
|  | 	FatNeeded += (BytesPerSect-1); | ||||||
|  | 	FatNeeded /= BytesPerSect; | ||||||
|  | 	if (FatNeeded > FatSize) { | ||||||
|  | 		die("This drive is too big for large FAT32 format\n", APPERR(ERROR_INVALID_VOLUME_SIZE)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Now we're commited - print some info first
 | ||||||
|  | 	uprintf("Size : %gGB %u sectors\n", (double) (piDrive.PartitionLength.QuadPart / (1000*1000*1000)), TotalSectors); | ||||||
|  | 	uprintf("Cluster size %d bytes, %d Bytes Per Sector\n", SectorsPerCluster*BytesPerSect, BytesPerSect); | ||||||
|  | 	uprintf("Volume ID is %x:%x\n", VolumeId>>16, VolumeId&0xffff); | ||||||
|  | 	uprintf("%d Reserved Sectors, %d Sectors per FAT, %d FATs\n", ReservedSectCount, FatSize, NumFATs); | ||||||
|  | 	uprintf("%d Total clusters\n", ClusterCount); | ||||||
|  | 
 | ||||||
|  | 	// Fix up the FSInfo sector
 | ||||||
|  | 	pFAT32FsInfo->dFree_Count = (UserAreaSize/SectorsPerCluster) - 1; | ||||||
|  | 	pFAT32FsInfo->dNxt_Free = 3; // clusters 0-1 resered, we used cluster 2 for the root dir
 | ||||||
|  | 
 | ||||||
|  | 	uprintf("%d Free Clusters\n", pFAT32FsInfo->dFree_Count); | ||||||
|  | 	// Work out the Cluster count
 | ||||||
|  | 
 | ||||||
|  | 	// First zero out ReservedSect + FatSize * NumFats + SectorsPerCluster
 | ||||||
|  | 	SystemAreaSize = ReservedSectCount + (NumFATs*FatSize) + SectorsPerCluster; | ||||||
|  | 	uprintf("Clearing out %d sectors for reserved sectors, FATs and root cluster...\n", SystemAreaSize); | ||||||
|  | 
 | ||||||
|  | 	// Not the most effective, but easy on RAM
 | ||||||
|  | 	pZeroSect = (BYTE*)calloc(BytesPerSect, BurstSize); | ||||||
|  | 	if (!pZeroSect) { | ||||||
|  | 		die("Failed to allocate memory\n", ERROR_NOT_ENOUGH_MEMORY); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	format_percent = 0.0f; | ||||||
|  | 	for (i=0; i<(SystemAreaSize+BurstSize-1); i+=BurstSize) { | ||||||
|  | 		format_percent = (100.0f*i)/(1.0f*(SystemAreaSize+BurstSize)); | ||||||
|  | 		PrintStatus(0, FALSE, "Formatting: %d%% completed.", (int)format_percent); | ||||||
|  | 		UpdateProgress(OP_FORMAT, format_percent); | ||||||
|  | 		if (IS_ERROR(FormatStatus)) goto out;	// For cancellation
 | ||||||
|  | 		if (write_sectors(hLogicalVolume, BytesPerSect, i, BurstSize, pZeroSect) != (BytesPerSect*BurstSize)) { | ||||||
|  | 			die("Error clearing reserved sectors\n", ERROR_WRITE_FAULT); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	uprintf ("Initialising reserved sectors and FATs...\n"); | ||||||
|  | 	// Now we should write the boot sector and fsinfo twice, once at 0 and once at the backup boot sect position
 | ||||||
|  | 	for (i=0; i<2; i++) { | ||||||
|  | 		int SectorStart = (i==0) ? 0 : BackupBootSect; | ||||||
|  | 		write_sectors(hLogicalVolume, BytesPerSect, SectorStart, 1, pFAT32BootSect); | ||||||
|  | 		write_sectors(hLogicalVolume, BytesPerSect, SectorStart+1, 1, pFAT32FsInfo); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Write the first fat sector in the right places
 | ||||||
|  | 	for ( i=0; i<NumFATs; i++ ) { | ||||||
|  | 		int SectorStart = ReservedSectCount + (i * FatSize ); | ||||||
|  | 		uprintf("FAT #%d sector at address: %d\n", i, SectorStart); | ||||||
|  | 		write_sectors(hLogicalVolume, BytesPerSect, SectorStart, 1, pFirstSectOfFat); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Set the FAT32 volume label
 | ||||||
|  | 	GetWindowTextW(hLabel, wLabel, ARRAYSIZE(wLabel)); | ||||||
|  | 	ToValidLabel(wLabel, TRUE); | ||||||
|  | 	wDriveName[0] = DriveLetter; | ||||||
|  | 	// Handle must be closed for SetVolumeLabel to work
 | ||||||
|  | 	safe_closehandle(hLogicalVolume); | ||||||
|  | 
 | ||||||
|  | 	PrintStatus(0, TRUE, "Setting Label (This can take while)..."); | ||||||
|  | 	if (!SetVolumeLabelW(wDriveName, wLabel)) { | ||||||
|  | 		uprintf("Could not set label: %s\n", WindowsErrorString()); | ||||||
|  | 	} | ||||||
|  | 	uprintf("Format completed.\n"); | ||||||
|  | 	r = TRUE; | ||||||
|  | 
 | ||||||
|  | out: | ||||||
|  | 	safe_closehandle(hLogicalVolume); | ||||||
|  | 	safe_free(pFAT32BootSect); | ||||||
|  | 	safe_free(pFAT32FsInfo); | ||||||
|  | 	safe_free(pFirstSectOfFat); | ||||||
|  | 	safe_free(pZeroSect); | ||||||
|  | 	return r; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Call on fmifs.dll's FormatEx() to format the drive |  * Call on fmifs.dll's FormatEx() to format the drive | ||||||
|  */ |  */ | ||||||
|  | @ -398,11 +742,24 @@ static BOOL AnalyzePBR(HANDLE hLogicalVolume) | ||||||
| 
 | 
 | ||||||
| static BOOL ClearMBR(HANDLE hPhysicalDrive) | static BOOL ClearMBR(HANDLE hPhysicalDrive) | ||||||
| { | { | ||||||
| 	FILE fake_fd = { 0 }; | 	BOOL r = FALSE; | ||||||
|  | 	// Clearing the first 64K seems to help with reluctant access to large drive
 | ||||||
|  | 	size_t SectorSize = 65536; | ||||||
|  | 	unsigned char* pBuf = (unsigned char*) calloc(SectorSize, 1); | ||||||
| 
 | 
 | ||||||
| 	fake_fd._ptr = (char*)hPhysicalDrive; | 	PrintStatus(0, TRUE, "Clearing MBR..."); | ||||||
| 	fake_fd._bufsiz = SelectedDrive.Geometry.BytesPerSector; | 	if (pBuf == NULL) { | ||||||
| 	return clear_mbr(&fake_fd); | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_ENOUGH_MEMORY; | ||||||
|  | 		goto out; | ||||||
|  | 	} | ||||||
|  | 	if ((IS_ERROR(FormatStatus)) || (write_sectors(hPhysicalDrive, SectorSize, 0, 1, pBuf) != SectorSize)) { | ||||||
|  | 		goto out; | ||||||
|  | 	} | ||||||
|  | 	r = TRUE; | ||||||
|  | 
 | ||||||
|  | out: | ||||||
|  | 	safe_free(pBuf); | ||||||
|  | 	return r; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  | @ -741,6 +1098,10 @@ static BOOL RemountVolume(char drive_letter) | ||||||
|  */ |  */ | ||||||
| DWORD WINAPI FormatThread(LPVOID param) | DWORD WINAPI FormatThread(LPVOID param) | ||||||
| { | { | ||||||
|  | 	int r; | ||||||
|  | 	int fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); | ||||||
|  | 	int dt = (int)ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)); | ||||||
|  | 	BOOL ret; | ||||||
| 	DWORD num = (DWORD)(uintptr_t)param; | 	DWORD num = (DWORD)(uintptr_t)param; | ||||||
| 	HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE; | 	HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE; | ||||||
| 	HANDLE hLogicalVolume = INVALID_HANDLE_VALUE; | 	HANDLE hLogicalVolume = INVALID_HANDLE_VALUE; | ||||||
|  | @ -749,7 +1110,6 @@ DWORD WINAPI FormatThread(LPVOID param) | ||||||
| 	char bb_msg[512]; | 	char bb_msg[512]; | ||||||
| 	char logfile[MAX_PATH], *userdir; | 	char logfile[MAX_PATH], *userdir; | ||||||
| 	FILE* log_fd; | 	FILE* log_fd; | ||||||
| 	int r, fs, dt; |  | ||||||
| 
 | 
 | ||||||
| 	hPhysicalDrive = GetDriveHandle(num, NULL, TRUE, TRUE); | 	hPhysicalDrive = GetDriveHandle(num, NULL, TRUE, TRUE); | ||||||
| 	if (hPhysicalDrive == INVALID_HANDLE_VALUE) { | 	if (hPhysicalDrive == INVALID_HANDLE_VALUE) { | ||||||
|  | @ -839,7 +1199,8 @@ DWORD WINAPI FormatThread(LPVOID param) | ||||||
| 	// before repartitioning. Else, all kind of bad things happen
 | 	// before repartitioning. Else, all kind of bad things happen
 | ||||||
| 	if (!ClearMBR(hPhysicalDrive)) { | 	if (!ClearMBR(hPhysicalDrive)) { | ||||||
| 		uprintf("unable to zero MBR\n"); | 		uprintf("unable to zero MBR\n"); | ||||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT; | 		if (!FormatStatus) | ||||||
|  | 			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT; | ||||||
| 		goto out; | 		goto out; | ||||||
| 	}  | 	}  | ||||||
| 	UpdateProgress(OP_ZERO_MBR, -1.0f); | 	UpdateProgress(OP_ZERO_MBR, -1.0f); | ||||||
|  | @ -853,7 +1214,11 @@ DWORD WINAPI FormatThread(LPVOID param) | ||||||
| 	// Add a small delay after partitioning to be safe
 | 	// Add a small delay after partitioning to be safe
 | ||||||
| 	Sleep(200); | 	Sleep(200); | ||||||
| 
 | 
 | ||||||
| 	if (!FormatDrive(drive_name[0])) { | 	// If FAT32 is requested and we have a large drive (>32 GB) use 
 | ||||||
|  | 	// large FAT32 format, else use MS's FormatEx.
 | ||||||
|  | 	ret = ((fs == FS_FAT32) && (SelectedDrive.DiskSize > LARGE_FAT32_SIZE))? | ||||||
|  | 		FormatFAT32(num):FormatDrive(drive_name[0]); | ||||||
|  | 	if (!ret) { | ||||||
| 		// Error will be set by FormatDrive() in FormatStatus
 | 		// Error will be set by FormatDrive() in FormatStatus
 | ||||||
| 		uprintf("Format error: %s\n", StrError(FormatStatus)); | 		uprintf("Format error: %s\n", StrError(FormatStatus)); | ||||||
| 		goto out; | 		goto out; | ||||||
|  | @ -867,8 +1232,6 @@ DWORD WINAPI FormatThread(LPVOID param) | ||||||
| 	} | 	} | ||||||
| 	UpdateProgress(OP_FIX_MBR, -1.0f); | 	UpdateProgress(OP_FIX_MBR, -1.0f); | ||||||
| 
 | 
 | ||||||
| 	fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); |  | ||||||
| 	dt = (int)ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)); |  | ||||||
| 	if (IsChecked(IDC_DOS)) { | 	if (IsChecked(IDC_DOS)) { | ||||||
| 		if ((dt == DT_WINME) || (dt == DT_FREEDOS) || ((dt == DT_ISO) && (fs == FS_NTFS))) { | 		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 
 | ||||||
|  |  | ||||||
							
								
								
									
										51
									
								
								src/format.h
									
										
									
									
									
								
							
							
						
						
									
										51
									
								
								src/format.h
									
										
									
									
									
								
							|  | @ -1,6 +1,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) 2011-2012 Pete Batard <pete@akeo.ie> |  * Copyright (c) 2011-2012 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 | ||||||
|  | @ -103,3 +104,53 @@ typedef BOOLEAN (WINAPI* EnableVolumeCompression_t)( | ||||||
| 	WCHAR*          DriveRoot, | 	WCHAR*          DriveRoot, | ||||||
| 	ULONG           CompressionFlags	// FILE_SYSTEM_PROP_FLAG
 | 	ULONG           CompressionFlags	// FILE_SYSTEM_PROP_FLAG
 | ||||||
| ); | ); | ||||||
|  | 
 | ||||||
|  | /* Large FAT32 */ | ||||||
|  | #pragma pack(push, 1) | ||||||
|  | typedef struct tagFAT_BOOTSECTOR32 | ||||||
|  | { | ||||||
|  | 	// Common fields.
 | ||||||
|  | 	BYTE sJmpBoot[3]; | ||||||
|  | 	BYTE sOEMName[8]; | ||||||
|  | 	WORD wBytsPerSec; | ||||||
|  | 	BYTE bSecPerClus; | ||||||
|  | 	WORD wRsvdSecCnt; | ||||||
|  | 	BYTE bNumFATs; | ||||||
|  | 	WORD wRootEntCnt; | ||||||
|  | 	WORD wTotSec16;           // if zero, use dTotSec32 instead
 | ||||||
|  | 	BYTE bMedia; | ||||||
|  | 	WORD wFATSz16; | ||||||
|  | 	WORD wSecPerTrk; | ||||||
|  | 	WORD wNumHeads; | ||||||
|  | 	DWORD dHiddSec; | ||||||
|  | 	DWORD dTotSec32; | ||||||
|  | 	// Fat 32/16 only
 | ||||||
|  | 	DWORD dFATSz32; | ||||||
|  | 	WORD wExtFlags; | ||||||
|  | 	WORD wFSVer; | ||||||
|  | 	DWORD dRootClus; | ||||||
|  | 	WORD wFSInfo; | ||||||
|  | 	WORD wBkBootSec; | ||||||
|  | 	BYTE Reserved[12]; | ||||||
|  | 	BYTE bDrvNum; | ||||||
|  | 	BYTE Reserved1; | ||||||
|  | 	BYTE bBootSig;           // == 0x29 if next three fields are ok
 | ||||||
|  | 	DWORD dBS_VolID; | ||||||
|  | 	BYTE sVolLab[11]; | ||||||
|  | 	BYTE sBS_FilSysType[8]; | ||||||
|  | } FAT_BOOTSECTOR32; | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  | 	DWORD dLeadSig;         // 0x41615252
 | ||||||
|  | 	BYTE sReserved1[480];   // zeros
 | ||||||
|  | 	DWORD dStrucSig;        // 0x61417272
 | ||||||
|  | 	DWORD dFree_Count;      // 0xFFFFFFFF
 | ||||||
|  | 	DWORD dNxt_Free;        // 0xFFFFFFFF
 | ||||||
|  | 	BYTE sReserved2[12];    // zeros
 | ||||||
|  | 	DWORD dTrailSig;        // 0xAA550000
 | ||||||
|  | } FAT_FSINFO; | ||||||
|  | #pragma pack(pop) | ||||||
|  | 
 | ||||||
|  | #define die(msg, err) do { uprintf(msg); \ | ||||||
|  | 	FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|err; \ | ||||||
|  | 	goto out; } while(0) | ||||||
|  |  | ||||||
|  | @ -42,6 +42,10 @@ const char* additional_copyrights = | ||||||
| "http://e2fsprogs.sourceforge.net\r\n" | "http://e2fsprogs.sourceforge.net\r\n" | ||||||
| "GNU General Public License (GPL) v3 compatible\r\n" | "GNU General Public License (GPL) v3 compatible\r\n" | ||||||
| "\r\n" | "\r\n" | ||||||
|  | "Large FAT32 volume formatting from fat32format by Tom Thornhill:\r\n" | ||||||
|  | "http://www.ridgecrop.demon.co.uk/index.htm?fat32format.htm\r\n" | ||||||
|  | "GNU General Public License (GPL) v2 or later\r\n" | ||||||
|  | "\r\n" | ||||||
| "fmifs.dll usage based on Formatx by Mark Russinovich:\r\n" | "fmifs.dll usage based on Formatx by Mark Russinovich:\r\n" | ||||||
| "http://doc.sch130.nsc.ru/www.sysinternals.com/ntw2k/source/fmifs.shtml\r\n" | "http://doc.sch130.nsc.ru/www.sysinternals.com/ntw2k/source/fmifs.shtml\r\n" | ||||||
| "http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/libs/fmifs\r\n" | "http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/libs/fmifs\r\n" | ||||||
|  |  | ||||||
							
								
								
									
										53
									
								
								src/rufus.c
									
										
									
									
									
								
							
							
						
						
									
										53
									
								
								src/rufus.c
									
										
									
									
									
								
							|  | @ -124,7 +124,7 @@ static int64_t last_iso_blocking_status; | ||||||
|  */ |  */ | ||||||
| static int nb_slots[OP_MAX]; | static int nb_slots[OP_MAX]; | ||||||
| static float slot_end[OP_MAX+1];	// shifted +1 so that we can substract 1 to OP indexes
 | static float slot_end[OP_MAX+1];	// shifted +1 so that we can substract 1 to OP indexes
 | ||||||
| static float previous_end = 0.0f; | static float previous_end; | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Convert a partition type to its human readable form using |  * Convert a partition type to its human readable form using | ||||||
|  | @ -164,7 +164,7 @@ static BOOL DefineClusterSizes(void) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * The following is MS's allowed cluster sizes for FAT16 and FAT32: |  * The following are MS's allowed cluster sizes for FAT16 and FAT32: | ||||||
|  * |  * | ||||||
|  * FAT16 |  * FAT16 | ||||||
|  * 31M  :  512 - 4096 |  * 31M  :  512 - 4096 | ||||||
|  | @ -188,8 +188,9 @@ static BOOL DefineClusterSizes(void) | ||||||
|  * 4095M: 1024 - 32k |  * 4095M: 1024 - 32k | ||||||
|  * 7GB  : 2048 - 64k |  * 7GB  : 2048 - 64k | ||||||
|  * 15GB : 4096 - 64k |  * 15GB : 4096 - 64k | ||||||
|  * 31GB : 8192 - 64k |  * 31GB : 8192 - 64k This is as far as Microsoft's FormatEx goes... | ||||||
|  * 32GB+: possible but N/A from Microsoft (see below) |  * 63GB :  16k - 64k ...but we can go higher using fat32format from RidgeCrop. | ||||||
|  |  * 2TB+ : N/A | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| 	// FAT 16
 | 	// FAT 16
 | ||||||
|  | @ -206,10 +207,11 @@ static BOOL DefineClusterSizes(void) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// FAT 32
 | 	// FAT 32
 | ||||||
| 	// > 32GB FAT32 is not supported by MS (and likely FormatEx) but is feasible
 | 	// > 32GB FAT32 is not supported by MS and FormatEx but is achieved using fat32fomat
 | ||||||
| 	// See: http://www.ridgecrop.demon.co.uk/index.htm?fat32format.htm
 | 	// See: http://www.ridgecrop.demon.co.uk/index.htm?fat32format.htm
 | ||||||
| 	// < 32 MB FAT32 is not allowed by FormatEx
 | 	// < 32 MB FAT32 is not allowed by FormatEx, so we don't bother
 | ||||||
| 	if ((SelectedDrive.DiskSize >= 32*MB) && (SelectedDrive.DiskSize < 32*GB)) { | 
 | ||||||
|  | 	if ((SelectedDrive.DiskSize >= 32*MB) && (SelectedDrive.DiskSize < 2*TB)) { | ||||||
| 		SelectedDrive.ClusterSize[FS_FAT32].Allowed = 0x000001F8; | 		SelectedDrive.ClusterSize[FS_FAT32].Allowed = 0x000001F8; | ||||||
| 		for (i=32; i<=(32*1024); i<<=1) {			// 32 MB -> 32 GB
 | 		for (i=32; i<=(32*1024); i<<=1) {			// 32 MB -> 32 GB
 | ||||||
| 			if (SelectedDrive.DiskSize < i*MB) { | 			if (SelectedDrive.DiskSize < i*MB) { | ||||||
|  | @ -221,7 +223,7 @@ static BOOL DefineClusterSizes(void) | ||||||
| 		SelectedDrive.ClusterSize[FS_FAT32].Allowed &= 0x0001FE00; | 		SelectedDrive.ClusterSize[FS_FAT32].Allowed &= 0x0001FE00; | ||||||
| 
 | 
 | ||||||
| 		// Default cluster sizes in the 256MB to 32 GB range do not follow the rule above
 | 		// Default cluster sizes in the 256MB to 32 GB range do not follow the rule above
 | ||||||
| 		if (SelectedDrive.DiskSize >= 256*MB) { | 		if ((SelectedDrive.DiskSize >= 256*MB) && (SelectedDrive.DiskSize < 32*GB)) { | ||||||
| 			for (i=8; i<=32; i<<=1) {				// 256 MB -> 32 GB
 | 			for (i=8; i<=32; i<<=1) {				// 256 MB -> 32 GB
 | ||||||
| 				if (SelectedDrive.DiskSize < i*GB) { | 				if (SelectedDrive.DiskSize < i*GB) { | ||||||
| 					SelectedDrive.ClusterSize[FS_FAT32].Default = ((ULONG)i/2)*1024; | 					SelectedDrive.ClusterSize[FS_FAT32].Default = ((ULONG)i/2)*1024; | ||||||
|  | @ -229,6 +231,11 @@ static BOOL DefineClusterSizes(void) | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 		// More adjustments for large drives
 | ||||||
|  | 		if (SelectedDrive.DiskSize >= 32*GB) { | ||||||
|  | 			SelectedDrive.ClusterSize[FS_FAT32].Allowed &= 0x0001C000; | ||||||
|  | 			SelectedDrive.ClusterSize[FS_FAT32].Default = 0x00008000; | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// NTFS
 | 	// NTFS
 | ||||||
|  | @ -484,12 +491,10 @@ static void SetFSFromISO(void) | ||||||
| 
 | 
 | ||||||
| void SetMBRProps(void) | void SetMBRProps(void) | ||||||
| { | { | ||||||
| 	int fs, dt; | 	int fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); | ||||||
|  | 	int dt = (int)ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)); | ||||||
| 	BOOL needs_masquerading = (IS_WINPE(iso_report.winpe) && (!iso_report.uses_minint)); | 	BOOL needs_masquerading = (IS_WINPE(iso_report.winpe) && (!iso_report.uses_minint)); | ||||||
| 
 | 
 | ||||||
| 	fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); |  | ||||||
| 	dt = (int)ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)); |  | ||||||
| 
 |  | ||||||
| 	if ((!mbr_selected_by_user) && ((iso_path == NULL) || (dt != DT_ISO) || (fs != FS_NTFS))) { | 	if ((!mbr_selected_by_user) && ((iso_path == NULL) || (dt != DT_ISO) || (fs != FS_NTFS))) { | ||||||
| 		CheckDlgButton(hMainDialog, IDC_RUFUS_MBR, BST_UNCHECKED); | 		CheckDlgButton(hMainDialog, IDC_RUFUS_MBR, BST_UNCHECKED); | ||||||
| 		IGNORE_RETVAL(ComboBox_SetCurSel(hDiskID, 0)); | 		IGNORE_RETVAL(ComboBox_SetCurSel(hDiskID, 0)); | ||||||
|  | @ -812,6 +817,10 @@ static void InitProgress(void) | ||||||
| 	memset(&slot_end, 0, sizeof(slot_end)); | 	memset(&slot_end, 0, sizeof(slot_end)); | ||||||
| 	previous_end = 0.0f; | 	previous_end = 0.0f; | ||||||
| 
 | 
 | ||||||
|  | 	memset(nb_slots, 0, sizeof(nb_slots)); | ||||||
|  | 	memset(slot_end, 0, sizeof(slot_end)); | ||||||
|  | 	previous_end = 0.0f; | ||||||
|  | 
 | ||||||
| 	nb_slots[OP_ZERO_MBR] = 1; | 	nb_slots[OP_ZERO_MBR] = 1; | ||||||
| 	if (IsChecked(IDC_BADBLOCKS)) { | 	if (IsChecked(IDC_BADBLOCKS)) { | ||||||
| 		nb_slots[OP_BADBLOCKS] = -1; | 		nb_slots[OP_BADBLOCKS] = -1; | ||||||
|  | @ -837,7 +846,8 @@ static void InitProgress(void) | ||||||
| 	nb_slots[OP_FIX_MBR] = 1; | 	nb_slots[OP_FIX_MBR] = 1; | ||||||
| 	nb_slots[OP_CREATE_FS] =  | 	nb_slots[OP_CREATE_FS] =  | ||||||
| 		nb_steps[ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem))]; | 		nb_steps[ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem))]; | ||||||
| 	if (!IsChecked(IDC_QUICKFORMAT)) { | 	if ( (!IsChecked(IDC_QUICKFORMAT)) | ||||||
|  | 	  || ((fs == FS_FAT32) && (SelectedDrive.DiskSize >= LARGE_FAT32_SIZE)) ) { | ||||||
| 		nb_slots[OP_FORMAT] = -1; | 		nb_slots[OP_FORMAT] = -1; | ||||||
| 	} | 	} | ||||||
| 	nb_slots[OP_FINALIZE] = ((dt == DT_ISO) && (fs == FS_NTFS))?2:1; | 	nb_slots[OP_FINALIZE] = ((dt == DT_ISO) && (fs == FS_NTFS))?2:1; | ||||||
|  | @ -1512,7 +1522,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 	int nDeviceIndex, fs, i, nWidth, nHeight; | 	int nDeviceIndex, fs, 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; | 	static UINT uDOSChecked = BST_CHECKED, uQFChecked; | ||||||
| 	static BOOL first_log_display = TRUE; | 	static BOOL first_log_display = TRUE; | ||||||
| 
 | 
 | ||||||
| 	switch (message) { | 	switch (message) { | ||||||
|  | @ -1625,6 +1635,8 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 			PrintStatus(0, TRUE, "%d device%s found.", ComboBox_GetCount(hDeviceList), | 			PrintStatus(0, TRUE, "%d device%s found.", ComboBox_GetCount(hDeviceList), | ||||||
| 				(ComboBox_GetCount(hDeviceList)!=1)?"s":""); | 				(ComboBox_GetCount(hDeviceList)!=1)?"s":""); | ||||||
| 			PopulateProperties(ComboBox_GetCurSel(hDeviceList)); | 			PopulateProperties(ComboBox_GetCurSel(hDeviceList)); | ||||||
|  | 			SendMessage(hMainDialog, WM_COMMAND, (CBN_SELCHANGE<<16) | IDC_FILESYSTEM, | ||||||
|  | 				ComboBox_GetCurSel(hFileSystem)); | ||||||
| 			break; | 			break; | ||||||
| 		case IDC_NBPASSES: | 		case IDC_NBPASSES: | ||||||
| 			if (HIWORD(wParam) != CBN_SELCHANGE) | 			if (HIWORD(wParam) != CBN_SELCHANGE) | ||||||
|  | @ -1649,6 +1661,19 @@ 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)); | ||||||
| 			SetClusterSizes(fs); | 			SetClusterSizes(fs); | ||||||
|  | 			// Disable/restore the quick format control depending on large FAT32
 | ||||||
|  | 			if ((fs == FS_FAT32) && (SelectedDrive.DiskSize > LARGE_FAT32_SIZE)) { | ||||||
|  | 				if (IsWindowEnabled(GetDlgItem(hMainDialog, IDC_QUICKFORMAT))) { | ||||||
|  | 					uQFChecked = IsDlgButtonChecked(hMainDialog, IDC_QUICKFORMAT); | ||||||
|  | 					CheckDlgButton(hMainDialog, IDC_QUICKFORMAT, BST_CHECKED); | ||||||
|  | 					EnableWindow(GetDlgItem(hMainDialog, IDC_QUICKFORMAT), FALSE); | ||||||
|  | 				} | ||||||
|  | 			} else { | ||||||
|  | 				if (!IsWindowEnabled(GetDlgItem(hMainDialog, IDC_QUICKFORMAT))) { | ||||||
|  | 					CheckDlgButton(hMainDialog, IDC_QUICKFORMAT, uQFChecked); | ||||||
|  | 					EnableWindow(GetDlgItem(hMainDialog, IDC_QUICKFORMAT), TRUE); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
| 			if (fs < 0) { | 			if (fs < 0) { | ||||||
| 				EnableBootOptions(TRUE); | 				EnableBootOptions(TRUE); | ||||||
| 				SetMBRProps(); | 				SetMBRProps(); | ||||||
|  |  | ||||||
|  | @ -37,6 +37,7 @@ | ||||||
| #define MAX_LOG_SIZE                0x7FFFFFFE | #define MAX_LOG_SIZE                0x7FFFFFFE | ||||||
| #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 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"
 | ||||||
|  |  | ||||||
							
								
								
									
										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.2.0.185" | CAPTION "Rufus v1.2.0.186" | ||||||
| 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 | ||||||
|  | @ -77,7 +77,7 @@ BEGIN | ||||||
|     DEFPUSHBUTTON   "OK",IDOK,231,175,50,14,WS_GROUP |     DEFPUSHBUTTON   "OK",IDOK,231,175,50,14,WS_GROUP | ||||||
|     CONTROL         "<a href=""http://rufus.akeo.ie"">http://rufus.akeo.ie</a>",IDC_ABOUT_RUFUS_URL, |     CONTROL         "<a href=""http://rufus.akeo.ie"">http://rufus.akeo.ie</a>",IDC_ABOUT_RUFUS_URL, | ||||||
|                     "SysLink",WS_TABSTOP,46,47,114,9 |                     "SysLink",WS_TABSTOP,46,47,114,9 | ||||||
|     LTEXT           "Version 1.2.0 (Build 185)",IDC_STATIC,46,19,78,8 |     LTEXT           "Version 1.2.0 (Build 186)",IDC_STATIC,46,19,78,8 | ||||||
|     PUSHBUTTON      "License...",IDC_ABOUT_LICENSE,46,175,50,14,WS_GROUP |     PUSHBUTTON      "License...",IDC_ABOUT_LICENSE,46,175,50,14,WS_GROUP | ||||||
|     EDITTEXT        IDC_ABOUT_COPYRIGHTS,46,107,235,63,ES_MULTILINE | ES_READONLY | WS_VSCROLL |     EDITTEXT        IDC_ABOUT_COPYRIGHTS,46,107,235,63,ES_MULTILINE | ES_READONLY | WS_VSCROLL | ||||||
|     LTEXT           "Report bugs or request enhancements at:",IDC_STATIC,46,66,187,8 |     LTEXT           "Report bugs or request enhancements at:",IDC_STATIC,46,66,187,8 | ||||||
|  | @ -237,8 +237,8 @@ END | ||||||
| // | // | ||||||
| 
 | 
 | ||||||
| VS_VERSION_INFO VERSIONINFO | VS_VERSION_INFO VERSIONINFO | ||||||
|  FILEVERSION 1,2,0,185 |  FILEVERSION 1,2,0,186 | ||||||
|  PRODUCTVERSION 1,2,0,185 |  PRODUCTVERSION 1,2,0,186 | ||||||
|  FILEFLAGSMASK 0x3fL |  FILEFLAGSMASK 0x3fL | ||||||
| #ifdef _DEBUG | #ifdef _DEBUG | ||||||
|  FILEFLAGS 0x1L |  FILEFLAGS 0x1L | ||||||
|  | @ -255,13 +255,13 @@ BEGIN | ||||||
|         BEGIN |         BEGIN | ||||||
|             VALUE "CompanyName", "akeo.ie" |             VALUE "CompanyName", "akeo.ie" | ||||||
|             VALUE "FileDescription", "Rufus" |             VALUE "FileDescription", "Rufus" | ||||||
|             VALUE "FileVersion", "1.2.0.185" |             VALUE "FileVersion", "1.2.0.186" | ||||||
|             VALUE "InternalName", "Rufus" |             VALUE "InternalName", "Rufus" | ||||||
|             VALUE "LegalCopyright", "© 2011 Pete Batard (GPL v3)" |             VALUE "LegalCopyright", "© 2011 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.2.0.185" |             VALUE "ProductVersion", "1.2.0.186" | ||||||
|         END |         END | ||||||
|     END |     END | ||||||
|     BLOCK "VarFileInfo" |     BLOCK "VarFileInfo" | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue