16 extern DWORD_PTR
dwPad( DWORD_PTR X );
25 if (!hMod) hMod = GetModuleHandle( NULL );
33 TCHAR name[ MAX_PATH ];
37 GetModuleFileName( NULL, name,
dimof(name) );
40 vSize = GetFileVersionInfoSize( FName, &Hnd );
41 if (!vSize) vInfo = NULL;
44 if (pSize) *pSize = vSize;
45 vInfo = LocalAlloc( LPTR, vSize );
50 if (!GetFileVersionInfo( FName, Hnd, vSize, vInfo ))
61 return (PVOID) LocalFree( (HLOCAL) vInfo );
68 #if 0 // 2016-11-12: BUGBUG in VerQueryValueA 82 _stprintf_s( vname,
dimof(vname), _T(
"\\StringFileInfo\\%s\\%s"), BlockId, Name );
84 if (!VerQueryValue( VerBuf, vname, &buf, &len ) || (len == 0))
102 #define _VNAME_FMT L"\\StringFileInfo\\%s\\%s" 104 #define _VNAME_FMT L"\\StringFileInfo\\%S\\%S" 108 if (!VerQueryValueW( VerBuf, vname, &buf, &len ) || (len == 0))
113 #pragma message("ALERT: Using workaround for VerQueryValueA bug. > " __FILE__ ":" PP_NSTR(__LINE__)) 114 static CHAR szAnsi[ MAX_PATH ];
122 WideCharToMultiByte( CP_ACP, 0, (
WCSTR)buf, len, szAnsi,
dimof(szAnsi), 0,0 );
134 IN PVOID VerBuf, IN
CSTR BlockId, IN
CSTR Name, OUT
TSTR Buffer, IN UINT BufLen
140 if (!Buffer || !BufLen)
141 SetLastError( ERROR_INVALID_PARAMETER );
146 #define _VNAME_FMT L"\\StringFileInfo\\%s\\%s" 148 #define _VNAME_FMT L"\\StringFileInfo\\%S\\%S" 152 if (!VerQueryValueW( VerBuf, vname, &buf, &len ) || (len == 0))
156 #else// Take over the flawed VerQueryValueA string translation.. 157 else WideCharToMultiByte( CP_ACP, 0, (
WCSTR)buf, len, Buffer, BufLen, 0,0 );
167 static TCHAR sInfo[32] = _T(
"");
169 VS_FIXEDFILEINFO* fvi;
172 if (VerQueryValue( vInfo, _T(
"\\"), (
void**)&fvi, &len ))
173 _stprintf_s( sInfo,
dimof(sInfo), _T(
"%u.%u.%u.%u"),
174 HIWORD( fvi->dwProductVersionMS ), LOWORD( fvi->dwProductVersionMS ),
175 HIWORD( fvi->dwProductVersionLS ), LOWORD( fvi->dwProductVersionLS )
184 BOOL ok = VerQueryValue(
185 vInfo, _T(
"\\VarFileInfo\\Translation"), (
void**)ppXlt, pCount
187 if (ok) *pCount /=
sizeof(
VXLT);
196 static TCHAR szXlt[12] = _T(
"");
197 PVXLT pXlt; UINT len;
200 _stprintf_s( szXlt,
dimof(szXlt), _T(
"%04X%04X"), pXlt[0].Lang, pXlt[0].Cp );
203 TRACE(
DP_WARNING, _T(
"[uLib] GetVerTranslationStr: No translation spec found!\r\n") );
223 static const BYTE cbVihFix = 6;
224 typedef struct _viHdr
235 static const WCHAR S_VerInfo[] = L
"VS_VERSION_INFO";
236 static const WCHAR S_StrInfo[] = L
"StringFileInfo";
237 static const WCHAR S_VarInfo[] = L
"VarFileInfo";
238 static const WCHAR S_Trans[] = L
"Translation";
242 #define CB_CWSTR(s) (BYTE)dwPad( sizeof(s)-sizeof(WCHAR) ) 252 PVIH pVroot = (PVIH) vInfo;
258 #ifdef _DEBUG // VS_FIXEDFILEINFO is located after the Name of the root block 259 VS_FIXEDFILEINFO* fvi = (VS_FIXEDFILEINFO*)
dwAlign(
PBYTE(pVroot) + cbVihFix + cbsVerInfo );
260 if (fvi->dwSignature != 0xFEEF04BD) DebugBreak();
265 _.pb +=
dwPad( cbVihFix + cbsVerInfo + pVroot->ValueLen );
267 size_t sfiLen = wcslen( S_StrInfo );
268 if (wcsncmp( _.pVi->Name, S_StrInfo, sfiLen ) != 0)
269 _.pb +=
dwPad( _.pVi->Length );
271 if (wcsncmp( _.pVi->Name, S_StrInfo, sfiLen ) == 0)
277 PVIH pStbl = (PVIH)
dwAlign(
PBYTE(pSfi) + cbVihFix + cbsStrInfo );
278 PVIH pEnd = (PVIH)
dwAlign(
PBYTE(pStbl) + pStbl->Length );
282 PVIH pvStr = (PVIH)
dwAlign(
PBYTE(pStbl) + cbVihFix + 16 );
283 while( pvStr < pEnd )
285 if (pvStr->Type == 1)
287 size_t cbName =
wcsbytes( pvStr->Name );
288 PCWSTR sVal = pvStr->ValueLen
289 ? (PCWSTR)
dwAlign(
PBYTE(pvStr) + cbVihFix + cbName ) : L
"";
291 #define szName pvStr->Name 293 #else // Make MB translations for the UI 294 CHAR szName[128], szVal[512];
295 WideCharToMultiByte( CP_ACP,0, pvStr->Name,-1, szName,
dimof(szName), NULL,NULL );
296 WideCharToMultiByte( CP_ACP,0, sVal,-1, szVal,
dimof(szVal), NULL,NULL );
299 UserFunc( szName, szVal, UserData );
313 static const WORD ABT_HELPID = 1000;
314 static const WORD ST_HEADING = 100;
315 static const WORD LB_INFO = 101;
318 #define WS_VISICHILD (WS_CHILD| WS_VISIBLE) 321 #define WS_SCROLL (WS_VSCROLL| WS_HSCROLL) 334 DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU,
335 0, 0, 200,154, Caption, ABT_HELPID, 3, L
"Tahoma", 8, FW_NORMAL, ANSI_CHARSET
339 WS_VISICHILD| WS_GROUP| SS_CENTER| SS_CENTERIMAGE| SS_SUNKEN,
340 0, 6,6, 188,16, L
"..", ST_HEADING, ABT_HELPID+ST_HEADING
345 WS_EX_STATICEDGE, 6,24, 188,108, L
"", LB_INFO, ABT_HELPID+LB_INFO
350 0, 74,136, 50,14, L
"&OK", IDOK, ABT_HELPID+IDOK
355 int rc = (int) DialogBoxIndirectParam(
366 static void __stdcall addVerStr(
CSTR Name,
CSTR Val, PVOID pCtl )
369 if (!Name) width = 0;
372 TCHAR szItem[ MAX_PATH ];
373 HWND hCtl = (HWND) pCtl;
374 int len = _stprintf_s( szItem,
dimof(szItem), _T(
"%s\t%s"), Name, Val );
375 ListBox_AddString( hCtl, szItem );
379 HDC hdc = GetDC( hCtl );
380 if (GetTextExtentPoint32( hdc, szItem, len, &size ))
385 ListBox_SetHorizontalExtent( hCtl, width );
388 ReleaseDC( hCtl, hdc );
411 hCtl = GetDlgItem( hdlg, LB_INFO );
412 ListBox_SetTabStops( hCtl, 1, &tablen );
422 if (!vStr) vStr = _T(
"This Program");
423 SetDlgItemText( hdlg, ST_HEADING, vStr );
425 addVerStr( NULL,NULL,NULL );
426 IMAGE_NT_HEADERS Hdr;
430 addVerStr( _T(
"Machine"), pcz, hCtl );
432 addVerStr( _T(
"Subsystem"), pcz, hCtl );
444 switch( LOWORD( wp )) {
447 EndDialog( hdlg, LOWORD( wp ));
454 GetObject( (HFONT)wp,
sizeof(lf), &lf );
455 lf.lfWeight = FW_BOLD;
456 hBold = CreateFontIndirect( &lf );
460 case WM_CTLCOLORSTATIC:
461 SetTextColor( (HDC)wp, RGB( 0,100,200 ));
462 SetBkColor( (HDC)wp, RGB( 255,255,255 ));
463 if (hBold) SelectFont( (HDC)wp, hBold );
464 rc = (
DRESULT) GetStockBrush( WHITE_BRUSH );
bool ReadNTHeaders(CSTR ExeName, IMAGE_NT_HEADERS *Hdr, bool GetOptHdr)
CSTR GetMachineStr(WORD Machine)
bool GetVerTranslations(PVOID vInfo, PVXLT *ppXlt, PUINT pCount)
CSTR GetVersionStr(PVOID VerBuf, CSTR BlockId, CSTR Name)
void(__stdcall * PFnEnumVerStr)(CSTR Name, CSTR Val, PVOID UserData)
DIALOGPROC _AboutProc(HWND hdlg, UINT msg, WPARAM wp, LPARAM lp)
int AboutVerBox(HWND hOwner, LPCWSTR Caption, CSTR FName)
void FreeExDlgTemplate(PDLGTEMPLATEEX pDlg)
PVOID WINAPI LoadCustomResource(HMODULE hModule, CSTR Id, CSTR Type, UINT *pSize OPTOUT=NULL)
DWORD_PTR dwPad(DWORD_PTR X)
PDLGITEMTEMPLATEEX AddExDlgItem(PDLGITEMTEMPLATEEX pBuf, DWORD Type, DWORD Style, DWORD ExStyle, short X, short Y, short W, short H, LPCWSTR Caption, WORD Id, DWORD HelpId)
BOOL(WINAPI *SysImgList::Shell_GetImageLists)(HIMAGELIST *pimlLarge
CCSTR V_EnMultiBlock
US English / Codepage 1252.
PVOID GetVersionResource(HMODULE hMod, CSTR ResId, PUINT pSize)
bool __forceinline bool_cast(BOOL B52)
CSTR GetFixedVersionStr(PVOID vInfo)
Debug and error handling support.
CSTR GetSubSystemStr(WORD SubSys)
PVOID FreeVersionInfo(PVOID vInfo)
PVOID LoadVersionInfo(CSTR FName, PDWORD pSize)
PDLGTEMPLATEEX AllocExDlgTemplate(WORD Size)
CSTR GetVerTranslationStr(PVOID vInfo)
size_t wcsbytes(const wchar_t *Src)
PDLGITEMTEMPLATEEX SetExDlgStyle(PDLGTEMPLATEEX pBuf, DWORD Style, short X, short Y, short W, short H, LPCWSTR Caption, DWORD HelpId, WORD nCtls, LPCWSTR Font, short Points, short Weight=FW_NORMAL, BYTE CharSet=DEFAULT_CHARSET)
UINT GetVersionString(IN PVOID VerBuf, IN CSTR BlockId, IN CSTR Name, OUT TSTR Buffer, IN UINT BufLen)
Get a specific version string.
UINT EnumVersionStrings(PVOID vInfo, PFnEnumVerStr UserFunc, PVOID UserData)