mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[core] added formatting
* also added filter for hotplug detection
This commit is contained in:
		
							parent
							
								
									7280b0c45b
								
							
						
					
					
						commit
						1c302ee594
					
				
					 3 changed files with 246 additions and 11 deletions
				
			
		|  | @ -30,6 +30,11 @@ const char* additional_copyrights = | |||
| "http://www.gnu.org/software/fdisk\r\n" | ||||
| "GNU General Public License (GPL) v3 or later\r\n" | ||||
| "\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://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/libs/fmifs\r\n" | ||||
| "Public Domain\r\n" | ||||
| "\r\n" | ||||
| "About and License dialogs inspired by WinSCP\r\n" | ||||
| "Copyright (c) 2000-2011 Martin Prikryl\r\n" | ||||
| "GNU General Public License (GPL) v3 or later"; | ||||
|  |  | |||
							
								
								
									
										155
									
								
								rufus.c
									
										
									
									
									
								
							
							
						
						
									
										155
									
								
								rufus.c
									
										
									
									
									
								
							|  | @ -35,12 +35,9 @@ | |||
| #include <commctrl.h> | ||||
| #include <setupapi.h> | ||||
| #include <winioctl.h> | ||||
| #include <dbt.h> | ||||
| 
 | ||||
| // http://doc.sch130.nsc.ru/www.sysinternals.com/ntw2k/source/fmifs.shtml
 | ||||
| // http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/libs/fmifs/
 | ||||
| //#include <fmifs.h>
 | ||||
| // http://git.kernel.org/?p=fs/ext2/e2fsprogs.git;a=blob;f=misc/badblocks.c
 | ||||
| 
 | ||||
| // http://ms-sys.sourceforge.net/
 | ||||
| // http://thestarman.pcministry.com/asm/mbr/MSWIN41.htm
 | ||||
| 
 | ||||
