mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[ui] improve the allowed cluster sizes
* follow what MS/FormatEx actually allow * closes #15 * also fixed potential empty selection in cluster size dropdown * also improved Local Group Policy handling
This commit is contained in:
		
							parent
							
								
									72485b7568
								
							
						
					
					
						commit
						d59854ef4f
					
				
					 4 changed files with 110 additions and 69 deletions
				
			
		
							
								
								
									
										13
									
								
								TODO
									
										
									
									
									
								
							
							
						
						
									
										13
									
								
								TODO
									
										
									
									
									
								
							|  | @ -1,9 +1,10 @@ | |||
| o create a report file with failed block details when bad blocks are found | ||||
| o use the umount/remount trick to make the volume reappear post formatting | ||||
| o set keyboard according to locale in DOS | ||||
| o allow selection of one of the existing compatible volume (keep existing MBR) / full repartitioning (overwrite MBR) | ||||
| o FreeDOS integration | ||||
| o Enable compression for NTFS | ||||
| o Create a report file with failed block details on bad blocks | ||||
| o Integrate FreeDOS | ||||
| o Allow the provision of external DOS files | ||||
| o Set DOS keyboard according to locale | ||||
| o Allow selection of one of the existing compatible partitions (keep existing MBR) vs. full repartitioning (overwrite MBR) | ||||
| o Bootable NTFS/exFAT (http://sourceforge.net/projects/grub4dos)? | ||||
| o GPT support? | ||||
| o Enable compression for NTFS? | ||||
| o disable indexing support on NTFS? | ||||
| o FAT32 formatting for volumes > 32 GB? | ||||
|  |  | |||
|  | @ -61,7 +61,6 @@ static BOOLEAN __stdcall FormatExCallback(FILE_SYSTEM_CALLBACK_COMMAND Command, | |||
| 
 | ||||
| 	switch(Command) { | ||||
| 	case FCC_PROGRESS: | ||||
| 		// TODO: send this percentage to the status bar
 | ||||
| 		percent = (DWORD*)pData; | ||||
| 		PrintStatus(0, "Formatting: %d%% completed.\n", *percent); | ||||
| //		uprintf("%d percent completed.\n", *percent);
 | ||||
|  |  | |||
							
								
								
									
										93
									
								
								src/rufus.c
									
										
									
									
									
								
							
							
						
						
									
										93
									
								
								src/rufus.c
									
										
									
									
									
								
							|  | @ -105,35 +105,70 @@ static BOOL DefineClusterSizes(void) | |||
| 	default_fs = FS_UNKNOWN; | ||||
| 	memset(&SelectedDrive.ClusterSize, 0, sizeof(SelectedDrive.ClusterSize)); | ||||
| 	if (SelectedDrive.DiskSize < 8*MB) { | ||||
| 		// TODO: muck with FAT12 and Small FAT16 like Microsoft does
 | ||||
| 		uprintf("This application does not support volumes smaller than 8 MB yet\n"); | ||||
| 		// TODO: muck with FAT12 and Small FAT16 like Microsoft does to support small drives?
 | ||||
| 		uprintf("This application does not support volumes smaller than 8 MB\n"); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| /*
 | ||||
|  * The following is MS's allowed cluster sizes for FAT16 and FAT32: | ||||
|  * | ||||
|  * FAT16 | ||||
|  * 31M  :  512 - 4096 | ||||
|  * 63M  : 1024 - 8192 | ||||
|  * 127M : 2048 - 16k | ||||
|  * 255M : 4096 - 32k | ||||
|  * 511M : 8192 - 64k | ||||
|  * 1023M:  16k - 64k | ||||
|  * 2047M:  32k - 64k | ||||
|  * 4095M:  64k | ||||
|  * 4GB+ : N/A | ||||
|  * | ||||
|  * FAT32 | ||||
|  * 31M  : N/A | ||||
|  * 63M  : N/A			(NB unlike MS, we're allowing 512-512 here - UNTESTED) | ||||
|  * 127M :  512 - 1024 | ||||
|  * 255M :  512 - 2048 | ||||
|  * 511M :  512 - 4096 | ||||
|  * 1023M:  512 - 8192 | ||||
|  * 2047M:  512 - 16k | ||||
|  * 4095M: 1024 - 32k | ||||
|  * 7GB  : 2048 - 64k | ||||
|  * 15GB : 4096 - 64k | ||||
|  * 31GB : 8192 - 64k | ||||
|  * 32GB+: possible but N/A from Microsoft (see below) | ||||
|  */ | ||||
| 
 | ||||
| 	// FAT 16
 | ||||
| 	if (SelectedDrive.DiskSize < 4*GB) { | ||||
| 		// TODO: Refine the following according to size
 | ||||
| 		SelectedDrive.ClusterSize[FS_FAT16].Allowed = 0x0001FE00; | ||||
| 		SelectedDrive.ClusterSize[FS_FAT16].Allowed = 0x00001E00; | ||||
| 		for (i=32; i<=4096; i<<=1) {			// 8 MB -> 4 GB
 | ||||
| 			if (SelectedDrive.DiskSize < i*MB) { | ||||
| 				SelectedDrive.ClusterSize[FS_FAT16].Default = 16*(ULONG)i; | ||||
| 				break; | ||||
| 			} | ||||
| 			SelectedDrive.ClusterSize[FS_FAT16].Allowed <<= 1; | ||||
| 		} | ||||
| 		SelectedDrive.ClusterSize[FS_FAT16].Allowed &= 0x0001FE00; | ||||
| 	} | ||||
| 
 | ||||
| 	// FAT 32
 | ||||
| 	if (SelectedDrive.DiskSize < 256*MB) { | ||||
| 		// TODO: Refine the following according to size
 | ||||
| 		SelectedDrive.ClusterSize[FS_FAT32].Allowed = 0x0001FE00; | ||||
| 		for (i=64; i<=256; i<<=1) {				// 8 MB -> 256 MB
 | ||||
| 	// > 32GB FAT32 is not supported by MS (and likely FormatEx) but is feasible
 | ||||
| 	// See: http://www.ridgecrop.demon.co.uk/index.htm?fat32format.htm
 | ||||
| 	// < 32 MB FAT32 is not allowed by FormatEx
 | ||||
| 	if ((SelectedDrive.DiskSize >= 32*MB) && (SelectedDrive.DiskSize < 32*GB)) { | ||||
| 		SelectedDrive.ClusterSize[FS_FAT32].Allowed = 0x000001F8; | ||||
| 		for (i=32; i<=(32*1024); i<<=1) {			// 32 MB -> 32 GB
 | ||||
| 			if (SelectedDrive.DiskSize < i*MB) { | ||||
| 				SelectedDrive.ClusterSize[FS_FAT32].Default = 8*(ULONG)i; | ||||
| 				break; | ||||
| 			} | ||||
| 			SelectedDrive.ClusterSize[FS_FAT32].Allowed <<= 1; | ||||
| 		} | ||||
| 	} else if (SelectedDrive.DiskSize < 32*GB) { | ||||
| 		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
 | ||||
| 		if (SelectedDrive.DiskSize >= 256*MB) { | ||||
| 			for (i=8; i<=32; i<<=1) {				// 256 MB -> 32 GB
 | ||||
| 				if (SelectedDrive.DiskSize < i*GB) { | ||||
| 					SelectedDrive.ClusterSize[FS_FAT32].Default = ((ULONG)i/2)*1024; | ||||
|  | @ -141,6 +176,7 @@ static BOOL DefineClusterSizes(void) | |||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// NTFS
 | ||||
| 	if (SelectedDrive.DiskSize < 256*TB) { | ||||
|  | @ -192,7 +228,7 @@ out: | |||
| static BOOL SetClusterSizes(int FSType) | ||||
| { | ||||
| 	char szClustSize[64]; | ||||
| 	int i, default_index = 0; | ||||
| 	int i, k, default_index = 0; | ||||
| 	ULONG j; | ||||
| 
 | ||||
| 	IGNORE_RETVAL(ComboBox_ResetContent(hClusterSize)); | ||||
|  | @ -208,14 +244,15 @@ static BOOL SetClusterSizes(int FSType) | |||
| 		return FALSE; | ||||
| 	} | ||||
| 
 | ||||
| 	for(i=0,j=0x200;j<0x10000000;i++,j<<=1) { | ||||
| 	for(i=0,j=0x200,k=0;j<0x10000000;i++,j<<=1) { | ||||
| 		if (j & SelectedDrive.ClusterSize[FSType].Allowed) { | ||||
| 			safe_sprintf(szClustSize, sizeof(szClustSize), "%s", ClusterSizeLabel[i]); | ||||
| 			if (j == SelectedDrive.ClusterSize[FSType].Default) { | ||||
| 				safe_strcat(szClustSize, sizeof(szClustSize), " (Default)"); | ||||
| 				default_index = i; | ||||
| 				default_index = k; | ||||
| 			} | ||||
| 			IGNORE_RETVAL(ComboBox_SetItemData(hClusterSize, ComboBox_AddStringU(hClusterSize, szClustSize), j)); | ||||
| 			k++; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -663,16 +700,15 @@ void UpdateProgress(int op, float percent) | |||
| /*
 | ||||
|  * Set or restore a Local Group Policy DWORD key indexed by szPath/SzPolicy | ||||
|  */ | ||||
| #pragma push_macro("INTERFACE") | ||||
| #undef  INTERFACE | ||||
| #define INTERFACE IGroupPolicyObject | ||||
| #define REGISTRY_EXTENSION_GUID { 0x35378EAC, 0x683F, 0x11D2, {0xA8, 0x9A, 0x00, 0xC0, 0x4F, 0xBB, 0xCF, 0xA2} } | ||||
| #define GPO_OPEN_LOAD_REGISTRY  1 | ||||
| #define GPO_SECTION_MACHINE     2 | ||||
| typedef enum _GROUP_POLICY_OBJECT_TYPE { | ||||
| 	GPOTypeLocal = 0, GPOTypeRemote, GPOTypeDS | ||||
| } GROUP_POLICY_OBJECT_TYPE, *PGROUP_POLICY_OBJECT_TYPE; | ||||
| 
 | ||||
| #define REGISTRY_EXTENSION_GUID { 0x35378EAC,0x683F,0x11D2, {0xA8,0x9A,0x00,0xC0,0x4F,0xBB,0xCF,0xA2} } | ||||
| #define GPO_OPEN_LOAD_REGISTRY 0x00000001 | ||||
| #define GPO_SECTION_MACHINE 2 | ||||
| 
 | ||||
| #undef INTERFACE | ||||
| #define INTERFACE IGroupPolicyObject | ||||
| DECLARE_INTERFACE_(IGroupPolicyObject, IUnknown) { | ||||
| 	STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID *ppvObj) PURE; | ||||
| 	STDMETHOD_(ULONG, AddRef) (THIS) PURE; | ||||
|  | @ -706,7 +742,7 @@ BOOL SetLGP(BOOL bRestore, const char* szPath, const char* szPolicy, DWORD dwVal | |||
| 	HRESULT hr; | ||||
| 	IGroupPolicyObject* pLGPO; | ||||
| 	// These statuc values are used to restore initial state
 | ||||
| 	static BOOL key_was_present = FALSE; | ||||
| 	static BOOL existing_key = FALSE; | ||||
| 	static DWORD original_val; | ||||
| 	HKEY path_key = NULL, policy_key = NULL; | ||||
| 	// MSVC is finicky about these ones => redefine them
 | ||||
|  | @ -755,20 +791,20 @@ BOOL SetLGP(BOOL bRestore, const char* szPath, const char* szPolicy, DWORD dwVal | |||
| 		goto error; | ||||
| 	} | ||||
| 
 | ||||
| 	if ((disp == REG_OPENED_EXISTING_KEY) && (!bRestore) && (!key_was_present)) { | ||||
| 	if ((disp == REG_OPENED_EXISTING_KEY) && (!bRestore) && (!existing_key)) { | ||||
| 		// backup existing value for restore
 | ||||
| 		key_was_present = TRUE; | ||||
| 		existing_key = TRUE; | ||||
| 		regtype = REG_DWORD; | ||||
| 		r = RegQueryValueExA(policy_key, szPolicy, NULL, ®type, (LPBYTE)&original_val, &val_size); | ||||
| 		if (r == ERROR_FILE_NOT_FOUND) { | ||||
| 			// The Key exists but not its value, which is OK
 | ||||
| 			key_was_present = FALSE; | ||||
| 			existing_key = FALSE; | ||||
| 		} else if (r != ERROR_SUCCESS) { | ||||
| 			uprintf("SetLGP: Failed to read original %s policy value - error %x\n", szPolicy, r); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if ((!bRestore) || (key_was_present)) { | ||||
| 	if ((!bRestore) || (existing_key)) { | ||||
| 		val = (bRestore)?original_val:dwValue; | ||||
| 		r = RegSetValueExA(policy_key, szPolicy, 0, REG_DWORD, (BYTE*)&val, sizeof(val)); | ||||
| 	} else { | ||||
|  | @ -786,7 +822,11 @@ BOOL SetLGP(BOOL bRestore, const char* szPath, const char* szPolicy, DWORD dwVal | |||
| 		uprintf("SetLGP: Unable to apply %s policy - error %x\n", szPolicy, hr); | ||||
| 		goto error; | ||||
| 	} else { | ||||
| 		uprintf("SetLGP: Successfully %s %s policy\n", (bRestore)?"restored":"disabled", szPolicy); | ||||
| 		if ((bRestore) && (!existing_key)) { | ||||
| 			uprintf("SetLGP: Successfully removed %s policy key\n", szPolicy); | ||||
| 		} else { | ||||
| 			uprintf("SetLGP: Successfully %s %s policy to 0x%08X\n", (bRestore)?"restored":"set", szPolicy, val); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	RegCloseKey(path_key); | ||||
|  | @ -799,6 +839,7 @@ error: | |||
| 	if (pLGPO != NULL) pLGPO->lpVtbl->Release(pLGPO); | ||||
| 	return FALSE; | ||||
| } | ||||
| #pragma pop_macro("INTERFACE") | ||||
| 
 | ||||
| /* 
 | ||||
|  * Toggle controls according to operation | ||||
|  |  | |||
							
								
								
									
										12
									
								
								src/rufus.rc
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								src/rufus.rc
									
										
									
									
									
								
							|  | @ -30,7 +30,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL | |||
| IDD_DIALOG DIALOGEX 12, 12, 206, 278 | ||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | ||||
| EXSTYLE WS_EX_APPWINDOW | ||||
| CAPTION "Rufus v1.0.2.89 (Beta)" | ||||
| CAPTION "Rufus v1.0.2.90 (Beta)" | ||||
| FONT 8, "MS Shell Dlg", 400, 0, 0x1 | ||||
| BEGIN | ||||
|     DEFPUSHBUTTON   "Start",IDC_START,94,236,50,14 | ||||
|  | @ -64,7 +64,7 @@ BEGIN | |||
|     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, | ||||
|                     "SysLink",WS_TABSTOP,46,47,114,9 | ||||
|     LTEXT           "Version 1.0.2 (Build 89)",IDC_STATIC,46,19,78,8 | ||||
|     LTEXT           "Version 1.0.2 (Build 90)",IDC_STATIC,46,19,78,8 | ||||
|     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 | ||||
|     LTEXT           "Report bugs or request enhancements at:",IDC_STATIC,46,66,187,8 | ||||
|  | @ -163,8 +163,8 @@ END | |||
| // | ||||
| 
 | ||||
| VS_VERSION_INFO VERSIONINFO | ||||
|  FILEVERSION 1,0,2,89 | ||||
|  PRODUCTVERSION 1,0,2,89 | ||||
|  FILEVERSION 1,0,2,90 | ||||
|  PRODUCTVERSION 1,0,2,90 | ||||
|  FILEFLAGSMASK 0x3fL | ||||
| #ifdef _DEBUG | ||||
|  FILEFLAGS 0x1L | ||||
|  | @ -181,13 +181,13 @@ BEGIN | |||
|         BEGIN | ||||
|             VALUE "CompanyName", "akeo.ie" | ||||
|             VALUE "FileDescription", "Rufus" | ||||
|             VALUE "FileVersion", "1.0.2.89" | ||||
|             VALUE "FileVersion", "1.0.2.90" | ||||
|             VALUE "InternalName", "Rufus" | ||||
|             VALUE "LegalCopyright", "© 2011 Pete Batard (GPL v3)" | ||||
|             VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" | ||||
|             VALUE "OriginalFilename", "rufus.exe" | ||||
|             VALUE "ProductName", "Rufus" | ||||
|             VALUE "ProductVersion", "1.0.2.89" | ||||
|             VALUE "ProductVersion", "1.0.2.90" | ||||
|         END | ||||
|     END | ||||
|     BLOCK "VarFileInfo" | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue