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> | ||||
|     </ClCompile> | ||||
|     <Link> | ||||
|       <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies> | ||||
|       <AdditionalDependencies>setupapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies> | ||||
|       <UACExecutionLevel>HighestAvailable</UACExecutionLevel> | ||||
|       <GenerateDebugInformation>true</GenerateDebugInformation> | ||||
|       <SubSystem>Windows</SubSystem> | ||||
|  | @ -98,7 +98,7 @@ | |||
|       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> | ||||
|     </ClCompile> | ||||
|     <Link> | ||||
|       <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies> | ||||
|       <AdditionalDependencies>setupapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies> | ||||
|       <UACExecutionLevel>HighestAvailable</UACExecutionLevel> | ||||
|       <GenerateDebugInformation>true</GenerateDebugInformation> | ||||
|       <SubSystem>Windows</SubSystem> | ||||
|  | @ -113,7 +113,7 @@ | |||
|       <WarningLevel>Level3</WarningLevel> | ||||
|     </ClCompile> | ||||
|     <Link> | ||||
|       <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies> | ||||
|       <AdditionalDependencies>setupapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies> | ||||
|       <UACExecutionLevel>HighestAvailable</UACExecutionLevel> | ||||
|       <GenerateDebugInformation>false</GenerateDebugInformation> | ||||
|       <SubSystem>Windows</SubSystem> | ||||
|  | @ -131,7 +131,7 @@ | |||
|       <WarningLevel>Level3</WarningLevel> | ||||
|     </ClCompile> | ||||
|     <Link> | ||||
|       <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies> | ||||
|       <AdditionalDependencies>setupapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies> | ||||
|       <UACExecutionLevel>HighestAvailable</UACExecutionLevel> | ||||
|       <GenerateDebugInformation>false</GenerateDebugInformation> | ||||
|       <SubSystem>Windows</SubSystem> | ||||
|  |  | |||
							
								
								
									
										224
									
								
								usbdos.c
									
										
									
									
									
								
							
							
						
						
									
										224
									
								
								usbdos.c
									
										
									
									
									
								
							|  | @ -22,6 +22,8 @@ | |||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <commctrl.h> | ||||
| #include <setupapi.h> | ||||
| #include <ntddscsi.h> | ||||
| 
 | ||||
| #include "msapi_utf8.h" | ||||
| #include "resource.h" | ||||
|  | @ -30,19 +32,234 @@ | |||
| /*
 | ||||
|  * 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 | ||||
| 
 | ||||
| /*
 | ||||
|  * Main dialog callback | ||||
|  * 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 | ||||
| */ | ||||
| static INT_PTR CALLBACK main_callback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) | ||||
| { | ||||
| 	switch (message) { | ||||
| 
 | ||||
| 	case WM_DEVICECHANGE: | ||||
| 		GetUSBDevices(); | ||||
| 		return (INT_PTR)TRUE; | ||||
| 
 | ||||
| 	case WM_INITDIALOG: | ||||
| 		hDeviceList = GetDlgItem(hDlg, IDC_DEVICE); | ||||
| 		GetUSBDevices(); | ||||
| 		return (INT_PTR)TRUE; | ||||
| 
 | ||||
| 	case WM_COMMAND: | ||||
|  | @ -111,6 +328,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine | |||
| 	HWND hDlg = NULL; | ||||
| 	MSG msg; | ||||
| 
 | ||||
| 	uprintf("*** USBDOS INIT ***\n"); | ||||
| 
 | ||||
| 	// Prevent 2 applications from running at the same time
 | ||||
| 	mutex = CreateMutexA(NULL, TRUE, "Global/USBDOS"); | ||||
| 	if ((mutex == NULL) || (GetLastError() == ERROR_ALREADY_EXISTS)) | ||||
|  | @ -144,6 +363,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine | |||
| 
 | ||||
| out: | ||||
| 	CloseHandle(mutex); | ||||
| 	uprintf("*** USBDOS EXIT ***\n"); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
|  |  | |||
							
								
								
									
										24
									
								
								usbdos.h
									
										
									
									
									
								
							
							
						
						
									
										24
									
								
								usbdos.h
									
										
									
									
									
								
							|  | @ -18,17 +18,10 @@ | |||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #if !defined(bool) | ||||
| #define bool BOOL | ||||
| #endif | ||||
| #if !defined(true) | ||||
| #define true TRUE | ||||
| #endif | ||||
| #if !defined(false) | ||||
| #define false FALSE | ||||
| #endif | ||||
| #define USBDOS_DEBUG | ||||
| 
 | ||||
| #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_min(a, b) min((size_t)(a), (size_t)(b)) | ||||
|  | @ -44,3 +37,16 @@ | |||
| #define safe_sprintf _snprintf | ||||
| #define safe_strlen(str) ((((char*)str)==NULL)?0:strlen(str)) | ||||
| #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