Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

DLL Versions from C and VB


May 2001/DLL Versions from C and VB/Listing 2

Listing 2: verres.bas — Version extractor for VB

Attribute VB_Name = "Module1"
Option Explicit
'-- Win32 API Declarations
Private Declare Function LoadLibrary Lib "kernel32" _
        Alias "LoadLibraryA" _
        (ByVal lpLibFileName As String) As Long
Private Declare Function FindResource Lib "kernel32" _
        Alias "FindResourceA" (ByVal hInstance As Long, _
        ByVal lpName As String, ByVal lpType As String) As Long
Private Declare Function FindResourceI Lib "kernel32" _
        Alias "FindResourceA" (ByVal hInstance As Long, _
        ByVal lpName As Long, ByVal lpType As Long) As Long
Private Declare Function LoadResource Lib "kernel32" _
        (ByVal hInstance As Long, ByVal hResInfo As Long) _
        As Long
Private Declare Function LockResource Lib "kernel32" _
        (ByVal hResData As Long) As Long
Private Declare Function GetModuleFileName Lib "kernel32" _
        Alias "GetModuleFileNameA" (ByVal hModule As Long, _
        ByVal lpFileName As String, ByVal nSize As Long) As Long
Private Declare Function FreeLibrary Lib "kernel32" _
        (ByVal hLibModule As Long) As Long
'-- VB type casting!
Public Declare Sub CopyMemoryFromPointer Lib "kernel32" _
        Alias "RtlMoveMemory" (Destination As Any, _
        ByVal Source As Long, ByVal Length As Long)

Type VS_VERSIONINFO
  wLength As Integer
  wValueLength As Integer
  wType As Integer
  szKey(29) As Byte '-- contains the UNICODE String
                    '-- "VS_VERSION_INFO" and in VB that's (29)!
  '-- Padding1(?) As Byte '-- this is the dynamic element
End Type

'-- This UDT is defined in <windows.h>, and here
'-- is the VB translation
Type VS_FIXEDFILEINFO
    dwSignature As Long
    dwStrucVersion As Long
    dwFileVersionMS As Long
    dwFileVersionLS As Long
    dwProductVersionMS As Long
    dwProductVersionLS As Long
    dwFileFlagsMask As Long
    dwFileFlags As Long
    dwFileOS As Long
    dwFileType As Long
    dwFileSubtype As Long
    dwFileDateMS As Long
    dwFileDateLS As Long
End Type

Function GetDllVersion(ByVal supFile As String, _
                       ByRef loadpath As String, _
                       ByRef maj As Long, _
                       ByRef min As Long, _
                       ByRef rev As Long, _
                       ByRef build As Long) As Boolean
'---------------------------------------------------------------
'   This function uses the supFile parameter to do a dynamic
'   load of the dll name.  Once loaded, the version resource
'   is queried for the file version number.  The version info
'   as well as the full load path are returned to the caller.
'
'   parameters:
'       supFile     [in] String         Dll file name
'       loadpath    [out] String        full path of file
'       maj         [out] integer       File version info
'       min         [out] integer       File version info
'       rev         [out] integer       File version info
'       build       [out] integer       File version info
'---------------------------------------------------------------
Dim hDll As Long
Dim retval As Long

maj = -1: min = -1: rev = -1: build = -1

GetDllVersion = False           '-- pessimistic view
hDll = LoadLibrary(supFile)     '-- try to load the file
If (hDll) Then
    '-- get the load path
    Dim tmpPath As String
    tmpPath = String(512, 0)    '-- buffer for API call
    retval = GetModuleFileName(hDll, tmpPath, 511)
    If (retval) Then
        '-- make sure there is a null(0)
        If (InStr(tmpPath, Chr$(0)) > 0) Then
            '-- trim the returned string
            loadpath = Left$(tmpPath, InStr(tmpPath, Chr$(0)) - 1)
        End If
    End If
    '-- find the version resource
    Dim hRes As Long
    hRes = FindResourceI(hDll, 1, 16)
    If (hRes) Then
        Dim hGbl As Long
        hGbl = LoadResource(hDll, hRes)
        If (hGbl) Then
            Dim lpRes As Long
            lpRes = LockResource(hGbl)
            If (lpRes) Then
                '-- lpRes is a memory pointer to file's
                '-- version resource!
                Dim verinfo As VS_VERSIONINFO   '-- make space
                '-- copy what we know of the verinfo UDT
                CopyMemoryFromPointer verinfo, lpRes, _
                   Len(verinfo)
                '-- test if we have a VS_FIXEDFILEINFO struct
                If (verinfo.wValueLength > 0) Then
                    '-- lpRes is the pointer to the locked
                    '-- resource and we need to position just
                    '-- past the known data elements...

                    '-- set the pointer to Padding1(0)
                    lpRes = lpRes + Len(verinfo)

                    '-- Since the actual Padding1 element is
                    '-- unknown in size we must loop and
                    '-- increment the memory pointer until it
                    '-- it is on a 32bit (DWORD) boundry.
                    While ((lpRes And &H4) <> 0)
                        lpRes = lpRes + 1
                    Wend

                    '-- create a variable to hold the fixed
                    '-- version info
                    Dim fInfo As VS_FIXEDFILEINFO
                    
                    '-- copy the fixed file info now
                    CopyMemoryFromPointer fInfo, lpRes, Len(fInfo)
                    
                    '-- extract the version data, and we're done!
                    maj = fInfo.dwFileVersionMS / 65535
                    min = fInfo.dwFileVersionMS And &H7FFF
                    rev = fInfo.dwFileVersionLS / 65535
                    build = fInfo.dwFileVersionLS And &H7FFF
                    GetDllVersion = True    '-- SUCCESS!!!
                End If
            End If
        End If
    End If
    '-- unload the library instance count...
    FreeLibrary (hDll)
End If
End Function

Sub main()
'-- Main application entry point.
Dim myFilename As String
Dim myLoadpath As String
Dim maj As Long, min As Long, rev As Long, bld As Long

myFilename = Command$()

If (Len(myFilename) <= 0) Then
    MsgBox "VerRes requires a filename as a parameter"
    Exit Sub
End If

If (GetDllVersion(myFilename, myLoadpath, maj, min, rev, bld)) Then
    MsgBox "File " & myFilename & " is vesion " & CStr(maj) & _
           "." & CStr(min) & "." & CStr(rev) & "." & CStr(bld), _
           vbInformation, "VerRes"
Else
    MsgBox "Couldn't get the version of " & myFilename, vbExclamation, _
           "VerRes"
End If

End Sub

Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.