读取U盘物理序列号).txt
根据给定文件的信息,我们可以深入探讨如何在Windows操作系统下通过编程方式读取U盘的物理序列号,这一过程涉及到对Windows设备驱动模型的理解以及对特定API的调用。以下是对标题、描述、标签以及部分内容中提及的知识点的详细解读。 ### 读取U盘物理序列号 #### 概念理解 物理序列号是存储设备固有的标识符,用于区分不同的硬件实体。对于U盘而言,其物理序列号是制造商在生产过程中赋予的唯一编号,可以用于设备识别、安全管理等场景。 #### 编程实现 1. **头文件与库的引入**:在代码片段中可以看到,作者导入了多个头文件,如`windows.h`、`winioctl.h`、`stdio.h`、`initguid.h`、`setupapi.h`、`string.h`,这些头文件包含了操作Windows系统资源、设备控制、输入输出操作、GUID定义、设备枚举和字符串处理所需的各种函数声明和类型定义。 2. **设备枚举与查询**:通过`setupapi.h`中的`SetupDiGetInterfaceDeviceDetail`函数,可以获取指定接口的设备详细信息。这里定义了一个GUID变量`UsbClassGuid`,它是USB设备类的GUID,用于定位USB设备。 3. **设备属性查询**:使用`winioctl.h`中的`IOCTL_STORAGE_QUERY_PROPERTY`控制码,可以向设备发送特定请求以获取其属性信息。这通常包括设备类型、厂商信息、产品信息以及序列号等。 4. **数据结构定义**:为了接收和处理设备属性查询的响应,定义了`STORAGE_PROPERTY_QUERY`和`STORAGE_DEVICE_DESCRIPTOR`等结构体。其中,`STORAGE_DEVICE_DESCRIPTOR`包含设备的详细信息,如版本、大小、设备类型、是否支持命令队列等,以及重要的序列号偏移量。 5. **函数实现**:`GetDevicePath`函数的目标是根据提供的GUID获取设备路径。这一步骤是整个流程的基础,因为在获取设备的详细信息前,必须首先确定设备的实例路径。 #### 实现步骤 1. 初始化:确保所有必要的库和头文件被正确导入。 2. 枚举设备:使用`SetupDiGetClassDevs`或`SetupDiGetInterfaceDeviceDetail`等函数枚举系统中的USB设备。 3. 获取设备路径:通过枚举获得的设备信息,使用`GetDevicePath`函数得到具体设备的路径。 4. 发送查询:利用`DeviceIoControl`函数,结合`IOCTL_STORAGE_QUERY_PROPERTY`控制码,向设备发送查询请求,获取其属性。 5. 解析响应:从设备接收到的数据中解析出序列号信息。 6. 存储与比较:将获取到的序列号存储于预设位置,如`C:\Windows\system32\USBSerial.dat`,并进行后续的比较或使用。 ### 总结 读取U盘物理序列号的过程不仅涉及底层设备驱动的交互,还考验了对Windows设备枚举机制的掌握。通过上述步骤,开发者能够实现对USB设备的精确识别,这对于开发安全认证、设备管理等应用具有重要意义。然而,值得注意的是,此类操作可能受到操作系统权限限制的影响,因此在实际开发中应确保有足够的权限进行设备访问。
//
#include "stdafx.h"
/*************************************************************
Win32控制台应用程序
编译环境:Visual Studio 2005
主要功能:
1). 读取U盘序列号,保存在USBSerial数组里。
2). 验证
第一次运行程序读取U盘序列号存放在
C:\Windows\system32\USBSerial.dat文件中
以后运行检验读取到的U盘序列号与保存在文件中的是否一致,
若相同,置 gTag 为1; 若不一致,置 gTag 为0;
***********************************************************/
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
#include <initguid.h>
#include <setupapi.h>
#include <string.h>
#pragma comment(lib,"setupapi.lib")
wchar_t USBSerial[5][100] = {TEXT("")};
int gTag = 0;
//#define USBSERIAL_PATH C:\\Windows\\system32\\USBSerial.dat
DEFINE_GUID(UsbClassGuid, 0xa5dcbf10L, 0x6530, 0x11d2, 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed);
// SetupDiGetInterfaceDeviceDetail所需要的输出长度,定义足够大
#define INTERFACE_DETAIL_SIZE (1024)
// IOCTL控制码
#define IOCTL_STORAGE_QUERY_PROPERTY CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS)
// 查询存储设备属性的类型
/*typedef enum _STORAGE_QUERY_TYPE {
PropertyStandardQuery = 0, // 读取描述
PropertyExistsQuery, // 测试是否支持
PropertyMaskQuery, // 读取指定的描述
PropertyQueryMaxDefined // 验证数据
} STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE;
*/
// 查询存储设备还是适配器属性
//typedef enum _STORAGE_PROPERTY_ID {
// StorageDeviceProperty = 0, // 查询设备属性
// StorageAdapterProperty // 查询适配器属性
//} STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID;
//
// 查询属性输入的数据结构
//typedef struct _STORAGE_PROPERTY_QUERY {
// STORAGE_PROPERTY_ID PropertyId; // 设备/适配器
剩余11页未读,继续阅读
- qq4572995962012-12-06编译不成功了。。。
- goodluck10202014-04-02只能获取本地硬盘的,不能获取移动硬盘的
- 粉丝: 4
- 资源: 44
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助