|
|
//*************************************************************
//
// Copyright (c) Microsoft Corporation 1999 - 2000
// All rights reserved
//
// pollog.cxx
//
//*************************************************************
#include "rsop.hxx"
#include <strsafe.h>
#define RECORD_ENUMERATION_TIMEOUT -1
#define WQL_LANGUAGE L"WQL"
#define WSZGENERAL_CRITERIA_TEMPLATE L"select * from %s"
#define WSZSPECIFIC_CRITERIA_TEMPLATE WSZGENERAL_CRITERIA_TEMPLATE L" where %s"
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CPolicyLog::CPolicyLog
//
// Purpose: Constructor for CPolicyLog class
//
// Params: none
//
// Return value: none
//
// Notes:
//
//------------------------------------------------------------
CPolicyLog::CPolicyLog() : _pRsopContext(NULL ) {}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CPolicyRecord::InitLog
//
// Purpose: Initializes the logging class so that it
// can create / delete / edit record in the database
//
// Params:
// pRsopContext -- context used to bind to the namespace
// wszPolicyType -- string corresponding to the record
// (policy) type -- this is the name of a class defined
// in the database schema.
//
// Return value: S_OK if success, error otherwise
//
// Notes:
//
//------------------------------------------------------------
HRESULT CPolicyLog::InitLog( CRsopContext* pRsopContext, WCHAR* wszPolicyType) { HRESULT hr;
_pRsopContext = pRsopContext;
if ( ! _pRsopContext->IsRsopEnabled() ) { return S_OK; }
//
// Set our internal automation compatible version
// of the policy type with the caller's specification --
// return if we cannot set this value
//
_wszClass = wszPolicyType;
XBStr xbstrClass;
xbstrClass = wszPolicyType;
if ( ! xbstrClass ) { return E_OUTOFMEMORY; }
//
// Now, bind the context to get the correct namespace
//
hr = pRsopContext->Bind( &_xWbemServices );
if ( FAILED(hr) ) { return hr; }
//
// Be sure to AddRef it, since we don't want it to
// go away when we're done
//
_xWbemServices->AddRef();
//
// Now we attempt to get an interface to the class of policy
// requested by the caller
//
hr = GetRecordCreator( &xbstrClass, &_xRecordCreator);
if (FAILED(hr)) { return hr; }
return hr; }
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CPolicyRecord::UninitLog
//
// Purpose: Uninitializes the logging class so that all
// its resources are freed
//
// Params: none
//
// Return value: none
//
// Notes:
//
//------------------------------------------------------------
void CPolicyLog::UninitLog() { _xEnum = NULL; _xWbemServices = NULL;
_xRecordCreator = NULL; }
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CPolicyLog::AddBlankRecord
//
// Purpose: Creates a blank record in the policy database,
// and connects the supplied CPolicyRecord with the
// newly created record
//
// Params: pRecord -- reference to a CPolicyRecord which will
// be associated with the new record if this funciton
// succeeds.
//
// Return S_OK if success, error otherwise
//
// Notes:
//
//------------------------------------------------------------
HRESULT CPolicyLog::AddBlankRecord(CPolicyRecord* pRecord) { HRESULT hr; IWbemClassObject* pRecordInterface;
if ( ! _pRsopContext->IsRsopEnabled() ) { return S_OK; }
pRecordInterface = NULL;
//
// Use the record creator interface to create
// an instance of the class of record associated
// with this log
//
hr = _xRecordCreator->SpawnInstance( 0, &pRecordInterface);
if (FAILED(hr)) { return hr; }
//
// Initialize the CPolicyRecord so that it is
// associated with the newly created record
//
pRecord->InitRecord(pRecordInterface);
return S_OK; }
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CPolicyLog::CommitRecord
//
// Purpose: Commits an edited policy record to the database
//
// Params: pRecord -- the record to commit
//
// Return value: S_OK if successful, other error if not
//
// Notes:
//
//------------------------------------------------------------
HRESULT CPolicyLog::CommitRecord(CPolicyRecord* pRecord) { return _xWbemServices->PutInstance( pRecord->GetRecordInterface(), WBEM_FLAG_CREATE_OR_UPDATE, NULL, NULL); }
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CPolicyRecord::WriteNewRecord
//
// Purpose: Creates a new record in the database, populates
// that record with information specific to the CPolicyRecord
// object, and commits the record.
//
// Params: pRecord -- reference to a CPolicyRecord which contains
// information that should be written to the database
//
// Return S_OK if success, error otherwise
//
// Notes: The pRecord object may not be passed to this
// method more than once
//
//------------------------------------------------------------
HRESULT CPolicyLog::WriteNewRecord(CPolicyRecord* pRecord) { HRESULT hr;
if ( ! _pRsopContext->IsRsopEnabled() ) { return S_OK; }
//
// Now, let's attempt to add a blank entry for this record to the database
//
hr = AddBlankRecord( pRecord );
if (FAILED(hr)) { return hr; }
//
// Write the information for this record into the blank log record
//
hr = pRecord->Write();
if (FAILED(hr)) { return hr; }
//
// We've written the record, now commit it permanently to the log
// in the database
//
hr = CommitRecord( pRecord );
return hr; }
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CPolicyRecord::GetRecordCreator
//
// Purpose: Returns an interface that allows for the creation
// of records of a specified class in the database
//
// Params: pStrClass -- a string named with a class as defined
// by the database schema that indicates the class for
// which we require an interface
//
// ppClass -- out param returning an interface to the
// record creator for a given class
//
// Return S_OK if success, error otherwise
//
// Notes:
//
//------------------------------------------------------------
HRESULT CPolicyLog::GetRecordCreator( XBStr* pxStrClass, IWbemClassObject** ppClass) { HRESULT hr;
//
// Call the method of the namespace interface to return
// an instance of the specified class defined in that namespace
//
hr = _xWbemServices->GetObject( *pxStrClass, 0L, NULL, ppClass, NULL );
return hr; }
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CPolicyRecord::GetNextRecord
//
// Purpose: Associates a CPolicyRecord with a database
// record that's next in the current enumeration
//
// Params: pRecord -- CPolicyRecord to be associated with
// the next db record in the enumeration
//
// Return S_OK if success, error otherwise
//
// Notes:
//
//------------------------------------------------------------
HRESULT CPolicyLog::GetNextRecord( CPolicyRecord* pRecord ) { ULONG ulReturned; IWbemClassObject* pInstance; HRESULT hr;
ulReturned = 1;
//
// Use the enumeration interface to return a record interface
// to the next item in the enumeration -- we choose
// here to enumerate one at a time as this is not
// optimzed for speed currently.
//
hr = _xEnum->Next( RECORD_ENUMERATION_TIMEOUT, 1, &pInstance, &ulReturned );
//
// If we received one item back with a success code,
// we have retrieved an interface -- associate
// the retrieved interface with the caller-specified
// pRecord
//
if ( (S_OK == hr) && (1 == ulReturned) ) { pRecord->InitRecord( pInstance ); } else { ASSERT(FAILED(hr) || (S_FALSE == hr)); }
return hr; }
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CPolicyLog::OpenExistingRecord
//
// Purpose: Associates a CPolicyRecord with a database
// record that corresponds to a path emitted by
// CPolicyRecord's GetPath method
//
// Params: pRecord -- CPolicyRecord to be associated with
// the existing database item
//
// Return S_OK if success, error otherwise
//
// Notes:
//
//------------------------------------------------------------
HRESULT CPolicyLog::OpenExistingRecord( CPolicyRecord* pRecord ) { HRESULT hr;
WCHAR* wszPath = NULL; DWORD cchLength = MAX_PATH; BSTR PathName = NULL;
wszPath = (WCHAR*)LocalAlloc(LPTR, cchLength*sizeof(WCHAR)); if ( wszPath == NULL ) { return E_OUTOFMEMORY; }
hr = pRecord->GetPath( wszPath, &cchLength ); if ( FAILED( hr ) ) { LocalFree( wszPath ); return hr; }
if ( S_OK == hr ) { PathName = SysAllocString( wszPath ); LocalFree( wszPath ); wszPath = NULL; } else { LocalFree( wszPath ); wszPath = (WCHAR*)LocalAlloc(LPTR, cchLength*sizeof(WCHAR)); if ( wszPath != NULL ) { hr = pRecord->GetPath( wszPath, &cchLength ); if ( FAILED(hr) ) { LocalFree( wszPath ); return hr; }
PathName = SysAllocString( wszPath ); LocalFree( wszPath ); wszPath = NULL; } } if ( ! PathName ) { return E_OUTOFMEMORY; }
if ( SUCCEEDED( hr ) ) { IWbemClassObject* pInstance; pInstance = NULL;
if ( _xWbemServices ) { hr = _xWbemServices->GetObject( PathName, WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL, &pInstance, NULL); } else { hr = E_OUTOFMEMORY; }
if ( SUCCEEDED( hr ) ) { pRecord->InitRecord( pInstance ); } }
SysFreeString( PathName );
if ( SUCCEEDED( hr ) ) { pRecord->_bNewRecord = FALSE; }
return hr; }
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CPolicyRecord::DeleteRecord
//
// Purpose: Deletes the record associated with this CPolicyRecord
// from the database
//
// Params: pRecord -- CPolicyRecord associated with
// the record to delete
//
// Return S_OK if success, error otherwise
//
// Notes:
//
//------------------------------------------------------------
HRESULT CPolicyLog::DeleteRecord( CPolicyRecord* pRecord, BOOL bDeleteStatus) { CVariant var; HRESULT hr;
//
// If specified by the caller, delete any associated status records
//
if ( bDeleteStatus ) { hr = DeleteStatusRecords( pRecord );
if ( FAILED(hr) ) { return hr; } }
//
// Retrieve the database path of the record to delete
//
hr = pRecord->GetRecordInterface()->Get( WMI_PATH_PROPERTY, 0L, (VARIANT*) &var, NULL, NULL);
if ( FAILED(hr) ) { return hr; }
//
// Now that we have the path, we can use it to delete the record
// by supplying it to the namespace's delete instance method --
// this will delete the record from the namespace
//
hr = _xWbemServices->DeleteInstance( ((VARIANT*) &var)->bstrVal, 0L, NULL, NULL );
return hr; }
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CPolicyRecord::DeleteRecord
//
// Purpose: Deletes the record associated with this CPolicyRecord
// from the database
//
// Params: pRecord -- CPolicyRecord associated with
// the record to delete
//
// Return S_OK if success, error otherwise
//
// Notes:
//
//------------------------------------------------------------
HRESULT CPolicyLog::DeleteStatusRecords( CPolicyRecord* pRecord ) { HRESULT hr;
//
// If there is a setting status associated with
// this error, delete it
//
hr = RsopResetPolicySettingStatus( 0, _xWbemServices, pRecord->GetRecordInterface());
return hr; }
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CPolicyRecord::ClearLog
//
// Purpose: Clears all records of this log's class (policy type)
// from the log's associated namespace
//
// Params: none
//
// Return S_OK if success, error otherwise
//
// Notes:
//
//------------------------------------------------------------
HRESULT CPolicyLog::ClearLog( WCHAR* wszSpecifiedCriteria, BOOL bDeleteStatus) { HRESULT hr;
if ( ! _pRsopContext->IsRsopEnabled() ) { return S_OK; }
//
// Retrieve an enumerator for the specified criteria
//
hr = GetEnum( wszSpecifiedCriteria );
if (FAILED(hr)) { return hr; }
//
// We will iterate through all existing records
//
for (;;) { CPolicyRecord CurrentRecord;
//
// Retrieve the current record from the
// namespace
//
hr = GetNextRecord(&CurrentRecord); if (FAILED(hr)) { return hr; } //
// If there are no more records to retrieve,
// we are done and can exit the loop.
//
if (S_FALSE == hr) { break; } //
// Delete the current record from the namespace
//
hr = DeleteRecord( &CurrentRecord, bDeleteStatus ); }
FreeEnum();
return S_OK; }
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CPolicyRecord::ClearLog
//
// Purpose: Deletes all instances of this class from the namespace
//
// Params: none
//
// Return S_OK if success, error otherwise
//
// Notes:
//
//------------------------------------------------------------
HRESULT CPolicyLog::GetEnum( WCHAR* wszSpecifiedCriteria ) { HRESULT hr;
if ( _xEnum ) { return E_FAIL; }
//
// Generate criteria from the caller's specification
//
WCHAR* wszCriteria; DWORD dwCritLength = ( wszSpecifiedCriteria ? lstrlen(wszSpecifiedCriteria) : 0 ) + sizeof( WSZSPECIFIC_CRITERIA_TEMPLATE ) / sizeof(WCHAR) + lstrlen( _wszClass ) + 1;
wszCriteria = new WCHAR [ dwCritLength ];
if ( ! wszCriteria ) { return E_OUTOFMEMORY; }
//
// This creates a query for instances of the class supported by this log
// that adhere to the caller's specifications (usually asserts the value of some property)
//
if ( wszSpecifiedCriteria ) { //
// Include the user's criteria if specified
//
hr = StringCchPrintf(wszCriteria, dwCritLength, WSZSPECIFIC_CRITERIA_TEMPLATE, _wszClass, wszSpecifiedCriteria); ASSERT(SUCCEEDED(hr)); } else { //
// If the user specified no criteria, do not attempt to include it
//
hr = StringCchPrintf(wszCriteria, dwCritLength, WSZGENERAL_CRITERIA_TEMPLATE, _wszClass); ASSERT(SUCCEEDED(hr)); }
hr = E_OUTOFMEMORY;
XBStr Query( wszCriteria ); XBStr QueryLanguage( WQL_LANGUAGE );
if ( Query && QueryLanguage ) { //
// Use this method to obtain an enumerator for instances
// satisfying the specified criteria
//
hr = _xWbemServices->ExecQuery( QueryLanguage, Query, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &_xEnum ); }
delete [] wszCriteria;
if ( FAILED(hr) ) { return hr; }
return S_OK; }
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CPolicyRecord::ClearLog
//
// Purpose: Deletes all instances of this class from the namespace
//
// Params: none
//
// Return S_OK if success, error otherwise
//
// Notes:
//
//------------------------------------------------------------
void CPolicyLog::FreeEnum() { //
// This will release the interface and set it to NULL so
// that we know that it is released;
//
_xEnum = 0; }
|