Solved

Reading a string from Registry using RegQueryValueEx

Posted on 2004-08-26
4
2,756 Views
Last Modified: 2010-07-27
Hi,
   I have stored a string value under a key in the registry. I want to read back this value using RegQueryValueEx.

1. I dont know the length of the string...so wat do i pass as the parameter?
2. I want to read the value into a BSTR

...Cosinex
0
Comment
Question by:manoj_johar
  • 2
4 Comments
 
LVL 19

Expert Comment

by:drichards
Comment Utility
The length you pass in is not the length of the string but rather the length of the buffer you passed in to receive the value.  You just need to make this big enough to handle the largest string length you expect to receive.  On return, the value contains the actual number of bytes loaded into the value buffer or the number of bytes required if the buffer was not big enough.  This is all explained in the documentation:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/regqueryvalueex.asp

You will not be able to read the value directly into a BSTR.  You will ned to create the BSTR using the returned data bytes.  This value will be UNICODE if the app is compiled as UNICODE or ANSI otherwise.  Then you need to either use a COM helper _bstr_t which takes either type of string as a constructor parameter:

_bstr_t regStr((LPCTSTR)lpData);

or convert the data to UNICODE if necessary and then call SysAllocString.
0
 
LVL 2

Accepted Solution

by:
carribus earned 60 total points
Comment Utility
Assuming that you have access to Microsoft's CString class, you can use the following code (to specialise it into a BSTR will be just as simple)

----------- START -------------

// specialised key value retrieval function for strings
CString GetStringValue(LPCTSTR lpszName)
{
  if ( !m_hKey )             // the currently open registry key handle
    return _T("");

  BYTE*            pBuffer = NULL;
  CString            strVal(_T(""));

  GetValue(lpszName, &pBuffer);

  if ( pBuffer )
  {
    strVal = pBuffer;
  }

  delete [] pBuffer;
  pBuffer = NULL;

  return strVal;
}

//
// this function will retrieve ANY key's value into a BYTE buffer
void GetValue(LPCTSTR lpszName, BYTE** ppBuffer)
{
  BYTE*            pBuffer = NULL;
  DWORD            dwType, dwSize = 1;
  LONG            lResult = ERROR_SUCCESS;

  do
  {
    if ( pBuffer )
    {
      delete [] pBuffer;
      pBuffer = NULL;
    }
    pBuffer = new BYTE[dwSize];
    ZeroMemory(pBuffer, dwSize);
    lResult = RegQueryValueEx(m_hKey, lpszName, NULL, &dwType, pBuffer, &dwSize);
  } while ( lResult == ERROR_MORE_DATA );

  if ( lResult == ERROR_SUCCESS )
  {
    *ppBuffer = pBuffer;
  }
  else
  {
    delete [] pBuffer;
    *ppBuffer = NULL;
  }
}

----------- EOF -------------

Hope this helps
0
 
LVL 16

Assisted Solution

by:nonubik
nonubik earned 35 total points
Comment Utility
1.As drichards said, you need to pass a buffer length enough to store the data. Or if you want to retrieve the exact buffer length you can call RegQueryValueEx with the last parameter as a reference to a DWORD set to 0. The call will fail, but the DWORD var will contain the exact length. Then you call again.

DWORD dwSize = 0;
RegQueryValueEx(hKey, lpValueName, 0, 0, lpData, &dwSize); //this call will fail with a retunr value of ERROR_MORE_DATA
//now dwSize contain the exact length
RegQueryValueEx(hKey, lpValueName, 0, 0, lpData, &dwSize);

2. You can read your data directly into a BSTR if you allocate it properly

BSTR bstrData = SysAllocStringByteLen(0, dwSize);
RegQueryValueEx(hKey, lpValueName, 0, 0, (LPBYTE)bstrData, &dwSize);
.....
//somwhere deallocate the bstr
SysFreeString(bstrData);
0
 
LVL 19

Assisted Solution

by:drichards
drichards earned 30 total points
Comment Utility
>> You can read your data directly into a BSTR if you allocate it properly

You must also either be doing a UNICODE build or explicitly call RegQueryValueExW for this to work.  Under Windows 95/98/Me, it means you must also have Microsoft Layer for Unicode installed along with your app.  Otherwise, the string is automatically converted to ANSI before it is returned to you and this approach will not work

And if you do this, it is VERY important to do exactly the code given by nonubik, with the caveat that you define a UNICODE build or use ReqQueryValueExW.  A BSTR stores its length in the 4 bytes preceding the BSTR pointer value.  BSTR functions look at this to determine the length.  This allows BSTR's to have internal NULLs and not require NULL-termination.  If you just copy some bytes onto a BSTR buffer, the string length will not reflect the length of the string you copied in and you will ghet unexpected behavior.
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now