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.
 
 
 
 
 
 

409 lines
9.2 KiB

//*************************************************************
//
// Copyright (c) Microsoft Corporation 2000-2001
// All rights reserved
//
// conflict.cxx
//
//*************************************************************
#include "appmgext.hxx"
CConflict::CConflict(
CAppInfo* pAppInfo,
CAppInfo* pWinner,
DWORD dwReason,
LONG Precedence ) :
_pAppInfo( pAppInfo ),
_pwszConflictId( NULL ),
_Precedence( Precedence ),
_PrecedenceReason( dwReason ),
_pWinner( pWinner )
{}
CConflict::~CConflict()
{
delete [] _pwszConflictId;
}
HRESULT
CConflict::Write()
{
HRESULT hr;
DebugMsg((DM_VERBOSE, IDS_RSOP_LOG_WRITE_INFO, GetApp()->_pwszDeploymentName, GetApp()->_pwszGPOName));
hr = SetValue(
RSOP_ATTRIBUTE_ID,
_pwszConflictId);
REPORT_ATTRIBUTE_SET_STATUS( RSOP_ATTRIBUTE_ID, hr )
if (FAILED(hr))
{
goto CConflict_Write_cleanup;
}
hr = SetValue(
RSOP_ATTRIBUTE_PRECEDENCE,
_Precedence);
REPORT_ATTRIBUTE_SET_STATUS( RSOP_ATTRIBUTE_PRECEDENCE, hr )
if (FAILED(hr))
{
goto CConflict_Write_cleanup;
}
if ( 1 == _Precedence )
{
_PrecedenceReason = APP_ATTRIBUTE_REASON_VALUE_WINNING;
}
if ( 0 != _PrecedenceReason )
{
hr = SetValue(
APP_ATTRIBUTE_PRECEDENCE_REASON,
(LONG) _PrecedenceReason);
REPORT_ATTRIBUTE_SET_STATUS( APP_ATTRIBUTE_PRECEDENCE_REASON, hr )
}
if ( 0 != _Precedence )
{
if ( _Precedence > 1 || AlreadyExists() )
{
GetApp()->_dwApplyCause = APP_ATTRIBUTE_APPLYCAUSE_VALUE_NONE;
hr = ClearValue( APP_ATTRIBUTE_APPLY_CAUSE );
REPORT_ATTRIBUTE_SET_STATUS( APP_ATTRIBUTE_APPLY_CAUSE, hr )
}
}
else
{
GetApp()->_dwRemovalCause = APP_ATTRIBUTE_REMOVALCAUSE_NONE;
}
hr = GetApp()->Write( this );
CConflict_Write_cleanup:
return S_OK;
}
HRESULT
CConflict::GetPath( WCHAR* wszPath, DWORD* pchLength )
{
//
// A relative path to an instance of RSOP_ApplicationManagementPolicySetting
// looks like:
//
// RSOP_ApplicationManagementPolicySetting.EntryType=<entrytype>,id="<id-guid>",applicationid="<appid-guid>",precedence=<precedence>
//
DWORD cchRequired;
HRESULT hr = S_OK;
ASSERT( ( GetApp()->GetPublicRsopEntryType() <= APP_ATTRIBUTE_ENTRYTYPE_VALUE_ARPLIST_ITEM ) &&
( GetApp()->GetPublicRsopEntryType() >= APP_ATTRIBUTE_ENTRYTYPE_VALUE_INSTALLED_PACKAGE ) );
cchRequired = sizeof( RELATIVE_PATH_FORMAT ) / sizeof( WCHAR ) + // Fixed length portion
1 + // Entry type
MAX_SZGUID_LEN * 2 + // 2 guids
9; // Precedence = 1
if ( cchRequired <= *pchLength )
{
WCHAR wszDeploymentId[ MAX_SZGUID_LEN ];
WCHAR* wszApplicationId;
LONG lPrecedence;
LONG EntryType;
if ( GetApp()->_bRemovalLogged )
{
EntryType = APP_ATTRIBUTE_ENTRYTYPE_VALUE_REMOVED_PACKAGE;
lPrecedence = 0;
}
else
{
EntryType = GetApp()->GetPublicRsopEntryType();
lPrecedence = 1;
}
GuidToString( GetApp()->_DeploymentId, wszDeploymentId);
//
// Since we are only using precedence 1 applications, the application id
// happens to be the same as the id
//
wszApplicationId = wszDeploymentId;
hr = StringCchPrintf(
wszPath,
*pchLength,
RELATIVE_PATH_FORMAT,
EntryType,
wszDeploymentId,
wszApplicationId,
lPrecedence);
ASSERT(SUCCEEDED(hr));
}
else
{
*pchLength = cchRequired;
hr = S_FALSE;
}
return hr;
}
HRESULT
CConflict::SetConflictId( WCHAR* pwszConflictId )
{
HRESULT hr;
hr = ERROR_SUCCESS;
ASSERT ( ! _pwszConflictId );
_pwszConflictId = StringDuplicate( pwszConflictId );
if ( ! _pwszConflictId )
{
hr = E_OUTOFMEMORY;
}
return hr;
}
CConflictList::~CConflictList()
{
CConflict* pConflict;
Reset();
for ( Reset(); pConflict = (CConflict*) GetCurrentItem(); )
{
MoveNext();
pConflict->Remove();
delete pConflict;
}
}
LONG
CConflictList::AddConflict( CAppInfo* pAppInfo, CAppInfo* pWinner, DWORD dwReason, LONG Precedence )
{
CConflict* pNewConflict;
pNewConflict = new CConflict( pAppInfo, pWinner, dwReason, Precedence );
if ( ! pNewConflict )
{
return ERROR_NOT_ENOUGH_MEMORY;
}
InsertFIFO( pNewConflict );
return ERROR_SUCCESS;
}
CConflictTable::CConflictTable() :
_pLastConflict( NULL )
{}
void
CConflictTable::Reset()
{
_pLastConflict = NULL;
_SupersededApps.Reset();
}
LONG
CConflictTable::AddConflict(
CAppInfo* pAppInfo,
CAppInfo* pWinner,
DWORD dwReason,
LONG Prececence )
{
return _SupersededApps.AddConflict( pAppInfo, pWinner, dwReason );
}
CConflict*
CConflictTable::GetNextConflict( LONG* pCurrentPrecedence )
{
CConflict* pNextConflict;
pNextConflict = NULL;
//
// If we're at the end, leave
//
if ( ! _pLastConflict && ! _SupersededApps.GetCurrentItem() )
{
return NULL;
}
//
// Try to traverse the last conflict to find the next conflict
//
if ( _pLastConflict )
{
//
// The precedence of the next application should be one more
// than the last conflict
//
pNextConflict = _pLastConflict->GetApp()->GetConflictTable()->GetNextConflict( pCurrentPrecedence );
if ( pNextConflict )
{
(*pCurrentPrecedence)++;
}
}
if ( ! pNextConflict )
{
//
// If we did not find a conflict as a result of the previous conflict,
// let's try the next item in our conflict list
//
pNextConflict = (CConflict*) ( _SupersededApps.GetCurrentItem() );
_SupersededApps.MoveNext();
if ( pNextConflict )
{
pNextConflict->GetApp()->GetConflictTable()->Reset();
}
}
_pLastConflict = pNextConflict;
//
// We are finished calculating the precedence and may now
// set the final precedence value
//
if ( pNextConflict )
{
pNextConflict->_Precedence = *pCurrentPrecedence;
}
return pNextConflict;
}
LONG
CConflictTable::GenerateResultantConflictList( CConflictList* pConflictList )
{
CConflict* pConflict;
LONG Status;
LONG Precedence;
Precedence = 2;
Status = ERROR_SUCCESS;
Reset();
while ( pConflict = GetNextConflict( &Precedence ) )
{
Status = pConflictList->AddConflict(
pConflict->GetApp(),
pConflict->_pWinner,
pConflict->_PrecedenceReason,
pConflict->_Precedence);
if ( ERROR_SUCCESS != Status )
break;
Precedence = pConflict->_Precedence;
}
return Status;
}
HRESULT
CConflict::LogFailure()
{
//
// We only log status for settings
// with failures
//
CAppStatus* pAppStatus;
//
// First, see if this setting (app) has a status
//
pAppStatus = (CAppStatus*) GetApp()->_StatusList.GetCurrentItem();
if ( ! pAppStatus )
{
return S_FALSE;
}
//
// Advance the list to the next failure so
// that the next caller will log a different failure
//
GetApp()->_StatusList.MoveNext();
//
// Skip this status if this is not a failure
//
if ( RSOPFailed != pAppStatus->_SettingStatus )
{
return S_OK;
}
HRESULT hr;
IWbemServices* pWbemServices;
//
// Bind to WMI -- this is essentially no op in policy refresh
//
hr = GetApp()->_pManApp->GetRsopContext()->Bind( &pWbemServices );
if ( SUCCEEDED(hr) )
{
POLICYSETTINGSTATUSINFO SettingStatus;
memset( &SettingStatus, 0, sizeof( SettingStatus ) );
SettingStatus.szEventSource = APPMGMT_EVENT_SOURCE;
SettingStatus.szEventLogName = L"Application";
SettingStatus.dwEventID = pAppStatus->_dwEventId;
SettingStatus.dwErrorCode = ERROR_SUCCESS;
SettingStatus.status = pAppStatus->_SettingStatus;
SettingStatus.timeLogged = pAppStatus->_StatusTime;
hr = RsopSetPolicySettingStatus(
0,
pWbemServices,
GetRecordInterface(),
1,
&SettingStatus);
}
if ( FAILED(hr) )
{
REPORT_ATTRIBUTE_SET_STATUS( L"Policy Setting Status", hr )
}
return hr;
}