Recent

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

FlierMate

  • Guest
Re: Windows API test programs / Examples
« Reply #45 on: January 28, 2021, 03:44:44 pm »
I ran TISWOW64.pas on my machine and get:

Quote
Running "e:\tiswow64.exe "
Machines: Process = 0000, Host = 014C

From MS docs, I found 0x014C is:
Quote
0x14c
Intel 386 or later processors and compatible processors

From the docs though, I don't recognize which is Intel x64 CPU. Sorry if my question was dumb.

I see only the below are x64 but none are Intel's:
Quote
MACHINE_IA64
0x200
Intel Itanium processor family

MACHINE_ARM64
0xaa64
ARM64 little endian

MACHINE_AMD64
0x8664
x64

Is there any other list?

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Windows API test programs / Examples
« Reply #46 on: January 28, 2021, 06:05:38 pm »
Is there any other list?

Difficult to say without knowing which list you're looking to, but the one for Image File Machine Constants (as returned by e,g, IsWow64Process2) contains the following Intel-related constants:
Code: Pascal  [Select][+][-]
  1. IMAGE_FILE_MACHINE_I386 = 0x014c = Intel 386
  2. IMAGE_FILE_MACHINE_IA64 = 0x0200 = Intel 64
Note that while in your list MACHINE_IA64 is taken to mean Itanium family, in this one it's used for any Intel IA64 processor.
« Last Edit: January 28, 2021, 06:08:05 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: Windows API test programs / Examples
« Reply #47 on: January 28, 2021, 06:49:32 pm »
I ran TISWOW64.pas on my machine and get:

Quote
Running "e:\tiswow64.exe "
Machines: Process = 0000, Host = 014C
It's one thing to determine the CPU Windows is running under and another thing to determine if a program is running under Wow64.  The presence of a 64 bit CPU does not imply that a 64 bit O/S is installed.

For instance, a 32bit version of Windows runs fine on an x64 CPU (Intel or AMD.)  A program that returns which CPU is present should report an x86_64 type of CPU even though the program is _not_ running under Wow64.  The intel/AMD 64 bit CPUs are identified as an IMAGE_FILE_MACHINE_AMD64.

It's also important to note that depending on the API used, Windows may report different results.  For instance, if a 32 bit program uses GetSystemInfo on a 64 bit processor (and running under Wow64), Windows will report the processor architecture as being PROCESSOR_ARCHITECTURE_INTEL and processor type as PROCESSOR_INTEL_PENTIUM (which is a 32 bit processor), whereas a 32 bit program that uses GetNativeSystemInfo will return a processor architecture of PROCESSOR_ARCHITECTURE_AMD64 and a processor type of PROCESSOR_AMD_8664. 

For some reason, MS explicitly discourages using GetNativeSystemInfo to determine if a program is running under Wow64.  The reason why is still unclear.
« Last Edit: January 28, 2021, 06:51:53 pm by 440bx »
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

FlierMate

  • Guest
Re: Windows API test programs / Examples
« Reply #48 on: January 29, 2021, 09:31:29 am »
Difficult to say without knowing which list you're looking to, but the one for Image File Machine Constants (as returned by e,g, IsWow64Process2) contains the following Intel-related constants:
Code: Pascal  [Select][+][-]
  1. IMAGE_FILE_MACHINE_I386 = 0x014c = Intel 386
  2. IMAGE_FILE_MACHINE_IA64 = 0x0200 = Intel 64
Note that while in your list MACHINE_IA64 is taken to mean Itanium family, in this one it's used for any Intel IA64 processor.

Thank you for the link, looks like the 'Itanium' word has been removed from that list.

It's one thing to determine the CPU Windows is running under and another thing to determine if a program is running under Wow64.  The presence of a 64 bit CPU does not imply that a 64 bit O/S is installed.
......The intel/AMD 64 bit CPUs are identified as an IMAGE_FILE_MACHINE_AMD64.

Then I think Process is the Windows and Host is the CPU?

Thanks for the answer, AMD64, need to test it on Windows 64-bit one day.

It's also important to note that depending on the API used, Windows may report different results.  For instance, if a 32 bit program uses GetSystemInfo on a 64 bit processor (and running under Wow64), Windows will report the processor architecture as being PROCESSOR_ARCHITECTURE_INTEL and processor type as PROCESSOR_INTEL_PENTIUM (which is a 32 bit processor), whereas a 32 bit program that uses GetNativeSystemInfo will return a processor architecture of PROCESSOR_ARCHITECTURE_AMD64 and a processor type of PROCESSOR_AMD_8664. 

