How to run x64 bit version of registry from cmd.exe located under c:\windows\sysWow64

windows-command-promptwindows-registry

I have a 32 bit application which has to add a value to x64 bit portion of the registry.

I want to do it through utilization of regedit.exe -s fileWithKeys.reg, However when I try to span regedit (in the code of the application, I utilized C:\windows\sysnative directory) then I get 32 bit version. I need to span x64 bit version of the tool (regedit) in order to add these keys to proper x64 bit node.

I found out that I can simulate this by running C:\Windows\SysWOW64\cmd.exe and calling C:\Windows\regedit.exe from there. I am not able to run 64 bit version because it seems to run the 32 bit version of regedit instead.

Is there a way to do it ?

Best Answer

In 64-bit Windows, there exists what are called file system and registry redirection. These exist for compatibility with older applications that were written for 32-bit Windows and for applications designed for older versions of Windows. WoW64 hooks all system calls made by 32-bit processes, such that if my 32-bit application running on a 64-bit version of Windows calls C:\Windows\System32, WoW64 will transparently redirect it to C:\Windows\SysWoW64, etc.. The C:\Windows\Sysnative virtual directory points you to the native version (the 64-bit version) of the directory, regardless of the bitness of the thread referencing that file system path.

A similar mechanism exists for the registry, which is what the WoW6432Node key is all about. Technically I would call these 32-bit and 64-bit views of the registry if I wanted to be concise... Or pedantic.

I wrote some code (in C#) not too long ago for accessing a key in the native (64-bit) portion of the hive from within a 32-bit process. Here's an abridged snippet:

// Accessing 64-bit registry key from 32-bit process
enum RegAccessFlag
{
    NONE                   = 0,
    KEY_QUERY_VALUE        = 0x0001,
    KEY_SET_VALUE          = 0x0002,
    KEY_CREATE_SUB_KEY     = 0x0004,
    KEY_ENUMERATE_SUB_KEYS = 0x0008,
    KEY_NOTIFY             = 0x0010,
    KEY_CREATE_LINK        = 0x0020,
    KEY_WOW64_64KEY        = 0x0100, // This is the ticket
    KEY_WOW64_32KEY        = 0x0200,
    KEY_WOW64_RES          = 0x0300
}

public static UIntPtr HKEY_LOCAL_MACHINE = new UIntPtr(0x80000002u);

[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int RegOpenKeyEx(UIntPtr hkey, string subKey, int ulOptions, int samDesired, out UIntPtr hkResult);

static void Main(string[] args)
{
    int statusCode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE", 0, (int)RegAccessFlag.KEY_WOW64_64KEY | (int)RegAccessFlag.KEY_QUERY_VALUE, out hKey);
}

Of course you still need to read a value from the key once you've opened it, or create a new value, then remember to close the key once you're finished, but that would get you started if you cared to write any code.

But since you are talking about spawning a 32-bit process from another 32-bit process, so that child process can access the native view of the registry, on a 64-bit platform... you're dealing with a combination of both file system redirection and registry redirection both getting in your way. And to top all that off, regedit.exe is a bit of a special utility in this regard.

TL;DR: Give C:\Windows\sysnative\regedt32.exe a try instead of regedit.exe.

https://stackoverflow.com/questions/12233396/open-64-bit-regedit-from-32-bit-application