C++:Browser set to default browser on windows 8/10 - c++

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.

Related

CreateFile to open an MS-DOS device created in another terminal session

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.

Monitor registry using C++

I want to monitor when a key is changed/added/deleted to the registry whenever application is being installed or removed. I have tested the sample code from the msdn(link) and it works fine.
But the problem is that it does not tell me which key has actually been modified/added/deleted. How can i retrieve this information using c++?
There are only 3 ways, none of which is both easy and adequate:
RegNotifyChangeKeyValue:
Doesn't give you the info you need, but is very easy to use.
EVENT_TRACE_FLAG_REGISTRY which is part of Event Tracing for Windows
which is what ProcMon uses. It works well, but it's quite difficult to use.
I'm not sure exactly how to use it myself, but if I figure it out I'll post it here.
CmRegisterCallback:
Requires kernel-mode driver, which is a pain in 64-bit.
But it's the most perfect solution otherwise.
Unfortunately Event Tracing for Windows (EWT) does not allow to see full key path in the event. You get only a partial key name and a strange handle with is actually a key control block. It's not so simple to get information from this block.
Yes the process monitor uses EWT, but it does not use Windows Kernel Trace as a provider.

How to find out if hibernation is available for a Windows user (with C++)

I know that one can call the following API to hibernate the system:
SetSuspendState(TRUE, FALSE, FALSE);
But is there any way to find out if "real" hibernation is available for the current Windows user?
Here's what I mean:
If an admin calls:
powercfg.exe /hibernate off
the API above will put system into a Sleep mode. So how do you know (from a C++ program) that this will happen instead of hibernation?
I'm not sure if there's a group policy that can prohibit a user from hibernating a computer connected to an Active Directory?
Edit I am aware of the (dated) IsPwrHibernateAllowed API. I find that it doesn't work: it still returns the same result even if powercfg.exe /hibernate off was called. Am I doing something wrong there? Can someone explain why IsPwrHibernateAllowed doesn't work for me?
Take a look at SYSTEM_POWER_CAPABILITIES structure that can be obtained with CallNtPowerInformation. Specifically, look at HiberFilePresent field.

Name mapping -- \\.\PhysicalDrive to \\.\SCSI

I'm developing in windows with C/C++ and I want to know is it possible to get an apropriate \\.\SCSI device name by \\.\PhysicalDrive ?..
For example, it's wonderful to know how to get that \\.\PhysicalDrive0 is the same that \\.\SCSI0.
Look at the code which I posted in my answer to the question. The author of the question had changed the text of the question so many time and the last version of text clear nor really what the original problem was.
In the example, which C source code you can download here, I show how to get many kind of information about the local drive using different Windows API. The important thing which you need is that some name conversion like DeviceType and DeviceNumber (received by IOCTL_STORAGE_GET_DEVICE_NUMBER) like the following
DeviceType: 7, DeviceNumber: 5, PartitionNumber: 1
are unique in the operation system and can be used to identify the same devices. The reference to the statement you can find in the documentation of IOCTL_STORAGE_GET_DEVICE_NUMBER control code:
The values in the
STORAGE_DEVICE_NUMBER structure are
guaranteed to remain unchanged until
the device is removed or the system is
restarted. It is not guaranteed to be
persistent across device restarts or
system restarts.
In the way you can compare \\.\SCSI0 devices and \\.\PhysicalDrive0 and find out the correspondence.

Repairing a "disconnected" windows drive mapping

Sometimes a network drive that is already mapped to a drive letter because "disconnected". Using the normal Windows functions to access files / folders on that drive fail. As soon as the user manually clicks on that drive it the Windows Explorer dialog, it's magically repaired.
Since my program is a batch program I'd like to start this "magic" from my program (C++) but I haven't found a Windows function for that. There's nothing in the usual WNet... functions...
NET USE V: /DELETE
NET USE V: "\\server1\videos"
NET USE L: /DELETE
NET USE L: "\\server2\archive"
When the path is inserted, you could check to see if it is a network resource and before opening files, use WNetGetConnection() to get the network resource.
You could also try to use WNetRestoreConnectionW(), which seems to have more spurious support, depending on the environment.
Try re-connecting to the share via net use:
net use \\server\folder [/user:[domain\]username] [password]
If that doesn't work, you can net use /delete it first, then re-connect.
Isn't this what WNetAddConnection and WNetAddConnection2 are for?
I suspect that is really the same thing, though. Explorer probably caches the connection info somewhere in the registry. When the user tries to go to that drive Explorer sees that the mapping is disconnected, reads the connection info from the registry, and re-creates the connection. Maybe you could try running regmon while you create a drive mapping and see if you can figure out where and how the connection information is cached.
I had trouble with this at a client of mine not long ago. I don't know if it's possible in your situation, but our fix was to tweak the Server's network settings to stop the timeouts and disconnects. See MSKB 297684 for details.
I agree with the comment from CMB, above. I've been down this path (excuse the pun) in the past and it caused me no end of trouble.
If the path is user configurable, they could use m:\pathonserver or they could use \server\c\pathonserver.
It shouldn't make any difference to your code, opening a file as m:\blahdeblah.dat or \server\c\blahdeblah.dat will be identical.
Using the UNC path is far more reliable, Windows will reconnect to that path automatically whether or not the mapped letter is there.
If you map a drive to a network
share, the mapped drive may be disconnected after a regular interval
of inactivity, and Windows Explorer may display a red "X" on the icon
of the mapped drive. However, if you try to access or browse the
mapped drive, it reconnects quickly.
To avoid this behavior use the following command:
net config server /autodisconnect:-1
Explanation of Microsoft on this topic:
https://support.microsoft.com/da-dk/help/297684/mapped-drive-connection-to-network-share-may-be-lost