home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / OWLSRC.PAK / MODVERSI.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  8.0 KB  |  301 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1995, 1997 by Borland International, All Rights Reserved
  4. //
  5. //$Revision:   10.7  $
  6. //
  7. // Implementation of class TModuleVersionInfo, version resource parser &
  8. // accessor class
  9. //----------------------------------------------------------------------------
  10. #pragma hdrignore SECTION
  11. #include <owl/pch.h>
  12. #if !defined(OWL_MODULE_H)
  13. # include <owl/module.h>
  14. #endif
  15. #include <stdio.h>
  16. #if defined(BI_PLAT_WIN16)
  17. # include <ver.h>
  18. #endif
  19.  
  20. OWL_DIAGINFO;
  21.  
  22. static char viRootStr[] =             "\\";
  23. static char viTransStr[] =            "\\VarFileInfo\\Translation";
  24. static char viSubBlockQueryFmt[] =    "\\StringFileInfo\\%08lx\\%s";
  25. static char viFileDescStr[] =         "FileDescription";
  26. static char viFileVersionStr[] =      "FileVersion";
  27. static char viInternalNameStr[] =     "InternalName";
  28. static char viLegalCopyrightStr[] =   "LegalCopyright";
  29. static char viOriginalFilenameStr[] = "OriginalFilename";
  30. static char viProductNameStr[] =      "ProductName";
  31. static char viProductVersionStr[] =   "ProductVersion";
  32. static char viSpecialBuildStr[] =     "SpecialBuild";
  33.  
  34. //
  35. // Construct a TModuleVersionInfo given a module or instance handle
  36. //
  37. TModuleVersionInfo::TModuleVersionInfo(TModule::THandle hModule)
  38. :
  39.   Buff(0),
  40.   Lang(0),
  41.   FixedInfo(0)
  42. {
  43.   char    modFName[_MAX_PATH];
  44.   ::GetModuleFileName(hModule, modFName, sizeof modFName);
  45.   ::OemToAnsi(modFName, modFName);
  46.  
  47.   if (!Init(modFName)) {
  48.     delete Buff;  
  49.     Buff = 0; 
  50.   }
  51. }
  52.  
  53. //
  54. // Construct a TModuleVersionInfo given a module filename
  55. //
  56. TModuleVersionInfo::TModuleVersionInfo(const char far* modFName)
  57. :
  58.   Buff(0),
  59.   Lang(0),
  60.   FixedInfo(0)
  61. {
  62.   if (!Init(modFName)) {
  63.     delete Buff;    
  64.     Buff = 0; 
  65.   }
  66. }
  67.  
  68. //
  69. // Internal initialization fills in the data members
  70. //
  71. bool
  72. TModuleVersionInfo::Init(const char far* modFName)
  73. {
  74.   uint32 fvHandle;
  75.   uint32 infoSize = ::GetFileVersionInfoSize((char far*)modFName, &fvHandle);
  76.   if (!infoSize) {  
  77.     long rc;
  78. #if defined(BI_PLAT_WIN16)      
  79.     rc = 0;                     
  80. #else                           
  81.     rc = GetLastError();        
  82. #endif                          
  83.     char buf[10];               
  84.     sprintf(buf, "%ld", rc);    
  85.     TXOwl::Raise(buf);          
  86.   }
  87.  
  88.   Buff  = new char[uint(infoSize)];
  89.   if (!::GetFileVersionInfo((char far*)modFName, fvHandle, infoSize, Buff))
  90.     return false;
  91.  
  92.   // Copy string to buffer so if the -dc compiler switch (Put constant
  93.   // strings in code segments) is on, VerQueryValue will work under Win16.
  94.   // This works around a problem in Microsoft's ver.dll which writes to the
  95.   // string pointed to by subBlockName.
  96.   //
  97.   uint    vInfoLen;                 // not really used, but must be passed
  98. #if defined(BI_PLAT_WIN16) && defined(BI_MODEL_LARGE)
  99.   char    subBlockName[sizeof viTransStr + 16];
  100.   strcpy(subBlockName, viRootStr);
  101. #else
  102.   char* subBlockName = viRootStr;
  103. #endif
  104.   if (!::VerQueryValue(Buff, subBlockName, (void far**)&FixedInfo, &vInfoLen))
  105.     return false;
  106.  
  107. #if defined(BI_PLAT_WIN16) && defined(BI_MODEL_LARGE)
  108.   strcpy(subBlockName, viTransStr);
  109. #else
  110.   subBlockName = viTransStr;
  111. #endif
  112.   uint32 far* trans;
  113.   if (!::VerQueryValue(Buff, subBlockName, (void far**)&trans, &vInfoLen))
  114.     return false;
  115.  
  116.   // Swap the words so sprintf will print the lang-charset in the correct
  117.   // format.
  118.   //
  119.   Lang = MkUint32(HiUint16(*trans), LoUint16(*trans));
  120.  
  121.   return true;
  122. }
  123.  
  124. //
  125. // Clean up the new'd buffer
  126. //
  127. TModuleVersionInfo::~TModuleVersionInfo()
  128. {
  129.   delete[] Buff;
  130. }
  131.  
  132. //
  133. // Query any given "\StringFileInfo\lang-charset\<str>" version info string
  134. // lang indicates the language translation, may be 0 to signify file default.
  135. //
  136. bool
  137. TModuleVersionInfo::GetInfoString(const char far* str, const char far*& value, uint lang)
  138. {
  139.   uint    vSize;
  140.   char    subBlockName[255];
  141.  
  142.   sprintf(subBlockName, viSubBlockQueryFmt, lang ? uint32(lang) : Lang, str);
  143.   return Buff ? ::VerQueryValue(Buff, subBlockName, (void far**)&value, &vSize)
  144.               : false;
  145. }
  146.  
  147. //
  148. // Commonly used, predefined info string queries. Pass requested language thru,
  149. // may be 0 to signify default.
  150. //
  151. bool TModuleVersionInfo::GetFileDescription(const char far*& fileDesc, uint lang)
  152. {
  153.   return GetInfoString(viFileDescStr, fileDesc, lang);
  154. }
  155.  
  156. //
  157. // Retrieve the file version information in the requested language id.
  158. //
  159. bool
  160. TModuleVersionInfo::GetFileVersion(const char far*& fileVersion, uint lang)
  161. {
  162.   return GetInfoString(viFileVersionStr, fileVersion, lang);
  163. }
  164.  
  165. //
  166. // Retrieve the internal name of the module.
  167. //
  168. bool
  169. TModuleVersionInfo::GetInternalName(const char far*& internalName, uint lang)
  170. {
  171.   return GetInfoString(viInternalNameStr, internalName, lang);
  172. }
  173.  
  174. //
  175. // Retrieve the copyright message.
  176. //
  177. bool
  178. TModuleVersionInfo::GetLegalCopyright(const char far*& copyright, uint lang)
  179. {
  180.   return GetInfoString(viLegalCopyrightStr, copyright, lang);
  181. }
  182.  
  183. //
  184. // Retrieve the original filename.
  185. //
  186. bool
  187. TModuleVersionInfo::GetOriginalFilename(const char far*& originalFilename, uint lang)
  188. {
  189.   return GetInfoString(viOriginalFilenameStr, originalFilename, lang);
  190. }
  191.  
  192. //
  193. // Retrieve the product name this module is associated with.
  194. //
  195. bool
  196. TModuleVersionInfo::GetProductName(const char far*& prodName, uint lang)
  197. {
  198.   return GetInfoString(viProductNameStr, prodName, lang);
  199. }
  200.  
  201. //
  202. // Retrieve the version of the product.
  203. //
  204. bool
  205. TModuleVersionInfo::GetProductVersion(const char far*& prodVersion, uint lang)
  206. {
  207.   return GetInfoString(viProductVersionStr, prodVersion, lang);
  208. }
  209.  
  210. //
  211. // Retrieve the special build number.
  212. //
  213. bool
  214. TModuleVersionInfo::GetSpecialBuild(const char far*& specialBuild, uint lang)
  215. {
  216.   return GetInfoString(viSpecialBuildStr, specialBuild, lang);
  217. }
  218.  
  219. //
  220. // Get the language name string associated with a language/charset code
  221. //
  222. string
  223. TModuleVersionInfo::GetLanguageName(uint lang)
  224. {
  225.   char langStr[128];
  226.   ::VerLanguageName(uint(lang), langStr, sizeof langStr);
  227.  
  228.   return string(langStr);
  229. }
  230.  
  231. // returns values of TFileType if GetFileType() returned
  232. // DevDriver or Font.
  233. // If GetFileType() returned VirtDriver, this function returns the virtual
  234. // device inentifier included in the virtual device control block.
  235. uint32 TModuleVersionInfo::GetFileSubType() const
  236. {
  237.   uint32 fileSubType = FixedInfo->dwFileSubtype;
  238.  
  239.   switch (GetFileType()) {
  240.     case DevDriver:
  241.       switch (FixedInfo->dwFileSubtype) {
  242.         case VFT2_UNKNOWN:
  243.           fileSubType = UnknownDevDriver;
  244.           break;
  245.         case VFT2_DRV_PRINTER:
  246.           fileSubType = PtrDriver;
  247.           break;
  248.         case VFT2_DRV_KEYBOARD:
  249.           fileSubType = KybdDriver;
  250.           break;
  251.         case VFT2_DRV_LANGUAGE:
  252.           fileSubType = LangDriver;
  253.           break;
  254.         case VFT2_DRV_DISPLAY:
  255.           fileSubType = DisplayDriver;
  256.           break;
  257.         case VFT2_DRV_MOUSE:
  258.           fileSubType = MouseDriver;
  259.           break;
  260.         case VFT2_DRV_NETWORK:
  261.           fileSubType = NtwkDriver;
  262.           break;
  263.         case VFT2_DRV_SYSTEM:
  264.           fileSubType = SysDriver;
  265.           break;
  266.         case VFT2_DRV_INSTALLABLE:
  267.           fileSubType = InstallableDriver;
  268.           break;
  269.         default: //case VFT2_DRV_SOUND:
  270.           fileSubType = SoundDriver;
  271.       }
  272.       break;
  273.     case Font:
  274.       switch (FixedInfo->dwFileSubtype) {
  275.         case VFT2_UNKNOWN:
  276.           fileSubType = UnknownFont;
  277.           break;
  278.         case VFT2_FONT_RASTER:
  279.           fileSubType = RasterFont;
  280.           break;
  281.         case VFT2_FONT_VECTOR:
  282.           fileSubType = VectorFont;
  283.           break;
  284.         default: //case VFT2_FONT_TRUETYPE:
  285.           fileSubType = TrueTypeFont;
  286.       }
  287.       break;
  288.   }
  289.   return fileSubType;
  290. }
  291.  
  292. //
  293. //
  294. //
  295. FILETIME TModuleVersionInfo::GetFileDate() const
  296. {
  297.   FILETIME ft = {FixedInfo->dwFileDateLS, FixedInfo->dwFileDateMS};
  298.   return ft;
  299. }
  300.  
  301.