Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
MachineInfo.cpp
Go to the documentation of this file.
1 /* Project nGenEx
2  Destroyer Studios LLC
3  Copyright © 1997-2004. All Rights Reserved.
4 
5  SUBSYSTEM: nGenEx.lib
6  FILE: MachineInfo.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  Collect and Display Machine, OS, and Driver Information
13 */
14 
15 #include "MemDebug.h"
16 #include "MachineInfo.h"
17 #include "Timesnap.h"
18 
19 #define DIRECTINPUT_VERSION 0x0700
20 
21 #include <stdio.h>
22 #include <ddraw.h>
23 #include <d3d9.h>
24 #include <dinput.h>
25 #include <winver.h>
26 
27 // +--------------------------------------------------------------------+
28 
29 void Print(const char* fmt, ...);
30 
31 static int cpu_class=-1;
32 static int cpu_speed=-1;
33 static int platform=-1;
34 static int dx_version=-1;
35 static int total_ram=-1;
36 
37 static OSVERSIONINFO os_ver = { sizeof(OSVERSIONINFO) };
38 static SYSTEM_INFO cpu_info;
39 static MEMORYSTATUS mem_info = { sizeof(MEMORYSTATUS) };
40 
41 // +--------------------------------------------------------------------+
42 
43 const char*
45 {
46  static char desc[256];
47 
48  static const char* cpu_names[] = {
49  "8088",
50  "8086",
51  "80286",
52  "80386",
53  "80486",
54  "Pentium",
55  "Pentium II",
56  "Pentium 3",
57  "Pentium 4"
58  };
59 
60  static const char* os_names[] = {
61  "DOS",
62  "Windows 95",
63  "Windows 98",
64  "Windows NT",
65  "Windows 2000",
66  "Windows XP",
67  "Windows XP x64",
68  "Windows Vista",
69  "Windows Seven",
70  "Future Windows"
71  };
72 
73  int cpu_index = GetCpuClass();
74  if (cpu_index < 0) cpu_index = 0;
75  else if (cpu_index > 8) cpu_index = 8;
76 
77  int os_index = GetPlatform();
78  if (os_index < 0) os_index = 0;
79 
80  sprintf_s(desc, "%s %d MHz %d MB RAM %s",
81  cpu_names[cpu_index],
82  GetCpuSpeed(),
83  GetTotalRam(),
84  os_names[os_index]);
85 
86  return desc;
87 }
88 
89 // +--------------------------------------------------------------------+
90 
91 static void DescribeCpuMake();
92 static void DescribeOwner95();
93 static void DescribeOwnerNT();
94 static void DescribeDrivers95(const char* sType);
95 static void DescribeDriversNT(const char* sType);
96 static void DescribeDriverVersion(const char* file);
97 static void DescribeDXVersion(const char* component);
98 
99 // wait for at least target_time,
100 // return the exact amount of time actually waited:
101 
102 static double SpinWait(double target_time)
103 {
104  double actual_time = 0;
105 
106  LARGE_INTEGER ifreq;
107  LARGE_INTEGER cnt1;
108  LARGE_INTEGER cnt2;
109 
110  QueryPerformanceFrequency(&ifreq);
111  double freq = (double) ifreq.QuadPart;
112 
113  QueryPerformanceCounter(&cnt1);
114 
115  do {
116  QueryPerformanceCounter(&cnt2);
117 
118  double delta = (double) (cnt2.QuadPart - cnt1.QuadPart);
119  actual_time = delta / freq;
120  }
121  while (actual_time < target_time);
122 
123  return actual_time;
124 }
125 
126 static double CalcCpuSpeed()
127 {
128  DWORD clock1 = 0;
129  DWORD clock2 = 0;
130 
131  TIMESNAP(clock1);
132 
133  double seconds = SpinWait(0.1);
134 
135  TIMESNAP(clock2);
136 
137  double clocks = clock2 - clock1;
138 
139  return (clocks/seconds);
140 }
141 
142 /****************************************************************************
143 *
144 * GetDXVersion
145 *
146 * This function returns
147 * 0 Insufficient DirectX installed
148 * 9 At least DirectX 9 installed.
149 *
150 ****************************************************************************/
151 
153 {
154  HRESULT hr = 0;
155  HINSTANCE DDHinst = 0;
156  LPDIRECT3D9 d3d9 = 0;
157  OSVERSIONINFO osVer = { sizeof(OSVERSIONINFO) };
158 
159  // First get the windows platform
160 
161  if (!GetVersionEx(&osVer))
162  return 0;
163 
164  // NT versions do not support DirectX 9
165  if (osVer.dwPlatformId == VER_PLATFORM_WIN32_NT) {
166  if (osVer.dwMajorVersion <= 4)
167  return 0;
168  }
169 
170  DDHinst = LoadLibrary("D3D9.DLL");
171  if (DDHinst == 0) {
172  return 0;
173  }
174 
175  FreeLibrary(DDHinst);
176  return 9;
177 }
178 
179 
180 // +--------------------------------------------------------------------+
181 
182 int
184 {
185  if (cpu_class < 0) {
186  GetSystemInfo(&cpu_info);
187 
188  if (cpu_info.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_INTEL ||
189  cpu_info.dwProcessorType < PROCESSOR_INTEL_PENTIUM)
190  Print("INCOMPATIBLE CPU TYPE!\n");
191 
192  if (GetPlatform() < OS_WINNT)
193  cpu_class = CPU_P5;
194 
195  else
196  cpu_class = cpu_info.wProcessorLevel;
197  }
198 
199  return cpu_class;
200 }
201 
202 // +--------------------------------------------------------------------+
203 
204 int
206 {
207  if (cpu_speed < 0) {
208  cpu_speed = (int) (CalcCpuSpeed() / 1e6);
209  }
210 
211  return cpu_speed;
212 }
213 
214 // +--------------------------------------------------------------------+
215 
216 int
218 {
219  if (total_ram < 0) {
220  GlobalMemoryStatus(&mem_info);
221  total_ram = (int) (mem_info.dwTotalPhys/(1024*1024)) + 1;
222  }
223 
224  return total_ram;
225 }
226 
227 // +--------------------------------------------------------------------+
228 
229 int
231 {
232  if (platform < 0) {
233  GetVersionEx(&os_ver);
234 
235  switch (os_ver.dwPlatformId) {
236  default:
237  case VER_PLATFORM_WIN32s:
238  case VER_PLATFORM_WIN32_WINDOWS: {
239  char msg[256];
240  sprintf_s(msg, "Invalid Operating System Platform: %d\n", os_ver.dwPlatformId);
241  Print(msg);
242  }
243  break;
244 
245  case VER_PLATFORM_WIN32_NT:
246  if (os_ver.dwMajorVersion == 4)
247  platform = OS_WINNT;
248  else if (os_ver.dwMajorVersion == 5 && os_ver.dwMinorVersion == 0)
249  platform = OS_WIN2K;
250  else if (os_ver.dwMajorVersion == 5 && os_ver.dwMinorVersion == 1)
251  platform = OS_WINXP;
252  else if (os_ver.dwMajorVersion == 5 && os_ver.dwMinorVersion == 2)
253  platform = OS_WINXP64;
254  else if (os_ver.dwMajorVersion == 6 && os_ver.dwMinorVersion == 0)
255  platform = OS_WINVISTA;
256  else if (os_ver.dwMajorVersion == 6 && os_ver.dwMinorVersion == 1)
257  platform = OS_WINSEVEN;
258  else if (os_ver.dwMajorVersion >= 6)
259  platform = OS_WINFUTURE;
260 
261  else {
262  platform = OS_INVALID;
263 
264  Print("Invalid Operating System Platform (NT-series): %d.%d\n", os_ver.dwMajorVersion, os_ver.dwMinorVersion);
265  }
266 
267  break;
268  }
269  }
270 
271  return platform;
272 }
273 
274 // +--------------------------------------------------------------------+
275 
276 int
278 {
279  if (dx_version < 0) {
280  dx_version = GetDXVersion();
281  }
282 
283  return dx_version;
284 }
285 
286 // +--------------------------------------------------------------------+
287 
288 void
290 {
291  GetPlatform();
292  GetCpuClass();
293 
294  Print("+====================================================================+\n");
295  Print("| |\n");
296 
297  char txt[256];
298 
299  switch (platform) {
300  case OS_WIN95:
301  sprintf_s(txt, "Windows 95 version %d.%d.%d %s",
302  os_ver.dwMajorVersion,
303  os_ver.dwMinorVersion,
304  LOWORD(os_ver.dwBuildNumber),
305  os_ver.szCSDVersion);
306  break;
307 
308  case OS_WIN98:
309  sprintf_s(txt, "Windows 98 version %d.%d.%d %s",
310  os_ver.dwMajorVersion,
311  os_ver.dwMinorVersion,
312  LOWORD(os_ver.dwBuildNumber),
313  os_ver.szCSDVersion);
314  break;
315 
316  case OS_WINNT:
317  sprintf_s(txt, "Windows NT %d.%d (Build %d) %s",
318  os_ver.dwMajorVersion,
319  os_ver.dwMinorVersion,
320  os_ver.dwBuildNumber,
321  os_ver.szCSDVersion);
322  break;
323 
324  case OS_WIN2K:
325  sprintf_s(txt, "Windows 2000 %d.%d (Build %d) %s",
326  os_ver.dwMajorVersion,
327  os_ver.dwMinorVersion,
328  os_ver.dwBuildNumber,
329  os_ver.szCSDVersion);
330 
331  case OS_WINXP:
332  sprintf_s(txt, "Windows XP %d.%d (Build %d) %s",
333  os_ver.dwMajorVersion,
334  os_ver.dwMinorVersion,
335  os_ver.dwBuildNumber,
336  os_ver.szCSDVersion);
337  break;
338  case OS_WINXP64:
339  sprintf_s(txt, "Windows XP x64 %d.%d (Build %d) %s",
340  os_ver.dwMajorVersion,
341  os_ver.dwMinorVersion,
342  os_ver.dwBuildNumber,
343  os_ver.szCSDVersion);
344  break;
345  case OS_WINVISTA:
346  sprintf_s(txt, "Windows Vista %d.%d (Build %d) %s",
347  os_ver.dwMajorVersion,
348  os_ver.dwMinorVersion,
349  os_ver.dwBuildNumber,
350  os_ver.szCSDVersion);
351  break;
352  case OS_WINSEVEN:
353  sprintf_s(txt, "Windows 7 %d.%d (Build %d) %s",
354  os_ver.dwMajorVersion,
355  os_ver.dwMinorVersion,
356  os_ver.dwBuildNumber,
357  os_ver.szCSDVersion);
358  break;
359  case OS_WINFUTURE:
360  sprintf_s(txt, "Windows from the future %d.%d (Build %d) %s",
361  os_ver.dwMajorVersion,
362  os_ver.dwMinorVersion,
363  os_ver.dwBuildNumber,
364  os_ver.szCSDVersion);
365  break;
366 
367  default:
368  sprintf_s(txt, "Unknown Operating System Platform");
369  break;
370  }
371 
372  Print("| %-66s |\n", txt);
373  Print("| |\n");
374 
375  if (platform == OS_WIN95 || platform == OS_WIN98)
376  DescribeOwner95();
377  else
378  DescribeOwnerNT();
379 
380  sprintf_s(txt, "CPUs Detected: %d CPU Level: %d.%d.%d CPU Speed: %d",
381  cpu_info.dwNumberOfProcessors,
382  cpu_info.wProcessorLevel,
383  cpu_info.wProcessorRevision >> 8,
384  cpu_info.wProcessorRevision & 0xff,
385  GetCpuSpeed() + 1);
386 
387  Print("| %-66s |\n", txt);
388  DescribeCpuMake();
389 
390  GlobalMemoryStatus(&mem_info);
391  total_ram = (int) (mem_info.dwTotalPhys/(1024*1024)) + 1;
392  int swap_max = (int) (mem_info.dwTotalPageFile/(1024*1024));
393  int swap_avail = (int) (mem_info.dwAvailPageFile/(1024*1024));
394 
395  sprintf_s(txt, "%d MB RAM %d MB Max Swap %d MB Avail Swap",
396  total_ram, swap_max, swap_avail);
397 
398 
399  Print("| %-66s |\n", txt);
400 
401  Print("| |\n");
402  Print("| DirectX %d installed. |\n",
404  DescribeDXVersion("DDRAW");
405  DescribeDXVersion("D3DIM");
406  DescribeDXVersion("DINPUT");
407  DescribeDXVersion("DPLAY");
408  DescribeDXVersion("DSOUND");
409  DescribeDXVersion("DMUSIC");
410  DescribeDXVersion("DSHOW");
411  Print("| |\n");
412 
413 
414  if (platform == OS_WIN95 || platform == OS_WIN98) {
415  DescribeDrivers95("Display");
416  DescribeDrivers95("Media");
417  DescribeDrivers95("Monitor");
418  DescribeDrivers95("Multimedia");
419  }
420  else {
421  DescribeDriversNT("");
422  }
423 
424  Print("+====================================================================+\n");
425  Print("\n");
426 }
427 
428 // +--------------------------------------------------------------------+
429 
430 static void DescribeCpuMake()
431 {
432  HKEY hkWin;
433  char sProcessor[256] = "";
434  char sMMXInfo[256] = "";
435  char sVendor[256] = "";
436  DWORD dwSize;
437 
438  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
439  "Hardware\\Description\\System\\CentralProcessor\\0",
440  0,
441  KEY_READ,
442  &hkWin) == ERROR_SUCCESS) {
443 
444  dwSize = 256;
445  RegQueryValueEx(hkWin,
446  "Identifier",
447  NULL,
448  NULL,
449  (LPBYTE) sProcessor,
450  &dwSize);
451 
452  dwSize = 256;
453  RegQueryValueEx(hkWin,
454  "MMXIdentifier",
455  NULL,
456  NULL,
457  (LPBYTE) sMMXInfo,
458  &dwSize);
459 
460  dwSize = 256;
461  RegQueryValueEx(hkWin,
462  "VendorIdentifier",
463  NULL,
464  NULL,
465  (LPBYTE) sVendor,
466  &dwSize);
467 
468  RegCloseKey(hkWin);
469  }
470 
471  if (sProcessor[0]) Print("| %-66s |\n", sProcessor);
472  if (sMMXInfo[0]) Print("| %-66s |\n", sMMXInfo);
473  if (sVendor[0]) Print("| %-66s |\n", sVendor);
474 
475  if (sProcessor[0] || sMMXInfo[0] || sVendor[0])
476  Print("| |\n");
477 }
478 
479 // +--------------------------------------------------------------------+
480 
481 static void DescribeOwner95()
482 {
483  HKEY hkWin;
484  char sRegisteredOwner[256] = "";
485  char sRegisteredOrganization[256] = "";
486  DWORD dwSize;
487 
488  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
489  "SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
490  0,
491  KEY_READ,
492  &hkWin) == ERROR_SUCCESS) {
493 
494  dwSize = 256;
495  RegQueryValueEx(hkWin,
496  "RegisteredOwner",
497  NULL,
498  NULL,
499  (LPBYTE) sRegisteredOwner,
500  &dwSize);
501 
502  dwSize = 256;
503  RegQueryValueEx(hkWin,
504  "RegisteredOrganization",
505  NULL,
506  NULL,
507  (LPBYTE) sRegisteredOrganization,
508  &dwSize);
509 
510  RegCloseKey(hkWin);
511  }
512  else {
513  Print("Could not access registered owner\n");
514  }
515 
516  if (sRegisteredOwner[0]) {
517  char txt[256];
518  sprintf_s(txt, "Registered Owner: %s, %s", sRegisteredOwner, sRegisteredOrganization);
519  Print("| %-66s |\n", txt);
520  Print("| |\n");
521  }
522 }
523 
524 static void DescribeOwnerNT()
525 {
526  HKEY hkWin;
527  char sRegisteredOwner[256] = "";
528  char sRegisteredOrganization[256] = "";
529  DWORD dwSize;
530 
531  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
532  "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
533  0,
534  KEY_READ,
535  &hkWin) == ERROR_SUCCESS) {
536 
537  dwSize = 256;
538  RegQueryValueEx(hkWin,
539  "RegisteredOwner",
540  NULL,
541  NULL,
542  (LPBYTE) sRegisteredOwner,
543  &dwSize);
544 
545  dwSize = 256;
546  RegQueryValueEx(hkWin,
547  "RegisteredOrganization",
548  NULL,
549  NULL,
550  (LPBYTE) sRegisteredOrganization,
551  &dwSize);
552 
553  RegCloseKey(hkWin);
554  }
555  else {
556  Print("Could not access registered owner\n");
557  }
558 
559  if (sRegisteredOwner[0]) {
560  char txt[256];
561  sprintf_s(txt, "Registered Owner: %s, %s", sRegisteredOwner, sRegisteredOrganization);
562  Print("| %-66s |\n", txt);
563  Print("| |\n");
564  }
565 }
566 
567 // +--------------------------------------------------------------------+
568 
569 static void DescribeDrivers95(const char* sType)
570 {
571  HKEY hkWin, hkSub;
572  int nKey = 0;
573  char sKey[256];
574  char sSub[256];
575  char sDriver[256];
576  char txt[256];
577  DWORD dwSize;
578  int worked;
579 
580  // describe the video driver(s):
581  do {
582  worked = 0;
583 
584  sprintf_s(sKey, "System\\CurrentControlSet\\Services\\Class\\%s\\%04X", sType, nKey);
585  sprintf_s(sSub, "System\\CurrentControlSet\\Services\\Class\\%s\\%04X\\DEFAULT", sType, nKey);
586 
587  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
588  sKey,
589  0,
590  KEY_READ,
591  &hkWin) == ERROR_SUCCESS) {
592 
593  dwSize = 256;
594  RegQueryValueEx(hkWin,
595  "DriverDesc",
596  NULL,
597  NULL,
598  (LPBYTE) sDriver,
599  &dwSize);
600 
601  if (sDriver[0]) {
602  sprintf_s(txt, "* %s", sDriver);
603  Print("| %-66s |\n", txt);
604  worked = 1;
605  }
606 
607  // try to find the driver file name:
608  if (worked) {
609  ZeroMemory(sDriver, sizeof(sDriver));
610 
611  dwSize = 256;
612  DWORD err = RegQueryValueEx(hkWin, "Driver", NULL, NULL, (LPBYTE) sDriver, &dwSize);
613 
614  if (err != ERROR_SUCCESS) {
615  dwSize = 256;
616  err = RegQueryValueEx(hkWin, "DeviceDriver", NULL, NULL, (LPBYTE) sDriver, &dwSize);
617  }
618 
619  if (err != ERROR_SUCCESS) {
620  dwSize = 256;
621  err = RegQueryValueEx(hkWin, "drv", NULL, NULL, (LPBYTE) sDriver, &dwSize);
622  }
623 
624  if (err != ERROR_SUCCESS) {
625  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
626  sSub,
627  0,
628  KEY_READ,
629  &hkSub) == ERROR_SUCCESS) {
630 
631  dwSize = 256;
632  err = RegQueryValueEx(hkSub, "drv", NULL, NULL, (LPBYTE) sDriver, &dwSize);
633 
634  RegCloseKey(hkSub);
635  }
636  }
637 
638  // if we found it, try to display version info:
639  if (err == ERROR_SUCCESS) {
640  DescribeDriverVersion(sDriver);
641  }
642 
643  Print("| |\n");
644  }
645 
646  RegCloseKey(hkWin);
647  }
648 
649  nKey++;
650  }
651  while (worked);
652 }
653 
654 static void DescribeDriversNT(const char* sType)
655 {
656  Print("| |\n");
657 
658  HKEY hkWin;
659  char sVideo[256] = "";
660  char sDriver[256] = "";
661  DWORD dwSize = NULL;
662 
663  // find the pointer to the video driver:
664  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
665  "HARDWARE\\DEVICEMAP\\VIDEO",
666  0,
667  KEY_READ,
668  &hkWin) == ERROR_SUCCESS) {
669 
670  dwSize = 256;
671  RegQueryValueEx(hkWin,
672  "\\Device\\Video0",
673  NULL,
674  NULL,
675  (LPBYTE) sVideo,
676  &dwSize);
677 
678  RegCloseKey(hkWin);
679  }
680 
681  // follow the pointer and get the driver description:
682  if (dwSize && sVideo[0]) {
683  const char* sLeader = "\\REGISTRY\\Machine\\";
684  int nLeader = strlen(sLeader);
685 
686  if (_strnicmp(sVideo, sLeader, nLeader) == 0) {
687  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
688  sVideo + nLeader,
689  0,
690  KEY_READ,
691  &hkWin) == ERROR_SUCCESS) {
692 
693  dwSize = 256;
694  RegQueryValueEx(hkWin,
695  "Device Description",
696  NULL,
697  NULL,
698  (LPBYTE) sDriver,
699  &dwSize);
700 
701  RegCloseKey(hkWin);
702  }
703  }
704  }
705 
706  if (sDriver[0]) {
707  Print("| %-66s |\n", sDriver);
708  Print("| |\n");
709  }
710 }
711 
712 // +--------------------------------------------------------------------+
713 
714 static char sTranslation[16];
715 
716 static void GetTranslation(const LPBYTE pBlock)
717 {
718  LPBYTE sData = NULL;
719  UINT lenData = 0;
720 
721  if (VerQueryValue(pBlock, "\\VarFileInfo\\Translation",
722  (LPVOID*) &sData, &lenData)) {
723 
724  if (lenData && sData) {
725  sprintf_s(sTranslation, "%02X%02X%02X%02X", sData[1], sData[0], sData[3], sData[2]);
726  }
727  }
728 }
729 
730 void DisplayVersionString(const LPBYTE pBlock, LPTSTR sSection)
731 {
732  char txt[256];
733  char sFullSection[256];
734 
735  sprintf_s(sFullSection, "\\StringFileInfo\\%s\\%s", sTranslation, sSection);
736 
737  LPBYTE sData = NULL;
738  UINT lenData = 0;
739  DWORD dwErr = 0;
740 
741  if (VerQueryValue(pBlock, sFullSection, (LPVOID*) &sData, &lenData)) {
742  if (lenData && sData) {
743  sprintf_s(txt, "%-16s %s", sSection, sData);
744  Print("| %-60s |\n", txt);
745  }
746  }
747 }
748 
749 static void DescribeDriverVersion(const char* file)
750 {
751  DWORD dwHandle = 0;
752  TCHAR szFile[512];
753 
754  strcpy_s(szFile, file);
755 
756  int nBytes = GetFileVersionInfoSize(szFile, &dwHandle);
757 
758  if (nBytes <= 0) {
759  char szWinDir[256];
760  GetSystemDirectory(szWinDir, 256);
761  sprintf_s(szFile, "%s\\%s", szWinDir, file);
762 
763  nBytes = GetFileVersionInfoSize(szFile, &dwHandle);
764 
765  if (nBytes <= 0)
766  return;
767  }
768 
769  LPBYTE pBlock = new(__FILE__,__LINE__) BYTE[nBytes];
770 
771  if (pBlock && GetFileVersionInfo(szFile, dwHandle, nBytes, (LPVOID) pBlock)) {
772  GetTranslation(pBlock);
773  DisplayVersionString(pBlock, "CompanyName");
774  // DisplayVersionString(pBlock, "FileDescription");
775  DisplayVersionString(pBlock, "FileVersion");
776  // DisplayVersionString(pBlock, "InternalName");
777  // DisplayVersionString(pBlock, "LegalCopyright");
778  // DisplayVersionString(pBlock, "OriginalFilename");
779  // DisplayVersionString(pBlock, "ProductName");
780  // DisplayVersionString(pBlock, "ProductVersion");
781  // DisplayVersionString(pBlock, "Comments");
782  // DisplayVersionString(pBlock, "LegalTrademarks");
783  // DisplayVersionString(pBlock, "PrivateBuild");
784  // DisplayVersionString(pBlock, "SpecialBuild");
785  }
786 
787  delete [] pBlock;
788 }
789 
790 static void DescribeDXVersion(const char* component)
791 {
792  DWORD dwHandle = 0;
793  char szFile[512];
794  char szWinDir[512];
795 
796  GetSystemDirectory(szWinDir, 512);
797 
798  sprintf_s(szFile, "%s\\%s.dll", szWinDir, component);
799 
800  int nBytes = GetFileVersionInfoSize(szFile, &dwHandle);
801 
802  if (nBytes <= 0) {
803  return;
804  }
805 
806  LPBYTE pBlock = new(__FILE__,__LINE__) BYTE[nBytes];
807 
808  if (pBlock && GetFileVersionInfo(szFile, dwHandle, nBytes, (LPVOID) pBlock)) {
809  GetTranslation(pBlock);
810 
811  char txt[256];
812  char sFullSection[256];
813  LPBYTE sData = NULL;
814  UINT lenData = 0;
815  DWORD dwErr = 0;
816 
817  sprintf_s(sFullSection, "\\StringFileInfo\\%s\\FileVersion", sTranslation);
818 
819  if (VerQueryValue(pBlock, sFullSection, (LPVOID*) &sData, &lenData)) {
820  if (lenData && sData) {
821  sprintf_s(txt, "%-8s%s", component, sData);
822  Print("| %-64s |\n", txt);
823  }
824  }
825  }
826 
827  delete [] pBlock;
828 }