436 lines
12 KiB
C++
436 lines
12 KiB
C++
/*++
|
|
|
|
Copyright (C) 1999-2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
PropBag.cpp
|
|
|
|
Abstract:
|
|
|
|
Implementation of the private IPropertyBag interface used by
|
|
the Performance Log Manager.
|
|
|
|
--*/
|
|
|
|
#include "logman.h"
|
|
#include "stdafx.h"
|
|
#include "unihelpr.h"
|
|
#include "strings.h"
|
|
#include "propbag.h"
|
|
|
|
#define MAX_GUID_STRING_LENGTH 39
|
|
|
|
/*
|
|
* CPropertyBag::CPropertyBag
|
|
*
|
|
* Purpose:
|
|
* Constructor.
|
|
*
|
|
* Return Value:
|
|
*/
|
|
|
|
CPropertyBag::CPropertyBag ( void )
|
|
: m_pszData ( NULL ),
|
|
m_dwCurrentDataLength ( 0 ),
|
|
m_plistData ( NULL )
|
|
{
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* CPropertyBag::~CPropertyBag
|
|
*
|
|
* Purpose:
|
|
* Destructor.
|
|
*
|
|
* Return Value:
|
|
*/
|
|
|
|
CPropertyBag::~CPropertyBag ( void )
|
|
{
|
|
if ( NULL != m_pszData ) {
|
|
delete m_pszData;
|
|
}
|
|
|
|
while ( NULL != m_plistData ) {
|
|
PPARAM_DATA pData = DataListRemoveHead();
|
|
VariantClear ( &pData->vValue );
|
|
delete pData;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/*
|
|
* CPropertyBag::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
|
|
*/
|
|
|
|
HRESULT
|
|
CPropertyBag::Read (
|
|
LPCWSTR pszPropName, //Pointer to the property to be read
|
|
VARIANT* pVar ) //Pointer to the VARIANT to receive the
|
|
//property value
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
PPARAM_DATA pData = NULL;
|
|
|
|
assert ( NULL != pszPropName );
|
|
assert ( NULL != pVar );
|
|
|
|
if ( NULL == pszPropName )
|
|
return ResultFromScode ( E_POINTER );
|
|
|
|
if ( NULL == pVar )
|
|
return ResultFromScode ( E_POINTER );
|
|
|
|
//Read the specified data into the passed variant.
|
|
pData = FindProperty ( pszPropName );
|
|
|
|
if ( NULL != pData ) {
|
|
hr = VariantChangeType ( pVar, &pData->vValue, NULL, pVar->vt );
|
|
} else {
|
|
hr = E_INVALIDARG;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*
|
|
* CPropertyBag::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
|
|
*/
|
|
|
|
HRESULT
|
|
CPropertyBag::Write (
|
|
LPCWSTR 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;
|
|
static DWORD dwDelimiterLength = 0;
|
|
static DWORD dwParamNameLength = 0;
|
|
static DWORD dwEolTagLength = 0;
|
|
static DWORD dwValueTagLength = 0;
|
|
HRESULT hrConvert;
|
|
LPWSTR pszNextField = m_pszData;
|
|
DWORD dwCurrentDataUsedLength;
|
|
|
|
assert ( NULL != pszPropName );
|
|
assert ( NULL != pVar );
|
|
|
|
if ( NULL == pszPropName )
|
|
return ResultFromScode ( E_POINTER );
|
|
|
|
if ( NULL == pVar )
|
|
return ResultFromScode ( E_POINTER );
|
|
|
|
USES_CONVERSION
|
|
|
|
VariantInit ( &vValueBstr );
|
|
|
|
hrConvert = VariantChangeType ( &vValueBstr, pVar, NULL, VT_BSTR );
|
|
// All length values calculated number of WCHARs.
|
|
|
|
if ( 0 == dwDelimiterLength ) {
|
|
// Initialize static values
|
|
|
|
dwParamNameLength = lstrlenW (cwszHtmlParamTag);
|
|
dwValueTagLength = lstrlenW ( cwszHtmlValueTag );
|
|
dwEolTagLength = lstrlenW ( cwszHtmlValueEolTag );
|
|
|
|
dwDelimiterLength = dwParamNameLength + dwValueTagLength + dwEolTagLength;
|
|
}
|
|
|
|
if ( SUCCEEDED ( hr ) ) {
|
|
hr = E_NOTIMPL;
|
|
// Todo: Implement
|
|
|
|
dwNameLength = lstrlenW ( pszPropName );
|
|
dwDataLength = lstrlenW ( vValueBstr.bstrVal );
|
|
dwCurrentDataUsedLength = lstrlenW ( m_pszData );
|
|
|
|
// Add 1 to size calculation for NULL buffer terminator.
|
|
if ( m_dwCurrentDataLength
|
|
< dwCurrentDataUsedLength + dwNameLength + dwDataLength + dwDelimiterLength + 1 ) {
|
|
|
|
LPWSTR pszNewBuffer;
|
|
|
|
if ( 0 == m_dwCurrentDataLength ) {
|
|
m_dwCurrentDataLength += eDefaultBufferLength;
|
|
} else {
|
|
m_dwCurrentDataLength *= 2;
|
|
}
|
|
pszNewBuffer = new WCHAR[m_dwCurrentDataLength];
|
|
|
|
if ( NULL == pszNewBuffer )
|
|
return E_OUTOFMEMORY;
|
|
|
|
if ( NULL != m_pszData ) {
|
|
memcpy ( pszNewBuffer, m_pszData, dwCurrentDataUsedLength * sizeof(WCHAR) );
|
|
delete m_pszData;
|
|
}
|
|
m_pszData = pszNewBuffer;
|
|
}
|
|
|
|
// Build the new string and add it to the current data.
|
|
|
|
pszNextField = m_pszData + dwCurrentDataUsedLength;
|
|
memcpy ( pszNextField, cwszHtmlParamTag, dwParamNameLength * sizeof(WCHAR) );
|
|
|
|
pszNextField += dwParamNameLength;
|
|
memcpy ( pszNextField, pszPropName, dwNameLength * sizeof(WCHAR) );
|
|
|
|
pszNextField += dwNameLength;
|
|
memcpy ( pszNextField, cwszHtmlValueTag, dwValueTagLength * sizeof(WCHAR) );
|
|
|
|
pszNextField += dwValueTagLength;
|
|
memcpy ( pszNextField, W2T(vValueBstr.bstrVal), dwDataLength * sizeof(WCHAR) );
|
|
|
|
pszNextField += dwDataLength;
|
|
memcpy ( pszNextField, cwszHtmlValueEolTag, dwEolTagLength * sizeof(WCHAR) );
|
|
|
|
pszNextField += dwEolTagLength;
|
|
lstrcpyW ( pszNextField, cwszNull );
|
|
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
/*
|
|
* CPropertyBag::GetData
|
|
*
|
|
* Purpose:
|
|
* Return pointer to the data buffer.
|
|
*
|
|
* Return Value:
|
|
* Pointer to the data buffer.
|
|
*/
|
|
|
|
LPWSTR
|
|
CPropertyBag::GetData ( void )
|
|
{
|
|
return m_pszData;
|
|
}
|
|
|
|
/*
|
|
* CPropertyBag::LoadData
|
|
*
|
|
* Purpose:
|
|
* Load data from the supplied buffer into internal data structures.
|
|
*
|
|
* Return Value:
|
|
* Status.
|
|
*/
|
|
|
|
DWORD
|
|
CPropertyBag::LoadData (
|
|
LPCTSTR pszData,
|
|
LPTSTR& rpszNextData )
|
|
{
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
LPWSTR szNextEoo = NULL;
|
|
BOOL bUnicode = TRUE;
|
|
|
|
USES_CONVERSION
|
|
|
|
assert ( NULL != pszData );
|
|
|
|
rpszNextData = NULL;
|
|
|
|
if ( NULL != pszData ) {
|
|
LPWSTR pszDataW = NULL;
|
|
LPWSTR pszDataAllocW = NULL;
|
|
LPWSTR pszCurrentPos;
|
|
LPWSTR pszGuid;
|
|
|
|
// Unicode search: Begin the search after the first instance
|
|
// of the System Monitor class id.
|
|
|
|
pszGuid = wcstok ( const_cast<LPWSTR>(cwszHtmlObjectClassId), L"{} " );
|
|
pszCurrentPos = wcsstr( (LPWSTR) pszData, pszGuid );
|
|
|
|
// Handle wide vs ansi.
|
|
if ( NULL != pszCurrentPos ) {
|
|
pszDataW = (LPWSTR)pszData;
|
|
bUnicode = TRUE;
|
|
} else {
|
|
// Check for ANSI version:
|
|
LPSTR pszGuidA = NULL;
|
|
LPSTR pszCurrentPosA = NULL;
|
|
LPSTR pszDataA = (CHAR*) pszData;
|
|
|
|
pszGuidA = W2A( pszGuid );
|
|
pszCurrentPosA = strstr ( pszDataA, pszGuidA );
|
|
|
|
if ( NULL != pszCurrentPosA ) {
|
|
pszDataAllocW = A2W ( pszDataA );
|
|
pszDataW = pszDataAllocW;
|
|
bUnicode = FALSE;
|
|
pszCurrentPos = wcsstr(pszDataW, pszGuid );
|
|
}
|
|
}
|
|
|
|
if ( NULL != pszCurrentPos ) {
|
|
LPWSTR szEoo;
|
|
|
|
// 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.
|
|
szEoo = wcsstr(pszCurrentPos, cwszHtmlObjectFooter );
|
|
|
|
if ( NULL != szEoo ) {
|
|
|
|
// Find first parameter tag.
|
|
pszCurrentPos = wcsstr(pszCurrentPos, cwszHtmlParamSearchTag );
|
|
|
|
while ( NULL != pszCurrentPos && pszCurrentPos < szEoo ) {
|
|
|
|
LPWSTR pszNextPos;
|
|
INT lStrLength;
|
|
PPARAM_DATA pParamData;
|
|
LPWSTR szTemp;
|
|
|
|
// Store parameter/property name.
|
|
// Find one past first quote.
|
|
pszCurrentPos = wcsstr(pszCurrentPos, cwszQuote ) + 1;
|
|
|
|
// The param name is between first and second quote.
|
|
pszNextPos = wcsstr(pszCurrentPos, cwszQuote );
|
|
|
|
lStrLength = ( (INT)((UINT_PTR)pszNextPos - (UINT_PTR)pszCurrentPos) ) / sizeof ( WCHAR ) ;
|
|
|
|
pParamData = new PARAM_DATA;
|
|
|
|
if ( NULL != pParamData ) {
|
|
pParamData->pNextParam = NULL;
|
|
VariantInit ( &pParamData->vValue );
|
|
pParamData->vValue.vt = VT_BSTR;
|
|
} else {
|
|
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, cwszHtmlValueSearchTag );
|
|
// Find one past first quote
|
|
pszCurrentPos = wcsstr ( pszCurrentPos, cwszQuote ) + 1;
|
|
// The value is between first and second quote.
|
|
pszNextPos = wcsstr ( pszCurrentPos, cwszQuote );
|
|
|
|
lStrLength = ( (INT)((UINT_PTR)pszNextPos - (UINT_PTR)pszCurrentPos) ) / sizeof ( WCHAR );
|
|
|
|
szTemp = new WCHAR[lStrLength+1];
|
|
if (szTemp != NULL) {
|
|
wcsncpy ( szTemp, pszCurrentPos, lStrLength );
|
|
szTemp[lStrLength] = TEXT('\0');
|
|
|
|
pParamData->vValue.bstrVal =
|
|
SysAllocString ( szTemp );
|
|
|
|
delete szTemp;
|
|
DataListAddHead ( pParamData );
|
|
// Find next parameter/property tag.
|
|
pszCurrentPos = wcsstr(pszCurrentPos, cwszHtmlParamSearchTag );
|
|
} else {
|
|
delete pParamData;
|
|
dwStatus = ERROR_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
} // While parameter tags exist for a single object.
|
|
|
|
// Search for next object
|
|
// Start after current object footer
|
|
szEoo += lstrlenW ( cwszHtmlObjectFooter );
|
|
|
|
szNextEoo = wcsstr(szEoo, cwszHtmlObjectFooter);
|
|
|
|
// Successful. Return pointer to end of the current object, or NULL if all
|
|
// objects have been processed.
|
|
if ( NULL != szNextEoo ) {
|
|
if ( bUnicode ) {
|
|
rpszNextData = (LPTSTR)szEoo;
|
|
} else {
|
|
INT lStrLength;
|
|
lStrLength = ( (INT)((UINT_PTR)szEoo - (UINT_PTR)pszDataW) ) / sizeof ( WCHAR ) ;
|
|
|
|
// Add string length to original buffer pointer
|
|
rpszNextData = (LPTSTR)((LPSTR)pszData + lStrLength);
|
|
}
|
|
}
|
|
} else {
|
|
dwStatus = LOGMAN_NO_SYSMON_OBJECT;
|
|
}
|
|
} else {
|
|
dwStatus = LOGMAN_NO_SYSMON_OBJECT;
|
|
}
|
|
} else {
|
|
dwStatus = ERROR_INVALID_PARAMETER;
|
|
}
|
|
return dwStatus;
|
|
}
|
|
|
|
void
|
|
CPropertyBag::DataListAddHead ( PPARAM_DATA pData )
|
|
{
|
|
|
|
assert ( NULL != pData );
|
|
|
|
pData->pNextParam = m_plistData;
|
|
m_plistData = pData;
|
|
return;
|
|
}
|
|
|
|
CPropertyBag::PPARAM_DATA
|
|
CPropertyBag::DataListRemoveHead ( )
|
|
{
|
|
PPARAM_DATA pReturnData;
|
|
|
|
pReturnData = m_plistData;
|
|
|
|
if ( NULL != m_plistData )
|
|
m_plistData = m_plistData->pNextParam;
|
|
|
|
return pReturnData;
|
|
}
|
|
|
|
|
|
CPropertyBag::PPARAM_DATA
|
|
CPropertyBag::FindProperty ( LPCWSTR pszPropName )
|
|
{
|
|
PPARAM_DATA pReturnData;
|
|
|
|
pReturnData = m_plistData;
|
|
|
|
while ( NULL != pReturnData ) {
|
|
if ( 0 == lstrcmpiW ( pszPropName, pReturnData->pszPropertyName ) )
|
|
break;
|
|
pReturnData = pReturnData->pNextParam;
|
|
}
|
|
|
|
return pReturnData;
|
|
}
|