For some reason, MS explicitly discourages using GetNativeSystemInfo to determine if a program is running under Wow64.  The reason why is still unclear.

This is an additional information. I am not sure how .NET detects Windows bitness although I believe there is a simpler way (than IsWow64)?

P.S. You do not have to answer anyway. The information you and others provided are enough for me.
« Last Edit: January 29, 2021, 09:34:27 am by FlierMate »

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: Windows API test programs / Examples
« Reply #49 on: January 29, 2021, 10:37:09 am »
Then I think Process is the Windows and Host is the CPU?
The "process" is the container Windows creates to run an executable.  The process' bitness is always determined by the bitness of the executale.  IOW, a 32 bit executable runs in a 32 bit process and a 64 bit executable in a 64 bit process.

As far as "Host", without context it's a bit dangerous to define it.  For instance, the process can be considered the "host" to the executable.

This is an additional information. I am not sure how .NET detects Windows bitness although I believe there is a simpler way (than IsWow64)?
I have no idea how .NET goes about detecting the Windows bitness.  Based on MS' documentation, I would guess it uses the APIs IsWow64Process(2) but, personally, I prefer checking csrss.exe's bitness because that eliminates the possibility that an API may lie to the program (which some Windows APIs seem a bit too fond of doing and seems to be quite acceptable to MS in general.)

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: Windows API test programs / Examples
« Reply #50 on: January 29, 2021, 01:15:57 pm »
I ran TISWOW64.pas on my machine and get:

Quote
Running "e:\tiswow64.exe "
Machines: Process = 0000, Host = 014C

From MS docs, I found 0x014C is:
Quote
0x14c
Intel 386 or later processors and compatible processors

If your Windows is a 32-bit Windows, then this is indeed correct.

As others already said, if your Windows is a 64-bit one running on a x86 64-bit processor then HostMachine will be $8664 (IMAGE_FILE_MACHINE_AMD64 even for Intel CPUs because Intel licensed the 64-bit extensions from AMD).

Then I think Process is the Windows and Host is the CPU?

No. ProcessMachine is the machine type of the process if different from HostMachine and HostMachine is the machine type the operating system is using natively. The CPU needs to be determined differently (at least for e.g. Intel vs. AMD vs. VIA).

FlierMate

  • Guest
Re: Windows API test programs / Examples
« Reply #51 on: January 29, 2021, 02:02:16 pm »
Thanks 440bx and PascalDragon for the explanation. Learned a bit because I am new to OS and most part of Windows API.

With that said  :D, I think I found a quick way to determine Windows Bitness.
Code: [Select]
GetSystemWow64DirectoryA
Quote
Retrieves the path of the system directory used by WOW64. This directory is not present on 32-bit Windows.

Someone posted the ASM code and I modified it a bit and compile to EXE... if you want to test. Or perhaps can implement it in Pascal?

EDIT ON Mar 1st, 2021:

The "64-bit Windows" and "32-bit Windows" text string in the EXE (compiled by Flat Assembler) do not have null byte as terminated string. That's why you might already notice on 64-bit Windows, you get "64-bit Windows. 32-bit Windows" concatenated together.

Below is the correct code (just append ",0" to the back of both text string):
(However, I am not going to re-compile and re-upload the correct version of EXE. If you like, you can compile it yourself with FASM )
Code: ASM  [Select][+][-]
  1. format PE GUI 4.0
  2.  
  3. entry start
  4.  
  5. include '\fasm\include\win32a.inc'
  6.  
  7. section '.data' data readable writeable
  8.  
  9. a rb MAX_PATH
  10. IS64 db '64-bit Windows',0
  11. IS32 db '32-bit Windows',0
  12.  
  13. section '.code' code readable executable
  14.  
  15. start:
  16.       invoke GetSystemWow64Directory, a, MAX_PATH
  17.       cmp eax, 0
  18.       je NOT64
  19.  
  20.       invoke MessageBox, 0, IS64, a, MB_OK
  21.       jmp exit
  22. NOT64:
  23.       invoke MessageBox, 0, IS32, '', MB_OK
  24.  
  25. exit:
  26.       invoke ExitProcess, 0        
  27.      
  28. section '.idata' import data readable
  29.  
  30.  library kernel32,'kernel32.dll',\
  31.       user32,'user32.dll'
  32.  
  33. import kernel32,\
  34.      ExitProcess,'ExitProcess',\
  35.      GetSystemWow64Directory,'GetSystemWow64DirectoryA'
  36.  
  37. import user32,\
  38.      MessageBox,'MessageBoxA'


« Last Edit: March 01, 2021, 02:58:04 pm by FlierMate »

FlierMate

  • Guest
Re: Windows API test programs / Examples
« Reply #52 on: January 29, 2021, 02:33:54 pm »
I have modified the previous TIsWow64Process.pas with this one. Please help to rectify it if not correct..  :P

Code: Pascal  [Select][+][-]
  1. program tiswow64;
  2.  
  3.  
  4. {$APPTYPE CONSOLE}
  5.  
  6. uses Windows, SysUtils;
  7.  
  8. procedure TestWow64Process2;
  9. type
  10.   TIsWow64Process2 = function(lpBuffer: PCHAR; uSize: UINT): UINT; stdcall;
  11. var
  12.   K32: HMODULE;
  13.   P: FARPROC;
  14.   Buffer: PCHAR;
  15. begin
  16.   K32 := GetModuleHandle(kernel32);
  17.   P := GetProcAddress(K32, 'GetSystemWow64DirectoryA');
  18.   if Assigned(P) then begin
  19.     if TIsWow64Process2(P)(@Buffer, 255)>0 then begin
  20.       Writeln('64-bit' + Buffer);
  21.     end else
  22.       Writeln('32-bit');
  23.   end else
  24.     Writeln('GetSystemWow64DirectoryA not found');
  25.   ReadLn;
  26. end;
  27.  
  28. begin
  29.   TestWow64Process2;
  30. end.
  31.  

ASerge

  • Hero Member
  • *****
  • Posts: 2222
Re: Windows API test programs / Examples
« Reply #53 on: January 29, 2021, 03:38:40 pm »
I have modified the previous TIsWow64Process.pas with this one. Please help to rectify it if not correct..  :P
Interesting idea. Only you forgot to allocate memory for the buffer.
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2.  
  3. uses Windows, SysUtils;
  4.  
  5. procedure TestWow64Process2;
  6. type
  7.   GetSystemWow64DirectoryA = function(lpBuffer: PCHAR; uSize: UINT): UINT; stdcall;
  8. var
  9.   P: FARPROC;
  10.   Buffer: array[Byte] of AnsiChar;
  11. begin
  12.   P := GetProcAddress(GetModuleHandle(kernel32), 'GetSystemWow64DirectoryA');
  13.   if Assigned(P) then
  14.     if GetSystemWow64DirectoryA(P)(@Buffer, Length(Buffer)) > 0 then
  15.       Writeln('64-bit ' + Buffer)
  16.     else
  17.       Writeln('32-bit')
  18.   else
  19.     Writeln('GetSystemWow64DirectoryA not found');
  20. end;
  21.  
  22. begin
  23.   TestWow64Process2;
  24.   ReadLn;
  25. end.

FlierMate

  • Guest
Re: Windows API test programs / Examples
« Reply #54 on: January 29, 2021, 04:03:18 pm »
Thanks @ASerge for the nice correction.

I just need to replace plus sign with comma on my FPC 3.2.0:
Code: Pascal  [Select][+][-]
  1. Writeln('64-bit ', Buffer)

Have you tested it? Not sure what is the result if running on 64-bit Windows (both ARM64 and AMD64).

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: Windows API test programs / Examples
« Reply #55 on: January 29, 2021, 04:18:06 pm »
Just an observation, you probably don't need to GetProcAddress the function since it is implemented in Windows XP and above.  IOW, you need the GetProcAddress only for O/Ses older than XP.

This also means that the "else" part of the "if Assigned" can report the O/S as being 32 bit (it cannot be anything else, at least on intel compatible hardware.)

Tested on 64 bit Windows and 32 bit Windows XP, not tested on any ARM cpu.

It would be nice to know if that method works on an ARM64.  Maybe PascalDragon can do that test if he is so inclined. ;)

