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.
I am using Windows' RegEnumValueA function which, after passing correct arguments, always returns 87 – which stands for "Invalid Parameter".
The method looks as follows:
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 = &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);
}
}
}
As you can see, all the parameters are set correctly. My suspicion is that the NULL passed after lpcchValueName 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:
int main()
{
TRegistry* treg = new TRegistry; // Create a TRegistry object
if (treg->OpenKey(AnsiString("TRegistryTest"), false)) // Open the TRegistryTest key
{
if (treg->OpenKey(AnsiString("subkey1"), true)) // Open the subkey1 key
{
TStringList ts;
treg->GetValueNames(&ts); // Write the value names into a TStringList
}
}
delete treg;
}
TStringList is essentially a container which stores AnsiString values, which in turn are basically glorified std::strings.
I expected the RegEnumValueA 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.
Changing TREG_MAX_VALUES_BUF_SIZE does not influence the result at all - it's currently set to a value of 200.