mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	misc] move formatting functions into their own source
* also add missing #pragma once in msapi_utf8.h
This commit is contained in:
		
							parent
							
								
									bc252400a1
								
							
						
					
					
						commit
						79f3e78ec3
					
				
					 11 changed files with 644 additions and 569 deletions
				
			
		|  | @ -151,12 +151,14 @@ | |||
|     <ClCompile Include="..\fat16.c" /> | ||||
|     <ClCompile Include="..\fat32.c" /> | ||||
|     <ClCompile Include="..\file.c" /> | ||||
|     <ClCompile Include="..\format.c" /> | ||||
|     <ClCompile Include="..\msdos.c" /> | ||||
|     <ClCompile Include="..\rufus.c" /> | ||||
|     <ClCompile Include="..\stdio.c" /> | ||||
|     <ClCompile Include="..\stdlg.c" /> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClInclude Include="..\format.h" /> | ||||
|     <ClInclude Include="..\inc\br.h" /> | ||||
|     <ClInclude Include="..\inc\br_fat12_0x0.h" /> | ||||
|     <ClInclude Include="..\inc\br_fat12_0x3e.h" /> | ||||
|  |  | |||
|  | @ -45,6 +45,9 @@ | |||
|     <ClCompile Include="..\stdio.c"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\format.c"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClInclude Include="..\rufus.h"> | ||||
|  | @ -146,6 +149,9 @@ | |||
|     <ClInclude Include="..\inc\mbr_zero.h"> | ||||
|       <Filter>Header Files\inc</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\format.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <None Include="..\rufus.ico"> | ||||
|  |  | |||
|  | @ -24,6 +24,7 @@ TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \ | |||
| SXS_APPLICATION_MANIFEST=common_controls_and_elevation.manifest | ||||
| 
 | ||||
| SOURCES=rufus.c  \ | ||||
|         format.c \ | ||||
|         stdio.c  \ | ||||
|         stdlg.c  \ | ||||
|         msdos.c  \ | ||||
|  |  | |||
							
								
								
									
										2
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
										
									
									
									
								
							|  | @ -17,7 +17,7 @@ | |||
| # along with this program; if not, see <http://www.gnu.org/licenses/>.
 | ||||
| #
 | ||||
| 
 | ||||
| OBJECTS   = fat12.o fat16.o fat32.o br.o file.o msdos.o stdio.o stdlg.o rufus.o   | ||||
| OBJECTS   = fat12.o fat16.o fat32.o br.o file.o msdos.o format.o stdio.o stdlg.o rufus.o   | ||||
| TARGET    = rufus | ||||
| 
 | ||||
| CC        = gcc | ||||
|  |  | |||
							
								
								
									
										435
									
								
								format.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										435
									
								
								format.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,435 @@ | |||
