views:

110

answers:

1

Hi. I'm trying to read some ODBC details from a registry and for that I use RegQueryValueEx. The problem is when I compile the release version it simply cannot read any registry values.

The code is:

CString odbcFuns::getOpenedKeyRegValue(HKEY hKey, CString valName)
{
    CString retStr;
    char *strTmp = (char*)malloc(MAX_DSN_STR_LENGTH * sizeof(char));
    memset(strTmp, 0, MAX_DSN_STR_LENGTH);
    DWORD cbData;
    long rret = RegQueryValueEx(hKey, valName, NULL, NULL, (LPBYTE)strTmp, &cbData);
    if (rret != ERROR_SUCCESS)
    {
        free(strTmp);
        return CString("?");
    }
    strTmp[cbData] = '\0';
    retStr.Format(_T("%s"), strTmp);
    free(strTmp);
    return retStr;
}

I've found a workaround for this - I disabled Optimization (/Od), but it seems strange that I needed to do that. Is there some other way? I use Visual Studio 2005. Maybe it's a bug in VS?

Almost forgot - the error code is 2 (as the key wouldn't be found).

+3  A: 

You need to initialize cbData - set it to be MAX_DSN_STR_LENGTH - 1 before calling RegQueryValueEx().

The problem is likely configuration-dependent because the variable is initialized by the compiler in one configuration and left uninitialized in another.

Also you'll be much better of using std::vector for the buffer - less code, better exception safety, less error-prone.

sharptooth
Yes. In the Debug build the value will be initialized to 0xcccccccc. Don't subtract 1. Use the CRegKey class to avoid these traps.
Hans Passant
@Hans Passant He has buffer for N characters, filles with zeroes. If he doesn't subtract 1 and the function fills all N characters the string is no longer null-terminated.
sharptooth
Check the SDK docs: *If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type, this size includes any terminating null character or characters unless the data was stored without them*
Hans Passant
@Hans Passant: Yes, then "see remarks" follows and the remarks section says that the string might have been stored without the terminating null, so the program must be prepared to this.
sharptooth
Thanks, sharptooth. I guess I've missed that while preparing the code and forgot afterwards :-).@Hans Thanks, I'll try that too.
Nux