How to open the registry and get the specific value in c++ - c++

Ineed to open this key" HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\100\"
and get the "VerSpecificRootDir" value using c++ ....How can i do this
I have no knowledge abt it can any one help me in this regard..
After Getting All The Support I did it as
unsigned long type=REG_SZ, size=1024;
char res[1024]="";
HKEY hk;
long n = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SOFTWARE\\Microsoft\\Microsoft SQL Server\\100"),
0,KEY_QUERY_VALUE, &hk );
if ( n == ERROR_SUCCESS )
{
printf("OK \n");
RegQueryValueEx(hk,L"VerSpecificRootDir",NULL,&type,(LPBYTE)&res[0],&size);
RegCloseKey(hk);
}
But in this i am not getting the value of "VerSpecificDirectory" what i have missed let me know?? what is wrong in this code....

You can use the Windows function SHRegGetValue like this:
TCHAR buffer[260];
DWORD bufferSize = sizeof(buffer);
SHRegGetValue(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Microsoft SQL Server\\100", "VerSpecificRootDir", SRRF_RT_REG_SZ, NULL, buffer, &bufferSize);
After calling the function, buffer will contain a null-terminated string of the directory. Might want to check the return value for errors too.

#include <windows.h>
HKEY hKey;
int buffersize = 1024;
char *buffer = new char[buffersize];
RegOpenKeyEx (HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Microsoft SQL Server\\100",NULL,KEY_READ,&hKey);
RegQueryValueEx(hKey,"VerSpecificRootDir",NULL,NULL,(LPBYTE) buffer, buffersize);
std::cout << buffer;
RegCloseKey (hKey);

I currently only know how to do that by using the Qt framework:
QSettings settings("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\100\");
QString dir = settings.value("VerSpecificRootDir");
Qt is free and allows you to use simple and very good documented c++ APIs instead of the mixed and up Windows APIs. Sorry - that sounds for advertising... but I formerly struggled with the very bad designed Windows API and than found Qt, which allows me to develop faster and (a cool benefit) for multiple platforms without having to adapt my code.
Regards,
Chris

You can sure use ATL::CRegKey. It has all the functionality you need.
http://msdn.microsoft.com/en-us/library/xka57xy4(VS.80).aspx

Registry API was available (for ~15 years) from Windows 95 onwards. It's all well documented on MSDN ; and if you care to Google so many examples.

Related

Is there a way to save raw binary data from a registry call to a string without casting it as a string?

I'm working on an utility to hook various bits of the Windows API used by different applications. The aim of the project is, at the moment to make any application portable by redirecting filesystem and registry calls to custom locations using easyhook and boost (specifically the property_tree library).
I'm currently working on the registry part of the project and I have successfully created analogues to the RegCreateKey(ExA/ExW/A/W), RegOpenKey(ExA/ExW/A/W) and RegCloseKey functions and they work fine (i made a virtual handle system to create and translate hKey handles). They work by basically translating everything to strings and saving them in a boost property tree (and then writing the tree to an .info file).
I started working on the RegSetValue and RegQueryValue functions, the ones that actually handle the data and encountered a major problem. Below are the two functions. Note that these are called by easyhook with the same parameters of the original winapi call.
LSTATUS WINAPI myRegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, const BYTE* lpData, DWORD cbData)
{
boost::property_tree::ptree VirtualRegistry;
boost::property_tree::read_info("VirtualRegistry.info", VirtualRegistry);
VirtualRegistry.put(boost::property_tree::ptree::path_type(std::string(GetPathFromHandleA(hKey) + '\\' + lpValueName), '\\'), reinterpret_cast<const char*>(lpData));
boost::property_tree::write_info("VirtualRegistry.info", VirtualRegistry);
return ERROR_SUCCESS;
}
This works fine for REG_SZ calls but other types of data are not saved correctly.
LSTATUS WINAPI myRegQueryValueExA(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
{
boost::property_tree::ptree VirtualRegistry;
boost::property_tree::read_info("VirtualRegistry.info", VirtualRegistry);
try
{
*lpData = reinterpret_cast<const BYTE*>VirtualRegistry.get_child(boost::property_tree::ptree::path_type(std::string(GetPathFromHandleA(hKey) + "\\" + lpValueName), '\\')).data();
return ERROR_SUCCESS;
}
catch (const boost::property_tree::ptree_bad_path& e1)
{
std::cout << "\n" << "ENTRY NOT FOUND" << "\n";
return ERROR_FILE_NOT_FOUND;
}
}
This does not work. The reinterpret cast on line 6 is invalid and it won't compile.
The problem is the way my functions handle different types of data. A registry call can have many different value types and the way I wrote myRegSetValue only seems to work for REG_SZ. I will also have to save the value type when writing the call to the file but that does not solve the problem.
So my question is, is there any way of saving the raw data of a call, as a string, without having to cast it as a string, so that it works for all types of data, and then reading it back from the file from a string back to raw data and passing it to the application?
I guess I could write a separate interpreter for each key type but i would really rather not because it would be very hacky and also would break applications that do not use the registry API correctly and store invalid values in the registry (like, for example, the Unity game Sunless Sea).
Thank you, I hope I explained this in enough detail.
It appears that the real problem is already the implementation of myRegSetValueExA. When you get lpData, you can't assume that it points to data that will remain valid. You must store not the pointer, but the pointed-to data.
That's also why cbData is necessary; you need to know how much data to store. You can't rely on strlen since the type might not be REG_SZ.
Note that your assumption about This works fine for REG_SZ is true only because VirtualRegistry.put(std::string key, const char* value) is a convenient overload which calls strlen(buf) for you.
The solution is to create explicitly std::string data(static_cast<const char*>(lpData), cbData) and use that in the put. To retrieve it, you use .get<std::string>(key) instead of get_child(key).data().

The equivelant code %SystemDrive% in batch translated into C++

To anyone that can help Please,
(My operating system is Windows XP)
I have looked on the this forum but have not found a similair answer that I could use or adapt to suite this particular situation. I will try to explain (I apologise in advance if my question seems confusing)
I am constructing a batch file that will call a C++ program (.exe) The C++ program is hard coded to the C: drive. By the way I did not write the C++ program as I am incapable of writing in C++ but would like to exchange the C: in C++ for what would be in batch %SystemDrive%. The line of code in C++ reads as follows:
SetSfcFileException(0, L"c:\\windows\\system32\\calc.exe",-1);
// Now we can modify the system file in a complete stealth.
}
The bit of code I would like to alter in the above code is C: or "C" to change it to %systemDrive% but in C++ code language, in effect change the hard coded part of the C++ program to read a System path variable within XP.
I have also looked elsewhere on the net but have not found a suitable answer as I do Not want to break the C++ code you see.
The C++ code was obtained from the folowing website written by Abdellatif_El_Khlifi:
https://www.codeproject.com/Articles/14933/A-simple-way-to-hack-Windows-File-Protection-WFP-u
Many Thanks for any help given,
David
The search term you should be looking for is Known Folders.
Specifically, calling SHGetKnownFolderPath() with the FOLDERID_System identifier, one of the many IDs found here.
That's for Vista or better. For earlier than that (such as XP), you have to use CSIDL values, CSIDL_SYSTEM (see here for list) passed into SHGetFolderPath().
You can still use the pre-Vista ones but I think they're just thin wrappers around the newer ones.
This is the simplest console application I could come up with that shows this in action (Visual Studio 2019):
#include <iostream>
#include <shlobj_core.h>
#include <comutil.h>
int main()
{
PWSTR path = NULL;
HRESULT hr = SHGetKnownFolderPath(FOLDERID_System, 0, NULL, &path);
_bstr_t bstrPath(path);
std::string strPath((char*)bstrPath);
std::cout << "Path is '" << strPath << "'\n";
}
and the output on my system is:
Path is 'C:\WINDOWS\system32'
This is not really answering my own question, well it is but in a alternative manner, many ways to skin a cat so to speak!
Here is one encouraging bit of news though I have stumbled across the very thing I need called WFPReplacer, it is a commandline windows utility that pretty well does what I want & generally in the same manner. it disables WFP for both singular files & can be used for wholesale switching off of WFP if the right file is replaced. All I need to do is write a batch file as a front end to back up the system files I want to disable use WFPReplacer.exe. So if in the event of the proceedings the routine gets stuffed I can revert back to the backed up files. I think this program uses the same type of embedded coding but is written in Delphi/pascal, it is called Remko Weijnen's Blog (Remko's Blog) "replacing Wfp protected files".
I generally like to leave whatever I am doing on a positive note. So just in case someone else lands on this forum & is trying to accomplish a similair exercise here is the code that one can compile (This is not my code it belongs to Remko Weijnen's Blog (Remko's Blog)) Please be advised it is NOT C++ it is a commandline exe Delhi/Pascal found at this link, so all credits belong to him. The link is:
https://www.remkoweijnen.nl/blog/2012/12/05/replacing-wfp-protected-files/
DWORD __stdcall SfcFileException(RPC_BINDING_HANDLE hServer, LPCWSTR lpSrc, int Unknown)
{
RPC_BINDING_HANDLE hServerVar; // eax#2
int nts; // eax#6
__int32 dwResult; // eax#7
DWORD dwResultVar; // esi#9
int v8; // [sp+8h] [bp-8h]#1
int v9; // [sp+Ch] [bp-4h]#1
LOWORD(v8) = 0;
*(int *)((char *)&v8 + 2) = 0;
HIWORD(v9) = 0;
if ( !hServer )
{
hServerVar = _pRpcHandle;
if ( !_pRpcHandle )
{
hServerVar = SfcConnectToServer(0);
_pRpcHandle = hServerVar;
if ( !hServerVar )
return 0x6BA; // RPC_S_SERVER_UNAVAILABLE
}
hServer = hServerVar;
}
nts = SfcRedirectPath(lpSrc, (int)&v8);
if ( nts >= 0 )
dwResult = SfcCli_FileException((int)hServer, v9, Unknown).Simple;
else
dwResult = RtlNtStatusToDosError(nts);
dwResultVar = dwResult;
MemFree(v9);
return dwResultVar;
}
Also as one further warning (Unless you know what you are doing!!!) do not attempt to use this program, ALWAYS ALWAYS ALWAYS backup your system files before deletion or alteration.
What this program will do is disarm WFP for 60 seconds whilst you intercange or amend your files. Example usage for example is:
WfpReplacer.exe c:\windows\Notepad.exe (Errorlevel true or false will be produced on execution).
Best Regards
David

