Jasmin25
Jasmin25

Reputation: 177

RegQueryValueEx - What code add to this function to show ERROR_SUCCESS

What code add to this function to work good? (ERROR_SUCCESS)

I have code, that check value in registry.

In function RegQueryValueEx is bug. When oldValue is few letters longer than newValue, function shows ERROR_MORE_DATA, but I want want ERROR_SUCCESS

What code add to this function to do this?

void function(string newValue, string key, string name)

{

 // string key - key in registry, ie Myapp\\Options
 // string name - name in registry
 // string newValue - data in REG_SZ


 string oldValue;
 DWORD keytype = REG_SZ;
    HKEY keyHandle;
 DWORD size = sizeof(string);
 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, key.c_str(),0L,KEY_ALL_ACCESS,&keyHandle) == ERROR_SUCCESS)
 {


  LONG isgood = RegQueryValueEx(keyHandle, name.c_str(), 0, &keytype, (LPBYTE)&oldValue, &size);
  if(isgood == ERROR_MORE_DATA)
   {
    cout << "Error more data\n"; 
   }
  if(isgood == ERROR_SUCCESS)
  {
   cout << "Old data is " << oldValue.c_str() << endl;
   cout << "New data is " << newValue.c_str() << endl;
   if(strcmp(newValue.c_str(), oldValue.c_str()) != 0) // compare 2 strings, if
   {
    cout << "String 1 and string 2 are different";

   }
   else
   {
    cout << "String 1 and string 2 are the same";
   }
  }
  if(isgood == ERROR_FILE_NOT_FOUND)
  {
   cout << "Name in registry not found!";
  }
 }

}

Upvotes: 1

Views: 2470

Answers (2)

Justin Grant
Justin Grant

Reputation: 46713

ERROR_MORE_DATA means that you need to pass in a larger string buffer. The typical pattern you'll need to use is to call once to get the size, then allocate a properly-sized buffer, then call again. Or, alternatively, you can guess at a size, pass in that-sized buffer, and increase size if you get ERROR_MORE_DATA back.

BTW, you are also computing size incorrectly. And you're not closing the registry key. And you're not prepared to support being compiled under unicode or non-unicode modes.

Here's some revised code which addresses these issues.

#include <string>
#include <vector>
#include <iostream>

#include <windows.h>
using namespace std;

namespace std
{
#ifdef _UNICODE
    #define tcout wcout
    #define tcin wcin
    typedef wstring tstring;
#else
    #define tcout cout
    #define tcin cin
    typedef string tstring;
#endif
};

void function(tstring newValue, tstring key, tstring name)
{
    // string key - key in registry, ie Myapp\\Options
    // string name - name in registry
    // string newValue - data in REG_SZ
    HKEY keyHandle;
    if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, key.c_str(),0L,KEY_ALL_ACCESS,&keyHandle) == ERROR_SUCCESS)
    {
        DWORD size = 500;   // initial size
        vector<TCHAR> buf(size);
        tstring oldValue;
        DWORD keytype = REG_SZ;

        LONG isgood = RegQueryValueEx(keyHandle, name.c_str(), 0, &keytype, (LPBYTE) &buf[0], &size);
        if(isgood == ERROR_SUCCESS)
        {
            oldValue.assign (&buf[0], size);
        }
        else if(isgood == ERROR_MORE_DATA)
        {
            buf.reserve (size); // expand to however large we need
            isgood = RegQueryValueEx(keyHandle, name.c_str(), 0, &keytype, (LPBYTE)&buf[0], &size);
            if(isgood == ERROR_SUCCESS)
                oldValue.assign (&buf[0], size);
        }
        RegCloseKey (keyHandle);    // remember to close this!
        if(isgood == ERROR_SUCCESS)
        {
            tcout << _T("Old data is ") << oldValue << endl;
            tcout << _T("New data is ") << newValue << endl;
            if(newValue.compare(oldValue) != 0) // compare 2 strings, if
            {
                tcout << _T("String 1 and string 2 are different");

            }
            else
            {
                tcout << _T("String 1 and string 2 are the same");
            }
        }
        if(isgood == ERROR_FILE_NOT_FOUND)
        {
            tcout << _T("Name in registry not found!");
        }
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    tstring val;
    function (val, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"), _T("CommonFilesDir"));
    return 0;
}

Upvotes: 2

i_am_jorf
i_am_jorf

Reputation: 54610

ERROR_MORE_DATA means the buffer you supplied to hold the data is not big enough.

Your problems are multiple:

  1. When you say sizeof(string) you're getting the size of the string data type, not the length of the string. You should call string::size() to get the length of the string.
  2. You can't just cast a string to an LPBYTE. That is going to FAIL miserably. The Registry APIs are not designed to work with strings, they are designed to work with char* and WCHAR* types. You need to declare a local character array (e.g. char *foo = new char[256]) and then pass that. If you get ERROR_MORE_DATA, declare a bigger one.

Upvotes: 2

Related Questions