The MASM Forum

Projects => Poasm => Topic started by: Vortex on January 19, 2025, 05:26:52 AM

Title: Retrieving the version of EXEs and DLLs
Post by: Vortex on January 19, 2025, 05:26:52 AM
Here is a command line tool to get the version of the an exe\dll.

Tested on Windows 7 Sp1 :

GetFileVersion.exe C:\Windows\System32\ntdll.dll
6.1.7601.24545
Title: Re: Retrieving the version of EXEs and DLLs
Post by: NoCforMe on January 20, 2025, 06:23:23 AM
Here's my GUI file version display app. (Code available to those interested.)
Title: Re: Retrieving the version of EXEs and DLLs
Post by: Vortex on January 20, 2025, 07:02:53 AM
Hi NoCforMe,

Thanks for your GUI version.
Title: Re: Retrieving the version of EXEs and DLLs
Post by: NoCforMe on January 20, 2025, 07:28:08 AM
And thanks for your console app.
Title: Re: Retrieving the version of EXEs and DLLs
Post by: NoCforMe on January 20, 2025, 04:23:11 PM
Hey, you should expand your version to show all the other interesting stuff that GetFileVersionInfo() gives you.

My source attached.
Title: Re: Retrieving the version of EXEs and DLLs
Post by: sinsi on January 22, 2025, 12:35:24 PM
Quotefatal error A1000:cannot open file : WhatVer_bitmaps.inc
Title: Re: Retrieving the version of EXEs and DLLs
Post by: NoCforMe on January 22, 2025, 01:10:44 PM
Aaargh. Sorry 'bout that; guess I didn't think anyone would actually want to download this.
Attached here. (This is my "poor man's resource file", an assembler include file that has the bitmaps as DB statements. Avoids use of the resource compiler.)
Title: Re: Retrieving the version of EXEs and DLLs
Post by: greenozon on January 22, 2025, 07:42:43 PM
@NoCforMe
thanks for nice piece of code!

some questions raised after building it up/ using on the field:

1) Unicode file names support?  -> https://prnt.sc/XOrFOk6JHm2j (https://prnt.sc/XOrFOk6JHm2j)
Title: Re: Retrieving the version of EXEs and DLLs
Post by: jj2007 on January 22, 2025, 07:44:01 PM
Quote from: Vortex on January 19, 2025, 05:26:52 AMTested on Windows 7 Sp1 :

Tested on Windows 10 - works like a charm:
GetFileVersion.exe \Masm32\bin\ml.exe
14.29.30154.0

Similar but with GetFileProps (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1389):
  GetFileProps CL$() ; get the props of the file passed in the commandline
  For_ ecx=0 To FileProp$(?)-1
Print Str$("%_i  ", ecx), FilePropName$(ecx) ; show the predefined names
wPrintLine At(30) wRec$(FileProp$(ecx)) ; descriptions may be Utf8
  Next

0  Lang                      040904B0
 1  Comments                  ?
 2  InternalName              POASM
 3  ProductName               Pelles C for Windows
 4  CompanyName               Pelle Orinius
 5  LegalCopyright            Copyright © Pelle Orinius 2005-2011
 6  ProductVersion            6.50
 7  FileDescription           Pelles Macro Assembler
 8  LegalTrademarks           ?
 9  PrivateBuild              ?
10  FileVersion               6.50.0
11  OriginalFilename          POASM.EXE
12  SpecialBuild              ?
13  Lang                      041D04B0
14  Comments                  ?
15  InternalName              POASM
16  ProductName               Pelles C för Windows
17  CompanyName               Pelle Orinius
18  LegalCopyright            Copyright © Pelle Orinius 2005-2011
19  ProductVersion            6.50
20  FileDescription           Pelles makro-assemblator
21  LegalTrademarks           ?
22  PrivateBuild              ?
23  FileVersion               6.50.0
24  OriginalFilename          POASM.EXE
25  SpecialBuild              ?

No. 16 looks interesting ;-)
Title: Re: Retrieving the version of EXEs and DLLs
Post by: NoCforMe on January 24, 2025, 03:14:10 AM
Quote from: greenozon on January 22, 2025, 07:42:43 PM@NoCforMe
thanks for nice piece of code!

some questions raised after building it up/ using on the field:

1) Unicode file names support?  -> https://prnt.sc/XOrFOk6JHm2j (https://prnt.sc/XOrFOk6JHm2j)


Looks like I've got some more work to do on this.
You could start with my code and add Unicode capability. (I guess you'd need to use the ___W() versions of functions here.)
Title: Re: Retrieving the version of EXEs and DLLs
Post by: greenozon on January 27, 2025, 05:52:21 AM
@NoCforMe
I'm reading the code of your sources
how about this small refactoring?
reading 2 goals:
1) less lines to code
2) more clear to understand as well as #3:
more ready to migrate to x64 masm (as you are omitting direct ref to eax CPU reg)

