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.
 
 
 
 
 
 

556 lines
16 KiB

/*++
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 <strsafe.h>
#include "smcfgmsg.h"
#include "strnoloc.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;
LPWSTR pszNewBuffer = NULL;
size_t cchRemaining = 0;
LPWSTR szNext = NULL;
INT iCurrentLength = 0;
ResourceStateManager rsm;
if ( NULL != pszPropName && NULL != pVar ) {
VariantInit ( &vValueBstr );
hr = VariantChangeType ( &vValueBstr, pVar, NULL, VT_BSTR );
if ( SUCCEEDED ( hr ) ) {
MFC_TRY
dwDelimiterLength = lstrlen ( CGlobalString::m_cszHtmlParamTag )
+ lstrlen ( CGlobalString::m_cszHtmlValueTag )
+ lstrlen ( CGlobalString::m_cszHtmlValueEolTag );
dwNameLength = lstrlen ( pszPropName );
dwDataLength = lstrlen ( vValueBstr.bstrVal );
// Include 1 for the ending NULL character in the length check.
iCurrentLength = lstrlen ( m_pszData );
if ( m_dwCurrentDataLength
< iCurrentLength + dwNameLength + dwDataLength + dwDelimiterLength + 1 ) {
m_dwCurrentDataLength += eDefaultBufferLength;
pszNewBuffer = new WCHAR[m_dwCurrentDataLength];
pszNewBuffer[0] = L'\0';
if ( NULL != m_pszData ) {
StringCchCopyEx ( pszNewBuffer, m_dwCurrentDataLength, m_pszData, &szNext, &cchRemaining, 0 );
delete [] m_pszData;
}
m_pszData = pszNewBuffer;
pszNewBuffer = NULL;
szNext = m_pszData + iCurrentLength;
if ( ( m_dwCurrentDataLength - iCurrentLength) > 0 ) {
cchRemaining = m_dwCurrentDataLength - iCurrentLength - 1;
} else {
cchRemaining = 0;
}
} else {
szNext = m_pszData + iCurrentLength;
if ( ( m_dwCurrentDataLength - iCurrentLength) > 0 ) {
cchRemaining = m_dwCurrentDataLength - iCurrentLength - 1;
} else {
cchRemaining = 0;
}
}
// Build the new string and add it to the current data.
StringCchCopyEx ( szNext, cchRemaining, CGlobalString::m_cszHtmlParamTag, &szNext, &cchRemaining, 0 );
StringCchCopyEx ( szNext, cchRemaining, pszPropName, &szNext, &cchRemaining, 0 );
StringCchCopyEx ( szNext, cchRemaining, CGlobalString::m_cszHtmlValueTag, &szNext, &cchRemaining, 0 );
StringCchCopyEx ( szNext, cchRemaining, vValueBstr.bstrVal, &szNext, &cchRemaining, 0 );
StringCchCopyEx ( szNext, cchRemaining, CGlobalString::m_cszHtmlValueEolTag, &szNext, &cchRemaining, 0 );
MFC_CATCH_HR_RETURN;
if ( NULL != pszNewBuffer ) {
delete [] pszNewBuffer;
}
VariantClear ( &vValueBstr );
}
} else {
hr = E_POINTER;
}
return hr;
}
/*
* CImpIPropertyBag::GetData
*
* Purpose:
* Return pointer to the data buffer.
*
* Return Value:
* Pointer to the data buffer.
*/
LPWSTR
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 ( LPWSTR pszData, LPWSTR* ppszNextData )
{
DWORD dwStatus = ERROR_SUCCESS;
BOOL bUnicode = TRUE;
LPWSTR pszDataW = NULL;
LPWSTR pszDataAllocW = NULL;
LPWSTR pszCurrentPos = NULL;
INT iBufLen;
USES_CONVERSION;
if ( NULL != pszData ) {
// Unicode search: Begin the search after the first instance
// of the System Monitor class id.
pszCurrentPos = wcsstr(pszData, CGlobalString::m_cszHtmlObjectClassId );
if ( NULL != pszCurrentPos ) {
pszDataW = pszData;
bUnicode = TRUE;
} else {
//
// Check for ANSI version:
//
LPSTR pszGuidA = NULL;
LPSTR pszCurrentPosA = NULL;
LPSTR pszDataA = (CHAR*) pszData;
MFC_TRY
pszGuidA = W2A( CGlobalString::m_cszHtmlObjectClassId );
if ( NULL != pszGuidA ) {
pszCurrentPosA = strstr ( pszDataA, pszGuidA );
if ( NULL != pszCurrentPosA ) {
iBufLen = lstrlenA (pszDataA) + 1;
pszDataAllocW = new WCHAR [iBufLen];
pszDataAllocW[0] = L'\0';
MultiByteToWideChar(
CP_ACP,
0,
pszDataA,
-1, // Input string is null-terminated.
pszDataAllocW,
iBufLen );
pszDataAllocW [iBufLen - 1] = L'\0';
pszCurrentPos = wcsstr(pszDataAllocW, CGlobalString::m_cszHtmlObjectClassId );
}
}
MFC_CATCH_DWSTATUS
}
if ( NULL != pszCurrentPos ) {
WCHAR szQuote[2];
LPWSTR pszEoo;
szQuote[0] = L'\"';
szQuote[1] = L'\0';
// 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, CGlobalString::m_cszHtmlObjectFooter );
if ( NULL != pszEoo ) {
// Find first parameter tag.
pszCurrentPos = wcsstr(pszCurrentPos, CGlobalString::m_cszHtmlParamSearchTag );
while ( NULL != pszCurrentPos && pszCurrentPos < pszEoo ) {
LPWSTR pszNextPos = NULL;
INT lStrLength;
PPARAM_DATA pParamData = NULL;
LPWSTR pszTemp = NULL;
// 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 ) ;
MFC_TRY
pParamData = new PARAM_DATA;
pParamData->pNextParam = NULL;
VariantInit ( &pParamData->vValue );
pParamData->vValue.vt = VT_BSTR;
wcsncpy ( pParamData->pszPropertyName, pszCurrentPos, lStrLength );
pParamData->pszPropertyName[lStrLength] = L'\0';
// Find value tag and store parameter/property value.
// Find value tag
pszCurrentPos = wcsstr ( pszCurrentPos, CGlobalString::m_cszHtmlValueSearchTag );
// 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 );
pszTemp = new WCHAR[lStrLength+1];
wcsncpy ( pszTemp, pszCurrentPos, lStrLength );
pszTemp[lStrLength] = L'\0';
pParamData->vValue.bstrVal =
SysAllocString ( pszTemp );
DataListAddHead ( pParamData );
pParamData = NULL;
//
// Find next parameter/property tag.
//
pszCurrentPos = wcsstr(pszCurrentPos, CGlobalString::m_cszHtmlParamSearchTag );
MFC_CATCH_DWSTATUS
if ( NULL != pszTemp ) {
delete [] pszTemp;
pszTemp = NULL;
}
if ( NULL != pParamData ) {
delete pParamData;
pParamData = NULL;
break;
}
if ( ERROR_SUCCESS != dwStatus ) {
break;
}
} // While parameter tags exist for a single object.
if ( NULL != ppszNextData ) {
LPWSTR pszNextEoo = NULL;
pszEoo += lstrlenW ( CGlobalString::m_cszHtmlObjectFooter );
pszNextEoo = wcsstr(pszEoo, CGlobalString::m_cszHtmlObjectFooter );
// 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;
}
if ( NULL != pszDataAllocW ) {
delete [] pszDataAllocW;
}
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 ( LPCWSTR 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()