【问题标题】:Windows RegQueryValueEx odd return resultsWindows RegQueryValueEx 奇数返回结果
【发布时间】:2013-07-30 18:02:48
【问题描述】:

我在使用 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;
}

【问题讨论】:

    标签: windows winapi registry


    【解决方案1】:

    这是设计使然。第一次调用失败,因为您指定的大小太小。但您没想到的是它更新了您的 dataSize 变量。告诉您要分配多少内存才能使调用成功。

    所以第二次调用成功了,因为您现在指定了一个完全正确的大小。但不做你需要做的other 事情,实际上使缓冲区更大。当调用然后导致缓冲区溢出并损坏您的堆栈帧时,不会发生什么好事,请务必使用 /RTC 编译选项,这样您就会得到运行时错误。

    您通过将缓冲区大小从 256 增加到 1024 避免了这个问题。但是您的代码仍然不正确,如果注册表值变得大于 1024 字节,您的程序将严重失败。不要使用本地数组,使用 new 运算符或 malloc() 来分配缓冲区,这样它就不会像这样失败。或者干脆让调用失败并声明“坏数据”。

    还要注意另一个错误,dataSize 以 bytes 为单位,但缓冲区是 TCHAR,而不是字节。这可能就是您没有破坏堆栈帧的原因,缓冲区意外地足够大。你不想依赖这样的事故。考虑使用像 CRegKey 这样的辅助类来避免此类错误。

    【讨论】:

    • 谢谢,我认为至少解决了缓冲区溢出问题。现在我第一次调用RegQueryValueEx 以获得dataSize 中的正确大小,然后使用new 运算符分配TCHAR 缓冲区大小为dataSize。这仍然是一个错误,因为您声明 dataSize 以字节为单位,缓冲区是 TCHAR,而不是一个字节?
    • 是的。你可以用 malloc() 解决这个问题。
    猜你喜欢
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    • 2018-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-08
    相关资源
    最近更新 更多