| /*
 | ||||
|  * Rufus: The Resourceful USB Formatting Utility | ||||
|  * Formatting function calls | ||||
|  * Copyright (c) 2011 Pete Batard <pete@akeo.ie> | ||||
|  * | ||||
|  * 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 | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| #ifdef _CRTDBG_MAP_ALLOC | ||||
| #include <stdlib.h> | ||||
| #include <crtdbg.h> | ||||
| #endif | ||||
| 
 | ||||
| #include <windows.h> | ||||
| #include <windowsx.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| #include <process.h> | ||||
| // #include <ctype.h>
 | ||||
| 
 | ||||
| #include "msapi_utf8.h" | ||||
| #include "rufus.h" | ||||
| #include "resource.h" | ||||
| #include "br.h" | ||||
| #include "fat16.h" | ||||
| #include "fat32.h" | ||||
| #include "file.h" | ||||
| #include "format.h" | ||||
| 
 | ||||
| /*
 | ||||
|  * FormatEx callback. Return FALSE to halt operations | ||||
|  */ | ||||
| static BOOLEAN __stdcall FormatExCallback(FILE_SYSTEM_CALLBACK_COMMAND Command, DWORD Action, PVOID pData) | ||||
| { | ||||
| 	DWORD* percent; | ||||
| 	int task_number = 0; | ||||
| 
 | ||||
| 	if (IS_ERROR(FormatStatus)) | ||||
| 		return FALSE; | ||||
| 
 | ||||
| 	switch(Command) { | ||||
| 	case FCC_PROGRESS: | ||||
| 		percent = (DWORD*)pData; | ||||
| 		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/? completed.\n", ++task_number); | ||||
| 		break; | ||||
| 	case FCC_DONE: | ||||
| 		if(*(BOOLEAN*)pData == FALSE) { | ||||
| 			uprintf("Error while formatting.\n"); | ||||
| 			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_GEN_FAILURE; | ||||
| 		} | ||||
| 		break; | ||||
| 	case FCC_DONE_WITH_STRUCTURE:	// We get this message when formatting Small FAT16
 | ||||
| 		// pData Seems to be a struct with at least one (32 BIT!!!) string pointer to the size in MB
 | ||||
| 		uprintf("Done with that sort of things: Action=%d pData=%0p\n", Action, pData); | ||||
| 		DumpBufferHex(pData, 8); | ||||
| 		uprintf("Volume size: %s MB\n", (char*)(LONG_PTR)(*(ULONG32*)pData)); | ||||
| 		break; | ||||
| 	case FCC_INCOMPATIBLE_FILE_SYSTEM: | ||||
| 		uprintf("Incompatible File System\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INCOMPATIBLE_FS; | ||||
| 		break; | ||||
| 	case FCC_ACCESS_DENIED: | ||||
| 		uprintf("Access denied\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_ACCESS_DENIED; | ||||
| 		break; | ||||
| 	case FCC_MEDIA_WRITE_PROTECTED: | ||||
| 		uprintf("Media is write protected\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_PROTECT; | ||||
| 		break; | ||||
| 	case FCC_VOLUME_IN_USE: | ||||
| 		uprintf("Volume is in use\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_DEVICE_IN_USE; | ||||
| 		break; | ||||
| 	case FCC_CANT_QUICK_FORMAT: | ||||
| 		uprintf("Cannot quick format this volume\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANT_QUICK_FORMAT; | ||||
| 		break; | ||||
| 	case FCC_BAD_LABEL: | ||||
| 		uprintf("Bad label\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_LABEL_TOO_LONG; | ||||
| 		break; | ||||
| 	case FCC_OUTPUT: | ||||
| 		uprintf("%s\n", ((PTEXTOUTPUT)pData)->Output); | ||||
| 		break; | ||||
| 	case FCC_CLUSTER_SIZE_TOO_BIG: | ||||
| 	case FCC_CLUSTER_SIZE_TOO_SMALL: | ||||
| 		uprintf("Unsupported cluster size\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INVALID_CLUSTER_SIZE; | ||||
| 		break; | ||||
| 	case FCC_VOLUME_TOO_BIG: | ||||
| 	case FCC_VOLUME_TOO_SMALL: | ||||
| 		uprintf("Volume is too %s\n", FCC_VOLUME_TOO_BIG?"big":"small"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INVALID_VOLUME_SIZE; | ||||
| 	case FCC_NO_MEDIA_IN_DRIVE: | ||||
| 		uprintf("No media in drive\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NO_MEDIA_IN_DRIVE; | ||||
| 		break; | ||||
| 	default: | ||||
| 		uprintf("FormatExCallback: received unhandled command %X\n", Command); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_SUPPORTED; | ||||
| 		break; | ||||
| 	} | ||||
| 	return (!IS_ERROR(FormatStatus)); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Call on fmifs.dll's FormatEx() to format the drive | ||||
|  */ | ||||
| static BOOL FormatDrive(char DriveLetter) | ||||
| { | ||||
| 	BOOL r = FALSE; | ||||
| 	PF_DECL(FormatEx); | ||||
| 	WCHAR wDriveRoot[] = L"?:\\"; | ||||
| 	WCHAR wFSType[32]; | ||||
| 	WCHAR wLabel[128]; | ||||
| 	size_t i; | ||||
| 
 | ||||
| 	wDriveRoot[0] = (WCHAR)DriveLetter; | ||||
| 	PrintStatus("Formatting..."); | ||||
| 	PF_INIT_OR_OUT(FormatEx, fmifs); | ||||
| 
 | ||||
| 	// TODO: properly set MediaType
 | ||||
| 	GetWindowTextW(hFileSystem, wFSType, ARRAYSIZE(wFSType)); | ||||
| 	// We may have a " (Default)" trail
 | ||||
| 	for (i=0; i<wcslen(wFSType); i++) { | ||||
| 		if (wFSType[i] == ' ') { | ||||
| 			uprintf("removed %d\n", i); | ||||
| 			wFSType[i] = 0; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	GetWindowTextW(hLabel, wLabel, ARRAYSIZE(wLabel)); | ||||
| 	uprintf("Using cluster size: %d bytes\n", ComboBox_GetItemData(hClusterSize, ComboBox_GetCurSel(hClusterSize))); | ||||
| 	pfFormatEx(wDriveRoot, RemovableMedia, wFSType, wLabel, | ||||
| 		IsChecked(IDC_QUICKFORMAT), (ULONG)ComboBox_GetItemData(hClusterSize, ComboBox_GetCurSel(hClusterSize)), | ||||
| 		FormatExCallback); | ||||
| 	if (!IS_ERROR(FormatStatus)) { | ||||
| 		uprintf("Format completed.\n"); | ||||
| 		r = TRUE; | ||||
| 	} | ||||
| 
 | ||||
| out: | ||||
| 	return r; | ||||
| } | ||||
| 
 | ||||
| static BOOL AnalyzeMBR(HANDLE hPhysicalDrive) | ||||
| { | ||||
| 	FILE fake_fd; | ||||
| 
 | ||||
| 	fake_fd._ptr = (char*)hPhysicalDrive; | ||||
| 	fake_fd._bufsiz = SelectedDrive.Geometry.BytesPerSector; | ||||
| 
 | ||||
| 	// TODO: Apply this detection before partitioning
 | ||||
| 	// TODO: since we detect all these, might as well give some MBR choice to the user?
 | ||||
| 	if (is_br(&fake_fd)) { | ||||
| 		uprintf("Drive has an x86 boot sector\n"); | ||||
| 	} else{ | ||||
| 		uprintf("Drive is missing an x86 boot sector!\n"); | ||||
| 		return FALSE; | ||||
| 	} | ||||
| 	// TODO: Add/Eliminate FAT12?
 | ||||
| 	if (is_fat_16_br(&fake_fd) || is_fat_32_br(&fake_fd)) { | ||||
| 		if (entire_fat_16_br_matches(&fake_fd)) { | ||||
| 			uprintf("Exact FAT16 DOS boot record match\n"); | ||||
| 		} else if (entire_fat_16_fd_br_matches(&fake_fd)) { | ||||
| 			uprintf("Exact FAT16 FreeDOS boot record match\n"); | ||||
| 		} else if (entire_fat_32_br_matches(&fake_fd)) { | ||||
| 			uprintf("Exact FAT32 DOS boot record match\n"); | ||||
| 		} else if (entire_fat_32_nt_br_matches(&fake_fd)) { | ||||
| 			uprintf("Exact FAT32 NT boot record match\n"); | ||||
| 		} else if (entire_fat_32_fd_br_matches(&fake_fd)) { | ||||
| 			uprintf("Exactly FAT32 FreeDOS boot record match\n"); | ||||
| 		} else { | ||||
| 			uprintf("Unknown FAT16 or FAT32 boot record\n"); | ||||
| 		} | ||||
| 	} else if (is_dos_mbr(&fake_fd)) { | ||||
| 		uprintf("Microsoft DOS/NT/95A master boot record match\n"); | ||||
| 	} else if (is_dos_f2_mbr(&fake_fd)) { | ||||
| 		uprintf("Microsoft DOS/NT/95A master boot record with the undocumented\n"); | ||||
| 		uprintf("F2 instruction match\n"); | ||||
| 	} else if (is_95b_mbr(&fake_fd)) { | ||||
| 		uprintf("Microsoft 95B/98/98SE/ME master boot record match\n"); | ||||
| 	} else if (is_2000_mbr(&fake_fd)) { | ||||
| 		uprintf("Microsoft 2000/XP/2003 master boot record match\n"); | ||||
| 	} else if (is_vista_mbr(&fake_fd)) { | ||||
| 		uprintf("Microsoft Vista master boot record match\n"); | ||||
| 	} else if (is_win7_mbr(&fake_fd)) { | ||||
| 		uprintf("Microsoft 7 master boot record match\n"); | ||||
| 	} else if (is_zero_mbr(&fake_fd)) { | ||||
| 		uprintf("Zeroed non-bootable master boot record match\n"); | ||||
| 	} else { | ||||
| 		uprintf("Unknown boot record\n"); | ||||
| 	} | ||||
| 	return TRUE; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Process the MBR | ||||
|  */ | ||||
| static BOOL ProcessMBR(HANDLE hPhysicalDrive) | ||||
| { | ||||
| 	BOOL r = FALSE; | ||||
| 	unsigned char* buf = NULL; | ||||
| 	size_t SecSize = SelectedDrive.Geometry.BytesPerSector; | ||||
| 	size_t nSecs = (0x200 + SecSize -1) / SecSize; | ||||
| 	FILE fake_fd; | ||||
| 
 | ||||
| 	if (!AnalyzeMBR(hPhysicalDrive)) return FALSE; | ||||
| 
 | ||||
| 	// FormatEx rewrites the MBR and removes the LBA attribute of FAT16
 | ||||
| 	// and FAT32 partitions - we need to correct this in the MBR
 | ||||
| 	// TODO: something else for bootable GPT
 | ||||
| 	buf = (unsigned char*)malloc(SecSize * nSecs); | ||||
| 	if (buf == NULL) { | ||||
| 		uprintf("Could not allocate memory for MBR"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_ENOUGH_MEMORY; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!read_sectors(hPhysicalDrive, SelectedDrive.Geometry.BytesPerSector, 0, nSecs, buf, SecSize)) { | ||||
| 		uprintf("Could not read MBR\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_READ_FAULT; | ||||
| 		goto out; | ||||
| 	} | ||||
| //	DumpBufferHex(buf, 0x200);
 | ||||
| 	switch (ComboBox_GetCurSel(hFileSystem)) { | ||||
| 	// TODO: check for 0x06 & 0x0b?
 | ||||
| 	case FS_FAT16: | ||||
| 		buf[0x1c2] = 0x0e; | ||||
| 		break; | ||||
| 	case FS_FAT32: | ||||
| 		buf[0x1c2] = 0x0c; | ||||
| 		break; | ||||
| 	} | ||||
| 	if (IsChecked(IDC_DOSSTARTUP)) { | ||||
| 		buf[0x1be] = 0x80;		// Set first partition bootable
 | ||||
| 	} | ||||
| 
 | ||||
| 	if (!write_sectors(hPhysicalDrive, SelectedDrive.Geometry.BytesPerSector, 0, nSecs, buf, SecSize*nSecs)) { | ||||
| 		uprintf("Could not write MBR\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	fake_fd._ptr = (char*)hPhysicalDrive; | ||||
| 	fake_fd._bufsiz = SelectedDrive.Geometry.BytesPerSector; | ||||
| 	r = write_95b_mbr(&fake_fd); | ||||
| 
 | ||||
| 	if (!read_sectors(hPhysicalDrive, SelectedDrive.Geometry.BytesPerSector, 0, nSecs, buf, SecSize)) { | ||||
| 		uprintf("Could not re-read MBR\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_READ_FAULT; | ||||
| 		goto out; | ||||
| 	} | ||||
| 	DumpBufferHex(buf, 0x200); | ||||
| 
 | ||||
| out: | ||||
| 	safe_free(buf); | ||||
| 	return r; | ||||
| } | ||||
| 
 | ||||
| static BOOL ProcessFS_BR(HANDLE hLogicalVolume) | ||||
| { | ||||
| 	BOOL r = FALSE; | ||||
| 	unsigned char* buf = NULL; | ||||
| 	FILE fake_fd; | ||||
| 	size_t SecSize = SelectedDrive.Geometry.BytesPerSector; | ||||
| 	size_t nSecs = (0x400 + SecSize -1) / SecSize; | ||||
| 
 | ||||
| 	fake_fd._ptr = (char*)hLogicalVolume; | ||||
| 	fake_fd._bufsiz = SelectedDrive.Geometry.BytesPerSector; | ||||
| 	write_fat_32_br(&fake_fd, 0); | ||||
| 
 | ||||
| 	// FormatEx rewrites the MBR and removes the LBA attribute of FAT16
 | ||||
| 	// and FAT32 partitions - we need to correct this in the MBR
 | ||||
| 	// TODO: something else for bootable GPT
 | ||||
| 	buf = (unsigned char*)malloc(SecSize * nSecs); | ||||
| 	if (buf == NULL) { | ||||
| 		uprintf("Could not allocate memory for FS BR"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_ENOUGH_MEMORY; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!read_sectors(hLogicalVolume, SelectedDrive.Geometry.BytesPerSector, 0, nSecs, buf, SecSize*nSecs)) { | ||||
| 		uprintf("Could not read FS BR\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_READ_FAULT; | ||||
| 		goto out; | ||||
| 	} | ||||
| 	uprintf("FS_BR:\n"); | ||||
| 	DumpBufferHex(buf, 0x400); | ||||
| 
 | ||||
| out: | ||||
| 	safe_free(buf); | ||||
| 	return r; | ||||
| } | ||||
| 
 | ||||
| /* http://msdn.microsoft.com/en-us/library/windows/desktop/aa364562%28v=vs.85%29.aspx
 | ||||
|    Dismounting a volume is useful when a volume needs to disappear for a while. For | ||||
|    example, an application that changes a volume file system from the FAT file system | ||||
|    to the NTFS file system might use the following procedure. | ||||
| 
 | ||||
|    To change a volume file system | ||||
| 
 | ||||
|     Open a volume. | ||||
|     Lock the volume. | ||||
|     Format the volume. | ||||
|     Dismount the volume. | ||||
|     Unlock the volume. | ||||
|     Close the volume handle. | ||||
| 
 | ||||
|    A dismounting operation removes the volume from the FAT file system awareness. | ||||
|    When the operating system mounts the volume, it appears as an NTFS file system volume. | ||||
| */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Standalone thread for the formatting operation | ||||
|  */ | ||||
| void __cdecl FormatThread(void* param) | ||||
| { | ||||
| 	DWORD num = (DWORD)(uintptr_t)param; | ||||
| 	HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE; | ||||
| 	HANDLE hLogicalVolume = INVALID_HANDLE_VALUE; | ||||
| 	char drive_name[] = "?:"; | ||||
| 	int i; | ||||
| //	DWORD size;
 | ||||
| 
 | ||||
| 	hPhysicalDrive = GetDriveHandle(num, NULL, TRUE, TRUE); | ||||
| 	if (hPhysicalDrive == INVALID_HANDLE_VALUE) { | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; | ||||
| 		goto out; | ||||
| 	} | ||||
| 	// At this stage with have both a handle and a lock to the physical drive
 | ||||
| 
 | ||||
| 	if (!CreatePartition(hPhysicalDrive)) { | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_PARTITION_FAILURE; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	// Make sure we can access the volume again before trying to format it
 | ||||
| 	for (i=0; i<10; i++) { | ||||
| 		Sleep(500); | ||||
| 		hLogicalVolume = GetDriveHandle(num, drive_name, FALSE, TRUE); | ||||
| 		if (hLogicalVolume != INVALID_HANDLE_VALUE) { | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	if (i >= 10) { | ||||
| 		uprintf("Could not access volume after partitioning\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; | ||||
| 		goto out; | ||||
| 	} | ||||
| 	// Handle needs to be closed for FormatEx to be happy - we keep a lock though
 | ||||
| 	safe_closehandle(hLogicalVolume); | ||||
| 
 | ||||
| 	if (!FormatDrive(drive_name[0])) { | ||||
| 		// Error will be set by FormatDrive() in FormatStatus
 | ||||
| 		uprintf("Format error: 0x%08X\n", FormatStatus); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	// TODO: Enable compression on NTFS
 | ||||
| 	// TODO: optionally disable indexing on NTFS
 | ||||
| 	// TODO: use progress bar during MBR/FSBR/MSDOS copy
 | ||||
| 
 | ||||
| 	// Ideally we would lock, FSCTL_DISMOUNT_VOLUME, unlock and close our volume
 | ||||
| 	// handle, but some explorer versions have problems with volumes disappear
 | ||||
| // #define VOL_DISMOUNT
 | ||||
| #ifdef VOL_DISMOUNT | ||||
| 	// Dismount the volume
 | ||||
| 	hLogicalVolume = GetDriveHandle(num, drive_name, FALSE, TRUE); | ||||
| 	if (hLogicalVolume == INVALID_HANDLE_VALUE) { | ||||
| 		uprintf("Could not open the volume for dismount\n"); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!DeviceIoControl(hLogicalVolume, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &size, NULL)) { | ||||
| 		uprintf("Could not dismount volume\n"); | ||||
| 		goto out; | ||||
| 	} | ||||
| #endif | ||||
| 	PrintStatus("Writing master boot record...\n"); | ||||
| 	if (!ProcessMBR(hPhysicalDrive)) { | ||||
| 		// Errorcode has already been set
 | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| #ifdef VOL_DISMOUNT | ||||
| 	safe_unlockclose(hLogicalVolume); | ||||
| //	Sleep(10000);
 | ||||
| 	hLogicalVolume = GetDriveHandle(num, drive_name, FALSE, FALSE); | ||||
| 	if (hLogicalVolume == INVALID_HANDLE_VALUE) { | ||||
| 		uprintf("Could not re-mount volume\n"); | ||||
| 		goto out; | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 	if (IsChecked(IDC_DOSSTARTUP)) { | ||||
| 		hLogicalVolume = GetDriveHandle(num, drive_name, TRUE, FALSE); | ||||
| 		if (hLogicalVolume == INVALID_HANDLE_VALUE) { | ||||
| 			uprintf("Could not re-mount volume\n"); | ||||
| 			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; | ||||
| 			goto out; | ||||
| 		} | ||||
| 		PrintStatus("Writing filesystem boot record...\n"); | ||||
| 		if (!ProcessFS_BR(hLogicalVolume)) { | ||||
| 			// Errorcode has already been set
 | ||||
| 			goto out; | ||||
| 		} | ||||
| 		PrintStatus("Copying MS-DOS files...\n"); | ||||
| 		if (!ExtractMSDOS(drive_name)) { | ||||
| 			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANNOT_COPY; | ||||
| 			goto out; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| out: | ||||
| 	safe_unlockclose(hLogicalVolume); | ||||
| 	safe_unlockclose(hPhysicalDrive); | ||||
| 	PostMessage(hMainDialog, UM_FORMAT_COMPLETED, 0, 0); | ||||
| 	_endthread(); | ||||
| } | ||||
							
								
								
									
										106
									
								
								format.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								format.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,106 @@ | |||
| /*
 | ||||
|  * Rufus: The Resourceful USB Formatting Utility | ||||
|  * Formatting function calls | ||||
|  * Copyright (c) 2011 Pete Batard <pete@akeo.ie> | ||||
|  * | ||||
|  * 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 | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * 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 <Windows.h> | ||||
| #include <winioctl.h>				// for MEDIA_TYPE | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| /*
 | ||||
|  * 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                        pData | ||||
| ); | ||||
| 
 | ||||
| /* Parameter names 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
 | ||||
| ); | ||||
|  | @ -25,6 +25,8 @@ | |||
| #include <shellapi.h> | ||||
| #include <setupapi.h> | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
|  |  | |||
							
								
								
									
										441
									
								
								rufus.c
									
										
									
									
									
								
							
							
						
						
									
										441
									
								
								rufus.c
									
										
									
									
									
								
							|  | @ -40,26 +40,20 @@ | |||
| #include <io.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
 | ||||
| // http://www.c-jump.com/CIS24/Slides/FAT/lecture.html#F01_0130_sector_assignments
 | ||||
| 
 | ||||
| #include "msapi_utf8.h" | ||||
| #include "resource.h" | ||||
| #include "rufus.h" | ||||
| #include "sys_types.h" | ||||
| #include "br.h" | ||||
| #include "fat16.h" | ||||
| #include "fat32.h" | ||||
| #include "file.h" | ||||
| 
 | ||||
| #if !defined(GUID_DEVINTERFACE_DISK) | ||||
| const GUID GUID_DEVINTERFACE_DISK = { 0x53f56307L, 0xb6bf, 0x11d0, {0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b} }; | ||||
| #endif | ||||
| 
 | ||||
| const char* FileSystemLabel[FS_MAX] = { "FAT", "FAT32", "NTFS", "exFAT" }; | ||||
| static const char* FileSystemLabel[FS_MAX] = { "FAT", "FAT32", "NTFS", "exFAT" }; | ||||
| // Don't ask me - just following the MS standard here
 | ||||
| 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", | ||||
| 	"1024 kilobytes","2048 kilobytes","4096 kilobytes","8192 kilobytes","16 megabytes","32 megabytes" }; | ||||
| 
 | ||||
|  | @ -81,27 +75,14 @@ HWND hStatus; | |||
| float fScale = 1.0f; | ||||
| int default_fs; | ||||
| ULONG default_clutersize; | ||||
| 
 | ||||
| RUFUS_DRIVE_INFO SelectedDrive; | ||||
| BOOL bBootable; | ||||
| BOOL bQuickFormat; | ||||
| 
 | ||||
| struct { | ||||
| 	DWORD DeviceNumber; | ||||
| 	LONGLONG DiskSize; | ||||
| 	DISK_GEOMETRY Geometry; | ||||
| 	DWORD FirstSector; | ||||
| 	int FSType; | ||||
| 	struct { | ||||
| 		ULONG Allowed; | ||||
| 		ULONG Default; | ||||
| 	} ClusterSize[FS_MAX]; | ||||
| } SelectedDrive; | ||||
| 
 | ||||
| static HWND hDeviceList, hCapacity, hFileSystem, hClusterSize, hLabel; | ||||
| DWORD FormatStatus; | ||||
| HWND hDeviceList, hCapacity, hFileSystem, hClusterSize, hLabel; | ||||
| static HWND hDeviceTooltip = NULL, hFSTooltip = NULL; | ||||
| static StrArray DriveID, DriveLabel; | ||||
| static DWORD FormatStatus; | ||||
| 
 | ||||
| static StrArray DriveID, DriveLabel; | ||||
| 
 | ||||
| /*
 | ||||
|  * Convert a partition type to its human readable form using | ||||
|  | @ -119,7 +100,7 @@ static const char* GetPartitionType(BYTE Type) | |||
| 
 | ||||
| /*
 | ||||
|  * Open a drive with optional write access - returns a drive HANDLE and the drive letter | ||||
|  * or INVALID_HANDLE_VALUE (/!\ which is != NULL /!\) on failure | ||||
|  * or INVALID_HANDLE_VALUE (/!\ which is DIFFERENT from NULL /!\) on failure | ||||
|  * This call is quite risky (left unchecked, inadvertently passing 0 as index would | ||||
|  * return a handle to C:, which we might then proceed to unknowingly repartition!), | ||||
|  * so we apply the following mitigation factors: | ||||
|  | @ -128,7 +109,7 @@ static const char* GetPartitionType(BYTE Type) | |||
|  *   typically be the case on C:\ or any other drive in use, we report failure | ||||
|  * - We report the full path of any drive that was successfully opened for write acces | ||||
|  */ | ||||
| static HANDLE GetDriveHandle(DWORD DriveIndex, char* DriveLetter, BOOL bWriteAccess, BOOL bLockDrive) | ||||
| HANDLE GetDriveHandle(DWORD DriveIndex, char* DriveLetter, BOOL bWriteAccess, BOOL bLockDrive) | ||||
| { | ||||
| 	BOOL r; | ||||
| 	DWORD size; | ||||
|  | @ -212,12 +193,6 @@ out: | |||
| 	return hDrive; | ||||
| } | ||||
| 
 | ||||
| static __inline BOOL UnlockDrive(HANDLE hDrive) | ||||
| { | ||||
| 	DWORD size; | ||||
| 	return DeviceIoControl(hDrive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &size, NULL); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Return the drive letter and volume label | ||||
|  */ | ||||
|  | @ -242,12 +217,10 @@ static BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label) | |||
| 	return TRUE; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #define KB          1024LL | ||||
| #define MB       1048576LL | ||||
| #define GB    1073741824LL | ||||
| #define TB 1099511627776LL | ||||
| 
 | ||||
| /* 
 | ||||
|  * Set cluster size values according to http://support.microsoft.com/kb/140365
 | ||||
|  * this call will return FALSE if we can't find a supportable FS for the drive | ||||
|  | @ -559,7 +532,7 @@ static BOOL PopulateProperties(int ComboIndex) | |||
| /*
 | ||||
|  * Create a partition table | ||||
|  */ | ||||
| static BOOL CreatePartition(HANDLE hDrive) | ||||
| BOOL CreatePartition(HANDLE hDrive) | ||||
| { | ||||
| 	BYTE layout[sizeof(DRIVE_LAYOUT_INFORMATION_EX) + 3*sizeof(PARTITION_INFORMATION_EX)] = {0}; | ||||
| 	PDRIVE_LAYOUT_INFORMATION_EX DriveLayoutEx = (PDRIVE_LAYOUT_INFORMATION_EX)layout; | ||||
|  | @ -605,402 +578,6 @@ static BOOL CreatePartition(HANDLE hDrive) | |||
| 	return TRUE; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * FormatEx callback. Return FALSE to halt operations | ||||
|  */ | ||||
| static BOOLEAN __stdcall FormatExCallback(FILE_SYSTEM_CALLBACK_COMMAND Command, DWORD Action, PVOID pData) | ||||
| { | ||||
| 	DWORD* percent; | ||||
| 	int task_number = 0; | ||||
| 
 | ||||
| 	if (IS_ERROR(FormatStatus)) | ||||
| 		return FALSE; | ||||
| 
 | ||||
| 	switch(Command) { | ||||
| 	case FCC_PROGRESS: | ||||
| 		percent = (DWORD*)pData; | ||||
| 		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/? completed.\n", ++task_number); | ||||
| 		break; | ||||
| 	case FCC_DONE: | ||||
| 		if(*(BOOLEAN*)pData == FALSE) { | ||||
| 			uprintf("Error while formatting.\n"); | ||||
| 			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_GEN_FAILURE; | ||||
| 		} | ||||
| 		break; | ||||
| 	case FCC_DONE_WITH_STRUCTURE:	// We get this message when formatting Small FAT16
 | ||||
| 		// pData Seems to be a struct with at least one (32 BIT!!!) string pointer to the size in MB
 | ||||
| 		uprintf("Done with that sort of things: Action=%d pData=%0p\n", Action, pData); | ||||
| 		DumpBufferHex(pData, 8); | ||||
| 		uprintf("Volume size: %s MB\n", (char*)(LONG_PTR)(*(ULONG32*)pData)); | ||||
| 		break; | ||||
| 	case FCC_INCOMPATIBLE_FILE_SYSTEM: | ||||
| 		uprintf("Incompatible File System\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INCOMPATIBLE_FS; | ||||
| 		break; | ||||
| 	case FCC_ACCESS_DENIED: | ||||
| 		uprintf("Access denied\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_ACCESS_DENIED; | ||||
| 		break; | ||||
| 	case FCC_MEDIA_WRITE_PROTECTED: | ||||
| 		uprintf("Media is write protected\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_PROTECT; | ||||
| 		break; | ||||
| 	case FCC_VOLUME_IN_USE: | ||||
| 		uprintf("Volume is in use\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_DEVICE_IN_USE; | ||||
| 		break; | ||||
| 	case FCC_CANT_QUICK_FORMAT: | ||||
| 		uprintf("Cannot quick format this volume\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANT_QUICK_FORMAT; | ||||
| 		break; | ||||
| 	case FCC_BAD_LABEL: | ||||
| 		uprintf("Bad label\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_LABEL_TOO_LONG; | ||||
| 		break; | ||||
| 	case FCC_OUTPUT: | ||||
| 		uprintf("%s\n", ((PTEXTOUTPUT)pData)->Output); | ||||
| 		break; | ||||
| 	case FCC_CLUSTER_SIZE_TOO_BIG: | ||||
| 	case FCC_CLUSTER_SIZE_TOO_SMALL: | ||||
| 		uprintf("Unsupported cluster size\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INVALID_CLUSTER_SIZE; | ||||
| 		break; | ||||
| 	case FCC_VOLUME_TOO_BIG: | ||||
| 	case FCC_VOLUME_TOO_SMALL: | ||||
| 		uprintf("Volume is too %s\n", FCC_VOLUME_TOO_BIG?"big":"small"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INVALID_VOLUME_SIZE; | ||||
| 	case FCC_NO_MEDIA_IN_DRIVE: | ||||
| 		uprintf("No media in drive\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NO_MEDIA_IN_DRIVE; | ||||
| 		break; | ||||
| 	default: | ||||
| 		uprintf("FormatExCallback: received unhandled command %X\n", Command); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_SUPPORTED; | ||||
| 		break; | ||||
| 	} | ||||
| 	return (!IS_ERROR(FormatStatus)); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Call on fmifs.dll's FormatEx() to format the drive | ||||
|  */ | ||||
| static BOOL FormatDrive(char DriveLetter) | ||||
| { | ||||
| 	BOOL r = FALSE; | ||||
| 	PF_DECL(FormatEx); | ||||
| 	WCHAR wDriveRoot[] = L"?:\\"; | ||||
| 	WCHAR wFSType[32]; | ||||
| 	WCHAR wLabel[128]; | ||||
| 	size_t i; | ||||
| 
 | ||||
| 	wDriveRoot[0] = (WCHAR)DriveLetter; | ||||
| 	PrintStatus("Formatting..."); | ||||
| 	PF_INIT_OR_OUT(FormatEx, fmifs); | ||||
| 
 | ||||
| 	// TODO: properly set MediaType
 | ||||
| 	GetWindowTextW(hFileSystem, wFSType, ARRAYSIZE(wFSType)); | ||||
| 	// We may have a " (Default)" trail
 | ||||
| 	for (i=0; i<wcslen(wFSType); i++) { | ||||
| 		if (wFSType[i] == ' ') { | ||||
| 			uprintf("removed %d\n", i); | ||||
| 			wFSType[i] = 0; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	GetWindowTextW(hLabel, wLabel, ARRAYSIZE(wLabel)); | ||||
| 	uprintf("Using cluster size: %d bytes\n", ComboBox_GetItemData(hClusterSize, ComboBox_GetCurSel(hClusterSize))); | ||||
| 	pfFormatEx(wDriveRoot, RemovableMedia, wFSType, wLabel, | ||||
| 		IsChecked(IDC_QUICKFORMAT), (ULONG)ComboBox_GetItemData(hClusterSize, ComboBox_GetCurSel(hClusterSize)), | ||||
| 		FormatExCallback); | ||||
| 	if (!IS_ERROR(FormatStatus)) { | ||||
| 		uprintf("Format completed.\n"); | ||||
| 		r = TRUE; | ||||
| 	} | ||||
| 
 | ||||
| out: | ||||
| 	return r; | ||||
| } | ||||
| 
 | ||||
| static BOOL AnalyzeMBR(HANDLE hPhysicalDrive) | ||||
| { | ||||
| 	FILE fake_fd; | ||||
| 
 | ||||
| 	fake_fd._ptr = (char*)hPhysicalDrive; | ||||
| 	fake_fd._bufsiz = SelectedDrive.Geometry.BytesPerSector; | ||||
| 
 | ||||
| 	// TODO: Apply this detection before partitioning
 | ||||
| 	// TODO: since we detect all these, might as well give some MBR choice to the user?
 | ||||
| 	if (is_br(&fake_fd)) { | ||||
| 		uprintf("Drive has an x86 boot sector\n"); | ||||
| 	} else{ | ||||
| 		uprintf("Drive is missing an x86 boot sector!\n"); | ||||
| 		return FALSE; | ||||
| 	} | ||||
| 	// TODO: Add/Eliminate FAT12?
 | ||||
| 	if (is_fat_16_br(&fake_fd) || is_fat_32_br(&fake_fd)) { | ||||
| 		if (entire_fat_16_br_matches(&fake_fd)) { | ||||
| 			uprintf("Exact FAT16 DOS boot record match\n"); | ||||
| 		} else if (entire_fat_16_fd_br_matches(&fake_fd)) { | ||||
| 			uprintf("Exact FAT16 FreeDOS boot record match\n"); | ||||
| 		} else if (entire_fat_32_br_matches(&fake_fd)) { | ||||
| 			uprintf("Exact FAT32 DOS boot record match\n"); | ||||
| 		} else if (entire_fat_32_nt_br_matches(&fake_fd)) { | ||||
| 			uprintf("Exact FAT32 NT boot record match\n"); | ||||
| 		} else if (entire_fat_32_fd_br_matches(&fake_fd)) { | ||||
| 			uprintf("Exactly FAT32 FreeDOS boot record match\n"); | ||||
| 		} else { | ||||
| 			uprintf("Unknown FAT16 or FAT32 boot record\n"); | ||||
| 		} | ||||
| 	} else if (is_dos_mbr(&fake_fd)) { | ||||
| 		uprintf("Microsoft DOS/NT/95A master boot record match\n"); | ||||
| 	} else if (is_dos_f2_mbr(&fake_fd)) { | ||||
| 		uprintf("Microsoft DOS/NT/95A master boot record with the undocumented\n"); | ||||
| 		uprintf("F2 instruction match\n"); | ||||
| 	} else if (is_95b_mbr(&fake_fd)) { | ||||
| 		uprintf("Microsoft 95B/98/98SE/ME master boot record match\n"); | ||||
| 	} else if (is_2000_mbr(&fake_fd)) { | ||||
| 		uprintf("Microsoft 2000/XP/2003 master boot record match\n"); | ||||
| 	} else if (is_vista_mbr(&fake_fd)) { | ||||
| 		uprintf("Microsoft Vista master boot record match\n"); | ||||
| 	} else if (is_win7_mbr(&fake_fd)) { | ||||
| 		uprintf("Microsoft 7 master boot record match\n"); | ||||
| 	} else if (is_zero_mbr(&fake_fd)) { | ||||
| 		uprintf("Zeroed non-bootable master boot record match\n"); | ||||
| 	} else { | ||||
| 		uprintf("Unknown boot record\n"); | ||||
| 	} | ||||
| 	return TRUE; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Process the MBR | ||||
|  */ | ||||
| static BOOL ProcessMBR(HANDLE hPhysicalDrive) | ||||
| { | ||||
| 	BOOL r = FALSE; | ||||
| 	unsigned char* buf = NULL; | ||||
| 	size_t SecSize = SelectedDrive.Geometry.BytesPerSector; | ||||
| 	size_t nSecs = (0x200 + SecSize -1) / SecSize; | ||||
| 	FILE fake_fd; | ||||
| 
 | ||||
| 	if (!AnalyzeMBR(hPhysicalDrive)) return FALSE; | ||||
| 
 | ||||
| 	// FormatEx rewrites the MBR and removes the LBA attribute of FAT16
 | ||||
| 	// and FAT32 partitions - we need to correct this in the MBR
 | ||||
| 	// TODO: something else for bootable GPT
 | ||||
| 	buf = (unsigned char*)malloc(SecSize * nSecs); | ||||
| 	if (buf == NULL) { | ||||
| 		uprintf("Could not allocate memory for MBR"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_ENOUGH_MEMORY; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!read_sectors(hPhysicalDrive, SelectedDrive.Geometry.BytesPerSector, 0, nSecs, buf, SecSize)) { | ||||
| 		uprintf("Could not read MBR\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_READ_FAULT; | ||||
| 		goto out; | ||||
| 	} | ||||
| //	DumpBufferHex(buf, 0x200);
 | ||||
| 	switch (ComboBox_GetCurSel(hFileSystem)) { | ||||
| 	// TODO: check for 0x06 & 0x0b?
 | ||||
| 	case FS_FAT16: | ||||
| 		buf[0x1c2] = 0x0e; | ||||
| 		break; | ||||
| 	case FS_FAT32: | ||||
| 		buf[0x1c2] = 0x0c; | ||||
| 		break; | ||||
| 	} | ||||
| 	if (IsChecked(IDC_DOSSTARTUP)) { | ||||
| 		buf[0x1be] = 0x80;		// Set first partition bootable
 | ||||
| 	} | ||||
| 
 | ||||
| 	if (!write_sectors(hPhysicalDrive, SelectedDrive.Geometry.BytesPerSector, 0, nSecs, buf, SecSize*nSecs)) { | ||||
| 		uprintf("Could not write MBR\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	fake_fd._ptr = (char*)hPhysicalDrive; | ||||
| 	fake_fd._bufsiz = SelectedDrive.Geometry.BytesPerSector; | ||||
| 	r = write_95b_mbr(&fake_fd); | ||||
| 
 | ||||
| 	if (!read_sectors(hPhysicalDrive, SelectedDrive.Geometry.BytesPerSector, 0, nSecs, buf, SecSize)) { | ||||
| 		uprintf("Could not re-read MBR\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_READ_FAULT; | ||||
| 		goto out; | ||||
| 	} | ||||
| 	DumpBufferHex(buf, 0x200); | ||||
| 
 | ||||
| out: | ||||
| 	safe_free(buf); | ||||
| 	return r; | ||||
| } | ||||
| 
 | ||||
| static BOOL ProcessFS_BR(HANDLE hLogicalVolume) | ||||
| { | ||||
| 	BOOL r = FALSE; | ||||
| 	unsigned char* buf = NULL; | ||||
| 	FILE fake_fd; | ||||
| 	size_t SecSize = SelectedDrive.Geometry.BytesPerSector; | ||||
| 	size_t nSecs = (0x400 + SecSize -1) / SecSize; | ||||
| 
 | ||||
| 	fake_fd._ptr = (char*)hLogicalVolume; | ||||
| 	fake_fd._bufsiz = SelectedDrive.Geometry.BytesPerSector; | ||||
| 	write_fat_32_br(&fake_fd, 0); | ||||
| 
 | ||||
| 	// FormatEx rewrites the MBR and removes the LBA attribute of FAT16
 | ||||
| 	// and FAT32 partitions - we need to correct this in the MBR
 | ||||
| 	// TODO: something else for bootable GPT
 | ||||
| 	buf = (unsigned char*)malloc(SecSize * nSecs); | ||||
| 	if (buf == NULL) { | ||||
| 		uprintf("Could not allocate memory for FS BR"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_ENOUGH_MEMORY; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!read_sectors(hLogicalVolume, SelectedDrive.Geometry.BytesPerSector, 0, nSecs, buf, SecSize*nSecs)) { | ||||
| 		uprintf("Could not read FS BR\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_READ_FAULT; | ||||
| 		goto out; | ||||
| 	} | ||||
| 	uprintf("FS_BR:\n"); | ||||
| 	DumpBufferHex(buf, 0x400); | ||||
| 
 | ||||
| out: | ||||
| 	safe_free(buf); | ||||
| 	return r; | ||||
| } | ||||
| 
 | ||||
| /* http://msdn.microsoft.com/en-us/library/windows/desktop/aa364562%28v=vs.85%29.aspx
 | ||||
|    Dismounting a volume is useful when a volume needs to disappear for a while. For | ||||
|    example, an application that changes a volume file system from the FAT file system | ||||
|    to the NTFS file system might use the following procedure. | ||||
| 
 | ||||
|    To change a volume file system | ||||
| 
 | ||||
|     Open a volume. | ||||
|     Lock the volume. | ||||
|     Format the volume. | ||||
|     Dismount the volume. | ||||
|     Unlock the volume. | ||||
|     Close the volume handle. | ||||
| 
 | ||||
|    A dismounting operation removes the volume from the FAT file system awareness. | ||||
|    When the operating system mounts the volume, it appears as an NTFS file system volume. | ||||
| */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Standalone thread for the formatting operation | ||||
|  */ | ||||
| static void __cdecl FormatThread(void* param) | ||||
| { | ||||
| 	DWORD num = (DWORD)(uintptr_t)param; | ||||
| 	HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE; | ||||
| 	HANDLE hLogicalVolume = INVALID_HANDLE_VALUE; | ||||
| 	char drive_name[] = "?:"; | ||||
| 	int i; | ||||
| //	DWORD size;
 | ||||
| 
 | ||||
| 	hPhysicalDrive = GetDriveHandle(num, NULL, TRUE, TRUE); | ||||
| 	if (hPhysicalDrive == INVALID_HANDLE_VALUE) { | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; | ||||
| 		goto out; | ||||
| 	} | ||||
| 	// At this stage with have both a handle and a lock to the physical drive
 | ||||
| 
 | ||||
| 	if (!CreatePartition(hPhysicalDrive)) { | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_PARTITION_FAILURE; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	// Make sure we can access the volume again before trying to format it
 | ||||
| 	for (i=0; i<10; i++) { | ||||
| 		Sleep(500); | ||||
| 		hLogicalVolume = GetDriveHandle(num, drive_name, FALSE, TRUE); | ||||
| 		if (hLogicalVolume != INVALID_HANDLE_VALUE) { | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	if (i >= 10) { | ||||
| 		uprintf("Could not access volume after partitioning\n"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; | ||||
| 		goto out; | ||||
| 	} | ||||
| 	// Handle needs to be closed for FormatEx to be happy - we keep a lock though
 | ||||
| 	safe_closehandle(hLogicalVolume); | ||||
| 
 | ||||
| 	if (!FormatDrive(drive_name[0])) { | ||||
| 		// Error will be set by FormatDrive() in FormatStatus
 | ||||
| 		uprintf("Format error: 0x%08X\n", FormatStatus); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	// TODO: Enable compression on NTFS
 | ||||
| 	// TODO: optionally disable indexing on NTFS
 | ||||
| 	// TODO: use progress bar during MBR/FSBR/MSDOS copy
 | ||||
| 
 | ||||
| 	// Ideally we would lock, FSCTL_DISMOUNT_VOLUME, unlock and close our volume
 | ||||
| 	// handle, but some explorer versions have problems with volumes disappear
 | ||||
| // #define VOL_DISMOUNT
 | ||||
| #ifdef VOL_DISMOUNT | ||||
| 	// Dismount the volume
 | ||||
| 	hLogicalVolume = GetDriveHandle(num, drive_name, FALSE, TRUE); | ||||
| 	if (hLogicalVolume == INVALID_HANDLE_VALUE) { | ||||
| 		uprintf("Could not open the volume for dismount\n"); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!DeviceIoControl(hLogicalVolume, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &size, NULL)) { | ||||
| 		uprintf("Could not dismount volume\n"); | ||||
| 		goto out; | ||||
| 	} | ||||
| #endif | ||||
| 	PrintStatus("Writing master boot record...\n"); | ||||
| 	if (!ProcessMBR(hPhysicalDrive)) { | ||||
| 		// Errorcode has already been set
 | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| #ifdef VOL_DISMOUNT | ||||
| 	safe_unlockclose(hLogicalVolume); | ||||
| //	Sleep(10000);
 | ||||
| 	hLogicalVolume = GetDriveHandle(num, drive_name, FALSE, FALSE); | ||||
| 	if (hLogicalVolume == INVALID_HANDLE_VALUE) { | ||||
| 		uprintf("Could not re-mount volume\n"); | ||||
| 		goto out; | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 	if (IsChecked(IDC_DOSSTARTUP)) { | ||||
| 		hLogicalVolume = GetDriveHandle(num, drive_name, TRUE, FALSE); | ||||
| 		if (hLogicalVolume == INVALID_HANDLE_VALUE) { | ||||
| 			uprintf("Could not re-mount volume\n"); | ||||
| 			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; | ||||
| 			goto out; | ||||
| 		} | ||||
| 		PrintStatus("Writing filesystem boot record...\n"); | ||||
| 		if (!ProcessFS_BR(hLogicalVolume)) { | ||||
| 			// Errorcode has already been set
 | ||||
| 			goto out; | ||||
| 		} | ||||
| 		PrintStatus("Copying MS-DOS files...\n"); | ||||
| 		if (!ExtractMSDOS(drive_name)) { | ||||
| 			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANNOT_COPY; | ||||
| 			goto out; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| out: | ||||
| 	safe_unlockclose(hLogicalVolume); | ||||
| 	safe_unlockclose(hPhysicalDrive); | ||||
| 	PostMessage(hMainDialog, UM_FORMAT_COMPLETED, 0, 0); | ||||
| 	_endthread(); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Refresh the list of USB devices | ||||
|  */ | ||||
|  |  | |||
							
								
								
									
										184
									
								
								rufus.h
									
										
									
									
									
								
							
							
						
						
									
										184
									
								
								rufus.h
									
										
									
									
									
								
							|  | @ -15,8 +15,8 @@ | |||
|  * 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 <Windows.h> | ||||
| #include <winioctl.h>				// for MEDIA_TYPE | ||||
| #include <windows.h> | ||||
| #include <winioctl.h>				// for DISK_GEOMETRY | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
|  | @ -62,42 +62,6 @@ | |||
| #define safe_vsnprintf vsnprintf | ||||
| #endif | ||||
| 
 | ||||
| /*
 | ||||
|  * Globals | ||||
|  */ | ||||
| extern HINSTANCE hMainInstance; | ||||
| extern HWND hMainDialog; | ||||
| extern HWND hStatus; | ||||
| extern float fScale; | ||||
| extern char szFolderPath[MAX_PATH]; | ||||
| 
 | ||||
| /*
 | ||||
|  * Shared prototypes | ||||
|  */ | ||||
| extern char *WindowsErrorString(void); | ||||
| extern void DumpBufferHex(void *buf, size_t size); | ||||
| extern void PrintStatus(const char *format, ...); | ||||
| extern void CenterDialog(HWND hDlg); | ||||
| extern void CreateStatusBar(void); | ||||
| extern INT_PTR CreateAboutBox(void); | ||||
| extern HWND CreateTooltip(HWND hControl, const char* message, int duration); | ||||
| extern void DestroyTooltip(HWND hWnd); | ||||
| extern void DestroyAllTooltips(void); | ||||
| extern void Notification(int type, char* text, char* title); | ||||
| extern BOOL ExtractMSDOS(const char* path); | ||||
| 
 | ||||
| /* Basic String Array */ | ||||
| typedef struct { | ||||
| 	char** Table; | ||||
| 	size_t Size; | ||||
| 	size_t Index; | ||||
| 	size_t Max; | ||||
| } StrArray; | ||||
| extern void StrArrayCreate(StrArray* arr, size_t initial_size); | ||||
| extern void StrArrayAdd(StrArray* arr, const char* str); | ||||
| extern void StrArrayClear(StrArray* arr); | ||||
| extern void StrArrayDestroy(StrArray* arr); | ||||
| 
 | ||||
| #ifdef RUFUS_DEBUG | ||||
| extern void _uprintf(const char *format, ...); | ||||
| #define uprintf(...) _uprintf(__VA_ARGS__) | ||||
|  | @ -131,95 +95,73 @@ enum { | |||
| 	FS_MAX | ||||
| }; | ||||
| 
 | ||||
| /* Current drive info */ | ||||
| typedef struct { | ||||
| 	DWORD DeviceNumber; | ||||
| 	LONGLONG DiskSize; | ||||
| 	DISK_GEOMETRY Geometry; | ||||
| 	DWORD FirstSector; | ||||
| 	int FSType; | ||||
| 	struct { | ||||
| 		ULONG Allowed; | ||||
| 		ULONG Default; | ||||
| 	} ClusterSize[FS_MAX]; | ||||
| } RUFUS_DRIVE_INFO; | ||||
| 
 | ||||
| /*
 | ||||
|  * Globals | ||||
|  */ | ||||
| extern HINSTANCE hMainInstance; | ||||
| extern HWND hMainDialog, hStatus, hDeviceList, hCapacity; | ||||
| extern HWND hFileSystem, hClusterSize, hLabel;  | ||||
| extern float fScale; | ||||
| extern char szFolderPath[MAX_PATH]; | ||||
| extern DWORD FormatStatus; | ||||
| extern RUFUS_DRIVE_INFO SelectedDrive; | ||||
| 
 | ||||
| /*
 | ||||
|  * Shared prototypes | ||||
|  */ | ||||
| extern char *WindowsErrorString(void); | ||||
| extern void DumpBufferHex(void *buf, size_t size); | ||||
| extern void PrintStatus(const char *format, ...); | ||||
| extern void CenterDialog(HWND hDlg); | ||||
| extern void CreateStatusBar(void); | ||||
| extern INT_PTR CreateAboutBox(void); | ||||
| extern HWND CreateTooltip(HWND hControl, const char* message, int duration); | ||||
| extern void DestroyTooltip(HWND hWnd); | ||||
| extern void DestroyAllTooltips(void); | ||||
| extern void Notification(int type, char* text, char* title); | ||||
| extern BOOL ExtractMSDOS(const char* path); | ||||
| extern void __cdecl FormatThread(void* param); | ||||
| extern BOOL CreatePartition(HANDLE hDrive); | ||||
| extern HANDLE GetDriveHandle(DWORD DriveIndex, char* DriveLetter, BOOL bWriteAccess, BOOL bLockDrive); | ||||
| 
 | ||||
| __inline static BOOL UnlockDrive(HANDLE hDrive) | ||||
| { | ||||
| 	DWORD size; | ||||
| 	return DeviceIoControl(hDrive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &size, NULL); | ||||
| } | ||||
| 
 | ||||
| /* Basic String Array */ | ||||
| typedef struct { | ||||
| 	char** Table; | ||||
| 	size_t Size; | ||||
| 	size_t Index; | ||||
| 	size_t Max; | ||||
| } StrArray; | ||||
| extern void StrArrayCreate(StrArray* arr, size_t initial_size); | ||||
| extern void StrArrayAdd(StrArray* arr, const char* str); | ||||
| extern void StrArrayClear(StrArray* arr); | ||||
| extern void StrArrayDestroy(StrArray* arr); | ||||
| 
 | ||||
| /* We need a redef of this MS structure */ | ||||
| typedef struct { | ||||
| 	DWORD DeviceType; | ||||
| 	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                        pData | ||||
| ); | ||||
| 
 | ||||
| /* Parameter names 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
 | ||||
| ); | ||||
| 
 | ||||
| /* Custom application errors */ | ||||
| #define FAC(f)                         (f<<16) | ||||
|  |  | |||
							
								
								
									
										12
									
								
								rufus.rc
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								rufus.rc
									
										
									
									
									
								
							|  | @ -63,7 +63,7 @@ BEGIN | |||
|     DEFPUSHBUTTON   "OK",IDOK,231,175,50,14,WS_GROUP | ||||
|     CONTROL         "<a href=""https://github.com/pbatard/rufus/wiki/Rufus"">https://github.com/pbatard/rufus</a>",IDC_ABOUT_RUFUS_URL, | ||||
|                     "SysLink",WS_TABSTOP,46,47,114,9 | ||||
|     LTEXT           "Version 1.0.0 (Build 57)",IDC_STATIC,46,19,78,8 | ||||
|     LTEXT           "Version 1.0.0 (Build 58)",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 | ||||
|  | @ -162,8 +162,8 @@ END | |||
| // | ||||
| 
 | ||||
| VS_VERSION_INFO VERSIONINFO | ||||
|  FILEVERSION 1,0,0,57 | ||||
|  PRODUCTVERSION 1,0,0,57 | ||||
|  FILEVERSION 1,0,0,58 | ||||
|  PRODUCTVERSION 1,0,0,58 | ||||
|  FILEFLAGSMASK 0x3fL | ||||
| #ifdef _DEBUG | ||||
|  FILEFLAGS 0x1L | ||||
|  | @ -180,13 +180,13 @@ BEGIN | |||
|         BEGIN | ||||
|             VALUE "CompanyName", "akeo.ie" | ||||
|             VALUE "FileDescription", "Rufus" | ||||
|             VALUE "FileVersion", "1.0.0.57" | ||||
|             VALUE "FileVersion", "1.0.0.58" | ||||
|             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.0.57" | ||||
|             VALUE "ProductVersion", "1.0.0.58" | ||||
|         END | ||||
|     END | ||||
|     BLOCK "VarFileInfo" | ||||
|  | @ -212,7 +212,7 @@ IDI_ICON                ICON                    "rufus.ico" | |||
| 
 | ||||
| STRINGTABLE | ||||
| BEGIN | ||||
|     IDS_VERSION             "Rufus v1.0.0.57" | ||||
|     IDS_VERSION             "Rufus v1.0.0.58" | ||||
| END | ||||
| 
 | ||||
| #endif    // English resources | ||||
|  |  | |||
							
								
								
									
										4
									
								
								stdio.c
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								stdio.c
									
										
									
									
									
								
							|  | @ -16,6 +16,10 @@ | |||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| #ifdef _CRTDBG_MAP_ALLOC | ||||
| #include <stdlib.h> | ||||
| #include <crtdbg.h> | ||||
| #endif | ||||
| 
 | ||||
| #include <windows.h> | ||||
| #include <stdio.h> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue