I am trying to get a handle to the Registry hive "\REGISTRY\A{GUID}" and enumerate the keys under that handle. I been searching for hours but still hasn't got a clue on how to open or enumerate it.Please help me get to the correct API to do so. Btw, RegOpenKeyEx() and RegEnumKeyEx() doesn't work, I tried.
Applications with handles for "\REGISTRY\A\{GUID}" paths have either called RegLoadAppKey or NtLoadKeyEx. RegLoadAppKey loads a private application hive at an automatically generated path, "\REGISTRY\A\{GUID}". It returns a handle for the hive's root Key, and subkeys can be enumerated, created and opened relative to this handle.
It used to be possible to open "A" relative to a handle for "\REGISTRY" and enumerate its subkeys. This is no longer allowed in Windows 10. I assume access is restricted in the Configuration Manager's parse procedure for Key objects, CmpParseKey. However, you can still inspect this Key using a kernel debugger with commands such as !reg q \REGISTRY\A.
Related
I am creating process using create process does anyone knows how to use create function if process is already running not create or externally having any other way to detect process is running.
On Windows, you use the Process Status API (PSAPI) to search through all the processes running on the system. The degree of access you have to this resource will depend on the privileges that the program is running under.
See the MSDN article
Specifically, you would invoke the EnumProcesses function to get a full list of the running processes IDs, then, using those IDs use other functions in the API to get information about them. For example, to get a processes name, and have it's ID already, you could call GetProcessImageFileName.
Beware that these functions have ASCII and Wide-character versions.
I'd like to set a program as the 'default browser', so that for example, it'll be opened when addresses like http://google.com/ are opened by another program or Windows.
At first I assumed this was the same as XP/7 (via HKCR), but I found that you need to use the Default Programs feature of win8[+]. The relevant key is stored I think, at [HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice]"Hash"="/9CPwAgPN4s=" "Progid"="IE.HTTPS".
But I don't know how to generate the hash keys.
Any information about how other programs do this or just hints in the right direction is greatly appreciated.
I have a Windows service written in C++ that needs to access the clipboard and read data from/paste data to it. I'm considering only textual data.
From MSDN's documentation, I can use OpenClipboard, EmptyClipboard and SetClipboardData to achieve what I want to.
I would have to pass NULL to OpenClipboard since I don't have any UI and hence no window handles. However, this would mean -
If an application calls OpenClipboard with hwnd set to NULL, EmptyClipboard sets the clipboard owner to NULL; this causes SetClipboardData to fail.
which would mean I can't set data on the clipboard.
What would be the correct way to get around this problem? Is it possible without using any windows?
You definitely CAN access the clipboard from a non-GUI application. Windows even included a command-line app (clip.exe) to do it.
However, before you spend too much time working on this......
The clipboard isn't shared among users on the same system. Suppose you have two users logged in. You can't copy data from one session, switch users (from the lock screen) and paste that same data.
So presumably, your service would act like another user session, and your app would only be able to see data that was copied earlier within that same instance of the service.
My app needs to write and maintain a log file and its not running in admin mode. My question is what path could my app write to in such a situation. How could I obtain that path ?
There are two good options:
Use the Windows Event Log. You can easily create your own log for your application (if you expect to generate a lot of messages), or you can just add the messages to the standard logs (if you expect to generate only a few, occasional messages).
Since this is a built-in feature, any technical person is going to know about it and be able to locate your log files easily. It's also very interoperable with centralized management systems.
Write to a text file saved in the Application Data directory. This is where applications are supposed to store non-user data files, since, as you mentioned, the application directory is not something you can assume write privileges to.
For a log file about stuff that is specific to a particular computer, I'd say that this is local (non-roaming) application data, so you want the Local App Data folder. I'm sure that there is a Qt wrapper for this, but in Win32, you would call the SHGetKnownFolderPath function, specifying the KNOWNFOLDERID value FOLDERID_LocalAppData.
Remember that this function allocates memory to store the returned string—you must free it with a call to CoTaskMemFree when you are finished.
Sample code:
// Retrieve the path to the local App Data folder.
wchar_t* pszPath = 0;
SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &pszPath);
// Make a copy of that path.
std::wstring path(pszPath);
// Free the memory now, so you don't forget!
CoTaskMemFree(static_cast<void*>(pszPath));
Refer to the SHGetKnownFolderPath API, probably using the FOLDERID_LocalAppData option.
I have a (sort of a filter) driver that should communicate with user-mode components. It creates a device object by calling IoCreateDevice, and then it creates a so-called MS-DOS symbolic link for it by IoCreateSymbolicLink, to make it possible to access it from user-mode code (by CreateFile). This is a standard technique more-or-less. The driver creates a symbolic link of the form \DosDevices\mydevicename, whereas the user-mode code opens a file named \\.\mydevicename.
Now, the problems start when the driver creates a device in the context of a terminal server session. The created symbolic link actually belongs to the local session directory, whereas my user-mode service runs under system account in "zero session", and it "sees" symbolic links that belong to global directory.
It's mentioned in the documentation that usually there's no problem, because drivers mostly create device objects in the context of DriverEntry or AddDevice functions, which are guaranteed to run under system account. But my case is different. And I don't want to change this, what I really need is to be able to create/destroy device objects in the context of arbitrary thread, belonging to any session.
According to the documentation there's a way to solve this. The driver may insist to create a symbolic link belonging to the global directory, by naming it this way: \DosDevices\Global\mydevicename. Moreover, if the user-mode code happens to run under some account, it may also insist to look for the link in the global directory, by naming the file this way: \\.\Global\mydevicename. Though this is not required usually, if the symbol doesn't exist in local directory, it's automatically checked in the global directory.
I've tried this trick: it doesn't work for me. I'm using Windows 2008R2, 64-bit. No success so far. I'm consistently able to open devices created in the system account, but unable to open devices created in another sessions (the error code is "file not found"). I've tried all the combinations and variations of specifying \Global in kernel/user mode - so far the result is the same.
This makes me suspect that there's one more level of symbol isolation. Perhaps using \Global creates a symbolic link that is global session-wide, but still not system-wide.
Does this make sense? Is there a way to create a system-wide symbolic link? Or is there a way to open a file whose symbolic link belongs to another session?
EDIT:
Thanks to #Hans Passant. I've tried WinObj utility to actually see which devices and symbolic links the driver actually creates.
Everything seems ok at the first glance. I see all my devices under \Device directory, and all the symbolic links are under \GLOBAL??. Symbolic links point to correct device names.
One thing is weird however. Trying to see the device properties from within WinObj: for devices created in zero session this works ok, but for devices created in other sessions WinObj responds with an error:
Error opening \Device\mydevicename: The system cannot find the file specified.
So, it displays this device object in its list, but OTOH it's "not found" when trying to open it.
Very strange. But this explains my problem. But this is really strange.
Any ideas? Thanks in advance.
There is a \Sessions\N\DosDevices\ path, where N is a session number. I didn't try that but it should work.
Also I noticed that subst and network drive mapping create symbolic links in \Sessions\0\DosDevices\ID\, where ID is a session id. So you can check that path too.