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.

438 lines
11 KiB

  1. //*************************************************************
  2. //
  3. // Copyright (c) Microsoft Corporation 1998
  4. // All rights reserved
  5. //
  6. // appmgext.cxx
  7. //
  8. //*************************************************************
  9. #include "appmgext.hxx"
  10. BOOL gbInitialized = FALSE;
  11. HINSTANCE ghInst = NULL;
  12. extern "C" DWORD WINAPI
  13. ProcessGroupPolicyObjectsEx(
  14. IN DWORD dwFlags,
  15. IN HANDLE hUserToken,
  16. IN HKEY hKeyRoot,
  17. IN PGROUP_POLICY_OBJECT pDeletedGPOList,
  18. IN PGROUP_POLICY_OBJECT pChangedGPOList,
  19. IN ASYNCCOMPLETIONHANDLE pHandle,
  20. IN BOOL *pbAbort,
  21. IN PFNSTATUSMESSAGECALLBACK pfnStatusCallback,
  22. IN IWbemServices *pWbemServices,
  23. OUT HRESULT *phrRsopStatus
  24. )
  25. {
  26. DWORD Status;
  27. *phrRsopStatus = S_OK;
  28. Status = ERROR_SUCCESS;
  29. //
  30. // It is not appropriate for appmgmt to function in safe mode --
  31. // detect this case and exit if we are in safe mode
  32. //
  33. if ( dwFlags & GPO_INFO_FLAG_SAFEMODE_BOOT )
  34. return ERROR_GEN_FAILURE;
  35. if ( ! gbInitialized )
  36. Initialize();
  37. InitDebugSupport( DEBUGMODE_POLICY );
  38. CreatePolicyEvents();
  39. if ( dwFlags & GPO_INFO_FLAG_VERBOSE )
  40. gDebugLevel |= DL_VERBOSE | DL_EVENTLOG;
  41. ConditionalBreakIntoDebugger();
  42. //
  43. // Before NT 5.1, appmgmt was never applied in the background. Starting
  44. // with NT 5.1 however, it gets called for background refresh when asynchronous
  45. // foreground refreshes are enabled so that it can detect the need for a synchronous refresh.
  46. //
  47. // Normally, it will not be called for a slow link, but that behavior
  48. // can be modified by policy on group policy.
  49. //
  50. //
  51. // Note that during the asynchronous foreground refresh, the background refresh flag is
  52. // also set in order to maintain compatibility with earlier extensions, so when detecting
  53. // a true background refresh case below, we need to make sure the asynchronous foreground flag
  54. // is not enabled
  55. //
  56. if ( ( dwFlags & GPO_INFO_FLAG_BACKGROUND ) && ! ( dwFlags & GPO_INFO_FLAG_ASYNC_FOREGROUND ) )
  57. {
  58. DebugMsg((DM_VERBOSE, IDS_BACKGROUND_REFRESH));
  59. //
  60. // For background refreshes, we will notify the policy engine that we
  61. // need to be called in the synchronous foreground refresh if there are changes
  62. //
  63. if ( ! ( dwFlags & GPO_INFO_FLAG_NOCHANGES ) )
  64. {
  65. DebugMsg((DM_VERBOSE, IDS_CHANGES_DETECTED));
  66. Status = ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED;
  67. }
  68. DebugMsg((DM_VERBOSE, IDS_PROCESSGPT_RETURN, Status));
  69. return Status;
  70. }
  71. gpEvents->SetToken( hUserToken );
  72. LogTime();
  73. SignalPolicyStart( ! (dwFlags & GPO_INFO_FLAG_MACHINE) );
  74. CRsopAppContext DiagnosticModeContext(
  75. pWbemServices,
  76. ( dwFlags & GPO_INFO_FLAG_LOGRSOP_TRANSITION ) && ! ( dwFlags & GPO_INFO_FLAG_ASYNC_FOREGROUND ),
  77. phrRsopStatus );
  78. if ( pDeletedGPOList )
  79. {
  80. DiagnosticModeContext.SetGPOAppRemoval();
  81. Status = ProcessGPOList(
  82. pDeletedGPOList,
  83. dwFlags,
  84. hUserToken,
  85. hKeyRoot,
  86. pfnStatusCallback,
  87. PROCESSGPOLIST_DELETED,
  88. &DiagnosticModeContext
  89. );
  90. }
  91. if ( pChangedGPOList && (ERROR_SUCCESS == Status) )
  92. {
  93. DiagnosticModeContext.SetGPOAppAdd();
  94. Status = ProcessGPOList(
  95. pChangedGPOList,
  96. dwFlags,
  97. hUserToken,
  98. hKeyRoot,
  99. pfnStatusCallback,
  100. PROCESSGPOLIST_CHANGED,
  101. &DiagnosticModeContext);
  102. }
  103. DebugMsg((DM_VERBOSE, IDS_PROCESSGPT_RETURN, Status));
  104. SignalPolicyEnd( ! (dwFlags & GPO_INFO_FLAG_MACHINE) );
  105. gpEvents->ClearToken();
  106. return Status;
  107. }
  108. DWORD
  109. ProcessGPOList(
  110. PGROUP_POLICY_OBJECT pGPOList,
  111. DWORD dwFlags,
  112. HANDLE hUserToken,
  113. HKEY hKeyRoot,
  114. PFNSTATUSMESSAGECALLBACK pfnStatusCallback,
  115. DWORD dwListType,
  116. CRsopAppContext* pRsopContext
  117. )
  118. {
  119. CManagedAppProcessor * pManApps;
  120. PGROUP_POLICY_OBJECT pCurrentGPO;
  121. DWORD Status;
  122. BOOL bDeletedGPOs;
  123. //
  124. // In reporting mode, we need to dump all the apps --
  125. // here, we are computing resultant set, which is much different
  126. // than dumping the contents -- we will simply exit
  127. // successfully and instead allow the ARP planning simulation
  128. // to dump the list of apps
  129. //
  130. if ( pRsopContext->IsReportingModeEnabled() )
  131. {
  132. return STATUS_SUCCESS;
  133. }
  134. CLoadMsi LoadMsi( Status );
  135. if ( Status != ERROR_SUCCESS )
  136. return Status;
  137. Status = ERROR_OUTOFMEMORY;
  138. bDeletedGPOs = (PROCESSGPOLIST_DELETED == dwListType);
  139. pManApps = new CManagedAppProcessor(
  140. dwFlags,
  141. hUserToken,
  142. hKeyRoot,
  143. pfnStatusCallback,
  144. FALSE,
  145. ! bDeletedGPOs,
  146. pRsopContext,
  147. Status);
  148. if ( ERROR_SUCCESS != Status )
  149. {
  150. if ( pManApps )
  151. delete pManApps;
  152. pManApps = 0;
  153. }
  154. if ( ! pManApps )
  155. return Status;
  156. if ( bDeletedGPOs )
  157. {
  158. DebugMsg((DM_VERBOSE, IDS_POLICY_REMOVED, dwFlags));
  159. }
  160. else
  161. {
  162. DebugMsg((DM_VERBOSE, IDS_POLICY_APPLY, dwFlags));
  163. }
  164. Status = pManApps->SetPolicyListFromGPOList( pGPOList );
  165. if ( ERROR_SUCCESS != Status )
  166. return Status;
  167. if ( bDeletedGPOs )
  168. Status = pManApps->Delete();
  169. else
  170. Status = pManApps->Process();
  171. //
  172. // Write any Rsop logs -- this is a no op if
  173. // rsop logging is not enabled
  174. //
  175. pManApps->WriteRsopLogs();
  176. if ( ! pManApps->NoChanges() &&
  177. ((Status != ERROR_SUCCESS) || ! bDeletedGPOs) )
  178. {
  179. gpEvents->PolicyStatus( Status, pManApps->ErrorReason() );
  180. }
  181. if ( ! pManApps->GetRsopContext()->PurgeRemovalEntries() )
  182. {
  183. pRsopContext->ResetRemovalPurge();
  184. }
  185. HRESULT hrRsopStatus;
  186. hrRsopStatus = pManApps->GetRsopContext()->GetRsopStatus();
  187. if ( FAILED( hrRsopStatus ) )
  188. {
  189. gpEvents->RsopLoggingStatus( hrRsopStatus );
  190. }
  191. delete pManApps;
  192. return Status;
  193. }
  194. extern "C" BOOL WINAPI
  195. DllMain(
  196. HINSTANCE hInstance,
  197. DWORD dwReason,
  198. LPVOID lpReserved
  199. )
  200. {
  201. switch (dwReason)
  202. {
  203. case DLL_PROCESS_ATTACH :
  204. ghDllInstance = hInstance;
  205. gSystemLangId = GetSystemDefaultLangID();
  206. DisableThreadLibraryCalls(hInstance);
  207. InitDebugSupport( DEBUGMODE_CLIENT );
  208. InitializeClassStore(FALSE);
  209. //
  210. // Init our event logging -- this is used
  211. // by both server and cstore subcomponents
  212. //
  213. gpEvents = new CEvents();
  214. if (!gpEvents)
  215. return FALSE;
  216. break;
  217. case DLL_PROCESS_DETACH :
  218. Uninitialize();
  219. break;
  220. }
  221. return TRUE;
  222. }
  223. void
  224. Initialize()
  225. {
  226. ghInst = LoadLibrary( L"appmgmts.dll" );
  227. gbInitialized = ghInst != NULL;
  228. }
  229. extern "C" DWORD WINAPI
  230. GenerateGroupPolicy(
  231. IN DWORD dwFlags,
  232. IN BOOL *pbAbort,
  233. IN WCHAR *pwszSite,
  234. IN PRSOP_TARGET pComputerTarget,
  235. IN PRSOP_TARGET pUserTarget )
  236. {
  237. DWORD Status;
  238. Status = ERROR_SUCCESS;
  239. if ( ! gbInitialized )
  240. Initialize();
  241. InitDebugSupport( DEBUGMODE_POLICY );
  242. if ( dwFlags & GPO_INFO_FLAG_VERBOSE )
  243. gDebugLevel |= DL_VERBOSE | DL_EVENTLOG;
  244. ConditionalBreakIntoDebugger();
  245. LogTime();
  246. if ( pComputerTarget && pComputerTarget->pGPOList )
  247. {
  248. CRsopAppContext MachinePlanningModeContext(
  249. pComputerTarget,
  250. dwFlags & GPO_INFO_FLAG_REPORT
  251. );
  252. Status = ProcessGPOList(
  253. pComputerTarget->pGPOList,
  254. dwFlags,
  255. NULL,
  256. NULL,
  257. NULL,
  258. PROCESSGPOLIST_CHANGED,
  259. &MachinePlanningModeContext);
  260. if ( ( ERROR_SUCCESS == Status ) &&
  261. ( dwFlags & GPO_INFO_FLAG_REPORT ) )
  262. {
  263. CRsopAppContext MachineReportingModeContext( pComputerTarget, TRUE );
  264. Status = GenerateManagedApplications(
  265. pComputerTarget->pGPOList,
  266. dwFlags,
  267. &MachineReportingModeContext);
  268. }
  269. }
  270. if ( pUserTarget && pUserTarget->pGPOList )
  271. {
  272. CRsopAppContext UserPlanningModeContext(
  273. pUserTarget,
  274. dwFlags & GPO_INFO_FLAG_REPORT
  275. );
  276. Status = ProcessGPOList(
  277. pUserTarget->pGPOList,
  278. dwFlags,
  279. NULL,
  280. NULL,
  281. NULL,
  282. PROCESSGPOLIST_CHANGED,
  283. &UserPlanningModeContext);
  284. if ( ERROR_SUCCESS == Status )
  285. {
  286. CRsopAppContext UserPlanningModeARPContext( pUserTarget, dwFlags & GPO_INFO_FLAG_REPORT );
  287. Status = GenerateManagedApplications(
  288. pUserTarget->pGPOList,
  289. dwFlags,
  290. &UserPlanningModeARPContext);
  291. }
  292. }
  293. //
  294. // In planning mode, Need to undo the extra reference count
  295. // that normally occurs in regular policy execution mode.
  296. //
  297. if ( ghInst )
  298. {
  299. FreeLibrary( ghInst );
  300. }
  301. DebugMsg((DM_VERBOSE, IDS_PROCESSGPT_RETURN, Status));
  302. return Status;
  303. }
  304. DWORD
  305. GenerateManagedApplications(
  306. PGROUP_POLICY_OBJECT pGPOList,
  307. DWORD dwFlags,
  308. CRsopAppContext* pRsopContext
  309. )
  310. {
  311. DWORD Status;
  312. HRESULT hr;
  313. hr = pRsopContext->SetARPContext();
  314. if ( FAILED(hr) )
  315. {
  316. return ERROR_INVALID_PARAMETER;
  317. }
  318. CManagedAppProcessor ApplicationProcessor(
  319. dwFlags,
  320. NULL,
  321. NULL,
  322. NULL,
  323. TRUE,
  324. FALSE,
  325. pRsopContext,
  326. Status);
  327. if ( ERROR_SUCCESS == Status )
  328. {
  329. Status = ApplicationProcessor.SetPolicyListFromGPOList(
  330. pGPOList);
  331. if ( ERROR_SUCCESS == Status )
  332. {
  333. Status = ApplicationProcessor.GetManagedApplications(
  334. NULL,
  335. NULL);
  336. }
  337. }
  338. return Status;
  339. }