Old 8th June 2018, 19:48   #1
jkunkee
Junior Member
 
Join Date: Jun 2018
Posts: 5
Windows 10 updated architecture detection

Hi,

(Moderators, I tried to post a longer version of this earlier today, but either my browser crashed before it could post or some variant of PEBKAC happened. If, instead, this is a duplicate, please feel free to delete it.)

I have recently been working with OpenVPN to get their Windows driver to work on the new Windows 10 on ARM devices. Part of this process required using IsWowProcess2 to correctly detect the system's processor's architecture so the right driver (ARM64) could be installed. Since x64.nsh has not yet been updated, I updated it:

https://github.com/OpenVPN/tap-windows6/pull/57

Specifically:
https://github.com/jkunkee/tap-windo...taller/wow.nsh

This script calls the Windows 10 function IsWow64Process2 if available, but falls back to IsWow64Process if not. It stubs in the ability to work with any architecture combination future Windows versions may offer.

I post it here with the hope that it will be useful to someone else, maybe even the maintainers of x64.nsh. Please do let me know if you have any feedback.
jkunkee is offline   Reply With Quote
Old 8th June 2018, 20:02   #2
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 4,867
If you look at trunk you will see that I have already added code for ARM64 detection and it will be part of the next release. I'm using GetNativeSystemInfo instead, not sure if that matters.

Your code uses !insertmacro _== but that is a string compare in LogicLib, use _= for IntCmp.

(Your first post was marked as spam because you posted a fair amount of code as a new user)

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 11th June 2018, 21:25   #3
jkunkee
Junior Member
 
Join Date: Jun 2018
Posts: 5
When the UI started bogging down on that much text, I started to wonder. That's entirely fair.

