luqingfei@C++

为中华之崛起而崛起!
兼听则明,偏听则暗。

Win32汇编--使用资源--版本信息资源

 

Win32汇编--使用资源版本信息资源

 

有时应用程序需要确保自己运行时使用某一特定版本的DLL,以便确保可以使用某些函数。检测版本是通过API函数查询定义于资源中的版本信息来完成的,如果资源中没有定义版本,那么就无法知道一个文件的版本究竟是多少。

 

版本信息是以VERSIONINFO类型的资源保存在应用程序中的,里面可以定义的信息包括文件的版本号、创建单位和语种等。版本信息的定义是可选的,一个程序可以不定义版本信息资源,如果定义了的话,也不一定要定义全部信息项目。

 

如果一个文件定义有版本信息资源,那么在文件的属性页(在文件图标上按鼠标右键,在弹出的菜单上选择)上就会有一个“版本”页面。

 

1、版本信息资源的定义

//Version.rc

1 VERSIONINFO

FILEVERSION 1,2,3,4

PRODUCTVERSION 2,3,4,5

FILEOS VOS_WINDOWS32

FILETYPE VFT_APP

FILESUBTYPE VFT2_UNKNOWN

BEGIN

        BLOCK "VerFileInfo"

        BEGIN

                VALUE "Translation", 0x804, 0x4b0

        END

        BLOCK "StringFileInfo"

        BEGIN

                BLOCK "080404b0"

                BEGIN

                        VALUE "Comments", "Here is Comments\0"

                        VALUE "CompanyName", "Here is CompanyName\0"

                        VALUE "FileDescription", "Here is FileDescription\0"

                        VALUE "FileVersion", "1,0,0,1\0"

                        VALUE "InternalName", "Here is InternalName\0"

                        VALUE "LegalCopyright", "Here is LegalCopyright\0"

                        VALUE "LegalTrademarks", "Here is LegalTrademarks\0"

                        VALUE "OriginalFilename", "Here is OriginalFilename\0"

                        VALUE "PrivateBuild", "Here is PrivateBuild\0"

                        VALUE "ProductName", "Here is ProductName\0"

                        VALUE "ProductVersion", "1,0,0,1\0"

                        VALUE "SpecialBuild", "Here is SpecialBuild\0"

                END

        END

END

 

这些定义语句的含义。首先,版本信息定义的语句格式是:

版本信息资源ID   VERSIONINFO

固定属性

BEGIN

       块声明定义

       ……

END

 

版本信息资源ID的取值必须为1,如果不为1则属性页上的“版本”信息是无法显示出来的。(怪异!)

 

可以定义的固定属性有:

l         FILEVERSION——定义文件版本号,可以定义416位版本号xx.xx.xx.xx

l         PRODUCTVERSION——定义产品版本号,可以定义416位版本号xx.xx.xx.xx

l         FILELAGSMASK——指定FILELAGS属性中哪些位有效。

l         FILELAGS——文件标志,是一些标志位的组合:VS_FF_PATCHED,VS_FF_DEBUG,VS_FF_PRIVATEBUILD,VS_FF_INFOINFERRED,VS_FF_PRERELEASEVS_FF_SPECI_ALBUILD

l         FILEOS——定义适用的操作系统,可以定义为VOS_UNKNOWN,VOS_DOS,VOS_NT,VOS_WINDOWS16,VOS_WINDOWS32,VOS_DOS_WINDOWS16,VOS_DOW_WINDOWS32VOS_NT_WINDOW32

l         FILETYPE——定义文件的子类型。当文件类型是VFT_DRV(驱动程序)的时候,这里可以是VFT2_UNKNOWN,VFT2_DRV_COMM,VFT2_DRV_PRINTER,VFT2_DRV_KEYBOARD,VFT2_DRV_LANGUAGE,VFT2_DRV_DISPLAY,VFT2_DRV_MOUSE,VFT2_DRV_NETWORK,VFT2_DRV_SYSTEM,VFT2_DRV_INSTALLABLEVFT2_DRV_SOUND;当文件类型是VFT_FONT(字体)的时候,这里可以是VFT2_UNKNOWN,VFT2_FONT_RASTER,VFT2_FONT_VECTORVFT2_FONT_TRUETYPE

 

当固定属性定义完成以后,需要定义一些块声明,块声明有两种:变量型的信息块和字符串类型的信息块,变量类型的信息块定义如下:

BLOCK “VerFileInfo”

BEGIN

       VALUE “Translation”, 语言ID, 字符集ID

       ……

END

 

语言ID的常用值有0x0404(繁体中文)、0x0409(美国英语)和0x0804(简体中文),字符集ID的常用值有07ASCII)、950(台湾GB5)和1200Unicode)。一般使用0x804,0x4b0来定义,也就是简体中文和Unicode0x4b0=1200)。其他还有很多取值,可以查看Rc.exe的帮助文件。

 

变量类型信息块用来表示VERSIONINFO资源中定义有哪些语言和字符集的字符串类型信息块。如上例中有一句VALUE “Translation”, 0x804, 0x4b0表示对应有一个名为“080404b0”的字符串类型的信息块。

 

字符串信息块的定义语句为:

BLOCK “StringFileInfo”

BEGIN

       BLOCK “语言集

       BEGIN

              VALUE “字符串名称”, “字符串

              ……

       END

END

 

语言集就是变量类型中定义的,其名称一定要是将语言ID和字符集ID组合成一个8位的16进制的格式,以上例文件来说明,当变量类型的信息块中定义0x804, 0x4b0时,语言集名称就是“080404b0”,在语言集块的定义中,还可以定义多条字符串型的版本信息,这些版本信息的字符串名有12种,如下表所示:

版本信息字符串类型

字符串名称

属性页位置

说明

Comments

备注

有关程序的附加说明信息

CompanyName

公司

开发产品的公司

FileDescription

描述

有关文件的简单描述

FileVersion

文件版本

1.505.0.RC2等字符串型的版本信息

InternalName

内部名称

 

LegalCopyright

版权

文件的所有版权信息

LegalTrademarks

合法商标

文件的所有注册商标信息

OriginalFilename

源文件名

原始文件名,从这里可以得知文件是否被改名

PrivateBuild

个人用内部版本说明

作者私人信息

ProductName

产品名称

文件所属的产品名称

ProductVersion

产品版本

文件所属的产品的版本号

SpecialBuild

特殊内部版本说明

特殊说明

 

定义版本信息字符串的时候要注意,所有的字符串必须是以NULL结尾的串,所以要在字符串尾加上\0

 

Demo:给exe添加版本信息

//VersionInfo.rc

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

#include <resource.h>

#include <Version.h>

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

#define ICO_MAIN 0x1000 //图标

ICO_MAIN   ICON    "Main.ico"

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

1 VERSIONINFO

FILEVERSION 1,2,3,4

PRODUCTVERSION 2,3,4,5

FILEOS VOS_WINDOWS32

FILETYPE VFT_APP

FILESUBTYPE VFT2_UNKNOWN

BEGIN

        BLOCK "VarFileInfo"

        BEGIN

                VALUE "Translation", 0x804, 0x4b0

        END

        BLOCK "StringFileInfo"

        BEGIN

                BLOCK "080404b0"

                BEGIN

                        VALUE "Comments", "Here is Comments\0"

                        VALUE "CompanyName", "Here is CompanyName\0"

                        VALUE "FileDescription", "Here is FileDescription\0"

                        VALUE "FileVersion", "1,0,0,1\0"

                        VALUE "InternalName", "Here is InternalName\0"

                        VALUE "LegalCopyright", "Here is LegalCopyright\0"

                        VALUE "LegalTrademarks", "Here is LegalTrademarks\0"

                        VALUE "OriginalFilename", "Here is OriginalFilename\0"

                        VALUE "PrivateBuild", "Here is PrivateBuild\0"

                        VALUE "ProductName", "Here is ProductName\0"

                        VALUE "ProductVersion", "1,0,0,1\0"

                        VALUE "SpecialBuild", "Here is SpecialBuild\0"

                END

        END

END

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

 

 

//Version.h

/******************************************

* VersionInfo Resource include file

* by LuoYunBin

******************************************/

#define    VS_VERSION_INFO                  1

#define    VS_USER_DEFINED                  100

#define    VS_FFI_SIGNATURE          0x0FEEF04BD

#define    VS_FFI_STRUCVERSION          0x10000

#define    VS_FFI_FILEFLAGSMASK 0x3F

#define    VS_FF_DEBUG                          1

#define    VS_FF_PRERELEASE          2

#define    VS_FF_PATCHED                4

#define    VS_FF_PRIVATEBUILD              8

#define    VS_FF_INFOINFERRED            0x10

#define    VS_FF_SPECIALBUILD              0x20

#define    VOS_UNKNOWN                       0

#define    VOS_DOS                                  0x10000

#define    VOS_OS216                        0x20000

#define    VOS_OS232                        0x30000

#define    VOS_NT                             0x40000

#define    VOS_BASE                         0

#define    VOS_WINDOWS16                    1

#define    VOS_PM16                         2

#define    VOS_PM32                         3

#define    VOS_WINDOWS32                    4

#define    VOS_DOS_WINDOWS16           0x10001

#define    VOS_DOS_WINDOWS32           0x10004

#define    VOS_OS216_PM16                     0x20002

#define    VOS_OS232_PM32                     0x30003

#define    VOS_NT_WINDOWS32             0x40004

#define    VFT_UNKNOWN                       0

#define    VFT_APP                                   1

#define    VFT_DLL                                  2

#define    VFT_DRV                                  3

#define    VFT_FONT                         4

#define    VFT_VXD                                  5

#define    VFT_STATIC_LIB               7

#define    VFT2_UNKNOWN                     0

#define    VFT2_DRV_PRINTER         1

#define    VFT2_DRV_KEYBOARD             2

#define    VFT2_DRV_LANGUAGE            3

#define    VFT2_DRV_DISPLAY          4

#define    VFT2_DRV_MOUSE                   5

#define    VFT2_DRV_NETWORK              6

#define    VFT2_DRV_SYSTEM                 7

#define    VFT2_DRV_INSTALLABLE 8

#define    VFT2_DRV_SOUND                   9

#define    VFT2_DRV_COMM                    0x0A

#define    VFT2_DRV_INPUTMETHOD      0x0B

#define    VFT2_FONT_RASTER        1

#define    VFT2_FONT_VECTOR        2

#define    VFT2_FONT_TRUETYPE           3

 

//VersionInfo.asm

                .386

                .model flat, stdcall

                option casemap :none

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; Include 文件定义

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

include         windows.inc

include         user32.inc

includelib      user32.lib

include         kernel32.inc

includelib      kernel32.lib

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; 数据段

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

              .const

szTitle            db    '提示...',0

szMessage      db    '请用鼠标右键单击本文件,再看看“属性”菜单项中的“版本”页!',0

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; 代码段

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

              .code

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

start:

              invoke     MessageBox,NULL,addr szMessage,addr szTitle,MB_OK or MB_ICONEXCLAMATION

              invoke     ExitProcess,NULL

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

              end start

 

 

2、在程序中检测版本信息

       Win32 API中有3个版本信息函数:GetFileVersionSizeGetFileVersionInfoVerQueryValue,它们驻留在VERSION.DLL文件中,如果在源程序中使用它们,注意要加上include Version.inc以及includelib Version.lib语句。

用这3个函数获取版本信息的方法是:

首先调用GetFileVersionInfoSize函数检测文件中有没有版本信息资源:

       invoke GetFileVersionInfoSize, addr szFile, NULL

其中szFile是要检测的PE文件名字符串,该函数的返回值是版本信息资源的长度,如果返回0,则表示文件不是PE文件或没有定义版本信息资源。

 

如果检测到文件中有版本信息资源,那么可以将版本信息资源读取到一缓冲区中,缓冲区的长度必须足够容纳上一步返回的资源长度,方法是:

       invoke GetFileVersionInfo, addr szFile, NULL, sizeof dbVerInfo, addr dbVerInfo

其中dbVerInfo为一个足够大的缓冲区。该函数会把整个版本信息资源拷贝到这个缓冲区中。

 

拷贝到缓冲区中的信息有它自己的格式,必须用VerQueryValue去“解码”,解码固定属性的方法是:

       invoke VerQueryValue, addr dbVerInfo, addr szRoot, addr lpBuffer, addr dwLen

第一个参数指向前一步返回的版本信息资源数据,第二个参数指向一个字符串:“\”,第三和第四个参数指向dw类型的变量lpBufferdwLen,返回到lpBuffer中的是指向一个VS_FIXEDFILEINFO结构的指针,这个结构中有定义的固定属性的内容。

 

如果要获取字符串类型信息块中的版本信息,那就比较复杂一点了,必须首先知道语言集的名称,所以先要获取版本信息资源中变量类型信息块的内容,方法是:

       invoke VerQueryValue, addr dbVerInfo, addr szVarInfo, add lpBuffer, addr dwLen

       mov   eax, lpBuffer

       mov   eax, [eax]

       ror      eax, 16

szVarInfo是一个字符串:“\VarFileInfo\Translation”,这时函数在lpBuffer中返回语言集变量指针的指针,所以要先mov eax, lpBuffer,再用eax作指针用mov eax,[eax]得到语言集变量。语言集变量的高16位是字符集ID,低16位是语言ID,可以使用ror eax, 16来调换高低位,以我们的例子为例,现在eax中的值就是080404b0h了!

 

接下来就可以获取字符串版本信息了,先将语言集的值通过vsprintf函数转换成“080404b0”的形式,然后拼装成“\StringFileInfo\080404b0\字符串名称”形式的字符串,中间的“字符串名称”可以是上表中的12种名称之一,最后调用下面的语句(假定拼装好的字符串地址为szString)。

       invoke VerQueryValue, addr dbVerInfo, addr szString, addr lpBuffer, addr dwLen

执行后lpBuffer中会得到一个指针,指向版本信息字符串定义的内容,这就是我们最后需要的东西!重复这个步骤可以得到所有12种字符串版本信息。

 

Demo:获得版本信息

//ShowVersionInfo.rc

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

#include        <resource.h>

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

#define ICO_MAIN        0x1000 //图标

#define DLG_MAIN        1

#define IDC_INFO        101

#define IDC_FILE        102

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

ICO_MAIN        ICON    "Main.ico"

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

DLG_MAIN DIALOG 138, 123, 231, 139

STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU

CAPTION "查看PE文件版本信息"

FONT 9, "宋体"

{

    EDITTEXT IDC_INFO, 5, 5, 220, 110, ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY | WS_BORDER | WS_VSCROLL | WS_TABSTOP

    LTEXT "", IDC_FILE, 5, 123, 165, 8

    DEFPUSHBUTTON "选择文件(&B)", IDOK, 175, 120, 50, 14

}

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

 

// ShowVersionInfo.asm

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; ShowVersionInfo.asm

; 显示PE文件资源中版本信息的例子

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

                .386

                .model flat, stdcall

                option casemap :none

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; Include 文件定义

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

include         windows.inc

include         user32.inc

includelib      user32.lib

include         kernel32.inc

includelib      kernel32.lib

include         Version.inc

includelib      Version.lib

include         comctl32.inc

includelib      comctl32.lib

include         comdlg32.inc

includelib      comdlg32.lib

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; Equ 等值定义

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

ICO_MAIN        equ     1000h

DLG_MAIN        equ     1

IDC_INFO        equ     101

IDC_FILE        equ     102

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; 数据段

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

                .data?

hInstance       dd      ?

szBuffer        db      4096 dup(?)

 

                .const

szPeFileExt     db      'PE文件',0,'*.exe;*.dll;*.scr;*.drv',0,0

szError         db      '文件中没有包含版本信息!',0

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; 代码段

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

                .code

include         GetVersionInfo.inc

 

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

_ProcDlgMain    proc    uses ebx edi esi hWnd, wMsg, wParam, lParam

                local   @szBuffer[MAX_PATH]:byte

                local   @stOpenFileName:OPENFILENAME

               

                mov     eax,wMsg

               .if     eax == WM_CLOSE

                        invoke EndDialog, hWnd, NULL

                .elseif eax == WM_INITDIALOG

;*******************************************************************

; 设置标题栏图标

;*******************************************************************

                        invoke LoadIcon, hInstance, ICO_MAIN

                        invoke SendMessage, hWnd, WM_SETICON, ICON_BIG, eax

                .elseif eax == WM_COMMAND

                        mov     eax, wParam

                        .if     ax == IDOK

;*******************************************************************

; 打开一个选择文件的对话框

;*******************************************************************

                                invoke RtlZeroMemory, addr @stOpenFileName, sizeof OPENFILENAME

                                invoke RtlZeroMemory, addr @szBuffer, sizeof @szBuffer

                                mov @stOpenFileName.lStructSize, SIZEOF @stOpenFileName

                                mov @stOpenFileName.Flags, OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST

                                push hWnd

                                pop @stOpenFileName.hwndOwner

                                mov @stOpenFileName.lpstrFilter, offset szPeFileExt

                                lea eax, @szBuffer

                                mov @stOpenFileName.lpstrFile, eax

                                mov @stOpenFileName.nMaxFile, MAX_PATH

                                invoke GetOpenFileName, addr @stOpenFileName

                                .if     eax

;*******************************************************************

; 获取版本信息并显示出来

;*******************************************************************

                                        invoke _GetVersionInfo, addr @szBuffer, addr szBuffer

                                        .if     eax

                                                invoke SetDlgItemText, hWnd, IDC_FILE, addr @szBuffer

                                                invoke SetDlgItemText, hWnd, IDC_INFO, addr szBuffer

                                        .else

                                                invoke MessageBox, hWnd, addr szError, NULL, MB_OK or MB_ICONHAND

                                        .endif

                                .endif

                        .endif

;*******************************************************************

                .else

                        mov     eax, FALSE

                        ret

                .endif

                mov     eax, TRUE

                ret

 

_ProcDlgMain    endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

start:

                invoke InitCommonControls

                invoke GetModuleHandle, NULL

                mov hInstance, eax

                invoke DialogBoxParam, hInstance, DLG_MAIN, NULL, offset _ProcDlgMain, NULL

                invoke ExitProcess, NULL

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

                end     start

 

// GetVersionInfo.inc

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; Sample code for < Win32ASM Programming >

; by 罗云彬, http://asm.yeah.net

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; GetVersionInfo.inc

; 用来获取 PE 文件资源中版本信息的子程序

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; 通过 include 语句包含到其它源程序中使用

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

              .const

 

szRoot           db    '\',0

szVarInfo db    '\VarFileInfo\Translation',0

szStrInfoFmt db    '\StringFileInfo\%08x\',0

szArrow         db    ' --> ',0

szReturn db    0dh,0ah,0

szFixFileInfo   db    '固定版本信息属性:',0dh,0ah

              db    'FileVersion: %d.%d.%d.%d',0dh,0ah

              db    'ProductVersion: %d.%d.%d.%d',0dh,0ah

              db    'FileOS: %08x',0dh,0ah

              db    'FileType: %08x',0dh,0ah,0dh,0ah

              db    '字符串版本属性:',0dh,0ah,0

;********************************************************************

szStr1            db    'Comments',0

szStr2            db    'CompanyName',0

szStr3            db    'FileDescription',0

szStr4            db    'FileVersion',0

szStr5            db    'InternalName',0

szStr6            db    'LegalCopyright',0

szStr7            db    'LegalTrademarks',0

szStr8            db    'OriginalFilename',0

szStr9            db    'PrivateBuild',0

szStr10          db    'ProductName',0

szStr11           db    'ProductVersion',0

szStr12          db    'SpecialBuild',0

;********************************************************************

lpStr1             dd    szStr1

lpStr2             dd    szStr2

lpStr3             dd    szStr3

lpStr4             dd    szStr4

lpStr5             dd    szStr5

lpStr6             dd    szStr6

lpStr7             dd    szStr7

lpStr8             dd    szStr8

lpStr9             dd    szStr9

lpStr10           dd    szStr10

lpStr11           dd    szStr11

lpStr12           dd    szStr12

 

              .code

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; 获取文件版本信息

; 入口参数:文件名,返回信息缓冲区

; 返回参数:TRUE = 成功,FALSE = 失败

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

_GetVersionInfo     proc _lpFileName,_lpBuffer

              local @dbVerInfo[4096]:byte

              local @szStringInfo[128]:byte

              local @szString[128]:byte

              local @lpBuffer,@dwLen

              local @dwVer1,@dwVer2,@dwVer3,@dwVer4

              local @dwVer5,@dwVer6,@dwVer7,@dwVer8

 

              pushad

              invoke     GetFileVersionInfoSize,_lpFileName,NULL

              .if    !eax

                     popad

                     xor eax,eax

                     ret

              .endif

              invoke     GetFileVersionInfo,_lpFileName,NULL,sizeof @dbVerInfo,addr @dbVerInfo

;********************************************************************

; 获取固定属性

;********************************************************************

              invoke     VerQueryValue,addr @dbVerInfo,addr szRoot,addr @lpBuffer,addr @dwLen

              mov esi,@lpBuffer

              assume    esi:ptr VS_FIXEDFILEINFO

;********************************************************************

; 计算版本号

;********************************************************************

              mov eax,[esi].dwFileVersionMS

              movzx     ecx,ax

              mov @dwVer2,ecx

              shr   eax,16

              mov @dwVer1,eax

 

              mov eax,[esi].dwFileVersionLS

              movzx     ecx,ax

              mov @dwVer4,ecx

              shr   eax,16

              mov @dwVer3,eax

 

              mov eax,[esi].dwProductVersionMS

              movzx     ecx,ax

              mov @dwVer6,ecx

              shr   eax,16

              mov @dwVer5,eax

 

              mov eax,[esi].dwProductVersionLS

              movzx     ecx,ax

              mov @dwVer8,ecx

              shr   eax,16

              mov @dwVer7,eax

              invoke     wsprintf,_lpBuffer,addr szFixFileInfo,\

                     @dwVer1,@dwVer2,@dwVer3,@dwVer4,\

                     @dwVer5,@dwVer6,@dwVer7,@dwVer8,\

                     [esi].dwFileOS,[esi].dwFileType

 

              assume    esi:nothing

;********************************************************************

; 获取语言集

;********************************************************************

              invoke     VerQueryValue,addr @dbVerInfo,addr szVarInfo,addr @lpBuffer,addr @dwLen

              mov eax,@lpBuffer

              mov eax,[eax]

              ror   eax,16

              invoke     wsprintf,addr @szStringInfo,addr szStrInfoFmt,eax

;********************************************************************

; 获取字符串版本信息

;********************************************************************

              mov ebx,offset lpStr1

              .while      ebx <=    offset lpStr12

                     invoke     lstrcpy,addr @szString,addr @szStringInfo

                     mov eax,[ebx]

                     invoke     lstrcat,addr @szString,eax

                     mov eax,[ebx]

                     invoke     lstrcat,_lpBuffer,eax

                     invoke     lstrcat,_lpBuffer,addr szArrow             ;加上 -->

                     invoke     VerQueryValue,addr @dbVerInfo,addr @szString,addr @lpBuffer,addr @dwLen

                     .if    eax

                            invoke     lstrcat,_lpBuffer,@lpBuffer    ;加上获得的版本信息

                     .endif

                     invoke     lstrcat,_lpBuffer,addr szReturn             ;加上回车

                     add ebx,4

              .endw

              popad

              mov eax,TRUE

              ret

 

_GetVersionInfo     endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

 

posted on 2010-09-21 13:24 luqingfei 阅读(2099) 评论(0)  编辑 收藏 引用 所属分类: Win32汇编程语言序设计


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2010年9月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

统计

留言簿(6)

随笔分类(109)

随笔档案(105)

Blogers

Game

Life

NodeJs

Python

Useful Webs

大牛

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