mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[core] detect memory cards in card readers
* Also remove drives with no media from the list * Closes #18
This commit is contained in:
		
							parent
							
								
									897becd290
								
							
						
					
					
						commit
						36693d2144
					
				
					 6 changed files with 75 additions and 9 deletions
				
			
		
							
								
								
									
										17
									
								
								src/drive.c
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								src/drive.c
									
										
									
									
									
								
							|  | @ -450,6 +450,23 @@ uint64_t GetDriveSize(DWORD DriveIndex) | ||||||
| 	return DiskGeometry->DiskSize.QuadPart; | 	return DiskGeometry->DiskSize.QuadPart; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * GET_DRIVE_GEOMETRY is used to tell if there is an actual media | ||||||
|  |  */ | ||||||
|  | BOOL IsMediaPresent(DWORD DriveIndex) | ||||||
|  | { | ||||||
|  | 	BOOL r; | ||||||
|  | 	HANDLE hPhysical; | ||||||
|  | 	DWORD size; | ||||||
|  | 	BYTE geometry[128]; | ||||||
|  | 
 | ||||||
|  | 	hPhysical = GetPhysicalHandle(DriveIndex, FALSE, FALSE); | ||||||
|  | 	r = DeviceIoControl(hPhysical, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, | ||||||
|  | 			NULL, 0, geometry, sizeof(geometry), &size, NULL) || (size <= 0); | ||||||
|  | 	safe_closehandle(hPhysical); | ||||||
|  | 	return r; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Fill the drive properties (size, FS, etc) |  * Fill the drive properties (size, FS, etc) | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | @ -1243,7 +1243,7 @@ DWORD WINAPI FormatThread(LPVOID param) | ||||||
| 	// Try to ensure that all messages from Format and Checkdisk, which we report in the log, will be in English
 | 	// Try to ensure that all messages from Format and Checkdisk, which we report in the log, will be in English
 | ||||||
| 	pfSetThreadUILanguage(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)); | 	pfSetThreadUILanguage(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)); | ||||||
| 	if (PRIMARYLANGID(pfGetThreadUILanguage()) != LANG_ENGLISH) | 	if (PRIMARYLANGID(pfGetThreadUILanguage()) != LANG_ENGLISH) | ||||||
| 		uprintf("Note: the formatting thread could not be set to English"); | 		uprintf("Note: some formatting messages may still be localized"); | ||||||
| 
 | 
 | ||||||
| 	PrintStatus(0, TRUE, MSG_225); | 	PrintStatus(0, TRUE, MSG_225); | ||||||
| 	hPhysicalDrive = GetPhysicalHandle(DriveIndex, TRUE, TRUE); | 	hPhysicalDrive = GetPhysicalHandle(DriveIndex, TRUE, TRUE); | ||||||
|  |  | ||||||
|  | @ -134,7 +134,6 @@ static BOOL htab_create(uint32_t nel) | ||||||
| 		nel += 2; | 		nel += 2; | ||||||
| 
 | 
 | ||||||
| 	htab_size = nel; | 	htab_size = nel; | ||||||
| 	uprintf("localization: using %d entries hash table\n", nel); |  | ||||||
| 	htab_filled = 0; | 	htab_filled = 0; | ||||||
| 
 | 
 | ||||||
| 	// allocate memory and zero out.
 | 	// allocate memory and zero out.
 | ||||||
|  |  | ||||||
							
								
								
									
										52
									
								
								src/rufus.c
									
										
									
									
									
								
							
							
						
						
									
										52
									
								
								src/rufus.c
									
										
									
									
									
								
							|  | @ -31,6 +31,7 @@ | ||||||
| #include <commctrl.h> | #include <commctrl.h> | ||||||
| #include <setupapi.h> | #include <setupapi.h> | ||||||
| #include <winioctl.h> | #include <winioctl.h> | ||||||
|  | #include <shlobj.h> | ||||||
| #include <process.h> | #include <process.h> | ||||||
| #include <dbt.h> | #include <dbt.h> | ||||||
| #include <io.h> | #include <io.h> | ||||||
|  | @ -65,7 +66,7 @@ | ||||||
| #define DBT_CUSTOMEVENT 0x8006 | #define DBT_CUSTOMEVENT 0x8006 | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| // MinGW fails to link those
 | // MinGW fails to link those...
 | ||||||
