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.

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