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.

901 lines
27 KiB

  1. /******************************************************************************
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. PCHUpdate.cpp
  5. Abstract:
  6. This file contains the implementation of the HCUpdate::Engine class.
  7. Revision History:
  8. Ghim-Sim Chua (gschua) 12/20/99
  9. created
  10. ******************************************************************************/
  11. #include "stdafx.h"
  12. /////////////////////////////////////////////////////////////////////////////
  13. static const DWORD c_AllowedUsers = MPC::IDENTITY_SYSTEM |
  14. MPC::IDENTITY_ADMIN |
  15. MPC::IDENTITY_ADMINS |
  16. MPC::IDENTITY_POWERUSERS;
  17. /////////////////////////////////////////////////////////////////////////////
  18. // HCUpdate::Engine
  19. HCUpdate::Engine::Engine()
  20. {
  21. // MPC::wstring m_strWinDir;
  22. //
  23. // Taxonomy::Updater m_updater;
  24. // Taxonomy::Settings m_ts;
  25. m_sku = NULL; // Taxonomy::InstalledInstance* m_sku;
  26. m_pkg = NULL; // Taxonomy::Package* m_pkg;
  27. //
  28. m_fCreationMode = false; // bool m_fCreationMode;
  29. m_dwRefCount = 0; // DWORD m_dwRefCount;
  30. // JetBlue::SessionHandle m_handle;
  31. m_sess = NULL; // JetBlue::Session* m_sess;
  32. m_db = NULL; // JetBlue::Database* m_db;
  33. }
  34. HRESULT HCUpdate::Engine::FinalConstruct()
  35. {
  36. __HCP_FUNC_ENTRY( "HCUpdate::Engine::FinalConstruct" );
  37. HRESULT hr;
  38. //
  39. // get windows directory
  40. //
  41. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::SubstituteEnvVariables( m_strWinDir = L"%WINDIR%" ));
  42. hr = S_OK;
  43. __HCP_FUNC_CLEANUP;
  44. __HCP_FUNC_EXIT(hr);
  45. }
  46. void HCUpdate::Engine::FinalRelease()
  47. {
  48. (void)m_updater.Close();
  49. m_handle.Release();
  50. }
  51. ////////////////////////////////////////////////////////////////////////////////
  52. HRESULT HCUpdate::Engine::WriteLog( /*[in]*/ HRESULT hrRes ,
  53. /*[in]*/ LPCWSTR szLogFormat ,
  54. /*[in]*/ ... )
  55. {
  56. va_list arglist;
  57. va_start( arglist, szLogFormat );
  58. return WriteLogV( hrRes, szLogFormat, arglist );
  59. }
  60. ////////////////////////////////////////////////////////////////////////////////
  61. HRESULT HCUpdate::Engine::AcquireDatabase()
  62. {
  63. __HCP_FUNC_ENTRY( "HCUpdate::Engine::AcquireDatabase" );
  64. HRESULT hr;
  65. if(m_dwRefCount == 0)
  66. {
  67. if(m_db == NULL) m_fCreationMode = false;
  68. if(m_fCreationMode)
  69. {
  70. __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.Init( m_ts, m_db, /* Cache* */NULL )); // Don't use any cache for the database!!
  71. __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.LocateOwner( m_pkg->m_strVendorID.c_str() ));
  72. }
  73. else
  74. {
  75. __MPC_EXIT_IF_METHOD_FAILS(hr, m_ts.GetDatabase( m_handle, m_db, /*fReadOnly*/false ));
  76. m_sess = m_handle;
  77. __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.Init( m_ts, m_db, /* Cache* */NULL )); // Don't use any cache for the database!!
  78. }
  79. }
  80. m_dwRefCount++;
  81. hr = S_OK;
  82. __HCP_FUNC_CLEANUP;
  83. if(FAILED(hr))
  84. {
  85. WriteLog( hr, L"Error finding database to update" );
  86. }
  87. __HCP_FUNC_EXIT(hr);
  88. }
  89. void HCUpdate::Engine::ReleaseDatabase()
  90. {
  91. if(m_dwRefCount > 0)
  92. {
  93. if(--m_dwRefCount == 0)
  94. {
  95. (void)m_updater.Close();
  96. m_handle.Release();
  97. m_sess = NULL;
  98. m_db = NULL;
  99. if(m_fCreationMode)
  100. {
  101. struct Dump
  102. {
  103. LPCWSTR szText;
  104. Taxonomy::Updater_Stat::Entity* ent;
  105. };
  106. Taxonomy::Updater_Stat& stat = m_updater.Stat();
  107. Dump rgBuf[] =
  108. {
  109. { L"ContentOwners ", &stat.m_entContentOwners },
  110. { L"SynSets ", &stat.m_entSynSets },
  111. { L"HelpImage ", &stat.m_entHelpImage },
  112. { L"IndexFiles ", &stat.m_entIndexFiles },
  113. { L"FullTextSearch", &stat.m_entFullTextSearch },
  114. { L"Scope ", &stat.m_entScope },
  115. { L"Taxonomy ", &stat.m_entTaxonomy },
  116. { L"Topics ", &stat.m_entTopics },
  117. { L"Synonyms ", &stat.m_entSynonyms },
  118. { L"Keywords ", &stat.m_entKeywords },
  119. { L"Matches ", &stat.m_entMatches },
  120. };
  121. WriteLog( -1, L"\nStatistics:\n\n" );
  122. for(int i=0; i<ARRAYSIZE(rgBuf); i++)
  123. {
  124. Dump& d = rgBuf[i];
  125. WriteLog( -1, L" %s : Created: %8d, Modified: %8d, Deleted: %8d", d.szText, d.ent->m_iCreated, d.ent->m_iModified, d.ent->m_iDeleted );
  126. }
  127. WriteLog( -1, L"\n\n" );
  128. }
  129. }
  130. }
  131. }
  132. ////////////////////////////////////////////////////////////////////////////////
  133. HRESULT HCUpdate::Engine::SetSkuInfo( /*[in]*/ LPCWSTR szSKU, /*[in]*/ long lLCID )
  134. {
  135. MPC::SmartLock<_ThreadModel> lock( this );
  136. return m_ts.Initialize( szSKU, lLCID );
  137. }
  138. HRESULT HCUpdate::Engine::InternalCreateIndex( /*[in]*/ VARIANT_BOOL bForce )
  139. {
  140. __HCP_FUNC_ENTRY( "HCUpdate::Engine::InternalCreateIndex" );
  141. HRESULT hr;
  142. MPC::SmartLock<_ThreadModel> lock( this );
  143. Taxonomy::RS_Scope* rsScope;
  144. Taxonomy::RS_IndexFiles* rsIndex;
  145. HHK::Writer* writer = NULL;
  146. bool fDB = false;
  147. long lTotal = 0;
  148. long lDone = 0;
  149. __MPC_EXIT_IF_METHOD_FAILS(hr, AcquireDatabase()); fDB = true;
  150. __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.GetScope ( &rsScope ));
  151. __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.GetIndexFiles( &rsIndex ));
  152. for(int pass=0; pass<2; pass++)
  153. {
  154. bool fFound;
  155. __MPC_EXIT_IF_METHOD_FAILS(hr, rsScope->Move( 0, JET_MoveFirst, &fFound ));
  156. while(fFound)
  157. {
  158. MPC::wstring strBase;
  159. MPC::wstring strIndex;
  160. Taxonomy::WordSet setCHM;
  161. MPC::WStringList lst;
  162. MPC::WStringIter it;
  163. DATE dIndex;
  164. bool fCreate = (bForce == VARIANT_TRUE);
  165. bool fFound2;
  166. __MPC_EXIT_IF_METHOD_FAILS(hr, m_ts.HelpFilesDir( strBase )); strBase += L"\\";
  167. __MPC_EXIT_IF_METHOD_FAILS(hr, m_ts.IndexFile ( strIndex, MPC::StrICmp( rsScope->m_strID, L"<SYSTEM>" ) ? rsScope->m_ID_scope : -1 ));
  168. dIndex = MPC::GetLastModifiedDate( strIndex );
  169. __MPC_EXIT_IF_METHOD_FAILS(hr, rsIndex->Seek_ByScope( rsScope->m_ID_scope, &fFound2 ));
  170. while(fFound2)
  171. {
  172. MPC::wstring strURL;
  173. strURL = L"ms-its:%HELP_LOCATION%\\";
  174. strURL += rsIndex->m_strStorage;
  175. strURL += L"::";
  176. strURL += rsIndex->m_strFile;
  177. setCHM.insert( rsIndex->m_strStorage );
  178. __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.ExpandURL( strURL ));
  179. lst.push_back( strURL );
  180. if(!fCreate && bForce == VARIANT_FALSE)
  181. {
  182. MPC::wstring strFile( strBase ); strFile += rsIndex->m_strStorage;;
  183. DATE dFile = MPC::GetLastModifiedDate( strFile );
  184. if(dFile && dFile > dIndex) fCreate = true;
  185. }
  186. __MPC_EXIT_IF_METHOD_FAILS(hr, rsIndex->Move( 0, JET_MoveNext, &fFound2 ));
  187. }
  188. if(fCreate)
  189. {
  190. if(pass == 0)
  191. {
  192. lTotal++;
  193. }
  194. else
  195. {
  196. HHK::Merger merger;
  197. PCH_MACRO_CHECK_ABORT(hr);
  198. __MPC_EXIT_IF_ALLOC_FAILS(hr, writer, new HHK::Writer);
  199. WriteLog( S_OK, L"Recreating index for scope '%s'", rsScope->m_strID.c_str() );
  200. __MPC_EXIT_IF_METHOD_FAILS(hr, merger.PrepareMergedHhk( *writer, m_updater, setCHM, lst, strIndex.c_str() ));
  201. while(merger.MoveNext())
  202. {
  203. __MPC_EXIT_IF_METHOD_FAILS(hr, writer->OutputSection( merger.GetSection() ));
  204. }
  205. delete writer; writer = NULL;
  206. WriteLog( S_OK, L"Successfully merged index" );
  207. lDone++;
  208. }
  209. }
  210. __MPC_EXIT_IF_METHOD_FAILS(hr, rsScope->Move( 0, JET_MoveNext, &fFound ));
  211. }
  212. if(pass == 0 && lTotal == 0) break; // Nothing to do.
  213. }
  214. hr = S_OK;
  215. __HCP_FUNC_CLEANUP;
  216. delete writer;
  217. if(fDB)
  218. {
  219. ReleaseDatabase();
  220. }
  221. __HCP_FUNC_EXIT(hr);
  222. }
  223. HRESULT HCUpdate::Engine::InternalUpdatePkg( /*[in]*/ LPCWSTR szPathname ,
  224. /*[in]*/ bool fImpersonate )
  225. {
  226. __HCP_FUNC_ENTRY( "HCUpdate::Engine::InternalUpdatePkg" );
  227. HRESULT hr;
  228. MPC::SmartLock<_ThreadModel> lock( this );
  229. Taxonomy::InstalledInstanceStore* store = Taxonomy::InstalledInstanceStore::s_GLOBAL;
  230. Taxonomy::LockingHandle handle;
  231. Taxonomy::InstanceIter it;
  232. bool fFound;
  233. bool fLogStarted = false;
  234. __MPC_PARAMCHECK_BEGIN(hr)
  235. __MPC_PARAMCHECK_NOTNULL(store);
  236. __MPC_PARAMCHECK_END();
  237. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::FailOnLowDiskSpace( HC_ROOT, PCH_SAFETYMARGIN ));
  238. __MPC_EXIT_IF_METHOD_FAILS(hr, store->GrabControl( handle, &m_log ));
  239. if(STRINGISPRESENT(szPathname))
  240. {
  241. Taxonomy::PackageIter it;
  242. MPC::Impersonation imp;
  243. if(fImpersonate)
  244. {
  245. __MPC_EXIT_IF_METHOD_FAILS(hr, imp.Initialize());
  246. }
  247. if(!fLogStarted)
  248. {
  249. __MPC_EXIT_IF_METHOD_FAILS(hr, StartLog()); fLogStarted = true;
  250. }
  251. __MPC_EXIT_IF_METHOD_FAILS(hr, store->Package_Add( szPathname, fImpersonate ? &imp : NULL, NULL, /*fInsertAtTop*/false, fFound, it ));
  252. if(fFound)
  253. {
  254. WriteLog( -1, L"Package has already been processed" );
  255. }
  256. }
  257. //
  258. // Only start log if there's something to process.
  259. //
  260. if(!fLogStarted)
  261. {
  262. bool fWorkToProcess;
  263. __MPC_EXIT_IF_METHOD_FAILS(hr, store->MakeReady( *this, /*fNoOp*/true, fWorkToProcess ));
  264. if(fWorkToProcess)
  265. {
  266. __MPC_EXIT_IF_METHOD_FAILS(hr, StartLog()); fLogStarted = true;
  267. }
  268. }
  269. if(fLogStarted)
  270. {
  271. bool fWorkToProcess;
  272. __MPC_EXIT_IF_METHOD_FAILS(hr, store->MakeReady( *this, /*fNoOp*/false, fWorkToProcess ));
  273. }
  274. hr = S_OK;
  275. __HCP_FUNC_CLEANUP;
  276. if(fLogStarted) EndLog();
  277. __HCP_FUNC_EXIT(hr);
  278. }
  279. HRESULT HCUpdate::Engine::InternalRemovePkg( /*[in]*/ LPCWSTR szPathname ,
  280. /*[in]*/ Taxonomy::Package* pkg ,
  281. /*[in]*/ bool fImpersonate )
  282. {
  283. __HCP_FUNC_ENTRY( "HCUpdate::Engine::InternalRemovePkg" );
  284. HRESULT hr;
  285. MPC::SmartLock<_ThreadModel> lock( this );
  286. Taxonomy::InstalledInstanceStore* store = Taxonomy::InstalledInstanceStore::s_GLOBAL;
  287. Taxonomy::LockingHandle handle;
  288. Taxonomy::Package pkgTmp;
  289. __MPC_PARAMCHECK_BEGIN(hr)
  290. __MPC_PARAMCHECK_NOTNULL(store);
  291. if(!pkg) __MPC_PARAMCHECK_STRING_NOT_EMPTY(szPathname);
  292. __MPC_PARAMCHECK_END();
  293. //
  294. // start log file
  295. //
  296. __MPC_EXIT_IF_METHOD_FAILS(hr, StartLog());
  297. __MPC_EXIT_IF_METHOD_FAILS(hr, store->GrabControl( handle, &m_log ));
  298. if(!pkg)
  299. {
  300. MPC::Impersonation imp;
  301. if(fImpersonate)
  302. {
  303. __MPC_EXIT_IF_METHOD_FAILS(hr, imp.Initialize());
  304. }
  305. __MPC_EXIT_IF_METHOD_FAILS(hr, pkgTmp.Import ( m_log, szPathname, -2, fImpersonate ? &imp : NULL ));
  306. __MPC_EXIT_IF_METHOD_FAILS(hr, pkgTmp.Authenticate( m_log ));
  307. pkg = &pkgTmp;
  308. }
  309. {
  310. Taxonomy::PackageIter it;
  311. bool fFound;
  312. __MPC_EXIT_IF_METHOD_FAILS(hr, store->Package_Find( *pkg, fFound, it ));
  313. if(fFound)
  314. {
  315. bool fWorkToProcess;
  316. __MPC_EXIT_IF_METHOD_FAILS(hr, store->Package_Remove( it ));
  317. __MPC_EXIT_IF_METHOD_FAILS(hr, store->MakeReady( *this, /*fNoOp*/false, fWorkToProcess ));
  318. }
  319. }
  320. hr = S_OK;
  321. __HCP_FUNC_CLEANUP;
  322. //
  323. // end the log
  324. //
  325. EndLog();
  326. __HCP_FUNC_EXIT(hr);
  327. }
  328. HRESULT HCUpdate::Engine::ForceSystemRestore()
  329. {
  330. __HCP_FUNC_ENTRY( "HCUpdate::Engine::ForceSystemRestore" );
  331. HRESULT hr;
  332. MPC::SmartLock<_ThreadModel> lock( this );
  333. Taxonomy::InstalledInstanceStore* store = Taxonomy::InstalledInstanceStore::s_GLOBAL;
  334. Taxonomy::LockingHandle handle;
  335. Taxonomy::InstalledInstanceIterConst itBegin;
  336. Taxonomy::InstalledInstanceIterConst itEnd;
  337. bool fWorkToProcess;
  338. //
  339. // start log file
  340. //
  341. __MPC_EXIT_IF_METHOD_FAILS(hr, StartLog());
  342. __MPC_EXIT_IF_METHOD_FAILS(hr, store->GrabControl( handle, &m_log ));
  343. //
  344. // Invalidate all SKUs.
  345. //
  346. __MPC_EXIT_IF_METHOD_FAILS(hr, store->SKU_GetList( itBegin, itEnd ));
  347. for(; itBegin != itEnd; itBegin++)
  348. {
  349. __MPC_EXIT_IF_METHOD_FAILS(hr, store->State_InvalidateSKU( itBegin->m_inst.m_ths, /*fAlsoDatabase*/true ));
  350. }
  351. __MPC_EXIT_IF_METHOD_FAILS(hr, store->MakeReady( *this, /*fNoOp*/false, fWorkToProcess ));
  352. hr = S_OK;
  353. __HCP_FUNC_CLEANUP;
  354. //
  355. // end the log
  356. //
  357. EndLog();
  358. __HCP_FUNC_EXIT(hr);
  359. }
  360. ////////////////////////////////////////////////////////////////////////////////
  361. HRESULT HCUpdate::Engine::PopulateDatabase( /*[in]*/ LPCWSTR szCabinet ,
  362. /*[in]*/ LPCWSTR szHHTFile ,
  363. /*[in]*/ LPCWSTR szLogFile ,
  364. /*[in]*/ LPCWSTR szSKU ,
  365. /*[in]*/ long lLCID ,
  366. /*[in]*/ JetBlue::Session* sess ,
  367. /*[in]*/ JetBlue::Database* db )
  368. {
  369. __HCP_FUNC_ENTRY( "HCUpdate::Engine::CreateDatabase" );
  370. HRESULT hr;
  371. MPC::SmartLock<_ThreadModel> lock( this );
  372. WCHAR rgLCID[64];
  373. Taxonomy::Package pkg;
  374. bool fDB = false;
  375. __MPC_PARAMCHECK_BEGIN(hr)
  376. __MPC_PARAMCHECK_NOTNULL(sess);
  377. __MPC_PARAMCHECK_NOTNULL(db);
  378. __MPC_PARAMCHECK_STRING_NOT_EMPTY(szHHTFile);
  379. __MPC_PARAMCHECK_END();
  380. m_fCreationMode = true;
  381. m_sess = sess;
  382. m_db = db;
  383. m_pkg = &pkg;
  384. m_pkg->m_strFileName = szCabinet; // MPC::wstring m_strFileName; // VOLATILE
  385. m_pkg->m_fTemporary = false; // bool m_fTemporary; // VOLATILE Used for packages not yet authenticated.
  386. // long m_lSequence;
  387. // DWORD m_dwCRC;
  388. //
  389. m_pkg->m_strSKU = szSKU; // MPC::wstring m_strSKU;
  390. m_pkg->m_strLanguage = _ltow( lLCID, rgLCID, 10 ); // MPC::wstring m_strLanguage;
  391. // MPC::wstring m_strVendorID;
  392. // MPC::wstring m_strVendorName;
  393. // MPC::wstring m_strProductID;
  394. // MPC::wstring m_strVersion;
  395. //
  396. m_pkg->m_fMicrosoft = true; // bool m_fMicrosoft;
  397. m_pkg->m_fBuiltin = true; // bool m_fBuiltin; // Used for packages installed as part of the setup.
  398. //
  399. // start log file
  400. //
  401. __MPC_EXIT_IF_METHOD_FAILS(hr, m_log.StartLog( szLogFile ));
  402. __MPC_EXIT_IF_METHOD_FAILS(hr, m_pkg->Authenticate( m_log ));
  403. __MPC_EXIT_IF_METHOD_FAILS(hr, AcquireDatabase()); fDB = true;
  404. {
  405. MPC::XmlUtil oXMLUtil;
  406. bool fLoaded;
  407. //
  408. // Load the XML with the root tag.
  409. //
  410. if(FAILED(hr = oXMLUtil.Load( szHHTFile, Taxonomy::Strings::s_tag_root_HHT, fLoaded )))
  411. {
  412. __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( hr, L"Error loading HHT file" ));
  413. }
  414. if(fLoaded == false)
  415. {
  416. __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED), L"Invalid HHT file" ));
  417. }
  418. __MPC_EXIT_IF_METHOD_FAILS(hr, ProcessHHTFile( szHHTFile, oXMLUtil ));
  419. }
  420. hr = S_OK;
  421. __HCP_FUNC_CLEANUP;
  422. if(fDB)
  423. {
  424. ReleaseDatabase();
  425. }
  426. //
  427. // end the log
  428. //
  429. EndLog();
  430. __HCP_FUNC_EXIT(hr);
  431. }
  432. ////////////////////////////////////////////////////////////////////////////////
  433. ////////////////////////////////////////////////////////////////////////////////
  434. STDMETHODIMP HCUpdate::Engine::get_VersionList( /*[in]*/ IPCHCollection* *ppVC )
  435. {
  436. __HCP_FUNC_ENTRY( "HCUpdate::Engine::get_VersionList" );
  437. HRESULT hr;
  438. Taxonomy::LockingHandle handle;
  439. Taxonomy::InstalledInstanceStore* store = Taxonomy::InstalledInstanceStore::s_GLOBAL;
  440. CComPtr<CPCHCollection> pColl;
  441. CComPtr<VersionItem> pObj;
  442. __MPC_PARAMCHECK_BEGIN(hr)
  443. __MPC_PARAMCHECK_POINTER_AND_SET(ppVC,NULL);
  444. __MPC_PARAMCHECK_NOTNULL(store);
  445. __MPC_PARAMCHECK_END();
  446. //
  447. // Create the Enumerator and fill it with jobs.
  448. //
  449. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pColl ));
  450. __MPC_EXIT_IF_METHOD_FAILS(hr, store->GrabControl( handle, &m_log ));
  451. {
  452. Taxonomy::PackageIterConst itPackageBegin;
  453. Taxonomy::PackageIterConst itPackageEnd;
  454. __MPC_EXIT_IF_METHOD_FAILS(hr, store->Package_GetList( itPackageBegin, itPackageEnd ));
  455. for(Taxonomy::PackageIterConst itPackage = itPackageBegin; itPackage != itPackageEnd; itPackage++)
  456. {
  457. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pObj ));
  458. pObj->m_pkg = *itPackage;
  459. __MPC_EXIT_IF_METHOD_FAILS(hr, pColl->AddItem( pObj )); pObj.Release();
  460. }
  461. }
  462. __MPC_EXIT_IF_METHOD_FAILS(hr, pColl.QueryInterface( ppVC ));
  463. hr = S_OK;
  464. __HCP_FUNC_CLEANUP;
  465. __HCP_FUNC_EXIT(hr);
  466. }
  467. /////////////////////////////////////////////////////////////////////////////
  468. STDMETHODIMP HCUpdate::Engine::LatestVersion( /*[in]*/ BSTR bstrVendorID ,
  469. /*[in]*/ BSTR bstrProductID ,
  470. /*[in,optional]*/ VARIANT vSKU ,
  471. /*[in,optional]*/ VARIANT vLanguage ,
  472. /*[out, retval]*/ BSTR *pVal )
  473. {
  474. __HCP_FUNC_ENTRY( "HCUpdate::Engine::LatestVersion" );
  475. HRESULT hr;
  476. Taxonomy::LockingHandle handle;
  477. Taxonomy::InstalledInstanceStore* store = Taxonomy::InstalledInstanceStore::s_GLOBAL;
  478. __MPC_PARAMCHECK_BEGIN(hr)
  479. __MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL);
  480. __MPC_PARAMCHECK_NOTNULL(store);
  481. __MPC_PARAMCHECK_END();
  482. __MPC_EXIT_IF_METHOD_FAILS(hr, store->GrabControl( handle, &m_log ));
  483. {
  484. Taxonomy::PackageIterConst itPackageBegin;
  485. Taxonomy::PackageIterConst itPackageEnd;
  486. Taxonomy::Package pkgTmp;
  487. const Taxonomy::Package* best = NULL;
  488. pkgTmp.m_strVendorID = bstrVendorID;
  489. pkgTmp.m_strProductID = bstrProductID;
  490. __MPC_EXIT_IF_METHOD_FAILS(hr, store->Package_GetList( itPackageBegin, itPackageEnd ));
  491. for(Taxonomy::PackageIterConst itPackage = itPackageBegin; itPackage != itPackageEnd; itPackage++)
  492. {
  493. const Taxonomy::Package& pkg = *itPackage;
  494. if(pkg.Compare( pkgTmp, Taxonomy::Package::c_Cmp_ID ) == 0)
  495. {
  496. if(vSKU .vt == VT_BSTR && MPC::StrICmp( pkg.m_strSKU , vSKU .bstrVal )) continue;
  497. if(vLanguage.vt == VT_BSTR && MPC::StrICmp( pkg.m_strLanguage, vLanguage.bstrVal )) continue;
  498. if(best)
  499. {
  500. if(best->Compare( pkg, Taxonomy::Package::c_Cmp_VERSION ) >= 0) continue;
  501. }
  502. best = &pkg;
  503. }
  504. }
  505. if(best)
  506. {
  507. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::GetBSTR( best->m_strVersion.c_str(), pVal ));
  508. }
  509. }
  510. hr = S_OK;
  511. __HCP_FUNC_CLEANUP;
  512. __HCP_FUNC_EXIT(hr);
  513. }
  514. STDMETHODIMP HCUpdate::Engine::CreateIndex( /*[in ]*/ VARIANT_BOOL bForce ,
  515. /*[in,optional]*/ VARIANT vSKU ,
  516. /*[in,optional]*/ VARIANT vLanguage )
  517. {
  518. __HCP_FUNC_ENTRY( "HCUpdate::Engine::CreateIndex" );
  519. HRESULT hr;
  520. CComVariant vLocal_SKU;
  521. CComVariant vLocal_Language;
  522. BSTR bstrSKU;
  523. long lLCID;
  524. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CheckCallerAgainstPrincipal( /*fImpersonate*/true, NULL, c_AllowedUsers ));
  525. (void)vLocal_SKU .ChangeType( VT_BSTR, &vSKU );
  526. (void)vLocal_Language.ChangeType( VT_I4 , &vLanguage );
  527. bstrSKU = (vLocal_SKU .vt == VT_BSTR ? vLocal_SKU .bstrVal : NULL);
  528. lLCID = (vLocal_Language.vt == VT_I4 ? vLocal_Language.lVal : 0 );
  529. if(bstrSKU || lLCID)
  530. {
  531. __MPC_EXIT_IF_METHOD_FAILS(hr, SetSkuInfo( bstrSKU, lLCID ));
  532. }
  533. __MPC_EXIT_IF_METHOD_FAILS(hr, InternalCreateIndex( bForce ));
  534. hr = S_OK;
  535. __HCP_FUNC_CLEANUP;
  536. __HCP_FUNC_EXIT(hr);
  537. }
  538. STDMETHODIMP HCUpdate::Engine::UpdatePkg( /*[in]*/ BSTR bstrPathname ,
  539. /*[in]*/ VARIANT_BOOL bSilent )
  540. {
  541. HRESULT hr;
  542. if(SUCCEEDED(hr = MPC::CheckCallerAgainstPrincipal( /*fImpersonate*/true, NULL, c_AllowedUsers )))
  543. {
  544. hr = InternalUpdatePkg( bstrPathname, /*fImpersonate*/true );
  545. }
  546. return hr;
  547. }
  548. STDMETHODIMP HCUpdate::Engine::RemovePkg( /*[in]*/ BSTR bstrPathname )
  549. {
  550. HRESULT hr;
  551. if(SUCCEEDED(hr = MPC::CheckCallerAgainstPrincipal( /*fImpersonate*/true, NULL, c_AllowedUsers )))
  552. {
  553. hr = InternalRemovePkg( bstrPathname, NULL, /*fImpersonate*/true );
  554. }
  555. return hr;
  556. }
  557. STDMETHODIMP HCUpdate::Engine::RemovePkgByID( /*[in]*/ BSTR bstrVendorID ,
  558. /*[in]*/ BSTR bstrProductID ,
  559. /*[in,optional]*/ VARIANT vVersion )
  560. {
  561. __HCP_FUNC_ENTRY( "HCUpdate::Engine::RemovePkgByID" );
  562. HRESULT hr;
  563. MPC::SmartLock<_ThreadModel> lock( this );
  564. Taxonomy::InstalledInstanceStore* store = Taxonomy::InstalledInstanceStore::s_GLOBAL;
  565. bool fLogStarted = false;
  566. __MPC_PARAMCHECK_BEGIN(hr)
  567. __MPC_PARAMCHECK_NOTNULL(store);
  568. __MPC_PARAMCHECK_STRING_NOT_EMPTY(bstrVendorID);
  569. __MPC_PARAMCHECK_STRING_NOT_EMPTY(bstrProductID);
  570. __MPC_PARAMCHECK_END();
  571. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CheckCallerAgainstPrincipal( /*fImpersonate*/true, NULL, c_AllowedUsers ));
  572. {
  573. Taxonomy::LockingHandle handle;
  574. Taxonomy::Package pkgTmp;
  575. DWORD dwMode;
  576. pkgTmp.m_strVendorID = bstrVendorID;
  577. pkgTmp.m_strProductID = bstrProductID;
  578. if(vVersion.vt == VT_BSTR && vVersion.bstrVal)
  579. {
  580. pkgTmp.m_strVersion = vVersion.bstrVal;
  581. dwMode = Taxonomy::Package::c_Cmp_ID | Taxonomy::Package::c_Cmp_VERSION;
  582. }
  583. else
  584. {
  585. dwMode = Taxonomy::Package::c_Cmp_ID;
  586. }
  587. __MPC_EXIT_IF_METHOD_FAILS(hr, store->GrabControl( handle, &m_log ));
  588. while(1)
  589. {
  590. Taxonomy::PackageIterConst it;
  591. Taxonomy::PackageIterConst itBegin;
  592. Taxonomy::PackageIterConst itEnd;
  593. __MPC_EXIT_IF_METHOD_FAILS(hr, store->Package_GetList( itBegin, itEnd ));
  594. for(it=itBegin; it!=itEnd; it++)
  595. {
  596. PCH_MACRO_CHECK_ABORT(hr);
  597. if(it->Compare( pkgTmp, dwMode ) == 0)
  598. {
  599. if(!fLogStarted)
  600. {
  601. __MPC_EXIT_IF_METHOD_FAILS(hr, StartLog()); fLogStarted = true;
  602. }
  603. __MPC_EXIT_IF_METHOD_FAILS(hr, store->Package_Remove( it ));
  604. break;
  605. }
  606. }
  607. if(it == itEnd) break;
  608. }
  609. if(fLogStarted)
  610. {
  611. bool fWorkToProcess;
  612. __MPC_EXIT_IF_METHOD_FAILS(hr, store->MakeReady( *this, /*fNoOp*/false, fWorkToProcess ));
  613. }
  614. }
  615. hr = S_OK;
  616. __HCP_FUNC_CLEANUP;
  617. if(fLogStarted) EndLog();
  618. __HCP_FUNC_EXIT(hr);
  619. }
  620. /////////////////////////////////////////////////////////////////////////////
  621. /////////////////////////////////////////////////////////////////////////////
  622. STDMETHODIMP HCUpdate::VersionItem::get_SKU ( /*[out, retval]*/ BSTR *pVal ) { return MPC::GetBSTR( m_pkg.m_strSKU .c_str(), pVal ); }
  623. STDMETHODIMP HCUpdate::VersionItem::get_Language ( /*[out, retval]*/ BSTR *pVal ) { return MPC::GetBSTR( m_pkg.m_strLanguage .c_str(), pVal ); }
  624. STDMETHODIMP HCUpdate::VersionItem::get_VendorID ( /*[out, retval]*/ BSTR *pVal ) { return MPC::GetBSTR( m_pkg.m_strVendorID .c_str(), pVal ); }
  625. STDMETHODIMP HCUpdate::VersionItem::get_VendorName( /*[out, retval]*/ BSTR *pVal ) { return MPC::GetBSTR( m_pkg.m_strVendorName.c_str(), pVal ); }
  626. STDMETHODIMP HCUpdate::VersionItem::get_ProductID ( /*[out, retval]*/ BSTR *pVal ) { return MPC::GetBSTR( m_pkg.m_strProductID .c_str(), pVal ); }
  627. STDMETHODIMP HCUpdate::VersionItem::get_Version ( /*[out, retval]*/ BSTR *pVal ) { return MPC::GetBSTR( m_pkg.m_strVersion .c_str(), pVal ); }
  628. HRESULT HCUpdate::VersionItem::Uninstall()
  629. {
  630. __HCP_FUNC_ENTRY( "HCUpdate::VersionItem::Uninstall" );
  631. HRESULT hr;
  632. MPC::SmartLock<_ThreadModel> lock( this );
  633. CComObject<HCUpdate::Engine>* hc = NULL;
  634. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CheckCallerAgainstPrincipal( /*fImpersonate*/true, NULL, c_AllowedUsers ));
  635. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &hc ));
  636. __MPC_EXIT_IF_METHOD_FAILS(hr, hc->InternalRemovePkg( NULL, &m_pkg, /*fImpersonate*/false ));
  637. hr = S_OK;
  638. __HCP_FUNC_CLEANUP;
  639. if(hc) hc->Release();
  640. __HCP_FUNC_EXIT(hr);
  641. }