Reading Windows Registry Key REG_BINARY in c++ - c++

I'm trying to read a registry key in c++,
that's my function:
DWORD regkey()
{
HKEY hKey;
DWORD dwDisp = REG_BINARY;
DWORD dwSize = sizeof(dwDisp);
DWORD dwValue = 0;
DWORD dwReturn;
DWORD dwBufSize = sizeof(dwDisp);
if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"HERE\\IS\\THE\\REGKEY",0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
{
DWORD error = RegQueryValueEx(hKey,L"key",0,0, (LPBYTE)&dwReturn, &dwBufSize);
if(error == ERROR_SUCCESS)
{
return dwReturn;
}
}
RegCloseKey(hKey);
return 0;
}
but it's returning nothing... please help me.

The registry functions will return a meaningful error code, and that can help you diagnose the problem. Try holding on to that code:
{
HKEY hKey;
DWORD dwDisp = REG_BINARY;
DWORD dwSize = sizeof(dwDisp);
DWORD dwValue = 0;
DWORD dwReturn;
DWORD dwBufSize = sizeof(dwReturn);
DWORD dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"HERE\\IS\\THE\\REGKEY",0, KEY_READ, &hKey) ;
if( dwError == ERROR_SUCCESS)
{
dwError = RegQueryValueEx(hKey,L"key",0,0, (LPBYTE)&dwReturn, &dwBufSize);
if(error == ERROR_SUCCESS)
{
// it worked!
}
else
{
// it failed to read, check dwError for the error code
dwResult = 0;
}
RegCloseKey(hKey);
}
else
{
// it failed to open, check dwError for the error code
dwResult = 0;
}
return 0;
}
If you're using Visual Studio, you can break on any of the failure points and evaluate dwError,hr in your watch window. The ,hr format specifier causes the debugger to look up the error code for you and present a meaningful string that describes the problem. That should lead you to an understanding of what went wrong.
If you can tell us which function is failing and which code you're getting back from that function, we might be able to provide more detailed help. As it stands now, you've presented us with a bit of a guessing game. Maybe you've misspelled your registry key name or given an incorrect path. Your code seems to imply you're passing the registry key RegQueryValueEx(), but you're meant to pass a value name, not a key name, to that function. Maybe you have a problem with access privileges because you're looking at a protected part of the registry and not running as an account with enough rights to read that key. (And so, you should pass KEY_READ instead of KEY_ALL_ACCESS.)

Related

Anyone has experience on using GetAppContainerNamedObjectPath?

Recently I came across a Windows API called GetAppContainerNamedObjectPath. But I have no idea on how I can use it.
I found a msdn page for this api (https://learn.microsoft.com/en-us/windows/win32/api/securityappcontainer/nf-securityappcontainer-getappcontainernamedobjectpath). But it does not have a right example and remarks, parameters are written poorly.
I am getting ERROR_INVALID_PARAMETER(87) error at the end, which tells me something's wrong with the parameters that I put. Here's what I've tried.
#define TokenIsAppContainer 29
#define TokenAppContainerSid 31
#define TokenAppContainerNumber 32
typedef struct _TOKEN_APPCONTAINER_INFORMATION {
PSID TokenAppContainer;
} TOKEN_APPCONTAINER_INFORMATION, *PTOKEN_APPCONTAINER_INFORMATION;
void GetAppContainerProcessInfo(CString & procName)
{
DWORD dwSize = 0;
DWORD dwResult;
HANDLE hToken;
PTOKEN_APPCONTAINER_INFORMATION pAppCoInfo;
WCHAR wcsDebug[1024] = {0,};
WCHAR * pwSID = NULL;
typedef BOOL (WINAPI *_LPGETAPPCONTAINERNAMEOBJECTPATH)(HANDLE, PSID, ULONG, LPWSTR, PULONG);
static _LPGETAPPCONTAINERNAMEOBJECTPATH lpGetAppContainerNamedObjectPath = NULL;
if (0 == lpGetAppContainerNamedObjectPath)
{
HMODULE hKernel32 = LoadLibraryExW(L"kernel32.dll", NULL, 0);
if (hKernel32)
{
lpGetAppContainerNamedObjectPath = reinterpret_cast<_LPGETAPPCONTAINERNAMEOBJECTPATH>(GetProcAddress(hKernel32, "GetAppContainerNamedObjectPath"));
}
}
if (lpGetAppContainerNamedObjectPath)
{
DWORD processId = (DWORD)_ttoi((LPCTSTR)procName);
//HANDLE hProcess = GetProcessHandleByProcessName(procName);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);
if(!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken))
{
dwResult = GetLastError();
swprintf_s( wcsDebug, _countof(wcsDebug), L"OpenProcessToken Error(%u) PID(%d)\n", dwResult, processId );
AfxMessageBox(wcsDebug);
return;
}
if (!GetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS) TokenAppContainerSid, NULL, dwSize, &dwSize))
{
dwResult = GetLastError();
if( dwResult != ERROR_INSUFFICIENT_BUFFER )
{
swprintf_s( wcsDebug, _countof(wcsDebug), L"GetTokenInformation Error %u\n", dwResult );
AfxMessageBox(wcsDebug);
return;
}
}
pAppCoInfo = (PTOKEN_APPCONTAINER_INFORMATION) GlobalAlloc( GPTR, dwSize );
if (!GetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS) TokenAppContainerSid, pAppCoInfo, dwSize, &dwSize))
{
dwResult = GetLastError();
swprintf_s( wcsDebug, _countof(wcsDebug), L"GetTokenInformation Error %u\n", dwResult );
AfxMessageBox(wcsDebug);
return;
}
WCHAR wcsNamedObjectPath[MAX_PATH];
ULONG ulRetlen = 0;
BOOL bRet = lpGetAppContainerNamedObjectPath(hToken, pAppCoInfo->TokenAppContainer, _countof(wcsNamedObjectPath), wcsNamedObjectPath, &ulRetlen );
if (bRet)
{
swprintf_s( wcsDebug, _countof(wcsDebug), L"GetAppContainerNamedObjectPath Path(%s)\n", wcsNamedObjectPath );
AfxMessageBox(wcsDebug);
}
else
{
dwResult = GetLastError();
swprintf_s( wcsDebug, _countof(wcsDebug), L"GetAppContainerNamedObjectPath Error %u\n", dwResult );
AfxMessageBox(wcsDebug);
}
if (pwSID)
LocalFree(pwSID);
CloseHandle(hToken)
CloseHandle(hProcess);
}
}
As a side-note, I have tried using wchar_t * and dynamically allocate the memory buffer by calling GetAppContainerNamedObjectPath twice. But still had no chance. Return length does not return a meaningful value.
if you call RtlGetLastNtStatus(); instead GetLastError(); after GetAppContainerNamedObjectPath you will got
STATUS_INVALID_PARAMETER_MIX - An invalid combination of parameters was specified.
this give you more info compare simply invalid parameter.
then look for function signature
BOOL
WINAPI
GetAppContainerNamedObjectPath(
_In_opt_ HANDLE Token,
_In_opt_ PSID AppContainerSid,
_In_ ULONG ObjectPathLength,
_Out_writes_opt_(ObjectPathLength) LPWSTR ObjectPath,
_Out_ PULONG ReturnLength
);
the Token and AppContainerSid declared with In_opt -- this mean that this parameters is optional, and you can pass 0 in place one of it. then ask your self - for what you query token for TokenAppContainerSid ? are system can not do this for you if you pass this token to api ? obvious can. so you not need do this yourself. really you need pass Token to api and in this case AppContainerSid must be 0. or you can pass AppContainerSid to api and in this case Token must be 0. when both AppContainerSid and Token not zero - you and got STATUS_INVALID_PARAMETER_MIX
also as side note - you not need open process with PROCESS_ALL_ACCESS if you need get it token. the PROCESS_QUERY_LIMITED_INFORMATION is enough
really api not do big magic. it return to you
AppContainerNamedObjects\<Sid>
path, where string form of app container sid.(some like S-1-15-2-...)

In c++, how to disable windows UAC control by program?

In program C++, how to change the windows UAC to always notify or never notify.
Manually, I should change like this:
I found C# code from Internet:
const string UACkey = #"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System";
const string Subkey = "EnableLUA";
RegistryUtilities.SetValue(UACkey, Subkey, **1**, Microsoft.Win32.RegistryValueKind.DWord, RegistryUtilities.WOW64Key.Key64);
Does somebody know how to change into c++ code?
I tried to change the Registry with c++, but it does not work.
HKEY hKey = NULL;
LONG lResult = 0;
BOOL fSuccess = TRUE;
DWORD dwSize;
const size_t count = MAX_PATH*2;
wchar_t szValue[count] = {};
lResult = RegOpenKeyExW(HKEY_CURRENT_USER, L"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", 0, (KEY_WRITE | KEY_READ), &hKey);
fSuccess = (lResult == 0);
if (fSuccess)
{
dwSize = (wcslen(szValue)+1)*2;
lResult = RegSetValueExW(hKey, L"EnableLUA", 0, REG_SZ, (BYTE*)szValue, dwSize);
fSuccess = (lResult == 0);
}
if (hKey != NULL)
{
RegCloseKey(hKey);
hKey = NULL;
}
To answer your stated question, you can set registry keys with RegSetKeyValue, however you have to get past UAC in order to change the registry. To answer your implicit question, yes you could probably disable UAC programatically for malicious purposes, however you have to get past UAC in the first place to do so. Once you're on the other side of the airtight hatchway, you can do whatever you want of course. However you still have to get past the UAC hurdle.
Furthermore, I highly recommend you do a cursory google search before posting a question like this. The Windows C API is documented very well on MSDN.
Your code is actually very close;
DWORD val = 0;
HKEY uaKey;
RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", 0, KEY_WRITE , &uaKey);
if(uaKey == NULL)
{
//Handle error message here
}
else
{
if (RegSetValueEx (uaKey, "EnableLUA", 0, REG_DWORD, (const BYTE *)&val, sizeof(val)) != ERROR_SUCCESS)
{
//Error
}
else
{
//Success
}
RegCloseKey(uaKey);
}

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

Returning invalid data from RegQueryValueEx() DWORD

I'm trying to read a DWORD value from the registry. In the registry, it's stored as 0x00000068 (104). When I read the value from the registry, I'm getting a very large number (3435973836). Any help is appreciated!
DWORD getRecentId(PDWORD id) {
HKEY hKey;
LONG lRes = RegOpenKeyEx(HKEY_CURRENT_USER, _T("SOFTWARE\\My App\\Feed Reader"), 0, KEY_QUERY_VALUE, &hKey);
if (!lRes == ERROR_SUCCESS)
{
RegCloseKey(hKey);
return ERROR_FILE_NOT_FOUND;
}
DWORD dwSize = sizeof(DWORD);
lRes = RegQueryValueEx(hKey, _T("Latest"), NULL, NULL, (LPBYTE)&id, &dwSize);
if (!lRes == ERROR_SUCCESS)
{
RegCloseKey(hKey);
return ERROR_NOT_ENOUGH_MEMORY;
}
RegCloseKey(hKey);
return lRes;
}
3435973836 is a magic number. Convert it to hex to get 0xcccccccc. When you see that back in the Visual Studio debugger then you know that you are using an uninitialized variable.
It is, using &id was wrong. That alters the pointer, not the pointed-to value. Use id instead.

Save Me Simple Add to Startup via Registry [duplicate]