|  | @ -77,6 +74,7 @@ struct { | |||
| static HWND hDeviceList, hCapacity, hFileSystem, hLabel; | ||||
| static HWND hDeviceTooltip = NULL, hFSTooltip = NULL; | ||||
| static StrArray DriveID, DriveLabel; | ||||
| static DWORD FormatErr; | ||||
| 
 | ||||
| #ifdef RUFUS_DEBUG | ||||
| void _uprintf(const char *format, ...) | ||||
|  | @ -282,12 +280,12 @@ static BOOL GetDriveInfo(void) | |||
| 				if (DriveLayout->PartitionEntry[i].Mbr.PartitionType != PARTITION_ENTRY_UNUSED) { | ||||
| 					uprintf("Partition #%d:\n", ++nb_partitions); | ||||
| 					if (hFSTooltip == NULL) { | ||||
| 						safe_sprintf(tmp, sizeof(tmp), "Current file system: %s (0x%02X)", | ||||
| 						safe_sprintf(tmp, sizeof(tmp), "Current file system: %s (0x%02x)", | ||||
| 							GetPartitionType(DriveLayout->PartitionEntry[i].Mbr.PartitionType), | ||||
| 							DriveLayout->PartitionEntry[i].Mbr.PartitionType); | ||||
| 						hFSTooltip = CreateTooltip(hFileSystem, tmp, -1); | ||||
| 					} | ||||
| 					uprintf("  Type: %s (0x%02X)\n  Boot: %s\n  Recognized: %s\n  Hidden Sectors: %d\n", | ||||
| 					uprintf("  Type: %s (0x%02x)\n  Boot: %s\n  Recognized: %s\n  Hidden Sectors: %d\n", | ||||
| 						GetPartitionType(DriveLayout->PartitionEntry[i].Mbr.PartitionType), | ||||
| 						DriveLayout->PartitionEntry[i].Mbr.PartitionType, | ||||
| 						DriveLayout->PartitionEntry[i].Mbr.BootIndicator?"Yes":"No", | ||||
|  | @ -452,6 +450,7 @@ BOOL CreatePartition(HANDLE hDrive) | |||
| 	BOOL r; | ||||
| 	DWORD size; | ||||
| 
 | ||||
| 	StatusPrintf("Partitioning..."); | ||||
| 	DriveLayoutEx->PartitionStyle = PARTITION_STYLE_MBR; | ||||
| 	DriveLayoutEx->PartitionCount = 4;	// Must be multiple of 4 for MBR
 | ||||
| 	DriveLayoutEx->Mbr.Signature = GetTickCount(); | ||||
|  | @ -484,15 +483,126 @@ BOOL CreatePartition(HANDLE hDrive) | |||
| 		safe_closehandle(hDrive); | ||||
| 		return FALSE; | ||||
| 	} | ||||
| 	StatusPrintf("Successfully Created Partition"); | ||||
| 
 | ||||
| 	return TRUE; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * FormatEx callback. Return FALSE to halt operations | ||||
|  */ | ||||
| BOOLEAN __stdcall FormatExCallback(FILE_SYSTEM_CALLBACK_COMMAND Command, DWORD Action, PVOID Data) | ||||
| { | ||||
| 	DWORD* percent; | ||||
| 	int task_number = 0; | ||||
| 
 | ||||
| 	switch(Command) { | ||||
| 	case FCC_PROGRESS: | ||||
| 		percent = (DWORD*)Data; | ||||
| //		PostMessage(hMainDialog, UM_FORMAT_PROGRESS, (WPARAM)*percent, (LPARAM)0);
 | ||||
| 		uprintf("%d percent completed.\n", *percent); | ||||
| 		break; | ||||
| 	case FCC_STRUCTURE_PROGRESS:	// No progress on quick format
 | ||||
| 		uprintf("format task %d/n completed.\n", ++task_number); | ||||
| 		break; | ||||
| 	case FCC_DONE: | ||||
| 		if(*(BOOLEAN*)Data == FALSE) { | ||||
| 			uprintf("Error while formatting.\n"); | ||||
| 			if (FormatErr == 0) | ||||
| 				FormatErr = FCC_DONE; | ||||
| 		} | ||||
| 		break; | ||||
| 	case FCC_INCOMPATIBLE_FILE_SYSTEM: | ||||
| 		uprintf("Incompatible File System\n"); | ||||
| 		FormatErr = Command; | ||||
| 		break; | ||||
| 	case FCC_ACCESS_DENIED: | ||||
| 		uprintf("Access denied\n"); | ||||
| 		FormatErr = Command; | ||||
| 		break; | ||||
| 	case FCC_MEDIA_WRITE_PROTECTED: | ||||
| 		uprintf("Media is write protected\n"); | ||||
| 		FormatErr = Command; | ||||
| 		break; | ||||
| 	case FCC_VOLUME_IN_USE: | ||||
| 		uprintf("Volume is in use\n"); | ||||
| 		FormatErr = Command; | ||||
| 		break; | ||||
| 	case FCC_CANT_QUICK_FORMAT: | ||||
| 		uprintf("Cannot quick format this volume\n"); | ||||
| 		FormatErr = Command; | ||||
| 		break; | ||||
| 	case FCC_BAD_LABEL: | ||||
| 		uprintf("Bad label\n"); | ||||
| 		break; | ||||
| 	case FCC_OUTPUT: | ||||
| 		uprintf("%s\n", ((PTEXTOUTPUT)Data)->Output); | ||||
| 		break; | ||||
| 	case FCC_CLUSTER_SIZE_TOO_SMALL: | ||||
| 		uprintf("Allocation unit size is too small\n"); | ||||
| 		FormatErr = Command; | ||||
| 		break; | ||||
| 	case FCC_CLUSTER_SIZE_TOO_BIG: | ||||
| 		uprintf("Allocation unit size is too big\n"); | ||||
| 		FormatErr = Command; | ||||
| 		break; | ||||
| 	case FCC_VOLUME_TOO_SMALL: | ||||
| 		uprintf("Volume is too small\n"); | ||||
| 		FormatErr = Command; | ||||
| 		break; | ||||
| 	case FCC_VOLUME_TOO_BIG: | ||||
| 		uprintf("Volume is too big\n"); | ||||
| 		FormatErr = Command; | ||||
| 		break; | ||||
| 	case FCC_NO_MEDIA_IN_DRIVE: | ||||
| 		uprintf("No media\n"); | ||||
| 		FormatErr = Command; | ||||
| 		break; | ||||
| 	default: | ||||
| 		uprintf("FormatExCallback: received unhandled command %X\n", Command); | ||||
| 		break; | ||||
| 	} | ||||
| 	return (FormatErr == 0); | ||||
| } | ||||
| 
 | ||||
| BOOL Format(char DriveLetter) | ||||
| { | ||||
| 	BOOL r = FALSE; | ||||
| 	PF_DECL(FormatEx); | ||||
| 	WCHAR wDriveRoot[] = L"?:\\"; | ||||
| 	WCHAR wFSType[32]; | ||||
| 	WCHAR wLabel[128]; | ||||
| 
 | ||||
| 	wDriveRoot[0] = (WCHAR)DriveLetter; | ||||
| 	StatusPrintf("Formatting..."); | ||||
| 	PF_INIT_OR_OUT(FormatEx, fmifs); | ||||
| 
 | ||||
| 	// TODO: properly set MediaType
 | ||||
| 	FormatErr = 0; | ||||
| 	GetWindowText(hFileSystem, wFSType, ARRAYSIZE(wFSType)); | ||||
| 	GetWindowText(hLabel, wLabel, ARRAYSIZE(wLabel)); | ||||
| 	pfFormatEx(wDriveRoot, RemovableMedia, wFSType, wLabel, | ||||
| 		(IsDlgButtonChecked(hMainDialog, IDC_QUICKFORMAT) == BST_CHECKED), | ||||
| 		4096, FormatExCallback); | ||||
| 	if (FormatErr == 0) { | ||||
| 		uprintf("Format completed.\n"); | ||||
| 		StatusPrintf("Done."); | ||||
| 		r = TRUE; | ||||
| 	} else { | ||||
| 		uprintf("Format error: %X\n", FormatErr); | ||||
| 		StatusPrintf("FAILED."); | ||||
| 	} | ||||
| 
 | ||||
| out: | ||||
| 	return r; | ||||
| } | ||||
| 
 | ||||
| // TODO: create a thread for this
 | ||||
| BOOL FormatDrive(DWORD num) | ||||
| { | ||||
| 	HANDLE hDrive; | ||||
| 	BOOL r; | ||||
| 	BOOL r = FALSE; | ||||
| 	char drive_letter; | ||||
| 	int i; | ||||
| 
 | ||||
| 	if (!GetDriveHandle(num, &hDrive, NULL, TRUE)) { | ||||
| 		// TODO: report an error for exclusive access
 | ||||
|  | @ -500,8 +610,24 @@ BOOL FormatDrive(DWORD num) | |||
| 	} | ||||
| 
 | ||||
| 	r = CreatePartition(hDrive); | ||||
| 	safe_closehandle(hDrive); | ||||
| 	if (!r) return FALSE; | ||||
| 
 | ||||
| 	// Make sure we can reopen the drive before trying to format it
 | ||||
| 	for (i=0; i<10; i++) { | ||||
| 		Sleep(500); | ||||
| 		if (GetDriveHandle(num, &hDrive, &drive_letter, FALSE)) { | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	if (i >= 10) { | ||||
| 		uprintf("Unable to reopen drive after partitioning\n"); | ||||
| 		return FALSE; | ||||
| 	} | ||||
| 	safe_closehandle(hDrive); | ||||
| 
 | ||||
| 	r = Format(drive_letter); | ||||
| 
 | ||||
| 	CloseHandle(hDrive); | ||||
| 	return r; | ||||
| } | ||||
| 
 | ||||
|  | @ -629,8 +755,12 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | |||
| 	switch (message) { | ||||
| 
 | ||||
| 	case WM_DEVICECHANGE: | ||||
| 		// TODO: also prevent detect during format
 | ||||
| 		if ((wParam == DBT_DEVICEARRIVAL) || (wParam == DBT_DEVICEREMOVECOMPLETE)) { | ||||
| 			GetUSBDevices(); | ||||
| 			return (INT_PTR)TRUE; | ||||
| 		} | ||||
| 		break; | ||||
| 
 | ||||
| 	case WM_INITDIALOG: | ||||
| 		hMainDialog = hDlg; | ||||
|  | @ -646,8 +776,11 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | |||
| 		CreateStatusBar(); | ||||
| 		// Display the version in the right area of the status bar
 | ||||
| 		SendMessageA(GetDlgItem(hDlg, IDC_STATUS), SB_SETTEXTA, SBT_OWNERDRAW | 1, (LPARAM)APP_VERSION); | ||||
| 		// Create the string array
 | ||||
| 		StrArrayCreate(&DriveID, MAX_DRIVES); | ||||
| 		StrArrayCreate(&DriveLabel, MAX_DRIVES); | ||||
| 		// Set the quick format checkbox
 | ||||
| 		CheckDlgButton(hDlg, IDC_QUICKFORMAT, BST_CHECKED); | ||||
| 		GetUSBDevices(); | ||||
| 		return (INT_PTR)TRUE; | ||||
| 
 | ||||
|  | @ -706,6 +839,10 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | |||
| 		PostQuitMessage(0); | ||||
| 		break; | ||||
| 
 | ||||
| 	case UM_FORMAT_PROGRESS: | ||||
| 		uprintf("Got UM_FORMAT_PROGRESS with percent %d\n", (DWORD)wParam); | ||||
| 		return (INT_PTR)TRUE; | ||||
| 
 | ||||
| 	} | ||||
| 	return (INT_PTR)FALSE; | ||||
| } | ||||
|  |  | |||
							
								
								
									
										93
									
								
								rufus.h
									
										
									
									
									
								
							
							
						
						
									
										93
									
								
								rufus.h
									
										
									
									
									
								
							|  | @ -15,6 +15,7 @@ | |||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| #include <winioctl.h>	// for MEDIA_TYPE | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
|  | @ -98,6 +99,12 @@ extern void _uprintf(const char *format, ...); | |||
| #define uprintf(...) | ||||
| #endif | ||||
| 
 | ||||
| /* Custom Windows messages */ | ||||
| enum user_message_type { | ||||
| 	UM_FORMAT_PROGRESS = WM_APP, | ||||
| 	UM_FORMAT_COMPLETED | ||||
| }; | ||||
| 
 | ||||
| /* Custom notifications */ | ||||
| enum MessageType { | ||||
| 	MSG_INFO, | ||||
|  | @ -106,6 +113,8 @@ enum MessageType { | |||
| }; | ||||
| 
 | ||||
| /* File system indexes in our FS combobox */ | ||||
| // TODO: FormatEx should support "NTFS", "FAT", "FAT32", "UDF", and "EXFAT" as per
 | ||||
| // http://msdn.microsoft.com/en-us/library/windows/desktop/aa819439.aspx
 | ||||
| enum _FSType { | ||||
| 	FS_FAT16 = 0, | ||||
| 	FS_FAT32, | ||||
|  | @ -118,3 +127,87 @@ typedef struct { | |||
| 	ULONG DeviceNumber; | ||||
| 	ULONG PartitionNumber; | ||||
| } STORAGE_DEVICE_NUMBER_REDEF; | ||||
| 
 | ||||
| /*
 | ||||
|  * typedefs for the function prototypes. Use the something like: | ||||
|  *   PF_DECL(FormatEx); | ||||
|  * which translates to: | ||||
|  *   FormatEx_t pfFormatEx = NULL; | ||||
|  * in your code, to declare the entrypoint and then use: | ||||
|  *   PF_INIT(FormatEx, fmifs); | ||||
|  * which translates to: | ||||
|  *   pfFormatEx = (FormatEx_t) GetProcAddress(GetDLLHandle("fmifs"), "FormatEx"); | ||||
|  * to make it accessible. | ||||
|  */ | ||||
| static __inline HMODULE GetDLLHandle(char* szDLLName) | ||||
| { | ||||
| 	HMODULE h = NULL; | ||||
| 	if ((h = GetModuleHandleA(szDLLName)) == NULL) | ||||
| 		h = LoadLibraryA(szDLLName); | ||||
| 	return h; | ||||
| } | ||||
| #define PF_DECL(proc) proc##_t pf##proc = NULL | ||||
| #define PF_INIT(proc, dllname) pf##proc = (proc##_t) GetProcAddress(GetDLLHandle(#dllname), #proc) | ||||
| #define PF_INIT_OR_OUT(proc, dllname) \ | ||||
| 	PF_INIT(proc, dllname); if (pf##proc == NULL) { \ | ||||
| 	uprintf("unable to access %s DLL: %s", #dllname, \ | ||||
| 	WindowsErrorString()); goto out; } | ||||
| 
 | ||||
| /* Callback command types (some errorcode were filled from HPUSBFW V2.2.3 and their
 | ||||
|    designation from msdn.microsoft.com/en-us/library/windows/desktop/aa819439.aspx */ | ||||
| typedef enum { | ||||
| 	FCC_PROGRESS, | ||||
| 	FCC_DONE_WITH_STRUCTURE, | ||||
| 	FCC_UNKNOWN2, | ||||
| 	FCC_INCOMPATIBLE_FILE_SYSTEM, | ||||
| 	FCC_UNKNOWN4, | ||||
| 	FCC_UNKNOWN5, | ||||
| 	FCC_ACCESS_DENIED, | ||||
| 	FCC_MEDIA_WRITE_PROTECTED, | ||||
| 	FCC_VOLUME_IN_USE, | ||||
| 	FCC_CANT_QUICK_FORMAT, | ||||
| 	FCC_UNKNOWNA, | ||||
| 	FCC_DONE, | ||||
| 	FCC_BAD_LABEL, | ||||
| 	FCC_UNKNOWND, | ||||
| 	FCC_OUTPUT, | ||||
| 	FCC_STRUCTURE_PROGRESS, | ||||
| 	FCC_CLUSTER_SIZE_TOO_SMALL, | ||||
| 	FCC_CLUSTER_SIZE_TOO_BIG, | ||||
| 	FCC_VOLUME_TOO_SMALL, | ||||
| 	FCC_VOLUME_TOO_BIG, | ||||
| 	FCC_NO_MEDIA_IN_DRIVE, | ||||
| } FILE_SYSTEM_CALLBACK_COMMAND; | ||||
| 
 | ||||
| typedef struct { | ||||
| 	DWORD Lines; | ||||
| 	CHAR* Output; | ||||
| } TEXTOUTPUT, *PTEXTOUTPUT; | ||||
| 
 | ||||
| typedef BOOLEAN (__stdcall *FILE_SYSTEM_CALLBACK)( | ||||
| 	FILE_SYSTEM_CALLBACK_COMMAND Command, | ||||
| 	ULONG                        Action, | ||||
| 	PVOID                        Data | ||||
| ); | ||||
| 
 | ||||
| /* Parameter naming aligned to
 | ||||
|    http://msdn.microsoft.com/en-us/library/windows/desktop/aa819439.aspx */
 | ||||
| typedef VOID (WINAPI *FormatEx_t)( | ||||
| 	WCHAR*               DriveRoot, | ||||
| 	MEDIA_TYPE           MediaType,		// See WinIoCtl.h
 | ||||
| 	WCHAR*               FileSystemTypeName, | ||||
| 	WCHAR*               Label, | ||||
| 	BOOL                 QuickFormat, | ||||
| 	ULONG                DesiredUnitAllocationSize, | ||||
| 	FILE_SYSTEM_CALLBACK Callback | ||||
| ); | ||||
| 
 | ||||
| /* http://msdn.microsoft.com/en-us/library/windows/desktop/aa383357.aspx */ | ||||
| typedef enum  { | ||||
| 	FPF_COMPRESSED   = 0x01  | ||||
| } FILE_SYSTEM_PROP_FLAG; | ||||
| 
 | ||||
| typedef BOOLEAN (WINAPI* EnableVolumeCompression_t)( | ||||
| 	WCHAR*          DriveRoot, | ||||
| 	ULONG           CompressionFlags	// FILE_SYSTEM_PROP_FLAG
 | ||||
| ); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue