Solved

Reading a string from Registry using RegQueryValueEx

Posted on 2004-08-26
4
2,992 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

On Demand Webinar: Networking for the Cloud Era

Ready to improve network connectivity? Watch this webinar to learn how SD-WANs and a one-click instant connect tool can boost provisions, deployment, and management of your cloud connection.

Question has a verified solution.

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

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
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 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…

632 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