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.

1133 lines
29 KiB

  1. //*************************************************************
  2. //
  3. // Copyright (c) Microsoft Corporation 1998
  4. // All rights reserved
  5. //
  6. // Applist.cxx
  7. //
  8. //*************************************************************
  9. #include "appmgext.hxx"
  10. //
  11. // CAppList
  12. //
  13. CAppList::CAppList(
  14. CManagedAppProcessor * pManApp,
  15. CRsopAppContext * pRsopContext ) :
  16. _pManApp( pManApp ),
  17. _bRsopInitialized( FALSE ),
  18. _hrRsopInit( E_FAIL ),
  19. _pRsopContext( pRsopContext )
  20. {}
  21. CAppList::~CAppList()
  22. {
  23. CAppInfo * pAppInfo;
  24. Reset();
  25. while ( pAppInfo = (CAppInfo *) GetCurrentItem() )
  26. {
  27. MoveNext();
  28. pAppInfo->Remove();
  29. delete pAppInfo;
  30. }
  31. ResetEnd();
  32. }
  33. DWORD
  34. CAppList::SetAppActions()
  35. {
  36. CAppInfo * pAppInfo;
  37. DWORD Pass;
  38. DWORD Status;
  39. for ( Pass = 0; Pass <= 5; Pass++ )
  40. {
  41. Reset();
  42. for (;;)
  43. {
  44. pAppInfo = (CAppInfo *) GetCurrentItem();
  45. if ( ! pAppInfo )
  46. break;
  47. //
  48. // Apps get applied from lowest priority to highest priority.
  49. // Thus if one app fails to apply there is nothing of interest that
  50. // we can really do. We don't know which lower priority apps
  51. // may need to be "undone", and we shouldn't abort and thereby
  52. // prevent higher priority apps from being processed.
  53. //
  54. // Therefore, other than logging events, we ignore any errors in
  55. // the processing and continuing applying all apps.
  56. //
  57. switch ( Pass )
  58. {
  59. case 0 :
  60. Status = pAppInfo->InitializePass0();
  61. if ( Status != ERROR_SUCCESS )
  62. return Status;
  63. break;
  64. case 1 :
  65. pAppInfo->SetActionPass1();
  66. break;
  67. case 2 :
  68. pAppInfo->SetActionPass2();
  69. break;
  70. case 3 :
  71. pAppInfo->SetActionPass3();
  72. break;
  73. case 4 :
  74. pAppInfo->SetActionPass4();
  75. break;
  76. case 5 :
  77. if ( pAppInfo->_Status != ERROR_SUCCESS )
  78. return pAppInfo->_Status;
  79. break;
  80. }
  81. MoveNext();
  82. }
  83. ResetEnd();
  84. }
  85. return ERROR_SUCCESS;
  86. }
  87. DWORD
  88. CAppList::ProcessPolicy()
  89. {
  90. CAppInfo * pAppInfo;
  91. DWORD Pass;
  92. DWORD Status;
  93. DWORD FinalStatus;
  94. HRESULT hr;
  95. FinalStatus = ERROR_SUCCESS;
  96. Status = _pManApp->Impersonate();
  97. if ( ERROR_SUCCESS == Status )
  98. Status = SetAppActions();
  99. if ( Status != ERROR_SUCCESS )
  100. {
  101. //
  102. // Ensure that we log an event in this case so that RSoP
  103. // failed view at the extension level has enough information
  104. // to allow the administrator to diagnose the problem
  105. //
  106. gpEvents->PolicyAbort();
  107. _pManApp->Revert();
  108. _pManApp->GetRsopContext()->SetPolicyAborted( Status );
  109. return Status;
  110. }
  111. if ( _pManApp->GetRsopContext()->IsPlanningModeEnabled() )
  112. {
  113. return Status;
  114. }
  115. for ( Pass = 0; Pass <= 2; Pass++ )
  116. {
  117. for ( Reset();;MoveNext() )
  118. {
  119. pAppInfo = (CAppInfo *) GetCurrentItem();
  120. if ( ! pAppInfo )
  121. break;
  122. switch ( Pass )
  123. {
  124. case 0 :
  125. Status = pAppInfo->ProcessUnapplyActions();
  126. break;
  127. case 1 :
  128. Status = pAppInfo->ProcessApplyActions();
  129. break;
  130. case 2 :
  131. if ( _pRsopContext->IsRsopEnabled() && _pRsopContext->IsDiagnosticModeEnabled() )
  132. Status = pAppInfo->ProcessTransformConflicts();
  133. break;
  134. }
  135. if ( (FinalStatus == ERROR_SUCCESS) && (Status != ERROR_SUCCESS) )
  136. FinalStatus = Status;
  137. //
  138. // If we are returning an error of some sort, we should force a synchronous
  139. // refresh if we are not already returning the error to request one. This is
  140. // needed because some errors require a sync refresh to fix (such as
  141. // install / uninstall errors), and gp will not give us a sync refresh
  142. // unless we ask for it.
  143. //
  144. if ( ! _pManApp->NoChanges() &&
  145. ( ERROR_SUCCESS != FinalStatus ) &&
  146. ( ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED != FinalStatus ) )
  147. {
  148. _pManApp->Revert();
  149. (void) ForceSynchronousRefresh( _pManApp->UserToken() );
  150. _pManApp->Impersonate();
  151. }
  152. }
  153. ResetEnd();
  154. }
  155. _pManApp->Revert();
  156. return FinalStatus;
  157. }
  158. DWORD
  159. CAppList::ProcessARPList()
  160. {
  161. DWORD Status;
  162. Status = _pManApp->Impersonate();
  163. if ( ERROR_SUCCESS == Status )
  164. Status = SetAppActions();
  165. _pManApp->Revert();
  166. return Status;
  167. }
  168. DWORD
  169. CAppList::Count(
  170. DWORD Flags
  171. )
  172. {
  173. CAppInfo * pAppInfo;
  174. DWORD Count;
  175. Count = 0;
  176. Reset();
  177. for ( ;; )
  178. {
  179. pAppInfo = (CAppInfo *) GetCurrentItem();
  180. if ( ! pAppInfo )
  181. break;
  182. if ( pAppInfo->_ActFlags & Flags )
  183. Count++;
  184. MoveNext();
  185. }
  186. ResetEnd();
  187. return Count;
  188. }
  189. CAppInfo *
  190. CAppList::Find(
  191. GUID DeploymentId
  192. )
  193. {
  194. CAppInfo * pAppInfo;
  195. Reset();
  196. for (;;)
  197. {
  198. pAppInfo = (CAppInfo *) GetCurrentItem();
  199. if ( ! pAppInfo )
  200. break;
  201. if ( memcmp( &pAppInfo->_DeploymentId, &DeploymentId, sizeof(GUID) ) == 0 )
  202. break;
  203. MoveNext();
  204. }
  205. ResetEnd();
  206. return pAppInfo;
  207. }
  208. HRESULT
  209. CAppList::WriteLog( DWORD dwFilter )
  210. {
  211. CAppInfo * pAppInfo;
  212. DWORD Status;
  213. HRESULT hr;
  214. hr = InitRsopLog();
  215. if ( FAILED(hr) )
  216. {
  217. return hr;
  218. }
  219. if ( ( CRsopAppContext::POLICY_REFRESH == _pRsopContext->GetContext() ) &&
  220. _pRsopContext->IsDiagnosticModeEnabled() && ! _pManApp->IsRemovingPolicies() )
  221. {
  222. hr = PurgeEntries();
  223. }
  224. if ( FAILED(hr) )
  225. {
  226. return hr;
  227. }
  228. Reset();
  229. for (;;)
  230. {
  231. BOOL bLogApp;
  232. pAppInfo = (CAppInfo *) GetCurrentItem();
  233. if ( ! pAppInfo )
  234. break;
  235. //
  236. // Check to see if this app is applied to the user and should be logged
  237. //
  238. bLogApp = ( RSOP_FILTER_ALL == dwFilter ) ||
  239. ( ( ACTION_UNINSTALL == pAppInfo->Action() ) || ( ACTION_ORPHAN == pAppInfo->Action() ) );
  240. //
  241. // Check to see if this app would have been in the ARP list if not for the
  242. // fact that the administrator chose to conceal it
  243. //
  244. if ( CRsopAppContext::ARPLIST == _pRsopContext->GetContext() )
  245. {
  246. if ( ( ACTION_NONE == pAppInfo->Action() ) &&
  247. ( (pAppInfo->_ActFlags & (ACTFLG_Assigned | ACTFLG_Published) ) &&
  248. !(pAppInfo->_ActFlags & ACTFLG_UserInstall) ) )
  249. {
  250. bLogApp = TRUE;
  251. pAppInfo->SetAction(
  252. ACTION_INSTALL,
  253. 0,
  254. NULL);
  255. }
  256. }
  257. if ( bLogApp )
  258. {
  259. hr = WriteAppToRsopLog( pAppInfo );
  260. if (FAILED(hr))
  261. {
  262. break;
  263. }
  264. }
  265. MoveNext();
  266. }
  267. ResetEnd();
  268. return hr;
  269. }
  270. HRESULT
  271. CAppList::WriteAppToRsopLog( CAppInfo* pAppInfo )
  272. {
  273. HRESULT hr;
  274. CConflict WinningConflict( pAppInfo );
  275. //
  276. // If this is a rolled-back upgrade, the instance
  277. // is already written and we do not need to do anything
  278. //
  279. if ( pAppInfo->_bRollback )
  280. {
  281. return S_OK;
  282. }
  283. //
  284. // Do not log entries for applications that will be removed
  285. // in the next sync refresh
  286. //
  287. if ( ( ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED == pAppInfo->_Status ) &&
  288. ( ACTION_APPLY != pAppInfo->_Action ) && ( ACTION_INSTALL != pAppInfo->_Action ) &&
  289. ( ACTION_REINSTALL != pAppInfo->_Action ) )
  290. {
  291. return S_OK;
  292. }
  293. hr = InitRsopLog();
  294. if ( FAILED(hr) )
  295. {
  296. return hr;
  297. }
  298. //
  299. // If this app failed to be applied, we must log it anyway
  300. //
  301. if ( pAppInfo->_StatusList.GetCurrentItem() )
  302. {
  303. if ( ACTION_NONE == pAppInfo->Action() )
  304. {
  305. pAppInfo->SetAction(
  306. ACTION_APPLY,
  307. pAppInfo->_dwApplyCause,
  308. NULL);
  309. }
  310. }
  311. else if ( _pRsopContext->HasPolicyAborted() )
  312. {
  313. //
  314. // If policy aborted before even trying to apply the app
  315. // then we shouldn't log this setting unless it has a failure --
  316. // apps without failures haven't been applied, and apps with
  317. // failures are known to not apply, so we can safely log those
  318. //
  319. return S_OK;
  320. }
  321. switch ( pAppInfo->GetRsopEntryType() )
  322. {
  323. case APP_ATTRIBUTE_ENTRYTYPE_VALUE_INSTALLED_PACKAGE:
  324. WCHAR* wszCriteria;
  325. wszCriteria = pAppInfo->GetRsopAppCriteria();
  326. hr = ClearLog( wszCriteria, TRUE );
  327. delete [] wszCriteria;
  328. if ( FAILED(hr) )
  329. {
  330. return hr;
  331. }
  332. //
  333. // In planning mode, we only apply published apps if they upgrade
  334. // an assigned app
  335. //
  336. if ( _pRsopContext->IsPlanningModeEnabled() )
  337. {
  338. if ( ( ACTFLG_Published & pAppInfo->_ActFlags ) && ! pAppInfo->_bSupersedesAssigned )
  339. {
  340. break;
  341. }
  342. }
  343. //
  344. // Fall through to the next case
  345. //
  346. case APP_ATTRIBUTE_ENTRYTYPE_VALUE_ARPLIST_ITEM:
  347. //
  348. // In the arplist case, we require the action
  349. // set to ACTION_INSTALL in order to log the app
  350. //
  351. if ( _pManApp->ARPList() &&
  352. ( ACTION_INSTALL != pAppInfo->Action() ) )
  353. {
  354. break;
  355. }
  356. //
  357. // If this is a winning application, create a new entry for the winner
  358. // and then log its conflicts
  359. //
  360. if ( ! pAppInfo->IsSuperseded() )
  361. {
  362. WCHAR wszDeploymentId[ MAX_SZGUID_LEN ];
  363. pAppInfo->GetDeploymentId( wszDeploymentId);
  364. hr = WinningConflict.SetConflictId( wszDeploymentId );
  365. if ( SUCCEEDED(hr) )
  366. {
  367. hr = WriteNewRecord ( &WinningConflict );
  368. }
  369. if (FAILED(hr))
  370. {
  371. DebugMsg((DM_VERBOSE, IDS_RSOP_LOG_WRITE_FAIL, hr));
  372. hr = S_OK;
  373. }
  374. if (SUCCEEDED(hr))
  375. {
  376. (void) WinningConflict.LogFailure();
  377. }
  378. (void) WriteConflicts ( pAppInfo );
  379. }
  380. break;
  381. case APP_ATTRIBUTE_ENTRYTYPE_VALUE_REMOVED_PACKAGE:
  382. BOOL bDeleteInstalledEntry;
  383. CAppStatus* pCurrentStatus;
  384. bDeleteInstalledEntry = TRUE;
  385. pCurrentStatus = (CAppStatus*) pAppInfo->_StatusList.GetCurrentItem();
  386. //
  387. // Do not delete the installed entry if it was never
  388. // successfully removed
  389. //
  390. if ( pCurrentStatus &&
  391. ( RSOPFailed == pCurrentStatus->_SettingStatus ) )
  392. {
  393. bDeleteInstalledEntry = FALSE;
  394. }
  395. //
  396. // For removed applications, we do not create a new entry,
  397. // just change the existing entry to indicate that
  398. // it has been removed
  399. //
  400. hr = MarkRSOPEntryAsRemoved(
  401. pAppInfo,
  402. bDeleteInstalledEntry);
  403. if ( SUCCEEDED( hr ) )
  404. {
  405. pAppInfo->_bRemovalLogged = TRUE;
  406. }
  407. break;
  408. default:
  409. break;
  410. }
  411. return hr;
  412. }
  413. HRESULT
  414. CAppList::WriteConflicts( CAppInfo* pAppInfo )
  415. {
  416. HRESULT hr;
  417. CConflictList Conflicts;
  418. CConflict* pCurrentConflict;
  419. hr = pAppInfo->GetConflictTable()->GenerateResultantConflictList( &Conflicts );
  420. if (SUCCEEDED(hr))
  421. {
  422. Conflicts.Reset();
  423. while ( pCurrentConflict = (CConflict*) Conflicts.GetCurrentItem() )
  424. {
  425. WCHAR wszDeploymentId[ MAX_SZGUID_LEN ];
  426. pAppInfo->GetDeploymentId( wszDeploymentId);
  427. hr = pCurrentConflict->SetConflictId( wszDeploymentId );
  428. if ( FAILED(hr) )
  429. {
  430. break;
  431. }
  432. HRESULT hrWrite;
  433. if ( ! pCurrentConflict->GetApp()->IsLocal() )
  434. {
  435. hrWrite = WriteNewRecord( pCurrentConflict );
  436. }
  437. else
  438. {
  439. hrWrite = OpenExistingRecord( pCurrentConflict );
  440. if ( SUCCEEDED( hrWrite ) )
  441. {
  442. hrWrite = pCurrentConflict->Write();
  443. }
  444. if ( SUCCEEDED( hrWrite ) )
  445. {
  446. hrWrite = pCurrentConflict->GetApp()->ClearRemovalProperties( pCurrentConflict );
  447. }
  448. if ( SUCCEEDED( hrWrite ) )
  449. {
  450. hrWrite = CommitRecord( pCurrentConflict );
  451. }
  452. }
  453. if ( SUCCEEDED( hrWrite ) )
  454. {
  455. (void) DeleteStatusRecords( pCurrentConflict );
  456. }
  457. if (FAILED(hrWrite))
  458. {
  459. DebugMsg((DM_VERBOSE, IDS_RSOP_LOG_WRITE_FAIL, hrWrite));
  460. }
  461. Conflicts.MoveNext();
  462. }
  463. }
  464. if (FAILED(hr))
  465. {
  466. DebugMsg((DM_VERBOSE, IDS_RSOP_CONFLICTS_FAIL, pAppInfo->_pwszDeploymentName, pAppInfo->_pwszGPOName, hr));
  467. }
  468. return hr;
  469. }
  470. HRESULT CAppList::InitRsopLog()
  471. {
  472. if ( _bRsopInitialized )
  473. {
  474. return _hrRsopInit;
  475. }
  476. _bRsopInitialized = TRUE;
  477. _hrRsopInit = InitLog(
  478. _pRsopContext,
  479. RSOP_MANAGED_SOFTWARE_APPLICATION);
  480. if (FAILED(_hrRsopInit))
  481. {
  482. DebugMsg((DM_VERBOSE, IDS_RSOP_LOG_INIT_FAIL, _hrRsopInit));
  483. return _hrRsopInit;
  484. }
  485. if ( _pRsopContext->Transition() )
  486. {
  487. _hrRsopInit = ClearLog( NULL, TRUE );
  488. }
  489. else if ( ! _pRsopContext->ForcedRefresh() )
  490. {
  491. BOOL bPolicy;
  492. bPolicy = FALSE;
  493. //
  494. // In the forced refresh case, we need to preserve the
  495. // state of policy since it actually has not changed,
  496. // so we skip the purge below
  497. //
  498. //
  499. // In the policy refresh case, we need to clear everything
  500. // that does not apply to the user as well as removal entries
  501. //
  502. switch ( _pRsopContext->GetContext() )
  503. {
  504. case CRsopAppContext::POLICY_REFRESH:
  505. bPolicy = TRUE;
  506. if ( ! _pRsopContext->PurgeRemovalEntries() )
  507. {
  508. break;
  509. }
  510. _pRsopContext->ResetRemovalPurge();
  511. //
  512. // Purposefully fall through
  513. //
  514. case CRsopAppContext::ARPLIST:
  515. _hrRsopInit = ClearLog( GetRsopListCriteria(), bPolicy );
  516. if ( FAILED( _hrRsopInit ) )
  517. {
  518. DebugMsg((DM_VERBOSE, IDS_RSOP_LOG_INIT_FAIL, _hrRsopInit));
  519. }
  520. break;
  521. default:
  522. break;
  523. }
  524. }
  525. return _hrRsopInit;
  526. }
  527. HRESULT
  528. CAppList::PurgeEntries()
  529. {
  530. HRESULT hr;
  531. hr = GetEnum( RSOP_PURGE_QUERY );
  532. if ( SUCCEEDED(hr) )
  533. {
  534. HRESULT hrEnum;
  535. hrEnum = S_OK;
  536. for (;;)
  537. {
  538. CPolicyRecord CurrentApplication;
  539. LONG EntryType;
  540. hrEnum = GetNextRecord( &CurrentApplication );
  541. if ( S_OK != hrEnum )
  542. {
  543. if ( FAILED(hrEnum) )
  544. {
  545. hr = hrEnum;
  546. }
  547. break;
  548. }
  549. GUID DeploymentId;
  550. WCHAR wszDeploymentId[ MAX_SZGUID_LEN ];
  551. LONG cchSize;
  552. CAppInfo* pAppliedApp;
  553. cchSize = sizeof( wszDeploymentId ) / sizeof( *wszDeploymentId );
  554. hrEnum = CurrentApplication.GetValue(
  555. RSOP_ATTRIBUTE_ID,
  556. wszDeploymentId,
  557. &cchSize);
  558. if ( FAILED( hrEnum ) )
  559. {
  560. break;
  561. }
  562. if ( S_OK != hrEnum )
  563. {
  564. break;
  565. }
  566. StringToGuid( wszDeploymentId, &DeploymentId );
  567. pAppliedApp = Find( DeploymentId );
  568. if ( pAppliedApp )
  569. {
  570. if ( pAppliedApp->_State & ( APPSTATE_ASSIGNED | APPSTATE_PUBLISHED ) )
  571. {
  572. if ( ACTFLG_Published & pAppliedApp->_ActFlags )
  573. {
  574. (void) GetUserApplyCause(
  575. &CurrentApplication,
  576. pAppliedApp);
  577. }
  578. continue;
  579. }
  580. if ( ( ACTION_NONE != pAppliedApp->Action() ) ||
  581. pAppliedApp->_bRollback )
  582. {
  583. continue;
  584. }
  585. }
  586. hrEnum = DeleteRecord( &CurrentApplication, TRUE );
  587. if ( FAILED( hrEnum ) )
  588. {
  589. hr = hrEnum;
  590. }
  591. }
  592. FreeEnum();
  593. }
  594. return hr;
  595. }
  596. HRESULT
  597. CAppList::GetUserApplyCause(
  598. CPolicyRecord* pRecord,
  599. CAppInfo* pAppInfo
  600. )
  601. {
  602. HRESULT hr;
  603. LONG ApplyCause;
  604. hr = pRecord->GetValue(
  605. APP_ATTRIBUTE_APPLY_CAUSE,
  606. &ApplyCause);
  607. if ( SUCCEEDED( hr) &&
  608. ( APP_ATTRIBUTE_APPLYCAUSE_VALUE_NONE != ApplyCause ) &&
  609. ! pAppInfo->_wszDemandProp )
  610. {
  611. pAppInfo->_dwUserApplyCause = ApplyCause;
  612. switch ( ApplyCause )
  613. {
  614. case APP_ATTRIBUTE_APPLYCAUSE_VALUE_FILEEXT:
  615. pAppInfo->_wszDemandProp = APP_ATTRIBUTE_ONDEMAND_FILEEXT;
  616. break;
  617. case APP_ATTRIBUTE_APPLYCAUSE_VALUE_CLSID:
  618. pAppInfo->_wszDemandProp = APP_ATTRIBUTE_ONDEMAND_CLSID;
  619. break;
  620. case APP_ATTRIBUTE_APPLYCAUSE_VALUE_PROGID:
  621. pAppInfo->_wszDemandProp = APP_ATTRIBUTE_ONDEMAND_PROGID;
  622. break;
  623. default:
  624. pAppInfo->_wszDemandProp = NULL;
  625. break;
  626. }
  627. if ( pAppInfo->_wszDemandProp && ! pAppInfo->_wszDemandSpec )
  628. {
  629. LONG cchSize;
  630. cchSize = 0;
  631. hr = pRecord->GetValue(
  632. pAppInfo->_wszDemandProp,
  633. pAppInfo->_wszDemandSpec,
  634. &cchSize);
  635. if ( S_FALSE == hr )
  636. {
  637. pAppInfo->_wszDemandSpec = new WCHAR [ cchSize ];
  638. if ( pAppInfo->_wszDemandSpec )
  639. {
  640. hr = pRecord->GetValue(
  641. pAppInfo->_wszDemandProp,
  642. pAppInfo->_wszDemandSpec,
  643. &cchSize);
  644. }
  645. else
  646. {
  647. hr = E_OUTOFMEMORY;
  648. }
  649. }
  650. }
  651. }
  652. return hr;
  653. }
  654. HRESULT CAppList::MarkRSOPEntryAsRemoved(
  655. CAppInfo* pAppInfo,
  656. BOOL bRemoveInstances)
  657. {
  658. HRESULT hr;
  659. WCHAR* wszRemovalCriteria;
  660. wszRemovalCriteria = NULL;
  661. DebugMsg((DM_VERBOSE, IDS_RSOP_LOG_WRITE_INFO, pAppInfo->_pwszDeploymentName, pAppInfo->_pwszGPOName));
  662. //
  663. // If this is a removed app that was reapplied as part of upgrade rollback,
  664. // we do not want to remove the instances
  665. //
  666. if ( pAppInfo->_bRollback )
  667. {
  668. bRemoveInstances = FALSE;
  669. }
  670. //
  671. // Set up this list's rsop enumerator to enumerate instances of this application
  672. //
  673. hr = FindRsopAppEntry(
  674. pAppInfo,
  675. &wszRemovalCriteria );
  676. if ( SUCCEEDED( hr ) )
  677. {
  678. for (;;)
  679. {
  680. CConflict RemovedApplication( pAppInfo );
  681. LONG Precedence;
  682. hr = GetNextRecord( &RemovedApplication );
  683. if ( S_OK != hr )
  684. {
  685. break;
  686. }
  687. hr = RemovedApplication.GetValue(
  688. RSOP_ATTRIBUTE_PRECEDENCE,
  689. &Precedence);
  690. if ( FAILED (hr) )
  691. {
  692. break;
  693. }
  694. //
  695. // If this is a removal of an assigned application, then we should
  696. // change the apply cause of the installed application to assigned
  697. // rather than user
  698. //
  699. if ( 1 == Precedence )
  700. {
  701. if ( ( pAppInfo->_State & APPSTATE_ASSIGNED ) &&
  702. ( CRsopAppContext::REMOVAL == _pRsopContext->GetContext() ) )
  703. {
  704. LONG CurrentApplyCause;
  705. LONG CurrentEligibility;
  706. //
  707. // First, we must find out the current apply cause so
  708. // that we can propagate that to the removal entry
  709. //
  710. hr = RemovedApplication.GetValue(
  711. APP_ATTRIBUTE_APPLY_CAUSE,
  712. &CurrentApplyCause);
  713. if ( SUCCEEDED(hr) )
  714. {
  715. hr = RemovedApplication.GetValue(
  716. APP_ATTRIBUTE_ELIGIBILITY,
  717. &CurrentEligibility);
  718. }
  719. if ( SUCCEEDED(hr) )
  720. {
  721. //
  722. // Now set the current apply cause to assigned
  723. //
  724. hr = RemovedApplication.SetValue(
  725. APP_ATTRIBUTE_APPLY_CAUSE,
  726. APP_ATTRIBUTE_APPLYCAUSE_VALUE_ASSIGNED);
  727. REPORT_ATTRIBUTE_SET_STATUS( APP_ATTRIBUTE_APPLY_CAUSE, hr );
  728. if ( SUCCEEDED(hr) )
  729. {
  730. //
  731. // Also set the eligibility to assigned
  732. //
  733. hr = RemovedApplication.SetValue(
  734. APP_ATTRIBUTE_ELIGIBILITY,
  735. APP_ATTRIBUTE_ELIGIBILITY_VALUE_ASSIGNED);
  736. REPORT_ATTRIBUTE_SET_STATUS( APP_ATTRIBUTE_ELIGIBILITY, hr );
  737. }
  738. //
  739. // Clear out any attributes that should not be set for applications
  740. // applied due to assignment
  741. //
  742. hr = RemovedApplication.ClearValue(
  743. APP_ATTRIBUTE_ONDEMAND_FILEEXT);
  744. REPORT_ATTRIBUTE_SET_STATUS( APP_ATTRIBUTE_ONDEMAND_FILEEXT, hr )
  745. hr = RemovedApplication.ClearValue(
  746. APP_ATTRIBUTE_ONDEMAND_CLSID);
  747. REPORT_ATTRIBUTE_SET_STATUS( APP_ATTRIBUTE_ONDEMAND_CLSID, hr )
  748. hr = RemovedApplication.ClearValue(
  749. APP_ATTRIBUTE_ONDEMAND_PROGID);
  750. REPORT_ATTRIBUTE_SET_STATUS( APP_ATTRIBUTE_ONDEMAND_PROGID, hr )
  751. }
  752. //
  753. // Commit the record for the installed application
  754. //
  755. if ( SUCCEEDED(hr) )
  756. {
  757. hr = CommitRecord( &RemovedApplication );
  758. }
  759. if ( SUCCEEDED(hr) )
  760. {
  761. //
  762. // Now set the removal entry's install cause to
  763. // that of the original install
  764. //
  765. hr = RemovedApplication.SetValue(
  766. APP_ATTRIBUTE_APPLY_CAUSE,
  767. CurrentApplyCause);
  768. REPORT_ATTRIBUTE_SET_STATUS( APP_ATTRIBUTE_APPLY_CAUSE, hr );
  769. if ( SUCCEEDED(hr) )
  770. {
  771. //
  772. // Also set the eligibility to assigned
  773. //
  774. hr = RemovedApplication.SetValue(
  775. APP_ATTRIBUTE_ELIGIBILITY,
  776. CurrentEligibility);
  777. REPORT_ATTRIBUTE_SET_STATUS( APP_ATTRIBUTE_ELIGIBILITY, hr );
  778. }
  779. }
  780. }
  781. //
  782. // We must mark the highest precedence entry
  783. // (the currently applied entry) as removed --
  784. // see if this has the highest precedence (1)
  785. //
  786. if ( bRemoveInstances &&
  787. ( ( pAppInfo->_State & APPSTATE_PUBLISHED ) ||
  788. ( CRsopAppContext::POLICY_REFRESH != _pRsopContext->GetContext() ) ) )
  789. {
  790. hr = DeleteRecord ( &RemovedApplication, TRUE );
  791. }
  792. else
  793. {
  794. hr = DeleteStatusRecords( &RemovedApplication );
  795. }
  796. if ( SUCCEEDED( hr ) )
  797. {
  798. hr = RemovedApplication.SetValue(
  799. APP_ATTRIBUTE_ENTRYTYPE,
  800. APP_ATTRIBUTE_ENTRYTYPE_VALUE_REMOVED_PACKAGE);
  801. REPORT_ATTRIBUTE_SET_STATUS( APP_ATTRIBUTE_ENTRYTYPE, hr );
  802. }
  803. if ( SUCCEEDED( hr ) )
  804. {
  805. hr = RemovedApplication.SetValue(
  806. RSOP_ATTRIBUTE_PRECEDENCE,
  807. 0L);
  808. REPORT_ATTRIBUTE_SET_STATUS( RSOP_ATTRIBUTE_PRECEDENCE, hr );
  809. }
  810. if ( SUCCEEDED( hr ) )
  811. {
  812. hr = pAppInfo->WriteRemovalProperties( &RemovedApplication );
  813. }
  814. if ( SUCCEEDED( hr ) )
  815. {
  816. hr = CommitRecord( &RemovedApplication );
  817. if ( SUCCEEDED(hr) )
  818. {
  819. (void) DeleteStatusRecords( &RemovedApplication );
  820. (void) RemovedApplication.LogFailure();
  821. }
  822. }
  823. }
  824. else
  825. {
  826. hr = DeleteRecord ( &RemovedApplication, TRUE );
  827. }
  828. if ( FAILED(hr) )
  829. {
  830. break;
  831. }
  832. }
  833. }
  834. FreeEnum();
  835. if ( bRemoveInstances &&
  836. SUCCEEDED(hr) )
  837. {
  838. //
  839. // We've already found the highest precedence entry
  840. // and copied it as a removal entry --
  841. // if the caller specified to remove the original
  842. // instances for this app's conflict id, do so
  843. //
  844. hr = ClearLog( wszRemovalCriteria, TRUE );
  845. }
  846. delete [] wszRemovalCriteria;
  847. return hr;
  848. }
  849. HRESULT
  850. CAppList::FindRsopAppEntry(
  851. CAppInfo* pAppInfo,
  852. WCHAR** ppwszAppCriteria )
  853. {
  854. HRESULT hr;
  855. hr = InitRsopLog();
  856. if ( FAILED(hr) )
  857. {
  858. return hr;
  859. }
  860. hr = E_OUTOFMEMORY;
  861. *ppwszAppCriteria = pAppInfo->GetRsopAppCriteria();
  862. if ( *ppwszAppCriteria )
  863. {
  864. hr = GetEnum( *ppwszAppCriteria );
  865. }
  866. if ( FAILED(hr) )
  867. {
  868. delete [] *ppwszAppCriteria;
  869. *ppwszAppCriteria = NULL;
  870. }
  871. return hr;
  872. }
  873. WCHAR*
  874. CAppList::GetRsopListCriteria()
  875. {
  876. WCHAR* wszCriteria;
  877. switch ( _pRsopContext->GetContext() )
  878. {
  879. case CRsopAppContext::ARPLIST:
  880. wszCriteria = RSOP_ARP_CONTEXT_QUERY;
  881. break;
  882. case CRsopAppContext::POLICY_REFRESH:
  883. wszCriteria = RSOP_POLICY_CONTEXT_QUERY;
  884. break;
  885. default:
  886. ASSERT(FALSE);
  887. return NULL;
  888. }
  889. return wszCriteria;
  890. }