Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Reading a string from Registry using RegQueryValueEx

Posted on 2004-08-26
4
Medium Priority
?
3,178 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 240 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 140 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 120 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

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

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

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
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…
Suggested Courses

916 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