title: RegEnumValueA returns 87 ("Invalid Parameter")
body: <p>I am currently implementing functions and classes from Borland C++ Builder 5 in Visual Studio 2022. One of the classes is used to handle Windows registry IO, and one of its methods is supposed to return a list of values which the current key contains.</p>
  <p>I am using Windows' <code>RegEnumValueA</code> function which, after passing correct arguments, always returns 87 – which stands for &quot;Invalid Parameter&quot;.</p>
  <p>The method looks as follows:</p>
  <pre><code>void __fastcall TRegistry::GetValueNames(TStrings* Strings)
  {
      HKEY hKey                                     = m_CurrentKey;
      DWORD dwIndex                                 = 0;
      CHAR cValueName[TREG_MAX_VALUES_BUF_SIZE]     = {};
      LPSTR lpValueName                             = cValueName;
      DWORD dwValueBufSize                          = TREG_MAX_VALUES_BUF_SIZE;
      LPDWORD lpcchValueName                        = &amp;dwValueBufSize;
      LPDWORD lpType                                = NULL;
      BYTE cData[TREG_MAX_VALUES_BUF_SIZE]          = {};
      LPBYTE lpData                                 = cData;
      LPDWORD lpcbData                              = NULL;
  
      long res = RegEnumValueA(hKey, dwIndex, lpValueName, lpcchValueName, NULL, lpType, lpData, lpcbData);
      while (res != ERROR_NO_MORE_ITEMS)
      {
          if (res != ERROR_SUCCESS)
          {
              throw(Exception(AnsiString(res)));
          }
          else
          {
              ++dwIndex;
              res = RegEnumValueA(hKey, dwIndex, lpValueName, lpcchValueName, NULL, lpType, lpData, lpcbData);
          }
      }
  }
  </code></pre>
  <p>As you can see, all the parameters are set correctly. My suspicion is that the <code>NULL</code> passed after <code>lpcchValueName</code> is causing this problem, since I've seen some people having the same issue after looking it up. Unfortunately, these were problems from years ago and were related to system-specific issues on e.g. Windows NT. The call to this method looks as follows:</p>
  <pre><code>int main()
  {
      TRegistry* treg = new TRegistry; // Create a TRegistry object
      if (treg-&gt;OpenKey(AnsiString(&quot;TRegistryTest&quot;), false)) // Open the TRegistryTest key
      {
          if (treg-&gt;OpenKey(AnsiString(&quot;subkey1&quot;), true)) // Open the subkey1 key
          {
              TStringList ts; 
              treg-&gt;GetValueNames(&amp;ts); // Write the value names into a TStringList
          }
      }
      delete treg;
  }
  </code></pre>
  <p><code>TStringList</code> is essentially a container which stores <code>AnsiString</code> values, which in turn are basically glorified <code>std::string</code>s.
  I expected the <code>RegEnumValueA</code> function to exit with code 0 as long as there are registry values left to read - in this case, there are 4 values in total in TRegistryTest/subkey1.</p>
  <p>Changing <code>TREG_MAX_VALUES_BUF_SIZE</code> does not influence the result at all - it's currently set to a value of 200.</p>