使用STORAGE_PROPERTY_QUERY获取StorageAdapterPhysicalTopologyProperty失败求助
解决IOCTL_STORAGE_QUERY_PROPERTY获取StorageAdapterPhysicalTopologyProperty时的1117错误
核心问题分析
你的代码存在三个关键问题,直接导致了1117(ERROR_IO_DEVICE)错误:
- CreateFile权限缺失:查询存储拓扑属性需要至少
GENERIC_READ权限,你传入的访问权限为0,驱动会拒绝无权限的请求。 - 缓冲区调用流程错误:部分存储驱动要求先通过
STORAGE_DESCRIPTOR_HEADER获取所需缓冲区大小,再发起完整数据请求,直接用STORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR作为首次输出缓冲区会触发驱动报错。 - 字符集不匹配:
CreateFileA是ANSI版本,但你混用了_T宽字符宏,导致路径解析异常。
修正后的代码
#include <windows.h> #include <vector> #include <stdio.h> bool GetAdapterPhysicalTopology() { bool result = false; // 使用宽字符版本CreateFile,并传入GENERIC_READ权限 HANDLE hDevice = CreateFileW(L"\\\\.\\PhysicalDrive0", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (hDevice != INVALID_HANDLE_VALUE) { DWORD bytesReturned = 0; STORAGE_PROPERTY_QUERY query = {}; query.PropertyId = StorageAdapterPhysicalTopologyProperty; query.QueryType = PropertyStandardQuery; // 第一步:获取描述符头部,确定所需缓冲区大小 STORAGE_DESCRIPTOR_HEADER header = {}; if (DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), &header, sizeof(header), &bytesReturned, nullptr)) { // 第二步:分配对应大小的缓冲区,获取完整拓扑数据 std::vector<BYTE> buff(header.Size); if (DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), buff.data(), buff.size(), &bytesReturned, nullptr)) { PSTORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR psptd = reinterpret_cast<PSTORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR>(buff.data()); wprintf(L"NodeCount: %u\n", psptd->NodeCount); result = true; } else { printf("DeviceIoControl(2) failed. Error Code %d.\n", GetLastError()); } } else { printf("DeviceIoControl(1) failed. Error Code %d.\n", GetLastError()); } CloseHandle(hDevice); } else { printf("CreateFile failed. Error Code %d.\n", GetLastError()); } return result; }
额外注意事项
- 必须以管理员权限运行程序,访问物理磁盘设备需要系统级权限。
- 部分老旧存储驱动可能不支持
StorageAdapterPhysicalTopologyProperty,若仍报错可检查设备驱动版本是否兼容。
内容的提问来源于stack exchange,提问作者Mark Welo
相关产品推荐
相关产品推荐

