GetMem, I added your function to Wiki: http://wiki.freepascal.org/Multiplatform_Programming_Guide#Detecting_bitness_of_external_library_before_loading_itThank you @Zoran!
And I don't know is there a reason why you cut Pointer to LongWordInitially I wrote that function for delphi, where an explicit typecast needed, otherwise the function won't compile. The error message( both with D2007 and XE4): "E2015 Operator not applicable to this operand type".
Now I noticed that compiler issues hints on these two lines:Because we casting a pointer to a fixed size variable. The compiler knows that the size of pointers can have different values on different platforms, while the size of the variable stays the same(or not, it depends on a lot of things), hence the warning, nothing to worry about in my opinion.
in a 64-bit application this might lose significant bitsYou have a valid point here, Longword is enough for a 32 bit system, but NativeUInt(PtrUint) or QWord is more appropriate for 64 bit. Your pointer alternative is also good if you don't mind dropping the delphi compatibility support.
Now, another thing, this function can never return PE_16BIT, take a look at these lines (see added comments):You're correct! It's a logical error, thank you for noticing it. Feel free to modify the code anyway you like, personally I don't think 16 bit support is needed nowadays.
QuoteNow, another thing, this function can never return PE_16BIT, take a look at these lines (see added comments):You're correct! It's a logical error, thank you for noticing it. Feel free to modify the code anyway you like, personally I don't think 16 bit support is needed nowadays.
Are you sure that it works well for 16-bitif PIDH^.e_magic = IMAGE_DOS_SIGNATURE then // Executable
@ZoranNo, that was a logical error. My original code would fail to detect a 16 bit PE as you correctly pointed out in one of your previous post. I don't think it's a way to detect a corrupted 16/32/64 PE other then checking if a valid IMAGE_DOS_SIGNATURE, IMAGE_NT_SIGNATURE, etc... exist. I meant PE_UNKNOWN for special cases when the path to file is invalid or the memory map could not be crated or something else.
I'm asking because in the first version (see this post), there was a protective block, and I'm affraid that it was maybe inserted when the function returned 16-bit when it was not a valid 16-bit dll (I don't know, but it just looks like that...).
@ASergeYes, your code is more compact, however I prefer a slightly verbose approach. It's much easier this way to figure out what the code does at a later time. For example instead of:
Multiple CloseHandle calls can be excluded.
Test
Result with 64 compiler:
c:\Windows\SysWOW64\netmsg.dll is 32 bit
c:\Windows\System32\netmsg.dll is 64 bit
c:\Windows\Sysnative\netmsg.dll is Unknown
c:\Windows\twain.dll is 16 bit
c:\Windows\twain_32.dll is 32 bit
Result with 32 compiler:
c:\Windows\SysWOW64\netmsg.dll is 32 bit
c:\Windows\System32\netmsg.dll is 32 bit
c:\Windows\Sysnative\netmsg.dll is 64 bit
c:\Windows\twain.dll is 16 bit
c:\Windows\twain_32.dll is 32 bit
My original code would fail to detect a 16 bit PE as you correctly pointed out in one of your previous post.just FYI, there is no such thing as a 16bit PE.
Do you know why the result is different for c:\Windows\Sysnative\netmsg.dll ? the 64bit version says "unknown" and the 32bit version says 64 bit. Do you know if Windows is playing some kind of trick on 32bit executables when they look at files in the Sysnative directory or is there some other reason for the difference ?The Sysnative doesn't really exist. It's a redirection which is only available in 32 bit processes. So not available in 64 bit.
Note that 64-bit applications cannot use the Sysnative alias as it is a virtual directory not a real one.https://docs.microsoft.com/nl-nl/windows/desktop/WinProg64/file-system-redirector
The Sysnative doesn't really exist. It's a redirection which is only available in 32 bit processes. So not available in 64 bit.Thank you. :)