You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

移植Borland C++ Builder 5注册表类至Visual Studio 2022时RegEnumValueA返回87(无效参数)问题求助

Fixing RegEnumValueA Error 87 (Invalid Parameter) in TRegistry::GetValueNames

Let's break down why you're hitting error 87 and how to fix it:

The Root Cause

Your code is passing a non-NULL lpData pointer (pointing to cData) but a NULL lpcbData parameter. The RegEnumValueA API requires that if you provide a valid buffer via lpData, you must also pass a valid pointer to a DWORD in lpcbData to specify the buffer's size (and receive the actual data size after the call). When these two parameters are mismatched (non-NULL lpData + NULL lpcbData), Windows returns error 87 (invalid parameter).

Since your goal is only to retrieve value names (not their data or types), you don't need to allocate buffers for data at all. Plus, your current code has two other issues that would cause problems even after fixing the error 87:

  1. You never reset dwValueBufSize to TREG_MAX_VALUES_BUF_SIZE between API calls. After the first call, this variable gets updated to the length of the retrieved value name, so subsequent calls will use an incorrectly small buffer size.
  2. You don't actually add the retrieved value names to the TStrings* Strings parameter—so even if the API calls worked, your output list would be empty.

Corrected Code for GetValueNames

Here's the fixed version of your method:

void __fastcall TRegistry::GetValueNames(TStrings* Strings) {
    if (!Strings) {
        throw Exception("Strings parameter cannot be null");
    }
    Strings->Clear(); // Ensure the list is empty before adding new entries

    HKEY hKey = m_CurrentKey;
    DWORD dwIndex = 0;
    CHAR cValueName[TREG_MAX_VALUES_BUF_SIZE] = {};
    DWORD dwValueBufSize = 0;
    long res = ERROR_SUCCESS;

    do {
        // Reset buffer size and clear the name buffer for each iteration
        dwValueBufSize = TREG_MAX_VALUES_BUF_SIZE;
        memset(cValueName, 0, sizeof(cValueName));

        // Only request the value name—pass NULL for type, data, and data size parameters
        res = RegEnumValueA(
            hKey,
            dwIndex,
            cValueName,
            &dwValueBufSize,
            NULL,       // Reserved, must be NULL
            NULL,       // We don't need the value type
            NULL,       // We don't need the value data
            NULL        // No data buffer, so no size pointer needed
        );

        if (res == ERROR_SUCCESS) {
            // Convert the retrieved ANSI name to AnsiString and add to the list
            Strings->Add(AnsiString(cValueName));
            dwIndex++;
        } else if (res != ERROR_NO_MORE_ITEMS) {
            // Throw an exception for any error other than "no more items"
            throw Exception(AnsiString("RegEnumValueA failed with error code: ") + AnsiString(res));
        }
    } while (res != ERROR_NO_MORE_ITEMS);
}

Key Changes Made

  • Fixed parameter mismatch: Set lpData and lpcbData to NULL since we don't need value data. This eliminates the invalid parameter error.
  • Reset buffer state: For each iteration, we reset dwValueBufSize to the full buffer size and clear the name buffer to avoid leftover data from previous calls.
  • Populate the output list: Added Strings->Add(AnsiString(cValueName)) to actually store the retrieved value names in the provided TStrings container.
  • Added null check: Added a guard clause to ensure the Strings parameter isn't null, preventing crashes.
  • Improved loop structure: Switched to a do-while loop to make the flow more readable—we always attempt the first enumeration before checking the result.

Additional Notes

  • Ensure TREG_MAX_VALUES_BUF_SIZE is large enough to handle the longest value name in your registry key (including the null terminator). 200 is reasonable for most cases, but if you encounter ERROR_MORE_DATA, you may need to increase it or implement dynamic buffer allocation.
  • Verify that m_CurrentKey is a valid, open HKEY handle (your OpenKey calls seem correct, but it's worth double-checking if you still run into issues).

内容的提问来源于stack exchange,提问作者Jakub Cieślak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 20:52:41