I'm trying to add my software to registry, I have found some pieces of the codes I can use but not full working code C/C++ is new to me and can't create it on my own. But here is the basic idea: Check if reg key set if not create it.
I was able to get my program location using this code:
TCHAR szPath[MAX_PATH];
GetModuleFileName(NULL,szPath,MAX_PATH);
And was able to create the key with: (Not sure if it's the right way)
HKEY newValue;
RegOpenKey(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&newValue);
RegSetValueEx(newValue,"myprogram",0,REG_SZ,(LPBYTE)szPath,sizeof(szPath));
RegCloseKey(newValue);
return 0;
What is missing, A small check if the key isn't already there...
Thank you!
Here's some code that likely does what you want. Call RegisterProgram for your EXE to self-register itself for automatically being started when the user logs in. This function calls GetModuleFileName and then invokes another helper function called RegisterMyProgramForStartup that does the writing to the registry.
Call IsMyProgramRegisteredForStartup(L"My_Program") to detect if the registration actually exists and appears valid.
One quick note. The performance impact of checking to see if the key exists before actually writing it out again is negligible. You could just call RegisterProgram blindly and it will overwrite the key if it already exists. Detecting if the registration exists is useful for initializing your UI checkbox that enables or disables auto-start. (You are giving your users a choice, right? Because I hate apps that automatically install themselves to run automatically without giving me a choice.)
BOOL IsMyProgramRegisteredForStartup(PCWSTR pszAppName)
{
HKEY hKey = NULL;
LONG lResult = 0;
BOOL fSuccess = TRUE;
DWORD dwRegType = REG_SZ;
wchar_t szPathToExe[MAX_PATH] = {};
DWORD dwSize = sizeof(szPathToExe);
lResult = RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_READ, &hKey);
fSuccess = (lResult == 0);
if (fSuccess)
{
lResult = RegGetValueW(hKey, NULL, pszAppName, RRF_RT_REG_SZ, &dwRegType, szPathToExe, &dwSize);
fSuccess = (lResult == 0);
}
if (fSuccess)
{
fSuccess = (wcslen(szPathToExe) > 0) ? TRUE : FALSE;
}
if (hKey != NULL)
{
RegCloseKey(hKey);
hKey = NULL;
}
return fSuccess;
}
BOOL RegisterMyProgramForStartup(PCWSTR pszAppName, PCWSTR pathToExe, PCWSTR args)
{
HKEY hKey = NULL;
LONG lResult = 0;
BOOL fSuccess = TRUE;
DWORD dwSize;
const size_t count = MAX_PATH*2;
wchar_t szValue[count] = {};
wcscpy_s(szValue, count, L"\"");
wcscat_s(szValue, count, pathToExe);
wcscat_s(szValue, count, L"\" ");
if (args != NULL)
{
// caller should make sure "args" is quoted if any single argument has a space
// e.g. (L"-name \"Mark Voidale\"");
wcscat_s(szValue, count, args);
}
lResult = RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, NULL, 0, (KEY_WRITE | KEY_READ), NULL, &hKey, NULL);
fSuccess = (lResult == 0);
if (fSuccess)
{
dwSize = (wcslen(szValue)+1)*2;
lResult = RegSetValueExW(hKey, pszAppName, 0, REG_SZ, (BYTE*)szValue, dwSize);
fSuccess = (lResult == 0);
}
if (hKey != NULL)
{
RegCloseKey(hKey);
hKey = NULL;
}
return fSuccess;
}
void RegisterProgram()
{
wchar_t szPathToExe[MAX_PATH];
GetModuleFileNameW(NULL, szPathToExe, MAX_PATH);
RegisterMyProgramForStartup(L"My_Program", szPathToExe, L"-foobar");
}
int _tmain(int argc, _TCHAR* argv[])
{
RegisterProgram();
IsMyProgramRegisteredForStartup(L"My_Program");
return 0;
}
To check whether or not the value exists, call RegQueryValueEx.
LONG retval = RegQueryValueEx(hKey, "myprogram", NULL, NULL, NULL, NULL);
Note that what you called newValue is actually a key rather than a value. To avoid confusion you should name it such. I used the name hKey.
Then to check whether or not the value exists, compare retval against ERROR_SUCCESS as described in the documentation.
The other problem with your code is that there is absolutely no error checking. I'll leave that to you to address.
You forget to write an argument about security access