Ah, those are the changes my coworker was telling me about! It'll mostly work, but there are a few flaws in that approach that led me down a different road:
  • ${IsWow64} still reports an incorrect value on ARM64 systems (Windows has to lie to IsWow64Process to get good behavior out of callers who assume "IsWow64Process returning TRUE always means AMD64+x86". That's why IsWow64Process2 returns two full architecture IDs.)
  • Return values are ignored
  • GetNativeSystemInfo does not offer easy access to WOW64 guest architecture information, while IsWow64Process2 does (ease of future extension)
  • x64 is a misnomer for 64-bit, which now includes ARM64...but existing scripts still gotta work

If these aren't problems for you--and at least return value checking is not a problem in the trunk version--then what you have will do just fine. Windows does not lie to GetNativeSystemInfo unless a specific app requires it during app compat testing, and then it's a one-off app compat shim.

I have tested wow.nsh on Win7 and Win10, AMD64 and ARM64. I see you have a note about sub-XP compatibility; while I think my approach work that far back, I definitely haven't tested it.

Thanks for the _= vs. _== catch! I'll get that into the OpenVPN PR ASAP.
jkunkee is offline   Reply With Quote
Old 12th June 2018, 01:40   #4
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 4,867
  • Are you serious, IsWow64Process reports false for a 32-bit x86 application on ARM64? We only care about WoW here, not the CPU.
  • GetNativeSystemInfo does not return anything, it can't fail
  • I only care about the host, the guest (us) is known at compile time.
  • Yep At least we try to use AMD64 when we mean that specific CPU target
  • Can app compat shim lie to GetNativeSystemInfo but not IsWow64Process2?

https://docs.microsoft.com/en-us/win...leshooting-x86 says
Quote:
The original IsWow64Process indicates only whether the app is running on an x64 machine. Apps should now use IsWow64Process2 to determine whether they're running on a system with WOW support.
while the MSDN page for IsWow64Process still says
Quote:
Determines whether the specified process is running under WOW64.
so I don't know who to trust.

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 18th June 2018, 20:04   #5
jkunkee
Junior Member
 
Join Date: Jun 2018
Posts: 5
I feel your pain. Some of the legacy stuff is...interesting. It really sounds to me like GetNativeSystemInfo makes sense to you and does exactly what you want.
  • Yes, unfortunately for the first 20 years of its existence IsWow64Process returning true has meant both "you are a 32-bit program on a 64-bit system" and "you are an IA32 program running on x86_64" (ignoring, for a moment, IA64). Programs relying on the second interpretation (very nearly) always do the Wrong Thing(TM) when the function returns true, while programs with the first interpretation (very nearly) always do the Right Thing when the function returns false. OpenVPN's NSI relies on the second interpretation. (Extracting "is WoW" from IsWow64Process2 is pretty easy based on the docs: just check to see if the guest value is 'unknown architecture'.)
  • It's worth saying again: GetNativeSystemInfo is lookin' pretty good.
  • The doc points out that the guest info is non-obvious in one case: not WoW.
  • Yup.
  • I'll be honest: there's no technical reason IsWow64Process2 can't be shimmed now or in the future. We'd rather have a clean source of truth that programmers can rely on, so we won't. Part of this is that it returns enough info that, it's hoped, programs can be written intelligently and so it won't need to be shimmed. On the flip side, there are existing GetNativeSystemInfo callers that crash when ARM64 is returned, so that's why and when we shim it.

The x86 app troubleshooting doc is correct. I'll get IsWow64Process' doc fixed. I thought someone had already scoured the docs for that kind of discrepancy...
jkunkee is offline   Reply With Quote
Old 19th June 2018, 00:13   #6
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 4,867
I have to disagree a bit about IsWow64Process, it never said that native was AMD64 but people just assumed.

I stayed away from IsWow64Process2 because I only needed the WoW information, not CPU info and because it only exists on 10 I'll need extra fallback code. GetNativeSystemInfo works all the way back to XP.

It is so frustrating when good people suffer because idiots get shims. Does IsWow64Process lie even with the "supports 10 guid" in the manifest?

I even looked around for a cheap ARM64 tablet so I could verify but I found nothing.

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 30th June 2018, 02:54   #7
jkunkee
Junior Member
 
Join Date: Jun 2018
Posts: 5
You got me doing some research to double-check what I was saying earlier. Thank you! I have some good news and some bad news.

First, the bad news:

Both IsWow64Process AND GetNativeSystemInfo return nominally incorrect values under emulation on ARM64. The documentation for both is being updated.

(It might be of interest that, under the hood, Windows does not actually shim them. The functions themselves were modified.)

Backwards compatibility is, in my opinion, one of Windows' most important features, so this decision was not taken lightly. We debugged a large number of programs and found that these two careful changes together get the best behavior out of the broadest set of programs we can--including well-written apps and many NSIS-based installers--and the programs don't have to be modified at all.

Quote:
I have to disagree a bit about IsWow64Process, it never said that native was AMD64 but people just assumed.
Truth.

Even here at Microsoft there were dozens of places in Windows itself where bad IsWow64Process assumptions were made. Finding and fixing them was one of the bigger challenges when taking this product from a small demo to something that could ship.

Quote:
It is so frustrating when good people suffer because idiots get shims.
It runs even deeper than that. The design of IsWow64Process wasn't great to start with: all the boolean says is "you have another architecture to deal with" with no nuance, so, instead of calling another function (GetNativeSystemInfo), many devs just made assumptions. The advent of IA64 (Itanium) wasn't enough to change this, and the eventual dominance of x86_64 led to more works-for-now assumptions in lots and lots of code. Even the RunningX64 macro in x64.nsh calls IsWow64Process and doesn't call GetNativeSystemInfo afterwards.

Quote:
Does IsWow64Process lie even with the "supports 10 guid" in the manifest?
Yes. The manifest has no way to specifically state "aware of x86 emulation on ARM64"--and even apps with updated manifests use IsWow64Process to infer architecture.

Now, to the heart of the matter--and some good news.

Quote:
I stayed away from IsWow64Process2 because I only needed the WoW information, not CPU info and because it only exists on 10 I'll need extra fallback code. GetNativeSystemInfo works all the way back to XP.
Fair enough! GetNativeSystemInfo would be best, then, except for the bad news earlier.

One path forward, then, is what I outlined in wow.nsh plus GetNativeSystemInfo:
  1. Try IsWow64Process2 (win10, esp ARM64)
  2. Fall back to IsWow64Process+GetNativeSystemInfo (<win10)
  3. Default to IA32/x86 (win9x)

This might work extremely well, but one look at wow.nsh shows its complexity in NSIS script.

The really good news, then, is that Windows XP introduced two environment variables: PROCESSOR_ARCHITECTURE and PROCESSOR_ARCHITEW6432. These can be accessed by using System::Call Kernel32::GetEnvironmentVariable.

https://docs.microsoft.com/en-us/win...tation-details

If PROCESSOR_ARCHITEW6432 is not empty, the program is running under WoW and the variable holds the host's architecture. If it is empty, PROCESSOR_ARCHITECTURE is both the process and the OS' architecture. If System::Call returns an error, then GetProcAddress failed and you're probably on Windows ME or earlier and already don't care about WoW. If either variable is defined but the value is not recognized, an error can be returned, then you're on a new architecture.

So few programs use these environment variables badly that they only get one-off shims. This is, in part, why IsWow64Process2 returns so much information: this design is easier to use in a future-tolerant manner.

(Yes, I'm sad I didn't learn the environment variable trick sooner.)

Quote:
I even looked around for a cheap ARM64 tablet so I could verify but I found nothing.
The cheapest right now is the Asus NovaGo, but that's still $699 last I saw--so not cheap. (The other two are the HP Envy x2 and the Lenovo Miix 630.)

Last piece of good news: I have an ARM64 device and I'm happy to help with testing. PM me and we can get in touch.
jkunkee is offline   Reply With Quote
Old 30th June 2018, 14:38   #8
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 4,867
Thank you for the additional information! Working without hardware to test on and documentation you can't trust means you are my only source of information ATM.

RunningX64 just means the OS is 64-bit. I did not name it but that is what it is supposed to return. It does assume that a 32-bit OS cannot run 64-bit apps emulated but that seems safe enough to take a chance on. IsWow64Process did not lie when it was first written so calling anything else seemed pointless.

I don't want to rely on environment variables so IsWow64Process2 has to be used when available.

I don't think we care about IA-64 but I assume IsWow64Process and GetNativeSystemInfo are not shimmed there? I would care if there was a issue but there has never been any complaints about it and it is pretty much a dead platform.

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 10th July 2018, 00:26   #9
jkunkee
Junior Member
 
Join Date: Jun 2018
Posts: 5
Naming is hard and dealing with historical names is harder. No worries.

IsWow64Process and GetNativeSystemInfo should be normal on IA64, nothing special.
jkunkee is offline   Reply With Quote
Reply
Go Back   Winamp & SHOUTcast Forums > Developer Center > NSIS Discussion

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump