Recent

Author Topic: Windows API test programs / Examples  (Read 4823 times)

440bx

  • Hero Member
  • *****
  • Posts: 2253
Re: Windows API test programs / Examples
« Reply #30 on: January 16, 2021, 12:28:49 pm »
@PascalDragon

Note that I didn't say that it is not possible to determine the O/S bitness using IsWowProcess and/or IsWowProcess2.   What I state is that, making the determination using those APIs is cumbersome and, in the case of ARM, it is unreliable.  To use those APIs, the programmer first has to determine if those APIs are available and, if they are, use them.  To make matters worse, on an ARM processor, the result, if using IsWowProcess, will be incorrect. 

The alternative I recommend is a straight, reliable line to the correct answer.  Load csrss.exe and check its bitness.  No need to find out if a particular API is available and no possibility of getting it wrong regardless of the processor the O/S runs on.

Obviously, everyone is free to choose whatever method they want to use but, I recommend checking csrss.exe because it is the simplest and most reliable route to make the determination. No concerns about user privileges, API availability and processor affect the method.
FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

PascalDragon

  • Hero Member
  • *****
  • Posts: 2886
  • Compiler Developer
Re: Windows API test programs / Examples
« Reply #31 on: January 16, 2021, 05:09:22 pm »
Note that I didn't say that it is not possible to determine the O/S bitness using IsWowProcess and/or IsWowProcess2.   What I state is that, making the determination using those APIs is cumbersome and, in the case of ARM, it is unreliable.  To use those APIs, the programmer first has to determine if those APIs are available and, if they are, use them.  To make matters worse, on an ARM processor, the result, if using IsWowProcess, will be incorrect.

And here I don't agree. I consider the API the more straightforward, sane and stable approach then checking some file as long as one knows the restrictions of the functions (e.g. use IsWow64Process2 if available and only then IsWow64Process). In theory nothing is stopping Microsoft from using some file system redirection for csrss.exe (as they do for SysWow64 already) and then your checks would be completely screwed.

440bx

  • Hero Member
  • *****
  • Posts: 2253
Re: Windows API test programs / Examples
« Reply #32 on: January 16, 2021, 10:12:42 pm »
And here I don't agree.
We can agree to disagree.  I have no problem with that.

I consider the API the more straightforward, sane and stable approach then checking some file as long as one knows the restrictions of the functions (e.g. use IsWow64Process2 if available and only then IsWow64Process).
that "sane and stable approach" takes more code that is more complicated and, in the case of ARM whether or not it works is a question mark.  You know that is a fact.

In theory nothing is stopping Microsoft from using some file system redirection for csrss.exe (as they do for SysWow64 already) and then your checks would be completely screwed.
But there is something in _practice_ that stops MS from using file system redirection in this case which is, a 32 bit program is allowed to load a 64 bit DLL as a resource file (to either use its resources or manipulate them.)  If MS were to change that, they would break all 32 bit programs that load resources from 64 bit executables.  Additionally, in the case of 64 bit modules, there is only _one_ copy available in the system, there is nowhere to redirect to.  The bottom line is, yes, _in theory_ they could do it, _in practice_ doing it would result in the breaking of a fair amount of code including some of their own code for no good reason.  Doesn't seem a likely possibility.
FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

ASerge

  • Hero Member
  • *****
  • Posts: 1765
Re: Windows API test programs / Examples
« Reply #33 on: January 16, 2021, 10:34:33 pm »
This code work:
Code: Pascal  [Select][+][-]
  1. {$MODE OBJFPC}
  2. {$APPTYPE CONSOLE}
  3.  
  4. uses Windows, SysUtils;
  5.  
  6. function IsThisWin32OnWin64: Boolean;
  7. type
  8.   TIsWow64Process = function(hProcess: HMODULE; Wow64Process: PBOOL): BOOL; stdcall;
  9.   TIsWow64Process2 = function(hProcess: HMODULE; pProcessMachine: PUSHORT; pNativeMachine: PUSHORT): BOOL; stdcall;
  10. var
  11.   K32: HMODULE;
  12.   P: FARPROC;
  13.   Wow64Process: BOOL = False;
  14.   ProcessMachine: USHORT = IMAGE_FILE_MACHINE_UNKNOWN;
  15.   NotUsed: USHORT = 0;
  16. begin
  17.   K32 := GetModuleHandle(kernel32);
  18.   P := GetProcAddress(K32, 'IsWow64Process');
  19.   if Assigned(P) and TIsWow64Process(P)(GetCurrentProcess, @Wow64Process) and Wow64Process then
  20.     Exit(True);
  21.   P := GetProcAddress(K32, 'IsWow64Process2');
  22.   if Assigned(P) and TIsWow64Process2(P)(GetCurrentProcess, @ProcessMachine, @NotUsed) and (ProcessMachine <> IMAGE_FILE_MACHINE_UNKNOWN) then
  23.     Exit(True);
  24.   Result := False;
  25. end;
  26.  
  27. begin
  28.   Writeln(IsThisWin32OnWin64);
  29.   Readln;
  30. end.