How to get the full path to the Windows Explorer in C++

Can I safely assume that Windows Explorer is always started from a Windows system directory? Also, is its process always named "explorer.exe"?
And if not, how to get its full file path?
EDIT: Forgot to mention -- I need this to later find out the process ID of the Windows Explorer running in a given user session. Thus my search for its full path.
EDIT 2: Thanks everyone who contributed, and especially to sehe! After his post I found this page that explains how to set up your own shell. I made a wild test by completely replacing explorer.exe with my own process and here's the result:
Here's the full-size link if you it gets re-sized.
As you can see, I can technically replace explorer.exe with whatever process I may come up with. As you can also see in my screenshot Windows gives me a complete control over the Shell (the screenshot is my entire window.)
So the bottom line, the only way to get "explorer.exe" file path (or whatever Shell process is used) is to use those registry keys from the link I quoted above -- pretty much close to what sehe suggested, with just a few more checks to do, but it's a pretty straightforward stuff.
As for Sean Cline's suggestion, it would be a very elegant solution ONLY if we have the "stock" Windows Explorer running that comes with a tray window with that specific class name.
It is probably safe to assume that explorer.exe is always in the %windir% or %SystemRoot% as it hasn't moved for years. But, if you are trying to invoke something via Explorer, chances are you want to use the ShellExecute() function instead.
If you really do need the path, the easiest way to get it is probably with a call to SHGetKnownFolderPath() using FOLDERID_Windows as the first argument.
Edit:
Here is my stab at some code knowing that you are looking for the PID of the shell process:
DWORD trayPID;
HWND trayWnd = FindWindow("Shell_TrayWnd", NULL);
GetWindowThreadProcessId(trayWnd, &trayPID);
It looks for the hWnd of the taskbar and finds the owning PID. You will likely need to add some error handling for the case that explorer is not running and that window does not exist - unlikely, but possible.
No you can't safely assume that and none of this has to do with C++.
Also, you didn't show any code. Here goes:
The registry key for this is Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Shell (see here).
#include <windows.h>
#include <malloc.h>
#include <stdio.h>
#include <string>
LONG GetStringRegKey(HKEY hKey, const std::wstring &strValueName, std::wstring &strValue, const std::wstring &strDefaultValue)
{
strValue = strDefaultValue;
WCHAR szBuffer[512];
DWORD dwBufferSize = sizeof(szBuffer);
ULONG nError;
nError = RegQueryValueExW(hKey, strValueName.c_str(), 0, NULL, (LPBYTE)szBuffer, &dwBufferSize);
if (ERROR_SUCCESS == nError)
{
strValue = szBuffer;
}
return nError;
}
int main()
{
HKEY hKey;
LONG lRes = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon", 0, KEY_READ, &hKey);
bool bExistsAndSuccess (lRes == ERROR_SUCCESS);
bool bDoesNotExistsSpecifically (lRes == ERROR_FILE_NOT_FOUND);
std::wstring shell;
GetStringRegKey(hKey, L"Shell", shell, L"");
}
Yes to both. Windows Explorer is always located at %WINDIR%\Explorer.exe.

Getting application version from within application

Is there a simple way of obtaining the application version information from the resource file at runtime?
Effectively what I'd like to do is be able to have a "Version X.Y.Z" displayed at runtime without having a separate variable somewhere that I'd have to keep in sync with my ProductVersion and FileVersion.
To clarify: yes this is a standard C++ Windows project. I am aware of the GetFileVersionInfo method but it seems silly to have to open the binary from within the version in memory just to query the version information - I'm sure I'm missing something obvious here :-)
If the OS is Windows, use the GetFileVersionInfo and VerQueryValue functions.
I don't believe that there's an easier way (than opening the file and using GetFileVersionInfo and VerQueryValue). I use the following code, in case it's helpful:
static CString GetProductVersion()
{
CString strResult;
char szModPath[ MAX_PATH ];
szModPath[ 0 ] = '\0';
GetModuleFileName( NULL, szModPath, sizeof(szModPath) );
DWORD dwHandle;
DWORD dwSize = GetFileVersionInfoSize( szModPath, &dwHandle );
if( dwSize > 0 )
{
BYTE* pbBuf = static_cast<BYTE*>( alloca( dwSize ) );
if( GetFileVersionInfo( szModPath, dwHandle, dwSize, pbBuf ) )
{
UINT uiSize;
BYTE* lpb;
if( VerQueryValue( pbBuf,
"\\VarFileInfo\\Translation",
(void**)&lpb,
&uiSize ) )
{
WORD* lpw = (WORD*)lpb;
CString strQuery;
strQuery.Format( "\\StringFileInfo\\%04x%04x\\ProductVersion", lpw[ 0 ], lpw[ 1 ] );
if( VerQueryValue( pbBuf,
const_cast<LPSTR>( (LPCSTR)strQuery ),
(void**)&lpb,
&uiSize ) && uiSize > 0 )
{
strResult = (LPCSTR)lpb;
}
}
}
}
return strResult;
}
David
The only officially supported approach is to use GetFileVersionInfo() and VerQueryValue(). However, as you have noticed, GetFileVersionInfo() requires you to pass in the filename of the executable. There is a reason for this. Although it is simple to obtain the running process's filename using GetModuleFileName(), it is not the most efficient option, especially if the executable is running from a remote share, and it is not even guaranteed to be accurate if the executable has been modified on the HDD after the process has started running.
You can access the version info of the process that is already running in memory, by calling FindResource() to locate the process's RT_VERSION resource, then use LoadResource() and LockResource() to obtain a pointer to its data. It is tempting to then pass that pointer as the pBlock parameter of VerQueryValue(), but beware because doing so can crash your code! If you access the RT_VERSION resource directly then you are better off not using VerQueryValue() at all. The format of the RT_VERSION resource is documented, so you can parse the raw data manually, it is not very difficult.
As already said there is no easy way.
You can find here a great working example (ATL free).

Windows folder password

I have been thinking to implement the following program, just out of curiosity and learning experience. I want to write a program for password protecting a folder, so you can only open the folder after entering the correct password. I know this is specific to the operation system, so let it be Windows. I guess this is only possible in C++, but if it is also possible in plain C# or Java(which I doubt), then please tell me.
Could someone point me in the right direction? Thanks in advance!
Best regards, Petar
If you want a bulletproof protection of your files, then just protecting access to the folder is not enough, you'd have to encrypt them and there're secure containers and file system encyptions on the market.
If it does not need to be high security, you can hook into Windows I guess. You'll especially need to hook into the directory listing functions, like FindFirstFile, FindNextFile and OpenFile also probably (and into their derivates like FindFirstFileW) and maybe some others.
You do that by redirecting calls to kernel32.dll to your custom functions, see a little code example below which I found on the internet:
unsigned char Store[10];
//redirect FindNextFileW to your custom function
void HookAPI()
{
DWORD OldProtect, NewProtect = PAGE_EXECUTE_READWRITE;
HMODULE hmod = GetModuleHandle("Kernel32.dll");
long pa = (long)GetProcAddress(hmod,"FindNextFileW");
long pa2 = (long)MyFindNextFile;
long dAddr = pa2 - pa - 5;
unsigned char *p = (unsigned char *)pa;
unsigned char *p2 = (unsigned char *)(&dAddr);
VirtualProtect((void *)pa,5,NewProtect,&OldProtect);
for (int i=0;i<5;i++)
Store[i] = p[i];
p[0] = (unsigned char)0xE9;
for (int i=0;i<4;i++)
p[i + 1] = p2[i];
VirtualProtect((void *)pa,5,OldProtect,&NewProtect);
}
void UnHookAPI()
{
DWORD OldProtect, NewProtect = PAGE_EXECUTE_READWRITE;
HMODULE hmod = GetModuleHandle("Kernel32.dll");
long pa = (long)GetProcAddress(hmod,"FindNextFileW");
unsigned char *p = (unsigned char *)pa;
VirtualProtect((void *)pa,5,NewProtect,&OldProtect);
for (int i=0;i<5;i++)
p[i] = Store[i];
VirtualProtect((void *)pa,5,OldProtect,&NewProtect);
}
BOOL WINAPI MyFindNextFile(HANDLE hFindFile,LPWIN32_FIND_DATAW lpFindFileData)
{
UnHookAPI();
BOOL ans = FindNextFileW(hFindFile, lpFindFileData);
//your logic here, display password prompt to user e.g.
HookAPI();
return ans;
}
What you want to do can also be done with Java (JNI) or C# (pinvoke), but it'd be a real detour. I'd use something which can be compiled to native code.
Edit:
Aoi Karasu provided a link to a post which suggests to use a FileSystemFilterDriver, which is probably the best concept to realize the application in question.
An idea from the top of my head for a "simple" implementation.
The idea is to use windows authentication to create such protected folders.
Your application can generate a user for each encrypted folder F.
So for folder Fi you will generate user Ui with password Pi.
Also, for each Fi your application will have to make sure that ONLY Ui have access to it, and that no one can add access to it. Also, encrypt the files using window's encryption in NTFS.sys (there should be a simple function to encrypt the files in windows API, can't remember its name).
Now, if someone wants to access Fi you will popup a messagebox asking for the password, if they are right (you can use AccessCheck()) you can open explorer with Ui credentials pointing to Fi OR add Ui credentials to the user (in this case you will have to remove them at some point, so it could be tricky).
Windows (NTFS) supports "junction points". These are entries in the file system that tell Windows to execute a bit of code. A common type of junction point is the hardlink to another file or folder. However, you can add other types with matching drivers.
In your case, your encrypted folders could really be junction points that work like secured hardlinks. Yo only resolve the hardlink for authorized users. Because this works at NTFS kernel level, you don't need to worry about the million different file functions that exist in the different layers of Windows.