part of my test program :
Code: Pascal  [Select][+][-]
  1. function WndProc (Wnd : HWND; Msg : UINT; wParam, lParam : ptrint)
  2.          : ptrint; stdcall;
  3.   { main application/window handler function                                  }
  4. const
  5.   GetSystemWow64Directory_Call
  6.     = 'GetSystemWow64Directory (Buf : pchar; BufSize : UINT) : UINT;';
  7.  
  8.   SystemWow64Directory : packed array[0..MAX_PATH] of char = #0;
  9.  
  10.   NotImplemented       = 'There is no Wow64 directory in this installation';
  11.  
  12.   DisplayText          : pchar = NotImplemented;  { 32 bit                    }
  13.  
  14. var
  15.   ps           : TPAINTSTRUCT;
  16.   ClientRect   : TRECT;
  17.   Buf          : packed array[0..MAX_PATH] of char;
  18.   TextSize     : TSIZE;
  19.  
  20. begin
  21.   WndProc := 0;
  22.  
  23.   case Msg of
  24.     WM_CREATE:
  25.     begin
  26.       ZeroMemory(@SystemWow64Directory, sizeof(SystemWow64Directory));
  27.  
  28.       if GetSystemWow64Directory(SystemWow64Directory,
  29.                           sizeof(SystemWow64Directory)) <> 0 then
  30.       begin
  31.         DisplayText := SystemWow64Directory;  { s/b 64 bit                    }
  32.       end;
  33.     end;
  34.  
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: Windows API test programs / Examples
« Reply #56 on: January 30, 2021, 06:45:58 pm »
I just need to replace plus sign with comma on my FPC 3.2.0:
Code: Pascal  [Select][+][-]
  1. Writeln('64-bit ', Buffer)

You need to compile with {$H+}.

Have you tested it? Not sure what is the result if running on 64-bit Windows (both ARM64 and AMD64).

The output is the following on both x86_64 and aarch64:

Code: [Select]
64-bit C:\WINDOWS\SysWOW64
Please note however that you can not detect whether you're running on Windows on ARM64 this way, only that you're running on a 64-bit system which is where IsWow64Process2 comes in if one doesn't want to parse an important PE file like csrss.exe as 440bx is doing.

FlierMate

  • Guest
Re: Windows API test programs / Examples
« Reply #57 on: January 31, 2021, 08:22:42 am »
Just an observation, you probably don't need to GetProcAddress the function since it is implemented in Windows XP and above......
Tested on 64 bit Windows and 32 bit Windows XP, not tested on any ARM cpu..

Good catch. And thanks for the testing.

You need to compile with {$H+}.

The output is the following on both x86_64 and aarch64:

Code: [Select]
64-bit C:\WINDOWS\SysWOW64
Please note however that you can not detect whether you're running on Windows on ARM64 this way, only that you're running on a 64-bit system which is where IsWow64Process2 comes in if one doesn't want to parse an important PE file like csrss.exe as 440bx is doing.

Didn't know about the long string compiler directive, hah. And thanks a lot for helping to test it on ARM64 as well.
I admit that it would be good to know CPU architecture as well.

Can I say we have third method to check for Windows Bitness?    8)

From the reply of one of .NET user, he said he used:
Code: [Select]
public static bool Is64BitOperatingSystem { get; }
It is intriguing if System.Runtime.dll has some access to Win32 APIs, or has direct access to the operating system? Of course this is not in the scope of this series of topic discussion.


440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: Windows API test programs / Examples
« Reply #58 on: January 31, 2021, 11:08:19 am »
Good catch. And thanks for the testing.
You're welcome.

Can I say we have third method to check for Windows Bitness?    8)
The method you've proposed looks quite reasonable but, the fact that MS does not acknowledge it could be used to determine the O/S bitness creates some doubt about its reliability.  The same can be said about GetNativeSystemInfo, at first glance, it would also seem to be a reasonable alternative but, given the fact that MS can muck around with either leaves open some room for discomfort.

It is intriguing if System.Runtime.dll has some access to Win32 APIs, or has direct access to the operating system? Of course this is not in the scope of this series of topic discussion.
Access to the API is direct access to the O/S (at least its user mode part) and .NET most definitely has direct access to the API but, it is on the programmer's shoulders to ensure any direct access to the API doesn't violate assumptions the .NET framework makes about a .NET program.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018