| typedef HIMAGELIST (WINAPI *ImageList_Create_t)( | typedef HIMAGELIST (WINAPI *ImageList_Create_t)( | ||||||
| 	int cx, | 	int cx, | ||||||
| 	int cy, | 	int cy, | ||||||
|  | @ -86,6 +87,25 @@ struct { | ||||||
| 	UINT uAlign; | 	UINT uAlign; | ||||||
| } bi_iso = {0}, bi_up = {0}, bi_down = {0}, bi_lang = {0};	// BUTTON_IMAGELIST
 | } bi_iso = {0}, bi_up = {0}, bi_down = {0}, bi_lang = {0};	// BUTTON_IMAGELIST
 | ||||||
| 
 | 
 | ||||||
|  | // ...and MinGW doesn't know these.
 | ||||||
|  | typedef struct | ||||||
|  | { | ||||||
|  | 	LPCITEMIDLIST pidl; | ||||||
|  | 	BOOL   fRecursive; | ||||||
|  | } MY_SHChangeNotifyEntry; | ||||||
|  | 
 | ||||||
|  | typedef BOOL (WINAPI *SHChangeNotifyDeregister_t)( | ||||||
|  | 	ULONG ulID | ||||||
|  | ); | ||||||
|  | typedef ULONG (WINAPI *SHChangeNotifyRegister_t)( | ||||||
|  | 	HWND hwnd, | ||||||
|  | 	int fSources, | ||||||
|  | 	LONG fEvents, | ||||||
|  | 	UINT wMsg, | ||||||
|  | 	int cEntries, | ||||||
|  | 	const MY_SHChangeNotifyEntry *pshcne | ||||||
|  | ); | ||||||
|  | 
 | ||||||
| const char* FileSystemLabel[FS_MAX] = { "FAT", "FAT32", "NTFS", "UDF", "exFAT" }; | const char* FileSystemLabel[FS_MAX] = { "FAT", "FAT32", "NTFS", "UDF", "exFAT" }; | ||||||
| // Number of steps for each FS for FCC_STRUCTURE_PROGRESS
 | // Number of steps for each FS for FCC_STRUCTURE_PROGRESS
 | ||||||
| const int nb_steps[FS_MAX] = { 5, 5, 12, 1, 10 }; | const int nb_steps[FS_MAX] = { 5, 5, 12, 1, 10 }; | ||||||
|  | @ -745,6 +765,13 @@ static BOOL GetUSBDevices(DWORD devnum) | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			drive_index = device_number.DeviceNumber + DRIVE_INDEX_MIN; | 			drive_index = device_number.DeviceNumber + DRIVE_INDEX_MIN; | ||||||
|  | 			if (!IsMediaPresent(drive_index)) { | ||||||
|  | 				uprintf("Device eliminated because it appears to contain no media\n"); | ||||||
|  | 				safe_closehandle(hDrive); | ||||||
|  | 				safe_free(devint_detail_data); | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
| 			if (GetDriveLabel(drive_index, &drive_letter, &label)) { | 			if (GetDriveLabel(drive_index, &drive_letter, &label)) { | ||||||
| 				if ((!enable_HDDs) && ((score = IsHDD(drive_index, vid, pid, buffer)) > 0)) { | 				if ((!enable_HDDs) && ((score = IsHDD(drive_index, vid, pid, buffer)) > 0)) { | ||||||
| 					uprintf("Device eliminated because it was detected as an USB Hard Drive (score %d > 0)\n", score); | 					uprintf("Device eliminated because it was detected as an USB Hard Drive (score %d > 0)\n", score); | ||||||
|  | @ -1512,10 +1539,18 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 	char tmp[128]; | 	char tmp[128]; | ||||||
| 	static UINT uBootChecked = BST_CHECKED, uQFChecked; | 	static UINT uBootChecked = BST_CHECKED, uQFChecked; | ||||||
| 	static BOOL first_log_display = TRUE, user_changed_label = FALSE; | 	static BOOL first_log_display = TRUE, user_changed_label = FALSE; | ||||||
|  | 	static ULONG ulRegister = 0; | ||||||
|  | 	static LPITEMIDLIST pidlDesktop = NULL; | ||||||
|  | 	static MY_SHChangeNotifyEntry NotifyEntry; | ||||||
| 	loc_cmd* lcmd = NULL; | 	loc_cmd* lcmd = NULL; | ||||||
|  | 	PF_DECL(SHChangeNotifyRegister); | ||||||
|  | 	PF_DECL(SHChangeNotifyDeregister); | ||||||
| 
 | 
 | ||||||
| 	switch (message) { | 	switch (message) { | ||||||
| 
 | 
 | ||||||
|  | 	case UM_MEDIA_CHANGE: | ||||||
|  | 		wParam = DBT_CUSTOMEVENT; | ||||||
|  | 		// Fall through
 | ||||||
| 	case WM_DEVICECHANGE: | 	case WM_DEVICECHANGE: | ||||||
| 		// The Windows hotplug subsystem sucks. Among other things, if you insert a GPT partitioned
 | 		// The Windows hotplug subsystem sucks. Among other things, if you insert a GPT partitioned
 | ||||||
| 		// USB drive with zero partitions, the only device messages you will get are a stream of
 | 		// USB drive with zero partitions, the only device messages you will get are a stream of
 | ||||||
|  | @ -1528,7 +1563,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 			switch (wParam) { | 			switch (wParam) { | ||||||
| 			case DBT_DEVICEARRIVAL: | 			case DBT_DEVICEARRIVAL: | ||||||
| 			case DBT_DEVICEREMOVECOMPLETE: | 			case DBT_DEVICEREMOVECOMPLETE: | ||||||
| 			case DBT_CUSTOMEVENT:	// This last event is sent by our timer refresh function
 | 			case DBT_CUSTOMEVENT:	// Sent by our timer refresh function or for card reader media change
 | ||||||
| 				LastRefresh = GetTickCount();	// Don't care about 49.7 days rollback of GetTickCount()
 | 				LastRefresh = GetTickCount();	// Don't care about 49.7 days rollback of GetTickCount()
 | ||||||
| 				KillTimer(hMainDialog, TID_REFRESH_TIMER); | 				KillTimer(hMainDialog, TID_REFRESH_TIMER); | ||||||
| 				GetUSBDevices((DWORD)ComboBox_GetItemData(hDeviceList, ComboBox_GetCurSel(hDeviceList))); | 				GetUSBDevices((DWORD)ComboBox_GetItemData(hDeviceList, ComboBox_GetCurSel(hDeviceList))); | ||||||
|  | @ -1549,6 +1584,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
| 	case WM_INITDIALOG: | 	case WM_INITDIALOG: | ||||||
|  | 		PF_INIT(SHChangeNotifyRegister, shell32); | ||||||
| 		apply_localization(IDD_DIALOG, hDlg); | 		apply_localization(IDD_DIALOG, hDlg); | ||||||
| 		SetUpdateCheck(); | 		SetUpdateCheck(); | ||||||
| 		advanced_mode = TRUE; | 		advanced_mode = TRUE; | ||||||
|  | @ -1559,6 +1595,15 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 		InitDialog(hDlg); | 		InitDialog(hDlg); | ||||||
| 		GetUSBDevices(0); | 		GetUSBDevices(0); | ||||||
| 		CheckForUpdates(FALSE); | 		CheckForUpdates(FALSE); | ||||||
|  | 		// Register MEDIA_INSERTED/MEDIA_REMOVED notifications for card readers
 | ||||||
|  | 		if ((pfSHChangeNotifyRegister != NULL) && (SUCCEEDED(SHGetSpecialFolderLocation(0, CSIDL_DESKTOP, &pidlDesktop)))) { | ||||||
|  | 			NotifyEntry.pidl = pidlDesktop; | ||||||
|  | 			NotifyEntry.fRecursive = TRUE; | ||||||
|  | 			// NB: The following only works if the media is already formatted.
 | ||||||
|  | 			// If you insert a blank card, notifications will not be sent... :(
 | ||||||
|  | 			ulRegister = pfSHChangeNotifyRegister(hDlg, 0x0001|0x0002|0x8000, | ||||||
|  | 				SHCNE_MEDIAINSERTED|SHCNE_MEDIAREMOVED, UM_MEDIA_CHANGE, 1, &NotifyEntry); | ||||||
|  | 		} | ||||||
| 		PostMessage(hMainDialog, UM_ISO_CREATE, 0, 0); | 		PostMessage(hMainDialog, UM_ISO_CREATE, 0, 0); | ||||||
| 		return (INT_PTR)TRUE; | 		return (INT_PTR)TRUE; | ||||||
| 
 | 
 | ||||||
|  | @ -1600,6 +1645,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 		switch(LOWORD(wParam)) { | 		switch(LOWORD(wParam)) { | ||||||
| 		case IDOK:			// close application
 | 		case IDOK:			// close application
 | ||||||
| 		case IDCANCEL: | 		case IDCANCEL: | ||||||
|  | 			PF_INIT(SHChangeNotifyDeregister, shell32); | ||||||
| 			EnableWindow(GetDlgItem(hISOProgressDlg, IDC_ISO_ABORT), FALSE); | 			EnableWindow(GetDlgItem(hISOProgressDlg, IDC_ISO_ABORT), FALSE); | ||||||
| 			EnableWindow(GetDlgItem(hDlg, IDCANCEL), FALSE); | 			EnableWindow(GetDlgItem(hDlg, IDCANCEL), FALSE); | ||||||
| 			if (format_thid != NULL) { | 			if (format_thid != NULL) { | ||||||
|  | @ -1622,6 +1668,8 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 				} | 				} | ||||||
| 				return (INT_PTR)TRUE; | 				return (INT_PTR)TRUE; | ||||||
| 			} | 			} | ||||||
|  | 			if ((pfSHChangeNotifyDeregister != NULL) && (ulRegister != 0)) | ||||||
|  | 				pfSHChangeNotifyDeregister(ulRegister); | ||||||
| 			PostQuitMessage(0); | 			PostQuitMessage(0); | ||||||
| 			StrArrayDestroy(&DriveID); | 			StrArrayDestroy(&DriveID); | ||||||
| 			StrArrayDestroy(&DriveLabel); | 			StrArrayDestroy(&DriveLabel); | ||||||
|  |  | ||||||
|  | @ -109,6 +109,7 @@ extern void _uprintf(const char *format, ...); | ||||||
| /* Custom Windows messages */ | /* Custom Windows messages */ | ||||||
| enum user_message_type { | enum user_message_type { | ||||||
| 	UM_FORMAT_COMPLETED = WM_APP, | 	UM_FORMAT_COMPLETED = WM_APP, | ||||||
|  | 	UM_MEDIA_CHANGE, | ||||||
| 	// TODO: relabel "ISO" to a more generic "progress"
 | 	// TODO: relabel "ISO" to a more generic "progress"
 | ||||||
| 	UM_ISO_CREATE, | 	UM_ISO_CREATE, | ||||||
| 	UM_ISO_INIT, | 	UM_ISO_INIT, | ||||||
|  | @ -329,6 +330,7 @@ extern BOOL DeletePartitions(HANDLE hDrive); | ||||||
| extern const char* GetPartitionType(BYTE Type); | extern const char* GetPartitionType(BYTE Type); | ||||||
| extern BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSystemNameSize); | extern BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSystemNameSize); | ||||||
| extern BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label); | extern BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label); | ||||||
|  | extern BOOL IsMediaPresent(DWORD DriveIndex); | ||||||
| extern BOOL MountVolume(char* drive_name, char *drive_guid); | extern BOOL MountVolume(char* drive_name, char *drive_guid); | ||||||
| extern BOOL UnmountVolume(HANDLE hDrive); | extern BOOL UnmountVolume(HANDLE hDrive); | ||||||
| extern BOOL RemountVolume(char* drive_name); | extern BOOL RemountVolume(char* drive_name); | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								src/rufus.rc
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								src/rufus.rc
									
										
									
									
									
								
							|  | @ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL | ||||||
| IDD_DIALOG DIALOGEX 12, 12, 206, 329 | IDD_DIALOG DIALOGEX 12, 12, 206, 329 | ||||||
| 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.4.2.359" | CAPTION "Rufus v1.4.2.360" | ||||||
| FONT 8, "MS Shell Dlg", 400, 0, 0x1 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 | ||||||
| BEGIN | BEGIN | ||||||
|     DEFPUSHBUTTON   "Start",IDC_START,94,291,50,14 |     DEFPUSHBUTTON   "Start",IDC_START,94,291,50,14 | ||||||
|  | @ -288,8 +288,8 @@ END | ||||||
| // | // | ||||||
| 
 | 
 | ||||||
| VS_VERSION_INFO VERSIONINFO | VS_VERSION_INFO VERSIONINFO | ||||||
|  FILEVERSION 1,4,2,359 |  FILEVERSION 1,4,2,360 | ||||||
|  PRODUCTVERSION 1,4,2,359 |  PRODUCTVERSION 1,4,2,360 | ||||||
|  FILEFLAGSMASK 0x3fL |  FILEFLAGSMASK 0x3fL | ||||||
| #ifdef _DEBUG | #ifdef _DEBUG | ||||||
|  FILEFLAGS 0x1L |  FILEFLAGS 0x1L | ||||||
|  | @ -306,13 +306,13 @@ BEGIN | ||||||
|         BEGIN |         BEGIN | ||||||
|             VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" |             VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" | ||||||
|             VALUE "FileDescription", "Rufus" |             VALUE "FileDescription", "Rufus" | ||||||
|             VALUE "FileVersion", "1.4.2.359" |             VALUE "FileVersion", "1.4.2.360" | ||||||
|             VALUE "InternalName", "Rufus" |             VALUE "InternalName", "Rufus" | ||||||
|             VALUE "LegalCopyright", "© 2011-2013 Pete Batard (GPL v3)" |             VALUE "LegalCopyright", "© 2011-2013 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.4.2.359" |             VALUE "ProductVersion", "1.4.2.360" | ||||||
|         END |         END | ||||||
|     END |     END | ||||||
|     BLOCK "VarFileInfo" |     BLOCK "VarFileInfo" | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue