Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
3.7 KiB

  1. #include <vector>
  2. class ATL_NO_VTABLE CVersionInfo : public IVersionInfo
  3. {
  4. public:
  5. class Info
  6. {
  7. Info () :
  8. m_Implid(GUID_NULL),
  9. m_MajorVer(0),
  10. m_MinorVer(0),
  11. m_cComponents(0),
  12. m_ComponentDescription(NULL),
  13. m_InstanceDescription(NULL),
  14. m_punk(NULL) { }
  15. Info (GUID Implid, DWORD MajorVer, DWORD MinorVer, LPCWSTR ComponentDescription, LPCWSTR InstanceDescription, IUnknown * punk) :
  16. m_Implid(Implid),
  17. m_MajorVer(MajorVer),
  18. m_MinorVer(MinorVer),
  19. m_cComponents(0),
  20. m_punk(punk)
  21. {
  22. m_ComponentDescription = SysAllocString( ComponentDescription );
  23. m_InstanceDescription = SysAllocString( InstanceDescription );
  24. }
  25. ~Info()
  26. {
  27. SysFreeString( m_ComponentDescription );
  28. SysFreeString( m_InstanceDescription );
  29. }
  30. private:
  31. friend CVersionInfo;
  32. GUID m_Implid;
  33. DWORD m_MajorVer;
  34. DWORD m_MinorVer;
  35. BSTR m_ComponentDescription;
  36. BSTR m_InstanceDescription;
  37. ULONG m_cComponents;
  38. IUnknown * m_punk;
  39. };
  40. public:
  41. CVersionInfo() { };
  42. ~CVersionInfo()
  43. {
  44. for ( int i = 0; i < m_VersionInfos.size(); i++ )
  45. {
  46. delete m_VersionInfos[i];
  47. }
  48. };
  49. void Add(GUID Implid, DWORD MajorVer, DWORD MinorVer, LPCWSTR ComponentDescription, LPCWSTR InstanceDescription, IUnknown * punk)
  50. {
  51. Info * pInfo = new Info( Implid, MajorVer, MinorVer, ComponentDescription, InstanceDescription, punk );
  52. BuildVersionInfos( *pInfo );
  53. m_VersionInfos[0]->m_cComponents = m_VersionInfos.size() - 1;
  54. }
  55. STDMETHOD(GetSubcomponentCount)( ULONG ulSub, ULONG *ulCount )
  56. {
  57. if (ulSub > m_VersionInfos.size())
  58. return E_INVALIDARG;
  59. if (m_VersionInfos.empty())
  60. *ulCount = 0;
  61. else
  62. *ulCount = m_VersionInfos[ulSub]->m_cComponents;
  63. return S_OK;
  64. }
  65. STDMETHOD(GetImplementationID)( ULONG ulSub, GUID * implid )
  66. {
  67. if (ulSub > m_VersionInfos.size())
  68. return E_INVALIDARG;
  69. *implid = m_VersionInfos[ulSub]->m_Implid;
  70. return S_OK;
  71. }
  72. STDMETHOD(GetBuildVersion)( ULONG ulSub, DWORD * pdwMajor, DWORD * pdwMinor)
  73. {
  74. if (ulSub > m_VersionInfos.size())
  75. return E_INVALIDARG;
  76. *pdwMajor = m_VersionInfos[ulSub]->m_MajorVer;
  77. *pdwMinor = m_VersionInfos[ulSub]->m_MinorVer;
  78. return S_OK;
  79. }
  80. // Expect string of the form "Company suite component version"
  81. // for human consumption only - not expected to be parsed.
  82. STDMETHOD(GetComponentDescription)( ULONG ulSub, BSTR * pImplStr )
  83. {
  84. if (ulSub > m_VersionInfos.size())
  85. return E_INVALIDARG;
  86. *pImplStr = SysAllocString( m_VersionInfos[ulSub]->m_ComponentDescription );
  87. return S_OK;
  88. }
  89. // Implementation can put any useful string here. (eg. internal object state)
  90. STDMETHOD(GetInstanceDescription)( ULONG ulSub, BSTR * pImplStr)
  91. {
  92. if (ulSub > m_VersionInfos.size())
  93. return E_INVALIDARG;
  94. *pImplStr = SysAllocString( m_VersionInfos[ulSub]->m_InstanceDescription );
  95. return S_OK;
  96. }
  97. private:
  98. void BuildVersionInfos( Info& info )
  99. {
  100. IUnknown * punk = NULL;
  101. IVersionInfo * pIVer = NULL;
  102. HRESULT hr;
  103. m_VersionInfos.push_back(&info);
  104. if (!info.m_punk)
  105. return;
  106. hr = info.m_punk->QueryInterface( IID_IVersionInfo, (void **)&pIVer );
  107. if (hr != S_OK || pIVer == NULL)
  108. return;
  109. ULONG cCount = 0;
  110. pIVer->GetSubcomponentCount( 0, &cCount );
  111. if ( cCount )
  112. {
  113. info.m_cComponents = cCount;
  114. for ( int i = 1; i <= cCount; i++ )
  115. {
  116. Info * pInfo = new Info;
  117. pIVer->GetImplementationID( i, &pInfo->m_Implid );
  118. pIVer->GetBuildVersion( i, &pInfo->m_MajorVer, &pInfo->m_MinorVer );
  119. pIVer->GetComponentDescription( i, &pInfo->m_ComponentDescription );
  120. pIVer->GetInstanceDescription( i,&pInfo->m_InstanceDescription );
  121. BuildVersionInfos( *pInfo );
  122. }
  123. }
  124. }
  125. private:
  126. std::vector < Info *> m_VersionInfos;
  127. };