mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[enum] populate the device list
This commit is contained in:
		
							parent
							
								
									7b84a6adff
								
							
						
					
					
						commit
						e041eea1df
					
				
					 3 changed files with 241 additions and 15 deletions
				
			
		|  | @ -78,7 +78,7 @@ | ||||||
|       <WarningLevel>Level3</WarningLevel> |       <WarningLevel>Level3</WarningLevel> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|     <Link> |     <Link> | ||||||
|       <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies> |       <AdditionalDependencies>setupapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies> | ||||||
|       <UACExecutionLevel>HighestAvailable</UACExecutionLevel> |       <UACExecutionLevel>HighestAvailable</UACExecutionLevel> | ||||||
|       <GenerateDebugInformation>true</GenerateDebugInformation> |       <GenerateDebugInformation>true</GenerateDebugInformation> | ||||||
|       <SubSystem>Windows</SubSystem> |       <SubSystem>Windows</SubSystem> | ||||||
|  | @ -98,7 +98,7 @@ | ||||||
|       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> |       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|     <Link> |     <Link> | ||||||
|       <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies> |       <AdditionalDependencies>setupapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies> | ||||||
|       <UACExecutionLevel>HighestAvailable</UACExecutionLevel> |       <UACExecutionLevel>HighestAvailable</UACExecutionLevel> | ||||||
|       <GenerateDebugInformation>true</GenerateDebugInformation> |       <GenerateDebugInformation>true</GenerateDebugInformation> | ||||||
|       <SubSystem>Windows</SubSystem> |       <SubSystem>Windows</SubSystem> | ||||||
|  | @ -113,7 +113,7 @@ | ||||||
|       <WarningLevel>Level3</WarningLevel> |       <WarningLevel>Level3</WarningLevel> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|     <Link> |     <Link> | ||||||
|       <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies> |       <AdditionalDependencies>setupapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies> | ||||||
|       <UACExecutionLevel>HighestAvailable</UACExecutionLevel> |       <UACExecutionLevel>HighestAvailable</UACExecutionLevel> | ||||||
|       <GenerateDebugInformation>false</GenerateDebugInformation> |       <GenerateDebugInformation>false</GenerateDebugInformation> | ||||||
|       <SubSystem>Windows</SubSystem> |       <SubSystem>Windows</SubSystem> | ||||||
|  | @ -131,7 +131,7 @@ | ||||||
|       <WarningLevel>Level3</WarningLevel> |       <WarningLevel>Level3</WarningLevel> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|     <Link> |     <Link> | ||||||
|       <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies> |       <AdditionalDependencies>setupapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies> | ||||||
|       <UACExecutionLevel>HighestAvailable</UACExecutionLevel> |       <UACExecutionLevel>HighestAvailable</UACExecutionLevel> | ||||||
|       <GenerateDebugInformation>false</GenerateDebugInformation> |       <GenerateDebugInformation>false</GenerateDebugInformation> | ||||||
|       <SubSystem>Windows</SubSystem> |       <SubSystem>Windows</SubSystem> | ||||||
|  |  | ||||||
							
								
								
									
										222
									
								
								usbdos.c
									
										
									
									
									
								
							
							
						
						
									
										222
									
								
								usbdos.c
									
										
									
									
									
								
							|  | @ -22,6 +22,8 @@ | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <commctrl.h> | #include <commctrl.h> | ||||||
|  | #include <setupapi.h> | ||||||
|  | #include <ntddscsi.h> | ||||||
| 
 | 
 | ||||||
| #include "msapi_utf8.h" | #include "msapi_utf8.h" | ||||||
| #include "resource.h" | #include "resource.h" | ||||||
|  | @ -30,7 +32,219 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Globals |  * Globals | ||||||
|  */ |  */ | ||||||
| HINSTANCE main_instance; | static HINSTANCE main_instance; | ||||||
|  | static HWND hDeviceList; | ||||||
|  | 
 | ||||||
