博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Windows下USB磁盘开发系列三:枚举系统中U盘、并获取其设备信息
阅读量:5219 次
发布时间:2019-06-14

本文共 4851 字,大约阅读时间需要 16 分钟。

前面我们介绍了枚举系统中的U盘盘符(见)、以及获取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.\n", 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\n", usb_list[i].volume, usb_list[i].friendname);			}		}	}	getchar();	return 1; }

 4,运行结果如下:

转载于:https://www.cnblogs.com/james1207/p/3423990.html

你可能感兴趣的文章
Java 内部类
查看>>
PHP程序员的技术成长规划
查看>>
测试一个对象是否是类字符串
查看>>
{面试题7: 使用两个队列实现一个栈}
查看>>
用JSONP方式跨域请求
查看>>
[Luogu 4135] 作诗
查看>>
[转]SQL中 OVER(PARTITION BY) 取上一条,下一条等
查看>>
前端开发就从认识浏览器开始 - 浏览器处理请求的过程
查看>>
【练习】使用事务和锁定语句
查看>>
centos7升级firefox的flash插件
查看>>
jmeter系列二(jmeter engine相关)
查看>>
前端页面设计问题小计
查看>>
一份超全超详细的 ADB 用法大全
查看>>
Spring定时任务(@Scheduled)
查看>>
WebView 调试
查看>>
IB使用
查看>>
Linux硬链接和软链接(符号链接)
查看>>
git stash
查看>>
Apache Common-IO 使用
查看>>
Java-第一课正则表达式
查看>>