440bx

  • Hero Member
  • *****
  • Posts: 2253
Re: Windows API test programs / Examples
« Reply #34 on: January 16, 2021, 10:39:02 pm »
@Serge.

Have you tried that code on an ARM platform ?... how does it work there ?
« Last Edit: January 16, 2021, 11:25:04 pm by 440bx »
FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

ASerge

  • Hero Member
  • *****
  • Posts: 1765
Re: Windows API test programs / Examples
« Reply #35 on: January 16, 2021, 10:48:09 pm »
Have tried that code on an ARM platform ?... how does it work there ?
No, I don't have an ARM machine. This part is based on the documentation for the IsWow64Process2 function, which does not make an exception for ARM machine.

440bx

  • Hero Member
  • *****
  • Posts: 2253
Re: Windows API test programs / Examples
« Reply #36 on: January 16, 2021, 11:03:19 pm »
No, I don't have an ARM machine. This part is based on the documentation for the IsWow64Process2 function, which does not make an exception for ARM machine.
That's a precarious thing to depend on because the documentation for IsWowProcess does _not_ state that on an ARM machine, IsWowProcess2 should be used instead.

When an API, such as IsWowProcess, doesn't work in a particular case, they point the reader to the one that works, which in this case should be IsWowProcess2 but, that recommendation is notably missing.

Contrast that with an API such as GlobalMemoryStatus which does not work on systems with more than 4GB, the description of that API directs the reader to use GlobalMemoryStatusEx because that one works in that case.  That is missing in IsWowProcess, they state the problem and do _not_ offer IsWowProcess2 as a solution to it.

