It appears that specifying the KEY_WOW64_64KEY flag (reference) when accessing a registry key under 32-bit Windows XP has no effect - that is, no error is thrown, and the key is opened as if you hadn't had the flag set.
I know Windows 2000 throws an error when it encounters this flag.
I want to make sure my app is compatible with as many versions of windows (2k and later) as possible.
Is there a Microsoft reference that specifies each version of Windows' behaviour for this flag? In particular, I'd like something that validates my assumption that it has no effect at all on post-2k 32-bit Windows.
I can't speak to Windows 2000 or XP, but I know that on Vista and above, KEY_WOW64_64KEY opens the registry key in the 64bit registry if it's a 64bit OS and the 32bit registry if it's a 32bit OS.
According to this Windows page:
https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry-key-security-and-access-rights?redirectedfrom=MSDN
Both
KEY_WOW64_32KEY (0x0200)
KEY_WOW64_64KEY (0x0100)
will be ignored on 32-bit Windows.
And those flags are not supported on Windows 2000.
I have tested on Windows XP 32 bit, and it seems to work OK.
Also, you should usually be avoiding this key - WOW64 provides a pretty complete "illusion" to 32-bit apps; just write your app properly on 32-bit without this flag, and it will still work on WOW64. Don't try to use this flag (and other mechanisms) to be "64-bit compatible".
Related
I'm trying to debug a 32 bit program on 64 bit Windows 7.
So I use gflags to set the debugger for that app. I fill in the path of the application, and the one of the debugger. But when I start the application, WinDBG doesn't run.
The same configuration works on 32 bit Windows 7.
So, is it impossible to debug a 32 bit application on 64 bit environment?
For me this has always worked, even if I use the "wrong" architecture gflags.
However Windbg must be in the PATH, or you must include path when you specify the debugger to gflags.
UPDATE
This is an old question. Older versions of gflags used to store the settings in one of the locations:
HTML\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
or
HTML\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
Depending on which architecture you pick for gflags.exe, it will affect either 64 bit or 32 bit processes.
Apparently at some point (thanks, #Thomas Weller to point it out), Microsoft changed gflags behavior and now (November 2016) current version of gflags.exe writes to both 32-bit and 64-bit registry locations, irrespective of the architecture.
This is a bit of a problem, because I used to use to attach 32-bit debugger to 32-bit processes and 64-bit debugger to 64 bit processes with the same process name. Now I cannot use gflags for this. However the workaround is to directly modify registry keys under Image File Execution Options.
Old Answer
Processor architecture of gflags.exe actually matters. If you use 64-bit version of Windows Debugging tools and launch gflags.exe from there, it will affect behavior of 64-bit applications. Similarly, if you use 32-bit version of Windows Debugging Tools and launch gflags.exe, it will affect 32-bit applications.
32-bit and 64-bit versions could be installed side-by-side. Pay close attention on bitness of application you are debugging and use the same architecture of the debugger/tools.
Attempting to call SetupDiCallClassInstaller from a program compiled in 32 bit mode fails on 64 bit Windows.
Apparently this is by design, but I'd like to know the reason.
According to MSDN:
Device Installations on 64-Bit Systems:
The 32-bit version of the application must check the value returned by UpdateDriverForPlugAndPlayDevices. If the return value is ERROR_IN_WOW64, the 32-bit application is executing on a 64-bit platform and cannot update inbox drivers. Instead, it must call CreateProcess (described in the Windows SDK documentation) to start the 64-bit version of the application. The 64-bit version can then call UpdateDriverForPlugAndPlayDevices, specifying a FullInfPath parameter that identifies the location of the 64-bit versions of all files.
So it looks like any API that is designed to report ERROR_IN_WOW64 is specifically intended NOT to work in WOW64, a 32bit process has to invoke a 64bit process to call the API.
If you are making that call from a 32bit process on a 64bit OS, it fails because it has to modify some registry keys in the 64bit portion of the registry. Where else if you were to make that call from a 64bit process on a 64bit OS, it would succeed likewise with 32bit process on a 32bit OS.
Here's my scenario: the company I work has applications deployed to a 32bit Windows 2003 server and they want to move to a Windows 2008 Server that is 64 bit. It has been noted that these 32bit custom developed applications will not run on a 64 bit machine. I was not aware of this.
I have always thought that 32bit software CAN run on a 64 bit OS and just use the 32bit address. A 64 bit software on the other cannot run on a 32 bit OS. On a 64 bit, one does have to create 64 bit software but can and still also create software that is designed for 32 bit machines.
Can someone please elaborate on this?
In general, 32-bit applications will run under a 64-bit Windows (This is technically called WOW64 - Windows On Windows). This applies to all 64-bit Windows version to date, including Server.
WOW64 processes are marked in task manager with *32, For example: chrome.exe *32. Sysinternals' Process Explorer has a separate column for this: Image Type (64 vs 32-bit).
If the app has components hosted inside other processes, then those components must accommodate processes they're hosted in. Examples:
Shell extensions are hosted in explorer.exe, whose bitness matches the OS' bitness. Therefore, you should compile the extension in both 32- and 64-bit, and register the one matching the OS' bitness during installation.
Kernel-mode driver are hosted in the Kernel, whose bitness also matches the OS' bitness. So, the above applies.
Winsock LSPs (Layered Service Providers) are hosted in all processes, both 64-bit (native) and 32-bit (WOW64). Therefore, you should compile the LSP in both 32- and 64-bit, and register both in their respective catalogs during installation.
There are also considerations regarding file redirection (System32 / SysWOW64 / SysNative) and registry redirection (Wow6432Node), which I will not go into.
In general, 32-bit applications will run under a 64-bit OS. If your app relies on a 32-bit kernel driver (say, a VPN client), then you will have to port to 64-bit.
Our application requires HASP SRM device driver to be installed in order for ours to install and run.
At this time, only their 5.50 drivers work consistently on all tested platforms (both their 5.75 (official) and 5.86 (beta) drivers crash on about 1 in 3 computers tested).
Hence, their 5.50 drivers are good, anything else currently available is broken, and the 5.50 drivers refuse to load under Vista and Windows 7. However, if I set the exe's properties to "XP compatibility mode" then their 5.50 driver installs and runs successfully.
I dug around in the registry under Windows 7, and I've found that there is at least one entry made when I ask for compatibility mode:
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers\
full-path REG_SZ WINXPSP3
I should be able to add that key from our installer, before attempting to launch the 5.50 driver installer.
Questions:
Where I can find a more complete discussion of compatibility modes?
Are the keys/settings different under Vista vs. Windows 7?
Are the keys/settings different under 32 bit vs. 64 bit?
Is there a way to directly ask for this when I call CreateProcess()?
You can set the __COMPAT_LAYER environment variable (By setting it in your process before calling CreateProcess, or build a new environment block for CreateProcess)
I was looking at some libraries with dumpbin and I noticed that all the 64-bit versions were linked to KERNEL32. Is there no KERNEL64 on 64-bit Windows? If not, why?
All my operating systems are 32-bit so I can't just look. A google search brings up nothing worthwhile so I suspect that there is no KERNEL64 but I'm still curious as to why this is.
EDIT: I found this later which is pretty useful. MSDN guide to x64
It's always called kernel32.dll, even on 64-bit windows. This is for the same compatibility reasons that system32 contains 64-bit binaries, while syswow64 contains 32-bit binaries.
On the 64-bit versions of Windows one of the "kernel32.dll"s contains 64-bit code but is still called kernel32.dll. This is at least misleading
Hope the following links will give the solution for this
http://www.howzatt.demon.co.uk/articles/DebuggingInWin64.html
http://www.viva64.com/en/l/0002/
http://blogs.msdn.com/b/aaron_margosis/archive/2012/12/10/using-ntfs-junctions-to-fix-application-compatibility-issues-on-64-bit-editions-of-windows.aspx
64-bit Windows provides such an environment "out of the box" and supports 32-bit applications using the 'Windows on Windows 64' subsystem, abbreviated to WOW64, which runs in user mode and maps the 32-bit calls to the operating system kernel into an equivalent 64-bit call. This is normally almost invisible to the calling program.Windows provides a set of 64-bit DLLs in %windir%\system32 and an equivalent set of 32-bit DLLs in %windir%\syswow64. In fact the bulk of the binary images in this directory are identical to the same files in the system32 directory on a 32-bit Windows installation. (It seems to me an unfortunate naming issue that the 64-bit DLLs live in system32 and the 32-bit ones live in syswow64, but there it is)