******请大家帮忙把这个C程序转换成DELPHI代码可以吗?******
××××我的目的就是想获取系统目前所有存储设备的信息(包括总线类型、厂商、ID、等等)×××
×××下面是我从网上找到的代码×× 今天我们讨论一个新的控制码: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;
}Q: 我用这个方法从IOCTL_STORAGE_QUERY_PROPERTY返回的数据中,没有得到CDROM和USB接口的外置硬盘的序列号、产品ID等信息。但从设备路径上看,明明是有这些信息的,为什么它没有填充到STORAGE_DEVICE_DESCRIPTOR中呢?再就是为什么硬盘序列号本是“D22P7KHE ”,为什么它填充的是“3146563447534558202020202020202020202020”这种形式呢?
A:非常感谢您的程序,上面的问题我已经解决了,是头文件的问题,硬盘和光驱都可以检测,为什么软驱不行呢
××××我的目的就是想获取系统目前所有存储设备的信息(包括总线类型、厂商、ID、等等)×××
×××下面是我从网上找到的代码×× 今天我们讨论一个新的控制码: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;
}Q: 我用这个方法从IOCTL_STORAGE_QUERY_PROPERTY返回的数据中,没有得到CDROM和USB接口的外置硬盘的序列号、产品ID等信息。但从设备路径上看,明明是有这些信息的,为什么它没有填充到STORAGE_DEVICE_DESCRIPTOR中呢?再就是为什么硬盘序列号本是“D22P7KHE ”,为什么它填充的是“3146563447534558202020202020202020202020”这种形式呢?
A:非常感谢您的程序,上面的问题我已经解决了,是头文件的问题,硬盘和光驱都可以检测,为什么软驱不行呢
unit Disks;
interfaceuses windows,Messages,SysUtils,Dialogs;
const
Method_Buffered = 0;
File_Any_Access = 0;
File_Device_Mass_Storage = $0000002D;
IOCTL_Storage_Base = File_Device_MASS_Storage;// $002Dtype
// 存储设备的总线类型
pSTORAGE_BUS_TYPE=^STORAGE_BUS_TYPE;
STORAGE_BUS_TYPE =(
BusTypeUnknown = $00,
BusTypeScsi,
BusTypeAtapi,
BusTypeAta,
BusType1394,
BusTypeSsa,
BusTypeFibre,
BusTypeUsb,
BusTypeRAID,
BusTypeMaxReserved = $7F
);// 查询存储设备属性的类型
pSTORAGE_QUERY_TYPe=^STORAGE_QUERY_TYPE;
STORAGE_QUERY_TYPE =(
PropertyStandardQuery = 0, // 读取描述
PropertyExistsQuery, // 测试是否支持
PropertyMaskQuery, // 读取指定的描述
PropertyQueryMaxDefined // 验证数据
);// 查询存储设备还是适配器属性
pSTORAGE_PROPERTY_ID=^PSTORAGE_PROPERTY_ID;
STORAGE_PROPERTY_ID =(
StorageDeviceProperty = 0, // 查询设备属性
StorageAdapterProperty // 查询适配器属性
);// 查询属性输入的数据结构
PSTORAGE_PROPERTY_QUERY=^STORAGE_PROPERTY_QUERY;
STORAGE_PROPERTY_QUERY = packed record
PropertyId:STORAGE_PROPERTY_ID ; // 设备/适配器
QueryType:STORAGE_QUERY_TYPE ; // 查询类型
AdditionalParameters:string[1]; // 额外的数据(仅定义了象征性的1个字节)
end;
// 查询属性输出的数据结构
PSTORAGE_DEVICE_DESCRIPTOR=^STORAGE_DEVICE_DESCRIPTOR;
STORAGE_DEVICE_DESCRIPTOR = packed record
Version:ULONG; // 版本
Size:ULONG; // 结构大小
DeviceType:UCHAR; // 设备类型
DeviceTypeModifier:UCHAR; // SCSI-2额外的设备类型
RemovableMedia:Boolean; // 是否可移动
CommandQueueing:Boolean; // 是否支持命令队列
VendorIdOffset:Ulong; // 厂家设定值的偏移
ProductIdOffset:ULONG; // 产品ID的偏移
ProductRevisionOffset:ULONG; // 产品版本的偏移
SerialNumberOffset:ULONG; // 序列号的偏移
BusType:STORAGE_BUS_TYPE ; // 总线类型
RawPropertiesLength:ULONG; // 额外的属性数据长度
RawDeviceProperties:string[1]; // 额外的属性数据(仅定义了象征性的1个字节)} STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR;
end;function GetDriveProperty(hDevice:Thandle;pDevDesc:PSTORAGE_DEVICE_DESCRIPTOR):Boolean;
function Ctl_Code(DeviceType, FuncNo, Method, Access: integer): integer;implementationfunction Ctl_Code(DeviceType, FuncNo, Method, Access: integer): integer;
begin
Result:= (DeviceType shl 16) or (Access shl 14) or (FuncNo shl 2) or (Method)
end;function GetDriveProperty(hDevice:Thandle;pDevDesc:PSTORAGE_DEVICE_DESCRIPTOR):Boolean;
var
Query:STORAGE_PROPERTY_QUERY; // 查询输入参数
dwOutBytes:Dword; // IOCTL输出数据长度
IOCTL_STORAGE_QUERY_PROPERTY:integer;
begin
// 指定查询方式
IOCTL_STORAGE_QUERY_PROPERTY:=Ctl_Code(IOCTL_STORAGE_BASE, $0500, METHOD_BUFFERED, FILE_ANY_ACCESS);
Query.PropertyId:= StorageDeviceProperty;
Query.QueryType:= PropertyStandardQuery;
Result:=DeviceIoControl(hDevice, // 设备句柄
IOCTL_STORAGE_QUERY_PROPERTY , // 取设备属性信息
@Query,
sizeof(Query), // 输入数据缓冲区
pDevDesc, // 输出数据缓冲区
pDevDesc.Size, // 输出数据长度
dwOutBytes,
nil); // 用同步I/O
end;end.