Same code, system, but different arch using Win32 for reading registry.

Dear Haskellers, The setup: Having a binary compiled on either x86 or x64 system (same installation, utilizing stack) in order to preserve compatibility against x64 systems. Actually, not to have 2 separate executable for each, that would be the overall goal. However it surprises me when running the x86 .exe utilizing Win32-2.5.4.1 package with ghc-8.0.2, reading out a registry key fails on x64 system with the following:/ / /me.exe: RegOpenKey: invalid argument (The system cannot find the file specified.)/ That would be fine, however the key does exists. When same code, same system, but the .exe built to be x64 it runs like a charm. A couple of question, which some of them eventually will not make sense, but still: - Can it be ghc code optimization issue? - but this is a runtime check in IO, if so, how? - Yes, I could use a built-in windows system command and parse the input of that; unless absolutely necessary I would not introduce another dependency (system package). Would love to solve it with the currently utilized weapons. - the issue just puzzles me... I would know the answer if possible. - Is it more library (Win32), ghc, binary I generate, issue? What library can I use to detect a system's architecture which works in this scenario? Another thing which convoluted in the issue... The function, /getSystemInfo :: IO SYSTEM_INFO, /can read out the underlying architecture. When compiled on x86 and run on x64 it would tell me: "I am running on x86". That's failure. Most importantly: what is the obvious I am missing? Thank you for your insights! Best, Akos Ps.: Would you/we need sample code to puzzle about I can quickly weld one. - not sure if necessary.

On Fri, 2017-04-07 at 18:51 -0100, Akos Marton wrote:
Dear Haskellers, The setup: Having a binary compiled on either x86 or x64 system (same installation, utilizing stack) in order to preserve compatibility against x64 systems. Actually, not to have 2 separate executable for each, that would be the overall goal. However it surprises me when running the x86 .exe utilizing Win32-2.5.4.1 package with ghc-8.0.2, reading out a registry key fails on x64 system with the following: me.exe: RegOpenKey: invalid argument (The system cannot find the file specified.) That would be fine, however the key does exists. When same code, same system, but the .exe built to be x64 it runs like a charm.
32bit and 64bit Windows executables read different keys using the same registry path. The 64bit executable can read keys from the 32bit part of the registry, but is has to use the WOW6432Node path. Maybe this will help: https://support.microsoft.com/en-us/help/305097/h ow-to-view-the-system-registry-by-using-64-bit-versions-of-windows
A couple of question, which some of them eventually will not make sense, but still: - Can it be ghc code optimization issue? - but this is a runtime check in IO, if so, how? - Yes, I could use a built-in windows system command and parse the input of that; unless absolutely necessary I would not introduce another dependency (system package). Would love to solve it with the currently utilized weapons. - the issue just puzzles me... I would know the answer if possible. - Is it more library (Win32), ghc, binary I generate, issue? What library can I use to detect a system's architecture which works in this scenario? Another thing which convoluted in the issue... The function, getSystemInfo :: IO SYSTEM_INFO, can read out the underlying architecture. When compiled on x86 and run on x64 it would tell me: "I am running on x86". That's failure.
Most importantly: what is the obvious I am missing?
Thank you for your insights! Best, Akos
Ps.: Would you/we need sample code to puzzle about I can quickly weld one. - not sure if necessary. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

On 04/07/2017 05:08 PM, Arjen wrote:
That would be fine, however the key does exists. When same code, same system, but the .exe built to be x64 it runs like a charm. 32bit and 64bit Windows executables read different keys using the same registry path. The 64bit executable can read keys from the 32bit part of the registry, but is has to use the WOW6432Node path. Maybe this will help:https://support.microsoft.com/en-us/help/305097/h ow-to-view-the-system-registry-by-using-64-bit-versions-of-windows
That's okay: for other reasons also related to registry reading I need to deal with it. The interesting thing is really, the registry-key which I wish to read exists on the system and the key is the same on x86 and x64. The key must be related to /getSystemInfo :: IO SYSTEM_INFO. /

On Fri, Apr 7, 2017 at 3:51 PM, Akos Marton
*me.exe: RegOpenKey: invalid argument (The system cannot find the file specified.)*
That would be fine, however the key does exists. When same code, same system, but the .exe built to be x64 it runs like a charm.
My guess is that the FFI call has an incorrect type somewhere and therefore passes garbage. Another thing which convoluted in the issue...
The function, *getSystemInfo :: IO SYSTEM_INFO, *can read out the underlying architecture. When compiled on x86 and run on x64 it would tell me: "I am running on x86". That's failure.
You can blame Windows for that one: if you run an x86 binary on x86_64, it launches the WoW subsystem emulating an x86 processor, so you will get the emulated processor reported back. There may be a different API to get the actual host --- but given that WoW exists to minimize incompatibilities for x86 software, it is likely well hidden if it exists at all. -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

On Fri, Apr 7, 2017 at 3:51 PM, Akos Marton
wrote: *me.exe: RegOpenKey: invalid argument (The system cannot find the file specified.)*
That would be fine, however the key does exists. When same code, same system, but the .exe built to be x64 it runs like a charm.
My guess is that the FFI call has an incorrect type somewhere and therefore passes garbage. My fear is that, even if digging into the code of win32 package, underlying details seems to be hidden how certain values are read out. - at least for me. Can it be that ghc forces its evaluation during compilation and renders something hard-coded into the binary? - this is how it feels, I am
On 04/07/2017 05:09 PM, Brandon Allbery wrote: trying to show it, so far w/o success.
Another thing which convoluted in the issue...
The function, *getSystemInfo :: IO SYSTEM_INFO, *can read out the underlying architecture. When compiled on x86 and run on x64 it would tell me: "I am running on x86". That's failure.
You can blame Windows for that one: if you run an x86 binary on x86_64, it launches the WoW subsystem emulating an x86 processor, so you will get the emulated processor reported back. There may be a different API to get the actual host --- but given that WoW exists to minimize incompatibilities for x86 software, it is likely well hidden if it exists at all.
I do not know that, but it feels like I should use something which can be called via /system/ and hence on can rely on the local window api and not on the system I compile.

On Mon, Apr 10, 2017 at 2:17 PM, Akos Marton
Can it be that ghc forces its evaluation during compilation and renders something hard-coded into the binary? - this is how it feels, I am trying to show it, so far w/o success.
No. The System.Info module works that way (more precisely it reports things baked into the binary at compile time), but the Win32 module is making an actual system call. That system call is being processed by WoW32 and returning information about the emulator, not the host. If it's not clear yet: WoW32 is a restricted virtual machine. Expect it to behave as if the program is running in a 32-bit Windows inside VirtualBox. You get this any time you run a 32-bit executable on 64-bit Windows. It does not matter what language you use. It does not matter how you access this information. I do not know that, but it feels like I should use something which can be
called via *system* and hence on can rely on the local window api and not on the system I compile.
That will likely still run within WoW32 though, and report the emulated 32-bit CPU. Windows is specifically avoiding the thing you want, in order to provide backward compatibility. At this point you probably need to spend some time with MSDN to see if there is a way for something running in WoW32 to find out details of the host, probably by communicating with the hypervisor. -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net
participants (3)
-
Akos Marton
-
Arjen
-
Brandon Allbery