Solved

Reading a string from Registry using RegQueryValueEx

Posted on 2004-08-26
4
2,826 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
ID: 11900294
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
ID: 11901230
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
ID: 11920850
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
ID: 11922381
>> 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

Are your AD admin tools letting you down?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

831 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