Windows RegQueryValueEx奇数返回结果

时间:2013-07-30 18:02:48

标签: windows winapi registry

使用RegQueryValueEx时我得到奇怪的结果,我无法弄清楚原因。

这是我在制作RegQueryValueEx

之前设置的内容
DWORD dataSize;
TCHAR data[256];

我第一次打电话

LONG ret = RegQueryValueEx( hKey, dataKey, NULL, NULL, (LPBYTE)data, &dataSize);

ret等于234(ERROR_MORE_DATA

但是当我在下一行打电话给同样的事情时

LONG ret2 = RegQueryValueEx( hKey, dataKey, NULL, NULL, (LPBYTE)data, &dataSize);

ret2等于0(ERROR_SUCCESS

为什么这个函数会在我第一次调用它时返回ERROR_MORE_DATA,然后在下一行的同一个调用中返回ERROR_SUCESS

我尝试更改TCHAR data[1024],但我得到了完全相同的结果。有什么想法吗?

完整代码:

for( int i=0; i<NUM_HISTORY; i++){
     CString dataKey = getDataKey(i);

     DWORD dataSize = 1024;
     TCHAR data[1024];

     LONG ret = RegQueryValueEx( hKey, dataKey, NULL, NULL, (LPBYTE)data, &dataSize);
     LONG ret2 = RegQueryValueEx( hKey, dataKey, NULL, NULL, (LPBYTE)data, &dataSize);

     // Breakpoint to see what ret and ret2 are equal to
     int j = 0;
}

1 个答案:

答案 0 :(得分:0)

这是设计的。第一次调用失败,因为您指定的尺寸太小。但是你没有指望的是它更新了你的dataSize变量。告诉你要分配多少内存,以便呼叫成功。

因此,第二次调用成功,因为您现在指定了完全正确的大小。但是如果不做你需要做的其他事情,实际上要使缓冲区更大。当调用然后导致缓冲区溢出并损坏堆栈帧时,可能会发生任何好处,请确保使用/ RTC编译选项,这样就会从中获得运行时错误。

您通过将缓冲区大小从256增加到1024来避免此问题。但是您的代码仍然不正确,如果注册表值大于1024字节,您的程序将失败。不要使用本地数组,使用 new 运算符或malloc()来分配缓冲区,以便它永远不会像这样失败。或者只是使通话失败并宣布“不良数据”。

另请注意另一个错误,dataSize位于 bytes 中,但缓冲区是TCHAR,而不是字节。这可能就是为什么你没有破坏堆栈框架,缓冲区很大就意外了。你不想依赖这样的事故。考虑像CRegKey这样的辅助类来避免这些错误。