C ++ RegEnumValue抛出ERROR_MORE_DATA

时间:2013-07-25 12:33:13

标签: c++ winapi registry

我试图从注册表中获取所有的符号。 不幸的是我总是收到ERROR_MORE_DATA错误... 我已经尝试让我的缓冲区更大,但它根本没用。 这是我的代码:

DWORD registry::regGetValue(char *key, int index)
{
HKEY hKey; 
 RegOpenKeyEx(HKEY_LOCAL_MACHINE,"HARDWARE\\DEVICEMAP\\SERIALCOMM",0,KEY_ALL_ACCESS,&hKey);
     DWORD chars = sizeof(key);
     LONG result = RegEnumValue(hKey, index, key, &chars, 0,0,0,0 );
 RegCloseKey(hKey);
 return result;
}

参数是:

char key[512];
int index = 0;

2 个答案:

答案 0 :(得分:0)

MSDN说:如果lpName缓冲区太小而无法接收密钥的名称,则该函数返回ERROR_MORE_DATA。在致电RegEnumKeyEx之前,您可以调用函数RegQueryInfoKey来确定由hKey标识的密钥的最大子密钥的大小。 RegQueryInfoKey的使用可在此处找到:“http://msdn.microsoft.com/en-us/library/windows/desktop/ms724902(v=vs.85).aspx

答案 1 :(得分:0)

缓冲区可能足够大,你只是对函数说实际大小。

在指针上使用sizeof运算符时,它返回指针的大小,而不是指向它的数组的大小。并且因为key作为char*传递给函数,它只是指向数组的指针,而不是数组本身。

您必须将缓冲区的实际大小作为参数与指针一起传递给函数:

DWORD regGetValue(char *key, size_t length, int index)
{
   HKEY hKey; 
   RegOpenKeyEx(HKEY_LOCAL_MACHINE,"HARDWARE\\DEVICEMAP\\SERIALCOMM",0,KEY_ALL_ACCESS,&hKey);
   DWORD chars = length;
   LONG result = RegEnumValue(hKey, index, key, &chars, 0,0,0,0 );
   RegCloseKey(hKey);
   return result;
}
char key[512];
int index = 0;
regGetValue(key, sizeof(key), index);

sizeof运算符在此处按预期工作,因为它在数组本身上运行,而不仅仅是指向它的指针。这种方法在C API中很常见,但很麻烦。

通过使用自动推断缓冲区大小的函数模板并将其传递给实际完成工作的内部帮助函数,您可以稍微简化调用站点的内容:

// Helper function, implemented as a private member of your class
DWORD regGetValue(char *key, size_t length int index)
{
   HKEY hKey; 
   RegOpenKeyEx(HKEY_LOCAL_MACHINE,"HARDWARE\\DEVICEMAP\\SERIALCOMM",0,KEY_ALL_ACCESS,&hKey);
   DWORD chars = length;
   LONG result = RegEnumValue(hKey, index, key, &chars, 0,0,0,0 );
   RegCloseKey(hKey);
   return result;
}

// The public function that you will actually call
template <size_t N>
DWORD regGetValue(char (&key)[N], int index)
{
   return regGetValue(key, N, index);
}
char key[512];
int index = 0;
regGetValue(key, index);  // length determined and passed automatically

这是有效的,因为您将引用传递给数组,而不是指针。

除此之外,我还要认真质疑为什么要调用ANSI函数并使用char*作为字符串。所有现代Windows应用程序都应该是Unicode。这意味着调用W - 后缀版本的Windows API函数并使用wchar_t*作为字符串类型。确保为项目定义了UNICODE_UNICODE符号,如果使用了错误的类型,则会出现编译时错误。