Reputation: 177
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
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
Reputation: 54610
ERROR_MORE_DATA
means the buffer you supplied to hold the data is not big enough.
Your problems are multiple:
LPBYTE
. That is going to FAIL miserably. The Registry APIs are not designed to work with string
s, 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