一、注册表中与U盘相关的键
1. \\HKEY_LOCAL_MACHINESYSTEM\\CurrentControlSet\\Services\\USBSTOR\\Enum ,该键中有本机连接的所有U盘的设备路径,Count为U盘的数量,数字键对应的值为U盘的设备路径,形如:USB\VID_1E3D&PID_2096\CCBBEE012B;
2. \\HKEY_LOCAL_MACHINESYSTEM\\CurrentControlSet\\Services\\disk\\Enum,该键中存储有物理磁盘设备的路径;count为磁盘数量,数字键对应的值为设备路径,形如:USBSTOR\Disk&Ven_2.0&Prod_Flash_Disk&Rev_2.61\CCBBEE012B&1;
3. \\HKEY_LOCAL_MACHINESYSTEM\\CurrentControlSet\\Services\\cdrom\\Enum,该键中存储有光驱的设备路径,Count为数量,数字键名对应的键值为设备路径,形如:USBSTOR\CdRom&Ven_2.0&Prod_Flash_Disk&Rev_2.60\CCBBEE012B&0;
4. \\HKEY_LOCAL_MACHINESYSTEM\\MountedDevices,该键中有\DosDevices\X:的键名,X为盘符,其值为对应设备的路径,如:“\DosDevices\E:”的键值为:\??\USBSTOR#CdRom&Ven_2.0&Prod_Flash_Disk&Rev_2.60#CCBBEE012B&0#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b},“\DosDevices\F:”的键值为:_??_USBSTOR#Disk&Ven_2.0&Prod_Flash_Disk&Rev_2.61#CCBBEE012B&1#{53f56307-b6bf-11d0-94f2-00a0c91efb8b};
二、检测U盘的流程
1. 查询上述1-3所有的键值,存储在三个vector<string>中,然后逐个遍历通过关键字找出各自的对应关系,把对应的值存入USBNod中,USBNode定义如下:
struct UsbNod //检索本机U盘节点,通过检索注册表获取 { LPCTSTR usb; //U盘的对应USB设备 LPCTSTR cdrom; //U盘对应的光驱设备路径 string cdvol; //U盘对应的光驱盘符 LPCTSTR disk; //U盘对应的大容量磁盘设备路径 string diskvol; //U盘对应的盘符 };
讯享网
遍历对应关系的代码如下:
讯享网//构造系统USB设备的节点数组 char* USBSTOR_key = "SYSTEM\\CurrentControlSet\\Services\\USBSTOR\\Enum"; vector<string> USBSTOR_vals; getRegEnumValues(USBSTOR_key , USBSTOR_vals); char* USBDISK_key = "SYSTEM\\CurrentControlSet\\Services\\disk\\Enum"; vector<string> USBDISK_vals; getRegEnumValues(USBDISK_key , USBDISK_vals); char* USBCDROM_key = "SYSTEM\\CurrentControlSet\\Services\\cdrom\\Enum"; vector<string> USBCDROM_vals; getRegEnumValues(USBCDROM_key , USBCDROM_vals); UsbNod usbdisknod[26]; int count = 0; for (unsigned int i = 0; i < USBCDROM_vals.size(); i++) { int pos = USBCDROM_vals.at(i).rfind('\\') + 1; string serialnum = USBCDROM_vals.at(i).substr(pos, USBCDROM_vals.at(i).size()); serialnum = serialnum.substr(0,serialnum.size() - 2); for (unsigned int j = 0; j < USBSTOR_vals.size(); j++) { if (USBSTOR_vals.at(j).find(serialnum) == -1) continue; for (unsigned int k = 0; k < USBDISK_vals.size(); k++) { if (USBDISK_vals.at(k).find(serialnum) == -1) continue; usbdisknod[count].cdrom = USBCDROM_vals.at(i).data(); usbdisknod[count].disk = USBDISK_vals.at(k).data(); usbdisknod[count].usb = USBSTOR_vals.at(j).data(); usbdisknod[count].diskvol = getVolFromDevicePath(USBDISK_vals.at(k)); usbdisknod[count].cdvol = getVolFromDevicePath(USBCDROM_vals.at(i)); count++; } } }
读取注册表键值构造vector的函数
//检索Emnu类型的USB设备相关的注册表键值,返回获取到的数量,循环读取内容内容保存在 vector<string> &values int getRegEnumValues(LPCTSTR key, vector<string> &values) { values.clear(); CRegKey usbreg; long rt = usbreg.Open(HKEY_LOCAL_MACHINE, key, KEY_READ | KEY_ALL_ACCESS); if (rt != ERROR_SUCCESS) return 0; DWORD count = 0; usbreg.QueryDWORDValue("Count", count); if (count == 0) return 0; DWORD i, j = 0; for (i = 0; i<count; i++) { char vname[2]; sprintf_s(vname, "%d", i); DWORD len = 256; char kValue[256]; if (usbreg.QueryStringValue(vname, kValue, &len) == ERROR_SUCCESS) { string v(kValue); if (v.find("USB") != -1) { values.push_back(kValue); //printf("%s\n",kValue); j++; } } } usbreg.Close(); return j; }
2. 获取U盘对应光盘与磁盘盘符的方法
讯享网//根据设备路径获取其对应的盘符 string getVolFromDevicePath(string pDPath) { string::iterator it = pDPath.begin(); for (; it != pDPath.end(); it++) if (*it == '\\') *it = '#'; int DeviceNum = 1001; if (pDPath.find("Disk") != -1) //如果设备路径中有disk字符,则构造如下路径 { char ph_Path[MAX_PATH]; sprintf_s(ph_Path, "\\\\?\\%s#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}", pDPath.data()); DeviceNum = GetPhysicalDriveFromDevicePath(ph_Path); //获取磁盘设备地址对应的物理磁盘号 } string vol; //得到U盘盘符; LPTSTR lpDrives = new TCHAR[MAX_PATH]; DWORD dwLen = ::GetLogicalDriveStrings(MAX_PATH, lpDrives); char* sDrives[26] = { "" }; for (DWORD nIndex = 0; nIndex < dwLen / 4; nIndex++) { UINT dType = ::GetDriveType(lpDrives + nIndex * 4); if (dType == DRIVE_REMOVABLE || dType == DRIVE_CDROM) { sDrives[nIndex] = (lpDrives + nIndex * 4); if (sDrives[nIndex] != "A:\\" && sDrives[nIndex] != "B:\\") { //获取盘符对应的MountedDevices中对应的键值 string volkey = getVolKey(sDrives[nIndex][0]); int pnum = 1002; //该判断增加对XP系统的支持,在XP中U盘盘符对应的MountedDevices //的键值与以上2中值不同需要通过获取其物理磁盘号进行比较 if (dType == DRIVE_REMOVABLE) pnum = GetPhysicalDriveFromPartitionLetter(sDrives[nIndex][0]); if (pnum == DeviceNum || volkey.find(pDPath) != -1) { vol = string(sDrives[nIndex]); } } } } delete lpDrives; return vol; }
以上注册表键值由windows系统服务维持,经使用还是比较可靠的,未尽问题是对于U盘仅检测有一个U盘盘符的情况,多个U盘盘符未做处理,不过根据源码应该很容易写出。
通过CSDN学习了很多,今天终于自己写了一点东西,不对之处欢迎拍砖。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/74966.html