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.
833 lines
20 KiB
833 lines
20 KiB
//*************************************************************
|
|
//
|
|
// Copyright (c) Microsoft Corporation 1999 - 2000
|
|
// All rights reserved
|
|
//
|
|
// polbase.cxx
|
|
//
|
|
//*************************************************************
|
|
|
|
#include "rsop.hxx"
|
|
#include <strsafe.h>
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CPolicyDatabase::CPolicyDatabase
|
|
//
|
|
// Purpose: Constructor for CPolicyDatabase
|
|
//
|
|
// Params:
|
|
//
|
|
// Return value: none
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
CPolicyDatabase::CPolicyDatabase() :
|
|
_hrInit(E_OUTOFMEMORY),
|
|
_pOle32Api( NULL )
|
|
{}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CPolicyDatabase::~CPolicyDatabase
|
|
//
|
|
// Purpose: destructor for CPolicyDatabase -- uninitializes
|
|
// COM
|
|
//
|
|
// Params:
|
|
//
|
|
// Return value: none
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
CPolicyDatabase::~CPolicyDatabase()
|
|
{
|
|
//
|
|
// Clean up COM state
|
|
//
|
|
if ( SUCCEEDED(_hrInit) )
|
|
{
|
|
_pOle32Api->pfnCoUnInitialize();
|
|
}
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CPolicyDatabase::InitializeCOM
|
|
//
|
|
// Purpose: Initializes the calling thread for COM, loading
|
|
// necessary dll's and function entry points
|
|
//
|
|
// Params: none
|
|
//
|
|
//
|
|
// Return value: S_OK if successful, other facility error if
|
|
// the function fails.
|
|
//
|
|
// Notes: State initialized by this call is cleaned up by
|
|
// the destructor
|
|
//
|
|
//------------------------------------------------------------
|
|
HRESULT CPolicyDatabase::InitializeCOM()
|
|
{
|
|
//
|
|
// Need to dynamically load the the COM api's since
|
|
// the policy database is accessed through COM.
|
|
//
|
|
_pOle32Api = LoadOle32Api();
|
|
|
|
if ( _pOle32Api )
|
|
{
|
|
//
|
|
// If we successfully loaded COM, initialize it
|
|
//
|
|
_hrInit = _pOle32Api->pfnCoInitializeEx( NULL, COINIT_MULTITHREADED );
|
|
}
|
|
else
|
|
{
|
|
_hrInit = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
|
|
return _hrInit;
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CPolicyDatabase::Bind
|
|
//
|
|
// Purpose: Bind to a policy database and return an interface
|
|
// for the user or machine namespace
|
|
//
|
|
// Params:
|
|
//
|
|
//
|
|
// Return value: S_OK if successful, other facility error if
|
|
// the function fails.
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
HRESULT CPolicyDatabase::Bind(
|
|
WCHAR* wszRequestedNameSpace,
|
|
IWbemServices** ppWbemServices)
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = InitializeCOM();
|
|
|
|
if ( FAILED(hr) )
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
XInterface<IWbemLocator> xLocator; // Interface used to locate classes
|
|
|
|
//
|
|
// To bind, we use COM to request the COM interface to
|
|
// the database
|
|
//
|
|
hr = _pOle32Api->pfnCoCreateInstance( CLSID_WbemLocator,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IWbemLocator,
|
|
(LPVOID *) &xLocator );
|
|
|
|
if ( FAILED(hr) )
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// Refer to the namespace with an automation type so that
|
|
// we can make use of the locator interface, which takes bstr's.
|
|
//
|
|
XBStr xNameSpace( wszRequestedNameSpace );
|
|
|
|
//
|
|
// Verify the initialization of the bstr
|
|
//
|
|
if ( !xNameSpace )
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//
|
|
// Now connect to the namespace requested by the caller
|
|
//
|
|
hr = xLocator->ConnectServer( xNameSpace,
|
|
NULL,
|
|
NULL,
|
|
0L,
|
|
0L,
|
|
NULL,
|
|
NULL,
|
|
ppWbemServices );
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CPolicyRecord::GetUnknown
|
|
//
|
|
// Purpose: retrieves an IUnknown for this policy record --
|
|
// useful if this policy record itself needs to be nested
|
|
// inside another record and we want to use VT_UNKNOWN to
|
|
// do this.
|
|
//
|
|
// Params: ppUnk -- out param for IUnknown
|
|
//
|
|
// Return value: S_OK if successful, other error if not
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
HRESULT CPolicyRecord::GetUnknown(IUnknown** ppUnk)
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = GetRecordInterface()->QueryInterface(
|
|
IID_IUnknown,
|
|
(LPVOID*) ppUnk);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CPolicyRecord::InitRecord
|
|
//
|
|
// Purpose: Initializes a policy record with the database's
|
|
// record interface, thereby connecting this record object
|
|
// with the database record abstraction.
|
|
//
|
|
// Params: pRecordInterface -- the database's record interface
|
|
//
|
|
// Return value: S_OK if successful, other error if not
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
void CPolicyRecord::InitRecord(IWbemClassObject* pRecordInterface)
|
|
{
|
|
_xRecordInterface = pRecordInterface;
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CPolicyRecord::SetValue
|
|
//
|
|
// Purpose: Sets a specific value (column) of a database
|
|
// record (row) with a specific value
|
|
//
|
|
// Params: wszValueName -- name of value (column) to set
|
|
// wszValue -- unicode value to which to set it
|
|
//
|
|
// Return value: S_OK if successful, other error if not
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
HRESULT CPolicyRecord::SetValue(
|
|
WCHAR* wszValueName,
|
|
WCHAR* wszValue)
|
|
{
|
|
CVariant varValue;
|
|
HRESULT hr;
|
|
|
|
if ( ! wszValue )
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
//
|
|
// Set up a variant for the value itself
|
|
//
|
|
hr = varValue.SetStringValue(wszValue);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// Now that we have the data, call the method
|
|
// to set it
|
|
//
|
|
return _xRecordInterface->Put(
|
|
wszValueName,
|
|
0,
|
|
varValue,
|
|
0);
|
|
}
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CPolicyRecord::SetValue
|
|
//
|
|
// Purpose: Sets a specific value (column) of a database
|
|
// record (row) with a specific value
|
|
//
|
|
// Params: wszValueName -- name of value (column) to set
|
|
// lzValue -- long value to which to set it
|
|
//
|
|
// Return value: S_OK if successful, other error if not
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
HRESULT CPolicyRecord::SetValue(
|
|
WCHAR* wszValueName,
|
|
LONG Value)
|
|
{
|
|
CVariant varValue;
|
|
HRESULT hr;
|
|
|
|
//
|
|
// Set up a variant for the value itself
|
|
//
|
|
varValue.SetLongValue(Value);
|
|
|
|
//
|
|
// Now that we have the data, call the method
|
|
// to set it
|
|
//
|
|
return _xRecordInterface->Put(
|
|
wszValueName,
|
|
0,
|
|
varValue,
|
|
0);
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CPolicyRecord::SetValue
|
|
//
|
|
// Purpose: Sets a specific value (column) of a database
|
|
// record (row) with a specific value
|
|
//
|
|
// Params: wszValueName -- name of value (column) to set
|
|
// bValue -- boolean value to which to set it
|
|
//
|
|
// Return value: S_OK if successful, other error if not
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
HRESULT CPolicyRecord::SetValue(
|
|
WCHAR* wszValueName,
|
|
BOOL bValue)
|
|
{
|
|
CVariant varValue;
|
|
HRESULT hr;
|
|
|
|
//
|
|
// Set up a variant for the value itself
|
|
//
|
|
varValue.SetBoolValue(bValue);
|
|
|
|
//
|
|
// Now that we have the data, call the method
|
|
// to set it
|
|
//
|
|
return _xRecordInterface->Put(
|
|
wszValueName,
|
|
0,
|
|
varValue,
|
|
0);
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CPolicyRecord::SetValue
|
|
//
|
|
// Purpose: Sets a specific value (column) of a database
|
|
// record (row) with a specific value
|
|
//
|
|
// Params: wszValueName -- name of value (column) to set
|
|
// pTime -- time to which to set the value
|
|
//
|
|
// Return value: S_OK if successful, other error if not
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
HRESULT CPolicyRecord::SetValue(
|
|
WCHAR* wszValueName,
|
|
SYSTEMTIME* pTimeValue)
|
|
{
|
|
CVariant varValue;
|
|
HRESULT hr;
|
|
|
|
//
|
|
// Set up a variant for the value itself
|
|
//
|
|
XBStr xTimeString;
|
|
|
|
hr = SystemTimeToWbemTime( *pTimeValue, xTimeString );
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
hr = varValue.SetStringValue( xTimeString );
|
|
|
|
if ( FAILED(hr) )
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// Now that we have the data, call the method
|
|
// to set it
|
|
//
|
|
return _xRecordInterface->Put(
|
|
wszValueName,
|
|
0,
|
|
varValue,
|
|
0);
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CPolicyRecord::SetValue
|
|
//
|
|
// Purpose: Adds an element to an array value (column)
|
|
// of a database record (row) with a specific value
|
|
//
|
|
// Params: wszValueName -- name of value (column) to set
|
|
// rgwszValues -- string array to which to set this value
|
|
// cMaxElements -- number of elements in the array
|
|
//
|
|
// Return value: S_OK if successful, S_FALSE if successful
|
|
// and the array is now full, error otherwise
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
HRESULT CPolicyRecord::SetValue(
|
|
WCHAR* wszValueName,
|
|
WCHAR** rgwszValues,
|
|
DWORD cMaxElements)
|
|
{
|
|
CVariant varValue;
|
|
HRESULT hr;
|
|
|
|
if ( ! cMaxElements )
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
DWORD iElement;
|
|
|
|
for (iElement = 0; iElement < cMaxElements; iElement++)
|
|
{
|
|
//
|
|
// Now set up a variant for the value itself
|
|
//
|
|
hr = varValue.SetNextStringArrayElement(
|
|
rgwszValues[iElement],
|
|
cMaxElements);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
}
|
|
|
|
//
|
|
// We will only write this once we have all the data --
|
|
// The set function above will return S_FALSE if the
|
|
// array is full, so we check for that below
|
|
//
|
|
ASSERT( (S_FALSE == hr) || ! cMaxElements );
|
|
|
|
//
|
|
// Now that we have all the data, call the method
|
|
// to set it
|
|
//
|
|
hr = _xRecordInterface->Put(
|
|
wszValueName,
|
|
0,
|
|
varValue,
|
|
0);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CPolicyRecord::SetValue
|
|
//
|
|
// Purpose: Adds an element to an array value (column)
|
|
// of a database record (row) with a specific value
|
|
//
|
|
// Params: wszValueName -- name of value (column) to set
|
|
// rgValues -- LONG array to which to set this value
|
|
// cMaxElements -- number of in the array
|
|
//
|
|
// Return value: S_OK if successful, S_FALSE if successful
|
|
// and the array is now full, error otherwise
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
HRESULT CPolicyRecord::SetValue(
|
|
WCHAR* wszValueName,
|
|
LONG* rgValues,
|
|
DWORD cMaxElements)
|
|
{
|
|
CVariant varValue;
|
|
HRESULT hr;
|
|
|
|
if ( ! cMaxElements )
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
DWORD iElement;
|
|
|
|
for (iElement = 0; iElement < cMaxElements; iElement++)
|
|
{
|
|
//
|
|
// Now set up a variant for the value itself
|
|
//
|
|
hr = varValue.SetNextLongArrayElement(
|
|
rgValues[iElement],
|
|
cMaxElements);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
}
|
|
|
|
//
|
|
// We will only write this once we have all the data --
|
|
// The set function above will return S_FALSE if the
|
|
// array is full, so we check for that below
|
|
//
|
|
ASSERT( (S_FALSE == hr) || ! cMaxElements );
|
|
|
|
//
|
|
// Now that we have all the data, call the method
|
|
// to set it
|
|
//
|
|
hr = _xRecordInterface->Put(
|
|
wszValueName,
|
|
0,
|
|
varValue,
|
|
0);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CPolicyRecord::SetValue
|
|
//
|
|
// Purpose: Sets a record's value to that of the specified byte array
|
|
//
|
|
// Params: wszValueName -- name of value (column) to set
|
|
// rgValues -- byte array to which to set this value
|
|
// cMaxElements -- number of elements in the array
|
|
//
|
|
// Return value: S_OK if successful, S_FALSE if successful
|
|
// and the array is now full, error otherwise
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
HRESULT CPolicyRecord::SetValue(
|
|
WCHAR* wszValueName,
|
|
BYTE* rgValues,
|
|
DWORD cMaxElements)
|
|
{
|
|
CVariant varValue;
|
|
HRESULT hr;
|
|
|
|
if ( ! cMaxElements )
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
DWORD iElement;
|
|
|
|
for (iElement = 0; iElement < cMaxElements; iElement++)
|
|
{
|
|
//
|
|
// Now set up a variant for the value itself
|
|
//
|
|
hr = varValue.SetNextByteArrayElement(
|
|
rgValues[iElement],
|
|
cMaxElements);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
}
|
|
|
|
//
|
|
// We will only write this once we have all the data --
|
|
// The set function above will return S_FALSE if the
|
|
// array is full, so we check for that below
|
|
//
|
|
ASSERT( (S_FALSE == hr) || ! cMaxElements );
|
|
|
|
//
|
|
// Now that we have all the data, call the method
|
|
// to set it
|
|
//
|
|
hr = _xRecordInterface->Put(
|
|
wszValueName,
|
|
0,
|
|
varValue,
|
|
0);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CPolicyRecord::ClearValue
|
|
//
|
|
// Purpose: Sets a value to VT_NULL
|
|
//
|
|
// Params: wszValueName -- name of value (column) to set
|
|
//
|
|
// Return value: S_OK if successful, error otherwise
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
HRESULT CPolicyRecord::ClearValue(
|
|
WCHAR* wszValueName)
|
|
{
|
|
CVariant varValue;
|
|
HRESULT hr;
|
|
|
|
( (VARIANT*) varValue )->vt = VT_NULL;
|
|
|
|
//
|
|
// Set this to an empty value by passing it an
|
|
// empty variant
|
|
//
|
|
hr = _xRecordInterface->Put(
|
|
wszValueName,
|
|
0L,
|
|
varValue,
|
|
0);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CPolicyRecord::GetValue
|
|
//
|
|
// Purpose: Reads the named column of the record into a LONG
|
|
//
|
|
// Params: wszValueName -- name of value (column) to get
|
|
// pValue -- pointer to LONG for contents of column
|
|
//
|
|
// Return value: S_OK if successful, error otherwise
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
HRESULT CPolicyRecord::GetValue(
|
|
WCHAR* wszValueName,
|
|
LONG* pValue)
|
|
{
|
|
CVariant varValue;
|
|
HRESULT hr;
|
|
|
|
//
|
|
// Now that we have the value name, call the method
|
|
// to set it
|
|
//
|
|
hr = _xRecordInterface->Get(
|
|
wszValueName,
|
|
0L,
|
|
(VARIANT*) &varValue,
|
|
NULL,
|
|
NULL);
|
|
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
if ( varValue.IsLongValue() )
|
|
{
|
|
*pValue = ((VARIANT*)varValue)->lVal;
|
|
}
|
|
else
|
|
{
|
|
hr = E_INVALIDARG;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CPolicyRecord::GetValue
|
|
//
|
|
// Purpose: Reads the named column of the record into a WCHAR*
|
|
//
|
|
// Params: wszValueName -- name of value (column) to get
|
|
// pwszValue -- pointer to caller allocated buffer for
|
|
// data
|
|
// pcchValue -- on success, the length of the string in chars
|
|
// written to pwszValue. If the function returns
|
|
// S_FALSE, this is the length in chars required to
|
|
// write the string including the zero terminator
|
|
//
|
|
// Return value: S_OK if successful, S_FALSE if insufficient
|
|
// buffer, error otherwise
|
|
//
|
|
// Notes:
|
|
//
|
|
//------------------------------------------------------------
|
|
HRESULT CPolicyRecord::GetValue(
|
|
WCHAR* wszValueName,
|
|
WCHAR* wszValue,
|
|
LONG* pcchValue)
|
|
{
|
|
CVariant varValue;
|
|
HRESULT hr;
|
|
|
|
//
|
|
// Now that we have the value name, call the method
|
|
// to set it
|
|
//
|
|
hr = _xRecordInterface->Get(
|
|
wszValueName,
|
|
0L,
|
|
(VARIANT*) &varValue,
|
|
NULL,
|
|
NULL);
|
|
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
if ( varValue.IsStringValue() )
|
|
{
|
|
LONG Required;
|
|
|
|
Required = ( SysStringLen( ((VARIANT*)varValue)->bstrVal ) + 1 );
|
|
|
|
if ( Required <= *pcchValue )
|
|
{
|
|
hr = StringCchCopy( wszValue, *pcchValue, ((VARIANT*)varValue)->bstrVal );
|
|
ASSERT(SUCCEEDED(hr));
|
|
}
|
|
else
|
|
{
|
|
*pcchValue = Required;
|
|
hr = S_FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_INVALIDARG;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CPolicyRecord::GetRecordInterface
|
|
//
|
|
// Purpose: private method to allow the log class to
|
|
// manipulate this record object through the
|
|
// record object's encapsulated database record
|
|
// interface.
|
|
//
|
|
// Params:
|
|
//
|
|
// Return value: a database record interface
|
|
//
|
|
// Notes: Should never fail unless called in
|
|
// inappropriate circumstances (e.g. unit'ed object)
|
|
//
|
|
//------------------------------------------------------------
|
|
IWbemClassObject* CPolicyRecord::GetRecordInterface()
|
|
{
|
|
return _xRecordInterface;
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CPolicyRecordStatus::CPolicyRecordStatus
|
|
//
|
|
// Purpose: constructore for CPolicyRecordStatus
|
|
//
|
|
//------------------------------------------------------------
|
|
CPolicyRecordStatus::CPolicyRecordStatus() :
|
|
_SettingStatus( RSOPIgnored )
|
|
{}
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Function: CPolicyRecordStatus::SetRsopFailureStatus
|
|
//
|
|
// Purpose: set a record's failure status data
|
|
//
|
|
// Params: dwStatus -- os error code for the setting represented by this record
|
|
// dwEventId -- event log id for the attempt to apply this setting
|
|
//
|
|
// Return value: none
|
|
//
|
|
// Notes: Does not fail -- should only be called in diagnostic (logging) mode
|
|
//
|
|
//------------------------------------------------------------
|
|
void CPolicyRecordStatus::SetRsopFailureStatus(
|
|
DWORD dwStatus,
|
|
DWORD dwEventId)
|
|
{
|
|
SETTINGSTATUS SettingStatus;
|
|
|
|
//
|
|
// Setting status is based on the error code
|
|
//
|
|
SettingStatus = ( ERROR_SUCCESS != dwStatus ) ? RSOPFailed : RSOPApplied;
|
|
|
|
//
|
|
// Get the current time -- this does not fail
|
|
//
|
|
GetSystemTime( &_StatusTime );
|
|
|
|
//
|
|
// Now set the record's failure status data
|
|
//
|
|
_SettingStatus = SettingStatus;
|
|
_dwEventId = dwEventId;
|
|
}
|
|
|
|
|
|
|
|
|
|
|