Forum > Windows

WinAPI - examples - post 5

(1/1)

440bx:
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  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---                         public RtlGetNtVersionNumbersRtlGetNtVersionNumbers proc near                 test    rcx, rcx            ; ensure pointer not nil                jz      short loc_78E9517B                mov     dword ptr [rcx], 6 loc_78E9517B:                test    rdx, rdx            ; ensure pointer not nil                jz      short loc_78E95186                mov     dword ptr [rdx], 1 loc_78E95186:                test    r8, r8              ; ensure pointer not nil                jnz     loc_78EB7C9D        ; see below                rep retnRtlGetNtVersionNumbers endp loc_78EB7C9D:                ; F000 -> free build                ; 1DB1 -> build number                 mov     dword ptr [r8], 0F0001DB1h                retn 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!

Navigation

[0] Message Index

Go to full version