windows registry read - c++

Using this code snippet:
TCHAR buf[255] = {0};
DWORD dwBufSize = sizeof(buf);
HKEY hKey = 0;
DWORD dwType = REG_DWORD;
if ( RegOpenKeyEx( HKEY_CURRENT_USER, TEXT("Software\\Developer\\KGReader"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
{
if( RegQueryValueEx( HKEY_CURRENT_USER, TEXT("Software\\Developer\\KGReader\\ComPort"), 0, &dwType, (LPBYTE)buf, &dwBufSize ) == ERROR_SUCCESS )
{
nrPort = _wtoi(buf);
}
if( RegQueryValueEx( HKEY_CURRENT_USER, TEXT("Software\\Developer\\KGReader\\KGID"), 0, &dwType, (LPBYTE)buf, &dwBufSize ) == ERROR_SUCCESS )
{
nrCentrala = _wtoi(buf);
}
}
No value is passed to hKey using RegOpenKeyEx method.
Although RegOpenKeyEx returns an ERROR_SUCCES, RegQueryValueEx returns 2 (ERROR_FILE_NOT_FOUND). KGID and ComPort do exist,i added them myself, i double checked the paths.

Pass the hKey obtained from the RegOpenKeyEx() call to the RegQueryValueEx() functions instead of HKEY_CURRENT_USER. The second argument to RegQueryValueEx() is the name of the value, not a path.
For example:
if( RegQueryValueEx(hKey,
TEXT("ComPort"),
0,
&dwType,
(LPBYTE)buf,
&dwBufSize ) == ERROR_SUCCESS )
Remember to reset buf and dwBufSize before the second call to RegQueryValueEx:
memset(buf, 0, sizeof(buf));
dwBufSize = sizeof(buf);
For error reporting purposes you should save the return value of the RegOpenKeyEx() and RegQueryValueEx() functions so the failure reason can be made known.
The posted code may be incomplete but ensure RegCloseKey(hKey) is called if the call to RegOpenKeyEx() was successful.

The first argument to RegQueryValueEx should be the HKEY opened by RegOpenKeyEx. In addition, the second argument should just be a value name, not the full path:
if( RegQueryValueEx( hKey, TEXT("ComPort"), 0, &dwType,
(LPBYTE)buf, &dwBufSize ) == ERROR_SUCCESS )

Related

RegQueryValueEx returns 0x02 while trying to read registry key?

i'm trying to read the graphics card used by the system from the registry. Therefor i'm accessing the registry with the szRegKey/szSubKEy listed below.
The RegQueryValueEx exits with Error 0x02 (ERROR_FILE_NOT_FOUND).
If i'm trying to access the key via the cmd with reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winsat" /v PrimaryAdapterString it succeeds succesfully. Can you help me with my problem?
HKEY hKey;
WCHAR szRegKey[]= L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winsat";
WCHAR szSubKey[] = L"PrimaryAdapterString";
WCHAR *buf;
DWORD dwBufSize = 0;
DWORD dwType = REG_SZ;
if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, szRegKey, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS) {
return false;
}
if(RegQueryValueExW(hKey, szSubKey, 0, &dwType, NULL, &dwBufSize) != ERROR_SUCCESS) {
return false;
}

Copying DWORD from HKCU to HKLM

Having a problem copying a registry value from HKCU to HKLM. It is a DWORD and I am using this code to enumerate all the keys and copy them at a certain time of my install.
HRESULT hr = S_OK;
UINT er = ERROR_SUCCESS;
HKEY hKey;
char szProductKey[MAX_PATH], lszValue[MAX_PATH];
TCHAR achKey[MAX_KEY_LENGTH], achClass[MAX_PATH] = TEXT(""), achValue[MAX_VALUE_NAME];
DWORD cbName, cchClassName = MAX_PATH, cSubKeys=0, cbMaxSubKey, cchMaxClass, cValues, cchMaxValue, cbMaxValueData, cbSecurityDescriptor;
FILETIME ftLastWriteTime;
PHKEY phkResult = NULL;
DWORD i, retCode, cchValue = MAX_VALUE_NAME,dwType=REG_SZ,dwSKeyValueSize,dwSize=255;
hr = WcaInitialize(hInstall, "ReadTempRegKey");
ExitOnFailure(hr, "Failed to initialize");
WcaLog(LOGMSG_STANDARD, "Initialized.");
Orc_Reg_Sub_LM_CU();
sprintf_s(szProductKey, "SOFTWARE\\M\\%s",Orc_Get_Product_Name());
WcaLog(LOGMSG_STANDARD , szProductKey);
if( RegOpenKeyEx( HKEY_CURRENT_USER,
szProductKey,
0,
KEY_READ,
&hKey) == ERROR_SUCCESS
)
{
//Get the class name and the value count.
retCode = RegQueryInfoKey(
hKey, // key handle
achClass, // buffer for class name
&cchClassName, // size of class string
NULL, // reserved
&cSubKeys, // number of subkeys
&cbMaxSubKey, // longest subkey size
&cchMaxClass, // longest class string
&cValues, // number of values for this key
&cchMaxValue, // longest value name
&cbMaxValueData, // longest value data
&cbSecurityDescriptor, // security descriptor
&ftLastWriteTime); // last write time
// Enumerate the subkeys, until RegEnumKeyEx fails.
if (cSubKeys)
{
for (i=0; i<cSubKeys; i++)
{
cbName = MAX_KEY_LENGTH;
retCode = RegEnumKeyEx(hKey, i,
achKey,
&cbName,
NULL,
NULL,
NULL,
&ftLastWriteTime);
}
}
//Enumerate the key values.
if (cValues)
{
for (i=0, retCode=ERROR_SUCCESS; i<cValues; i++)
{
cchValue = MAX_VALUE_NAME;
achValue[0] = '\0';
retCode = RegEnumValue(hKey, i,
achValue,
&cchValue,
NULL,
NULL,
NULL,
NULL);
if (retCode == ERROR_SUCCESS )
{
DWORD dwSize = sizeof(lszValue);
retCode = RegQueryValueEx(hKey, achValue, NULL, &dwType,(LPBYTE)&lszValue, &dwSize);
if (retCode == ERROR_SUCCESS)
{
Orc_Reg_Stop_LM_CU();
dwSKeyValueSize = strlen((char*) lszValue);
Orc_RegValue(HKEY_LOCAL_MACHINE,
"SOFTWARE\\M\\Orchestrator",
KEY_SET_VALUE,
achValue,
&dwType,
(unsigned char *)lszValue,
&dwSKeyValueSize);
}
}
}
}
}
After the copy the value for the registry is correct but the data says invalid dword 32-bit value Does anyone know what would cause this?
Thanks
You get the invalid dword 32-bit value message because the last parameter passed to Orc_RegValue() is incorrect. The correct value for REG_DWORD data type is sizeof(DWORD).
Try passing dwSize instead of dwSKeyValueSize
Orc_RegValue(HKEY_LOCAL_MACHINE,
"SOFTWARE\\M\\Orchestrator",
KEY_SET_VALUE,
achValue,
&dwType,
(unsigned char *)lszValue,
&dwSize);
Alternatively you can try
dwSKeyValueSize = dwSize;
instead of
dwSKeyValueSize = strlen((char*) lszValue);

RegSetValueEx() not changing the key value

In my application, when I first set the key-value using RegSetValueEx() it works, but when I try to change the value using the same function it doesn't work, the value remains same. What am I doing wrong ?
Here is the code :
SetSZValue( "MyAppData", "versionInfo", "1.0.0" );
HKEY CreateKey( string regkey )
{
HKEY hKey ;
DWORD disValue ;
char msg[512] ;
string _key = "HKEY_LOCAL_MACHINE\\" ;
_key += regkey ;
LONG retValue = RegCreateKeyEx( HKEY_LOCAL_MACHINE, regkey.c_str(), 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hKey, &disValue ) ;
if (retValue != ERROR_SUCCESS)
{
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, &msg[0], 512, 0 ) ;
MessageBox( 0, &msg[0], "CreateKey", MB_OK | MB_ICONEXCLAMATION );
}
return hKey ;
}
void SetSZValue( string regkey, string keyName, string keyValue )
{
HKEY hKey;
DWORD disValue;
char msg[512];
hKey = CreateKey(regkey);
if (hKey)
{
LONG retValue = RegSetValueEx( hKey, keyName.c_str(), 0, REG_SZ, ( const BYTE* )( keyValue.c_str() ), keyValue.size()+1 );
if ( retValue != ERROR_SUCCESS )
{
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, &msg[0], 512, 0 );
MessageBox( 0, &msg[0], "SetSZValue", MB_OK | MB_ICONEXCLAMATION );
}
RegCloseKey ( hKey );
}
}
RegSetValueEx accepts the name of the value inside the key to change; not the name of the key. Supply the value name instead; the key name comes from the HKEY itself.
Is your app a 32-bit process running on a 64-bit Windows version? If so, does your app have a UAC manifest with a "requestedExecutionLevel" value in it? If not, your key may be getting virtualized to another section of the Registry and you are simply not looking in the right place. Registry Virtualization is a feature of WOW64 so legacy 32-bit and 64-bit processes do not step over each other in the Registry. You should install SysInternals Process Monitor, it will show you which keys and values your app is actually accessing.

