RegEnumKeyEx无法正常工作

时间:2012-08-03 20:08:26

标签: c winapi registry

我正在尝试创建一个列出特定(Windows注册表)密钥的所有子密钥的函数。

正在发生的事情是只有第一项正确输出,所有其他项目都被截断或重复 - 我认为这是一个缓冲问题。

我已经阅读了功能文档,但它对我没什么帮助。

以下是代码:

#include<stdio.h>
#include<windows.h>

void print_list(HKEY hkey, char* path){

char dwValue[255];
DWORD  dwSize = 0;
DWORD n; // subkeys
HKEY tmp;
int i;

if(RegOpenKeyEx(hkey, path, 0, KEY_READ, &tmp) == ERROR_SUCCESS){

    DWORD  dwSize = sizeof(dwValue);

    RegQueryInfoKey(tmp,NULL,NULL,NULL,&n,NULL,NULL,NULL,NULL,NULL,NULL,NULL);      

    for(i=0; i< n; i++){
        RegEnumKeyEx(tmp,i,dwValue,&dwSize,NULL,NULL,NULL,NULL);
        printf("%s\n", dwValue);
    }

    RegCloseKey(tmp);
}
}

int main(){
print_list(HKEY_LOCAL_MACHINE, "SOFTWARE");
return 0;
}

2 个答案:

答案 0 :(得分:3)

在调用RegEnumKeyEx()之前添加以下行:

dwSize = sizeof(dwValue);

因为dwSize是输入和输出参数。在输入时,它指出缓冲区的大小。来自RegEnumKeyEx()

  

指向变量的指针,该变量指定由lpName参数指定的缓冲区的大小(以字符为单位)。此大小应包括终止空字符。如果函数成功,则lpcName指向的变量包含缓冲区中存储的字符数,不包括终止空字符。

注意,您应该始终检查函数的返回值(就像您为RegOpenKeyEx()所做的那样)。

答案 1 :(得分:1)

如果您从RegEnumKeyEx调用中检查返回代码,您将看到您获得0xEA,这意味着数据比您提供的缓冲区长。

这是因为dwSize是输入/输出参数。当你调用它时,该函数假定缓冲区最后有dwSize字符可用。返回时,dwSize已更改为实际数据的大小。这使得dwSize远小于实际的缓冲区大小。在下次调用时,它可能认为您没有足够的空间,而是返回错误代码。

您需要在每次通话前重置dwSize。