;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ; FileName: VerInfo3.asm ; Function: Demo the way to get file's version information and language ; Author: Purple Endurer ; ; LOG ; ---------------------------------------------------------------------------------------- ; 2006-11-22 Can display in CN ; 2006-11-20 Added comments! ; 2006-09-14 Created! ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< .386 .model flat, stdcall option casemap: none include /masm32/ include/windows.inc include /masm32/ include/kernel32.inc includelib /masm32/ lib/kernel32.lib include /masm32/ include/user32.inc includelib /masm32/ lib/user32.lib include /masm32/ include/shell32.inc includelib /masm32/ lib/shell32.lib include /masm32/ include/comdlg32.inc includelib /masm32/ lib/comdlg32.lib include /masm32/ include/version.inc includelib /masm32/ lib/version.lib WinMain PROTO : DWORD, : DWORD, : DWORD, : DWORD ResizeConctrol PROTO ShowVerInfo PROTO :LPSTR btnShow_Click PROTO btnBrowse_Click PROTO ;.const IDC_BtnBrowse equ 101 IDC_BtnShow equ 103 IDC_EdtFileSpec equ 105 IDC_EdtVerInfo equ 107 c_BufLen EQU MAX_PATH c_EditFileSpecLeft equ 2 c_EditFileSpecTop equ 5 c_EditFileSpecWidth equ 300 c_EditFileSpecHeight equ 20 c_BtnBrowseTop equ c_EditFileSpecTop c_BtnBrowseLeft equ (c_EditFileSpecLeft+c_EditFileSpecWidth+10) c_BtnBrowseWidth equ 70 c_BtnBrowseHeight equ c_EditFileSpecHeight c_BtnShowTop equ c_EditFileSpecTop c_BtnShowLeft equ (c_BtnBrowseLeft+c_BtnBrowseWidth+10) c_BtnShowWidth equ 70 c_BtnShowHeight equ c_BtnBrowseHeight c_EdtVerInfoLeft equ 2 c_EdtVerInfoTop equ 30 c_EdtVerInfoWidth equ c_BtnShowLeft+c_BtnShowWidth+2 c_EdtVerInfoHeight equ 165 c_WinWidth equ c_EdtVerInfoLeft+c_EdtVerInfoWidth+10 c_WinHeight equ c_EdtVerInfoTop+c_EdtVerInfoHeight+30 m_CatStr MACRO szStr: REQ invoke SendMessage, g_hEditVerInfo, EM_REPLACESEL, FALSE, ADDR szStr ENDM m_GoNextLine MACRO invoke SendMessage, g_hEditVerInfo, EM_REPLACESEL, FALSE, ADDR g_szCR ENDM .data g_szClsName db "FileVerInfoCls", 0 g_szAppName db "文件版本信息", 0 g_szEditCls db "EDIT", 0 g_szBtnCls db "button", 0 g_szBtnBrowseText db "&B 浏览", 0 g_szBtnShowText db "&S 显示", 0 g_szEnterFileErr db "请先输入文件说明符", 0 g_szFailGetVerSize db "获取文件版本信息大小失败!", 0 g_szFailAllocMem db "申请内存失败!", 0 g_szFailGetVerInfo db "获取文件版本信息失败!", 0 g_szFailFailGetLangPage db "获取语言和代码页失败!", 0 g_szCR db 0dh, 0ah, 0 g_szOp db "properties", 0 g_szPeFileFilter db "*.EXE;*.DLL",0, "*.EXE;*.DLL", 0, 0 .data? g_hInstance HINSTANCE ? g_hWndMain HANDLE ? g_hEditFileSpec HANDLE ? g_hBtnShow HANDLE ? g_hBtnBrowse HANDLE ? g_hEditVerInfo HANDLE ? g_szFileSpec db c_BufLen dup (?) g_ofn OPENFILENAME <?> g_ShlExecInfo SHELLEXECUTEINFO <?> .code start: invoke GetModuleHandle, NULL mov g_hInstance, eax invoke WinMain, g_hInstance, NULL, NULL, SW_SHOWDEFAULT invoke ExitProcess, eax WinMain proc hInst: DWORD, hPrevInst: DWORD, CmdLine: DWORD, CmdShow: DWORD LOCAL wc: WNDCLASSEX LOCAL msg: MSG LOCAL hwnd: HWND mov wc.cbSize, SIZEOF WNDCLASSEX mov wc.style, CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra, NULL mov wc.cbWndExtra, NULL mov eax, g_hInstance mov wc.hInstance, eax mov wc.hbrBackground, COLOR_APPWORKSPACE mov wc.lpszMenuName, NULL mov wc.lpszClassName, OFFSET g_szClsName invoke LoadIcon, NULL, IDI_APPLICATION mov wc.hIcon, eax mov wc.hIconSm, eax invoke LoadCursor, NULL, IDC_ARROW mov wc.hCursor, eax invoke RegisterClassEx, addr wc invoke CreateWindowEx, WS_EX_TOPMOST, ADDR g_szClsName,/ ADDR g_szAppName, WS_OVERLAPPEDWINDOW+WS_VISIBLE,/ CW_USEDEFAULT, CW_USEDEFAULT, c_WinWidth, c_WinHeight,/ NULL, NULL, hInst, NULL mov hwnd, eax .while TRUE invoke GetMessage, ADDR msg, NULL, 0, 0 .BREAK .IF (! eax) ;--- process keystrokes directly in the message loop .if msg.message == WM_SYSKEYUP .if msg.wParam == VK_B ; Alt + B invoke PostMessage, hwnd, WM_COMMAND, IDC_BtnBrowse, BM_CLICK .elseif msg.wParam == VK_S ; Alt + S invoke PostMessage, hwnd, WM_COMMAND, IDC_BtnShow, BM_CLICK .endif .endif ; ------------------------------------------------ invoke TranslateMessage, ADDR msg invoke DispatchMessage, ADDR msg .endw mov eax, msg.wParam ret WinMain endp WndProc proc hWnd: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM LOCAL rect: RECT LOCAL hdc: DWORD .if uMsg==WM_CREATE mov eax, hWnd mov g_hWndMain, eax ;--- Create file spec editbox invoke CreateWindowEx, NULL, offset g_szEditCls, NULL, WS_CHILD+WS_VISIBLE+ES_AUTOHSCROLL+WS_BORDER,/ c_EditFileSpecLeft, c_EditFileSpecTop, c_EditFileSpecWidth, c_EditFileSpecHeight,/ hWnd, IDC_EdtFileSpec, g_hInstance, NULL mov g_hEditFileSpec, eax ;--- Create browse button invoke CreateWindowEx, NULL, offset g_szBtnCls, offset g_szBtnBrowseText,/ WS_CHILD+WS_VISIBLE, c_BtnBrowseLeft, c_BtnBrowseTop, c_BtnBrowseWidth, c_BtnBrowseHeight,/ hWnd, IDC_BtnBrowse, g_hInstance, NULL mov g_hBtnBrowse, eax ;--- Create show button invoke CreateWindowEx, NULL, offset g_szBtnCls, offset g_szBtnShowText,/ WS_CHILD+WS_VISIBLE, c_BtnShowLeft, c_BtnShowTop, c_BtnShowWidth, c_BtnShowHeight,/ g_hWndMain, IDC_BtnShow, g_hInstance, NULL mov g_hBtnShow, eax ;--- Create file ver info editbox invoke CreateWindowEx, NULL, addr g_szEditCls, NULL,/ WS_CHILD+WS_VISIBLE+ES_MULTILINE+WS_HSCROLL+WS_VSCROLL+WS_BORDER,/ c_EdtVerInfoLeft, c_EdtVerInfoTop, c_EdtVerInfoWidth, c_EdtVerInfoHeight,/ g_hWndMain, IDC_EdtVerInfo, g_hInstance, NULL mov g_hEditVerInfo, eax ;--- Initialize OPENFILENAME structure invoke RtlZeroMemory, offset g_ofn, sizeof g_ofn mov g_ofn.lStructSize, sizeof OPENFILENAME mov eax, g_hInstance mov g_ofn.hInstance, eax mov g_ofn.nMaxFile, c_BufLen mov g_ofn.Flags, OFN_HIDEREADONLY + OFN_FILEMUSTEXIST + OFN_PATHMUSTEXIST + OFN_EXPLORER mov g_ofn.lpstrFilter, OFFSET g_szPeFileFilter mov g_ofn.lpstrFile, OFFSET g_szFileSpec mov eax, g_hWndMain mov g_ofn.hWndOwner, eax ;--- Initialize SHELLEXECUTEINFO structure invoke RtlZeroMemory, offset g_ShlExecInfo, sizeof SHELLEXECUTEINFO mov g_ShlExecInfo.cbSize, sizeof g_ShlExecInfo mov g_ShlExecInfo.fMask, SEE_MASK_INVOKEIDLIST mov g_ShlExecInfo.lpVerb, offset g_szOp mov g_ShlExecInfo.lpFile, offset g_szFileSpec .elseif uMsg==WM_COMMAND .IF lParam mov edx, wParam mov eax, edx shr edx, 16 .if dx == BN_CLICKED .IF ax == IDC_BtnShow invoke btnShow_Click .else invoke btnBrowse_Click .endif .ENDIF .endif .elseif uMsg==WM_DESTROY invoke PostQuitMessage, NULL .elseif uMsg==WM_SIZE invoke ResizeConctrol xor eax, eax jz @F .else @@: invoke DefWindowProc, hWnd, uMsg, wParam, lParam ret .endif xor eax, eax ret WndProc endp btnShow_Click proc invoke GetWindowText, g_hEditFileSpec, ADDR g_szFileSpec, SIZEOF g_szFileSpec .IF eax==0 invoke MessageBox, g_hWndMain, OFFSET g_szEnterFileErr, OFFSET g_szAppName, MB_ICONERROR+MB_OK .ELSE ;--- clear the file ver info box invoke SendMessage, g_hEditVerInfo, WM_SETTEXT, 0, NULL invoke ShowVerInfo, OFFSET g_szFileSpec .if eax > 0 .IF eax==1 mov eax, OFFSET g_szFailGetVerSize .ELSEIF eax==2 mov eax, OFFSET g_szFailAllocMem .ELSEIF eax==3 mov eax, OFFSET g_szFailGetVerInfo .ELSEIF eax==4 mov eax, OFFSET g_szFailFailGetLangPage .ENDIF invoke MessageBox, g_hWndMain, eax, OFFSET g_szAppName, MB_ICONERROR+MB_OK .else invoke ShellExecuteEx, offset g_ShlExecInfo .endif .ENDIF ret btnShow_Click endp btnBrowse_Click proc invoke GetOpenFileName, ADDR g_ofn .if eax != 0 invoke SendMessage, g_hEditFileSpec, WM_SETTEXT, 0, OFFSET g_szFileSpec .endif ret btnBrowse_Click endp ResizeConctrol PROC LOCAL st_Rect: RECT invoke GetClientRect, g_hWndMain, ADDR st_Rect ;--- Resize the Show button mov eax, st_Rect.right sub eax, 5+c_BtnShowWidth push eax invoke MoveWindow, g_hBtnShow, eax, c_BtnShowTop, c_BtnShowWidth, c_BtnShowHeight, TRUE ;--- Resize the Show button pop eax sub eax, 5+c_BtnShowWidth push eax invoke MoveWindow, g_hBtnBrowse, eax, c_BtnBrowseTop, c_BtnBrowseWidth, c_BtnBrowseHeight, TRUE ;--- Resize the file spec editbox pop eax sub eax, 10 invoke MoveWindow, g_hEditFileSpec, c_EditFileSpecLeft, c_EditFileSpecTop, eax, c_EditFileSpecHeight, TRUE ;--- Resize the Ver info editbox mov eax, st_Rect.right sub eax, 5 mov edi, st_Rect.bottom sub edi, 30 invoke MoveWindow, g_hEditVerInfo, c_EdtVerInfoLeft, c_EdtVerInfoTop, eax, edi, TRUE ret ResizeConctrol ENDP ;/ ; Result: ; eax == 0 sucess ; eax == 1 Fail to get file ver info size ; eax == 2 Fail to alloc global memory ; eax == 3 Fail to get file ver info ; eax == 4 Fail to get the language id and code page ;/ ShowVerInfo PROC lpszFileSpec: LPSTR LOCAL dwBufSize: DWORD LOCAL hMem: HANDLE LOCAL bInfoStr[MAX_PATH]: byte LOCAL lpszValue: LPSTR LOCAL bLangCharset[9]: byte invoke GetFileVersionInfoSize, lpszFileSpec, ADDR dwBufSize or eax , eax jnz @F mov eax, 1 ret @@: mov dwBufSize, eax invoke GlobalAlloc, GMEM_ZEROINIT, eax cmp eax, NULL jnz @F mov eax, 2 ret @@: mov hMem, eax ; BOOL GetFileVersionInfo( ; LPTSTR lptstrFilename, // pointer to filename string ; DWORD dwHandle, // ignored ; DWORD dwLen, // size of buffer ; LPVOID lpData // pointer to buffer to receive file-version info. ; ); invoke GetFileVersionInfo, lpszFileSpec, 0, dwBufSize, hMem or eax, eax jnz @F invoke GlobalFree, hMem mov eax, 3 ret g_szTranslation db "/VarFileInfo/Translation", 0 @@: ; BOOL VerQueryValue( ; const LPVOID pBlock, // address of buffer for version resource ; LPTSTR lpSubBlock, // address of value to retrieve ; LPVOID *lplpBuffer, // address of buffer for version pointer ; PUINT puLen // address of version-value length buffer ; ); invoke VerQueryValue, hMem, OFFSET g_szTranslation, ADDR lpszValue, ADDR dwBufSize or eax, eax jnz @F invoke GlobalFree, hMem mov eax, 4 ret g_szProductName db 'ProductName', 0 g_szProductVersion db 'ProductVersion', 0 g_szFileDescription db 'FileDescription', 0 g_szLegalCopyright db 'LegalCopyright', 0 g_szFileVersion db 'FileVersion', 0 g_szCompanyName db 'CompanyName', 0 g_szLegalTradeMarks db 'LegalTradeMarks', 0 g_szInternalName db 'InternalName', 0 g_szOriginalFileName db 'OriginalFileName', 0 g_szComments db "Comments", 0 g_lpszInfo label dword dword OFFSET g_szFileVersion dword OFFSET g_szFileDescription dword OFFSET g_szLegalCopyright dword OFFSET g_szComments dword OFFSET g_szProductVersion dword OFFSET g_szProductName dword OFFSET g_szCompanyName dword OFFSET g_szLegalTradeMarks dword OFFSET g_szInternalName dword OFFSET g_szOriginalFileName c_lpszInfoLen equ ($-g_lpszInfo)/4 c_language_cn equ 1 if c_language_cn eq 1 g_szProductName_cn db '产品名称', 0 g_szProductVersion_cn db '产品版本', 0 g_szFileDescription_cn db '说明', 0 g_szLegalCopyright_cn db '版权', 0 g_szFileVersion_cn db '文件版本', 0 g_szCompanyName_cn db '公司名称', 0 g_szLegalTradeMarks_cn db '合法商标', 0 g_szInternalName_cn db '内部名称', 0 g_szOriginalFileName_cn db '源文件名', 0 g_szComments_cn db "备注", 0 g_lpszInfo_cn label dword dword OFFSET g_szFileVersion_cn dword OFFSET g_szFileDescription_cn dword OFFSET g_szLegalCopyright_cn dword OFFSET g_szComments_cn dword OFFSET g_szProductVersion_cn dword OFFSET g_szProductName_cn dword OFFSET g_szCompanyName_cn dword OFFSET g_szLegalTradeMarks_cn dword OFFSET g_szInternalName_cn dword OFFSET g_szOriginalFileName_cn c_lpszInfo_cn_Len equ ($-g_lpszInfo_cn)/4 g_szLang_cn db "语言" g_szBlkColonBlk db " : ", 0 else g_szLang db "Langeage" g_szBlkColonBlk db " : ", 0 endif g_szPre db 'StringFileInfo/', 0 ;080404B0 g_szInfoFmt db "%s%s/%s", 0 g_szHexFmt db "%08X", 0 @@: ;--- Now, lpszValue is a pointer to four 4 bytes of Hex number, ; first two bytes are language id, and last two bytes are code page. ; However, Lang_Charset_String needs a string of 4 hex digits, ; the first two characters correspond to the language id ; and last two the last two character correspond to the code page id. if c_language_cn eq 1 m_CatStr g_szLang_cn else m_CatStr g_szLang endif mov eax, lpszValue mov eax, [ eax] push eax ;---Get the description string ; DWORD VerLanguageName( ; DWORD wLang, // Microsoft language identifier ; LPTSTR szLang, // pointer to buffer for language description string ; DWORD nSize // size of buffer ; ); movzx eax, ax mov dwBufSize, eax invoke VerLanguageName, dwBufSize, ADDR bInfoStr, MAX_PATH or eax, eax jz @F m_CatStr bInfoStr @@: m_GoNextLine pop eax ;--- Change the order of the language id and code page rol eax, 16 ;--- Convert the language id and code page into a 8 bytes Hex string representation invoke wsprintf, ADDR bLangCharset, ADDR g_szHexFmt, eax ;--- For example, the language id and code page may look like 040904E4 ; Or to pull it all apart: ; 04------ = SUBLANG_ENGLISH_USA ; --09---- = LANG_ENGLISH ; ----04E4 = 1252 = Codepage for Windows:Multilingual c_showTranslation equ 0 if c_showTranslation eq 1 ; --- Show the language id and code page in editbox m_CatStr g_szTranslation m_CatStr g_szBlkColonBlk m_CatStr bLangCharset m_GoNextLine endif xor eax, eax .while eax < c_lpszInfoLen push eax or eax, eax jz @F shl eax, 2 ; eax<--eax * 4 @@: push eax if c_language_cn eq 1 invoke SendMessage, g_hEditVerInfo, EM_REPLACESEL, FALSE, [ eax+g_lpszInfo_cn] else invoke SendMessage, g_hEditVerInfo, EM_REPLACESEL, FALSE, [ eax+g_lpszInfo] endif m_CatStr g_szBlkColonBlk pop eax invoke wsprintf, ADDR bInfoStr, ADDR g_szInfoFmt, OFFSET g_szPre, ADDR bLangCharset, [ eax+g_lpszInfo] invoke VerQueryValue, hMem, ADDR bInfoStr, ADDR lpszValue, ADDR dwBufSize or eax, eax jz @F invoke SendMessage, g_hEditVerInfo, EM_REPLACESEL, FALSE, lpszValue @@: m_GoNextLine pop eax inc eax .endw invoke GlobalFree, hMem xor eax, eax ret ShowVerInfo ENDP end ----------------------------------- ©著作权归作者所有:来自51CTO博客作者PurpleEndurer的原创作品,请联系作者获取转载授权,否则将追究法律责任 [11-22]MASM32编程获取文件语言、版本信息v3 https://blog.51cto.com/endurer/5856456