|
|
//*************************************************************
//
// Copyright (c) Microsoft Corporation 1998
// All rights reserved
//
// appmgext.cxx
//
//*************************************************************
#include "appmgext.hxx"
BOOL gbInitialized = FALSE; HINSTANCE ghInst = NULL;
extern "C" DWORD WINAPI ProcessGroupPolicyObjectsEx( IN DWORD dwFlags, IN HANDLE hUserToken, IN HKEY hKeyRoot, IN PGROUP_POLICY_OBJECT pDeletedGPOList, IN PGROUP_POLICY_OBJECT pChangedGPOList, IN ASYNCCOMPLETIONHANDLE pHandle, IN BOOL *pbAbort, IN PFNSTATUSMESSAGECALLBACK pfnStatusCallback, IN IWbemServices *pWbemServices, OUT HRESULT *phrRsopStatus ) { DWORD Status;
*phrRsopStatus = S_OK;
Status = ERROR_SUCCESS;
//
// It is not appropriate for appmgmt to function in safe mode --
// detect this case and exit if we are in safe mode
//
if ( dwFlags & GPO_INFO_FLAG_SAFEMODE_BOOT ) return ERROR_GEN_FAILURE;
if ( ! gbInitialized ) Initialize();
InitDebugSupport( DEBUGMODE_POLICY ); CreatePolicyEvents();
if ( dwFlags & GPO_INFO_FLAG_VERBOSE ) gDebugLevel |= DL_VERBOSE | DL_EVENTLOG;
ConditionalBreakIntoDebugger();
//
// Before NT 5.1, appmgmt was never applied in the background. Starting
// with NT 5.1 however, it gets called for background refresh when asynchronous
// foreground refreshes are enabled so that it can detect the need for a synchronous refresh.
//
// Normally, it will not be called for a slow link, but that behavior
// can be modified by policy on group policy.
//
//
// Note that during the asynchronous foreground refresh, the background refresh flag is
// also set in order to maintain compatibility with earlier extensions, so when detecting
// a true background refresh case below, we need to make sure the asynchronous foreground flag
// is not enabled
//
if ( ( dwFlags & GPO_INFO_FLAG_BACKGROUND ) && ! ( dwFlags & GPO_INFO_FLAG_ASYNC_FOREGROUND ) ) { DebugMsg((DM_VERBOSE, IDS_BACKGROUND_REFRESH));
//
// For background refreshes, we will notify the policy engine that we
// need to be called in the synchronous foreground refresh if there are changes
//
if ( ! ( dwFlags & GPO_INFO_FLAG_NOCHANGES ) ) { DebugMsg((DM_VERBOSE, IDS_CHANGES_DETECTED));
Status = ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED; }
DebugMsg((DM_VERBOSE, IDS_PROCESSGPT_RETURN, Status));
return Status; }
gpEvents->SetToken( hUserToken );
LogTime();
SignalPolicyStart( ! (dwFlags & GPO_INFO_FLAG_MACHINE) );
CRsopAppContext DiagnosticModeContext( pWbemServices, ( dwFlags & GPO_INFO_FLAG_LOGRSOP_TRANSITION ) && ! ( dwFlags & GPO_INFO_FLAG_ASYNC_FOREGROUND ), phrRsopStatus );
if ( pDeletedGPOList ) { DiagnosticModeContext.SetGPOAppRemoval();
Status = ProcessGPOList( pDeletedGPOList, dwFlags, hUserToken, hKeyRoot, pfnStatusCallback, PROCESSGPOLIST_DELETED, &DiagnosticModeContext ); }
if ( pChangedGPOList && (ERROR_SUCCESS == Status) ) { DiagnosticModeContext.SetGPOAppAdd();
Status = ProcessGPOList( pChangedGPOList, dwFlags, hUserToken, hKeyRoot, pfnStatusCallback, PROCESSGPOLIST_CHANGED, &DiagnosticModeContext); }
DebugMsg((DM_VERBOSE, IDS_PROCESSGPT_RETURN, Status));
SignalPolicyEnd( ! (dwFlags & GPO_INFO_FLAG_MACHINE) );
gpEvents->ClearToken();
return Status; }
DWORD ProcessGPOList( PGROUP_POLICY_OBJECT pGPOList, DWORD dwFlags, HANDLE hUserToken, HKEY hKeyRoot, PFNSTATUSMESSAGECALLBACK pfnStatusCallback, DWORD dwListType, CRsopAppContext* pRsopContext ) { CManagedAppProcessor * pManApps; PGROUP_POLICY_OBJECT pCurrentGPO;
DWORD Status; BOOL bDeletedGPOs;
//
// In reporting mode, we need to dump all the apps --
// here, we are computing resultant set, which is much different
// than dumping the contents -- we will simply exit
// successfully and instead allow the ARP planning simulation
// to dump the list of apps
//
if ( pRsopContext->IsReportingModeEnabled() ) { return STATUS_SUCCESS; }
CLoadMsi LoadMsi( Status );
if ( Status != ERROR_SUCCESS ) return Status;
Status = ERROR_OUTOFMEMORY;
bDeletedGPOs = (PROCESSGPOLIST_DELETED == dwListType);
pManApps = new CManagedAppProcessor( dwFlags, hUserToken, hKeyRoot, pfnStatusCallback, FALSE, ! bDeletedGPOs, pRsopContext, Status);
if ( ERROR_SUCCESS != Status ) { if ( pManApps ) delete pManApps;
pManApps = 0; }
if ( ! pManApps ) return Status;
if ( bDeletedGPOs ) { DebugMsg((DM_VERBOSE, IDS_POLICY_REMOVED, dwFlags)); } else { DebugMsg((DM_VERBOSE, IDS_POLICY_APPLY, dwFlags)); }
Status = pManApps->SetPolicyListFromGPOList( pGPOList ); if ( ERROR_SUCCESS != Status ) return Status;
if ( bDeletedGPOs ) Status = pManApps->Delete(); else Status = pManApps->Process();
//
// Write any Rsop logs -- this is a no op if
// rsop logging is not enabled
//
pManApps->WriteRsopLogs();
if ( ! pManApps->NoChanges() && ((Status != ERROR_SUCCESS) || ! bDeletedGPOs) ) { gpEvents->PolicyStatus( Status, pManApps->ErrorReason() ); }
if ( ! pManApps->GetRsopContext()->PurgeRemovalEntries() ) { pRsopContext->ResetRemovalPurge(); }
HRESULT hrRsopStatus;
hrRsopStatus = pManApps->GetRsopContext()->GetRsopStatus();
if ( FAILED( hrRsopStatus ) ) { gpEvents->RsopLoggingStatus( hrRsopStatus ); }
delete pManApps;
return Status; }
extern "C" BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved ) { switch (dwReason) { case DLL_PROCESS_ATTACH : ghDllInstance = hInstance; gSystemLangId = GetSystemDefaultLangID(); DisableThreadLibraryCalls(hInstance); InitDebugSupport( DEBUGMODE_CLIENT ); InitializeClassStore(FALSE);
//
// Init our event logging -- this is used
// by both server and cstore subcomponents
//
gpEvents = new CEvents();
if (!gpEvents) return FALSE;
break; case DLL_PROCESS_DETACH : Uninitialize(); break; }
return TRUE; }
void Initialize() { ghInst = LoadLibrary( L"appmgmts.dll" ); gbInitialized = ghInst != NULL; }
extern "C" DWORD WINAPI GenerateGroupPolicy( IN DWORD dwFlags, IN BOOL *pbAbort, IN WCHAR *pwszSite, IN PRSOP_TARGET pComputerTarget, IN PRSOP_TARGET pUserTarget ) { DWORD Status;
Status = ERROR_SUCCESS;
if ( ! gbInitialized ) Initialize();
InitDebugSupport( DEBUGMODE_POLICY );
if ( dwFlags & GPO_INFO_FLAG_VERBOSE ) gDebugLevel |= DL_VERBOSE | DL_EVENTLOG;
ConditionalBreakIntoDebugger();
LogTime();
if ( pComputerTarget && pComputerTarget->pGPOList ) { CRsopAppContext MachinePlanningModeContext( pComputerTarget, dwFlags & GPO_INFO_FLAG_REPORT );
Status = ProcessGPOList( pComputerTarget->pGPOList, dwFlags, NULL, NULL, NULL, PROCESSGPOLIST_CHANGED, &MachinePlanningModeContext);
if ( ( ERROR_SUCCESS == Status ) && ( dwFlags & GPO_INFO_FLAG_REPORT ) ) { CRsopAppContext MachineReportingModeContext( pComputerTarget, TRUE );
Status = GenerateManagedApplications( pComputerTarget->pGPOList, dwFlags, &MachineReportingModeContext); } }
if ( pUserTarget && pUserTarget->pGPOList ) { CRsopAppContext UserPlanningModeContext( pUserTarget, dwFlags & GPO_INFO_FLAG_REPORT );
Status = ProcessGPOList( pUserTarget->pGPOList, dwFlags, NULL, NULL, NULL, PROCESSGPOLIST_CHANGED, &UserPlanningModeContext);
if ( ERROR_SUCCESS == Status ) { CRsopAppContext UserPlanningModeARPContext( pUserTarget, dwFlags & GPO_INFO_FLAG_REPORT );
Status = GenerateManagedApplications( pUserTarget->pGPOList, dwFlags, &UserPlanningModeARPContext); } }
//
// In planning mode, Need to undo the extra reference count
// that normally occurs in regular policy execution mode.
//
if ( ghInst ) { FreeLibrary( ghInst ); }
DebugMsg((DM_VERBOSE, IDS_PROCESSGPT_RETURN, Status));
return Status; }
DWORD GenerateManagedApplications( PGROUP_POLICY_OBJECT pGPOList, DWORD dwFlags, CRsopAppContext* pRsopContext ) { DWORD Status; HRESULT hr;
hr = pRsopContext->SetARPContext();
if ( FAILED(hr) ) { return ERROR_INVALID_PARAMETER; }
CManagedAppProcessor ApplicationProcessor( dwFlags, NULL, NULL, NULL, TRUE, FALSE, pRsopContext, Status);
if ( ERROR_SUCCESS == Status ) { Status = ApplicationProcessor.SetPolicyListFromGPOList( pGPOList);
if ( ERROR_SUCCESS == Status ) { Status = ApplicationProcessor.GetManagedApplications( NULL, NULL); } } return Status; }
|