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

[入库:2005年8月18日] [更新:2007年3月24日]

本文简介:选择自 bhw98 的 blog

息集句柄 hdevinfoset = ::setupdigetclassdevs(lpguid, // class guid null, // 无关键字 null, // 不指定父窗口句柄 digcf_present | digcf_deviceinterface); // 目前存在的设备 // 失败... if (hdevinfoset == invalid_handle_value) { return 0; } // 申请设备接口数据空间 pdetail = (psp_device_interface_detail_data)::globalalloc(lmem_zeroinit, interface_detail_size); pdetail->cbsize = sizeof(sp_device_interface_detail_data); ncount = 0; bresult = true; // 设备序号=0,1,2... 逐一测试设备接口,到失败为止 while (bresult) { ifdata.cbsize = sizeof(ifdata); // 枚举符合该guid的设备接口 bresult = ::setupdienumdeviceinterfaces( hdevinfoset, // 设备信息集句柄 null, // 不需额外的设备描述 lpguid, // guid (ulong)ncount, // 设备信息集里的设备序号 &ifdata); // 设备接口信息 if (bresult) { // 取得该设备接口的细节(设备路径) bresult = setupdigetinterfacedevicedetail( hdevinfoset, // 设备信息集句柄 &ifdata, // 设备接口信息 pdetail, // 设备接口细节(设备路径) interface_detail_size, // 输出缓冲区大小 null, // 不需计算输出缓冲区大小(直接用设定值) null); // 不需额外的设备描述 if (bresult) { // 复制设备路径到输出缓冲区 ::strcpy(pszdevicepath[ncount], pdetail->devicepath); // 调整计数值 ncount++; } } } // 释放设备接口数据空间 ::globalfree(pdetail); // 关闭设备信息集句柄 ::setupdidestroydeviceinfolist(hdevinfoset); return ncount; }

调用getdevicepath函数时要注意,pszdevicepath是个指向字符串指针的指针,例如可以这样

    int i;
    char* szdevicepath[max_device];        // 设备路径
  
    // 分配需要的空间
    for (i = 0; i < max_device; i++)
    {
        szdevicepath[i] = new char[256];
    }
  
    // 取设备路径
    ndevice = ::getdevicepath((lpguid)&diskclassguid, szdevicepath);
  
    // 逐一获取设备信息
    for (i = 0; i < ndevice; i++)
    {
        // 打开设备
        hdevice = ::opendevice(szdevicepath[i]);
  
        if (hdevice != invalid_handle_value)
        {
            ... ...        // i/o操作
  
            ::closehandle(hdevice);
        }
    }
  
    // 释放空间
    for (i = 0; i & lt; max_device; i++)
    {
        delete []szdevicepath[i];
    }

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

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

a 是的。尽管该设备路径与以前我们接触的那些不太一样。本是“\\.\physicaldrive0”,现在鸟枪换炮,变成了类似这样的一副尊容:

“\\?\ide#diskmaxtor_2f040j0__________________________vam51jj0#3146563447534558202020202020202020202020#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}”。

其实这个设备名在注册表的某处可以找到,例如在win2000中这个名字可以位于

hkey_local_machine\system\currentcontrolset\services\disk\enum\0,

只不过“#”换成了“\”。分析一下这样的设备路径,你会发现很有趣的东西,它们是由接口类型、产品型号、固件版本、序列号、计算机名、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_an

本文关键:DeviceIoControl,GUID
  相关方案
Google
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top