Copying DWORD from HKCU to HKLM - c++

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);

Related

C++ How To Convert String YYYYMMDD To TimeStamp

I have a program that gets installed on my laptop to a json file.
I retrieve the date of the installed program from registry and I would like to convert that date to a timestamp.
This is my code :
HKEY hUninstKey = NULL;
HKEY hAppKey = NULL;
WCHAR InstallDate[1024];
WCHAR *sRoot = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
long lResult = ERROR_SUCCESS;
DWORD dwType = KEY_ALL_ACCESS;
DWORD dwBufferSize = 0;
//Open the "Uninstall" key.
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, sRoot, 0, KEY_READ, &hUninstKey) != ERROR_SUCCESS)
{
}
for (DWORD dwIndex = 0; lResult == ERROR_SUCCESS; dwIndex++)
{
//Enumerate all sub keys...
dwBufferSize = sizeof(sAppKeyName);
if ((lResult = RegEnumKeyEx(hUninstKey, dwIndex, sAppKeyName,
&dwBufferSize, NULL, NULL, NULL, NULL)) == ERROR_SUCCESS)
{
//Open the sub key.
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, sSubKey, 0, KEY_READ, &hAppKey) != ERROR_SUCCESS)
{
RegCloseKey(hAppKey);
RegCloseKey(hUninstKey);
}
//Get the display name value from the application's sub key.
dwBufferSize = sizeof((RegQueryValueEx(hAppKey, L"InstallDate", NULL, &dwType, (unsigned char*)InstallDate, &dwBufferSize) == ERROR_SUCCESS))
{
// Display Date Of Installed Program
const TCHAR* xInstallDate = (TCHAR*)InstallDate;
char DateInstall[MAX_LENGTH + 200];
wcstombs_s(&nNumCharConverted, DateInstall, MAX_LENGTH + 200,
xInstallDate, MAX_LENGTH + 200);
file << "\"',date='" << DateInstall << endl;
}
else {
//Display name value doe not exist, this application was probably uninstalled.
}
RegCloseKey(hAppKey);
}
}
RegCloseKey(hUninstKey);
Could anyone please help with my code?
You should look into the usage of std::chrono::parse. It converts string streams into chrono objects which represent time.
This is the documentation of std::chrono::parse: https://en.cppreference.com/w/cpp/chrono/parse
This is a relevant question on SO (you are possibly a duplicate): How to parse a date string into a c++11 std::chrono time_point or similar?

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;
}

RegQueryValueEx getting incorrect data

I use this code to copy registry data from HKCU to HKLM. Between 1-9 the correct number is retrieved but on 10 I get a, 11 I get b, etc. I dont know what I have done incorrect, I wold be grateful for any help.
extern "C" UINT __stdcall ReadTempRegKey(MSIHANDLE hInstall)
{
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\\%s",Orc_Get_Product_Name());
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);
lszValue is the data recieved.
I'm going to use my crystal ball to attempt to answer this.
The copying is being performed perfectly well, but you are viewing the data as hexadecimal rather than decimal. The decimal value 10 is a in hex, decimal 11 is b and so on.

C++ Windows get registry value inconsistent returns

I am writing a simple C++ program to grab a Windows registry value on a 64 bit machine.
The problem is it only works for about 50% of the registry's and for the other half "ret" does not return ERROR_SUCCESS(0).
My question is to why I am getting these inconsistent returns and also when I attempt to make the path longer than two directories it also break.
ex.
keypath = TEXT("SOFTWARE\\Perl\\ASDF");
Here is my code.
LPCTSTR keypath = TEXT("SOFTWARE\\Perl");
HKEY key = NULL;
LONG ret = ERROR_SUCCESS;
DWORD BufferSize = TOTALBYTES;
DWORD cbData;
DWORD dwRet;
DWORD type;
char registry[256] = {'\0'};
ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keypath, 0, KEY_QUERY_VALUE, &key);
PPERF_DATA_BLOCK PerfData = (PPERF_DATA_BLOCK) malloc( BufferSize );
cbData = BufferSize;
if (ret == ERROR_SUCCESS)
{
dwRet = RegQueryValueEx( key,
TEXT("BinDir"),
NULL,
&type,
(LPBYTE) PerfData,
&cbData );
RegCloseKey(key);
printf("\nFinal buffer size is %d\n", BufferSize);
int i = 0;
while ((*PerfData).Signature[i] != NULL)
{
registry[i] = (char)(*PerfData).Signature[i];
i++;
}
printf("registery: %s\n", registry);
}
editing in fixes.

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;
}