; Create brush to set background color:
   INVOKE   GetSysColor, COLOR_BTNFACE      ;Color to match dialog bkground.
   MOV   BkColor, EAX
   INVOKE   CreateSolidBrush, EAX
   MOV   BkBrush, EAX            ;Store in a global (needed for subclassed statics).


--->


   MOV   BkColor, rv(GetSysColor, COLOR_BTNFACE) ;Color to match dialog bkground.
   MOV   BkBrush, rv(CreateSolidBrush, EAX)      ;Store in a global (needed for subclassed statics).

Title: Re: Retrieving the version of EXEs and DLLs
Post by: NoCforMe on January 27, 2025, 08:14:11 AM
Yeah, thanks, but:
1. I don't care--at all--about 64-bit operability for my own code. I only write 32-bit code.
2. Don't like to use macros like rv(xxx) for my own code.

However, for other coders here, good suggestion.
Title: Re: Retrieving the version of EXEs and DLLs
Post by: jj2007 on January 27, 2025, 07:14:48 PM
Quote from: NoCforMe on January 27, 2025, 08:14:11 AM2. Don't like to use macros like rv(xxx) for my own code.

You shouldn't use invoke, really :cool:
Title: Re: Retrieving the version of EXEs and DLLs
Post by: TimoVJL on January 27, 2025, 07:41:45 PM
Code Design (https://www.cs.emory.edu/~cheung/Courses/255/Syllabus/9-Intel/masm32/html/codedesn.htm)
Title: Re: Retrieving the version of EXEs and DLLs
Post by: jj2007 on January 27, 2025, 08:24:20 PM
Quote from: TimoVJL on January 27, 2025, 07:41:45 PMCode Design

This looks like written by Hutch :cool:
Title: Re: Retrieving the version of EXEs and DLLs
Post by: zedd151 on January 27, 2025, 09:21:49 PM
Quote from: jj2007 on January 27, 2025, 08:24:20 PM
Quote from: TimoVJL on January 27, 2025, 07:41:45 PMCode Design

This looks like written by Hutch :cool:

Or at the very least, in the style of hutch--, as used in the early days of Masm32 SDK development- in the documentation. It does look very familiar.


A short time later... I had to dig deeper...  :tongue:
Looking further up the tree in the url that TimoVJL posted, there is a complete partial Masm32 SDK package there (but the SDK install .exe is also along the url path). It uses qeditor version 3.0n in that version of the Masm32 SDK. A very old version... Seems it was used in a university course at one time.

https://www.cs.emory.edu/~cheung/Courses/255/Syllabus/9-Intel/masm32/ (https://www.cs.emory.edu/~cheung/Courses/255/Syllabus/9-Intel/masm32/)
If my assumptions are correct, the file linked by Timo was in fact written by hutch--. :)  Good catch, Jochen. It was part of the html help files for that version of the Masm32 SDK.

Still later...
That is all from The Masm32 SDK, version 9.0 release.  :smiley:
Hutch did mention a few times that he did license some version(s) of the Masm32 SDK to universities/colleges at one point.


P.S. sorry for the detour, but I had to get to the bottom of this...  :azn:
Title: Re: Retrieving the version of EXEs and DLLs
Post by: greenozon on January 27, 2025, 10:33:49 PM
Hutch is back from... his heavens?  :shhh:
Title: Re: Retrieving the version of EXEs and DLLs
Post by: NoCforMe on January 28, 2025, 08:37:02 AM
Quote from: jj2007 on January 27, 2025, 07:14:48 PM
Quote from: NoCforMe on January 27, 2025, 08:14:11 AM2. Don't like to use macros like rv(xxx) for my own code.

You shouldn't use invoke, really :cool:
That's the exception to my rule.
invoke is so much better than the alternative, push-push-call.
Title: Re: Retrieving the version of EXEs and DLLs
Post by: TimoVJL on January 28, 2025, 07:42:02 PM
Invoke is directive in masm32 / ml.exe
So not a macro.
Title: Re: Retrieving the version of EXEs and DLLs
Post by: NoCforMe on January 29, 2025, 08:56:07 AM
Quote from: TimoVJL on January 28, 2025, 07:42:02 PMInvoke is directive in masm32 / ml.exe
So not a macro.

Correct. According to my MASM 6.1 manual,

QuoteMASM provides the INVOKE directive to handle many of the details important to procedure calls,

So there.
Makes me feel better about my no-macros rule.
Title: Re: Retrieving the version of EXEs and DLLs
Post by: HSE on January 29, 2025, 12:37:24 PM
Quote from: Vortex on January 19, 2025, 05:26:52 AMHere is a command line tool to get the version of the an exe\dll.

Nice  :thumbsup:

Build and run in Win10 perfectly.
Title: Re: Retrieving the version of EXEs and DLLs
Post by: daydreamer on January 30, 2025, 02:56:15 AM
This thread made me curious about how to put in my own exe and dll version number instead of being limited to renaming file name my program V2.0 and comment in beginning of main source file ; my program V2.0?

Title: Re: Retrieving the version of EXEs and DLLs
Post by: zedd151 on January 30, 2025, 03:02:25 AM
Quote from: daydreamer on January 30, 2025, 02:56:15 AMThis thread made me curious about how to put in my own exe and dll version number instead of being limited to renaming file name my program V2.0 and comment in beginning of main source file ; my program V2.0?

VERSIONINFO Resource (https://learn.microsoft.com/en-us/windows/win32/menurc/versioninfo-resource)   :smiley:
Title: Re: Retrieving the version of EXEs and DLLs
Post by: TimoVJL on January 30, 2025, 03:23:51 AM
Creating a Proper Version Information Resource (https://www.osr.com/nt-insider/2011-issue2/creating-proper-version-information-resource/)
Title: Re: Retrieving the version of EXEs and DLLs
Post by: Vortex on January 30, 2025, 05:26:00 AM
Hi daydreamer,

Here is an example from Hutch. Downloading the attachment from this thread :

https://masm32.com/board/index.php?topic=88.0 (https://masm32.com/board/index.php?topic=88.0)

The resource script :

#include "Resource.h"

1 24 "barewin.xml"

5 ICON "barewin.ico"

// ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

VS_VERSION_INFO VERSIONINFO
FILEVERSION 1, 0, 0, 0
PRODUCTVERSION 1, 0, 0, 0
FILEOS VOS_WINDOWS32
FILETYPE VFT_APP
BEGIN
  BLOCK "StringFileInfo"
  BEGIN
    BLOCK "040904B0"
    BEGIN
      VALUE "CompanyName",      "PowerBASIC Inc\000"
      VALUE "FileDescription",  "Bare API Window\000"
      VALUE "FileVersion",      "1.0\000"
      VALUE "InternalName",    "barewin\000"
      VALUE "OriginalFilename", "barewin.exe\000"
      VALUE "LegalCopyright",  "\251 2011 PowerBASIC Inc\000"
      VALUE "ProductName",      "barewin\000"
      VALUE "ProductVersion",  "1.0\000"
    END
  END
  BLOCK "VarFileInfo"
  BEGIN
    VALUE "Translation", 0x409, 0x4B0
  END
END
Title: Re: Retrieving the version of EXEs and DLLs
Post by: ognil on January 30, 2025, 08:02:51 AM
It is from DeepSeek, :biggrin:

; Retrieve Version Information for Windows Executables in x64 Assembly
; Assemble with NASM and link with version.lib and kernel32.lib

section .data
    filename    db "C:\\path\\to\\file.exe",0  ; Replace with your file path
    subBlock    db "\",0                       ; Root block for version info
    errorMsg    db "Error retrieving version information.",0

section .bss
    versionSize resd 1          ; Size of version info buffer
    versionInfo resq 1          ; Pointer to version info buffer
    fixedInfo   resq 1          ; Pointer to fixed file info structure
    fixedLen    resd 1          ; Length of fixed file info

section .text
    global Start
    extern GetFileVersionInfoSizeA
    extern GetFileVersionInfoA
    extern VerQueryValueA
    extern VirtualAlloc
    extern VirtualFree
    extern ExitProcess

Start:
    ; Get version information size
    sub rsp, 32                 ; Shadow space + alignment
    lea rcx, [filename]
    xor edx, edx
    call GetFileVersionInfoSizeA
    add rsp, 32
    test eax, eax
    jz error
    mov [versionSize], eax

    ; Allocate memory for version info
    sub rsp, 32
    xor rcx, rcx                ; lpAddress
    mov edx, [versionSize]      ; dwSize
    mov r8, 0x1000              ; MEM_COMMIT
    mov r9, 4                   ; PAGE_READWRITE
    call VirtualAlloc
    add rsp, 32
    test rax, rax
    jz error
    mov [versionInfo], rax

    ; Retrieve version information
    sub rsp, 32
    lea rcx, [filename]
    xor edx, edx                ; dwHandle
    mov r8d, [versionSize]
    mov r9, [versionInfo]
    call GetFileVersionInfoA
    add rsp, 32
    test eax, eax
    jz error

    ; Query fixed file information
    sub rsp, 32
    mov rcx, [versionInfo]
    lea rdx, [subBlock]
    lea r8, [fixedInfo]
    lea r9, [fixedLen]
    call VerQueryValueA
    add rsp, 32
    test eax, eax
    jz error

    ; Extract version numbers
    mov rsi, [fixedInfo]
    mov eax, [rsi + 8]          ; dwFileVersionMS
    mov edx, [rsi + 12]         ; dwFileVersionLS

    ; Major = HIWORD(dwFileVersionMS)
    ; Minor = LOWORD(dwFileVersionMS)
    ; Build = HIWORD(dwFileVersionLS)
    ; Revision = LOWORD(dwFileVersionLS)
    mov ecx, eax
    shr ecx, 16                 ; Major version
    mov ebx, eax
    and ebx, 0xFFFF             ; Minor version
    mov esi, edx
    shr esi, 16                 ; Build number
    mov edi, edx
    and edi, 0xFFFF             ; Revision number

    ; Clean up allocated memory
    sub rsp, 32
    mov rcx, [versionInfo]
    xor edx, edx
    mov r8, 0x8000              ; MEM_RELEASE
    call VirtualFree
    add rsp, 32

    ; Exit with success
    xor ecx, ecx
    call ExitProcess

error:
    ; Handle error (exit with code 1)
    mov ecx, 1
    call ExitProcess

Title: Re: Retrieving the version of EXEs and DLLs
Post by: TimoVJL on January 30, 2025, 08:21:09 AM
From DeepSeek
; MASM 64-bit example to get file version information using GetFileVersionInfo

extrn GetFileVersionInfoSizeExW : proc
extrn GetFileVersionInfoExW : proc
extrn VerQueryValueW : proc
extrn GetLastError : proc
extrn ExitProcess : proc
extrn MessageBoxW : proc
extrn wsprintfW : proc
extrn LocalFree : proc

.data
wszFileName        dw 'C', ':', '\', 'P', 'a', 't', 'h', '\', 'T', 'o', '\', 'Y', 'o', 'u', 'r', 'F', 'i', 'l', 'e', '.', 'e', 'x', 'e', 0
wszSubBlock        dw '\', 0
wszFormat          dw 'File Version: %d.%d.%d.%d', 0
wszCaption         dw 'File Version Info', 0
wszError           dw 'Error getting file version info', 0
dwVersionInfoSize  dd 0
pVersionInfo       dq 0
pVersionBuffer     dq 0
dwLangCodepage     dd 0
dwFileVersionMS    dd 0
dwFileVersionLS    dd 0
wszBuffer          dw 256 dup(0)

.code
main proc
    ; Get the size of the version information
    mov rcx, 0
    lea rdx, wszFileName
    mov r8, 0
    lea r9, dwVersionInfoSize
    call GetFileVersionInfoSizeExW
    test rax, rax
    jz error_exit

    ; Allocate memory for the version information
    mov ecx, dwVersionInfoSize
    call LocalAlloc
    mov pVersionInfo, rax
    test rax, rax
    jz error_exit

    ; Get the version information
    mov rcx, 0
    lea rdx, wszFileName
    mov r8, 0
    mov r9, dwVersionInfoSize
    mov rax, pVersionInfo
    push rax
    sub rsp, 20h
    call GetFileVersionInfoExW
    add rsp, 20h
    test rax, rax
    jz error_exit

    ; Query the file version
    lea rcx, wszSubBlock
    lea rdx, pVersionBuffer
    lea r8, dwVersionInfoSize
    mov r9, pVersionInfo
    call VerQueryValueW
    test rax, rax
    jz error_exit
®
    ; Extract the file version
    mov rax, pVersionBuffer
    mov eax, [rax+8]  ; FileVersionMS
    mov dwFileVersionMS, eax
    mov eax, [rax+12] ; FileVersionLS
    mov dwFileVersionLS, eax

    ; Format the version string
    lea rcx, wszBuffer
    lea rdx, wszFormat
    mov r8d, dwFileVersionMS
    shr r8d, 16
    mov r9d, dwFileVersionMS
    and r9d, 0FFFFh
    mov eax, dwFileVersionLS
    shr eax, 16
    push rax
    mov eax, dwFileVersionLS
    and eax, 0FFFFh
    push rax
    call wsprintfW
    add rsp, 10h

    ; Display the version information
    mov rcx, 0
    lea rdx, wszBuffer
    lea r8, wszCaption
    mov r9, 0
    call MessageBoxW

    ; Clean up
    mov rcx, pVersionInfo
    call LocalFree

    ; Exit
    xor rcx, rcx
    call ExitProcess

error_exit:
    ; Display error message
    mov rcx, 0
    lea rdx, wszError
    lea r8, wszCaption
    mov r9, 0
    call MessageBoxW

    ; Exit with error
    mov rcx, 1
    call ExitProcess
main endp

end