请问REG_FULL_RESOURCE_DESCRIPTOR类型注册表值数据提取用哪个结构体?
Correct Structure for REG_FULL_RESOURCE_DESCRIPTOR Registry Values
你提到的CM_FULL_RESOURCE_DESCRIPTOR确实是对应REG_FULL_RESOURCE_DESCRIPTOR类型注册表值的正确结构体——问题大概率出在你对该值数据结构的理解上:HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\Configuration Data存储的不是单个CM_FULL_RESOURCE_DESCRIPTOR实例,而是一个该结构体的数组。
关键细节说明:
数据结构本质:
这个注册表值的内容是多个CM_FULL_RESOURCE_DESCRIPTOR结构体连续排列组成的列表,每个结构体描述了系统中某一硬件组件的完整资源分配情况(包含IO、内存、中断等资源类型)。正确解析步骤:
- 首先调用
RegQueryValueEx(或NtQueryValueKey)获取数据的总大小,以此分配足够的缓冲区。 - 将缓冲区中的数据视为
CM_FULL_RESOURCE_DESCRIPTOR数组,通过总数据大小除以单个结构体的大小计算元素数量(注意内存对齐,Windows内核结构体通常按8字节对齐,用户模式读取时要确保缓冲区符合对齐要求)。 - 遍历数组中的每个结构体,访问其
PartialResourceList字段(指向CM_PARTIAL_RESOURCE_LIST)来提取具体的资源条目。
- 首先调用
常见错误点:
- 误以为是单个结构体,导致解析时读取到错误的内存区域或越界。
- 忽略内存对齐问题,导致结构体字段偏移错误(比如在32位和64位系统下,结构体的大小可能不同,要使用对应平台的头文件)。
示例代码片段(用户模式):
HKEY hSystemKey = NULL; LONG status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System", 0, KEY_READ, &hSystemKey); if (status == ERROR_SUCCESS) { DWORD dataSize = 0; // First query to get data size status = RegQueryValueExW(hSystemKey, L"Configuration Data", NULL, NULL, NULL, &dataSize); if (status == ERROR_SUCCESS && dataSize > 0) { // Allocate aligned buffer (using HeapAlloc with HEAP_ZERO_MEMORY ensures alignment on most systems) CM_FULL_RESOURCE_DESCRIPTOR* pResourceDescs = (CM_FULL_RESOURCE_DESCRIPTOR*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dataSize); if (pResourceDescs != NULL) { status = RegQueryValueExW(hSystemKey, L"Configuration Data", NULL, NULL, (LPBYTE)pResourceDescs, &dataSize); if (status == ERROR_SUCCESS) { DWORD descCount = dataSize / sizeof(CM_FULL_RESOURCE_DESCRIPTOR); for (DWORD i = 0; i < descCount; i++) { CM_FULL_RESOURCE_DESCRIPTOR* pCurrDesc = &pResourceDescs[i]; // Process the partial resource list here CM_PARTIAL_RESOURCE_LIST* pPartialList = &pCurrDesc->PartialResourceList; for (DWORD j = 0; j < pPartialList->Count; j++) { CM_PARTIAL_RESOURCE_DESCRIPTOR* pRes = &pPartialList->PartialDescriptors[j]; // Handle each resource type (e.g., CmResourceTypePort, CmResourceTypeMemory) } } } HeapFree(GetProcessHeap(), 0, pResourceDescs); } } RegCloseKey(hSystemKey); }
额外注意事项:
- 读取该注册表项需要管理员权限,否则会返回访问被拒绝的错误。
- 确保使用对应Windows版本的头文件(
wdm.h或ntddk.h,用户模式下也可以包含setupapi.h间接获取结构体定义),不同版本的结构体可能有细微调整。
内容的提问来源于stack exchange,提问作者Aeoliyan
相关产品推荐
相关产品推荐

