Why is the SetupDiCallClassInstaller function restricted to 64 bit programs? - winapi

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.

Related

How to get x64 process's exact location from an x86 process?

I am running a .net 5 Windows service process, which cannot be complied to AnyCPU.
For the user compatible reason(some client still use 32 bit Windows), I need to build it to x86 App.
When I try to enum the details of a x64 process on x64 Windows, it said a x86 process cannot do so.
Is there a workaround to get the x64 process's exact running path on x64 Windows?
e.g. running another x64 bit process and communicate with the process to get process info, but it's not graceful way. I wanna know if any better way exists?

gflags doesn't work in 64 bit Windows 7, but 32 bit environment

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.

What does WoW64 emulation layer do?

All WoW64 apps go through WoW64 emulation layer.
I'd like to know what happen in this layer.(especially, how they can convert address space)
Please give me some important points.
Since you have already posted the diagram it is clear that you know why WOW64 exists. Now to answer your question:
I'd like to know what happen in this layer.
I think you want to know how it is implemented.
Process startup: The loader loads 64-bit user-mode part 'Ntdll.dll' as usual, but also loads 32-bit Ntdll.dll in case the process is for 32-bit execution. It is now the loaders responsibility to initialize using Wow64.dll, which sets up process and thread contexts in 32-bit Ntdll and 'switches the CPU to 32-bit mode' for execution.
System Call: Everything is now running in 32-bit mode, until a system call. We know that system calls go through Ntdll.dll, User32.dll, and Gdi32.dll etc; in this case the 32-bit versions. There is a separate 32-bit version of these libraries located in \Windows\Syswow64 bit folder. These are just stubs that instead of issuing 'native system calls,' actually call in Wow64.dll. Now, it's simple for Wow64.dll to transition to 64-bit mode, convert parameters to their 64-bit counterparts, issue the system call using 64-bit versions, get the result, and reconvert the output to 32-bit. It then transitions CPU back to 32-bit mode and returns the output.
Exception dispatching, user callbacks, file system and registry operations, and I/O is handled in the same way, using hooks somewhere down the line. Read the book prescribed below.
(especially, how they can convert address space).
64-bit address space is a superset of 32-bit address space. Plus, the same pointer (actually PTE) in 32-bit/64-bit isn't used to refer to the whole address space, but there are separate page tables for user-space and for system space.
Please give me some important points.
To know windows, the most important point I can give you is to read 'Windows Internals' -- Russinovich
MSDN says:
WOW64 is the x86 emulator that allows 32-bit Windows-based applications to run seamlessly on 64-bit Windows. WOW64 is provided with the operating system and does not have to be explicitly enabled.
The system isolates 32-bit applications from 64-bit applications, which includes preventing file and registry collisions. Console, GUI, and service applications are supported. The system provides interoperability across the 32/64 boundary for scenarios such as cut and paste and COM. However, 32-bit processes cannot load 64-bit DLLs for execution, and 64-bit processes cannot load 32-bit DLLs for execution.
What specifically do you not understand? Have you already read the Wikipedia article on the WoW64 subsystem? I think you'll find that it provides a fairly comprehensive overview.
And Microsoft provides some additional details here: WOW64 Implementation Details
"especially, how they can convert address space"
the key to that is knowing that amd and intel x64 processors have support for running 32bit and 64bit code side by side. this allows the os (when running native x64) to create a context for a 32bit thread that has 32bit addressing that coexists with the 64bit threads
in a similar way when the host os is running 32bit, it can create 16bit threads for running win16 and dos applications.
note, I don't think when running in the os 64bit that it can create 32bit AND 16bit threads - I guess amd decided that was just too much backwards compatability :-)

Will win32 bit applications run on a 64 bit server?

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.

Does KEY_WOW64_64KEY have any effect on 32 bit Windows?

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".

Resources