zoukankan      html  css  js  c++  java
  • Windows下USB磁盘开发系列三:枚举系统中U盘、并获取其设备信息

    前面我们介绍了枚举系统中的U盘盘符(见Windows下USB磁盘开发系列一:枚举系统中U盘的盘符)、以及获取USB设备的信息(见Windows下USB磁盘开发系列二:枚举系统中所有USB设备)。有个时候我们不仅仅需要获取U盘盘符(路径),而且需要获取该U盘的硬件信息,比如厂商、friendly name、描述等等。那么我们可以通过前面两个方法,把U盘盘符和设备信息匹配起来吗?答案是肯定的,下面介绍具体的实现方法。

     具体方法如下:

    1,获取U盘盘符(路径);

    2,对U盘路径调用CreateFile()获取U盘句柄;

    3,对U盘句柄调用DeviceIoControl()获取其Device Number;

    4,调用SetupDiGetClassDevs()/SetupDiEnumDeviceInfo()枚举系统中所有U盘设备;

    5,调用SetupDiEnumDeviceInterfaces()/SetupDiGetDeviceInterfaceDetail()获取设备路径; 

    6,对U盘设备路径调用CreateFile()获取U盘设备句柄; 

    7,对U盘设备句柄调用DeviceIoControl()获取其Device Number;

    8,判断3和7获得的Device Number,两者一致则表示该U盘盘符和设备为同一设备。 

    具体实现代码如下:

    1,获取U盘设备列表

    int get_usb_device_list(usb_device_info *usb_list, int list_size)
    {
    	int usb_device_cnt = 0;
    
        char disk_path[5] = {0}; 
        char device_path[10] = {0};        
    	DWORD all_disk = GetLogicalDrives();
    		
    	int i = 0;
    	DWORD bytes_returned = 0;
    	STORAGE_DEVICE_NUMBER device_num;
    	while (all_disk && usb_device_cnt < list_size)
    	{
    		if ((all_disk & 0x1) == 1)             
    		{       
    			sprintf_s(disk_path, "%c:", 'A'+i);
    			sprintf_s(device_path, "\\.\%s", disk_path);
    			if (GetDriveTypeA(disk_path) == DRIVE_REMOVABLE)                 
    			{       
    				// get this usb device id
    				HANDLE hDevice = CreateFileA(device_path, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    				if (DeviceIoControl(hDevice, IOCTL_STORAGE_GET_DEVICE_NUMBER, 
    								    NULL, 0, 
    									&device_num, sizeof(device_num), 
    									&bytes_returned, (LPOVERLAPPED) NULL))
    				{
    					usb_list[usb_device_cnt].volume = 'A' + i;
    					usb_list[usb_device_cnt].device_num = device_num.DeviceNumber;
    					usb_device_cnt++;
    				}
    				CloseHandle(hDevice);
    				hDevice = 0;
    			}			
    		}
    		all_disk = all_disk >> 1;
    		i++;
    	}
    	
    	return usb_device_cnt;
    }
    

    2,匹配U盘设备信息

    int get_usb_device_friendname(usb_device_info *usb_list, int list_size)
    {	
    	int i = 0;
    	int res = 0;
    	HDEVINFO hDevInfo;  
    	SP_DEVINFO_DATA DeviceInfoData = {sizeof(DeviceInfoData)};   
    
    	// get device class information handle
    	hDevInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_DISK,0, 0, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);       
    	if (hDevInfo == INVALID_HANDLE_VALUE)     
    	{         
    		res = GetLastError();     
    		return res;
    	}  
    
    	// enumerute device information
    	DWORD required_size = 0;
    	for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i++)
    	{		
    		DWORD DataT;         
    		char friendly_name[2046] = {0};         
    		DWORD buffersize = 2046;        
    		DWORD req_bufsize = 2046;      
    
    		// get device friendly name
    		if (!SetupDiGetDeviceRegistryPropertyA(hDevInfo, &DeviceInfoData, SPDRP_FRIENDLYNAME, &DataT, (LPBYTE)friendly_name, buffersize, &req_bufsize))
    		{
    			continue;
    		}
    		if (strstr(friendly_name, "USB") == 0)
    		{
    			continue;
    		}
    
    		int index = 0;
    		SP_DEVICE_INTERFACE_DATA did = {sizeof(did)};
    		PSP_DEVICE_INTERFACE_DETAIL_DATA pdd = NULL;
    
    		while(1)
    		{
    			// get device interface data
    			if (!SetupDiEnumDeviceInterfaces(hDevInfo, &DeviceInfoData, &GUID_DEVINTERFACE_DISK, index++, &did))
    			{
    				res = GetLastError();
    				if( ERROR_NO_MORE_DEVICES == res || ERROR_NO_MORE_ITEMS == res)
    					break;
    			}
    
    			// get device interface detail size
    			if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &did, NULL, 0, &required_size, NULL))
    			{
    				res = GetLastError();
    				if(ERROR_INSUFFICIENT_BUFFER == res)
    				{
    					pdd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, required_size);
    					pdd->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
    				}
    				else
    					break;
    			}
    
    			// get device interface detail
    			if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &did, pdd, required_size, NULL, NULL))
    			{
    				res = GetLastError();
    				LocalFree(pdd);
    				pdd = NULL;
    				break;
    			}
    			
    			// get device number
    			DWORD bytes_returned = 0;
    			STORAGE_DEVICE_NUMBER device_num;
    			HANDLE hDevice = CreateFile(pdd->DevicePath, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    			if (DeviceIoControl(hDevice, IOCTL_STORAGE_GET_DEVICE_NUMBER, 
    								NULL, 0, 
    								&device_num, sizeof(device_num), 
    								&bytes_returned, (LPOVERLAPPED) NULL))
    			{
    				for (int usb_index = 0; usb_index < list_size; usb_index++)
    				{
    					if (device_num.DeviceNumber == usb_list[usb_index].device_num)
    					{
    						strcpy_s(usb_list[usb_index].friendname, friendly_name);
    						break;			
    					}
    				}
    			}
    			CloseHandle(hDevice);
    			LocalFree(pdd);
    			pdd = NULL;
    		}
    	}
    	
    	SetupDiDestroyDeviceInfoList(hDevInfo);
    	return res;
    }

    3,调用代码:

    typedef struct usb_device_info_t
    {
    	char	volume;
    	char	friendname[256];
    	int		device_num;
    }usb_device_info;
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	bool bRes = false;
     
    	usb_device_info usb_list[8];
    	memset(usb_list, 0, 8*sizeof(usb_device_info));
    	int usb_cnt = get_usb_device_list(usb_list, 8);
    	printf("System has %d USB disk.
    ", usb_cnt);
    
    	if (usb_cnt > 0)
    	{
    		get_usb_device_friendname(usb_list, usb_cnt);
    		{
    			for (int i = 0; i < usb_cnt; i++)
    			{
    				printf("%c: %s
    ", usb_list[i].volume, usb_list[i].friendname);
    			}
    		}
    	}
    
    	getchar();
    	return 1; 
    }

     4,运行结果如下:

  • 相关阅读:
    IM设计思考:XMPP多用户文本聊天协议(MUC:Multi User Chat)
    软件设计中的“三视图”
    [C++] 应该如何应对OOM?
    Android 上Camera分析
    android的语言切换应用程序 根据 不同的语言 加载不同的 res
    布局
    布局
    如何解决"Launching New_configuration"问题
    android的语言切换应用程序 根据 不同的语言 加载不同的 res
    如何解决"Launching New_configuration"问题
  • 原文地址:https://www.cnblogs.com/james1207/p/3423990.html
Copyright © 2011-2022 走看看