Why does the RegQueryValueEx() function return ERROR_FILE_NOT_FOUND while trying to read from a registry key?

System: Windows 7 32bit
Language: C++
I have tried to access register HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0, key Driver (type REG_SZ) -- no problem.
The same for reading from HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM, all keys (types REG_SZ) got slashes, for example \Device\Serial0.
While reading such keys it always returns 2 (no such file) with following example code:
HKEY hKey = 0;
DWORD dwType = REG_SZ;
char buf[255] = {0};
DWORD dwBufSize = sizeof(buf);
if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"), 0, KEY_QUERY_VALUE, &hKey ) == ERROR_SUCCESS )
{
auto ret = RegQueryValueEx( hKey, TEXT("\Device\Serial0"), 0, &dwType, (LPBYTE)buf, &dwBufSize );
// ret always == 2 for key with slashes
--- CUT ---
What is the proper way to read key values with slashes in name?
Above has been properly answered by Cody Gray.
Below another issue.
Im getting the same problem when Im using variable instead of a text string.
Iv considered both approaches with single and double slashes:
HKEY hKey = 0;
DWORD keyType = REG_SZ;
TCHAR buf[255] = {0};
DWORD bufSize = sizeof(buf);
QSettings winReg("HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM", QSettings::NativeFormat);
auto comsKey = winReg.allKeys();
FOREACH( auto com, comsKey )
{
// FOREACH - boost macro
// comsKey = QList<QString> (list of key names) [from Qt framework]
// com = QString (single key name) [from Qt framework]
if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"), 0, KEY_QUERY_VALUE, &hKey ) == ERROR_SUCCESS )
{
wchar_t* keyw = new wchar_t();
//com.replace("/", "\\\\"); <- checked both variants commented and not commented; com == /Device/Serial0 so im converting to \\Device\\Serial0
int size = com.size();
mbstowcs( keyw, com.toStdString().data(), size );
//auto ret = RegQueryValueEx( hKey, TEXT("\\Device\\Serial0"), 0, &keyType, (LPBYTE)buf, &bufSize ); // <- this works!
auto ret = RegQueryValueExW( hKey, (LPCWSTR)&keyw, 0, &keyType, (LPBYTE)buf, &bufSize ); // <- this one not works!
I have tried all variants with "\Device..", "/Device", "\Device", etc.
You have to escape the slashes, just like you did in the first line...
if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"), 0, KEY_QUERY_VALUE, &hKey ) == ERROR_SUCCESS )
{
auto ret = RegQueryValueEx( hKey, TEXT("\\Device\\Serial0"), 0, &dwType, (LPBYTE)buf, &dwBufSize );
// ret always == 2 for key with slashes
If you don't, the RegQueryValueEx function can't find the specified key, and it returns ERROR_FILE_NOT_FOUND (== 2).
But there's another problem. You should be declaring the buffer array as type wchar_t (or TCHAR), rather than char:
TCHAR buf[255] = {0};
Otherwise, the RegQueryValueEx function is going to attempt to fill the array with a Unicode string read from the specified registry key, and you're going to get something unreadable.

How to set a value in windows registry? (C++)

I want to edit key "HKEY_LOCAL_MACHINE\Software\company name\game name\settings\value" to "1" (DWORD)
This is my code:
HKEY hkey;
DWORD dwDisposition;
if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\company name\\game name\\settings"), 0, NULL, 0, 0, NULL, &hkey, &dwDisposition) == ERROR_SUCCESS){
DWORD dwType, dwSize;
dwType = REG_DWORD;
dwSize = sizeof(DWORD);
DWORD rofl = 1;
RegSetValueEx(hkey, TEXT("value"), 0, dwType, (PBYTE)&rofl, dwSize); // does not create anything
RegCloseKey(hkey);
}
But it doesnt do anything. RegCreateKeyEx() is the only function that actually does something: creates the "folders" in the registry only. So once again how im failing? How i can create "files" in the registry?
Always check the return value of API functions. You'll see that RegSetValueEx() returns 5, access denied. You didn't ask for write permission. Fix:
if(RegCreateKeyEx(HKEY_LOCAL_MACHINE,
TEXT("Software\\company name\\game name\\settings"),
0, NULL, 0,
KEY_WRITE, NULL,
&hkey, &dwDisposition) == ERROR_SUCCESS) {
// etc..
}
You probably need to pass in KEY_WRITE as the value of the samDesired arugment to RegCreateKeyEx() function (sixth argument).
This is a copy and edit from an actual code, may contain errors.
LONG
SetRegValue
(
const wchar_t* path
,const wchar_t *name
,const wchar_t *value
)
{
LONG status;
HKEY hKey;
status = RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_ALL_ACCESS, &hKey);
if ( (status == ERROR_SUCCESS) && (hKey != NULL))
{
status = RegSetValueEx( hKey, name, 0, REG_SZ, (BYTE*)value, ((DWORD)wcslen(value) + 1)*sizeof(wchar_t));
RegCloseKey(hKey);
}
return status;
}