Wednesday, July 8, 2009

Reading Values From the Registry Using RegGetValue

I am working on rewriting this section of code that needs to read key values from the registry.

First of all, if you already know what the key value is, you can get directly with RegGetValue.
// you should always use SAL annotations and the free static analysis tool PreFAST
__checkReturn HRESULT ReadKeyValue(
__in LPCWSTR pszSubKey,
__deref_out LPWSTR *ppszKeyValue)
{
HRESULT hr = S_OK;
DWORD cbDataSize = 4096;

*ppszKeyValue = NULL;

// This preallocates a reasonable size buffer for the value I want to read
// so that 99% of the time we only have to do one trip to the registry
if (!(*ppszKeyValue = (LPWSTR)malloc(cbDataSize)))
{
hr = E_OUTOFMEMORY;
}
else
{
**ppszKeyValue = L'\0'; // this makes PreFAST happy
}

while (S_OK == hr && S_OK != (hr = HRESULT_FROM_WIN32(
RegGetValue(
HKEY_LOCAL_MACHINE,
pszSubKey,
szRegValue,
RRF_RT_REG_SZ,
NULL,
*ppszKeyValue,
&cbDataSize))))
{
// if our preallocated buffer is not big enough, we will make it the
// exact size here and try the registry again
if (*ppszKeyValue)
{
free(*ppszKeyValue);
*ppszKeyValue = NULL;
}

if (HRESULT_FROM_WIN32(ERROR_MORE_DATA) == hr)
{
hr = S_OK;

if(!(*ppszKeyValue = (LPWSTR)malloc(cbDataSize)))
{
hr = E_OUTOFMEMORY;
}
}
else
{
// this means we hit an unexpected failure
break;
}
}

// you should always clean up you memory on error states so you don't leak
if (S_OK != hr && *ppszKeyValue)
{
free(*ppszKeyValue);
*ppszKeyValue = NULL;
}

return hr;
}

No comments:

Post a Comment