|  | #ifdef USBDOS_DEBUG | ||||||
|  | static void _uprintf(const char *format, ...) | ||||||
|  | { | ||||||
|  | 	char buf[4096], *p = buf; | ||||||
|  | 	va_list args; | ||||||
|  | 	int n; | ||||||
|  | 
 | ||||||
|  | 	va_start(args, format); | ||||||
|  | 	n = safe_vsnprintf(p, sizeof(buf)-3, format, args); // buf-3 is room for CR/LF/NUL
 | ||||||
|  | 	va_end(args); | ||||||
|  | 
 | ||||||
|  | 	p += (n < 0)?sizeof(buf)-3:n; | ||||||
|  | 
 | ||||||
|  | 	while((p>buf) && (isspace(p[-1]))) | ||||||
|  | 		*--p = '\0'; | ||||||
|  | 
 | ||||||
|  | 	*p++ = '\r'; | ||||||
|  | 	*p++ = '\n'; | ||||||
|  | 	*p   = '\0'; | ||||||
|  | 
 | ||||||
|  | 	OutputDebugStringA(buf); | ||||||
|  | } | ||||||
|  | #define uprintf(...) _uprintf(__VA_ARGS__) | ||||||
|  | #else | ||||||
|  | #define uprintf(...) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Converts a windows error to human readable string | ||||||
|  |  * uses retval as errorcode, or, if 0, use GetLastError() | ||||||
|  |  */ | ||||||
|  | static char *WindowsErrorString(DWORD retval) | ||||||
|  | { | ||||||
|  | static char err_string[256]; | ||||||
|  | 
 | ||||||
|  | 	DWORD size; | ||||||
|  | 	DWORD error_code, format_error; | ||||||
|  | 
 | ||||||
|  | 	error_code = retval?retval:GetLastError(); | ||||||
|  | 
 | ||||||
|  | 	safe_sprintf(err_string, sizeof(err_string), "[%d] ", error_code); | ||||||
|  | 
 | ||||||
|  | 	size = FormatMessageU(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code, | ||||||
|  | 		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &err_string[strlen(err_string)], | ||||||
|  | 		sizeof(err_string)-(DWORD)strlen(err_string), NULL); | ||||||
|  | 	if (size == 0) { | ||||||
|  | 		format_error = GetLastError(); | ||||||
|  | 		if (format_error) | ||||||
|  | 			safe_sprintf(err_string, sizeof(err_string), | ||||||
|  | 				"Windows error code %u (FormatMessage error code %u)", error_code, format_error); | ||||||
|  | 		else | ||||||
|  | 			safe_sprintf(err_string, sizeof(err_string), "Unknown error code %u", error_code); | ||||||
|  | 	} | ||||||
|  | 	return err_string; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Returns the drive letter (0 if error) and fills the drive label | ||||||
|  |  */ | ||||||
|  | char GetDriveInfo(DWORD num, char** label) | ||||||
|  | { | ||||||
|  | 	BOOL r, ret = FALSE; | ||||||
|  | 	DWORD size; | ||||||
|  | 	HANDLE hDrive; | ||||||
|  | 	STORAGE_DEVICE_NUMBER sdn = {0}; | ||||||
|  | 	static char volume_label[MAX_PATH]; | ||||||
|  | 	static char drives[26*2]; | ||||||
|  | 	char *drive = drives; | ||||||
|  | 	char drive_name[] = "\\\\.\\#:"; | ||||||
|  | 
 | ||||||
|  | 	*label = "NO_LABEL"; | ||||||
|  | 
 | ||||||
|  | 	size = GetLogicalDriveStringsA(sizeof(drives), drives); | ||||||
|  | 	if (size == 0) { | ||||||
|  | 		uprintf("GetLogicalDriveStrings failed: %s\n", WindowsErrorString(0)); | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 	if (size > sizeof(drives)) { | ||||||
|  | 		uprintf("GetLogicalDriveStrings: buffer too small (required %d vs %d)\n", size, sizeof(drives)); | ||||||
|  | 		return FALSE; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for ( ;*drive; drive += safe_strlen(drive)+1) { | ||||||
|  | 		if (*drive < 'C') { | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  | 		safe_sprintf(drive_name, sizeof(drive_name), "\\\\.\\%c:", drive[0]); | ||||||
|  | 		hDrive = CreateFileA(drive_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); | ||||||
|  | 		if (hDrive == INVALID_HANDLE_VALUE) { | ||||||
|  | 			uprintf("Could not open drive %c: %s\n", WindowsErrorString(0)); | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  | 	 | ||||||
|  | 		r = DeviceIoControl(hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, | ||||||
|  | 			0, &sdn, sizeof(sdn), &size, NULL); | ||||||
|  | 		if ((!r) || (size <= 0)) { | ||||||
|  | 			uprintf("IOCTL_STORAGE_GET_DEVICE_NUMBER failed: %s\n", WindowsErrorString(0)); | ||||||
|  | 			CloseHandle(hDrive); | ||||||
|  | 			return 0; | ||||||
|  | 		} | ||||||
|  | 		if (sdn.DeviceNumber == num) | ||||||
|  | 			break; | ||||||
|  | 		CloseHandle(hDrive); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (*drive && GetVolumeInformationA(drive, volume_label, sizeof(volume_label), NULL, NULL, NULL, NULL, 0)) { | ||||||
|  | 		*label = volume_label; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *drive; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Refreshes the list of USB devices | ||||||
|  |  */ | ||||||
|  | static BOOL GetUSBDevices(void) | ||||||
|  | { | ||||||
|  | 	BOOL r; | ||||||
|  | 	HDEVINFO dev_info = NULL; | ||||||
|  | 	SP_DEVINFO_DATA dev_info_data; | ||||||
|  | 	SP_DEVICE_INTERFACE_DATA devint_data; | ||||||
|  | 	PSP_DEVICE_INTERFACE_DETAIL_DATA_A devint_detail_data; | ||||||
|  | 	STORAGE_DEVICE_NUMBER storage_device; | ||||||
|  | 	DWORD size, i, j, datatype; | ||||||
|  | 	HANDLE hDrive; | ||||||
|  | 	char drive_letter; | ||||||
|  | 	char *label, entry[MAX_PATH], buffer[MAX_PATH]; | ||||||
|  | 
 | ||||||
|  | 	IGNORE_RETVAL(ComboBox_ResetContent(hDeviceList)); | ||||||
|  | 
 | ||||||
|  | 	dev_info = SetupDiGetClassDevsA(&GUID_DEVINTERFACE_DISK, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); | ||||||
|  | 	if (dev_info == INVALID_HANDLE_VALUE) { | ||||||
|  | 		uprintf("SetupDiGetClassDevs (Interface) failed: %d\n", WindowsErrorString(0)); | ||||||
|  | 		return FALSE; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	dev_info_data.cbSize = sizeof(dev_info_data); | ||||||
|  | 	for (i=0; SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data); i++) { | ||||||
|  | 		memset(buffer, 0, sizeof(buffer)); | ||||||
|  | 		if (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_ENUMERATOR_NAME, | ||||||
|  | 				&datatype, (LPBYTE)buffer, sizeof(buffer), &size)) { | ||||||
|  | 			uprintf("SetupDiGetDeviceRegistryProperty (Enumerator Name) failed: %d\n", WindowsErrorString(0)); | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (safe_strcmp(buffer, "USBSTOR") != 0) | ||||||
|  | 			continue; | ||||||
|  | 		memset(buffer, 0, sizeof(buffer)); | ||||||
|  | 		if (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_FRIENDLYNAME, | ||||||
|  | 				&datatype, (LPBYTE)buffer, sizeof(buffer), &size)) { | ||||||
|  | 			uprintf("SetupDiGetDeviceRegistryProperty (Friendly Name) failed: %d\n", WindowsErrorString(0)); | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  | 		uprintf("found drive '%s'\n", buffer); | ||||||
|  | 
 | ||||||
|  | 		devint_data.cbSize = sizeof(devint_data); | ||||||
|  | 		devint_detail_data = NULL; | ||||||
|  | 		for (j=0;;j++) { | ||||||
|  | 			if (!SetupDiEnumDeviceInterfaces(dev_info, &dev_info_data, &GUID_DEVINTERFACE_DISK, j, &devint_data)) { | ||||||
|  | 				if(GetLastError() != ERROR_NO_MORE_ITEMS) { | ||||||
|  | 					uprintf("SetupDiEnumDeviceInterfaces failed: %s\n", WindowsErrorString(0)); | ||||||
|  | 				} | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (!SetupDiGetDeviceInterfaceDetailA(dev_info, &devint_data, NULL, 0, &size, NULL)) { | ||||||
|  | 				if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) { | ||||||
|  | 					devint_detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA_A)calloc(1, size); | ||||||
|  | 					if (devint_detail_data == NULL) { | ||||||
|  | 						uprintf("unable to allocate data for SP_DEVICE_INTERFACE_DETAIL_DATA\n"); | ||||||
|  | 						return FALSE; | ||||||
|  | 					} | ||||||
|  | 					devint_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); | ||||||
|  | 				} else { | ||||||
|  | 					uprintf("SetupDiGetDeviceInterfaceDetail (dummy) failed: %s\n", WindowsErrorString(0)); | ||||||
|  | 					continue; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			if(!SetupDiGetDeviceInterfaceDetailA(dev_info, &devint_data, devint_detail_data, size, &size, NULL)) { | ||||||
|  | 				uprintf("SetupDiGetDeviceInterfaceDetail (actual) failed: %s\n", WindowsErrorString(0)); | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			hDrive = CreateFileA(devint_detail_data->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); | ||||||
|  | 			if(hDrive == INVALID_HANDLE_VALUE) { | ||||||
|  | 				uprintf("could not open '%s': %s\n", devint_detail_data->DevicePath, WindowsErrorString(0));  | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			safe_free(devint_detail_data); | ||||||
|  | 
 | ||||||
|  | 			memset(&storage_device, 0, sizeof(storage_device)); | ||||||
|  | 			r = DeviceIoControl(hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER,  | ||||||
|  | 						NULL, 0, &storage_device, sizeof(storage_device), &size, NULL ); | ||||||
|  | 			if (!r || size <= 0) { | ||||||
|  | 				uprintf("IOCTL_STORAGE_GET_DEVICE_NUMBER failed: %s\n", WindowsErrorString(0)); | ||||||
|  | 				CloseHandle(hDrive); | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			CloseHandle(hDrive); | ||||||
|  | 
 | ||||||
|  | 			drive_letter = GetDriveInfo(storage_device.DeviceNumber, &label); | ||||||
|  | 			if (drive_letter) { | ||||||
|  | 				safe_sprintf(entry, sizeof(entry), "%s (%c:)\n", label, drive_letter); | ||||||
|  | 				IGNORE_RETVAL(ComboBox_AddStringU(hDeviceList, entry)); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	IGNORE_RETVAL(ComboBox_SetCurSel(hDeviceList, 0)); | ||||||
|  | 	return TRUE; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
| * Main dialog callback | * Main dialog callback | ||||||
|  | @ -40,9 +254,12 @@ static INT_PTR CALLBACK main_callback(HWND hDlg, UINT message, WPARAM wParam, LP | ||||||
| 	switch (message) { | 	switch (message) { | ||||||
| 
 | 
 | ||||||
| 	case WM_DEVICECHANGE: | 	case WM_DEVICECHANGE: | ||||||
|  | 		GetUSBDevices(); | ||||||
| 		return (INT_PTR)TRUE; | 		return (INT_PTR)TRUE; | ||||||
| 
 | 
 | ||||||
| 	case WM_INITDIALOG: | 	case WM_INITDIALOG: | ||||||
|  | 		hDeviceList = GetDlgItem(hDlg, IDC_DEVICE); | ||||||
|  | 		GetUSBDevices(); | ||||||
| 		return (INT_PTR)TRUE; | 		return (INT_PTR)TRUE; | ||||||
| 
 | 
 | ||||||
| 	case WM_COMMAND: | 	case WM_COMMAND: | ||||||
|  | @ -111,6 +328,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine | ||||||
| 	HWND hDlg = NULL; | 	HWND hDlg = NULL; | ||||||
| 	MSG msg; | 	MSG msg; | ||||||
| 
 | 
 | ||||||
|  | 	uprintf("*** USBDOS INIT ***\n"); | ||||||
|  | 
 | ||||||
| 	// Prevent 2 applications from running at the same time
 | 	// Prevent 2 applications from running at the same time
 | ||||||
| 	mutex = CreateMutexA(NULL, TRUE, "Global/USBDOS"); | 	mutex = CreateMutexA(NULL, TRUE, "Global/USBDOS"); | ||||||
| 	if ((mutex == NULL) || (GetLastError() == ERROR_ALREADY_EXISTS)) | 	if ((mutex == NULL) || (GetLastError() == ERROR_ALREADY_EXISTS)) | ||||||
|  | @ -144,6 +363,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine | ||||||
| 
 | 
 | ||||||
| out: | out: | ||||||
| 	CloseHandle(mutex); | 	CloseHandle(mutex); | ||||||
|  | 	uprintf("*** USBDOS EXIT ***\n"); | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										24
									
								
								usbdos.h
									
										
									
									
									
								
							
							
						
						
									
										24
									
								
								usbdos.h
									
										
									
									
									
								
							|  | @ -18,17 +18,10 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #if !defined(bool) | #define USBDOS_DEBUG | ||||||
| #define bool BOOL |  | ||||||
| #endif |  | ||||||
| #if !defined(true) |  | ||||||
| #define true TRUE |  | ||||||
| #endif |  | ||||||
| #if !defined(false) |  | ||||||
| #define false FALSE |  | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| #define APP_VERSION                 "USBDOS v0.1.0.1" | #define APP_VERSION                 "USBDOS v0.1.0.1" | ||||||
|  | #define IGNORE_RETVAL(expr)         do { (void)(expr); } while(0) | ||||||
| 
 | 
 | ||||||
| #define safe_free(p) do {free((void*)p); p = NULL;} while(0) | #define safe_free(p) do {free((void*)p); p = NULL;} while(0) | ||||||
| #define safe_min(a, b) min((size_t)(a), (size_t)(b)) | #define safe_min(a, b) min((size_t)(a), (size_t)(b)) | ||||||
|  | @ -44,3 +37,16 @@ | ||||||
| #define safe_sprintf _snprintf | #define safe_sprintf _snprintf | ||||||
| #define safe_strlen(str) ((((char*)str)==NULL)?0:strlen(str)) | #define safe_strlen(str) ((((char*)str)==NULL)?0:strlen(str)) | ||||||
| #define safe_strdup _strdup | #define safe_strdup _strdup | ||||||
|  | 
 | ||||||
|  | #if defined(_MSC_VER) | ||||||
|  | #define safe_vsnprintf(buf, size, format, arg) _vsnprintf_s(buf, size, _TRUNCATE, format, arg) | ||||||
|  | #else | ||||||
|  | #define safe_vsnprintf vsnprintf | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | typedef struct _SCSI_PASS_THROUGH_WITH_BUFFERS { | ||||||
|  | 	SCSI_PASS_THROUGH Spt; | ||||||
|  | 	ULONG             Filler; | ||||||
|  | 	UCHAR             SenseBuf[32]; | ||||||
|  | 	UCHAR             DataBuf[512]; | ||||||
|  | } SCSI_PASS_THROUGH_WITH_BUFFERS, *PSCSI_PASS_THROUGH_WITH_BUFFERS; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue