uLib  User mode C/C++ extended API library for Win32 programmers.
VerInfo.cpp
Go to the documentation of this file.
1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 // Project: uLib - User mode utility library.
3 // Module: Fetch and display version data from VERSION resource.
4 // Author: Copyright (c) Love Nystrom
5 // License: NNOSL (BSD descendant, see NNOSL.txt in the base directory).
6 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 
8 #include <uLib/VerInfo.h>
9 #include <uLib/DlgPlate.h>
10 #include <uLib/UtilFunc.h>
11 #include <uLib/StrFunc.h>
12 #include <uLib/Debug.h>
13 
14 // dwPad and dwAlign are defined in DlgPlate.cpp
15 
16 extern DWORD_PTR dwPad( DWORD_PTR X );
17 extern PBYTE dwAlign( PBYTE Ptr );
18 
19 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20 // Fundamental version info subroutines
21 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
22 
23 PVOID GetVersionResource( HMODULE hMod, CSTR ResId, PUINT pSize )
24 {
25  if (!hMod) hMod = GetModuleHandle( NULL ); // This module
26  return LoadCustomResource( hMod, ResId, RT_VERSION, pSize );
27 }
28 
29 PVOID LoadVersionInfo( CSTR FName, PDWORD pSize )
30 {
31  DWORD Hnd, vSize;
32  PVOID vInfo;
33  TCHAR name[ MAX_PATH ];
34 
35  if (!FName)
36  {
37  GetModuleFileName( NULL, name, dimof(name) );
38  FName = name;
39  }
40  vSize = GetFileVersionInfoSize( FName, &Hnd );
41  if (!vSize) vInfo = NULL;
42  else
43  {
44  if (pSize) *pSize = vSize;
45  vInfo = LocalAlloc( LPTR, vSize );
46  }
47  if (vInfo)
48  {
49  Hnd = 0; // Ref.MSDN: This is unused.
50  if (!GetFileVersionInfo( FName, Hnd, vSize, vInfo ))
51  {
52  LocalFree( vInfo );
53  vInfo = NULL;
54  }
55  }
56  return vInfo;
57 }
58 
59 PVOID FreeVersionInfo( PVOID vInfo )
60 {
61  return (PVOID) LocalFree( (HLOCAL) vInfo );
62 }
63 
64 // NOTE: GetVersionStr has been superceeded by GetVersionString.
65 // However, this old version stays around as a Memo until Microsoft re-opens
66 // a channel to hand in bug reports.. (There should be a law enforcing that!)
67 
68 #if 0 // 2016-11-12: BUGBUG in VerQueryValueA
69 // NtDll crashes *trying to write to the resource buffer*.
70 // VerQueryValueA assumes the resource is writable, and tries to use
71 // the resource buffer for in-place wide-char to ansi translation.
72 // (I might even had done that myself if I didn't think twice.)
73 // However, if given a direct resource pointer (eg. from Load/LockResource)
74 // the data buffer is read-only, and VerQueryValueA crashes in NtDll.
75 
76 CSTR GetVersionStr( PVOID VerBuf, CSTR BlockId, CSTR Name )
77 {
78  TCHAR vname[80];
79  PVOID buf = NULL;
80  UINT len = 0;
81 
82  _stprintf_s( vname, dimof(vname), _T("\\StringFileInfo\\%s\\%s"), BlockId, Name );
83  // In Ansi/MB builds VerQueryValue becomes VerQueryValueA, which is flawed..
84  if (!VerQueryValue( VerBuf, vname, &buf, &len ) || (len == 0))
85  buf = NULL;
86  return (CSTR) buf;
87 }
88 
89 #else
90 // NOTE: The bug does not appear in Unicode builds, since that uses VerQueryValueW,
91 // which doesn't require any resource string translation.
92 
93 // Work around the bug by always using VerQueryValueW
94 // and do the string translation manually.
95 
96 CSTR GetVersionStr( PVOID VerBuf, CSTR BlockId, CSTR Name )
97 {
98  WCHAR vname[80];
99  PVOID buf = NULL;
100  UINT len = 0;
101  #ifdef _UNICODE
102  #define _VNAME_FMT L"\\StringFileInfo\\%s\\%s"
103  #else
104  #define _VNAME_FMT L"\\StringFileInfo\\%S\\%S"
105  #endif
106 
107  swprintf_s( vname, dimof(vname), _VNAME_FMT, BlockId, Name );
108  if (!VerQueryValueW( VerBuf, vname, &buf, &len ) || (len == 0))
109  buf = NULL;
110  #ifndef _UNICODE
111  else
112  {
113  #pragma message("ALERT: Using workaround for VerQueryValueA bug. > " __FILE__ ":" PP_NSTR(__LINE__))
114  static CHAR szAnsi[ MAX_PATH ]; // Hackfix, use a static buffer
115 
116  // Take over the string translation to work around bug.
117  // Pray that the szAnsi buffer is big enough so we don't loose info.
118  // I do *not* want to bloat this simple function by extraneous heap allocations!
119  // It's bad enough that I have to hack around an MS bug (yet again),
120  // without being able to report the bug (since they closed all the doors!!)
121 
122  WideCharToMultiByte( CP_ACP, 0, (WCSTR)buf, len, szAnsi, dimof(szAnsi), 0,0 );
123  buf = szAnsi;
124  }
125  #endif
126  return (CSTR) buf;
127  #undef _VNAME_FMT
128 }
129 #endif
130 
131 // New version of GetVersionStr, uses caller supplied destination buffer.
132 
134  IN PVOID VerBuf, IN CSTR BlockId, IN CSTR Name, OUT TSTR Buffer, IN UINT BufLen
135  )
136 {
137  WCHAR vname[ 80 ];
138  PVOID buf = NULL;
139  UINT len = 0;
140  if (!Buffer || !BufLen)
141  SetLastError( ERROR_INVALID_PARAMETER );
142  else
143  {
144  *Buffer = 0;
145  #ifdef _UNICODE
146  #define _VNAME_FMT L"\\StringFileInfo\\%s\\%s"
147  #else
148  #define _VNAME_FMT L"\\StringFileInfo\\%S\\%S"
149  #endif
150  swprintf_s( vname, dimof(vname), _VNAME_FMT, BlockId, Name );
151  // Always use VerQueryValueW, since VerQueryValueA is flawed.. (See above)
152  if (!VerQueryValueW( VerBuf, vname, &buf, &len ) || (len == 0))
153  buf = NULL;
154  #ifdef _UNICODE
155  else _tcsncpyz( Buffer, (WCSTR)buf, BufLen );
156  #else// Take over the flawed VerQueryValueA string translation..
157  else WideCharToMultiByte( CP_ACP, 0, (WCSTR)buf, len, Buffer, BufLen, 0,0 );
158  #endif
159  #undef _VNAME_FMT
160  }
161 
162  return len;
163 }
164 
165 CSTR GetFixedVersionStr( PVOID vInfo )
166 {
167  static TCHAR sInfo[32] = _T("");
168 
169  VS_FIXEDFILEINFO* fvi;
170  UINT len;
171 
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 )
176  );
177  return sInfo;
178 }
179 
180 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
181 
182 bool GetVerTranslations( PVOID vInfo, PVXLT* ppXlt, PUINT pCount )
183 {
184  BOOL ok = VerQueryValue(
185  vInfo, _T("\\VarFileInfo\\Translation"), (void**)ppXlt, pCount
186  );
187  if (ok) *pCount /= sizeof(VXLT);
188  return bool_cast( ok );
189 }
190 
191 // Grab the first available translation entry.
192 // If it fails, return an empty string.
193 
195 {
196  static TCHAR szXlt[12] = _T("");
197  PVXLT pXlt; UINT len;
198 
199  if (GetVerTranslations( vInfo, &pXlt, &len ))
200  _stprintf_s( szXlt, dimof(szXlt), _T("%04X%04X"), pXlt[0].Lang, pXlt[0].Cp );
201  else
202  {
203  TRACE( DP_WARNING, _T("[uLib] GetVerTranslationStr: No translation spec found!\r\n") );
204  szXlt[0] = 0;
205  }
206  return szXlt;
207 }
208 
209 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
210 // Version string enumeration
211 // This is a rather esotheric and finicky task..
212 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
213 /*
214 struct Var {
215  WORD wLength;
216  WORD wValueLength;
217  WORD wType;
218  WCHAR szKey[];
219  WORD Padding[];
220  DWORD Value[];
221 };
222 */
223 static const BYTE cbVihFix = 6; // 3 WORDs fixed header size of VIH
224 typedef struct _viHdr // Version info header
225 {
229  WCHAR Name[1]; // Variable size
230  // Additional variably sized fields follow
231 }
232 VIH, *PVIH;
233 
234 // VIH names
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";
239 
240 // Padded count of bytes in a const WSTR (less the terminating NUL)
241 
242 #define CB_CWSTR(s) (BYTE)dwPad( sizeof(s)-sizeof(WCHAR) )
243 
244 static const BYTE cbsVerInfo = CB_CWSTR( S_VerInfo );
245 static const BYTE cbsStrInfo = CB_CWSTR( S_StrInfo );
246 static const BYTE cbsVarInfo = CB_CWSTR( S_VarInfo );
247 static const BYTE cbsTrans = CB_CWSTR( S_Trans );
248 
249 UINT EnumVersionStrings( PVOID vInfo, PFnEnumVerStr UserFunc, PVOID UserData )
250 {
251  UINT nStr = 0;
252  PVIH pVroot = (PVIH) vInfo; // Root block
253  union {
254  PVIH pVi; // Ptr to variably sized record.
255  PBYTE pb; // Ptr for castless byte pointer arithmetics on pVi.
256  }_; // Distinguished union name ;)
257 
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(); // Feefo forbid ;)
261  #endif
262 
263  _.pVi = pVroot;
264  // Forward pVi to the first StringFileInfo or VarFileInfo
265  _.pb += dwPad( cbVihFix + cbsVerInfo + pVroot->ValueLen );
266 
267  size_t sfiLen = wcslen( S_StrInfo );
268  if (wcsncmp( _.pVi->Name, S_StrInfo, sfiLen ) != 0) // If we got the VarFileInfo first
269  _.pb += dwPad( _.pVi->Length ); // .. the next one is StringFileInfo, if any
270 
271  if (wcsncmp( _.pVi->Name, S_StrInfo, sfiLen ) == 0) // If we got a StringFileInfo block
272  {
273  PVIH pSfi = _.pVi; // StringFileInfo
274 
275  // Just grab the first StringTable block present
276 
277  PVIH pStbl = (PVIH)dwAlign( PBYTE(pSfi) + cbVihFix + cbsStrInfo );
278  PVIH pEnd = (PVIH)dwAlign( PBYTE(pStbl) + pStbl->Length );
279 
280  // Forward to first version info string
281 
282  PVIH pvStr = (PVIH)dwAlign( PBYTE(pStbl) + cbVihFix + 16 ); // Name is 8 digit unicode hex str
283  while( pvStr < pEnd )
284  {
285  if (pvStr->Type == 1) // 1==String, 0==Binary
286  {
287  size_t cbName = wcsbytes( pvStr->Name );
288  PCWSTR sVal = pvStr->ValueLen
289  ? (PCWSTR)dwAlign( PBYTE(pvStr) + cbVihFix + cbName ) : L"";
290  #ifdef _UNICODE
291  #define szName pvStr->Name
292  #define szVal sVal
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 );
297  #endif
298 
299  UserFunc( szName, szVal, UserData ); // --->> Callback
300  ++nStr;
301  }
302  pvStr = (PVIH)dwAlign( PBYTE(pvStr) + pvStr->Length ); // Next
303  }
304  }
305  return nStr;
306 }
307 
308 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
309 // AboutVerBox uses a memory template, so it doesn't need a dialog resource.
310 // Hence it can live comfortably in a library.
311 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
312 
313 static const WORD ABT_HELPID = 1000;
314 static const WORD ST_HEADING = 100;
315 static const WORD LB_INFO = 101;
316 
317 #ifndef WS_VISICHILD
318  #define WS_VISICHILD (WS_CHILD| WS_VISIBLE)
319 #endif
320 #ifndef WS_SCROLL
321  #define WS_SCROLL (WS_VSCROLL| WS_HSCROLL)
322 #endif
323 
324 DIALOGPROC _AboutProc( HWND hdlg, UINT msg, WPARAM wp, LPARAM lp );
325 
326 int AboutVerBox( HWND hOwner, LPCWSTR Caption, CSTR FName )
327 {
328  PDLGTEMPLATEEX pDlg = AllocExDlgTemplate( 2048 );
329  PDLGITEMTEMPLATEEX pItem;
330 
331  // Setup the dialog template
332 
333  pItem = SetExDlgStyle( pDlg,
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
336  );
337  // Static text
338  pItem = AddExDlgItem( pItem, ORD_STATIC,
339  WS_VISICHILD| WS_GROUP| SS_CENTER| SS_CENTERIMAGE| SS_SUNKEN,
340  0, 6,6, 188,16, L"..", ST_HEADING, ABT_HELPID+ST_HEADING
341  );
342  // Listbox
343  pItem = AddExDlgItem( pItem, ORD_LISTBOX,
344  WS_VISICHILD| WS_SCROLL| WS_TABSTOP| LBS_USETABSTOPS| LBS_NOINTEGRALHEIGHT,
345  WS_EX_STATICEDGE, 6,24, 188,108, L"", LB_INFO, ABT_HELPID+LB_INFO
346  );
347  // Ok button
348  pItem = AddExDlgItem( pItem, ORD_BUTTON,
349  WS_VISICHILD| WS_TABSTOP| BS_DEFPUSHBUTTON,
350  0, 74,136, 50,14, L"&OK", IDOK, ABT_HELPID+IDOK
351  );
352 
353  // Run the modal dialog
354 
355  int rc = (int) DialogBoxIndirectParam(
356  hInstance, (LPDLGTEMPLATE)pDlg, hOwner, _AboutProc, (LPARAM) FName
357  );
358  FreeExDlgTemplate( pDlg );
359  return rc;
360 }
361 
362 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
363 // _AboutProc - Dialog proc for AboutVerBox
364 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
365 
366 static void __stdcall addVerStr( CSTR Name, CSTR Val, PVOID pCtl )
367 {
368  static int width;
369  if (!Name) width = 0; // Reset width
370  else
371  {
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 );
376  #if 1
377  {
378  SIZE size;
379  HDC hdc = GetDC( hCtl );
380  if (GetTextExtentPoint32( hdc, szItem, len, &size ))
381  {
382  if (size.cx > width)
383  {
384  width = size.cx;
385  ListBox_SetHorizontalExtent( hCtl, width );
386  }
387  }
388  ReleaseDC( hCtl, hdc );
389  }
390  #endif
391  }
392 }
393 
394 DIALOGPROC _AboutProc( HWND hdlg, UINT msg, WPARAM wp, LPARAM lp )
395 {
396  static HFONT hBold;
397 
398  HWND hCtl;
399  int tablen;
400  LOGFONT lf;
401  PVOID verInfo;
402  DWORD verSize;
403  CSTR pcz, fname;
404 
405  DRESULT rc = TRUE;
406 
407  switch( msg )
408  {
409  case WM_INITDIALOG:
410  tablen = 60;
411  hCtl = GetDlgItem( hdlg, LB_INFO );
412  ListBox_SetTabStops( hCtl, 1, &tablen );
413 
414  fname = (CSTR) lp;
415  verInfo = LoadVersionInfo( fname, &verSize );
416  if (verInfo)
417  {
418  CSTR sXlat = GetVerTranslationStr( verInfo );
419  if (!*sXlat) sXlat = V_EnMultiBlock; //V_EnUniBlock
420 
421  CSTR vStr = GetVersionStr( verInfo, sXlat, V_ProdName );
422  if (!vStr) vStr = _T("This Program");
423  SetDlgItemText( hdlg, ST_HEADING, vStr );
424 
425  addVerStr( NULL,NULL,NULL ); // Reset list width
426  IMAGE_NT_HEADERS Hdr;
427  if (ReadNTHeaders( NULL, &Hdr, true ))
428  {
429  pcz = GetMachineStr( Hdr.FileHeader.Machine );
430  addVerStr( _T("Machine"), pcz, hCtl );
431  pcz = GetSubSystemStr( Hdr.OptionalHeader.Subsystem );
432  addVerStr( _T("Subsystem"), pcz, hCtl );
433  }
434  EnumVersionStrings( verInfo, addVerStr, hCtl );
435  FreeVersionInfo( verInfo );
436  }
437  break;
438 
439  case WM_DESTROY:
440  hBold = DeleteFontEx( hBold );
441  break;
442 
443  case WM_COMMAND:
444  switch( LOWORD( wp )) {
445  case IDOK:
446  case IDCANCEL:
447  EndDialog( hdlg, LOWORD( wp ));
448  break;
449  }
450  break;
451 
452  case WM_SETFONT:
453  if (!hBold) { // Make a bold version of the dialog's font
454  GetObject( (HFONT)wp, sizeof(lf), &lf );
455  lf.lfWeight = FW_BOLD;
456  hBold = CreateFontIndirect( &lf );
457  }
458  break;
459 
460  case WM_CTLCOLORSTATIC: // Glorify the heading a bit
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 );
465  break;
466 
467  default:
468  rc = FALSE;
469  }
470  return rc;
471 }
472 
473 // EOF
unsigned long DWORD
Definition: Common.h:414
bool ReadNTHeaders(CSTR ExeName, IMAGE_NT_HEADERS *Hdr, bool GetOptHdr)
Definition: KernelUtil.cpp:994
WORD ValueLen
Definition: VerInfo.cpp:227
#define ORD_LISTBOX
Definition: DlgPlate.h:32
#define CSTR
Definition: Common.h:329
CSTR GetMachineStr(WORD Machine)
#define DIALOGPROC
Definition: Common.h:1099
unsigned short WORD
Definition: Common.h:413
#define DeleteFontEx(h)
Definition: UtilFunc.h:1771
Definition: VerInfo.cpp:224
bool GetVerTranslations(PVOID vInfo, PVXLT *ppXlt, PUINT pCount)
Definition: VerInfo.cpp:182
#define TSTR
Definition: Common.h:328
unsigned char * PBYTE
Definition: Common.h:412
#define CB_CWSTR(s)
Definition: VerInfo.cpp:242
#define dimof(x)
Definition: Common.h:949
CSTR GetVersionStr(PVOID VerBuf, CSTR BlockId, CSTR Name)
Definition: VerInfo.cpp:96
void(__stdcall * PFnEnumVerStr)(CSTR Name, CSTR Val, PVOID UserData)
Definition: VerInfo.h:26
#define TRACE(_lvl,...)
Definition: Debug.h:216
DIALOGPROC _AboutProc(HWND hdlg, UINT msg, WPARAM wp, LPARAM lp)
Definition: VerInfo.cpp:394
#define WS_VISICHILD
Definition: VerInfo.cpp:318
int AboutVerBox(HWND hOwner, LPCWSTR Caption, CSTR FName)
Definition: VerInfo.cpp:326
const wchar_t * WCSTR
Definition: Common.h:367
void FreeExDlgTemplate(PDLGTEMPLATEEX pDlg)
Definition: DlgPlate.cpp:133
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)
Definition: DlgPlate.cpp:206
BOOL(WINAPI *SysImgList::Shell_GetImageLists)(HIMAGELIST *pimlLarge
PBYTE dwAlign(PBYTE Ptr)
CCSTR V_EnMultiBlock
US English / Codepage 1252.
Definition: VerInfo.h:144
WORD Length
Definition: VerInfo.cpp:226
PVOID GetVersionResource(HMODULE hMod, CSTR ResId, PUINT pSize)
Definition: VerInfo.cpp:23
CCSTR V_ProdName
Definition: VerInfo.h:103
bool __forceinline bool_cast(BOOL B52)
Definition: Common.h:767
CSTR GetFixedVersionStr(PVOID vInfo)
Definition: VerInfo.cpp:165
#define ORD_STATIC
Definition: DlgPlate.h:31
Debug and error handling support.
HINSTANCE hInstance
Definition: Common.cpp:10
CSTR GetSubSystemStr(WORD SubSys)
#define _VNAME_FMT
PVOID FreeVersionInfo(PVOID vInfo)
Definition: VerInfo.cpp:59
#define ORD_BUTTON
Definition: DlgPlate.h:29
PVOID LoadVersionInfo(CSTR FName, PDWORD pSize)
Definition: VerInfo.cpp:29
PDLGTEMPLATEEX AllocExDlgTemplate(WORD Size)
Definition: DlgPlate.cpp:128
#define WS_SCROLL
Definition: VerInfo.cpp:321
CSTR GetVerTranslationStr(PVOID vInfo)
Definition: VerInfo.cpp:194
size_t wcsbytes(const wchar_t *Src)
Definition: StrFunc.cpp:154
#define DRESULT
Definition: Common.h:1104
Definition: VerInfo.h:121
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)
Definition: DlgPlate.cpp:146
#define DP_WARNING
Definition: Debug.h:83
UINT GetVersionString(IN PVOID VerBuf, IN CSTR BlockId, IN CSTR Name, OUT TSTR Buffer, IN UINT BufLen)
Get a specific version string.
Definition: VerInfo.cpp:133
unsigned char BYTE
Definition: Common.h:412
WORD Type
Definition: VerInfo.cpp:228
#define _tcsncpyz
Definition: StrFunc.h:77
unsigned long * PDWORD
Definition: Common.h:414
UINT EnumVersionStrings(PVOID vInfo, PFnEnumVerStr UserFunc, PVOID UserData)
Definition: VerInfo.cpp:249