实战DeviceIoControl之五:列举已安装的存储设备
2010-01-10 09:37:27 来源:WEB开发网本例的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 列举
编辑录入:爽爽 [复制链接] [打 印]- ››实战:企业使用交换机VLAN路由配置
- ››实战案例分析:高质量软文对网站百度排名的影响
- ››实战经验浅谈网站搬家后的优化工作
- ››实战Active Directory站点部署与管理,Active Dir...
- ››实战操作主机角色转移,Active Directory系列之十...
- ››实战经验:巧用微博推广淘宝网店
- ››实战iPhone GPS定位系统
- ››实战Linux环境配置DBD:Oracle模块
- ››实战DeviceIoControl系列之一:通过API访问设备驱...
- ››实战DeviceIoControl系列之二:获取软盘/硬盘/光盘...
- ››实战DeviceIoControl系列之三:制作磁盘镜像文件
- ››实战DeviceIoControl系列之四:获取硬盘的详细信息...
更多精彩
赞助商链接