Solved

Reading a string from Registry using RegQueryValueEx

Posted on 2004-08-26
4
2,899 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

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

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

IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

756 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