529 lines
14 KiB
C++
529 lines
14 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (C) 1993-1999 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
ipropbag.cpp
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Implementation of the private IPropertyBag interface used by
|
||
|
the Performance Logs and Alerts MMC snap-in.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
#include "smcfgmsg.h"
|
||
|
#include "ipropbag.h"
|
||
|
|
||
|
USE_HANDLE_MACROS("SMLOGCFG(ipropbag.cpp)");
|
||
|
|
||
|
/*
|
||
|
* CImpIPropertyBag interface implementation
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* CImpIPropertyBag::CImpIPropertyBag
|
||
|
*
|
||
|
* Purpose:
|
||
|
* Constructor.
|
||
|
*
|
||
|
* Return Value:
|
||
|
*/
|
||
|
|
||
|
CImpIPropertyBag::CImpIPropertyBag ()
|
||
|
: m_cRef ( 0 ),
|
||
|
m_pszData ( NULL ),
|
||
|
m_dwCurrentDataLength ( 0 ),
|
||
|
m_plistData ( NULL )
|
||
|
{
|
||
|
m_hModule = (HINSTANCE)GetModuleHandleW (_CONFIG_DLL_NAME_W_);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* CImpIPropertyBag::~CImpIPropertyBag
|
||
|
*
|
||
|
* Purpose:
|
||
|
* Destructor.
|
||
|
*
|
||
|
* Return Value:
|
||
|
*/
|
||
|
|
||
|
CImpIPropertyBag::~CImpIPropertyBag ( void )
|
||
|
{
|
||
|
if ( NULL != m_pszData ) {
|
||
|
delete m_pszData;
|
||
|
}
|
||
|
|
||
|
while ( NULL != m_plistData ) {
|
||
|
PPARAM_DATA pData = DataListRemoveHead();
|
||
|
VariantClear ( &pData->vValue );
|
||
|
delete pData;
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* CImpIPropertyBag::Read
|
||
|
*
|
||
|
* Purpose:
|
||
|
*
|
||
|
* This function is called to read a property from the property bag.
|
||
|
*
|
||
|
* Parameters:
|
||
|
* pszPropName Pointer to name of property to be read
|
||
|
* pVar Pointer to the VARIANT to receive the property value
|
||
|
* pIErrorLog Pointer to the caller's error log
|
||
|
*/
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CImpIPropertyBag::Read (
|
||
|
LPCOLESTR pszPropName, //Pointer to the property to be read
|
||
|
VARIANT* pVar, //Pointer to the VARIANT to receive the
|
||
|
//property value
|
||
|
IErrorLog* pIErrorLog ) //Pointer to the caller's error log // can be null
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
PPARAM_DATA pData;
|
||
|
|
||
|
if (NULL==pszPropName)
|
||
|
return ResultFromScode(E_POINTER);
|
||
|
|
||
|
if (NULL==pVar)
|
||
|
return ResultFromScode(E_POINTER);
|
||
|
|
||
|
// Currently don't handle error log.
|
||
|
ASSERT ( NULL == pIErrorLog );
|
||
|
pIErrorLog; // Avoid compiler warning
|
||
|
|
||
|
//Read the specified data into the passed variant.
|
||
|
pData = FindProperty ( pszPropName );
|
||
|
|
||
|
if ( NULL != pData ) {
|
||
|
//VARTYPE vtTarget = vValue.vt;
|
||
|
hr = VariantChangeType ( pVar, &pData->vValue, NULL, pVar->vt );
|
||
|
} else {
|
||
|
hr = E_INVALIDARG;
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* CImpIPropertyBag::Write
|
||
|
*
|
||
|
* Purpose:
|
||
|
*
|
||
|
* This function is called to write a property to the property bag.
|
||
|
*
|
||
|
* Parameters:
|
||
|
* pszPropName Pointer to name of property to be written
|
||
|
* pVar Pointer to the VARIANT containing the property value
|
||
|
*/
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CImpIPropertyBag::Write (
|
||
|
LPCOLESTR pszPropName, //Pointer to the property to be written
|
||
|
VARIANT* pVar ) //Pointer to the VARIANT containing the
|
||
|
//property value and type
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
VARIANT vValueBstr;
|
||
|
DWORD dwNameLength;
|
||
|
DWORD dwDataLength;
|
||
|
DWORD dwDelimiterLength;
|
||
|
CString strParamTag;
|
||
|
CString strValueTag;
|
||
|
CString strEolTag;
|
||
|
LPTSTR pszNewBuffer = NULL;
|
||
|
|
||
|
ResourceStateManager rsm;
|
||
|
|
||
|
if ( NULL != pszPropName && NULL != pVar ) {
|
||
|
|
||
|
VariantInit ( &vValueBstr );
|
||
|
|
||
|
hr = VariantChangeType ( &vValueBstr, pVar, NULL, VT_BSTR );
|
||
|
|
||
|
if ( SUCCEEDED ( hr ) ) {
|
||
|
|
||
|
MFC_TRY
|
||
|
|
||
|
strParamTag.LoadString(IDS_HTML_PARAM_TAG);
|
||
|
strValueTag.LoadString(IDS_HTML_VALUE_TAG);
|
||
|
strEolTag.LoadString(IDS_HTML_VALUE_EOL_TAG);
|
||
|
|
||
|
dwDelimiterLength = strParamTag.GetLength() + strValueTag.GetLength() + strEolTag.GetLength();
|
||
|
dwNameLength = lstrlen ( pszPropName );
|
||
|
dwDataLength = lstrlen ( W2T ( vValueBstr.bstrVal ) );
|
||
|
|
||
|
// Include 1 for the ending NULL character in the length check.
|
||
|
if ( m_dwCurrentDataLength
|
||
|
< lstrlen ( m_pszData ) + dwNameLength + dwDataLength + dwDelimiterLength + 1 ) {
|
||
|
|
||
|
m_dwCurrentDataLength += eDefaultBufferLength;
|
||
|
|
||
|
pszNewBuffer = new TCHAR[m_dwCurrentDataLength];
|
||
|
|
||
|
lstrcpy ( pszNewBuffer, L"");
|
||
|
|
||
|
if ( NULL != m_pszData ) {
|
||
|
lstrcpy ( pszNewBuffer, m_pszData );
|
||
|
delete m_pszData;
|
||
|
}
|
||
|
m_pszData = pszNewBuffer;
|
||
|
pszNewBuffer = NULL;
|
||
|
}
|
||
|
|
||
|
// Build the new string and add it to the current data.
|
||
|
|
||
|
lstrcat ( m_pszData, strParamTag.GetBufferSetLength(strParamTag.GetLength()) );
|
||
|
lstrcat ( m_pszData, pszPropName );
|
||
|
lstrcat ( m_pszData, strValueTag.GetBufferSetLength(strValueTag.GetLength()) );
|
||
|
lstrcat ( m_pszData, W2T(vValueBstr.bstrVal) );
|
||
|
lstrcat ( m_pszData, strEolTag.GetBufferSetLength(strEolTag.GetLength()) );
|
||
|
|
||
|
MFC_CATCH_HR_RETURN;
|
||
|
|
||
|
if ( NULL != pszNewBuffer ) {
|
||
|
delete pszNewBuffer;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
hr = E_POINTER;
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* CImpIPropertyBag::GetData
|
||
|
*
|
||
|
* Purpose:
|
||
|
* Return pointer to the data buffer.
|
||
|
*
|
||
|
* Return Value:
|
||
|
* Pointer to the data buffer.
|
||
|
*/
|
||
|
|
||
|
LPTSTR
|
||
|
CImpIPropertyBag::GetData ( void )
|
||
|
{
|
||
|
return m_pszData;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* CImpIPropertyBag::LoadData
|
||
|
*
|
||
|
* Purpose:
|
||
|
* Load data from the supplied buffer into internal data structures.
|
||
|
* Return pointer to the next object, or NULL if no more objects.
|
||
|
*
|
||
|
* Return Value:
|
||
|
* Status.
|
||
|
*/
|
||
|
|
||
|
DWORD
|
||
|
CImpIPropertyBag::LoadData ( LPTSTR pszData, LPTSTR* ppszNextData )
|
||
|
{
|
||
|
DWORD dwStatus = ERROR_SUCCESS;
|
||
|
BOOL bUnicode = TRUE;
|
||
|
LPWSTR pszDataW = NULL;
|
||
|
LPWSTR pszDataAllocW = NULL;
|
||
|
LPWSTR pszCurrentPos = NULL;
|
||
|
WCHAR szGuid[uiSmLogGuidStringBufLen];
|
||
|
WCHAR szParamSearchTag[MAX_PATH];
|
||
|
WCHAR szValueSearchTag[MAX_PATH];
|
||
|
WCHAR szEooSearchTag[MAX_PATH];
|
||
|
INT iLength;
|
||
|
|
||
|
USES_CONVERSION;
|
||
|
|
||
|
szGuid[0] = L'\0';
|
||
|
szParamSearchTag[0] = L'\0';
|
||
|
szValueSearchTag[0] = L'\0';
|
||
|
szEooSearchTag[0] = L'\0';
|
||
|
|
||
|
if ( NULL != pszData ) {
|
||
|
|
||
|
// Unicode search: Begin the search after the first instance
|
||
|
// of the System Monitor class id.
|
||
|
|
||
|
iLength = ::LoadString ( m_hModule, IDS_HTML_OBJECT_CLASSID, szGuid, uiSmLogGuidStringBufLen );
|
||
|
if ( 0 < iLength ) {
|
||
|
::LoadString ( m_hModule, IDS_HTML_PARAM_SEARCH_TAG, szParamSearchTag, MAX_PATH );
|
||
|
}
|
||
|
if ( 0 < iLength ) {
|
||
|
::LoadString ( m_hModule, IDS_HTML_VALUE_SEARCH_TAG, szValueSearchTag, MAX_PATH );
|
||
|
}
|
||
|
if ( 0 < iLength ) {
|
||
|
::LoadString ( m_hModule, IDS_HTML_OBJECT_FOOTER, szEooSearchTag, MAX_PATH );
|
||
|
}
|
||
|
|
||
|
ASSERT ( sizeof(TCHAR) == sizeof(WCHAR) );
|
||
|
|
||
|
if ( 0 < iLength ) {
|
||
|
pszCurrentPos = wcsstr(pszData, szGuid );
|
||
|
} else {
|
||
|
dwStatus = ERROR_OUTOFMEMORY;
|
||
|
}
|
||
|
|
||
|
if ( NULL != pszCurrentPos ) {
|
||
|
pszDataW = pszData;
|
||
|
bUnicode = TRUE;
|
||
|
} else {
|
||
|
// Check for ANSI version:
|
||
|
LPSTR pszGuidA = NULL;
|
||
|
LPSTR pszCurrentPosA = NULL;
|
||
|
LPSTR pszDataA = (CHAR*) pszData;
|
||
|
|
||
|
pszGuidA = W2A( szGuid );
|
||
|
pszCurrentPosA = strstr ( pszDataA, pszGuidA );
|
||
|
|
||
|
if ( NULL != pszCurrentPosA ) {
|
||
|
pszDataAllocW = A2W ( pszDataA );
|
||
|
pszDataW = pszDataAllocW;
|
||
|
bUnicode = FALSE;
|
||
|
pszCurrentPos = wcsstr(pszDataW, szGuid );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( NULL != pszCurrentPos ) {
|
||
|
WCHAR szQuote[2];
|
||
|
LPWSTR pszEoo;
|
||
|
|
||
|
wcscpy ( szQuote, L"\"" );
|
||
|
|
||
|
// End of object is the first object footer tag after the first sysmon
|
||
|
// class id found. If multiple objects in the data block, only parse the first sysmon.
|
||
|
pszEoo = wcsstr(pszCurrentPos, szEooSearchTag);
|
||
|
|
||
|
if ( NULL != pszEoo ) {
|
||
|
// Find first parameter tag.
|
||
|
pszCurrentPos = wcsstr(pszCurrentPos, szParamSearchTag );
|
||
|
|
||
|
while ( NULL != pszCurrentPos && pszCurrentPos < pszEoo ) {
|
||
|
|
||
|
LPWSTR pszNextPos;
|
||
|
INT lStrLength;
|
||
|
PPARAM_DATA pParamData;
|
||
|
LPWSTR pszTemp;
|
||
|
|
||
|
// Store parameter/property name.
|
||
|
// Find one past first quote.
|
||
|
pszCurrentPos = wcsstr(pszCurrentPos, szQuote ) + 1;
|
||
|
|
||
|
// The param name is between first and second quote.
|
||
|
pszNextPos = wcsstr(pszCurrentPos, szQuote );
|
||
|
|
||
|
lStrLength = ( (INT)((UINT_PTR)pszNextPos - (UINT_PTR)pszCurrentPos) ) / sizeof ( WCHAR ) ;
|
||
|
|
||
|
try {
|
||
|
pParamData = new PARAM_DATA;
|
||
|
|
||
|
pParamData->pNextParam = NULL;
|
||
|
VariantInit ( &pParamData->vValue );
|
||
|
pParamData->vValue.vt = VT_BSTR;
|
||
|
} catch ( ... ) {
|
||
|
dwStatus = ERROR_OUTOFMEMORY;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
wcsncpy ( pParamData->pszPropertyName, pszCurrentPos, lStrLength );
|
||
|
pParamData->pszPropertyName[lStrLength] = TEXT ('\0');
|
||
|
|
||
|
// Find value tag and store parameter/property value.
|
||
|
// Find value tag
|
||
|
pszCurrentPos = wcsstr ( pszCurrentPos, szValueSearchTag );
|
||
|
// Find one past first quote
|
||
|
pszCurrentPos = wcsstr ( pszCurrentPos, szQuote ) + 1;
|
||
|
// The value is between first and second quote.
|
||
|
pszNextPos = wcsstr ( pszCurrentPos, szQuote );
|
||
|
|
||
|
lStrLength = ( (INT)((UINT_PTR)pszNextPos - (UINT_PTR)pszCurrentPos) ) / sizeof ( WCHAR );
|
||
|
|
||
|
try {
|
||
|
pszTemp = new WCHAR[lStrLength+1];
|
||
|
wcsncpy ( pszTemp, pszCurrentPos, lStrLength );
|
||
|
pszTemp[lStrLength] = TEXT('\0');
|
||
|
|
||
|
pParamData->vValue.bstrVal =
|
||
|
SysAllocString ( pszTemp );
|
||
|
|
||
|
delete pszTemp;
|
||
|
DataListAddHead ( pParamData );
|
||
|
|
||
|
// Find next parameter/property tag.
|
||
|
pszCurrentPos = wcsstr(pszCurrentPos, szParamSearchTag );
|
||
|
} catch ( ... ) {
|
||
|
delete pParamData;
|
||
|
dwStatus = ERROR_OUTOFMEMORY;
|
||
|
break;
|
||
|
}
|
||
|
} // While parameter tags exist for a single object.
|
||
|
|
||
|
if ( NULL != ppszNextData ) {
|
||
|
LPWSTR pszNextEoo = NULL;
|
||
|
|
||
|
pszEoo += lstrlenW ( szEooSearchTag );
|
||
|
|
||
|
pszNextEoo = wcsstr(pszEoo, szEooSearchTag);
|
||
|
|
||
|
// Successful. Return pointer to end of the current object, or NULL if all
|
||
|
// objects have been processed.
|
||
|
if ( NULL != pszNextEoo ) {
|
||
|
if ( bUnicode ) {
|
||
|
*ppszNextData = pszEoo;
|
||
|
} else {
|
||
|
INT lStrLength;
|
||
|
lStrLength = ( (INT)((UINT_PTR)pszEoo - (UINT_PTR)pszDataW) ) / sizeof ( WCHAR ) ;
|
||
|
|
||
|
*(CHAR**)ppszNextData = (CHAR*)pszData + lStrLength;
|
||
|
}
|
||
|
} else {
|
||
|
*ppszNextData = NULL;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
if ( NULL != ppszNextData ) {
|
||
|
*ppszNextData = NULL;
|
||
|
}
|
||
|
dwStatus = SMCFG_NO_HTML_SYSMON_OBJECT;
|
||
|
}
|
||
|
} else {
|
||
|
if ( NULL != ppszNextData ) {
|
||
|
*ppszNextData = NULL;
|
||
|
}
|
||
|
dwStatus = SMCFG_NO_HTML_SYSMON_OBJECT;
|
||
|
}
|
||
|
} else {
|
||
|
if ( NULL != ppszNextData ) {
|
||
|
*ppszNextData = NULL;
|
||
|
}
|
||
|
dwStatus = SMCFG_NO_HTML_SYSMON_OBJECT;
|
||
|
}
|
||
|
|
||
|
return dwStatus;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CImpIPropertyBag::DataListAddHead ( PPARAM_DATA pData )
|
||
|
{
|
||
|
pData->pNextParam = m_plistData;
|
||
|
m_plistData = pData;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
CImpIPropertyBag::PPARAM_DATA
|
||
|
CImpIPropertyBag::DataListRemoveHead ( )
|
||
|
{
|
||
|
PPARAM_DATA pReturnData;
|
||
|
|
||
|
pReturnData = m_plistData;
|
||
|
|
||
|
if ( NULL != m_plistData )
|
||
|
m_plistData = m_plistData->pNextParam;
|
||
|
|
||
|
return pReturnData;
|
||
|
}
|
||
|
|
||
|
|
||
|
CImpIPropertyBag::PPARAM_DATA
|
||
|
CImpIPropertyBag::FindProperty ( LPCTSTR pszPropName )
|
||
|
{
|
||
|
PPARAM_DATA pReturnData;
|
||
|
|
||
|
pReturnData = m_plistData;
|
||
|
|
||
|
while ( NULL != pReturnData ) {
|
||
|
if ( 0 == lstrcmpi ( pszPropName, pReturnData->pszPropertyName ) )
|
||
|
break;
|
||
|
pReturnData = pReturnData->pNextParam;
|
||
|
}
|
||
|
|
||
|
return pReturnData;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// IUnknown implementation
|
||
|
//
|
||
|
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
// Standard implementation
|
||
|
//
|
||
|
STDMETHODIMP
|
||
|
CImpIPropertyBag::QueryInterface
|
||
|
(
|
||
|
REFIID riid,
|
||
|
LPVOID *ppvObj
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
if( NULL == ppvObj )
|
||
|
{
|
||
|
hr = E_INVALIDARG;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (IsEqualIID(riid, IID_IUnknown))
|
||
|
{
|
||
|
*ppvObj = (IUnknown *)(IDataObject *)this;
|
||
|
}
|
||
|
else if (IsEqualIID(riid, IID_IDataObject))
|
||
|
{
|
||
|
*ppvObj = (IUnknown *)(IPropertyBag *)this;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_NOINTERFACE;
|
||
|
*ppvObj = NULL;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// If we got this far we are handing out a new interface pointer on
|
||
|
// this object, so addref it.
|
||
|
AddRef();
|
||
|
} while (0);
|
||
|
|
||
|
return hr;
|
||
|
|
||
|
} // end QueryInterface()
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
// Standard implementation
|
||
|
//
|
||
|
STDMETHODIMP_(ULONG)
|
||
|
CImpIPropertyBag::AddRef()
|
||
|
{
|
||
|
return InterlockedIncrement((LONG*) &m_cRef);
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
// Standard implementation
|
||
|
//
|
||
|
STDMETHODIMP_(ULONG)
|
||
|
CImpIPropertyBag::Release()
|
||
|
{
|
||
|
ULONG cRefTemp;
|
||
|
cRefTemp = InterlockedDecrement((LONG *)&m_cRef);
|
||
|
|
||
|
if( 0 == cRefTemp )
|
||
|
{
|
||
|
delete this;
|
||
|
}
|
||
|
|
||
|
return cRefTemp;
|
||
|
|
||
|
} // end Release()
|
||
|
|
||
|
|
||
|
|