Advertisement
Guest User

Untitled

a guest
Jan 28th, 2019
404
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.47 KB | None | 0 0
  1. #if DBG
  2. #define DBG_OPT(x) _CRT_UNPARENTHESIZE(x)
  3. #else
  4. #define DBG_OPT(x)
  5. #endif
  6.  
  7. class RsrcNode
  8. {
  9.     struct RsrcHeader
  10.     {
  11.         WORD  wLength;
  12.         WORD  wValueLength;
  13.         WORD  wType;
  14.         WCHAR szKey[];
  15.     };
  16.  
  17.     C_ASSERT(sizeof(RsrcHeader) == 6);
  18.  
  19.     RsrcNode* _first, *_next;
  20.     PCWSTR _name;
  21.     const void* _pvValue;
  22.     ULONG _cbValue;
  23.     WORD  _wValueLength;
  24.     WORD  _wType;
  25.  
  26.     DBG_OPT((PCSTR _prefix)); // only for debug output
  27.  
  28. public:
  29.  
  30.     bool ParseResourse(PVOID buf, ULONG size, ULONG* pLength, PCSTR prefix);
  31.  
  32.     RsrcNode(DBG_OPT((PCSTR prefix = "")))
  33.         : _next(0), _first(0) DBG_OPT((, _prefix(prefix)))
  34.     {
  35.     }
  36.  
  37.     ~RsrcNode();
  38.  
  39.     bool IsStringValue() const
  40.     {
  41.         return _wType;
  42.     }
  43.  
  44.     const void* getValue(ULONG& cb)
  45.     {
  46.         cb = _cbValue;
  47.         return _pvValue;
  48.     }
  49.  
  50.     void setValue(const void* pv, ULONG cb)
  51.     {
  52.         _pvValue = pv, _cbValue = cb;
  53.         _wValueLength = (WORD)(_wType ? cb / sizeof(WCHAR) : cb);
  54.     }
  55.  
  56.     RsrcNode* find(const PCWSTR strings[], ULONG n);
  57.  
  58.     ULONG GetSize() const;
  59.  
  60.     PVOID Store(PVOID buf, ULONG* pcb) const;
  61. };
  62.  
  63. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  64.  
  65. bool RsrcNode::ParseResourse(PVOID buf, ULONG size, ULONG* pLength, PCSTR prefix)
  66. {
  67.     union {
  68.         PVOID pv;
  69.         RsrcHeader* ph;
  70.         ULONG_PTR up;
  71.         PCWSTR sz;
  72.     };
  73.  
  74.     pv = buf;
  75.  
  76.     if (size < sizeof(RsrcHeader) || (up & 3))
  77.     {
  78.         return false;
  79.     }
  80.  
  81.     WORD wType = ph->wType;
  82.     ULONG wValueLength = ph->wValueLength, wLength = ph->wLength;
  83.     ULONG cbValue = 0;
  84.  
  85.     switch (wType)
  86.     {
  87.     case 1:
  88.         cbValue = wValueLength * sizeof(WCHAR);
  89.         break;
  90.     case 0:
  91.         cbValue = wValueLength;
  92.         break;
  93.     default:
  94.         return false;
  95.     }
  96.  
  97.     *pLength = wLength;
  98.  
  99.     if (wLength > size || wLength < sizeof(RsrcHeader) || cbValue >= (wLength -= sizeof(RsrcHeader)))
  100.     {
  101.         return false;
  102.     }
  103.  
  104.     wLength -= cbValue;
  105.  
  106.     sz = ph->szKey, _name = sz;
  107.  
  108.     do
  109.     {
  110.         if (wLength < sizeof(WCHAR))
  111.         {
  112.             return false;
  113.         }
  114.  
  115.         wLength -= sizeof(WCHAR);
  116.  
  117.     } while (*sz++);
  118.  
  119.     DbgPrint("%s%S {\n", prefix, _name);
  120.  
  121.     if (up & 3)
  122.     {
  123.         if (wLength < 2)
  124.         {
  125.             return false;
  126.         }
  127.         up += 2, wLength -= 2;
  128.     }
  129.  
  130.     _wType = wType, _wValueLength = (WORD)wValueLength, _cbValue = cbValue, _pvValue = pv;
  131.  
  132.     if (wValueLength && wType)
  133.     {
  134.         if (sz[wValueLength - 1])
  135.         {
  136.             return false;
  137.         }
  138.         DbgPrint("%s\t%S\n", prefix, sz);
  139.     }
  140.  
  141.     if (wLength)
  142.     {
  143.         if (!*--prefix) return false;
  144.  
  145.         up += wValueLength;
  146.  
  147.         do
  148.         {
  149.             if (up & 3)
  150.             {
  151.                 if (wLength < 2)
  152.                 {
  153.                     return false;
  154.                 }
  155.  
  156.                 up += 2;
  157.  
  158.                 if (!(wLength -= 2))
  159.                 {
  160.                     break;
  161.                 }
  162.             }
  163.  
  164.             if (RsrcNode* node = new RsrcNode(DBG_OPT((prefix))))
  165.             {
  166.                 node->_next = _first, _first = node;
  167.  
  168.                 if (node->ParseResourse(ph, wLength, &size, prefix))
  169.                 {
  170.                     continue;
  171.                 }
  172.             }
  173.  
  174.             return false;
  175.  
  176.         } while (up += size, wLength -= size);
  177.  
  178.         prefix++;
  179.     }
  180.  
  181.     DbgPrint("%s}\n", prefix);
  182.  
  183.     return true;
  184. }
  185.  
  186. RsrcNode::~RsrcNode()
  187. {
  188.     if (RsrcNode* next = _first)
  189.     {
  190.         do
  191.         {
  192.             RsrcNode* cur = next;
  193.             next = next->_next;
  194.             delete cur;
  195.         } while (next);
  196.     }
  197.  
  198.     DBG_OPT((DbgPrint("%s%S\n", _prefix, _name)));
  199. }
  200.  
  201. RsrcNode* RsrcNode::find(const PCWSTR strings[], ULONG n)
  202. {
  203.     PCWSTR str = *strings++;
  204.  
  205.     if (!str || !wcscmp(str, _name))
  206.     {
  207.         if (!--n)
  208.         {
  209.             return this;
  210.         }
  211.  
  212.         if (RsrcNode* next = _first)
  213.         {
  214.             do
  215.             {
  216.                 if (RsrcNode* p = next->find(strings, n))
  217.                 {
  218.                     return p;
  219.                 }
  220.             } while (next = next->_next);
  221.         }
  222.     }
  223.  
  224.     return 0;
  225. }
  226.  
  227. ULONG RsrcNode::GetSize() const
  228. {
  229.     ULONG size = sizeof(RsrcHeader) + (1 + (ULONG)wcslen(_name)) * sizeof(WCHAR);
  230.  
  231.     if (_cbValue)
  232.     {
  233.         size = ((size + 3) & ~3) + _cbValue;
  234.     }
  235.  
  236.     if (RsrcNode* next = _first)
  237.     {
  238.         do
  239.         {
  240.             size = ((size + 3) & ~3) + next->GetSize();
  241.         } while (next = next->_next);
  242.     }
  243.  
  244.     return size;
  245. }
  246.  
  247. PVOID RsrcNode::Store(PVOID buf, ULONG* pcb) const
  248. {
  249.     union {
  250.         RsrcHeader* ph;
  251.         ULONG_PTR up;
  252.         PVOID pv;
  253.     };
  254.  
  255.     pv = buf;
  256.  
  257.     ph->wType = _wType;
  258.     ph->wValueLength = _wValueLength;
  259.  
  260.     ULONG size = (1 + (ULONG)wcslen(_name)) * sizeof(WCHAR), cb;
  261.  
  262.     memcpy(ph->szKey, _name, size);
  263.  
  264.     up += (size += sizeof(RsrcHeader));
  265.  
  266.     if (_cbValue)
  267.     {
  268.         up = (up + 3) & ~3;
  269.         memcpy(pv, _pvValue, _cbValue);
  270.         up += _cbValue;
  271.         size = ((size + 3) & ~3) + _cbValue;
  272.     }
  273.  
  274.     if (RsrcNode* next = _first)
  275.     {
  276.         do
  277.         {
  278.             up = (up + 3) & ~3;
  279.             pv = next->Store(pv, &cb);
  280.             size = ((size + 3) & ~3) + cb;
  281.         } while (next = next->_next);
  282.     }
  283.  
  284.     reinterpret_cast<RsrcHeader*>(buf)->wLength = (WORD)size;
  285.  
  286.     *pcb = size;
  287.  
  288.     return pv;
  289. }
  290.  
  291. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  292.  
  293. void ParseVersionInfo(PVOID pvVersion, ULONG cbVersion)
  294. {
  295.     char prefix[16];
  296.     memset(prefix, '\t', sizeof(prefix));
  297.     prefix[RTL_NUMBER_OF(prefix) - 1] = 0;
  298.     *prefix = 0;
  299.  
  300.     if (RsrcNode* node = new RsrcNode)
  301.     {
  302.         if (node->ParseResourse(pvVersion, cbVersion, &cbVersion, prefix + RTL_NUMBER_OF(prefix) - 1))
  303.         {
  304.             static const PCWSTR str[] = {
  305.                 L"VS_VERSION_INFO", L"StringFileInfo", 0, L"FileDescription"
  306.             };
  307.  
  308.             if (RsrcNode *p = node->find(str, RTL_NUMBER_OF(str)))
  309.             {
  310.                 if (p->IsStringValue())
  311.                 {
  312.                     ULONG cb;
  313.                     const void* pcsz = p->getValue(cb);
  314.                     DbgPrint("FileDescription: %S\n", pcsz);
  315.                 }
  316.             }
  317.         }
  318.         delete node;
  319.     }
  320. }
  321.  
  322. void ParseVersionInfo(PCWSTR FileName)
  323. {
  324.     if (HMODULE hmod = LoadLibraryExW(FileName, 0, LOAD_LIBRARY_AS_IMAGE_RESOURCE))
  325.     {
  326.         if (HRSRC hResInfo = FindResourceW(hmod, MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION))
  327.         {
  328.             if (HGLOBAL hg = LoadResource(hmod, hResInfo))
  329.             {
  330.                 if (ULONG size = SizeofResource(hmod, hResInfo))
  331.                 {
  332.                     if (PVOID pv = LockResource(hg))
  333.                     {
  334.                         ParseVersionInfo(pv, size);
  335.                     }
  336.                 }
  337.             }
  338.         }
  339.  
  340.         FreeLibrary(hmod);
  341.     }
  342. }
  343.  
  344. //////////////////////////////////////////////////////////////////////////////////////////////////////
  345.  
  346. VS_VERSION_INFO {
  347.     StringFileInfo {
  348.         040904b0 {
  349.             CompanyName {
  350.                 Microsoft Corporation
  351.             }
  352.             FileDescription {
  353.                 Microsoft TTS Engine (Desktop)
  354.             }
  355.             InternalName {
  356.                 TTSEngine
  357.             }
  358.             LegalCopyright {
  359.                 © Microsoft Corporation. All rights reserved.
  360.             }
  361.             OriginalFilename {
  362.                 MSTTSEngine.dll
  363.             }
  364.             ProductName {
  365.                 Microsoft TTS Engine®
  366.             }
  367.             FileVersion {
  368.                 11.0.58.18
  369.             }
  370.             ProductVersion {
  371.                 11.0.58.18
  372.             }
  373.         }
  374.     }
  375.     VarFileInfo {
  376.         Translation {
  377.         }
  378.     }
  379. }
  380. FileDescription: Microsoft TTS Engine (Desktop)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement