当U盘、移动硬盘和USB读卡器等设备插入计算机USB接口,Windows会对其进行解析和相关数据记录,这也是为什么很多设备第一次插入计算机时需要较长的时间识别、安装驱动后,才会出现盘符,而第二次插入则识别速度快了很多。这些设备的相关信息记录在Windows的注册表中,即使将设备拔出,一些信息仍将遗留在注册表中。
本文方法通过注册表可以的获取当前插入计算机的U盘、移动硬盘和USB读卡器等设备的PID、VID和序列号,这些信息可以用于标识设备和对设备进行下一步动作,如弹出设备需要PID和VID。从原理上讲,USB存储类设备插入当前系统时,会在Windows注册表如下目录中进行登记:KEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\USBSTOR\Enum,在其Count项中记录当前插入设备的个数,对应的0、1、2、...表项的键值就记录这响应设备的信息,这个序号是根据设备插入系统的先后顺序递增记录的,具体如下图:
通过编程代码可以访问该数据项,进行解析即可,一般当前插入的设备应该排在序号的最后一位。具体流程如下,代码测试环境为VS2010,获取Windows相关数据,还是用微软的IDE和接口比较方便一些。
1、 通过消息机制捕获插入USB端口的存储设备的事件,可参考博主之前的一篇文章:
http://blog.csdn.net/trustbo/article/details/50053229 点击打开链接
2、访问注册表获取信息,代码如下:
char lpRegPath[512] = { 0 };
char lpRegValue[256] = { 0 };
sprintf(lpRegPath, "SYSTEM\\CurrentControlSet\\services\\USBSTOR\\Enum");
sprintf(lpRegValue, "Count");
//
DWORD dwDataSize(0);
DWORD dwRegType1(REG_DWORD);
DWORD dwRegType2(REG_SZ);
LPBYTE lpRegDwordData(NULL);
LPBYTE lpRegSzData(NULL);
// 查询注册表中映射驱动器的设备信息
HKEY hKey;
long lRet;
try
{
lRet = ::RegOpenKeyEx(
HKEY_LOCAL_MACHINE, // root key
lpRegPath, // 要访问的键的位置
0, //
KEY_READ, // 以查询的方式访问注册表
&hKey); // hKEY保存此函数所打开的键的句柄
}
catch(...)
{
return false;
}
if(lRet != ERROR_SUCCESS)
return false;
else
{
try
{
lRet = ::RegQueryValueEx(hKey, // 所打开的键的句柄
lpRegValue, // 要查询的键值名
NULL,
&dwRegType1, // 查询数据的类型
lpRegDwordData, // 保存所查询的数据
&dwDataSize); // 预设置的数据长度
}
catch(...)
{
return false;
}
if(lRet != ERROR_SUCCESS)
{
::RegCloseKey(hKey);
return false;
}
else
{
lpRegDwordData = new BYTE[dwDataSize];
try
{
lRet = ::RegQueryValueEx(hKey,
lpRegValue,
NULL,
&dwRegType1,
lpRegDwordData,
&dwDataSize);
}
catch(...)
{
return false;
}
if(lRet != ERROR_SUCCESS)
{
delete []lpRegDwordData;
::RegCloseKey(hKey);
return false;
}
}
}
DWORD num_HDD = DWORD(*lpRegDwordData);
if (num_HDD==0)
{
return false;
}
char lpRegValue_HDD[16] = { 0 };
sprintf(lpRegValue_HDD, "%d", num_HDD-1);
delete []lpRegDwordData;
try
{
lRet = ::RegQueryValueEx(hKey, // 所打开的键的句柄
lpRegValue_HDD, // 要查询的键值名
NULL,
&dwRegType2, // 查询数据的类型
lpRegSzData, // 保存所查询的数据
&dwDataSize); // 预设置的数据长度
}
catch(...)
{
return false;
}
if(lRet != ERROR_SUCCESS)
{
::RegCloseKey(hKey);
return false;
}
else
{
lpRegSzData = new BYTE[dwDataSize];
try
{
lRet = ::RegQueryValueEx(hKey,
lpRegValue_HDD,
NULL,
&dwRegType2,
lpRegSzData,
&dwDataSize);
}
catch(...)
{
return false;
}
if(lRet != ERROR_SUCCESS)
{
delete []lpRegSzData;
::RegCloseKey(hKey);
return false;
}
}
::RegCloseKey(hKey);
memmove(GetUSBInfo->U_VID_PID, lpRegSzData+4, 17);//获取VID_PID
GetUSBInfo->U_VID_PID[17] = '\0';
char SN_temp[32]= {0};
memmove(SN_temp, lpRegSzData+22, 32);
delete []lpRegSzData;
char *needle="&";
char* buf = strstr( SN_temp, needle);
if (buf != NULL)
{
//char *SN_1 = (char *)malloc(buf-SN_temp);
char *temp = SN_temp;
//buf[0]='\0';
//printf( "%s\n ", haystack);
temp = buf + strlen(needle);
/* Get next token: */
buf = strstr( temp, needle);
if (buf != NULL)
{
int SN_strlen = buf - SN_temp;
memmove(GetUSBInfo->U_SN, SN_temp, SN_strlen);
GetUSBInfo->U_SN[SN_strlen] = '\0';
}
else
{
memmove(GetUSBInfo->U_SN, SN_temp, 32);
}
}
else
{
memmove(GetUSBInfo->U_SN, SN_temp, 32);
}