******请大家帮忙把这个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:非常感谢您的程序,上面的问题我已经解决了,是头文件的问题,硬盘和光驱都可以检测,为什么软驱不行呢

解决方案 »

  1.   

    以下是翻译完的,不过有问题,请大家帮忙看一下。
    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.