Recent

Author Topic: WinAPI - examples - post 5  (Read 440 times)

440bx

  • Hero Member
  • *****
  • Posts: 2295
WinAPI - examples - post 5
« on: February 23, 2021, 10:45:22 am »
This post includes examples for the following APIs :

WinAPI - GetFileSize
WinAPI - GetFileSizeEx

These two examples show how to get a file's size.  GetFileSize should be avoided because the results it returns can be ambiguous for large files.  For this reason, it is preferable to always use GetFileSizeEx.



WinAPI - GetSystemInfo
WinAPI - GetNativeSystemInfo

These two functions are very similar, almost identical.  The critical difference is in how the Processor Architecture is reported.

Presuming the program is run on a 64 bit intel/AMD CPU, A 32 bit program that uses GetSystemInfo will always see the processor architecture as PROCESSOR_ARCHITECTURE_INTEL, while a 32 bit program using GetNativeSystemInfo will see PROCESSOR_ARCHITECTURE_INTEL when running under a 32 bit version of Windows and see PROCESSOR_ARCHITECTURE_AMD64 when running under a 64 bit version of Windows.  The reported processor type will also be different in the above mentioned cases, one case reporting PROCESSOR_INTEL_PENTIUM and the other reporting PROCESSOR_AMD_X8664.

In spite of that, MS documentation claims that using GetNativeSystemInfo is _not_ a reliable method to determine the O/S bitness.





WinAPI - GetVersion     (deprecated)
WinAPI - GetVersionEx (deprecated)

WinAPI - RtlGetNtVersionNumbers (undocumented)

Both GetVersion and GetVersionEx should be avoided not only because they are deprecated but, because these functions (and a few others) don't report the _true_/real Windows version the program is running under.

On the other hand, RtlGetNtVersionNumbers reports the _true_ and accurate Windows version.

The function (in NTDLL) is as simple as can, and should be:
Code: ASM  [Select][+][-]
  1.                          public RtlGetNtVersionNumbers
  2. RtlGetNtVersionNumbers proc near
  3.  
  4.                 test    rcx, rcx            ; ensure pointer not nil
  5.                 jz      short loc_78E9517B
  6.                 mov     dword ptr [rcx], 6
  7.  
  8. loc_78E9517B:
  9.                 test    rdx, rdx            ; ensure pointer not nil
  10.                 jz      short loc_78E95186
  11.                 mov     dword ptr [rdx], 1
  12.  
  13. loc_78E95186:
  14.                 test    r8, r8              ; ensure pointer not nil
  15.                 jnz     loc_78EB7C9D        ; see below
  16.                 rep retn
  17. RtlGetNtVersionNumbers endp
  18.  
  19. loc_78EB7C9D:
  20.                 ; F000 -> free build
  21.                 ; 1DB1 -> build number
  22.  
  23.                 mov     dword ptr [r8], 0F0001DB1h
  24.                 retn
  25.  
Before any other consideration, it is worth pointing out that while this function is undocumented, some important MS code depends on its existence, notably some standard C dlls.  Obviously, deciding for or against using undocumented functions is programmer's choice.  In the case of this function, it's likely that it's here to stay.

The example RtlGetNtVersionNumbers comes in two "flavors", GUI and Console. From a programming viewpoint, there is nothing particularly remarkable in the GUI version.  The console version has some remarkable characteristics, not due to the API but, due to how FPC manages consoles and, getting a console application to display a dialog box by selecting a menu item appended to the system menu.

As far as how FPC manages consoles, the FPC RTL assumes that there can only be one console during the life of a program.  That assumption is incorrect. Consoles, just like any other "resource" can come and go at any time and multiple times.

The functions in console.inc are "general" in nature (actually, only somewhat general.)  They are meant to be used by a GUI program which creates and deletes multiple consoles during its execution.  Something the RtlGetNtVersionNumbers example does _not_ do.

For a discussion of how the FPC RTL manages consoles, see the thread :
https://forum.lazarus.freepascal.org/index.php/topic,44828.msg315468.html#msg315468
The last post includes an example program.


The other purpose of console.inc is to provide a mechanism for a console application to display a dialog box (usually with author's name, copyright, etc.) This sounds like it would be a trivial thing to do but, I could not find a simple and straightforward solution that worked reliably.  The solution in console.inc is pure brute force (but it works :)). It creates a thread specifically with the goal of figuring out if the "About ..." item in the system menu was selected and, if so, presents the dialog box.

If someone can come up with a simpler solution that works reliably to display the dialog box, that would be a very welcome and appreciated improvement.

If it weren't for the code to manage the creation and destruction of multiple consoles and displaying a dialog box, the console version of this API example would be totally trivial

Enjoy!
« Last Edit: February 23, 2021, 02:06:44 pm by 440bx »
FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

 

TinyPortal © 2005-2018