Reading registry value on windows with QSettings - windows

I'm trying to read MachineGuid key from windows registry using QSettings.
The address to that key is
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography".
I'm using the QSettings with QSettings::Native flag as follows.
QSettings settings("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography",QSettings::NativeFormat);
I can see all the subfolders and their keys and the value of MachineGuid from regedit.exe but the value function of QSettings does not seem to be working correctly.
the results are as follows:
settings.value("MachineGuid").toString();
returns empty QString.
settings.childGroups();
returns all the subfolders of Cryptography folder correctly.
settings.childKeys();
returns an empty QStringList
settings.allKeys();
returns all the keys inside Cryptography folder including the keys inside of all subfolders except for MachineGuid which is placed inside Cryptography.
I'm using Qt 5.7.1 built statically using Visual Studio 2015 on Windows 10.
I have tried codes that use Window.h header and I have successfully extracted the value but the problem with this approach is that I have to add lots of DLLs to my released software.

For accessing 64 Bit Windows OS with 32 Bit compiled code, the right format would be "Registry64Format" and if accessing 32 Bit OS from 64 compiler the the right format is "Registry32Format"
So, in my case, after setting format to 64 bit, the key could be fetched.
to read key "MachineGuid" on 64 bit OS with 32 bit Compiled code;
QSettings settings("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography",
QSettings::Registry64Format);
auto key = settings.childKeys().at(0);

Related

Merging PDF with pdfforge.dll in VBA on Windows x64

So I'm working around a macro that should merge some pdf. The code is pretty simple and work well using a dll given by PDFCreator setup (pdfforge.dll), but only on Windows 32Bits (XP or 7).
Here is the code
Dim Pdf As Object
Set Pdf = CreateObject("pdfforge.pdf.pdf")
Pdf.MergePDFFiles_2 FR1, Target & "FusionFR1.pdf", True
Pdf.MergePDFFiles_2 FR2, Target & "FusionFR2.pdf", True
Pdf.MergePDFFiles_2 FR3, Target & "FusionFR3.pdf", True
Pdf.MergePDFFiles_2 FR4, Target & "FusionFR4.pdf", True
Note that FR1, FR2, FR3 and FR4 are just some array of string which contains the path of those pdf I'm trying to merge.
So as I said, this code work well on any computer with Windows 32 Bits, as long as the version of PDFCreator provide the pdfforge.dll. But on a Windows 64 Bits, I've got an "Excel Automation Error" on
Set Pdf = CreateObject("pdfforge.pdf.pdf")
I guess this is a dll which work only on a 32 bits system and by default, a windows 64 bits try to work through a 64 bits environment. So I tried to register this dll for the 32 bits environment through two methods without having satisfying result :
Register 32 bit COM DLL to 64 bit Windows 7
http://www.gfi.com/blog/32bit-object-64bit-environment/
Hope you guys could help me :)
PS: I'm working on Excel 2007
Well I managed to make it work !
I mainly use the Assembly Registration Tool, regasm.exe
First, I've made sure that the dll was not registered anywhere, that is to say both in Framework 32 Bits and 64 Bits, using regasm.exe with the /u argument.
Then I registered the dll in framework\v2.0.50727 using the /codebase argument (I've read from multiple source this argument is the key)
Finally, I've created a text file named excel.exe.config in the root of the excel directory which contains
<?xml version="1.0"?>
<configuration>
<startup>
<supportedRuntime version="v2.0.50727"/>
</startup>
</configuration>
This should force excel to use framework v2.
Hope this could help someone one day ;)

Unable to retrive some regedit entries using *REG QUERY* command

I am using REG QUERY HKLM/SOFTWARE command to retrieve all installed soft wares,
but its not returning few of applications, what ever the application I needed is a 64 bit one.
OS:- Windows 7
Note:- When I use the command its returning the applications which are under [Wow6432Node] folder, but my application is not presented under this folder. Its present under [HKLM/SOFTWARE] location
Please help me to solve this problem.
This behaviour is due to the registry redirector. You are running the 32 bit version of REG, presumably because the process that invokes it is a 32 bit process. And so the 32 bit version of REG reads the 32 bit view of the registry by default.
You should use /reg:64 switch to force reg to use the 64 bit view of the registry, as described here: MS-KB-948698.
If you are doing this from a program then it's better to use the registry API to read entries than using the REG tool.

using RegCreateKeyEx gives error code 5

I used RegCreateKeyEx from a win32 application(VisualStudio 2008) in 64 bit windows(Project built with target x64). It was able to create a registry entry. Now I have a dll file (Project built with target x64) which too wanna create registry entry but my dll is returning error code 5(Yeah! its a sign of access denied). My samDesired flag have KEY_ALL_Access + In linker->manifestfile->run as administrator chosen which still fails with error code 5. Whereas it works perfectly in 32bit windows(Project built with target x86). Am i missing something?
NOTE: I'm trying to create an entry at HKEY_LOCAL_MACHINE.
You can't create a registry key in HKEY_LOCAL_MACHINE because this isn't a hive. You need to put your key in HKEY_LOCAL_MACHINE\Software or (less probably) one of the other hives.
I don't know why this appeared to work when you were running 32-bit code in WOW64, perhaps this is a side-effect of the way the 32-bit view of the registry is presented.

VB6 Registry Key Value Problem

Within VB6 I have used the following code to add to Registry,
Dim x As Object
x = CreateObject("WScript.Shell")
x.RegWrite "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell", "MADNESS"
It creates a key, however in the following location:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell
Instead of:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
Any help is appreciated.
It looks like it's because you have a 64-bit OS and you're running a 32-bit (x86) application which is handled by Windows'"Windows On Windows" (WOW) feature. Basically, it allows you to run an x86 program on an x64 Windows OS. x86 programs usually have their own registry key structure (ie. the Wow6432Node) and their own program files folder (ie. Program Files (x86)). You can try using something like this which uses WinAPI hooks. This may allow you to bypass the issue and write directly to the key you want. Though, I'm not sure if Windows has security measures in place that prevent x86 applications to write to x64 parts of the registry. (I can't see why it would.)
You can shell C:\Windows\System32\cscript.exe which is the x64 version.
FYI: The x86 version is C:\Windows\SysWOW64\cscript.exe
First off, I would stop using WScript.Shell and switch to this registry access class: http://www.planetsourcecode.com/vb/scripts/ShowCode.asp?txtCodeId=70915&lngWId=1
It's a little confusing to use at first, but it's solid and provides built-in support for accessing 64-bit registry entries rather than the re-directed Wow6432Node. You can do so simply by setting the desired access in the .Path method of the class. Here's an untested example:
Dim objRegistry as New UniRegistry
Dim objHKLMStartup as New UniRegistry
Set objHKLMStartup = objRegistry.Path([hKey Local Machine], "SOFTWARE\Microsoft\Windows\CurrentVersion\Run", [Registry: Read] + [Registry: WOW64 64-bit])
You can then use a For Each variant In objHKLMStartup to extract any/all values in the given registry path.

How do I read the registry in 32-bit c# app such that registry redirection works on 64-bit Windows 7

My boss just got Windows 7 and he tried running one of our installers which runs perfectly fine under XP. On Windows 7, the installer runs without giving any errors. However, it does not create registry keys under HKEY_LOCAL_MACHINE\SOFTWARE{Company}{product}. These keys get created correctly under XP.
Has anyone encountered this issue? I suspect it is a rights/security issue but I'm not sure and I don't have Windows 7 to experiment with.
EDIT
The computer in question is a 64-bit machine running 64-bit Windows. It turns out Windows 7 redirects 32-bit applications to HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node{Company}{product}. The problem is my application code tries to access the registry using a hardcoded value like this:
var t = Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\..., "ValueName", DefaultValue);
So, my new question is how do I access the registry such that the Windows 9 registry redirection will just work?
If you're using .NET 4, you can specifically request that your 32-bit (or 64-bit) process access the 64-bit view of the registry using the RegistryKey.OpenBaseKey method.
Cf. http://msdn.microsoft.com/en-us/library/microsoft.win32.registrykey.openbasekey.aspx
Here's an example that reads a value from the 64-bit view of the registry, even if it runs as part of a 32-bit process:
var hklm64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
var key = hklm.OpenSubKey(#"SOFTWARE\AcmeSoft\AnvilMaker 1.0");
var value = (string) key.GetValue("Blacksmith Name");
The RegistryKey.OpenBaseKey method also allows you to explicitly open a 32-bit view of the registry. This is useful if you're trying to go the other way around and access the 32-bit view of the registry from a 64-bit process and you don't want to explicitly add "Wow6432Node" to the registry path.
For example, today I needed to delete a sub-key tree in both the 32-bit and 64-bit views of the registry. Doing this in .NET 4 with a single registry path was easy:
foreach(var view in new[] {RegistryView.Registry32, RegistryView.Registry64})
{
var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, view);
hklm.DeleteSubKeyTree(#"SOFTWARE\AcmeSoft\SomeKeyWeNoLongerWant", throwOnMissingSubKey: false);
}
On a 64-bit version of windows, the above code will remove the following sub-key trees from the registry:
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\AcmeSoft\SomeKeyWeNoLongerWant
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\AcmeSoft\SomeKeyWeNoLongerWant
-Adam
After more digging I came across this link which describes the registry access rules for .NET applications. My program had initially been targeted for "AnyCpu" which causes the app to target the 64-bit registry even though Windows installed it under the Wow6432Node. By setting the target to "x86" my program "magically" started accessing the registry under the Wow6432Node. Go figure!
In the C Windows API this is done by setting the samDesired parameter in the RegOpenKeyEx call to KEY_WOW64_64KEY. This means that the lookup of the registry value will map onto the regular 64-bit entry, rather than the WOW32Node one. I can't see how you would achieve this in .Net though as the Registry class doesn't appear to support these operations, but maybe it's provided through a newer class?
Registry Reflection
Code Sample

Resources