WEB开发网
开发学院软件开发汇编语言 实战DeviceIoControl之五:列举已安装的存储设备 阅读

实战DeviceIoControl之五:列举已安装的存储设备

 2010-01-10 09:37:27 来源:WEB开发网   
核心提示:本例的Project中除了要包含winioctl.h外,还要包含initguid.h,实战DeviceIoControl之五:列举已安装的存储设备(2),setupapi.h,以及连接 setupapi.lib,今天我们讨论一个新的控制码:IOCTL_STORAGE_QUERY_PROPERTY,获取设备属性信息,Q

本例的Project中除了要包含winioctl.h外,还要包含initguid.h,setupapi.h,以及连接 setupapi.lib。

Q 得到设备路径后,就可以到下一步,用CreateFile打开设备,然后用 DeviceIoControl 进行读写了吧?

A 是的。尽管该设备路径与以前我们接触的那些不太一样。本 是“.PhysicalDrive0”,现在鸟枪换炮,

变成了类似这样的一副尊容:

“? ide#diskmaxtor_2f040j0__________________________vam51jj0#31465634475345582020202

0202 0202020202020#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}”。

其实这个设备名在注册表 的某处可以找到,例如在Win2000中这个名字位于 HKEY_LOCAL_MACHINESystemCurrentControlSetServicesDiskEnum,只不过“#”换成了 “”。分析一下这样的设备路径,你会发现很有趣的东西,它们是由接口类型、产品型号、 固件版本、序列号、计算机名、GUID等信息组合而成的。当然,它是没有规范的,不能指望从这里面得 到你希望知道的东西。

用CreateFile打开设备后,对于存储设备, IOCTL_DISK_GET_DRIVE_GEOMETRY,IOCTL_STORAGE_GET_MEDIA_TYPES_EX等I/O控制码照常使用。

今天我们讨论一个新的控制码:IOCTL_STORAGE_QUERY_PROPERTY,获取设备属性信息,希望得到系统中 所安装的各种固定的和可移动的硬盘、优盘和CD/DVD-ROM/R/W的接口类型、序列号、产品ID等信息。

// IOCTL控制码

#define IOCTL_STORAGE_QUERY_PROPERTY  CTL_CODE (IOCTL_STORAGE_BASE, 0x0500,
METHOD_BUFFERED, FILE_ANY_ACCESS) // 存储设备的总线类型
typedef enum _STORAGE_BUS_TYPE {
   BusTypeUnknown = 0x00,
   BusTypeScsi,
   BusTypeAtapi,
   BusTypeAta,
   BusType1394,
   BusTypeSsa,
   BusTypeFibre,
   BusTypeUsb,
   BusTypeRAID,
   BusTypeMaxReserved = 0x7F
} STORAGE_BUS_TYPE, *PSTORAGE_BUS_TYPE;
// 查询存储设备 属性的类型
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; // 设备/适配器
STORAGE_QUERY_TYPE QueryType; // 查询类型 
   UCHAR AdditionalParameters[1]; // 额外的数据(仅定义了象征性的1个字节)
} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY;
// 查询属性输出的数据结构
typedef struct _STORAGE_DEVICE_DESCRIPTOR {
   ULONG Version; // 版本
   ULONG Size;  // 结构大小
   UCHAR DeviceType; // 设备类型
   UCHAR DeviceTypeModifier; // SCSI-2额外的设备类型
   BOOLEAN RemovableMedia; // 是否可移动
   BOOLEAN CommandQueueing; // 是否支持命令队列
   ULONG VendorIdOffset; // 厂家设定值的偏移    ULONG ProductIdOffset; // 产品ID的偏移
   ULONG ProductRevisionOffset; // 产品 版本的偏移
   ULONG SerialNumberOffset; // 序列号的偏移
   STORAGE_BUS_TYPE BusType; // 总线类型
   ULONG RawPropertiesLength; // 额外的属性数据长度
   UCHAR RawDeviceProperties[1]; // 额外的属性数据(仅定义了象征性的1个字节)
} STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR;
// 取设备属性信息
// hDevice -- 设备句柄
// pDevDesc -- 输出的设备描述和属性信息缓冲区指针(包含连接在一起的 两部分)
BOOL GetDriveProperty(HANDLE hDevice, PSTORAGE_DEVICE_DESCRIPTOR pDevDesc)
{
STORAGE_PROPERTY_QUERY Query; // 查询输入参数
DWORD dwOutBytes;  // IOCTL输 出数据长度
BOOL bResult;   // IOCTL返回值
// 指定查询方式
Query.PropertyId = StorageDeviceProperty;
Query.QueryType = PropertyStandardQuery;
// 用 IOCTL_STORAGE_QUERY_PROPERTY取设备属性信息
bResult = ::DeviceIoControl(hDevice, // 设 备句柄
 IOCTL_STORAGE_QUERY_PROPERTY, // 取设备属性信息
 &Query, sizeof (STORAGE_PROPERTY_QUERY), // 输入数据缓冲区
 pDevDesc, pDevDesc->Size, // 输出数 据缓冲区
 &dwOutBytes,  // 输出数据长度
 (LPOVERLAPPED)NULL);  // 用同步 I/O 
return bResult;
}

Tags:实战 DeviceIoControl 列举

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接