【问题标题】:how to get property-exists status with IOCTL_STORAGE_QUERY_PROPERTY如何使用 IOCTL_STORAGE_QUERY_PROPERTY 获取属性存在状态
【发布时间】:2018-02-08 00:11:05
【问题描述】:

我找不到任何关于这个调用的解释:

DeviceIoControl( aHANDLE, 
        IOCTL_STORAGE_QUERY_PROPERTY,
        & aSTORAGE_PROPERTY_QUERY, 
       ... etc.)

应该在aSTORAGE_PROPERTY_QUERY.QueryType 时工作 设置为PropertyExistsQuery

这应该以某种方式告诉我财产是否, 由aSTORAGE_PROPERTY_QUERY.PropertyId 指定, 可从aHANDLE 寻址的对象获得。

此外,它特别不返回输出缓冲区中的任何信息(当QueryType 时返回信息 设置为PropertyStandardQuery)。

我通过反复试验发现DeviceIoControl() 的返回值仍然表示函数调用的成功/失败,并不表示该属性的可用性。

那么,这是如何工作的呢?

【问题讨论】:

  • 之所以断定DeviceIoControl() 的返回值不是我正在寻找的状态,是因为我从查询中获得了非零返回(输出缓冲区长度为零)然后,当使用QueryType=PropertyStandardQuery 询问该数据时,我得到错误和GetLastError() == ERROR_INVALID_FUNCTION (1)。当针对同一属性处理其他类似设备时,我同样从查询中获得非零返回,但随后成功获取属性数据。所以......我想我必须得出结论,有些东西没有按应有的方式工作(?)。
  • 对于它的价值,我刚刚了解到:“在用户模式下,STATUS_NOT_IMPLEMENTED 或 STATUS_INVALID_DEVICE_REQUEST 将映射到 ERROR_INVALID_FUNCTION。”我认为这意味着这两个映射到相同的值。

标签: winapi ioctl


【解决方案1】:

此外,它特别不返回输出缓冲区中的任何信息(当 QueryType 设置为 PropertyStandardQuery 时返回信息)。

IOCTRL_STORAGE_QUERY_PROPERTYSTORAGE_PROPERTY_QUERY 文档中明确说明了这一点:

通过lpOutBuffer 参数返回的可选输出缓冲区可以是多个结构之一,具体取决于lpInBuffer 参数指向的STORAGE_PROPERTY_QUERY 结构的PropertyId 成员的值。这些值由STORAGE_PROPERTY_ID 枚举枚举。 如果STORAGE_PROPERTY_QUERYQueryType 成员设置为PropertyExistsQuery,则不返回任何结构

通过IOCTL_STORAGE_QUERY_PROPERTY 控制代码的lpOutBuffer 参数返回的可选输出缓冲区可以是多个结构之一,具体取决于PropertyId 成员的值。 如果QueryType 成员设置为PropertyExistsQuery,则不返回任何结构

IOCTRL_STORAGE_QUERY_PROPERTY 文档还明确指出以下内容:

nOutBufferSize

输出缓冲区的大小,以字节为单位。 可以为零来确定属性是否存在而不检索其数据。为此,请将此参数设置为零 (0),并将 STORAGE_PROPERTY_QUERY 输入结构的 QueryType 成员设置为 PropertyExistsQuery (1)。如果对 DeviceIoControl 的调用返回非零值,则该属性存在

这与您声称 DeviceIoControl() 的返回值不告诉您要查找的内容相矛盾。

但是,PropertyExistsQuery is not reliable on all systems and devices!它有时会报告错误的结果(此外,在检索属性的STORAGE_DESCRIPTOR_HEADER 时,有时也会报告错误的Size 值)。

链接文章的作者继续展示他如何诉诸于不仅请求属性的存在,还查询其标题和数据,然后证实结果。

代码是VB,但可以翻译成C/C++。

【讨论】:

  • 结果可能会通过 STORAGE_PROPERTY_QUERY::AdditionalParameters 成员输出 - 这原则上不能。这是METHOD_BUFFERED - 这意味着输入缓冲区(STORAGE_PROPERTY_QUERY)被复制到内核。在此之后的驱动程序或 io 管理器已经无法更改 InputBuffer - 他们没有指向它的指针(只有它复制)。 STORAGE_PROPERTY_QUERY 独占输入参数。
  • 输出缓冲区的大小,以字节为单位。它可以为零来确定属性是否存在而不检索其数据 - 实际上不是。如果OutputBufferLength < sizeof(STORAGE_DESCRIPTOR_HEADER),大多数设备都会返回错误(如STATUS_INVALID_PARAMETER)。即使PropertyExistsQuery 需要设置OutputBufferLength 不少于sizeof(STORAGE_DESCRIPTOR_HEADER)(8 个字节)
  • 当我使用STORAGE_DESCRIPTOR_HEADER作为查询中的输出缓冲区时,我得到零字节返回,DeviceIoControl() 的返回值与使用零时相同(并且任何错误代码相同)长度输出缓冲区。
  • @jsc - 这是特定于设备的。驱动程序处理此请求。不是窗户本身。例如,我在某些磁盘驱动程序视图STATUS_INVALID_PARAMETER_1 上的测试中,当零长度输出缓冲区和另一个结果当我使用STORAGE_DESCRIPTOR_HEADER 作为查询中的输出缓冲区时。但在所有情况下,PropertyExistsQuery 返回零字节
  • 这是标准磁盘硬件。设备管理器说驱动程序是微软的,由微软 Windows 签名。文件 \Windows\systeme32\DRIVERS\disk.sys、...EhStorClass.sys、...partmgr.sys 和 ...stdcfltn.sys。我想我很满意这不像宣传的那样工作,所以感谢您的帮助。我让那个 Basic 程序以这种方式做出贡献,但我没有编译器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-01
  • 1970-01-01
  • 2018-05-12
  • 1970-01-01
相关资源
最近更新 更多