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.

2242 lines
65 KiB

  1. //*************************************************************
  2. //
  3. // Copyright (c) Microsoft Corporation 1998
  4. // All rights reserved
  5. //
  6. // apis.cxx
  7. //
  8. //*************************************************************
  9. #include "appmgext.hxx"
  10. typedef struct
  11. {
  12. CManagedAppProcessor * pManApp;
  13. CAppInfo * pAppInfo;
  14. BOOL bUninstallsCompleted;
  15. CLoadMsi * pLoadMsi;
  16. CLoadSfc * pLoadSfc;
  17. boolean bStatus;
  18. INT64 SRSequence;
  19. } APPCONTEXT, * PAPPCONTEXT;
  20. CRITICAL_SECTION gAppCS;
  21. static BOOL
  22. SetSystemRestorePoint(
  23. IN WCHAR * pwszApplicationName,
  24. IN OUT PAPPCONTEXT pAppContext
  25. );
  26. static void
  27. CheckLocalCall(
  28. IN handle_t hRpc
  29. );
  30. WCHAR*
  31. GetGpoNameFromGuid(
  32. IN PGROUP_POLICY_OBJECT pGpoList,
  33. IN GUID* pGpoGuid
  34. );
  35. DWORD
  36. GetPlatformCompatibleCOMClsCtx(
  37. DWORD Architecture,
  38. DWORD dwClsCtx
  39. );
  40. void
  41. LogRsopInstallData(
  42. CManagedAppProcessor* pManApp,
  43. CAppInfo* pAppInfo
  44. );
  45. DWORD
  46. WINAPI
  47. GetManagedAppsProc(
  48. LPVOID pvArpContext
  49. );
  50. error_status_t
  51. InstallBegin(
  52. IN handle_t hRpc,
  53. IN APPKEY * pAppType,
  54. OUT PINSTALLCONTEXT * ppInstallContext,
  55. OUT APPLICATION_INFO * pInstallInfo,
  56. OUT UNINSTALL_APPS * pUninstallApps
  57. )
  58. {
  59. CManagedAppProcessor * pManApp;
  60. CAppList LocalApps( NULL );
  61. HANDLE hUserToken;
  62. HKEY hkRoot;
  63. uCLSSPEC ClassSpec;
  64. QUERYCONTEXT QueryContext;
  65. PACKAGEDISPINFO PackageInfo;
  66. PAPPCONTEXT pAppContext;
  67. GUID DeploymentId;
  68. CAppInfo * pAppInfo;
  69. CAppInfo * pUpgradedApp;
  70. CAppInfo * pLocalApp;
  71. WCHAR wszGuid[40];
  72. WCHAR wszProductId[40];
  73. WCHAR * pwszDeploymentId;
  74. DWORD Size;
  75. DWORD UninstallApps;
  76. DWORD n;
  77. DWORD Status;
  78. HRESULT hr;
  79. BOOL bEnterCritSec;
  80. BOOL bStatus;
  81. CRsopAppContext RsopContext( CRsopAppContext::INSTALL, NULL, pAppType );
  82. PGROUP_POLICY_OBJECT pGPOList;
  83. *ppInstallContext = 0;
  84. memset( pInstallInfo, 0, sizeof(APPLICATION_INFO) );
  85. memset( pUninstallApps, 0, sizeof(UNINSTALL_APPS) );
  86. CheckLocalCall( hRpc );
  87. pManApp = 0;
  88. pAppInfo = 0;
  89. hUserToken = 0;
  90. hkRoot = 0;
  91. pAppContext = 0;
  92. bEnterCritSec = FALSE;
  93. pGPOList = NULL;
  94. Status = RpcImpersonateClient( NULL );
  95. if ( Status != ERROR_SUCCESS )
  96. return Status;
  97. if ( ERROR_SUCCESS == Status )
  98. {
  99. bStatus = OpenThreadToken(
  100. GetCurrentThread(),
  101. TOKEN_READ | TOKEN_IMPERSONATE | TOKEN_DUPLICATE,
  102. TRUE,
  103. &hUserToken );
  104. if ( ! bStatus )
  105. Status = GetLastError();
  106. }
  107. if ( ERROR_SUCCESS == Status )
  108. Status = RegOpenCurrentUser( GENERIC_ALL, &hkRoot );
  109. if ( Status != ERROR_SUCCESS )
  110. {
  111. CloseHandle( hUserToken );
  112. RevertToSelf();
  113. return Status;
  114. }
  115. gpEvents->SetToken( hUserToken );
  116. LogTime();
  117. //
  118. // Set the query context -- the LANG_SYSTEM_DEFAULT value
  119. // tells CsGetAppInfo that we should use our built-in language precedence
  120. // algorithm in filtering packages -- otherwise, it will only consider
  121. // packages that match exactly the locale specified in the .Locale member
  122. //
  123. QueryContext.Locale = LANG_SYSTEM_DEFAULT;
  124. //
  125. // For architecture, we use the architecture of the calling process to override
  126. // the architecture of this process
  127. //
  128. GetDefaultPlatform( &QueryContext.Platform, TRUE, pAppType->ProcessorArchitecture );
  129. QueryContext.dwContext = CLSCTX_ALL;
  130. QueryContext.dwVersionHi = -1;
  131. QueryContext.dwVersionLo = -1;
  132. switch ( pAppType->Type )
  133. {
  134. case APPNAME :
  135. ClassSpec.tyspec = TYSPEC_PACKAGENAME;
  136. ClassSpec.tagged_union.ByName.pPackageName = pAppType->uType.AppName.Name;
  137. ClassSpec.tagged_union.ByName.PolicyId = pAppType->uType.AppName.PolicyId;
  138. DebugMsg((DM_VERBOSE, IDS_INSTALL_APPNAME, pAppType->uType.AppName.Name));
  139. break;
  140. case FILEEXT :
  141. ClassSpec.tyspec = TYSPEC_FILEEXT;
  142. ClassSpec.tagged_union.pFileExt = pAppType->uType.FileExt;
  143. DebugMsg((DM_VERBOSE, IDS_INSTALL_FILEEXT, pAppType->uType.FileExt));
  144. break;
  145. case PROGID :
  146. ClassSpec.tyspec = TYSPEC_PROGID;
  147. ClassSpec.tagged_union.pProgId = pAppType->uType.ProgId;
  148. DebugMsg((DM_VERBOSE, IDS_INSTALL_PROGID, pAppType->uType.ProgId));
  149. break;
  150. case COMCLASS :
  151. ClassSpec.tyspec = TYSPEC_CLSID;
  152. ClassSpec.tagged_union.clsid = pAppType->uType.COMClass.Clsid;
  153. QueryContext.dwContext = GetPlatformCompatibleCOMClsCtx( pAppType->ProcessorArchitecture, pAppType->uType.COMClass.ClsCtx );
  154. GuidToString( pAppType->uType.COMClass.Clsid, wszGuid );
  155. DebugMsg((DM_VERBOSE, IDS_INSTALL_COMCLASS, wszGuid, QueryContext.dwContext));
  156. break;
  157. }
  158. hr = CsGetAppInfo( &ClassSpec, &QueryContext, &PackageInfo );
  159. RevertToSelf();
  160. if ( S_OK == hr )
  161. {
  162. WCHAR* pszPolicyName;
  163. Status = RpcImpersonateClient( NULL );
  164. if ( ERROR_SUCCESS == Status )
  165. {
  166. Status = GetCurrentUserGPOList( &pGPOList );
  167. RevertToSelf();
  168. }
  169. if ( ERROR_SUCCESS != Status )
  170. goto InstallAppExit;
  171. pszPolicyName = GetGpoNameFromGuid(
  172. pGPOList,
  173. &(PackageInfo.GpoId) );
  174. //
  175. // We've seen instance where getting the policy names fails because the gpo
  176. // history key for appmgmt in hklm was missing. This is remotely possible
  177. // if some registry api fails. In this instance we can't just let every
  178. // install from ARP fail, so we'll just have to chug along with an empty
  179. // policy name.
  180. //
  181. if ( ! pszPolicyName )
  182. pszPolicyName = L"";
  183. switch ( PackageInfo.PathType )
  184. {
  185. case DrwFilePath :
  186. DebugMsg((DM_VERBOSE, IDS_INSTALL_DARWIN, PackageInfo.pszPackageName, pszPolicyName));
  187. break;
  188. case SetupNamePath :
  189. DebugMsg((DM_VERBOSE, IDS_INSTALL_SETUP, PackageInfo.pszPackageName, pszPolicyName));
  190. pInstallInfo->pwszDeploymentName = StringDuplicate( PackageInfo.pszPackageName );
  191. pInstallInfo->pwszGPOName = StringDuplicate( pszPolicyName );
  192. pInstallInfo->pwszSetupCommand = StringDuplicate( PackageInfo.pszScriptPath );
  193. goto InstallAppExit;
  194. default :
  195. DebugMsg((DM_VERBOSE, IDS_INSTALL_UNKNOWN, PackageInfo.PathType, PackageInfo.pszPackageName, pszPolicyName));
  196. Status = CS_E_PACKAGE_NOTFOUND;
  197. goto InstallAppExit;
  198. }
  199. }
  200. else
  201. {
  202. DebugMsg((DM_VERBOSE, IDS_GETAPPINFO_FAIL, hr));
  203. memset( &PackageInfo, 0, sizeof(PackageInfo) );
  204. Status = (DWORD) hr;
  205. }
  206. if ( ERROR_SUCCESS == Status )
  207. {
  208. pAppContext = new APPCONTEXT;
  209. if ( pAppContext )
  210. {
  211. pAppContext->pManApp = 0;
  212. pAppContext->pAppInfo = 0;
  213. pAppContext->bUninstallsCompleted = FALSE;
  214. pAppContext->pLoadMsi = new CLoadMsi( Status );
  215. pAppContext->pLoadSfc = 0;
  216. pAppContext->bStatus = FALSE;
  217. pAppContext->SRSequence = 0;
  218. if ( Status != ERROR_SUCCESS )
  219. {
  220. delete pAppContext->pLoadMsi;
  221. pAppContext->pLoadMsi = 0;
  222. }
  223. if ( ! pAppContext->pLoadMsi )
  224. {
  225. delete pAppContext;
  226. pAppContext = 0;
  227. }
  228. }
  229. if ( ! pAppContext )
  230. {
  231. Status = ERROR_OUTOFMEMORY;
  232. }
  233. }
  234. if ( Status != ERROR_SUCCESS )
  235. goto InstallAppExit;
  236. RtlEnterCriticalSection( &gAppCS );
  237. bEnterCritSec = TRUE;
  238. pManApp = new CManagedAppProcessor( 0, hUserToken, hkRoot, NULL, TRUE, FALSE, &RsopContext, Status );
  239. if ( ! pManApp )
  240. Status = ERROR_OUTOFMEMORY;
  241. if ( ERROR_SUCCESS == Status )
  242. Status = pManApp->SetPolicyListFromGPOList( pGPOList );
  243. if ( ERROR_SUCCESS == Status )
  244. {
  245. pAppInfo = new CAppInfo( pManApp, &PackageInfo, TRUE, bStatus );
  246. if ( ! pAppInfo || ! bStatus )
  247. Status = ERROR_OUTOFMEMORY;
  248. }
  249. if ( ERROR_SUCCESS == Status )
  250. {
  251. GuidToString( PackageInfo.ProductCode, wszProductId);
  252. Status = pManApp->GetOrderedLocalAppList( LocalApps );
  253. }
  254. if ( ERROR_SUCCESS == Status )
  255. Status = pManApp->Impersonate();
  256. if ( Status != ERROR_SUCCESS )
  257. goto InstallAppExit;
  258. pAppContext->pManApp = pManApp;
  259. pAppContext->pAppInfo = pAppInfo;
  260. //
  261. // When servicing a demand install outside of ARP we prevent faulting in
  262. // any deployment of a particular product different from what is already
  263. // on the machine (if any) and we also prevent faulting in any app which
  264. // upgrades another app already on the machine. This is to prevent a
  265. // subsequent upgrade, transform conflict, or language mismatch from
  266. // occuring while the app is likely in use.
  267. //
  268. // So below we are checking these cases plus, in the case of an ARP install,
  269. // adding any such apps to an additional list for processing of orphan and
  270. // uninstall actions.
  271. //
  272. for ( LocalApps.Reset(), pLocalApp = (CAppInfo *) LocalApps.GetCurrentItem();
  273. pLocalApp;
  274. pLocalApp = (CAppInfo *) LocalApps.GetCurrentItem() )
  275. {
  276. if ( ! (pLocalApp->_State & (APPSTATE_ASSIGNED | APPSTATE_PUBLISHED)) )
  277. {
  278. LocalApps.MoveNext();
  279. continue;
  280. }
  281. //
  282. // This is the check for a similar product id but a different
  283. // deployment instance.
  284. //
  285. if ( (0 == lstrcmpi( pLocalApp->_pwszProductId, wszProductId )) &&
  286. (memcmp( &pLocalApp->_DeploymentId, &PackageInfo.PackageGuid, sizeof(GUID) ) != 0) )
  287. {
  288. if ( pAppType->Type != APPNAME )
  289. {
  290. // Abort if not doing an ARP install.
  291. Status = CS_E_PACKAGE_NOTFOUND;
  292. DebugMsg((DM_VERBOSE, IDS_DEMAND_BLOCK1, pAppInfo->_pwszDeploymentName));
  293. break;
  294. }
  295. else
  296. {
  297. LocalApps.MoveNext();
  298. pLocalApp->Remove();
  299. pManApp->AppList().InsertFIFO( pLocalApp );
  300. continue;
  301. }
  302. }
  303. //
  304. // This is the check to see if this new package is set to upgrade any
  305. // existing app we have.
  306. //
  307. for ( n = 0; n < PackageInfo.cUpgrades; n++ )
  308. {
  309. if ( (PackageInfo.prgUpgradeInfoList[n].Flag & (UPGFLG_Uninstall | UPGFLG_NoUninstall)) &&
  310. (0 == memcmp( &pLocalApp->_DeploymentId, &PackageInfo.prgUpgradeInfoList[n].PackageGuid, sizeof(GUID) )) )
  311. {
  312. if ( pAppType->Type != APPNAME )
  313. {
  314. // Abort if not doing an ARP install.
  315. Status = CS_E_PACKAGE_NOTFOUND;
  316. DebugMsg((DM_VERBOSE, IDS_DEMAND_BLOCK2, pAppInfo->_pwszDeploymentName));
  317. }
  318. else
  319. {
  320. LocalApps.MoveNext();
  321. pLocalApp->Remove();
  322. pManApp->AppList().InsertFIFO( pLocalApp );
  323. }
  324. break;
  325. }
  326. }
  327. if ( CS_E_PACKAGE_NOTFOUND == Status )
  328. break;
  329. if ( n < PackageInfo.cUpgrades )
  330. continue;
  331. //
  332. // This is the check to see if this app is superceded by an app which is
  333. // already installed. Note that in some instances this may actually be
  334. // a case where the new app upgrades the local app because of
  335. // policy precedence upgrade reversal. The result is the same for demand
  336. // installs, but slightly different for ARP installs where we must ensure
  337. // that the upgrade logic is invoked.
  338. //
  339. for ( pwszDeploymentId = pLocalApp->_pwszSupercededIds;
  340. pwszDeploymentId && *pwszDeploymentId;
  341. pwszDeploymentId += GUIDSTRLEN + 1 )
  342. {
  343. StringToGuid( pwszDeploymentId, &DeploymentId );
  344. if ( 0 == memcmp( &DeploymentId, &PackageInfo.PackageGuid, sizeof(GUID) ) )
  345. {
  346. if ( pAppType->Type != APPNAME )
  347. {
  348. // Abort if not doing an ARP install.
  349. Status = CS_E_PACKAGE_NOTFOUND;
  350. DebugMsg((DM_VERBOSE, IDS_DEMAND_BLOCK2, pAppInfo->_pwszDeploymentName));
  351. }
  352. else
  353. {
  354. //
  355. // There is an app already installed which has the new package
  356. // in it's override list. Either a previous upgrade setting is no
  357. // longer set or this is a policy precedence violation case where
  358. // the upgrade needs to be reversed.
  359. // Not the prettiest solution, trading a late product change for least
  360. // invasive code change.
  361. //
  362. if ( pManApp->GPOList().Compare( pLocalApp->_pwszGPOId, pAppInfo->_pwszGPOId ) < 0 )
  363. {
  364. PACKAGEDISPINFO LocalAppPackageInfo;
  365. CAppInfo * pNewApp = 0;
  366. memset( &LocalAppPackageInfo, 0, sizeof(LocalAppPackageInfo) );
  367. ClassSpec.tyspec = TYSPEC_OBJECTID;
  368. memcpy( &ClassSpec.tagged_union.ByObjectId.ObjectId, &pLocalApp->_DeploymentId, sizeof(GUID) );
  369. StringToGuid( pLocalApp->_pwszGPOId, &ClassSpec.tagged_union.ByObjectId.PolicyId );
  370. hr = CsGetAppInfo( &ClassSpec, NULL, &LocalAppPackageInfo );
  371. if ( S_OK == hr )
  372. {
  373. pNewApp = new CAppInfo( pManApp, &LocalAppPackageInfo, FALSE, bStatus );
  374. if ( ! bStatus )
  375. {
  376. delete pNewApp;
  377. pNewApp = 0;
  378. }
  379. ReleasePackageInfo( &LocalAppPackageInfo );
  380. }
  381. if ( pNewApp )
  382. {
  383. pManApp->AppList().InsertFIFO( pAppInfo );
  384. Status = pNewApp->InitializePass0();
  385. pAppInfo->Remove();
  386. pManApp->AppList().InsertFIFO( pNewApp );
  387. }
  388. if ( ! pNewApp || (Status != ERROR_SUCCESS) )
  389. Status = CS_E_PACKAGE_NOTFOUND;
  390. }
  391. }
  392. break;
  393. }
  394. }
  395. if ( CS_E_PACKAGE_NOTFOUND == Status )
  396. break;
  397. LocalApps.MoveNext();
  398. }
  399. LocalApps.ResetEnd();
  400. if ( ERROR_SUCCESS == Status )
  401. {
  402. //
  403. // When doing a fileext/progid/clsid demand install, we don't want to
  404. // set the full install state bit for the first time. This will enable
  405. // the full install option to still be applied at the next foreground
  406. // policy processing.
  407. //
  408. if ( (pAppType->Type != APPNAME) && ! (pAppInfo->_State & APPSTATE_INSTALL) )
  409. pAppInfo->_ActFlags &= ~ACTFLG_InstallUserAssign;
  410. pAppInfo->InitializePass0();
  411. pAppInfo->SetActionPass1();
  412. pAppInfo->SetActionPass2();
  413. pAppInfo->SetActionPass3();
  414. pAppInfo->SetActionPass4();
  415. Status = pAppInfo->_Status;
  416. }
  417. pManApp->Revert();
  418. if ( ERROR_SUCCESS == Status )
  419. {
  420. bStatus = pAppInfo->CopyToApplicationInfo( pInstallInfo );
  421. if ( ! bStatus )
  422. Status = ERROR_OUTOFMEMORY;
  423. }
  424. if ( Status != ERROR_SUCCESS )
  425. goto InstallAppExit;
  426. for ( pManApp->AppList().Reset(), pUpgradedApp = (CAppInfo *) pManApp->AppList().GetCurrentItem();
  427. pUpgradedApp;
  428. pManApp->AppList().MoveNext(), pUpgradedApp = (CAppInfo *) pManApp->AppList().GetCurrentItem() )
  429. {
  430. APPLICATION_INFO * pOldApplicationInfo;
  431. bStatus = FALSE;
  432. if ( (pUpgradedApp->_Action != ACTION_UNINSTALL) && (pUpgradedApp->_Action != ACTION_ORPHAN) )
  433. continue;
  434. pOldApplicationInfo = pUninstallApps->ApplicationInfo;
  435. pUninstallApps->ApplicationInfo = (APPLICATION_INFO *) LocalAlloc( 0, (pUninstallApps->Products + 1) * sizeof(APPLICATION_INFO) );
  436. if ( pUninstallApps->ApplicationInfo )
  437. {
  438. if ( pOldApplicationInfo )
  439. memcpy( pUninstallApps->ApplicationInfo, pOldApplicationInfo, pUninstallApps->Products * sizeof(APPLICATION_INFO) );
  440. bStatus = pUpgradedApp->CopyToApplicationInfo( &pUninstallApps->ApplicationInfo[pUninstallApps->Products] );
  441. }
  442. LocalFree( pOldApplicationInfo );
  443. if ( ! bStatus )
  444. {
  445. pUninstallApps->Products = 0;
  446. Status = ERROR_OUTOFMEMORY;
  447. goto InstallAppExit;
  448. }
  449. else
  450. {
  451. pUninstallApps->Products++;
  452. }
  453. }
  454. pManApp->AppList().ResetEnd();
  455. //
  456. // If we're doing a progid, file extension, or clsid based activation, we search
  457. // for the specific Darwin identifier.
  458. //
  459. if ( pAppType->Type != APPNAME )
  460. {
  461. const DWORD dwMaxStrLen = 128;
  462. HKEY hkPolicy;
  463. HKEY hkClasses;
  464. HKEY hkProgId;
  465. HKEY hkScratch;
  466. WCHAR wszScratch[dwMaxStrLen];
  467. WCHAR wszDarwinId[128];
  468. WCHAR * pwszProgId;
  469. DWORD ScriptFlags;
  470. hkPolicy = 0;
  471. hkClasses = 0;
  472. wszDarwinId[0] = 0;
  473. Status = RegOpenKeyEx(
  474. hkRoot,
  475. POLICYKEY,
  476. 0,
  477. KEY_ALL_ACCESS,
  478. &hkPolicy );
  479. if ( ERROR_SUCCESS == Status )
  480. {
  481. //
  482. // We can use a fixed temp name since we are in a crit sec here. This
  483. // key must be non volatile since that is how Darwin will do all of
  484. // their creates under this key.
  485. //
  486. Status = RegCreateKeyEx(
  487. hkPolicy,
  488. L"TempClasses",
  489. 0,
  490. NULL,
  491. REG_OPTION_NON_VOLATILE,
  492. KEY_ALL_ACCESS,
  493. NULL,
  494. &hkClasses,
  495. NULL );
  496. }
  497. if ( ERROR_SUCCESS == Status )
  498. {
  499. Status = pManApp->Impersonate();
  500. if ( ERROR_SUCCESS == Status )
  501. {
  502. Status = pAppInfo->CopyScriptIfNeeded();
  503. pManApp->Revert();
  504. }
  505. }
  506. if ( ERROR_SUCCESS == Status )
  507. {
  508. //
  509. // Must include the MACHINEASSIGN flag since we are not impersonating.
  510. // That's a little quirk in the semantics of the Msi API.
  511. //
  512. ScriptFlags = SCRIPTFLAGS_MACHINEASSIGN;
  513. //
  514. // In the progid case we need to advertise both extension and class data.
  515. // This is because different progids are registered in these two
  516. // cases and we want to catch both. In the former case they are progids
  517. // associated with file extensions and in the latter case with clsids.
  518. //
  519. if ( (FILEEXT == pAppType->Type) || (PROGID == pAppType->Type) )
  520. ScriptFlags |= SCRIPTFLAGS_REGDATA_EXTENSIONINFO;
  521. if ( (PROGID == pAppType->Type) || (COMCLASS == pAppType->Type) )
  522. ScriptFlags |= SCRIPTFLAGS_REGDATA_CLASSINFO;
  523. Status = (*gpfnMsiAdvertiseScript)(
  524. pAppInfo->LocalScriptPath(),
  525. ScriptFlags,
  526. &hkClasses,
  527. FALSE );
  528. }
  529. if ( Status != ERROR_SUCCESS )
  530. {
  531. gpEvents->Install(
  532. Status,
  533. pAppInfo);
  534. goto InstallAppDescriptorAbort;
  535. }
  536. //
  537. // Now we grovel our temporary registry dump for a darwin id under the
  538. // class info that was requested.
  539. //
  540. if ( pAppType->Type != COMCLASS )
  541. {
  542. //
  543. // Looking for a shell-open command verb. First figure out the
  544. // ProgID.
  545. //
  546. if ( FILEEXT == pAppType->Type )
  547. {
  548. Status = RegOpenKeyEx(
  549. hkClasses,
  550. pAppType->uType.FileExt,
  551. 0,
  552. KEY_ALL_ACCESS,
  553. &hkScratch );
  554. Size = sizeof(wszScratch);
  555. if ( ERROR_SUCCESS == Status )
  556. {
  557. Status = RegQueryValueEx(
  558. hkScratch,
  559. L"",
  560. NULL,
  561. NULL,
  562. (PBYTE) wszScratch,
  563. &Size );
  564. RegCloseKey( hkScratch );
  565. }
  566. pwszProgId = wszScratch;
  567. }
  568. else
  569. {
  570. pwszProgId = pAppType->uType.ProgId;
  571. }
  572. if ( ERROR_SUCCESS == Status )
  573. {
  574. Status = RegOpenKeyEx(
  575. hkClasses,
  576. pwszProgId,
  577. 0,
  578. KEY_ALL_ACCESS,
  579. &hkProgId );
  580. }
  581. if ( ERROR_SUCCESS == Status )
  582. {
  583. Status = RegOpenKeyEx(
  584. hkProgId,
  585. L"shell\\open\\command",
  586. 0,
  587. KEY_ALL_ACCESS,
  588. &hkScratch );
  589. RegCloseKey( hkProgId );
  590. }
  591. Size = sizeof(wszDarwinId);
  592. if ( ERROR_SUCCESS == Status )
  593. {
  594. Status = RegQueryValueEx(
  595. hkScratch,
  596. L"command",
  597. NULL,
  598. NULL,
  599. (PBYTE) wszDarwinId,
  600. &Size );
  601. if ( (ERROR_SUCCESS == Status) && DebugLevelOn( DM_VERBOSE ) )
  602. {
  603. DebugMsg((DM_VERBOSE, IDS_PROGID_FOUND, pwszProgId));
  604. }
  605. RegCloseKey( hkScratch );
  606. }
  607. }
  608. else // COMCLASS == pAppType->Type
  609. {
  610. //
  611. // Looking for a com clsid. We check both the inproc & localserver
  612. // keys if those clsctx bits are set.
  613. //
  614. hr = StringCchCopy( wszScratch, dwMaxStrLen, L"CLSID\\" );
  615. if (FAILED(hr))
  616. {
  617. Status = HRESULT_CODE(hr);
  618. goto InstallAppDescriptorAbort;
  619. }
  620. hr = StringCchCopy( &wszScratch[6], dwMaxStrLen-6, wszGuid );
  621. if (FAILED(hr))
  622. {
  623. Status = HRESULT_CODE(hr);
  624. goto InstallAppDescriptorAbort;
  625. }
  626. if ( pAppType->uType.COMClass.ClsCtx & CLSCTX_INPROC_SERVER )
  627. {
  628. hr = StringCchCopy( &wszScratch[6+GUIDSTRLEN], dwMaxStrLen-(6+GUIDSTRLEN),L"\\InprocServer32" );
  629. if (FAILED(hr))
  630. {
  631. Status = HRESULT_CODE(hr);
  632. goto InstallAppDescriptorAbort;
  633. }
  634. Status = RegOpenKeyEx(
  635. hkClasses,
  636. wszScratch,
  637. 0,
  638. KEY_ALL_ACCESS,
  639. &hkScratch );
  640. Size = sizeof(wszDarwinId);
  641. if ( ERROR_SUCCESS == Status )
  642. {
  643. Status = RegQueryValueEx(
  644. hkScratch,
  645. L"InprocServer32",
  646. NULL,
  647. NULL,
  648. (PBYTE) wszDarwinId,
  649. &Size );
  650. if ( ERROR_SUCCESS == Status )
  651. DebugMsg((DM_VERBOSE, IDS_CLSID_INPROC_FOUND));
  652. RegCloseKey( hkScratch );
  653. }
  654. }
  655. if ( (0 == wszDarwinId[0]) && (pAppType->uType.COMClass.ClsCtx & CLSCTX_LOCAL_SERVER) )
  656. {
  657. hr = StringCchCopy( &wszScratch[6+GUIDSTRLEN], dwMaxStrLen-(6+GUIDSTRLEN),L"\\LocalServer32" );
  658. if (FAILED(hr))
  659. {
  660. Status = HRESULT_CODE(hr);
  661. goto InstallAppDescriptorAbort;
  662. }
  663. Status = RegOpenKeyEx(
  664. hkClasses,
  665. wszScratch,
  666. 0,
  667. KEY_ALL_ACCESS,
  668. &hkScratch );
  669. Size = sizeof(wszDarwinId);
  670. if ( ERROR_SUCCESS == Status )
  671. {
  672. Status = RegQueryValueEx(
  673. hkScratch,
  674. L"LocalServer32",
  675. NULL,
  676. NULL,
  677. (PBYTE) wszDarwinId,
  678. &Size );
  679. if ( ERROR_SUCCESS == Status )
  680. DebugMsg((DM_VERBOSE, IDS_CLSID_LOCAL_FOUND));
  681. RegCloseKey( hkScratch );
  682. }
  683. }
  684. }
  685. //
  686. // We're done with the temp reg data, so blow it away now.
  687. //
  688. // Must include the MACHINEASSIGN flag since we are not impersonating.
  689. //
  690. (void) (*gpfnMsiAdvertiseScript)(
  691. pAppInfo->LocalScriptPath(),
  692. ScriptFlags,
  693. &hkClasses,
  694. TRUE );
  695. InstallAppDescriptorAbort:
  696. if ( hkClasses )
  697. {
  698. RegCloseKey( hkClasses );
  699. RegDeleteKey( hkPolicy, L"TempClasses" );
  700. }
  701. if ( hkPolicy )
  702. RegCloseKey( hkPolicy );
  703. if ( ERROR_SUCCESS == Status )
  704. {
  705. pInstallInfo->pwszDescriptor = (PWCHAR) LocalAlloc( 0, (lstrlen(wszDarwinId) + 1) * sizeof(WCHAR) );
  706. if ( pInstallInfo->pwszDescriptor )
  707. {
  708. hr = StringCchCopy( pInstallInfo->pwszDescriptor,lstrlen(wszDarwinId) + 1, wszDarwinId );
  709. if (FAILED(hr))
  710. {
  711. Status = HRESULT_CODE(hr);
  712. }
  713. }
  714. else
  715. Status = ERROR_OUTOFMEMORY;
  716. }
  717. //
  718. // If we fail to find a darwin id under the specific class data that
  719. // was requested, then we fall back to doing a full product based
  720. // install. Since the DS query succeeded, we have a valid app, but
  721. // there just isn't any darwin id registered for the specific class
  722. // data in the advertisement data.
  723. //
  724. // This could be a packaging problem, limitation, or design.
  725. //
  726. } // if ( pAppType->Type != APPNAME )
  727. if ( (ERROR_SUCCESS == Status) && (pAppInfo->_State & APPSTATE_SCRIPT_NOT_EXISTED) )
  728. {
  729. SetSystemRestorePoint( pAppInfo->_pwszDeploymentName, pAppContext );
  730. }
  731. InstallAppExit:
  732. if ( bEnterCritSec )
  733. RtlLeaveCriticalSection( &gAppCS );
  734. if ( Status != ERROR_SUCCESS )
  735. {
  736. for ( ; pUninstallApps->Products; )
  737. FreeApplicationInfo( &pUninstallApps->ApplicationInfo[--pUninstallApps->Products] );
  738. LocalFree( pUninstallApps->ApplicationInfo );
  739. pUninstallApps->Products = 0;
  740. pUninstallApps->ApplicationInfo = 0;
  741. FreeApplicationInfo( pInstallInfo );
  742. memset( pInstallInfo, 0, sizeof(APPLICATION_INFO) );
  743. if ( pManApp )
  744. {
  745. if ( pAppInfo )
  746. {
  747. //
  748. // Since this call has failed, the client will not call
  749. // the InstallEnd method to log the failure, so we must
  750. // log the failure in this call
  751. //
  752. (void) LogRsopInstallData( pManApp, pAppInfo );
  753. }
  754. delete pManApp;
  755. }
  756. if ( pAppInfo )
  757. delete pAppInfo;
  758. if ( pAppContext )
  759. {
  760. delete pAppContext->pLoadMsi;
  761. delete pAppContext;
  762. }
  763. }
  764. else
  765. {
  766. *ppInstallContext = pAppContext;
  767. }
  768. if ( ((long)Status) > 0 )
  769. DebugMsg((DM_VERBOSE, IDS_INSTALL_STATUS1, Status));
  770. else
  771. DebugMsg((DM_VERBOSE, IDS_INSTALL_STATUS2, Status));
  772. gpEvents->ClearToken();
  773. if ( hUserToken )
  774. CloseHandle( hUserToken );
  775. if ( hkRoot )
  776. RegCloseKey( hkRoot );
  777. if ( pGPOList )
  778. FreeGPOList( pGPOList );
  779. ReleasePackageInfo( &PackageInfo );
  780. return Status;
  781. }
  782. error_status_t
  783. InstallManageApp(
  784. IN PINSTALLCONTEXT pInstallContext,
  785. IN PWSTR pwszDeploymentId,
  786. IN DWORD RollbackStatus,
  787. OUT boolean * pbInstall
  788. )
  789. {
  790. PAPPCONTEXT pAppContext;
  791. CAppInfo * pAppInfo;
  792. GUID DeploymentId;
  793. DWORD Status;
  794. *pbInstall = FALSE;
  795. pAppContext = (PAPPCONTEXT) pInstallContext;
  796. StringToGuid( pwszDeploymentId, &DeploymentId );
  797. Status = pAppContext->pManApp->Impersonate();
  798. if ( Status != ERROR_SUCCESS )
  799. return Status;
  800. gpEvents->SetToken( pAppContext->pManApp->UserToken() );
  801. if ( memcmp( &DeploymentId, &pAppContext->pAppInfo->_DeploymentId, sizeof(GUID) ) == 0 )
  802. {
  803. pAppContext->bUninstallsCompleted = TRUE;
  804. Status = pAppContext->pAppInfo->ProcessApplyActions();
  805. if ( ERROR_SUCCESS == Status )
  806. {
  807. if ( pAppContext->pManApp->GetRsopContext()->IsRsopEnabled() && pAppContext->pManApp->GetRsopContext()->IsDiagnosticModeEnabled() )
  808. Status = pAppContext->pAppInfo->ProcessTransformConflicts();
  809. }
  810. goto InstallManageAppEnd;
  811. }
  812. for ( pAppContext->pManApp->AppList().Reset();
  813. pAppInfo = (CAppInfo *) pAppContext->pManApp->AppList().GetCurrentItem();
  814. pAppContext->pManApp->AppList().MoveNext() )
  815. {
  816. if ( memcmp( &DeploymentId, &pAppInfo->_DeploymentId, sizeof(GUID) ) == 0 )
  817. break;
  818. }
  819. if ( ! pAppInfo )
  820. {
  821. Status = ERROR_NOT_FOUND;
  822. goto InstallManageAppEnd;
  823. }
  824. //
  825. // Re-assigning one of the upgraded apps because of a failed upgrade. Not needed for
  826. // apps orphaned during the upgrade.
  827. //
  828. if ( ACTION_UNINSTALL == pAppInfo->_Action )
  829. {
  830. DWORD ScriptFlags = SCRIPTFLAGS_REGDATA_CNFGINFO | SCRIPTFLAGS_CACHEINFO | SCRIPTFLAGS_SHORTCUTS;
  831. *pbInstall = (pAppInfo->_State & APPSTATE_INSTALL) ? 1 : 0;
  832. if ( pAppInfo->_State & APPSTATE_ASSIGNED )
  833. ScriptFlags |= SCRIPTFLAGS_REGDATA_EXTENSIONINFO;
  834. Status = pAppInfo->Assign( ScriptFlags, TRUE, FALSE );
  835. //
  836. // Record an event so that we can track this as an RSoP failed setting if
  837. // necessary
  838. //
  839. if ( ERROR_SUCCESS != Status )
  840. {
  841. gpEvents->Assign( Status, pAppInfo );
  842. }
  843. }
  844. //
  845. // Remember that this application was rolled back
  846. //
  847. pAppInfo->_bRollback = TRUE;
  848. gpEvents->UpgradeAbort( RollbackStatus, pAppContext->pAppInfo, pAppInfo, ! pAppContext->bUninstallsCompleted );
  849. InstallManageAppEnd:
  850. gpEvents->ClearToken();
  851. pAppContext->pManApp->Revert();
  852. return Status;
  853. }
  854. error_status_t
  855. InstallUnmanageApp(
  856. IN PINSTALLCONTEXT pInstallContext,
  857. IN PWSTR pwszDeploymentId,
  858. IN boolean bUnadvertiseOnly
  859. )
  860. {
  861. PAPPCONTEXT pAppContext;
  862. CAppInfo * pAppInfo;
  863. GUID DeploymentId;
  864. DWORD Status;
  865. pAppContext = (PAPPCONTEXT) pInstallContext;
  866. StringToGuid( pwszDeploymentId, &DeploymentId );
  867. Status = pAppContext->pManApp->Impersonate();
  868. if ( Status != ERROR_SUCCESS )
  869. goto InstallUnmanageAppRemoveScript;
  870. gpEvents->SetToken( pAppContext->pManApp->UserToken() );
  871. if ( memcmp( &DeploymentId, &pAppContext->pAppInfo->_DeploymentId, sizeof(GUID) ) == 0 )
  872. {
  873. Status = pAppContext->pAppInfo->Unassign( SCRIPTFLAGS_REGDATA_CNFGINFO | SCRIPTFLAGS_CACHEINFO, TRUE );
  874. //
  875. // Record an event so that we can track this as an RSoP failed setting if
  876. // necessary
  877. //
  878. if ( ERROR_SUCCESS != Status )
  879. {
  880. gpEvents->Unassign( Status, pAppContext->pAppInfo );
  881. }
  882. goto InstallUnmanageAppEnd;
  883. }
  884. for ( pAppContext->pManApp->AppList().Reset();
  885. pAppInfo = (CAppInfo *) pAppContext->pManApp->AppList().GetCurrentItem();
  886. pAppContext->pManApp->AppList().MoveNext() )
  887. {
  888. if ( memcmp( &DeploymentId, &pAppInfo->_DeploymentId, sizeof(GUID) ) == 0 )
  889. break;
  890. }
  891. if ( ! pAppInfo )
  892. {
  893. Status = ERROR_NOT_FOUND;
  894. goto InstallUnmanageAppEnd;
  895. }
  896. //
  897. // Unassigning one of the upgraded apps.
  898. //
  899. if ( bUnadvertiseOnly )
  900. {
  901. Status = pAppInfo->Unassign( SCRIPTFLAGS_REGDATA_CNFGINFO | SCRIPTFLAGS_CACHEINFO | SCRIPTFLAGS_SHORTCUTS | SCRIPTFLAGS_REGDATA_EXTENSIONINFO, FALSE );
  902. }
  903. else
  904. {
  905. Status = pAppInfo->Unassign( 0, TRUE );
  906. //
  907. // Record an event so that we can track this as an RSoP failed setting if
  908. // necessary
  909. //
  910. if ( ERROR_SUCCESS != Status )
  911. {
  912. gpEvents->Unassign( Status, pAppInfo );
  913. }
  914. gpEvents->UpgradeComplete( pAppContext->pAppInfo, pAppInfo );
  915. }
  916. InstallUnmanageAppEnd:
  917. gpEvents->ClearToken();
  918. pAppContext->pManApp->Revert();
  919. InstallUnmanageAppRemoveScript:
  920. //
  921. // Be sure to remove the script for a failed upgrade app
  922. //
  923. if ( ( ERROR_SUCCESS != Status ) && ! bUnadvertiseOnly )
  924. {
  925. DeleteFile( pAppContext->pAppInfo->_pwszLocalScriptPath );
  926. }
  927. return Status;
  928. }
  929. error_status_t
  930. InstallEnd(
  931. IN boolean bStatus,
  932. IN OUT PINSTALLCONTEXT * ppInstallContext
  933. )
  934. {
  935. //
  936. // We are done installing -- now log the results
  937. //
  938. if ( ppInstallContext && *ppInstallContext )
  939. {
  940. PAPPCONTEXT pAppContext;
  941. CManagedAppProcessor* pManApp;
  942. pAppContext = (PAPPCONTEXT) *ppInstallContext;
  943. if ( pAppContext )
  944. pAppContext->bStatus = (boolean) bStatus;
  945. pManApp = pAppContext->pManApp;
  946. if ( pManApp && pAppContext )
  947. {
  948. (void) LogRsopInstallData( pManApp, pAppContext->pAppInfo );
  949. }
  950. }
  951. if ( ppInstallContext )
  952. {
  953. PINSTALLCONTEXT_rundown( *ppInstallContext );
  954. *ppInstallContext = 0;
  955. }
  956. return ERROR_SUCCESS;
  957. }
  958. void
  959. PINSTALLCONTEXT_rundown(
  960. IN PINSTALLCONTEXT pInstallContext
  961. )
  962. {
  963. PAPPCONTEXT pAppContext;
  964. pAppContext = (PAPPCONTEXT) pInstallContext;
  965. if ( pAppContext && (pAppContext->SRSequence != 0) )
  966. {
  967. RESTOREPOINTINFO RestoreInfo;
  968. STATEMGRSTATUS SRStatus;
  969. RestoreInfo.dwEventType = END_NESTED_SYSTEM_CHANGE;
  970. RestoreInfo.dwRestorePtType = pAppContext->bStatus ? 0 : CANCELLED_OPERATION;
  971. RestoreInfo.llSequenceNumber = pAppContext->SRSequence;
  972. RestoreInfo.szDescription[0] = 0;
  973. (void) (*gpfnSRSetRetorePointW)( &RestoreInfo, &SRStatus );
  974. }
  975. //
  976. // If this app failed to be installed, ensure that the status is
  977. // set properly (in upgrade cases, the status for the application may
  978. // not be set. If this status is not set as a failure, the
  979. // application's state (such as the script) may not be set
  980. //
  981. if ( pAppContext && pAppContext->pAppInfo && ! pAppContext->bStatus )
  982. {
  983. pAppContext->pAppInfo->ForceFailureStatus();
  984. }
  985. if (pAppContext)
  986. {
  987. delete pAppContext->pManApp;
  988. delete pAppContext->pAppInfo;
  989. delete pAppContext->pLoadMsi;
  990. if ( pAppContext->pLoadSfc )
  991. delete pAppContext->pLoadSfc;
  992. delete pAppContext;
  993. }
  994. }
  995. DWORD
  996. RemoveAppHelper(
  997. IN WCHAR * ProductCode,
  998. IN HANDLE hUserToken,
  999. IN HKEY hKeyRoot,
  1000. IN DWORD ARPStatus,
  1001. OUT BOOL * pbProductFound
  1002. )
  1003. {
  1004. CAppInfo * pAppInfo;
  1005. CAppInfo * pHighestAssignedApp;
  1006. CAppInfo * pRemovedApp;
  1007. DWORD Status;
  1008. *pbProductFound = FALSE;
  1009. CRsopAppContext RsopContext( CRsopAppContext::REMOVAL );
  1010. CManagedAppProcessor ManApps( hUserToken ? 0 : GPO_INFO_FLAG_MACHINE,
  1011. hUserToken,
  1012. hKeyRoot,
  1013. NULL,
  1014. FALSE,
  1015. FALSE,
  1016. &RsopContext,
  1017. Status );
  1018. if ( ERROR_SUCCESS != Status )
  1019. return Status;
  1020. CAppList LocalApps( NULL, ManApps.GetRsopContext() );
  1021. Status = ManApps.LoadPolicyList();
  1022. if ( ERROR_SUCCESS != Status )
  1023. return Status;
  1024. Status = ManApps.GetOrderedLocalAppList( LocalApps );
  1025. if ( ERROR_SUCCESS == Status )
  1026. Status = ManApps.Impersonate();
  1027. if ( Status != ERROR_SUCCESS )
  1028. return Status;
  1029. pHighestAssignedApp = 0;
  1030. pRemovedApp = 0;
  1031. LocalApps.Reset();
  1032. for ( pAppInfo = (CAppInfo *) LocalApps.GetCurrentItem();
  1033. pAppInfo;
  1034. LocalApps.MoveNext(), pAppInfo = (CAppInfo *) LocalApps.GetCurrentItem() )
  1035. {
  1036. if ( (lstrcmpi( pAppInfo->_pwszProductId, ProductCode ) != 0) ||
  1037. ! (pAppInfo->_State & (APPSTATE_ASSIGNED | APPSTATE_PUBLISHED)) )
  1038. {
  1039. continue;
  1040. }
  1041. pRemovedApp = pAppInfo;
  1042. *pbProductFound = TRUE;
  1043. if ( pAppInfo->_State & APPSTATE_PUBLISHED )
  1044. {
  1045. //
  1046. // We perform no actual unassignments unless ARP actually uninstalled the app
  1047. //
  1048. //
  1049. // We unassign using the same scriptflags we do during assignment
  1050. // to handle cases where the initial install action fails and
  1051. // we are called to undo the original assigment. In normal success
  1052. // cases this is redundant.
  1053. //
  1054. if ( ERROR_SUCCESS == ARPStatus )
  1055. {
  1056. DebugMsg((DM_VERBOSE, IDS_REMOVEAPP_MATCH1, pAppInfo->_pwszDeploymentName, ProductCode));
  1057. pAppInfo->Unassign( SCRIPTFLAGS_REGDATA_CNFGINFO | SCRIPTFLAGS_CACHEINFO | SCRIPTFLAGS_SHORTCUTS | SCRIPTFLAGS_REGDATA_EXTENSIONINFO, TRUE );
  1058. }
  1059. //
  1060. // Set this action for RSOP as a way to remember to log a removal entry for this app
  1061. //
  1062. pAppInfo->SetAction(
  1063. ACTION_UNINSTALL,
  1064. APP_ATTRIBUTE_REMOVALCAUSE_USER,
  1065. NULL);
  1066. }
  1067. else
  1068. {
  1069. //
  1070. // We only reassign if ARP was able to uninstall the app
  1071. //
  1072. if ( ERROR_SUCCESS == ARPStatus )
  1073. {
  1074. DebugMsg((DM_VERBOSE, IDS_REMOVEAPP_MATCH2, pAppInfo->_pwszDeploymentName, ProductCode));
  1075. }
  1076. pHighestAssignedApp = pAppInfo;
  1077. }
  1078. }
  1079. if ( ( ERROR_SUCCESS != ARPStatus ) &&
  1080. pRemovedApp )
  1081. {
  1082. //
  1083. // If ARP failed to uninstall the highest app, log a failure status
  1084. //
  1085. gpEvents->Uninstall(
  1086. ARPStatus,
  1087. pRemovedApp);
  1088. }
  1089. //
  1090. // Reassign the highest priority assigned app with this product id if
  1091. // one exists.
  1092. //
  1093. BOOL bRsopLogReassign;
  1094. bRsopLogReassign = FALSE;
  1095. if ( pHighestAssignedApp )
  1096. {
  1097. //
  1098. // We only reassign the app if it was successfully uninstalled
  1099. //
  1100. if ( ERROR_SUCCESS == ARPStatus )
  1101. {
  1102. Status = pHighestAssignedApp->Assign( SCRIPTFLAGS_REGDATA_CNFGINFO | SCRIPTFLAGS_CACHEINFO | SCRIPTFLAGS_SHORTCUTS | SCRIPTFLAGS_REGDATA_EXTENSIONINFO, TRUE, FALSE );
  1103. if ( Status != ERROR_SUCCESS )
  1104. gpEvents->Assign( Status, pHighestAssignedApp );
  1105. }
  1106. if ( ManApps.GetRsopContext()->IsRsopEnabled() )
  1107. {
  1108. //
  1109. // Remember to write a removal entry for this reassigned app if it
  1110. // was the app that was removed
  1111. //
  1112. bRsopLogReassign = ( pHighestAssignedApp == pRemovedApp );
  1113. }
  1114. }
  1115. ManApps.Revert();
  1116. //
  1117. // We must log rsop data after we revert because the user may not have
  1118. // access to her own rsop namespace
  1119. //
  1120. //
  1121. // Obtain exclusive access to log data -- this will disable rsop
  1122. // if implicit access cannot be obtained
  1123. //
  1124. (void) ManApps.GetRsopContext()->GetExclusiveLoggingAccess( NULL == hUserToken );
  1125. if ( ManApps.GetRsopContext()->IsRsopEnabled() )
  1126. {
  1127. //
  1128. // Now log all the uninstalled published apps which would have been marked above
  1129. // as having the action to uninstall
  1130. //
  1131. (void) LocalApps.WriteLog( CAppList::RSOP_FILTER_REMOVALSONLY );
  1132. //
  1133. // Now log the highest reassigned app
  1134. //
  1135. if ( bRsopLogReassign )
  1136. {
  1137. //
  1138. // Log the actual uninstall entry
  1139. //
  1140. (void) LocalApps.MarkRSOPEntryAsRemoved( pHighestAssignedApp, FALSE );
  1141. }
  1142. else if ( pHighestAssignedApp )
  1143. {
  1144. //
  1145. // We need to write a new entry for the assigned app that was not previously
  1146. // applied but is now due to the fact that the higher precedence application
  1147. // was removed
  1148. //
  1149. (void) LocalApps.WriteAppToRsopLog( pHighestAssignedApp );
  1150. }
  1151. }
  1152. (void) ManApps.GetRsopContext()->ReleaseExclusiveLoggingAccess();
  1153. //
  1154. // Whenever the user does an app uninstall, we force a full run of policy
  1155. // during the next logon to pick up any app that should now apply. Note that
  1156. // later we use a gp engine api to do this due to the NT 5.1 foreground async
  1157. // gp refresh feature, but for compatibility with NT 5.0 (roaming), we must
  1158. // continue to set our own registry value
  1159. //
  1160. if ( *pbProductFound && hUserToken )
  1161. {
  1162. Status = RegSetValueEx(
  1163. ManApps.AppmgmtKey(),
  1164. FULLPOLICY,
  1165. 0,
  1166. REG_DWORD,
  1167. (LPBYTE) pbProductFound,
  1168. sizeof(*pbProductFound) );
  1169. //
  1170. // Ensure that if async policy is enabled, we get a synchronous refresh at
  1171. // the next logon
  1172. //
  1173. if ( ERROR_SUCCESS == Status )
  1174. {
  1175. Status = ForceSynchronousRefresh( ManApps.UserToken() );
  1176. }
  1177. }
  1178. return Status;
  1179. }
  1180. error_status_t
  1181. ARPRemoveApp(
  1182. IN handle_t hRpc,
  1183. IN WCHAR * pwszProductCode,
  1184. IN DWORD ARPStatus
  1185. )
  1186. {
  1187. HANDLE hUserToken;
  1188. HKEY hKeyRoot;
  1189. DWORD Status;
  1190. BOOL bStatus;
  1191. BOOL bProductFound;
  1192. CheckLocalCall( hRpc );
  1193. hUserToken = NULL;
  1194. hKeyRoot = NULL;
  1195. bProductFound = FALSE;
  1196. CLoadMsi LoadMsi( Status );
  1197. if ( ERROR_SUCCESS == Status )
  1198. Status = RpcImpersonateClient( NULL );
  1199. if ( ERROR_SUCCESS == Status )
  1200. {
  1201. Status = RegOpenCurrentUser( GENERIC_ALL, &hKeyRoot );
  1202. if ( ERROR_SUCCESS == Status )
  1203. {
  1204. bStatus = OpenThreadToken(
  1205. GetCurrentThread(),
  1206. TOKEN_READ | TOKEN_IMPERSONATE | TOKEN_DUPLICATE,
  1207. TRUE,
  1208. &hUserToken );
  1209. if ( ! bStatus )
  1210. {
  1211. Status = GetLastError();
  1212. RegCloseKey( hKeyRoot );
  1213. }
  1214. }
  1215. RevertToSelf();
  1216. }
  1217. if ( Status != ERROR_SUCCESS )
  1218. return Status;
  1219. gpEvents->SetToken( hUserToken );
  1220. LogTime();
  1221. DebugMsg((DM_VERBOSE, IDS_REMOVEAPP, pwszProductCode));
  1222. Status = RemoveAppHelper( pwszProductCode, hUserToken, hKeyRoot, ARPStatus, &bProductFound );
  1223. if ( ! bProductFound )
  1224. {
  1225. if ( IsMemberOfAdminGroup( hUserToken ) )
  1226. Status = RemoveAppHelper( pwszProductCode, NULL, HKEY_LOCAL_MACHINE, ARPStatus, &bProductFound );
  1227. }
  1228. DebugMsg((DM_VERBOSE, IDS_REMOVEAPP_STATUS, Status));
  1229. gpEvents->ClearToken();
  1230. if ( hUserToken )
  1231. CloseHandle( hUserToken );
  1232. if ( hKeyRoot )
  1233. RegCloseKey( hKeyRoot );
  1234. return Status;
  1235. }
  1236. error_status_t
  1237. GetManagedApps(
  1238. IN handle_t hRpc,
  1239. IN GUID * pCategory,
  1240. IN DWORD dwQueryFlags,
  1241. IN DWORD dwInfoLevel,
  1242. OUT MANAGED_APPLIST * pAppList
  1243. )
  1244. {
  1245. HANDLE hUserToken;
  1246. HANDLE hEventAppsEnumerated;
  1247. error_status_t Status;
  1248. BOOL bStatus;
  1249. CheckLocalCall( hRpc );
  1250. hUserToken = NULL;
  1251. hEventAppsEnumerated = NULL;
  1252. if ( ! pAppList )
  1253. return ERROR_INVALID_PARAMETER;
  1254. //
  1255. // Clear this structure so that random
  1256. // garbage doesn't get marshalled back.
  1257. //
  1258. memset(pAppList, 0, sizeof(*pAppList));
  1259. //
  1260. // Validate the parameters passed in by the client.
  1261. //
  1262. if ( dwInfoLevel != MANAGED_APPS_INFOLEVEL_DEFAULT )
  1263. return ERROR_INVALID_PARAMETER;
  1264. switch (dwQueryFlags)
  1265. {
  1266. case MANAGED_APPS_USERAPPLICATIONS:
  1267. if (pCategory)
  1268. return ERROR_INVALID_PARAMETER;
  1269. break;
  1270. case MANAGED_APPS_FROMCATEGORY:
  1271. if (!pCategory)
  1272. return ERROR_INVALID_PARAMETER;
  1273. break;
  1274. default:
  1275. return ERROR_INVALID_PARAMETER;
  1276. }
  1277. //
  1278. // Now prepare to initiate the query -- first
  1279. // we need to get some user specific information
  1280. // to build the object which performs the query,
  1281. // so we impersonate.
  1282. //
  1283. Status = RpcImpersonateClient( NULL );
  1284. if ( Status != ERROR_SUCCESS )
  1285. return Status;
  1286. bStatus = OpenThreadToken(
  1287. GetCurrentThread(),
  1288. TOKEN_READ | TOKEN_IMPERSONATE | TOKEN_DUPLICATE,
  1289. TRUE,
  1290. &hUserToken );
  1291. if ( ! bStatus )
  1292. Status = GetLastError();
  1293. RevertToSelf();
  1294. if ( Status != ERROR_SUCCESS )
  1295. goto GetManagedAppsExit;
  1296. //
  1297. // We will create a separate thread to retrieve the ARP apps -- this allows
  1298. // this thread to wait for a signal from the ARP thread that app enumeration is done,
  1299. // and we can return the list at that point. The second thread will continue to
  1300. // execute since it needs to log rsop data -- this approach frees us from having to
  1301. // wait for rsop logging, which can take 10 times longer than it took us to retrieve
  1302. // the apps from the ds
  1303. //
  1304. //
  1305. // Below we create the event that the enumeration thread will use to signal this
  1306. // thread that enumeration is finished.
  1307. //
  1308. hEventAppsEnumerated = CreateEvent(
  1309. NULL,
  1310. TRUE, // manual reset
  1311. FALSE, // initially nonsignaled
  1312. NULL);
  1313. if ( ! hEventAppsEnumerated )
  1314. {
  1315. Status = GetLastError();
  1316. goto GetManagedAppsExit;
  1317. }
  1318. //
  1319. // We allocate a structure to pass to the enumeration thread containing all the
  1320. // context it needs to enumerate apps. Note that this structure is stack allocated,
  1321. // so the enumeration thread may only access it as long as this thread lives -- once
  1322. // it signals us that enumeration is complete, it may no longer access this structure
  1323. //
  1324. ARPCONTEXT ArpContext;
  1325. ArpContext.pCategory = pCategory;
  1326. ArpContext.pAppList = pAppList;
  1327. ArpContext.hUserToken = hUserToken;
  1328. ArpContext.hEventAppsEnumerated = hEventAppsEnumerated;
  1329. ArpContext.Status = ERROR_SUCCESS; // out parameter for the second thread to indicate status
  1330. HANDLE hThread;
  1331. hThread = CreateThread(
  1332. NULL,
  1333. 0,
  1334. GetManagedAppsProc,
  1335. &ArpContext,
  1336. 0,
  1337. NULL);
  1338. if ( ! hThread )
  1339. Status = GetLastError();
  1340. if ( ERROR_SUCCESS != Status )
  1341. goto GetManagedAppsExit;
  1342. //
  1343. // Wait for enumeration in the second thread to complete, or
  1344. // for the second thread itself to complete
  1345. //
  1346. HANDLE rgTasks[] = { hEventAppsEnumerated, hThread };
  1347. (void) WaitForMultipleObjects(
  1348. sizeof(rgTasks) / sizeof(*rgTasks),
  1349. rgTasks,
  1350. FALSE,
  1351. INFINITE);
  1352. //
  1353. // Retrieve the enumeration thread's status
  1354. //
  1355. Status = ArpContext.Status;
  1356. //
  1357. // Because tests assume they can check RSoP data as soon as
  1358. // the api has completed, if the tests are waiting for policy
  1359. // events to be signaled already, we'll also wait for rsop to finish
  1360. //
  1361. if ( gDebugLevel & DL_EVENT )
  1362. {
  1363. (void) WaitForSingleObject( hThread, INFINITE );
  1364. }
  1365. CloseHandle( hThread );
  1366. GetManagedAppsExit:
  1367. if ( hUserToken )
  1368. CloseHandle( hUserToken );
  1369. if ( hEventAppsEnumerated )
  1370. CloseHandle( hEventAppsEnumerated );
  1371. return Status;
  1372. }
  1373. error_status_t
  1374. RsopReportInstallFailure(
  1375. IN PINSTALLCONTEXT pInstallContext,
  1376. IN PWSTR pwszDeploymentId,
  1377. IN DWORD dwEventId
  1378. )
  1379. {
  1380. GUID DeploymentId;
  1381. PAPPCONTEXT pAppContext;
  1382. CManagedAppProcessor* pManApp;
  1383. CAppInfo* pAppInfo;
  1384. pAppContext = (PAPPCONTEXT) pInstallContext;
  1385. pManApp = pAppContext->pManApp;
  1386. if ( ! pManApp || ! pManApp->GetRsopContext()->IsDiagnosticModeEnabled() )
  1387. {
  1388. return ERROR_SUCCESS;
  1389. }
  1390. //
  1391. // Assume that the failure happened in the app that
  1392. // we're trying to install
  1393. //
  1394. pAppInfo = pAppContext->pAppInfo;
  1395. if ( ! pAppInfo )
  1396. {
  1397. return ERROR_SUCCESS;
  1398. }
  1399. StringToGuid( pwszDeploymentId, &DeploymentId );
  1400. //
  1401. // Check to see if the failure was in the app that we're
  1402. // trying to install
  1403. //
  1404. if ( ! IsEqualGUID( pAppInfo->DeploymentId(), DeploymentId ) )
  1405. {
  1406. //
  1407. // If not, see if the requested app is one of the apps
  1408. // that was uninstalled before trying to apply the
  1409. // target app, or was reinstalled as part of a rollback
  1410. // from failure
  1411. //
  1412. pAppInfo = pManApp->AppList().Find( DeploymentId );
  1413. if ( pAppInfo )
  1414. {
  1415. //
  1416. // The failure happened during an uninstall for
  1417. // a rip and replace upgrade, so we need to
  1418. // log a failure for the upgrade as well
  1419. //
  1420. pAppContext->pAppInfo->SetRsopFailureStatus(
  1421. ERROR_GEN_FAILURE,
  1422. dwEventId);
  1423. }
  1424. }
  1425. //
  1426. // If we found the app requested by the caller, log a failure
  1427. // status for it -- the error we pass to the method is only
  1428. // used as a check against ERROR_SUCCESS, so we do not
  1429. // need to pass the actual error that occurred
  1430. //
  1431. if ( pAppInfo )
  1432. {
  1433. pAppInfo->SetRsopFailureStatus(
  1434. ERROR_GEN_FAILURE,
  1435. dwEventId);
  1436. }
  1437. return ERROR_SUCCESS;
  1438. }
  1439. error_status_t
  1440. GetManagedAppCategories(
  1441. IN handle_t hRpc,
  1442. IN OUT APPCATEGORYLIST* pCategoryList
  1443. )
  1444. {
  1445. DWORD Status;
  1446. HRESULT hr;
  1447. APPCATEGORYINFOLIST AppCategories;
  1448. HANDLE hUserToken;
  1449. HKEY hkRoot;
  1450. CheckLocalCall( hRpc );
  1451. hr = S_OK;
  1452. hUserToken = NULL;
  1453. hkRoot = NULL;
  1454. memset( pCategoryList, 0, sizeof( *pCategoryList ) );
  1455. memset( &AppCategories, 0, sizeof( AppCategories ) );
  1456. //
  1457. // Now prepare to initiate the query -- first
  1458. // we need to get some user specific information
  1459. // to build the object which performs the query,
  1460. // so we impersonate.
  1461. //
  1462. Status = RpcImpersonateClient( NULL );
  1463. if ( ERROR_SUCCESS != Status )
  1464. return Status;
  1465. BOOL bStatus;
  1466. bStatus = OpenThreadToken(
  1467. GetCurrentThread(),
  1468. TOKEN_READ | TOKEN_IMPERSONATE | TOKEN_DUPLICATE,
  1469. TRUE,
  1470. &hUserToken );
  1471. if ( ! bStatus )
  1472. Status = GetLastError();
  1473. if ( ERROR_SUCCESS == Status )
  1474. Status = RegOpenCurrentUser( GENERIC_ALL, &hkRoot );
  1475. if ( ERROR_SUCCESS == Status )
  1476. hr = CsGetAppCategories( &AppCategories );
  1477. RevertToSelf();
  1478. if ( ( ERROR_SUCCESS != Status ) || FAILED( hr ) )
  1479. goto GetManagedAppCategoriesExit;
  1480. gpEvents->SetToken( hUserToken );
  1481. //
  1482. // The rpc interface is such that our out parameter is just
  1483. // one allocation -- references within each array element are allocated
  1484. // within the block, so we must first calculate how big the block is
  1485. //
  1486. if ( SUCCEEDED( hr ) )
  1487. {
  1488. DWORD cbSize;
  1489. DWORD iCat;
  1490. cbSize = sizeof( APPCATEGORY ) * AppCategories.cCategory;
  1491. for (iCat = 0; iCat < AppCategories.cCategory; iCat++)
  1492. {
  1493. cbSize += ( lstrlen( AppCategories.pCategoryInfo[iCat].pszDescription ) + 1 ) *
  1494. sizeof( WCHAR );
  1495. }
  1496. pCategoryList->pCategoryInfo = (APPCATEGORY*) midl_user_allocate( cbSize );
  1497. if ( ! pCategoryList->pCategoryInfo )
  1498. {
  1499. hr = E_OUTOFMEMORY;
  1500. }
  1501. }
  1502. //
  1503. // Now that we have sufficient memory, we can copy the data
  1504. //
  1505. if ( SUCCEEDED( hr ) )
  1506. {
  1507. WCHAR* wszDescriptions;
  1508. DWORD iCat;
  1509. wszDescriptions = (WCHAR*) &( pCategoryList->pCategoryInfo[ AppCategories.cCategory ] );
  1510. pCategoryList->cCategory = AppCategories.cCategory;
  1511. for (iCat = 0; iCat < AppCategories.cCategory; iCat++)
  1512. {
  1513. pCategoryList->pCategoryInfo[ iCat ].Locale = AppCategories.pCategoryInfo[iCat].Locale;
  1514. pCategoryList->pCategoryInfo[ iCat ].AppCategoryId = AppCategories.pCategoryInfo[iCat].AppCategoryId;
  1515. pCategoryList->pCategoryInfo[ iCat ].pszDescription = wszDescriptions;
  1516. hr = StringCchCopy( wszDescriptions,
  1517. lstrlen(AppCategories.pCategoryInfo[iCat].pszDescription)+1,
  1518. AppCategories.pCategoryInfo[iCat].pszDescription );
  1519. if (FAILED(hr))
  1520. {
  1521. break;
  1522. }
  1523. wszDescriptions += lstrlen( wszDescriptions ) + 1;
  1524. }
  1525. }
  1526. //
  1527. // If we have successfully generated results to return to the caller, log
  1528. // those results
  1529. //
  1530. if ( SUCCEEDED( hr ) )
  1531. {
  1532. HRESULT hrLog;
  1533. DWORD StatusLog;
  1534. CRsopAppContext RsopContext( CRsopAppContext::ARPLIST );
  1535. CManagedAppProcessor AppProcessor(
  1536. 0,
  1537. hUserToken,
  1538. hkRoot,
  1539. NULL,
  1540. TRUE,
  1541. FALSE,
  1542. &RsopContext,
  1543. StatusLog );
  1544. if ( ERROR_SUCCESS == StatusLog )
  1545. {
  1546. CCategoryInfoLog CategoryLog( AppProcessor.GetRsopContext(), &AppCategories );
  1547. Status = AppProcessor.GetRsopContext()->GetExclusiveLoggingAccess( NULL == hUserToken );
  1548. if ( ERROR_SUCCESS == Status )
  1549. {
  1550. hrLog = CategoryLog.WriteLog();
  1551. }
  1552. AppProcessor.GetRsopContext()->ReleaseExclusiveLoggingAccess();
  1553. }
  1554. else
  1555. {
  1556. hrLog = HRESULT_FROM_WIN32( StatusLog );
  1557. }
  1558. if ( FAILED(hrLog) )
  1559. {
  1560. RsopContext.DisableRsop( hrLog );
  1561. }
  1562. }
  1563. Status = GetWin32ErrFromHResult( hr );
  1564. //
  1565. // Free the internal version of the category list
  1566. //
  1567. ReleaseAppCategoryInfoList( &AppCategories );
  1568. GetManagedAppCategoriesExit:
  1569. if ( hUserToken )
  1570. {
  1571. CloseHandle( hUserToken );
  1572. }
  1573. if ( hkRoot )
  1574. {
  1575. RegCloseKey( hkRoot );
  1576. }
  1577. return Status;
  1578. }
  1579. DWORD
  1580. WINAPI
  1581. GetManagedAppsProc(
  1582. LPVOID pvArpContext
  1583. )
  1584. {
  1585. ARPCONTEXT* pArpContext;
  1586. pArpContext = (ARPCONTEXT*) pvArpContext;
  1587. HANDLE hUserToken;
  1588. error_status_t Status;
  1589. BOOL bStatus;
  1590. HKEY hkRoot;
  1591. hUserToken = NULL;
  1592. hkRoot = NULL;
  1593. Status = ERROR_SUCCESS;
  1594. bStatus = DuplicateTokenEx(
  1595. pArpContext->hUserToken,
  1596. TOKEN_DUPLICATE | TOKEN_QUERY | TOKEN_IMPERSONATE,
  1597. NULL,
  1598. SecurityImpersonation,
  1599. TokenImpersonation,
  1600. &hUserToken);
  1601. if ( ! bStatus )
  1602. Status = GetLastError();
  1603. if ( bStatus )
  1604. {
  1605. bStatus = ImpersonateLoggedOnUser( hUserToken );
  1606. if ( ! bStatus )
  1607. Status = GetLastError();
  1608. }
  1609. if ( ERROR_SUCCESS == Status )
  1610. Status = RegOpenCurrentUser( GENERIC_ALL, &hkRoot );
  1611. RevertToSelf();
  1612. if ( Status != ERROR_SUCCESS )
  1613. {
  1614. pArpContext->Status = Status;
  1615. goto GetManagedAppsProcExit;
  1616. }
  1617. gpEvents->SetToken( hUserToken );
  1618. LogTime();
  1619. //
  1620. // Now that we have a valid GPOInfo object, we can construct
  1621. // an app processor object to do the query
  1622. //
  1623. {
  1624. CRsopAppContext RsopContext( CRsopAppContext::ARPLIST, pArpContext->hEventAppsEnumerated );
  1625. CManagedAppProcessor AppProcessor( 0,
  1626. hUserToken,
  1627. hkRoot,
  1628. NULL,
  1629. TRUE,
  1630. FALSE,
  1631. &RsopContext,
  1632. Status );
  1633. if ( ERROR_SUCCESS == Status )
  1634. {
  1635. Status = AppProcessor.GetManagedApplications( pArpContext->pCategory, pArpContext );
  1636. }
  1637. }
  1638. GetManagedAppsProcExit:
  1639. gpEvents->ClearToken();
  1640. if ( hkRoot )
  1641. RegCloseKey( hkRoot );
  1642. if ( hUserToken )
  1643. CloseHandle( hUserToken );
  1644. return 0;
  1645. }
  1646. BOOL
  1647. SetSystemRestorePoint(
  1648. IN WCHAR * pwszApplicationName,
  1649. IN OUT PAPPCONTEXT pAppContext
  1650. )
  1651. {
  1652. RESTOREPOINTINFO RestoreInfo;
  1653. STATEMGRSTATUS SRStatus;
  1654. HKEY hkInstallerPolicy;
  1655. DWORD CheckpointPolicy;
  1656. DWORD CheckpointPolicySize;
  1657. DWORD InstallLen, NameLen;
  1658. DWORD Status;
  1659. BOOL bStatus;
  1660. Status = RegOpenKeyEx(
  1661. HKEY_LOCAL_MACHINE,
  1662. L"Software\\Policies\\Microsoft\\Windows\\Installer",
  1663. 0,
  1664. KEY_READ,
  1665. &hkInstallerPolicy );
  1666. if ( Status != ERROR_SUCCESS )
  1667. return FALSE;
  1668. CheckpointPolicy = 0;
  1669. CheckpointPolicySize = sizeof(CheckpointPolicy);
  1670. (void) RegQueryValueEx(
  1671. hkInstallerPolicy,
  1672. L"LimitSystemRestoreCheckpointing",
  1673. NULL,
  1674. NULL,
  1675. (LPBYTE) &CheckpointPolicy,
  1676. &CheckpointPolicySize );
  1677. RegCloseKey( hkInstallerPolicy );
  1678. if ( CheckpointPolicy != 0 )
  1679. return FALSE;
  1680. if ( ! LoadLoadString() )
  1681. return FALSE;
  1682. Status = (*pfnLoadStringW)( ghDllInstance, IDS_INSTALLED, RestoreInfo.szDescription, sizeof(RestoreInfo.szDescription) / sizeof(WCHAR) );
  1683. if ( 0 == Status )
  1684. return FALSE;
  1685. pAppContext->pLoadSfc = new CLoadSfc( Status );
  1686. if ( Status != ERROR_SUCCESS )
  1687. {
  1688. delete pAppContext->pLoadSfc;
  1689. pAppContext->pLoadSfc = 0;
  1690. }
  1691. if ( ! pAppContext->pLoadSfc )
  1692. return FALSE;
  1693. RestoreInfo.dwEventType = BEGIN_NESTED_SYSTEM_CHANGE;
  1694. RestoreInfo.dwRestorePtType = APPLICATION_INSTALL;
  1695. RestoreInfo.llSequenceNumber = 0;
  1696. InstallLen = lstrlen(RestoreInfo.szDescription);
  1697. NameLen = lstrlen(pwszApplicationName);
  1698. if ( InstallLen + NameLen >= MAX_DESC_W )
  1699. {
  1700. lstrcpyn( &RestoreInfo.szDescription[InstallLen], pwszApplicationName, MAX_DESC_W - InstallLen - 1 );
  1701. RestoreInfo.szDescription[MAX_DESC_W - 1] = 0;
  1702. }
  1703. else
  1704. {
  1705. HRESULT hr;
  1706. hr = StringCchCopy( &RestoreInfo.szDescription[InstallLen], MAX_DESC_W,pwszApplicationName );
  1707. if (FAILED(hr))
  1708. {
  1709. return FALSE;
  1710. }
  1711. }
  1712. bStatus = (*gpfnSRSetRetorePointW)( &RestoreInfo, &SRStatus );
  1713. if ( bStatus )
  1714. pAppContext->SRSequence = SRStatus.llSequenceNumber;
  1715. return bStatus;
  1716. }
  1717. void
  1718. CheckLocalCall(
  1719. IN handle_t hRpc
  1720. )
  1721. {
  1722. UINT Type;
  1723. DWORD Status;
  1724. Status = I_RpcBindingInqTransportType( hRpc, &Type);
  1725. if ( (Status != RPC_S_OK) ||
  1726. (Type != TRANSPORT_TYPE_LPC) )
  1727. RpcRaiseException( ERROR_ACCESS_DENIED );
  1728. }
  1729. WCHAR*
  1730. GetGpoNameFromGuid(
  1731. IN PGROUP_POLICY_OBJECT pGpoList,
  1732. IN GUID* pGpoGuid
  1733. )
  1734. {
  1735. PGROUP_POLICY_OBJECT pNextGpo;
  1736. WCHAR wszTargetGuid[MAX_SZGUID_LEN];
  1737. WCHAR* pszPolicyName;
  1738. pszPolicyName = NULL;
  1739. (void) GuidToString(
  1740. *pGpoGuid,
  1741. wszTargetGuid);
  1742. while (pGpoList)
  1743. {
  1744. pNextGpo = pGpoList->pNext;
  1745. if ( lstrcmpi(
  1746. pGpoList->szGPOName,
  1747. wszTargetGuid) == 0 )
  1748. {
  1749. pszPolicyName = pGpoList->lpDisplayName;
  1750. break;
  1751. }
  1752. pGpoList = pNextGpo;
  1753. }
  1754. return pszPolicyName;
  1755. }
  1756. DWORD
  1757. GetPlatformCompatibleCOMClsCtx(
  1758. DWORD Architecture,
  1759. DWORD dwClsCtx
  1760. )
  1761. {
  1762. if ( (PROCESSOR_ARCHITECTURE_AMD64 == Architecture) ||
  1763. (PROCESSOR_ARCHITECTURE_IA64 == Architecture) )
  1764. {
  1765. //
  1766. // On 64-bit, if we have any inproc server contexts, we need to
  1767. // ensure that we specifically ask for 64-bit inproc servers
  1768. //
  1769. if ( dwClsCtx & CLSCTX_INPROC )
  1770. {
  1771. DWORD dwInproc64;
  1772. dwInproc64 = 0;
  1773. if ( dwClsCtx & CLSCTX_INPROC_SERVER )
  1774. {
  1775. dwInproc64 |= CLSCTX64_INPROC_SERVER;
  1776. }
  1777. if ( dwClsCtx & CLSCTX_INPROC_HANDLER )
  1778. {
  1779. dwInproc64 |= CLSCTX64_INPROC_HANDLER;
  1780. }
  1781. //
  1782. // Now remove the standard inproc bits, which are interpreted
  1783. // as 32-bit inproc
  1784. //
  1785. dwClsCtx &= ~CLSCTX_INPROC;
  1786. //
  1787. // Add in the 64-bit inproc bits that we support
  1788. //
  1789. dwClsCtx |= dwInproc64;
  1790. }
  1791. }
  1792. return dwClsCtx;
  1793. }
  1794. void
  1795. LogRsopInstallData(
  1796. CManagedAppProcessor* pManApp,
  1797. CAppInfo* pAppInfo
  1798. )
  1799. {
  1800. HRESULT hr;
  1801. if ( ! pManApp->GetRsopContext()->IsRsopEnabled() )
  1802. {
  1803. return;
  1804. }
  1805. hr = pManApp->GetRsopContext()->GetExclusiveLoggingAccess( NULL == pManApp->UserToken() );
  1806. //
  1807. // If the call above failed, rsop will be disabled so we have nothing to do
  1808. //
  1809. if ( FAILED(hr) )
  1810. {
  1811. return;
  1812. }
  1813. //
  1814. // First log the installed application
  1815. //
  1816. pManApp->AppList().WriteAppToRsopLog( pAppInfo );
  1817. //
  1818. // Now write all the removal entries
  1819. //
  1820. pManApp->AppList().WriteLog( CAppList::RSOP_FILTER_REMOVALSONLY );
  1821. //
  1822. // Since we have installed an app, the resultant set has changed, so
  1823. // update the RSoP version to ensure that we detect the change if
  1824. // we roam to another machine
  1825. //
  1826. (void) pManApp->GetRsopContext()->WriteCurrentRsopVersion( pManApp->AppmgmtKey() );
  1827. (void) pManApp->GetRsopContext()->ReleaseExclusiveLoggingAccess();
  1828. }