一、注册表中与U盘相关的键

1. \\HKEY_LOCAL_MACHINESYSTEM\\CurrentControlSet\\Services\\USBSTOR\\Enum ,该键中有本机连接的所有U盘的设备路径,Count为U盘的数量,数字键对应的值为U盘的设备路径,形如:USB\VID_1E3D&PID_2096\CCBB123456EE012B;

2. \\HKEY_LOCAL_MACHINESYSTEM\\CurrentControlSet\\Services\\disk\\Enum,该键中存储有物理磁盘设备的路径;count为磁盘数量,数字键对应的值为设备路径,形如:USBSTOR\Disk&Ven_2.0&Prod_Flash_Disk&Rev_2.61\CCBB123456EE012B&1;

3. \\HKEY_LOCAL_MACHINESYSTEM\\CurrentControlSet\\Services\\cdrom\\Enum,该键中存储有光驱的设备路径,Count为数量,数字键名对应的键值为设备路径,形如:USBSTOR\CdRom&Ven_2.0&Prod_Flash_Disk&Rev_2.60\CCBB123456EE012B&0;

4. \\HKEY_LOCAL_MACHINESYSTEM\\MountedDevices,该键中有\DosDevices\X:的键名,X为盘符,其值为对应设备的路径,如:“\DosDevices\E:”的键值为:\??\USBSTOR#CdRom&Ven_2.0&Prod_Flash_Disk&Rev_2.60#CCBB123456EE012B&0#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b},“\DosDevices\F:”的键值为:_??_USBSTOR#Disk&Ven_2.0&Prod_Flash_Disk&Rev_2.61#CCBB123456EE012B&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学习了很多,今天终于自己写了一点东西,不对之处欢迎拍砖。

Windows系统U盘的检测相关推荐

  1. mac 环境下 制作windows系统U盘启动盘

    mac 环境下 制作windows系统U盘启动盘 下载系统文件   ylmf.iso 转换为img文件 hdiutil convert /Users/os/Downloads/ylmf.iso -fo ...

  2. windows系统C盘空间满了?两步让你多出来10个多G!

    windows系统 C盘很容易就满了,两步就能多出10个多G! 1.关闭电脑的休眠功能 操作步骤如下: (1)按win+r,输入cmd,点击确定:   (2)提示符后输入:powercfg -h of ...

  3. linux自动挂载win共享,在Deepin系统下实现开机自动挂载Windows系统共享盘的方法

    所要实现的目标:开机自动挂载Windows系统共享盘,所采用的操作系统:Deepin Linux.关于开机挂载网盘并不好,如果没有网络会卡住的问题,经过测试,下面介绍的方法及时是断网了也没有卡住. 前 ...

  4. windows系统下注册和检测 ocx,dll控件的问题.........

    in fact ...ocx控件注册和检测其实是对注册表中的相应的项注册和检测,当然注册表那些操作函数就不能不用到: 注册ocx控件无非两句话的功夫, 1.在系统目录下即:C:/windows/sys ...

  5. windows系统C盘越来越大怎么办(包括win10)

    欢迎访问我的网站:omegaxyz.com 对于Mac电脑来说,不必太过担心垃圾清理.至于Windows用户电脑垃圾会越来越多.使用360和CCleaner已经满足不了用户的需求了.另外Win10在更 ...

  6. 关于Windows系统C盘扩容遇到的问题

    我的电脑当时买的是128g的固态,没想到竟然够我用,但是当时分盘时分的不合理,导致最近电脑C盘快要挤爆了,但是D盘却还有20+G的空余空间.所以就想从D盘匀出10G给C盘,这样C.D盘都能够满足我的需 ...

  7. 为什么Windows系统磁盘盘已使用空间大小与磁盘中总文件大小不符?

    开头语 这个硬盘空间的使用牵扯的概念比较多,如果你比较懂linux的话也许能明白我接下来说的,当然我也会尽可能通俗易懂的讲解,其实windows也是建立在linux内核上的. 正文 windows电脑 ...

  8. windows系统如何使用命令检测网络

    按下[Win+R]组合键打开"运行",输入"CMD"打开系统命令窗口 ping 127.0.0.1 这个命令可以检测本地网络协议是否正常,有返回值表示网络正常 ...

  9. windows系统C盘“已用空间”不断增大

    这几天遇到个问题,C盘目录不断增大,设置的100个G,按理来说应该足够了,但是这几天突然发现竟然用了90个G,本人软件都是装在C盘的,只有极特殊的软件才会装在C盘,排查了好久,终于找到问题所在.原因就 ...

最新文章

  1. win7电脑恢复系统设置或计算机点不了,Win7系统电脑开机就提示需要启动修复的解决方法...
  2. 【Android NDK 开发】JNI 方法解析 ( 字符串数组参数传递 | 字符串遍历 | 类型强转 | Java 字符串与 C 字符串转换 | 字符串释放 )
  3. ITK:相同类型的多个输入
  4. java 获取http地址_java如何获取当前时间,java如何获取ip地址
  5. 第二代支付系统专题之报文篇(二)大额支付报文完整版(含二代新增功能业务说明)...
  6. 2017-2018-1 20155202 《信息安全系统设计基础》第4周学习总结
  7. 安装APK时INSTALL_FAILED_ALREADY_EXISTS的解决办法
  8. ArcGIS学习(一)——如何绘制一幅流域图
  9. 锐捷长ping_锐捷交换机命令
  10. python编程练习:爬虫爬取全国大江大河实时水情
  11. IEEEtran模板使用Bibtex插入DOI不显示问题
  12. 水彩绘画艺术效果PS动作
  13. linux scl,scl命令
  14. 《功夫熊猫》的人生启示
  15. 《开源安全运维平台-OSSIM最佳实践》于2016年1月出版
  16. 计算机考研408必考重难点整理(2022考纲大改后,陆续更新中。。)
  17. Lua学习篇③——数据类型
  18. 指南-Luat二次开发教程指南-功能开发教程-socket
  19. win10不识别移动硬盘
  20. 一阶常微分方程的数值解法(二阶显式、隐式 Adams 公式及 Milne 方法)

热门文章

  1. Scrum的基本功 - 集合中英文版本 (角色和责任篇)
  2. TF+K8s轻松上手|TF Carbide评估指南--准备篇
  3. 玩转 python selenium---抓取某知名电商商品页的图片
  4. 牛客java选择题每日打卡Day8
  5. 计算机毕业设计 基于web的网上招标系统的设计与实现-可定制
  6. java如何解析带时区的日期,java – Joda时间解析一个带时区的日期,并保留该时区...
  7. JavaSript及HTML5CANVAS实现钟表动画的讲解
  8. 【Matlab】混合整数规划
  9. Python爬虫怎么挣钱?6个Python爬虫赚钱方式,搞搞副业不是问题
  10. 如何正确的使用Photoshop进行图像的二值化(详细步骤)刘博士