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.

297 lines
8.5 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. // HCDetect.cpp
  3. //
  4. // Copyright (C) Microsoft Corp. 1999
  5. // All rights reserved
  6. //
  7. /////////////////////////////////////////////////////////////////////////////
  8. //
  9. // Description:
  10. // DLL loaded by the install engine that exposes entry points
  11. // that can determines the installation status of legacy or complex
  12. // components. The dll name and entry points are specified for a
  13. // component in the CIF file.
  14. /////////////////////////////////////////////////////////////////////////////
  15. #include <atlbase.h>
  16. #include "hcdetect.h"
  17. #include <initguid.h>
  18. //
  19. // From HelpServiceTypeLib.idl
  20. //
  21. #include <HelpServiceTypeLib.h>
  22. #include <HelpServiceTypeLib_i.c>
  23. //
  24. // Defines
  25. //
  26. #define IsDigit(c) ((c) >= '0' && (c) <= '9')
  27. #define MAX_ID 1024
  28. /////////////////////////////////////////////////////////////////////////////
  29. HRESULT getVersion( BSTR bstrVendorID ,
  30. BSTR bstrProductID ,
  31. CComBSTR& bstrValue )
  32. {
  33. TCHAR szWinDir[MAX_PATH];
  34. CComVariant cvVersionPathname;
  35. CComPtr <IXMLDOMDocument> pXMLDoc;
  36. CComPtr <IXMLDOMElement> pXMLRootElem;
  37. CComPtr <IXMLDOMNode> pXMLVersionNode;
  38. //
  39. // get windows directory
  40. //
  41. if(::GetWindowsDirectory( szWinDir, MAX_PATH ) == 0)
  42. {
  43. return E_FAIL;
  44. }
  45. _tcscat( szWinDir, "\\pchealth\\helpctr\\config\\pchver.xml" );
  46. if(SUCCEEDED(::CoCreateInstance( CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void**)&pXMLDoc )))
  47. {
  48. CComVariant cvVersionPathname = szWinDir;
  49. VARIANT_BOOL vBool;
  50. if(SUCCEEDED(pXMLDoc->load( cvVersionPathname, &vBool )) && vBool == VARIANT_TRUE)
  51. {
  52. if(SUCCEEDED(pXMLDoc->get_documentElement( &pXMLRootElem )) && pXMLRootElem)
  53. {
  54. CComBSTR bstrQuery;
  55. bstrQuery.Append( "VENDORS/VENDOR[@ID=\"" );
  56. bstrQuery.Append( bstrVendorID );
  57. bstrQuery.Append( "\"]/PRODUCT[@ID=\"" );
  58. bstrQuery.Append( bstrProductID );
  59. bstrQuery.Append( "\"]/VERSION" );
  60. if(SUCCEEDED(pXMLRootElem->selectSingleNode( bstrQuery, &pXMLVersionNode )))
  61. {
  62. CComQIPtr<IXMLDOMElement> elem = pXMLVersionNode;
  63. CComVariant vValue;
  64. if(elem && SUCCEEDED(elem->getAttribute( CComBSTR("VALUE"), &vValue )))
  65. {
  66. vValue.ChangeType( VT_BSTR );
  67. bstrValue = vValue.bstrVal;
  68. return S_OK;
  69. }
  70. }
  71. }
  72. }
  73. }
  74. return E_FAIL;
  75. }
  76. /////////////////////////////////////////////////////////////////////////////
  77. /////////////////////////////////////////////////////////////////////////////
  78. // fCompareVersion
  79. //
  80. // Returns: 1,0,-1 depending on whether dwVersion1 is greater than, equal, or
  81. // less than dwVersion2.
  82. /////////////////////////////////////////////////////////////////////////////
  83. inline int nCompareVersion(IN DWORD dwVer1,
  84. IN DWORD dwBuild1,
  85. IN DWORD dwVer2,
  86. IN DWORD dwBuild2)
  87. {
  88. int nResult = 0;
  89. if ( dwVer1 > dwVer2 )
  90. {
  91. nResult = 1;
  92. }
  93. else if ( dwVer1 < dwVer2 )
  94. {
  95. nResult = -1;
  96. }
  97. else if ( dwBuild1 > dwBuild2 ) // dwVer1 == dwVer2
  98. {
  99. nResult = 1;
  100. }
  101. else if ( dwBuild1 < dwBuild2 ) // dwVer1 == dwVer2
  102. {
  103. nResult = -1;
  104. }
  105. return nResult;
  106. }
  107. /////////////////////////////////////////////////////////////////////////////
  108. // ConvertDotVersionStrToDwords
  109. /////////////////////////////////////////////////////////////////////////////
  110. bool fConvertDotVersionStrToDwords(LPSTR pszVer, LPDWORD pdwVer, LPDWORD pdwBuild)
  111. {
  112. DWORD grVerFields[4] = {0,0,0,0};
  113. char *pch = pszVer;
  114. if (!pszVer || !pdwVer || !pdwBuild)
  115. return false;
  116. grVerFields[0] = atol(pch);
  117. for ( int index = 1; index < 4; index++ )
  118. {
  119. while ( IsDigit(*pch) && (*pch != '\0') )
  120. pch++;
  121. if ( *pch == '\0' )
  122. break;
  123. pch++;
  124. grVerFields[index] = atol(pch);
  125. }
  126. *pdwVer = (grVerFields[0] << 16) + grVerFields[1];
  127. *pdwBuild = (grVerFields[2] << 16) + grVerFields[3];
  128. return true;
  129. }
  130. /////////////////////////////////////////////////////////////////////////////
  131. // GetCifEntry
  132. // Get an entry from the CIF file.
  133. //
  134. // Comments :
  135. // We get the value differently depending on whether we are being
  136. // called by IE 4 or IE 5 Active Setup.
  137. /////////////////////////////////////////////////////////////////////////////
  138. inline bool FGetCifEntry(DETECTION_STRUCT *pDetection,
  139. char *pszParamName,
  140. char *pszParamValue,
  141. DWORD cbParamValue)
  142. {
  143. return (ERROR_SUCCESS == pDetection->pCifComp->GetCustomData(pszParamName,
  144. pszParamValue,
  145. cbParamValue));
  146. }
  147. /////////////////////////////////////////////////////////////////////////////
  148. // RegKeyExists (EXPORT)
  149. // This API will determine if an application exists based on the
  150. // existence of a registry key and perhaps a value.
  151. //
  152. // Parameters:
  153. //
  154. // Comments :
  155. /////////////////////////////////////////////////////////////////////////////
  156. DWORD WINAPI HelpPkgVersion(DETECTION_STRUCT *pDetection)
  157. {
  158. USES_CONVERSION;
  159. HRESULT hr;
  160. DWORD dwInstallStatus = DET_INSTALLED;
  161. TCHAR szVendorID[MAX_ID];
  162. TCHAR szProductID[MAX_ID];
  163. TCHAR szVersion[MAX_PATH];
  164. IPCHUpdate *pPCHUpdate = NULL;
  165. //
  166. // Initialize COM just in case
  167. //
  168. ::CoInitialize(NULL);
  169. //
  170. // make sure the struct is of the expected size
  171. //
  172. if ((pDetection->dwSize >= sizeof(DETECTION_STRUCT)))
  173. {
  174. CComBSTR bstrLatestVersion;
  175. DWORD dwCurrVersion, dwCurrBuild;
  176. DWORD dwLatestVersion, dwLatestBuild;
  177. //
  178. // get the version number from the components section of the CIF file.
  179. //
  180. if (!((FGetCifEntry(pDetection, "VendorID", szVendorID, sizeof(szVendorID))) &&
  181. (FGetCifEntry(pDetection, "ProductID", szProductID, sizeof(szProductID))) &&
  182. (FGetCifEntry(pDetection, "Version", szVersion, sizeof(szVersion)))))
  183. {
  184. goto end;
  185. }
  186. //
  187. // Convert it to build and version number
  188. //
  189. fConvertDotVersionStrToDwords(szVersion, &dwCurrVersion, &dwCurrBuild);
  190. // //
  191. // // create the IPCHUpdate object
  192. // //
  193. // if (FAILED(hr = CoCreateInstance(CLSID_PCHUpdate, NULL, CLSCTX_LOCAL_SERVER, IID_IPCHUpdate, (void**)&pPCHUpdate)))
  194. // {
  195. // goto end;
  196. // }
  197. //
  198. // //
  199. // // call to get the version number
  200. // //
  201. // if (FAILED(pPCHUpdate->LatestVersion(CComBSTR(szVendorID), CComBSTR(szProductID), &bstrLatestVersion)))
  202. // {
  203. // goto end;
  204. // }
  205. if(FAILED(getVersion( CComBSTR( szVendorID ), CComBSTR( szProductID ), bstrLatestVersion )))
  206. {
  207. dwInstallStatus = DET_NOTINSTALLED;
  208. goto end;
  209. }
  210. //
  211. // check if there is a version number, if not, return as not installed
  212. //
  213. if (bstrLatestVersion.Length() == 0)
  214. {
  215. dwInstallStatus = DET_NOTINSTALLED;
  216. goto end;
  217. }
  218. //
  219. // Convert it to build and version number
  220. //
  221. fConvertDotVersionStrToDwords(OLE2A(bstrLatestVersion), &dwLatestVersion, &dwLatestBuild);
  222. //
  223. // Compare versions, recommend that it is not installed only if current version
  224. // is greater than latest version installed on the client machine
  225. //
  226. if (nCompareVersion(dwCurrVersion, dwCurrBuild, dwLatestVersion, dwLatestBuild) == 1)
  227. {
  228. dwInstallStatus = DET_NOTINSTALLED;
  229. }
  230. }
  231. end:
  232. //
  233. // Cleanup
  234. //
  235. if (pPCHUpdate)
  236. pPCHUpdate->Release();
  237. ::CoUninitialize();
  238. return dwInstallStatus;
  239. }
  240. //DWORD WINAPI Test()
  241. //{
  242. // CComBSTR bstrVendorID = "CN=Microsoft Corporation,L=Redmond,S=Washington,C=US";
  243. // CComBSTR bstrProductID = "Microsoft Core Help Center Content";
  244. // CComBSTR bstrValue;
  245. // HRESULT hr;
  246. //
  247. // ::CoInitialize(NULL);
  248. //
  249. // hr = getVersion( bstrVendorID, bstrProductID, bstrValue );
  250. //
  251. // ::CoUninitialize();
  252. //
  253. // return hr;
  254. //}