|
|
libcdi 的 github 好像你设置为只读了,没法回复了。在这里回。
改了一个地方。修正一处获取 physicalDriveId 的错误,在我这个INTEL VMD 的机器下,NVME设备SMART读取成功。
把
- ULONG cbPdo = sizeof(szBuf);
- if (CM_Get_DevNode_Registry_PropertyW(devInst, CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME, NULL, szBuf, &cbPdo, 0) == CR_SUCCESS)
- {
- DebugPrint(szBuf);
- CString pdo(szBuf);
- int pos = pdo.Find(L"Harddisk");
- if (pos >= 0)
- {
- pos += (int)wcslen(L"Harddisk");
- CString num;
- while (pos < pdo.GetLength() && iswdigit(pdo[pos]))
- {
- num += pdo[pos];
- pos++;
- }
- if (!num.IsEmpty())
- {
- physicalDriveId = _wtoi(num);
- }
- }
- }
复制代码 改成:
- ULONG ulLength = 0;
- if (CM_Get_Device_Interface_List_SizeW(&ulLength, (LPGUID)&GUID_DEVINTERFACE_DISK, (DEVINSTID_W)pszId, CM_GET_DEVICE_INTERFACE_LIST_PRESENT) == CR_SUCCESS && ulLength > 0)
- {
- PWSTR pInterfaceList = (PWSTR)malloc(ulLength * sizeof(WCHAR));
- if (pInterfaceList)
- {
- ZeroMemory(pInterfaceList, ulLength * sizeof(WCHAR));
- if (CM_Get_Device_Interface_ListW((LPGUID)&GUID_DEVINTERFACE_DISK, (DEVINSTID_W)pszId, pInterfaceList, ulLength, CM_GET_DEVICE_INTERFACE_LIST_PRESENT) == CR_SUCCESS && pInterfaceList[0] != L'\0')
- {
- HANDLE hDisk = CreateFileW(
- pInterfaceList,
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL
- );
- if (hDisk != INVALID_HANDLE_VALUE)
- {
- STORAGE_DEVICE_NUMBER sdn = { 0 };
- DWORD bytesReturned = 0;
- if (DeviceIoControl(
- hDisk,
- IOCTL_STORAGE_GET_DEVICE_NUMBER,
- NULL,
- 0,
- &sdn,
- sizeof(sdn),
- &bytesReturned,
- NULL
- ))
- {
- physicalDriveId = sdn.DeviceNumber;
- }
- safeCloseHandle(hDisk);
- }
- }
- free(pInterfaceList);
- }
- }
复制代码
另外 pszIdBase 生成时,应该可以一次过滤掉非 "DiskDrive" 的类型列表。
补充:
if (!deviceName.IsEmpty() && deviceName.Find(L"AMD-RAID Config") >= 0)
发现这里的判断不是“优势”所在, 应该是用 CM_Get_Parent 获取磁盘的父设备(实际就是磁盘控制器),然后通过父设备的 硬件ID和兼容ID 列表判断(实际使用的是 兼容ID),比如这里的AMD RAID和AMD的硬件ID对应,实际就是"PCI\VEN_1022&CC_0104", AMD的NVME RAID 是 "PCI\VEN_1022&CC_0108"。
然后INTEL的RAID或者RST或者VMD,就是: "PCI\VEN_8086&CC_0104"
|
|