Leaked source code of windows server 2003
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.

1089 lines
36 KiB

  1. /********************************************************************
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. pkgdesc.cpp
  5. Abstract:
  6. Functions related to package description file processing
  7. Revision History:
  8. Ghim-Sim Chua (gschua) 07/07/99
  9. - created
  10. ********************************************************************/
  11. #include "stdafx.h"
  12. #include <strsafe.h>
  13. ////////////////////////////////////////////////////////////////////////////////
  14. const LPCWSTR HCUpdate::Engine::s_ActionText[] = { L"ADD", L"DELETE" };
  15. ////////////////////////////////////////////////////////////////////////////////
  16. long HCUpdate::Engine::CountNodes( /*[in]*/ IXMLDOMNodeList* poNodeList )
  17. {
  18. long lCount = 0;
  19. if(poNodeList)
  20. {
  21. (void)poNodeList->get_length( &lCount );
  22. }
  23. return lCount;
  24. }
  25. ////////////////////////////////////////////////////////////////////////////////
  26. void HCUpdate::Engine::DeleteTempFile( /*[in/out]*/ MPC::wstring& szFile )
  27. {
  28. if(FAILED(MPC::RemoveTemporaryFile( szFile )))
  29. {
  30. WriteLog( HRESULT_FROM_WIN32(ERROR_CAN_NOT_COMPLETE), L"Error cannot delete temporary file" );
  31. }
  32. }
  33. HRESULT HCUpdate::Engine::PrepareTempFile( /*[in/out]*/ MPC::wstring& szFile )
  34. {
  35. DeleteTempFile( szFile );
  36. return MPC::GetTemporaryFileName( szFile );
  37. }
  38. HRESULT HCUpdate::Engine::LookupAction( /*[in] */ LPCWSTR szAction ,
  39. /*[out]*/ Action& id )
  40. {
  41. if(szAction)
  42. {
  43. if(_wcsicmp( szAction, L"ADD" ) == 0)
  44. {
  45. id = ACTION_ADD; return S_OK;
  46. }
  47. if(_wcsicmp( szAction, L"DEL" ) == 0)
  48. {
  49. id = ACTION_DELETE; return S_OK;
  50. }
  51. }
  52. return WriteLog( HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION), L"Error Unknown action used to install trusted content" );
  53. }
  54. HRESULT HCUpdate::Engine::LookupBoolean( /*[in] */ LPCWSTR szString ,
  55. /*[out]*/ bool& fVal ,
  56. /*[in] */ bool fDefault )
  57. {
  58. if(szString[0] == 0)
  59. {
  60. fVal = fDefault; return S_OK;
  61. }
  62. if(_wcsicmp( szString, L"TRUE" ) == 0 ||
  63. _wcsicmp( szString, L"1" ) == 0 ||
  64. _wcsicmp( szString, L"ON" ) == 0 )
  65. {
  66. fVal = true; return S_OK;
  67. }
  68. if(_wcsicmp( szString, L"FALSE" ) == 0 ||
  69. _wcsicmp( szString, L"0" ) == 0 ||
  70. _wcsicmp( szString, L"OFF" ) == 0 )
  71. {
  72. fVal = false; return S_OK;
  73. }
  74. fVal = false; return S_OK;
  75. }
  76. HRESULT HCUpdate::Engine::LookupNavModel( /*[in] */ LPCWSTR szString ,
  77. /*[out]*/ long& lVal ,
  78. /*[in] */ long lDefault )
  79. {
  80. if(_wcsicmp( szString, L"DEFAULT" ) == 0) { lVal = QR_DEFAULT; return S_OK; }
  81. if(_wcsicmp( szString, L"DESKTOP" ) == 0) { lVal = QR_DESKTOP; return S_OK; }
  82. if(_wcsicmp( szString, L"SERVER" ) == 0) { lVal = QR_SERVER ; return S_OK; }
  83. lVal = lDefault; return S_OK;
  84. }
  85. ////////////////////////////////////////////////////////////////////////////////
  86. ////////////////////////////////////////////////////////////////////////////////
  87. ////////////////////////////////////////////////////////////////////////////////
  88. /*****************************************************************************
  89. *
  90. * FUNCTION : AppendVendorDir
  91. *
  92. * DESCRIPTION : Checks to see if it is a URL, if not, appends the correct path in front
  93. *
  94. * INPUTS :
  95. *
  96. * RETURNS :
  97. *
  98. * COMMENTS : Rules :
  99. * 1. Apply environment variable (%env%) changes to URI string
  100. * 2. Check if it has a '://' substring, if so it is a URL, do nothing and return
  101. * 3. Check if there is a ':\' or ':/' substring, if so it has a fixed path, do nothing and return
  102. * 4. Assume it is a relative path, prefix with vendor directory and return
  103. *
  104. *****************************************************************************/
  105. HRESULT HCUpdate::Engine::AppendVendorDir( /*[in] */ LPCWSTR szURL ,
  106. /*[in] */ LPCWSTR szOwnerID ,
  107. /*[in] */ LPCWSTR szWinDir ,
  108. /*[out]*/ LPWSTR szDest ,
  109. /*[in] */ int iMaxLen )
  110. {
  111. __HCP_FUNC_ENTRY( "HCUpdate::Engine::AppendVendorDir" );
  112. HRESULT hr;
  113. LPWSTR rgTemp = NULL;
  114. LPWSTR rgTemp2 = NULL;
  115. __MPC_EXIT_IF_ALLOC_FAILS(hr, rgTemp, new WCHAR[iMaxLen]);
  116. StringCchCopyW( rgTemp, iMaxLen, szURL );
  117. //
  118. // Check for :/ or :\ substring. If so, ignore.
  119. //
  120. if(_wcsnicmp( rgTemp, L"app:", 4 ) == 0 ||
  121. wcsstr ( rgTemp, L":/" ) ||
  122. wcsstr ( rgTemp, L":\\" ) )
  123. {
  124. StringCchCopyW( szDest, iMaxLen, rgTemp ); // Just copy straight since it is either a URL or fixed path.
  125. }
  126. else // Assume relative path.
  127. {
  128. int i = 0;
  129. //
  130. // Skip the initial slashes.
  131. //
  132. while(rgTemp[i] == '\\' ||
  133. rgTemp[i] == '/' )
  134. {
  135. i++;
  136. }
  137. //
  138. // If 'szWinDir' is not null, then a straight file path is required, otherwise a URL is required.
  139. //
  140. if(szWinDir)
  141. {
  142. MPC::wstring strRoot;
  143. __MPC_EXIT_IF_METHOD_FAILS(hr, m_ts.BaseDir( strRoot )); strRoot.append( HC_HELPSET_SUB_VENDORS );
  144. StringCchPrintfW( szDest, iMaxLen-1, L"%s\\%s\\%s", strRoot.c_str(), szOwnerID, &rgTemp[i] ); szDest[iMaxLen-1] = 0;
  145. //
  146. // Replace all / with \ character.
  147. //
  148. while(szDest[0])
  149. {
  150. if(szDest[0] == '/')
  151. {
  152. szDest[0] = '\\';
  153. }
  154. szDest++;
  155. }
  156. }
  157. else
  158. {
  159. const int iSizeMax = INTERNET_MAX_PATH_LENGTH;
  160. DWORD dwSize = iMaxLen-1;
  161. __MPC_EXIT_IF_ALLOC_FAILS(hr, rgTemp2, new WCHAR[iSizeMax]);
  162. StringCchPrintfW( rgTemp2, iSizeMax-1, PCH_STR_VENDOR_URL, szOwnerID, &rgTemp[i] ); rgTemp2[iSizeMax-1] = 0;
  163. ::InternetCanonicalizeUrlW( rgTemp2, szDest, &dwSize, ICU_ENCODE_SPACES_ONLY );
  164. //
  165. // Replace all \ with / character.
  166. //
  167. while(szDest[0])
  168. {
  169. if(szDest[0] == _T('\\'))
  170. {
  171. szDest[0] = _T('/');
  172. }
  173. szDest++;
  174. }
  175. }
  176. }
  177. hr = S_OK;
  178. __HCP_FUNC_CLEANUP;
  179. delete [] rgTemp;
  180. delete [] rgTemp2;
  181. __HCP_FUNC_EXIT(hr);
  182. }
  183. /*****************************************************************************
  184. *
  185. * FUNCTION : RegisterContentIsValidProtocol
  186. *
  187. * DESCRIPTION : Check if the registered trusted content is a
  188. * valid protocol (hcp:, ms-its:, http:, https:, file:)
  189. *
  190. *****************************************************************************/
  191. static HRESULT RegisterContentIsValidProtocol( /*[in]*/ LPCWSTR szURL )
  192. {
  193. __HCP_FUNC_ENTRY( "RegisterContentIsValidProtocol" );
  194. HRESULT hr = E_FAIL;
  195. // Allow hcp: and ms-its:
  196. if (!_wcsnicmp(szURL, L"hcp:", 4) ||
  197. !_wcsnicmp(szURL, L"ms-its:", 7))
  198. {
  199. hr = S_OK;
  200. }
  201. else
  202. {
  203. // Check URL scheme
  204. MPC::URL url;
  205. INTERNET_SCHEME scheme;
  206. if(SUCCEEDED(url.put_URL ( szURL )) &&
  207. SUCCEEDED(url.get_Scheme( scheme )) )
  208. {
  209. // Allow http:, https: and file:
  210. switch(scheme)
  211. {
  212. case INTERNET_SCHEME_HTTP :
  213. case INTERNET_SCHEME_HTTPS :
  214. case INTERNET_SCHEME_FILE : hr = S_OK;
  215. }
  216. }
  217. }
  218. __HCP_FUNC_EXIT(hr);
  219. }
  220. /*****************************************************************************
  221. *
  222. * FUNCTION : ProcessRegisterContent
  223. *
  224. * DESCRIPTION : Registers trusted content with the content store
  225. *
  226. * INPUTS :
  227. *
  228. * RETURNS :
  229. *
  230. * COMMENTS :
  231. *
  232. *****************************************************************************/
  233. HRESULT HCUpdate::Engine::ProcessRegisterContent( /*[in]*/ Action idAction ,
  234. /*[in]*/ LPCWSTR szURI )
  235. {
  236. __HCP_FUNC_ENTRY( "HCUpdate::Engine::ProcessRegisterContent" );
  237. HRESULT hr;
  238. HRESULT hr2;
  239. WCHAR rgDestPath[MAX_PATH];
  240. bool fCSLocked = false;
  241. PCH_MACRO_CHECK_STRINGW(hr, szURI, L"Error missing URI attribute");
  242. //
  243. // Get the complete URL for the link.
  244. //
  245. AppendVendorDir( szURI, m_pkg->m_strVendorID.c_str(), NULL, rgDestPath, MAXSTRLEN(rgDestPath) );
  246. WriteLog( S_OK, L"Registering trusted content : %s", s_ActionText[idAction] );
  247. //
  248. // Initialize the content store for processing.
  249. //
  250. if(FAILED(hr = CPCHContentStore::s_GLOBAL->Acquire()))
  251. {
  252. __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( hr, L"Error initializing the content store" ));
  253. }
  254. fCSLocked = true;
  255. if(idAction == ACTION_ADD)
  256. {
  257. //
  258. // Check if URL is an allowed protocol
  259. //
  260. if(FAILED(hr = RegisterContentIsValidProtocol(rgDestPath)))
  261. {
  262. __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( hr, L"Trusted content is not an allowed protocol" ));
  263. }
  264. if(FAILED(hr = CPCHContentStore::s_GLOBAL->Add( rgDestPath, m_pkg->m_strVendorID.c_str(), m_pkg->m_strVendorName.c_str() )))
  265. {
  266. if(hr == E_PCH_URI_EXISTS)
  267. {
  268. PCH_MACRO_DEBUG( L"Trusted content already registered" );
  269. }
  270. else
  271. {
  272. PCH_MACRO_DEBUG( L"Error Register trusted content failed" );
  273. }
  274. }
  275. else
  276. {
  277. PCH_MACRO_DEBUG( L"Trusted content registered" );
  278. }
  279. }
  280. else if(idAction == ACTION_DELETE)
  281. {
  282. if(FAILED(hr = CPCHContentStore::s_GLOBAL->Remove( rgDestPath, m_pkg->m_strVendorID.c_str(), m_pkg->m_strVendorName.c_str() )))
  283. {
  284. __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( hr, L"Error Remove trusted content failed" ));
  285. }
  286. PCH_MACRO_DEBUG( L"Trusted content removed" );
  287. }
  288. hr = S_OK;
  289. __HCP_FUNC_CLEANUP;
  290. if(fCSLocked)
  291. {
  292. if(FAILED(hr2 = CPCHContentStore::s_GLOBAL->Release( true )))
  293. {
  294. WriteLog( hr2, L"Error committing into Content Store" );
  295. }
  296. }
  297. if(FAILED(hr))
  298. {
  299. WriteLog( hr, L"Error processing registered content" );
  300. }
  301. __HCP_FUNC_EXIT(hr);
  302. }
  303. /*****************************************************************************
  304. *
  305. * FUNCTION : ProcessInstallFile
  306. *
  307. * DESCRIPTION : Extracts files to be installed and moves them to the vendor's
  308. * private directory
  309. *
  310. * INPUTS :
  311. *
  312. * RETURNS :
  313. *
  314. * COMMENTS :
  315. *
  316. *****************************************************************************/
  317. HRESULT HCUpdate::Engine::ProcessInstallFile( /*[in]*/ Action idAction ,
  318. /*[in]*/ LPCWSTR szSource ,
  319. /*[in]*/ LPCWSTR szDestination ,
  320. /*[in]*/ bool fSys ,
  321. /*[in]*/ bool fSysHelp )
  322. {
  323. __HCP_FUNC_ENTRY( "HCUpdate::Engine::ProcessInstallFile" );
  324. HRESULT hr;
  325. WCHAR rgDestPath[MAX_PATH];
  326. MPC::wstring strRoot;
  327. MPC::wstring strDestination;
  328. if(m_updater.IsOEM() != true)
  329. {
  330. if(fSys == true ||
  331. fSysHelp == true )
  332. {
  333. __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( S_OK, L"Ignoring install file : %s because certificate does not have enough priviliges to install into Sys or SysHelp locations.", szDestination ));
  334. }
  335. }
  336. WriteLog( S_OK, L"Installing file : %s : %s", s_ActionText[idAction], szDestination );
  337. PCH_MACRO_CHECK_STRINGW(hr, szDestination, L"Error missing URI attribute");
  338. //
  339. // Canonicalize szDestination.
  340. //
  341. if(FAILED(hr = MPC::GetCanonialPathName(strDestination, szDestination)))
  342. {
  343. __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), L"Error install file has a destination that is not allowed." ));
  344. }
  345. // Check if system file modification.
  346. if(fSys || fSysHelp)
  347. {
  348. if(fSys)
  349. {
  350. //
  351. // Only Microsoft can actually write to the SYSTEM directory, OEMs write to the SYSTEM_OEM one.
  352. //
  353. __MPC_EXIT_IF_METHOD_FAILS(hr, m_ts.BaseDir( strRoot )); strRoot.append( IsMicrosoft() ? HC_HELPSET_SUB_SYSTEM : HC_HELPSET_SUB_SYSTEM_OEM );
  354. }
  355. if(fSysHelp)
  356. {
  357. if(FAILED(hr = AcquireDatabase()))
  358. {
  359. __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( hr, L"Error finding database to update" ));
  360. }
  361. strRoot = m_updater.GetHelpLocation();
  362. ReleaseDatabase();
  363. }
  364. }
  365. if(fSys || fSysHelp)
  366. {
  367. MPC::SubstituteEnvVariables( strRoot );
  368. //
  369. // If system folder.
  370. //
  371. StringCchPrintfW( rgDestPath, MAXSTRLEN(rgDestPath), L"%s\\%s", strRoot.c_str(), strDestination.c_str() ); rgDestPath[MAXSTRLEN(rgDestPath)] = 0;
  372. }
  373. else
  374. {
  375. //
  376. // If regular vendor folder.
  377. //
  378. AppendVendorDir( strDestination.c_str(), m_pkg->m_strVendorID.c_str(), m_strWinDir.c_str(), rgDestPath, MAXSTRLEN(rgDestPath) );
  379. }
  380. // Change the mode to read/write so that file can be replaced.
  381. (void)::SetFileAttributesW( rgDestPath, FILE_ATTRIBUTE_NORMAL );
  382. if(idAction == ACTION_ADD)
  383. {
  384. // Source must not be empty.
  385. if(!STRINGISPRESENT( szSource ))
  386. {
  387. __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), L"Error - missing SOURCE attribute" ));
  388. }
  389. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::FailOnLowDiskSpace( HC_ROOT, PCH_SAFETYMARGIN ));
  390. // Create the directory if it hasn't been created already
  391. if(FAILED(hr = MPC::MakeDir( rgDestPath )))
  392. {
  393. __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( hr, L"Error creating directory for %s", rgDestPath ));
  394. }
  395. // Extract the file and store it in the vendor's private storage area
  396. __MPC_EXIT_IF_METHOD_FAILS(hr, m_pkg->ExtractFile( m_log, rgDestPath, szSource ));
  397. }
  398. else
  399. {
  400. MPC::FileSystemObject fso( rgDestPath );
  401. if(fso.IsDirectory())
  402. {
  403. if(fSys || fSysHelp)
  404. {
  405. __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( S_OK, L"Ignoring directory delete command on '%s', it only works for Vendor's directories.", rgDestPath ));
  406. }
  407. }
  408. if(FAILED(fso.Delete( /*fForce*/true, /*fComplain*/true )))
  409. {
  410. __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( -2, L"Error deleting installation file: %s", rgDestPath ));
  411. }
  412. }
  413. PCH_MACRO_DEBUG( L"Installed file" );
  414. hr = S_OK;
  415. __HCP_FUNC_CLEANUP;
  416. if(FAILED(hr))
  417. {
  418. WriteLog( hr, L"Error processing installation file" );
  419. }
  420. __HCP_FUNC_EXIT(hr);
  421. }
  422. /*****************************************************************************
  423. *
  424. * FUNCTION : ProcessSAFFile
  425. *
  426. * DESCRIPTION : Hand the SAF file over to the SAF lib for registration or removal
  427. *
  428. * INPUTS :
  429. *
  430. * RETURNS :
  431. *
  432. * COMMENTS :
  433. *
  434. *****************************************************************************/
  435. HRESULT HCUpdate::Engine::ProcessSAFFile( /*[in]*/ Action idAction ,
  436. /*[in]*/ LPCWSTR szSAFName ,
  437. /*[in]*/ MPC::XmlUtil& oXMLUtil )
  438. {
  439. __HCP_FUNC_ENTRY( "HCUpdate::Engine::ProcessSAFFile" );
  440. HRESULT hr;
  441. CSAFChannelRecord cr;
  442. WriteLog( S_OK, L"Processing SAF file : %s : %s. OwnerName : %s, Owner ID : %s", s_ActionText[idAction], szSAFName,
  443. m_pkg->m_strVendorName.c_str(), m_pkg->m_strVendorID.c_str() );
  444. cr.m_ths = m_ts;
  445. cr.m_bstrVendorID = m_pkg->m_strVendorID .c_str();
  446. cr.m_bstrVendorName = m_pkg->m_strVendorName.c_str();
  447. if(idAction == ACTION_ADD)
  448. {
  449. if(FAILED(hr = CSAFReg::s_GLOBAL->RegisterSupportChannel( cr, oXMLUtil )))
  450. {
  451. __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( hr, L"Error RegisterSupportChannel on SAF file failed" ));
  452. }
  453. WriteLog( S_OK, L"SAF file registered" );
  454. }
  455. else if(idAction == ACTION_DELETE)
  456. {
  457. if(FAILED(hr = CSAFReg::s_GLOBAL->RemoveSupportChannel( cr, oXMLUtil )))
  458. {
  459. __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( hr, L"Error RemoveSupportChannel on SAF file failed" ));
  460. }
  461. WriteLog( S_OK, L"SAF file removed" );
  462. }
  463. hr = S_OK;
  464. __HCP_FUNC_CLEANUP;
  465. if(FAILED(hr))
  466. {
  467. WriteLog( hr, L"Error processing SAF file" );
  468. }
  469. __HCP_FUNC_EXIT(hr);
  470. }
  471. ////////////////////////////////////////////////////////////////////////////////
  472. ////////////////////////////////////////////////////////////////////////////////
  473. ////////////////////////////////////////////////////////////////////////////////
  474. /*****************************************************************************
  475. *
  476. * FUNCTION : ProcessPackage
  477. *
  478. * DESCRIPTION : Reads the help_description package and processes the various sections
  479. *
  480. * INPUTS :
  481. *
  482. * RETURNS :
  483. *
  484. * COMMENTS :
  485. *
  486. *****************************************************************************/
  487. HRESULT HCUpdate::Engine::ProcessPackage( /*[in]*/ Taxonomy::InstalledInstance& sku ,
  488. /*[in]*/ Taxonomy::Package& pkg )
  489. {
  490. __HCP_FUNC_ENTRY( "HCUpdate::Engine::ProcessPackage" );
  491. HRESULT hr;
  492. MPC::XmlUtil oXMLUtil;
  493. bool fIsMachineHelp = (sku.m_inst.m_fSystem || sku.m_inst.m_fMUI);
  494. bool fDB = false;
  495. bool fFound;
  496. ////////////////////////////////////////////////////////////////////////////////
  497. //
  498. // Now let's validate that we have enough disk space on the drive
  499. //
  500. {
  501. ULARGE_INTEGER liFree;
  502. ULARGE_INTEGER liTotal;
  503. bool fEnoughSpace = false;
  504. if(SUCCEEDED(MPC::GetDiskSpace( m_strWinDir, liFree, liTotal )))
  505. {
  506. fEnoughSpace = (liFree.QuadPart > (ULONGLONG)10e6);
  507. }
  508. if(fEnoughSpace == false)
  509. {
  510. __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( STG_E_MEDIUMFULL, L"Error insufficient disk space for update operation." ));
  511. }
  512. }
  513. //
  514. // We cannot process a generic package if a database is already in use!!
  515. //
  516. if(m_sess || m_db)
  517. {
  518. __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( E_FAIL, L"Recursive invocation of HCUpdate!" ));
  519. }
  520. m_ts = sku.m_inst.m_ths;
  521. m_sku = &sku;
  522. m_pkg = &pkg;
  523. WriteLog( -1, L"\nProcessing package %s [%s] (Vendor: %s) from package store, %s/%d\n\n", pkg.m_strProductID.c_str() ,
  524. pkg.m_strVersion .c_str() ,
  525. pkg.m_strVendorID .c_str() ,
  526. m_ts.GetSKU() ,
  527. m_ts.GetLanguage() );
  528. ////////////////////////////////////////////////////////////////////////////////
  529. //
  530. // Check if it is OEM owner
  531. //
  532. {
  533. __MPC_EXIT_IF_METHOD_FAILS(hr, AcquireDatabase()); fDB = true;
  534. __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.LocateOwner( m_pkg->m_strVendorID.c_str() ));
  535. if(m_updater.GetOwner() == -1)
  536. {
  537. long idOwner;
  538. // Create the owner without OEM privs
  539. __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.CreateOwner( idOwner, m_pkg->m_strVendorID.c_str(), /*fIsOEM*/false ));
  540. __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.LocateOwner( m_pkg->m_strVendorID.c_str() ));
  541. }
  542. }
  543. if(m_updater.IsOEM())
  544. {
  545. WriteLog( S_OK, L"Update package has OEM credentials of %s", m_pkg->m_strVendorID.c_str() );
  546. }
  547. __MPC_EXIT_IF_METHOD_FAILS(hr, m_pkg->ExtractPkgDesc( m_log, oXMLUtil ));
  548. ////////////////////////////////////////////////////////////////////////////////
  549. //
  550. // Insert OEMs
  551. //
  552. if(m_updater.IsOEM())
  553. {
  554. CComPtr<IXMLDOMNodeList> poNodeList;
  555. if(FAILED(hr = oXMLUtil.GetNodes( PCH_XQL_OEM, &poNodeList )))
  556. {
  557. PCH_MACRO_DEBUG( L"Error processing package_description xml" );
  558. }
  559. else if(CountNodes(poNodeList) > 0)
  560. {
  561. JetBlue::TransactionHandle transaction;
  562. CComPtr<IXMLDOMNode> poNode;
  563. MPC::wstring strDN;
  564. long ID_owner;
  565. //
  566. // Process all the nodes.
  567. //
  568. HCUPDATE_BEGIN_TRANSACTION(hr,transaction);
  569. for(;SUCCEEDED(hr = poNodeList->nextNode( &poNode )) && poNode != NULL; poNode.Release())
  570. {
  571. HCUPDATE_GETATTRIBUTE(hr, oXMLUtil, PCH_TAG_OEM_DN, strDN, fFound, poNode );
  572. PCH_MACRO_CHECK_ABORT(hr);
  573. if(strDN.size() > 0)
  574. {
  575. WriteLog( S_OK, L"Registering '%s' as OEM", strDN.c_str() );
  576. // insert it into the content owner's table, making it an OEM.
  577. __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.CreateOwner( ID_owner, strDN.c_str(), true ));
  578. }
  579. }
  580. HCUPDATE_COMMIT_TRANSACTION(hr,transaction);
  581. }
  582. }
  583. ////////////////////////////////////////////////////////////////////////////////
  584. //
  585. // Insert Search Engines
  586. //
  587. if(fIsMachineHelp && m_updater.IsOEM())
  588. {
  589. CComPtr<IXMLDOMNodeList> poNodeList;
  590. if(FAILED(hr = oXMLUtil.GetNodes( PCH_XQL_SE, &poNodeList )))
  591. {
  592. PCH_MACRO_DEBUG( L"Error processing package_description xml" );
  593. }
  594. else if(CountNodes(poNodeList) > 0)
  595. {
  596. CComPtr<IXMLDOMNode> poNode;
  597. CComPtr<IXMLDOMNode> poDataNode;
  598. Action idAction;
  599. MPC::wstring strAction;
  600. MPC::wstring strCLSID;
  601. MPC::wstring strID;
  602. CComBSTR bstrData;
  603. SearchEngine::Config cfg;
  604. //
  605. // Process all the nodes.
  606. //
  607. for(;SUCCEEDED(hr = poNodeList->nextNode( &poNode )) && poNode != NULL; poNode.Release())
  608. {
  609. PCH_MACRO_CHECK_ABORT(hr);
  610. HCUPDATE_GETATTRIBUTE(hr, oXMLUtil, PCH_TAG_ACTION , strAction, fFound, poNode );
  611. HCUPDATE_GETATTRIBUTE(hr, oXMLUtil, PCH_TAG_SE_ID , strID , fFound, poNode );
  612. HCUPDATE_GETATTRIBUTE(hr, oXMLUtil, PCH_TAG_SE_CLSID, strCLSID , fFound, poNode );
  613. //
  614. // Get the data element
  615. //
  616. if(FAILED(poNode->selectSingleNode( PCH_TAG_SE_DATA, &poDataNode )))
  617. {
  618. PCH_MACRO_DEBUG2( L"Error getting data for search engine %s", strID.c_str());
  619. }
  620. if(FAILED(poDataNode->get_xml(&bstrData)))
  621. {
  622. PCH_MACRO_DEBUG2( L"Error extracting xml data for search engine %s", strID.c_str());
  623. }
  624. __MPC_EXIT_IF_METHOD_FAILS(hr, LookupAction( strAction.c_str(), idAction ));
  625. //
  626. // Check if it is adding search engines
  627. //
  628. if(idAction == ACTION_ADD)
  629. {
  630. WriteLog( S_OK, L"Adding Search Engine : Name : %s, CLSID : %s", strID.c_str(), strCLSID.c_str() );
  631. // register the search engine
  632. __MPC_EXIT_IF_METHOD_FAILS(hr, cfg.RegisterWrapper( m_ts, strID.c_str(), m_pkg->m_strVendorID.c_str(), strCLSID.c_str(), bstrData ));
  633. }
  634. else if(idAction == ACTION_DELETE)
  635. {
  636. WriteLog( S_OK, L"Deleting Search Engine : Name : %s, CLSID : %s", strID.c_str(), strCLSID.c_str() );
  637. // unregister the search engine
  638. __MPC_EXIT_IF_METHOD_FAILS(hr, cfg.UnRegisterWrapper( m_ts, strID.c_str(), m_pkg->m_strVendorID.c_str() ));
  639. }
  640. }
  641. }
  642. }
  643. ////////////////////////////////////////////////////////////////////////////////
  644. //
  645. // Search & process saf config files
  646. //
  647. if(fIsMachineHelp && m_updater.IsOEM())
  648. {
  649. CComPtr<IXMLDOMNodeList> poNodeList;
  650. if(FAILED(hr = oXMLUtil.GetNodes( PCH_XQL_SAF, &poNodeList )))
  651. {
  652. PCH_MACRO_DEBUG( L"Error processing package_description xml" );
  653. }
  654. else if(CountNodes(poNodeList) > 0)
  655. {
  656. CComPtr<IXMLDOMNode> poNode;
  657. Action idAction;
  658. MPC::wstring strAction;
  659. MPC::wstring strFilename;
  660. //
  661. // Process all the nodes.
  662. //
  663. for(;SUCCEEDED(hr = poNodeList->nextNode( &poNode )) && poNode != NULL; poNode.Release())
  664. {
  665. MPC::XmlUtil xmlSAF;
  666. PCH_MACRO_CHECK_ABORT(hr);
  667. HCUPDATE_GETATTRIBUTE(hr, oXMLUtil, PCH_TAG_ACTION, strAction , fFound, poNode);
  668. HCUPDATE_GETATTRIBUTE(hr, oXMLUtil, PCH_TAG_FILE , strFilename, fFound, poNode);
  669. __MPC_EXIT_IF_METHOD_FAILS(hr, LookupAction( strAction.c_str(), idAction ));
  670. // Extract the SAF file into the temp directory
  671. __MPC_EXIT_IF_METHOD_FAILS(hr, m_pkg->ExtractXMLFile( m_log, xmlSAF, Taxonomy::Strings::s_tag_root_SAF, strFilename.c_str() ));
  672. // process the SAF file
  673. __MPC_EXIT_IF_METHOD_FAILS(hr, ProcessSAFFile( idAction, strFilename.c_str(), xmlSAF ));
  674. }
  675. }
  676. }
  677. ////////////////////////////////////////////////////////////////////////////////
  678. //
  679. // Search & install help content
  680. //
  681. {
  682. CComPtr<IXMLDOMNodeList> poNodeList;
  683. if(FAILED(hr = oXMLUtil.GetNodes( PCH_XQL_INSTALLFILE, &poNodeList )))
  684. {
  685. PCH_MACRO_DEBUG( L"Error processing package_description xml" );
  686. }
  687. else if(CountNodes(poNodeList) > 0)
  688. {
  689. CComPtr<IXMLDOMNode> poNode;
  690. Action idAction;
  691. MPC::wstring strAction;
  692. MPC::wstring strSource;
  693. MPC::wstring strDest;
  694. MPC::wstring strSys;
  695. MPC::wstring strSysHelp;
  696. bool fSys;
  697. bool fSysHelp;
  698. //
  699. // Process all the nodes.
  700. //
  701. for(;SUCCEEDED(hr = poNodeList->nextNode( &poNode )) && poNode != NULL; poNode.Release())
  702. {
  703. PCH_MACRO_CHECK_ABORT(hr);
  704. HCUPDATE_GETATTRIBUTE (hr, oXMLUtil, PCH_TAG_ACTION , strAction , fFound, poNode);
  705. HCUPDATE_GETATTRIBUTE_OPT(hr, oXMLUtil, PCH_TAG_SOURCE , strSource , fFound, poNode);
  706. HCUPDATE_GETATTRIBUTE (hr, oXMLUtil, PCH_TAG_URI , strDest , fFound, poNode);
  707. HCUPDATE_GETATTRIBUTE_OPT(hr, oXMLUtil, PCH_TAG_SYS , strSys , fFound, poNode);
  708. HCUPDATE_GETATTRIBUTE_OPT(hr, oXMLUtil, PCH_TAG_SYSHELP, strSysHelp, fFound, poNode);
  709. __MPC_EXIT_IF_METHOD_FAILS(hr, LookupAction ( strAction .c_str(), idAction ));
  710. __MPC_EXIT_IF_METHOD_FAILS(hr, LookupBoolean( strSys .c_str(), fSys , false ));
  711. __MPC_EXIT_IF_METHOD_FAILS(hr, LookupBoolean( strSysHelp.c_str(), fSysHelp, false ));
  712. //
  713. // If the package is not the machine SKU, you don't want to install contents other than System Help Files.
  714. //
  715. if(fIsMachineHelp == false)
  716. {
  717. if(fSys == true ) continue;
  718. if(fSysHelp == false) continue;
  719. }
  720. // install the file
  721. __MPC_EXIT_IF_METHOD_FAILS(hr, ProcessInstallFile( idAction, strSource.c_str(), strDest.c_str(), fSys, fSysHelp ));
  722. }
  723. }
  724. }
  725. ////////////////////////////////////////////////////////////////////////////////
  726. //
  727. // Search & register trusted content
  728. //
  729. if(fIsMachineHelp && m_updater.IsOEM())
  730. {
  731. CComPtr<IXMLDOMNodeList> poNodeList;
  732. if(FAILED(hr = oXMLUtil.GetNodes( PCH_XQL_TRUSTED, &poNodeList )))
  733. {
  734. PCH_MACRO_DEBUG( L"Error processing package_description xml" );
  735. }
  736. else if(CountNodes(poNodeList) > 0)
  737. {
  738. CComPtr<IXMLDOMNode> poNode;
  739. Action idAction;
  740. MPC::wstring strAction;
  741. MPC::wstring strURI;
  742. //
  743. // Process all the nodes.
  744. //
  745. for(;SUCCEEDED(hr = poNodeList->nextNode( &poNode )) && poNode != NULL; poNode.Release())
  746. {
  747. PCH_MACRO_CHECK_ABORT(hr);
  748. HCUPDATE_GETATTRIBUTE(hr, oXMLUtil, PCH_TAG_ACTION, strAction, fFound, poNode);
  749. HCUPDATE_GETATTRIBUTE(hr, oXMLUtil, PCH_TAG_URI , strURI , fFound, poNode);
  750. __MPC_EXIT_IF_METHOD_FAILS(hr, LookupAction( strAction.c_str(), idAction ));
  751. // register the content
  752. __MPC_EXIT_IF_METHOD_FAILS(hr, ProcessRegisterContent( idAction, strURI.c_str() ));
  753. }
  754. }
  755. }
  756. ////////////////////////////////////////////////////////////////////////////////
  757. //
  758. // Search & process hht files
  759. //
  760. {
  761. CComPtr<IXMLDOMNodeList> poNodeList;
  762. if(FAILED(hr = oXMLUtil.GetNodes( PCH_XQL_HHT, &poNodeList)))
  763. {
  764. PCH_MACRO_DEBUG( L"Error processing package_description xml" );
  765. }
  766. else if(CountNodes(poNodeList) > 0)
  767. {
  768. CComPtr<IXMLDOMNode> poNode;
  769. MPC::wstring strFilename;
  770. //
  771. // Process all the nodes.
  772. //
  773. for(;SUCCEEDED(hr = poNodeList->nextNode( &poNode )) && poNode != NULL; poNode.Release())
  774. {
  775. MPC::XmlUtil xmlHHT;
  776. PCH_MACRO_CHECK_ABORT(hr);
  777. // get the filename
  778. HCUPDATE_GETATTRIBUTE(hr, oXMLUtil, PCH_TAG_FILE, strFilename, fFound, poNode);
  779. // Extract the HHT file into the temp directory
  780. __MPC_EXIT_IF_METHOD_FAILS(hr, m_pkg->ExtractXMLFile( m_log, xmlHHT, Taxonomy::Strings::s_tag_root_HHT, strFilename.c_str() ));
  781. // process the HHT file
  782. __MPC_EXIT_IF_METHOD_FAILS(hr, ProcessHHTFile( strFilename.c_str(), xmlHHT ));
  783. }
  784. }
  785. }
  786. ////////////////////////////////////////////////////////////////////////////////
  787. //
  788. // Search and add News content
  789. //
  790. if(m_updater.IsOEM())
  791. {
  792. CComPtr<IXMLDOMNodeList> poNodeList;
  793. if (FAILED(hr = oXMLUtil.GetNodes( PCH_XQL_NEWSROOT, &poNodeList)))
  794. {
  795. PCH_MACRO_DEBUG( L"Error processing package_description.xml" );
  796. }
  797. else
  798. {
  799. if(CountNodes(poNodeList) > 0)
  800. {
  801. CComPtr<IXMLDOMNode> poNodeHeadline;
  802. MPC::wstring strCurrentSKU;
  803. LPCWSTR szCurrentSKU = m_ts.GetSKU ();
  804. long lCurrentLCID = m_ts.GetLanguage();
  805. News::UpdateHeadlines uhUpdate;
  806. MPC::wstring strIcon;
  807. MPC::wstring strTitle;
  808. MPC::wstring strLink;
  809. MPC::wstring strDescription;
  810. MPC::wstring strExpiryDate;
  811. CComBSTR strTimeOutDays;
  812. int nTimeOutDays;
  813. DATE dExpiryDate;
  814. long lIndex;
  815. // Strip off the number from the SKU
  816. {
  817. LPCWSTR szEnd = wcschr( szCurrentSKU, '_' );
  818. size_t len = szEnd ? szEnd - szCurrentSKU : wcslen( szCurrentSKU );
  819. strCurrentSKU.assign( szCurrentSKU, len );
  820. }
  821. // Get all the news items and return them in the reverse order
  822. __MPC_EXIT_IF_METHOD_FAILS(hr, poNodeList->get_length( &lIndex ));
  823. for(--lIndex; lIndex >= 0; --lIndex)
  824. {
  825. if(SUCCEEDED(hr = poNodeList->get_item( lIndex, &poNodeHeadline )) && poNodeHeadline != NULL)
  826. {
  827. PCH_MACRO_CHECK_ABORT(hr);
  828. //// Quick fix for 357806 - ignore the ICON attribute
  829. ////__MPC_EXIT_IF_METHOD_FAILS(hr, oXMLUtil.GetAttribute(NULL, PCH_TAG_NEWS_ICON , strIcon , fFound, poNodeHeadline));
  830. __MPC_EXIT_IF_METHOD_FAILS(hr, oXMLUtil.GetAttribute(NULL, PCH_TAG_NEWS_TITLE , strTitle , fFound, poNodeHeadline));
  831. __MPC_EXIT_IF_METHOD_FAILS(hr, oXMLUtil.GetAttribute(NULL, PCH_TAG_NEWS_LINK , strLink , fFound, poNodeHeadline));
  832. __MPC_EXIT_IF_METHOD_FAILS(hr, oXMLUtil.GetAttribute(NULL, PCH_TAG_NEWS_DESCRIPTION, strDescription, fFound, poNodeHeadline));
  833. __MPC_EXIT_IF_METHOD_FAILS(hr, oXMLUtil.GetAttribute(NULL, PCH_TAG_NEWS_TIMEOUT , strTimeOutDays, fFound, poNodeHeadline));
  834. __MPC_EXIT_IF_METHOD_FAILS(hr, oXMLUtil.GetAttribute(NULL, PCH_TAG_NEWS_EXPIRYDATE , strExpiryDate , fFound, poNodeHeadline));
  835. // Make the necessary conversions
  836. if(FAILED(hr = MPC::ConvertStringToDate( strExpiryDate, dExpiryDate, /*fGMT*/false, /*fCIM*/false, -1 )))
  837. {
  838. dExpiryDate = 0;
  839. }
  840. if(strTimeOutDays.Length() > 0)
  841. {
  842. nTimeOutDays = _wtoi(strTimeOutDays);
  843. }
  844. else
  845. {
  846. nTimeOutDays = 0;
  847. }
  848. // Finally add the headlines - make sure that the title and link are not empty strings
  849. if(strTitle.length() > 0 && strLink.length() > 0)
  850. {
  851. __MPC_EXIT_IF_METHOD_FAILS(hr, uhUpdate.Add( lCurrentLCID, strCurrentSKU, strIcon, strTitle, strLink, strDescription, nTimeOutDays, dExpiryDate ));
  852. }
  853. else
  854. {
  855. WriteLog(S_OK, L"Skipping headlines no. %d because attribute TITLE or attribute LINK was not found", lIndex + 1);
  856. }
  857. poNodeHeadline.Release();
  858. }
  859. }
  860. WriteLog(S_OK, L"Headlines were successfully processed");
  861. }
  862. else
  863. {
  864. WriteLog(S_OK, L"No headlines items found");
  865. }
  866. }
  867. }
  868. hr = S_OK;
  869. ////////////////////////////////////////////////////////////////////////////////
  870. __HCP_FUNC_CLEANUP;
  871. if(fDB)
  872. {
  873. ReleaseDatabase();
  874. }
  875. ////////////////////
  876. __HCP_FUNC_EXIT(hr);
  877. }
  878. HRESULT HCUpdate::Engine::RecreateIndex( /*[in]*/ Taxonomy::InstalledInstance& sku, /*[in]*/ bool fForce )
  879. {
  880. __HCP_FUNC_ENTRY( "HCUpdate::Engine::RecreateIndex" );
  881. HRESULT hr;
  882. m_ts = sku.m_inst.m_ths;
  883. m_sku = &sku;
  884. m_pkg = NULL;
  885. if(FAILED(hr = InternalCreateIndex( fForce ? VARIANT_TRUE : VARIANT_FALSE )))
  886. {
  887. __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( hr, L"Error merging index" ));
  888. }
  889. hr = S_OK;
  890. __HCP_FUNC_CLEANUP;
  891. __HCP_FUNC_EXIT(hr);
  892. }