Unless you test it on an ARM machine, I wouldn't trust the code you provided to work on that platform.  Succinctly, without testing, you're just hoping it works (it may or may not, like you, I don't know.)

FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

ASerge

  • Hero Member
  • *****
  • Posts: 1765
Re: Windows API test programs / Examples
« Reply #37 on: January 17, 2021, 12:37:05 pm »
Unless you test it on an ARM machine, I wouldn't trust the code you provided to work on that platform.  Succinctly, without testing, you're just hoping it works (it may or may not, like you, I don't know.)
Until you test your code for ARM64, I can't trust it either. Mine is at least based on official documentation, and is more likely to work.

440bx

  • Hero Member
  • *****
  • Posts: 2253
Re: Windows API test programs / Examples
« Reply #38 on: January 17, 2021, 12:54:21 pm »
Until you test your code for ARM64, I can't trust it either. Mine is at least based on official documentation, and is more likely to work.
Your argument is reasonable but, mine will work as long as csrss.exe exists, which is rather likely. :) 

FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

PascalDragon

  • Hero Member
  • *****
  • Posts: 2886
  • Compiler Developer
Re: Windows API test programs / Examples
« Reply #39 on: January 17, 2021, 10:14:58 pm »
No, I don't have an ARM machine. This part is based on the documentation for the IsWow64Process2 function, which does not make an exception for ARM machine.
That's a precarious thing to depend on because the documentation for IsWowProcess does _not_ state that on an ARM machine, IsWowProcess2 should be used instead.

When an API, such as IsWowProcess, doesn't work in a particular case, they point the reader to the one that works, which in this case should be IsWowProcess2 but, that recommendation is notably missing.

Apparently we're not reading the same documentation then (emphasis mine):

Quote
Remarks

Applications should use IsWow64Process2 instead of IsWow64Process to determine if a process is running under WOW. IsWow64Process2 removes the ambiguity inherent to multiple WOW environments by explicitly returning both the architecture of the host and guest for a given process. Applications can use this information to reliably identify situations such as running under emulation on ARM64. To compile an application that uses this function, define _WIN32_WINNT as 0x0501 or later. For more information, see Using the Windows Headers.


Unless you test it on an ARM machine, I wouldn't trust the code you provided to work on that platform.  Succinctly, without testing, you're just hoping it works (it may or may not, like you, I don't know.)

I've modified ASerge's program as follows:

Code: Pascal  [Select][+][-]
  1. program tiswow64;
  2.  
  3. {$MODE OBJFPC}
  4. {$APPTYPE CONSOLE}
  5.  
  6. uses Windows, SysUtils;
  7.  
  8. procedure TestWow64Process2;
  9. type
  10.   TIsWow64Process2 = function(hProcess: HMODULE; pProcessMachine: PUSHORT; pNativeMachine: PUSHORT): BOOL; stdcall;
  11. var
  12.   K32: HMODULE;
  13.   P: FARPROC;
  14.   ProcessMachine,
  15.   HostMachine: USHORT;
  16. begin
  17.   K32 := GetModuleHandle(kernel32);
  18.   P := GetProcAddress(K32, 'IsWow64Process2');
  19.   if Assigned(P) then begin
  20.     if TIsWow64Process2(P)(GetCurrentProcess, @ProcessMachine, @HostMachine) then begin
  21.       Writeln('Machines: Process = ', HexStr(ProcessMachine, 4), ', Host = ', HexStr(HostMachine, 4));
  22.     end else
  23.       Writeln('Failed to execute IsWow64Process2: ', SysErrorMessage(GetLastOSError));
  24.   end else
  25.     Writeln('IsWow64Process2 not found');
  26. end;
  27.  
  28. begin
  29.   TestWow64Process2;
  30. end.

This I have run on Windows on ARM64 once compiled as aarch64-win64 and once as i386-win32:

Code: [Select]
D:\fpc\git\fpctests>tiswow64-a64.exe
Machines: Process = 0000, Host = AA64

D:\fpc\git\fpctests>tiswow64-i386.exe
Machines: Process = 014C, Host = AA64

And I'd wager that x86_64-win64 on Windows on ARM64 would look like this (since I'm not on the Windows Insider Preview channel I can't test):

Code: [Select]
Machines: Process = 8664, Host = AA64
And arm-win32 would look like this (I've not yet ported FPC for arm-win32 and arm-wince won't work there):

Code: [Select]
Machines: Process = 01C4, Host = AA64

440bx

  • Hero Member
  • *****
  • Posts: 2253
Re: Windows API test programs / Examples
« Reply #40 on: January 17, 2021, 10:22:58 pm »
Apparently we're not reading the same documentation then (emphasis mine):
Quote
Remarks

Applications should use IsWow64Process2 instead of IsWow64Process to determine if a process is running under WOW. IsWow64Process2 removes the ambiguity inherent to multiple WOW environments by explicitly returning both the architecture of the host and guest for a given process. Applications can use this information to reliably identify situations such as running under emulation on ARM64. To compile an application that uses this function, define _WIN32_WINNT as 0x0501 or later. For more information, see Using the Windows Headers.
You are right. My mistake.  Thank you for point it out.  Lesson: I should read the whole thing instead of stopping.

This I have run on Windows on ARM64 once compiled as aarch64-win64 and once as i386-win32:
Did you happen to test the method I recommend on ARM64 ? ... if the answer is yes, I'd like to know what the result was.  Thank you.
FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

PascalDragon

  • Hero Member
  • *****
  • Posts: 2886
  • Compiler Developer
Re: Windows API test programs / Examples
« Reply #41 on: January 19, 2021, 09:17:49 am »
This I have run on Windows on ARM64 once compiled as aarch64-win64 and once as i386-win32:
Did you happen to test the method I recommend on ARM64 ? ... if the answer is yes, I'd like to know what the result was.  Thank you.

I have not. Will try to fit that in some time this week.

440bx

  • Hero Member
  • *****
  • Posts: 2253
Re: Windows API test programs / Examples
« Reply #42 on: January 19, 2021, 11:47:26 am »
I have not. Will try to fit that in some time this week.
Thank you.
FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

PascalDragon

  • Hero Member
  • *****
  • Posts: 2886
  • Compiler Developer
Re: Windows API test programs / Examples
« Reply #43 on: January 24, 2021, 12:59:54 pm »
This I have run on Windows on ARM64 once compiled as aarch64-win64 and once as i386-win32:
Did you happen to test the method I recommend on ARM64 ? ... if the answer is yes, I'd like to know what the result was.  Thank you.

I have not. Will try to fit that in some time this week.

Of course it would take me till the weekend... ::) Anyway, your example seems to work. At least it shows that the Windows on ARM64 is a 64-bit one.

440bx

  • Hero Member
  • *****
  • Posts: 2253
Re: Windows API test programs / Examples
« Reply #44 on: January 24, 2021, 01:21:31 pm »
Anyway, your example seems to work. At least it shows that the Windows on ARM64 is a 64-bit one.
Thank you.  I appreciate your confirming that it works on other CPUs as well (ARM64 in this case.)
FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

 

TinyPortal © 2005-2018