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.
1110 lines
33 KiB
1110 lines
33 KiB
/*****************************************************************************\
|
|
|
|
Author: Corey Morgan (coreym)
|
|
|
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
\*****************************************************************************/
|
|
|
|
#include <fwcommon.h>
|
|
#include <strsafe.h>
|
|
|
|
#include "evntrprv.h"
|
|
|
|
LPCWSTR cszGlobalLogger = L"GlobalLogger";
|
|
LPCWSTR cszKernelLogger = L"NT Kernel Logger";
|
|
LPCWSTR cszPrivateLogger = L"{dc945bc4-34e5-4bc4-ab8d-cc4e9de1c2bb}";
|
|
|
|
_COM_SMARTPTR_TYPEDEF(CInstance, __uuidof(CInstance));
|
|
|
|
HRESULT
|
|
SetGlobalLoggerSettings(
|
|
DWORD StartValue,
|
|
PEVENT_TRACE_PROPERTIES LoggerInfo,
|
|
DWORD ClockType
|
|
);
|
|
|
|
BOOL
|
|
FindString( LPCWSTR strBuffer, LPCWSTR strMatch )
|
|
{
|
|
BOOL bReturn = FALSE;
|
|
|
|
LPWSTR buffer;
|
|
LPWSTR match;
|
|
|
|
if( NULL == strBuffer || NULL == strMatch ){
|
|
return FALSE;
|
|
}
|
|
|
|
buffer = _wcsdup( strBuffer );
|
|
match = _wcsdup( strMatch );
|
|
|
|
if( buffer != NULL && match != NULL ){
|
|
_wcslwr( buffer );
|
|
_wcslwr( match );
|
|
|
|
if( wcsstr( buffer, match ) ){
|
|
bReturn = TRUE;
|
|
}
|
|
}
|
|
|
|
if( NULL != match ){
|
|
free( match );
|
|
}
|
|
if( NULL != buffer ){
|
|
free( buffer );
|
|
}
|
|
|
|
return bReturn;
|
|
}
|
|
|
|
ULONG hextoi( LPWSTR s )
|
|
{
|
|
long len;
|
|
ULONG num, base, hex;
|
|
|
|
if (s == NULL || s[0] == L'\0') {
|
|
return 0;
|
|
}
|
|
|
|
len = (long) wcslen(s);
|
|
|
|
if (len == 0) {
|
|
return 0;
|
|
}
|
|
|
|
hex = 0;
|
|
base = 1;
|
|
num = 0;
|
|
|
|
while (-- len >= 0) {
|
|
if (s[len] >= L'0' && s[len] <= L'9'){
|
|
num = s[len] - L'0';
|
|
}else if (s[len] >= L'a' && s[len] <= L'f'){
|
|
num = (s[len] - L'a') + 10;
|
|
}else if (s[len] >= L'A' && s[len] <= L'F'){
|
|
num = (s[len] - L'A') + 10;
|
|
}else if( s[len] == L'x' || s[len] == L'X'){
|
|
break;
|
|
}else{
|
|
continue;
|
|
}
|
|
|
|
hex += num * base;
|
|
base = base * 16;
|
|
}
|
|
return hex;
|
|
}
|
|
|
|
CEventTrace SystemEventTraceProv( PROVIDER_NAME_EVENTTRACE, L"root\\wmi" );
|
|
|
|
const static WCHAR* pEventTraceErrorClass = L"\\\\.\\root\\wmi:EventTraceError";
|
|
|
|
CEventTrace::CEventTrace (LPCWSTR lpwszName, LPCWSTR lpwszNameSpace ) :
|
|
Provider(lpwszName, lpwszNameSpace)
|
|
{
|
|
}
|
|
|
|
CEventTrace::~CEventTrace ()
|
|
{
|
|
}
|
|
|
|
HRESULT
|
|
CEventTrace::EnumerateInstances( MethodContext* pMethodContext, long lFlags )
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
ULONG i, nLoggers;
|
|
DWORD dwSize;
|
|
PEVENT_TRACE_PROPERTIES pLoggerInfo[MAXIMUM_LOGGERS];
|
|
PEVENT_TRACE_PROPERTIES pStorage;
|
|
PVOID Storage;
|
|
PVOID GuidStorage = NULL;
|
|
PTRACE_GUID_PROPERTIES* GuidPropertiesArray = NULL;
|
|
ULONG nGuidCount = 0;
|
|
|
|
dwSize = MAXIMUM_LOGGERS*(sizeof(EVENT_TRACE_PROPERTIES)+2*MAXSTR*sizeof(WCHAR));
|
|
|
|
Storage = G_ALLOC(dwSize);
|
|
if( Storage == NULL ){
|
|
return ERROR_OUTOFMEMORY;
|
|
}
|
|
|
|
RtlZeroMemory(Storage, dwSize);
|
|
|
|
pStorage = (PEVENT_TRACE_PROPERTIES)Storage;
|
|
|
|
for (i=0; i<MAXIMUM_LOGGERS; i++) {
|
|
|
|
pStorage->Wnode.BufferSize = sizeof(EVENT_TRACE_PROPERTIES)+2*MAXSTR*sizeof(WCHAR);
|
|
pStorage->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES)+MAXSTR*sizeof(WCHAR);
|
|
pStorage->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
|
|
|
|
pLoggerInfo[i] = pStorage;
|
|
|
|
pStorage = (PEVENT_TRACE_PROPERTIES)( (char*)pStorage + pStorage->Wnode.BufferSize);
|
|
}
|
|
|
|
hr = QueryAllTraces(
|
|
pLoggerInfo,
|
|
MAXIMUM_LOGGERS,
|
|
&nLoggers
|
|
);
|
|
|
|
if( ERROR_SUCCESS == hr ){
|
|
|
|
try{
|
|
if( ERROR_SUCCESS == LoadGuidArray( &GuidStorage, &nGuidCount ) ){
|
|
GuidPropertiesArray = (PTRACE_GUID_PROPERTIES *)GuidStorage;
|
|
}
|
|
|
|
for( i=0; i<nLoggers && i<MAXIMUM_LOGGERS; i++){
|
|
|
|
CInstancePtr pInstance( CreateNewInstance(pMethodContext), false );
|
|
|
|
assert( NULL != pLoggerInfo[i] );
|
|
|
|
if( NULL != pInstance ){
|
|
if( SUCCEEDED( LoadPropertyValues(pInstance, pLoggerInfo[i], GuidPropertiesArray, nGuidCount ) )){
|
|
hr = pInstance->Commit();
|
|
}
|
|
}
|
|
}
|
|
|
|
}catch(...){
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
}
|
|
|
|
G_FREE( GuidStorage );
|
|
G_FREE( Storage );
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CEventTrace::GetObject ( CInstance* pInstance, long lFlags )
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
PEVENT_TRACE_PROPERTIES pLoggerInfo = NULL;
|
|
TRACEHANDLE LoggerHandle = 0;
|
|
CHString LoggerName;
|
|
|
|
pInstance->GetCHString( L"Name", LoggerName );
|
|
|
|
hr = InitTraceProperties( &pLoggerInfo );
|
|
|
|
if( ERROR_SUCCESS != hr ){
|
|
return hr;
|
|
}
|
|
|
|
if( wcsncmp( (LPCWSTR)LoggerName, cszPrivateLogger, wcslen( cszPrivateLogger ) ) == 0 ){
|
|
GUID guid;
|
|
LPWSTR szPrivateGuid;
|
|
size_t cchSize;
|
|
|
|
szPrivateGuid = (LPWSTR)(LPCWSTR)LoggerName;
|
|
cchSize = wcslen( szPrivateGuid );
|
|
|
|
if( cchSize + 1 > wcslen( cszPrivateLogger ) ){
|
|
szPrivateGuid += wcslen( cszPrivateLogger ) + 1;
|
|
CLSIDFromString( szPrivateGuid, &guid );
|
|
|
|
pLoggerInfo->Wnode.Guid = guid;
|
|
pLoggerInfo->LogFileMode = EVENT_TRACE_PRIVATE_LOGGER_MODE;
|
|
|
|
hr = QueryTraceW( 0, NULL, pLoggerInfo);
|
|
|
|
}else{
|
|
hr = WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
}else{
|
|
|
|
hr = QueryTraceW( LoggerHandle, (LPCWSTR)LoggerName, pLoggerInfo);
|
|
}
|
|
|
|
if( ERROR_SUCCESS == hr ){
|
|
|
|
if( hr == ERROR_SUCCESS ){
|
|
|
|
PVOID GuidStorage = NULL;
|
|
PTRACE_GUID_PROPERTIES* GuidPropertiesArray = NULL;
|
|
ULONG nGuidCount = 0;
|
|
|
|
try{
|
|
if( ERROR_SUCCESS == LoadGuidArray( &GuidStorage, &nGuidCount ) ){
|
|
GuidPropertiesArray = (PTRACE_GUID_PROPERTIES *)GuidStorage;
|
|
}
|
|
|
|
hr = LoadPropertyValues( pInstance, pLoggerInfo, GuidPropertiesArray, nGuidCount );
|
|
}catch(...){
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
G_FREE( GuidStorage );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
G_FREE( pLoggerInfo );
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CEventTrace::LoadGuidArray( PVOID* Storage, PULONG pnGuidCount )
|
|
{
|
|
ULONG i;
|
|
ULONG nGuidArray = 16;
|
|
ULONG nGuidCount = 0;
|
|
DWORD dwSize;
|
|
PTRACE_GUID_PROPERTIES* GuidPropertiesArray;
|
|
PTRACE_GUID_PROPERTIES pStorage;
|
|
HRESULT hr;
|
|
|
|
do{
|
|
dwSize = nGuidArray * (sizeof(TRACE_GUID_PROPERTIES) + sizeof(PTRACE_GUID_PROPERTIES));
|
|
*Storage = G_ALLOC(dwSize);
|
|
if(*Storage == NULL){
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
break;
|
|
}
|
|
RtlZeroMemory(*Storage, dwSize);
|
|
GuidPropertiesArray = (PTRACE_GUID_PROPERTIES *)(*Storage);
|
|
pStorage = (PTRACE_GUID_PROPERTIES)((char*)(*Storage) + nGuidArray * sizeof(PTRACE_GUID_PROPERTIES));
|
|
for (i=0; i < nGuidArray; i++) {
|
|
GuidPropertiesArray[i] = pStorage;
|
|
pStorage = (PTRACE_GUID_PROPERTIES)((char*)pStorage + sizeof(TRACE_GUID_PROPERTIES));
|
|
}
|
|
|
|
hr = EnumerateTraceGuids(GuidPropertiesArray,nGuidArray,&nGuidCount);
|
|
|
|
if(hr == ERROR_MORE_DATA){
|
|
if( nGuidCount <= nGuidArray ){
|
|
hr = WBEM_E_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
nGuidArray = nGuidCount;
|
|
G_FREE(*Storage);
|
|
(*Storage) = NULL;
|
|
}
|
|
|
|
}while( hr == ERROR_MORE_DATA );
|
|
|
|
if( ERROR_SUCCESS == hr ){
|
|
*pnGuidCount = nGuidCount;
|
|
}else{
|
|
*pnGuidCount = 0;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CEventTrace::LoadPropertyValues(
|
|
CInstance *pInstanceParam,
|
|
PEVENT_TRACE_PROPERTIES pLoggerInfo,
|
|
PTRACE_GUID_PROPERTIES *GuidPropertiesArray,
|
|
ULONG nGuidCount
|
|
)
|
|
{
|
|
LPWSTR strName;
|
|
ULONG i;
|
|
CInstance* pInstance = pInstanceParam;
|
|
|
|
if( NULL == pLoggerInfo || NULL == pInstance ){
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
|
|
if( NULL != GuidPropertiesArray ){
|
|
SAFEARRAY *saGuids;
|
|
SAFEARRAY *saFlags;
|
|
SAFEARRAY *saLevel;
|
|
BSTR HUGEP *pGuidData;
|
|
DWORD HUGEP *pLevelData;
|
|
DWORD HUGEP *pFlagData;
|
|
|
|
ULONG nGuidIndex = 0;
|
|
ULONG nProviderGuids = 0;
|
|
|
|
if( pLoggerInfo->Wnode.Guid == SystemTraceControlGuid ){
|
|
nProviderGuids = 1;
|
|
}else{
|
|
for (i=0; i < nGuidCount; i++) {
|
|
if( pLoggerInfo->Wnode.HistoricalContext == GuidPropertiesArray[i]->LoggerId ){
|
|
nProviderGuids++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( nProviderGuids ){
|
|
|
|
saGuids = SafeArrayCreateVector( VT_BSTR, 0, nProviderGuids );
|
|
saFlags = SafeArrayCreateVector( VT_I4, 0, nProviderGuids );
|
|
saLevel = SafeArrayCreateVector( VT_I4, 0, nProviderGuids );
|
|
|
|
if( saGuids == NULL || saFlags == NULL || saLevel == NULL ){
|
|
if( saGuids != NULL ){
|
|
SafeArrayDestroy( saGuids );
|
|
}
|
|
if( saFlags != NULL ){
|
|
SafeArrayDestroy( saFlags );
|
|
}
|
|
if( saLevel != NULL ){
|
|
SafeArrayDestroy( saLevel );
|
|
}
|
|
}else{
|
|
|
|
SafeArrayAccessData( saGuids, (void HUGEP **)&pGuidData);
|
|
SafeArrayAccessData( saFlags, (void HUGEP **)&pFlagData);
|
|
SafeArrayAccessData( saLevel, (void HUGEP **)&pLevelData);
|
|
|
|
if( pLoggerInfo->Wnode.Guid == SystemTraceControlGuid ){
|
|
WCHAR buffer[128];
|
|
BSTR strGUID;
|
|
|
|
StringFromGUID2( SystemTraceControlGuid, buffer, 128 );
|
|
strGUID = SysAllocString( buffer );
|
|
|
|
pGuidData[0] = strGUID;
|
|
pLevelData[0] = 0;
|
|
pFlagData[0] = pLoggerInfo->EnableFlags;
|
|
|
|
}else{
|
|
for (i=0; i < nGuidCount; i++) {
|
|
|
|
if( pLoggerInfo->Wnode.HistoricalContext == GuidPropertiesArray[i]->LoggerId ){
|
|
|
|
WCHAR buffer[128];
|
|
BSTR strGUID;
|
|
|
|
StringFromGUID2( GuidPropertiesArray[i]->Guid, buffer, 128 );
|
|
strGUID = SysAllocString( buffer );
|
|
|
|
pGuidData[nGuidIndex] = strGUID;
|
|
pLevelData[nGuidIndex] = GuidPropertiesArray[i]->EnableLevel;
|
|
pFlagData[nGuidIndex] = GuidPropertiesArray[i]->EnableFlags;
|
|
|
|
nGuidIndex++;
|
|
}
|
|
}
|
|
}
|
|
|
|
SafeArrayUnaccessData( saGuids );
|
|
SafeArrayUnaccessData( saFlags );
|
|
SafeArrayUnaccessData( saLevel );
|
|
VARIANT vArray;
|
|
vArray.vt = VT_ARRAY|VT_I4;
|
|
|
|
pInstance->SetStringArray( L"Guid", *saGuids );
|
|
|
|
vArray.parray = saFlags;
|
|
pInstance->SetVariant( L"EnableFlags", vArray );
|
|
|
|
vArray.parray = saLevel;
|
|
pInstance->SetVariant( L"Level", vArray );
|
|
|
|
SafeArrayDestroy( saGuids );
|
|
SafeArrayDestroy( saFlags );
|
|
SafeArrayDestroy( saLevel );
|
|
}
|
|
}
|
|
}
|
|
|
|
pInstance->SetDWORD( L"BufferSize", pLoggerInfo->BufferSize );
|
|
pInstance->SetDWORD( L"MinimumBuffers", pLoggerInfo->MinimumBuffers );
|
|
pInstance->SetDWORD( L"MaximumBuffers", pLoggerInfo->MaximumBuffers );
|
|
pInstance->SetDWORD( L"MaximumFileSize", pLoggerInfo->MaximumFileSize );
|
|
pInstance->SetDWORD( L"FlushTimer", pLoggerInfo->FlushTimer );
|
|
pInstance->SetDWORD( L"AgeLimit", pLoggerInfo->AgeLimit );
|
|
pInstance->SetDWORD( L"LoggerId", pLoggerInfo->Wnode.HistoricalContext );
|
|
pInstance->SetDWORD( L"NumberOfBuffers", pLoggerInfo->NumberOfBuffers );
|
|
pInstance->SetDWORD( L"FreeBuffers", pLoggerInfo->FreeBuffers );
|
|
pInstance->SetDWORD( L"EventsLost", pLoggerInfo->EventsLost );
|
|
pInstance->SetDWORD( L"BuffersWritten", pLoggerInfo->BuffersWritten );
|
|
pInstance->SetDWORD( L"LogBuffersLost", pLoggerInfo->LogBuffersLost );
|
|
pInstance->SetDWORD( L"RealTimeBuffersLost",pLoggerInfo->RealTimeBuffersLost );
|
|
pInstance->SetDWORD( L"LoggerThreadId", HandleToUlong( pLoggerInfo->LoggerThreadId ) );
|
|
|
|
DecodePropertyValue(
|
|
pInstance,
|
|
L"LogFileMode",
|
|
&pLoggerInfo->LogFileMode,
|
|
DECODE_MODE_TRACE_TO_WBEM );
|
|
|
|
DecodePropertyValue(
|
|
pInstance,
|
|
L"ClockType",
|
|
&pLoggerInfo->Wnode.ClientContext,
|
|
DECODE_MODE_TRACE_TO_WBEM );
|
|
|
|
strName = (LPWSTR)((char*)pLoggerInfo+pLoggerInfo->LoggerNameOffset);
|
|
pInstance->SetCHString( L"Name", strName );
|
|
|
|
strName = (LPWSTR)((char*)pLoggerInfo+pLoggerInfo->LogFileNameOffset );
|
|
pInstance->SetCHString( L"LogFileName", strName );
|
|
|
|
return WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
HRESULT
|
|
CEventTrace::DecodePropertyValue(
|
|
CInstance* pInstance,
|
|
LPCWSTR szProperty,
|
|
DWORD* pdwValue,
|
|
DWORD dwFlags )
|
|
{
|
|
HRESULT hr = ERROR_SUCCESS;
|
|
|
|
DWORD dwValue = 0;
|
|
CHString Property;
|
|
DWORD dwValueType = VALUETYPE_INDEX;
|
|
|
|
if( NULL == pdwValue ){
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
if( dwFlags & DECODE_MODE_WBEM_TO_TRACE ){
|
|
*pdwValue = 0;
|
|
pInstance->GetCHString( szProperty, Property );
|
|
|
|
if( ! Property.GetLength() ){
|
|
return hr;
|
|
}
|
|
}else{
|
|
dwValue = *pdwValue;
|
|
}
|
|
|
|
IWbemClassObject* pClass = pInstance->GetClassObjectInterface();
|
|
|
|
if( pClass != NULL ){
|
|
const ULONG cchBuffer = 1024;
|
|
WCHAR buffer[cchBuffer] = L"";
|
|
LONG nFlavor;
|
|
VARIANT var;
|
|
SAFEARRAY* saValues = NULL;
|
|
SAFEARRAY* saValueMap = NULL;
|
|
|
|
IWbemQualifierSet *pQualSet = NULL;
|
|
pClass->GetPropertyQualifierSet( szProperty, &pQualSet );
|
|
if( pQualSet != NULL ){
|
|
hr = pQualSet->Get( L"ValueMap", 0, &var, &nFlavor );
|
|
if( ERROR_SUCCESS == hr && (var.vt & VT_ARRAY) ){
|
|
saValueMap = var.parray;
|
|
}
|
|
|
|
hr = pQualSet->Get( L"Values", 0, &var, &nFlavor );
|
|
if( SUCCEEDED(hr) && (var.vt & VT_ARRAY) ){
|
|
saValues = var.parray;
|
|
}
|
|
|
|
hr = pQualSet->Get( L"ValueType", 0, &var, &nFlavor );
|
|
if( SUCCEEDED(hr) ){
|
|
if( _wcsicmp( var.bstrVal, L"index" ) == 0 ){
|
|
dwValueType = VALUETYPE_INDEX;
|
|
}
|
|
if( _wcsicmp( var.bstrVal, L"flag") == 0 ){
|
|
dwValueType = VALUETYPE_FLAG;
|
|
}
|
|
}
|
|
|
|
if( saValues != NULL && saValueMap != NULL ){
|
|
BSTR HUGEP *pMapData;
|
|
BSTR HUGEP *pValuesData;
|
|
LONG uMapBound, lMapBound;
|
|
LONG uValuesBound, lValuesBound;
|
|
|
|
hr = SafeArrayGetUBound( saValueMap, 1, &uMapBound );
|
|
if( SUCCEEDED(hr) ){
|
|
hr = SafeArrayGetLBound( saValueMap, 1, &lMapBound );
|
|
}
|
|
if( SUCCEEDED(hr) ){
|
|
hr = SafeArrayAccessData( saValueMap, (void HUGEP **)&pMapData );
|
|
}
|
|
|
|
if( SUCCEEDED(hr) ){
|
|
hr = SafeArrayGetUBound( saValues, 1, &uValuesBound );
|
|
}
|
|
if( SUCCEEDED(hr) ){
|
|
hr = SafeArrayGetLBound( saValues, 1, &lValuesBound );
|
|
}
|
|
if( SUCCEEDED(hr) ){
|
|
hr = SafeArrayAccessData( saValues, (void HUGEP **)&pValuesData );
|
|
}
|
|
|
|
for ( LONG i=lMapBound; i<=uMapBound && SUCCEEDED(hr); i++) {
|
|
LONG dwFlag;
|
|
|
|
if( i<lValuesBound || i>uValuesBound ){
|
|
break;
|
|
}
|
|
dwFlag = hextoi( pMapData[i] );
|
|
if( dwFlags & DECODE_MODE_WBEM_TO_TRACE ){
|
|
|
|
if( FindString( pValuesData[i], (LPCWSTR)Property ) ){
|
|
switch( dwValueType ){
|
|
case VALUETYPE_INDEX:
|
|
dwValue = dwFlag;
|
|
break;
|
|
case VALUETYPE_FLAG:
|
|
dwValue |= dwFlag;
|
|
break;
|
|
}
|
|
}
|
|
|
|
}else{
|
|
BOOL bValue = FALSE;
|
|
|
|
switch( dwValueType ){
|
|
case VALUETYPE_INDEX:
|
|
bValue = (dwFlag == dwValue);
|
|
break;
|
|
case VALUETYPE_FLAG:
|
|
bValue = ((dwFlag & dwValue) == dwFlag );
|
|
break;
|
|
}
|
|
|
|
if( bValue ){
|
|
|
|
if( wcslen(buffer) ){
|
|
hr = StringCchCat( buffer, cchBuffer, L"|" );
|
|
}
|
|
if( SUCCEEDED( hr ) ){
|
|
hr = StringCchCat( buffer, cchBuffer, pValuesData[i] );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
SafeArrayUnaccessData( saValueMap );
|
|
SafeArrayUnaccessData( saValues );
|
|
|
|
SafeArrayDestroy( saValueMap );
|
|
SafeArrayDestroy( saValues );
|
|
|
|
if( dwFlags & DECODE_MODE_TRACE_TO_WBEM ){
|
|
if( wcslen( buffer ) ){
|
|
pInstance->SetCHString( szProperty, buffer );
|
|
}else{
|
|
hr = pQualSet->Get( L"DefaultValue", 0, &var, &nFlavor );
|
|
if( ERROR_SUCCESS == hr && VT_BSTR == var.vt ){
|
|
pInstance->SetCHString( szProperty, var.bstrVal );
|
|
VariantClear( &var );
|
|
}
|
|
}
|
|
}else if( dwFlags & DECODE_MODE_WBEM_TO_TRACE ){
|
|
*pdwValue = dwValue;
|
|
}
|
|
|
|
}
|
|
|
|
pQualSet->Release();
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CEventTrace::PutInstance ( const CInstance &Instance, long lFlags )
|
|
{
|
|
HRESULT hr = WBEM_E_UNSUPPORTED_PARAMETER;
|
|
|
|
CHString LoggerName;
|
|
CHString LogFileName;
|
|
SAFEARRAY *saGuids = NULL;
|
|
SAFEARRAY *saLevel = NULL;
|
|
SAFEARRAY *saFlags = NULL;
|
|
GUID guid = {0};
|
|
|
|
DWORD dwValue;
|
|
|
|
LPWSTR strName;
|
|
LPWSTR strFile;
|
|
|
|
PEVENT_TRACE_PROPERTIES pLoggerInfo = NULL;
|
|
TRACEHANDLE LoggerHandle = 0;
|
|
BSTR HUGEP *pGuidData;
|
|
VARIANT vArray;
|
|
LONG lBound;
|
|
|
|
if ( !(lFlags & WBEM_FLAG_CREATE_ONLY|WBEM_FLAG_UPDATE_ONLY ) ){
|
|
return hr;
|
|
}
|
|
|
|
hr = InitTraceProperties( &pLoggerInfo );
|
|
if( hr != ERROR_SUCCESS ){
|
|
return hr;
|
|
}
|
|
|
|
Instance.GetCHString( L"Name", LoggerName );
|
|
strName = (LPWSTR)((char*)pLoggerInfo + pLoggerInfo->LoggerNameOffset );
|
|
hr = StringCchCopy( strName, MAXSTR, (LPCWSTR)LoggerName );
|
|
if( FAILED(hr) ){
|
|
return hr;
|
|
}
|
|
|
|
Instance.GetCHString( L"LogFileName", LogFileName );
|
|
strFile = (LPWSTR)((char*)pLoggerInfo + pLoggerInfo->LogFileNameOffset );
|
|
hr = StringCchCopy( strFile, MAXSTR, (LPCWSTR)LogFileName );
|
|
if( FAILED(hr) ){
|
|
return hr;
|
|
}
|
|
|
|
Instance.GetDWORD( L"BufferSize", pLoggerInfo->BufferSize );
|
|
Instance.GetDWORD( L"MinimumBuffers", pLoggerInfo->MinimumBuffers );
|
|
Instance.GetDWORD( L"MaximumBuffers", pLoggerInfo->MaximumBuffers );
|
|
Instance.GetDWORD( L"MaximumFileSize", pLoggerInfo->MaximumFileSize );
|
|
Instance.GetDWORD( L"FlushTimer", pLoggerInfo->FlushTimer );
|
|
|
|
hr = DecodePropertyValue(
|
|
(CInstance*)&Instance,
|
|
L"LogFileMode",
|
|
&dwValue,
|
|
DECODE_MODE_WBEM_TO_TRACE );
|
|
|
|
if( SUCCEEDED(hr) ){
|
|
pLoggerInfo->LogFileMode = dwValue;
|
|
}
|
|
|
|
hr = DecodePropertyValue(
|
|
(CInstance*)&Instance,
|
|
L"ClockType",
|
|
&dwValue,
|
|
DECODE_MODE_WBEM_TO_TRACE );
|
|
|
|
if( SUCCEEDED(hr) ){
|
|
pLoggerInfo->Wnode.ClientContext = dwValue;
|
|
}
|
|
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
if(! Instance.GetStringArray( L"Guid", saGuids ) ){
|
|
saGuids = NULL;
|
|
}
|
|
|
|
Instance.GetVariant( L"EnableFlags", vArray );
|
|
if( VT_NULL != vArray.vt ){
|
|
saFlags = vArray.parray;
|
|
}
|
|
|
|
Instance.GetVariant( L"Level", vArray );
|
|
if( VT_NULL != vArray.vt ){
|
|
saLevel = vArray.parray;
|
|
}
|
|
|
|
if( saGuids != NULL ){
|
|
|
|
//
|
|
// Need to check the guids now in case it
|
|
// is the kernel logger. The kernel logger
|
|
// is handled differently for both Create and Update
|
|
//
|
|
|
|
hr = SafeArrayGetLBound( saGuids, 1, &lBound );
|
|
if( SUCCEEDED(hr) ){
|
|
hr = SafeArrayAccessData( saGuids, (void HUGEP **)&pGuidData );
|
|
}
|
|
if( SUCCEEDED(hr) ){
|
|
CLSIDFromString( pGuidData[lBound], &guid );
|
|
SafeArrayUnaccessData( saGuids );
|
|
}
|
|
}
|
|
|
|
BOOL bSystemLogger = IsEqualGUID( gCritSecGuid, guid ) || IsEqualGUID( gHeapGuid, guid );
|
|
|
|
if (lFlags & WBEM_FLAG_CREATE_ONLY){
|
|
|
|
if( IsEqualGUID( guid, SystemTraceControlGuid ) || bSystemLogger ){
|
|
|
|
ULONG offset = sizeof(EVENT_TRACE_PROPERTIES) + 2 * MAXSTR * sizeof(WCHAR);
|
|
|
|
pLoggerInfo->Wnode.Guid = guid;
|
|
|
|
if( bSystemLogger ){
|
|
pLoggerInfo->LogFileMode |= EVENT_TRACE_PRIVATE_LOGGER_MODE;
|
|
pLoggerInfo->Wnode.HistoricalContext = 0x1000001;
|
|
}
|
|
|
|
hr = EtsSetExtendedFlags(
|
|
saFlags,
|
|
pLoggerInfo,
|
|
offset
|
|
);
|
|
|
|
hr = StartTrace( &LoggerHandle, (LPCWSTR)LoggerName, pLoggerInfo );
|
|
|
|
if( ERROR_SUCCESS == hr && bSystemLogger ){
|
|
hr = WmiEnableTrace( Instance, TRUE, saFlags, saLevel, saGuids, LoggerHandle );
|
|
}
|
|
|
|
}else if( LoggerName.CompareNoCase( cszGlobalLogger) == 0 ){
|
|
hr = StartGlobalLogger( pLoggerInfo );
|
|
}else{
|
|
if( pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE ){
|
|
pLoggerInfo->Wnode.Guid = guid;
|
|
}
|
|
|
|
hr = StartTrace( &LoggerHandle, (LPCWSTR)LoggerName, pLoggerInfo );
|
|
|
|
if( ERROR_SUCCESS == hr ){
|
|
hr = WmiEnableTrace( Instance, TRUE, saFlags, saLevel, saGuids, LoggerHandle );
|
|
}
|
|
}
|
|
|
|
}else if( lFlags & WBEM_FLAG_UPDATE_ONLY ){
|
|
|
|
Instance.GetWBEMINT64( L"LoggerId", LoggerHandle );
|
|
|
|
if( IsEqualGUID( guid, SystemTraceControlGuid ) || bSystemLogger ){
|
|
|
|
//
|
|
// The kernel logger does not use EnableTrace.
|
|
// Set the flags and call Update Only
|
|
//
|
|
|
|
ULONG offset = sizeof(EVENT_TRACE_PROPERTIES) + 2 * MAXSTR * sizeof(WCHAR);
|
|
|
|
hr = EtsSetExtendedFlags(
|
|
saFlags,
|
|
pLoggerInfo,
|
|
offset
|
|
);
|
|
|
|
if( bSystemLogger ){
|
|
pLoggerInfo->Wnode.Guid = guid;
|
|
}
|
|
|
|
hr = UpdateTrace( LoggerHandle, (LPCWSTR)LoggerName, pLoggerInfo );
|
|
|
|
}else{
|
|
|
|
hr = UpdateTrace( LoggerHandle, (LPCWSTR)LoggerName, pLoggerInfo );
|
|
if( ERROR_SUCCESS == hr ){
|
|
hr = WmiEnableTrace( Instance, TRUE, saFlags, saLevel, saGuids, LoggerHandle );
|
|
}
|
|
}
|
|
}
|
|
|
|
if( NULL != saGuids ){
|
|
SafeArrayDestroy( saGuids );
|
|
}
|
|
if( NULL != saFlags ){
|
|
SafeArrayDestroy( saFlags );
|
|
}
|
|
if( NULL != saLevel ){
|
|
SafeArrayDestroy( saLevel );
|
|
}
|
|
|
|
G_FREE( pLoggerInfo );
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CEventTrace::InitTraceProperties( PEVENT_TRACE_PROPERTIES* ppLoggerInfo )
|
|
{
|
|
PEVENT_TRACE_PROPERTIES pLoggerInfo = NULL;
|
|
|
|
DWORD dwSize = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(WCHAR)*MAXSTR*2 + EtsGetMaxEnableFlags() * sizeof(ULONG);
|
|
|
|
pLoggerInfo = (PEVENT_TRACE_PROPERTIES)G_ALLOC( dwSize );
|
|
|
|
if( NULL == pLoggerInfo ){
|
|
return ERROR_OUTOFMEMORY;
|
|
}
|
|
|
|
ZeroMemory( pLoggerInfo, dwSize );
|
|
pLoggerInfo->Wnode.BufferSize = dwSize;
|
|
pLoggerInfo->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
|
|
pLoggerInfo->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
|
|
pLoggerInfo->LogFileNameOffset = pLoggerInfo->LoggerNameOffset+MAXSTR*sizeof(WCHAR);
|
|
|
|
*ppLoggerInfo = pLoggerInfo;
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
HRESULT
|
|
CEventTrace::WmiEnableTrace(
|
|
const CInstance &Instance,
|
|
bool bEnable,
|
|
SAFEARRAY *saFlags,
|
|
SAFEARRAY *saLevel,
|
|
SAFEARRAY *saGuid,
|
|
TRACEHANDLE LoggerHandle
|
|
)
|
|
{
|
|
HRESULT hr = ERROR_SUCCESS;
|
|
|
|
BSTR HUGEP *pGuidData = NULL;
|
|
DWORD HUGEP *pFlagData = NULL;
|
|
DWORD HUGEP *pLevelData = NULL;
|
|
LONG lGuidBound,uGuidBound;
|
|
LONG lFlagBound,uFlagBound;
|
|
LONG lLevelBound,uLevelBound;
|
|
|
|
if( NULL == saGuid ){
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
hr = SafeArrayGetUBound( saGuid, 1, &uGuidBound );
|
|
if( FAILED(hr) ){ return hr; }
|
|
|
|
hr = SafeArrayGetLBound( saGuid, 1, &lGuidBound );
|
|
if( FAILED(hr) ){ return hr; }
|
|
|
|
hr = SafeArrayAccessData( saGuid, (void HUGEP **)&pGuidData );
|
|
if( FAILED(hr) ){ return hr; }
|
|
|
|
if( saFlags != NULL ){
|
|
hr = SafeArrayGetUBound( saFlags, 1, &uFlagBound );
|
|
if( SUCCEEDED(hr) ){
|
|
hr = SafeArrayGetLBound( saFlags, 1, &lFlagBound );
|
|
}
|
|
if( SUCCEEDED(hr) ){
|
|
hr = SafeArrayAccessData( saFlags, (void HUGEP **)&pFlagData );
|
|
}
|
|
}
|
|
if( NULL == saFlags || FAILED(hr) ){
|
|
uFlagBound = 0;
|
|
lFlagBound = 0;
|
|
}
|
|
|
|
if( saLevel != NULL ){
|
|
hr = SafeArrayGetUBound( saLevel, 1, &uLevelBound );
|
|
if(SUCCEEDED(hr) ){
|
|
hr = SafeArrayGetLBound( saLevel, 1, &lLevelBound );
|
|
}
|
|
if(SUCCEEDED(hr) ){
|
|
hr = SafeArrayAccessData( saLevel, (void HUGEP **)&pLevelData );
|
|
}
|
|
}
|
|
if( NULL == saLevel || FAILED(hr) ){
|
|
uLevelBound = 0;
|
|
lLevelBound = 0;
|
|
}
|
|
|
|
for ( LONG i=lGuidBound; i<=uGuidBound; i++) {
|
|
|
|
GUID guid;
|
|
DWORD dwLevel = 0;
|
|
DWORD dwFlags = 0;
|
|
|
|
if( pGuidData[i] == NULL ){
|
|
continue;
|
|
}
|
|
|
|
if( SUCCEEDED( CLSIDFromString( pGuidData[i], &guid ) ) ){
|
|
|
|
if( i>=lLevelBound && i<=uLevelBound && saLevel != NULL ){
|
|
if( NULL != pLevelData ){
|
|
dwLevel = pLevelData[i];
|
|
}
|
|
}
|
|
if( i>=lFlagBound && i<=uFlagBound && saFlags != NULL ){
|
|
if( NULL != pFlagData ){
|
|
dwFlags = pFlagData[i];
|
|
}
|
|
}
|
|
|
|
hr = EnableTrace( bEnable, dwFlags, dwLevel, &guid, LoggerHandle );
|
|
|
|
if(IsEqualGUID( gCritSecGuid, guid ) || IsEqualGUID( gHeapGuid, guid )){
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
SafeArrayUnaccessData( saGuid );
|
|
|
|
if( saFlags != NULL ){
|
|
SafeArrayUnaccessData( saFlags );
|
|
}
|
|
if( saLevel != NULL ){
|
|
SafeArrayUnaccessData( saLevel );
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CEventTrace::WmiFlushTrace( const CInstance &Instance )
|
|
{
|
|
HRESULT hr;
|
|
|
|
PEVENT_TRACE_PROPERTIES pLoggerInfo = NULL;
|
|
TRACEHANDLE LoggerHandle = 0;
|
|
|
|
CHString LoggerName;
|
|
|
|
hr = InitTraceProperties( &pLoggerInfo );
|
|
|
|
if( hr == ERROR_SUCCESS ){
|
|
|
|
Instance.GetCHString( L"Name", LoggerName );
|
|
Instance.GetWBEMINT64( L"LoggerId", LoggerHandle );
|
|
|
|
hr = ::FlushTraceW( LoggerHandle, (LPCWSTR)LoggerName, pLoggerInfo );
|
|
|
|
G_FREE( pLoggerInfo );
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CEventTrace::WmiStopTrace( const CInstance &Instance )
|
|
{
|
|
HRESULT hr;
|
|
|
|
CHString LoggerName;
|
|
SAFEARRAY *saGuids = NULL;
|
|
LONG nGuidCount,i;
|
|
GUID guid;
|
|
|
|
PEVENT_TRACE_PROPERTIES pLoggerInfo = NULL;
|
|
TRACEHANDLE LoggerHandle = 0;
|
|
BSTR HUGEP *pData;
|
|
|
|
Instance.GetCHString( L"Name", LoggerName );
|
|
hr = InitTraceProperties( &pLoggerInfo );
|
|
|
|
if( ERROR_SUCCESS != hr ){
|
|
return hr;
|
|
}
|
|
|
|
if( wcsncmp( (LPCWSTR)LoggerName, cszPrivateLogger, wcslen( cszPrivateLogger ) ) == 0 ){
|
|
|
|
LPWSTR szPrivateGuid;
|
|
size_t cchSize;
|
|
szPrivateGuid = (LPWSTR)(LPCWSTR)LoggerName;
|
|
cchSize = wcslen( szPrivateGuid );
|
|
if( cchSize + 1 > wcslen( cszPrivateLogger ) ){
|
|
szPrivateGuid += wcslen( cszPrivateLogger ) + 1;
|
|
CLSIDFromString( szPrivateGuid, &guid );
|
|
|
|
pLoggerInfo->Wnode.Guid = guid;
|
|
pLoggerInfo->LogFileMode = EVENT_TRACE_PRIVATE_LOGGER_MODE;
|
|
|
|
hr = ::StopTrace( 0, (LPCWSTR)LoggerName, pLoggerInfo );
|
|
}else{
|
|
hr = WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
}else{
|
|
|
|
Instance.GetWBEMINT64( L"LoggerId", LoggerHandle );
|
|
Instance.GetStringArray( L"Guid", saGuids );
|
|
|
|
if( NULL != saGuids ){
|
|
|
|
hr = SafeArrayGetUBound( saGuids, 0, &nGuidCount );
|
|
if( SUCCEEDED(hr) ){
|
|
hr = SafeArrayAccessData( saGuids, (void HUGEP **)&pData );
|
|
}
|
|
|
|
if( SUCCEEDED(hr) ){
|
|
for (i=0; i<nGuidCount; i++) {
|
|
CLSIDFromString( pData[i], &guid );
|
|
hr = EnableTrace( FALSE, 0, 0, &guid, LoggerHandle );
|
|
}
|
|
|
|
SafeArrayUnaccessData( saGuids );
|
|
}
|
|
|
|
SafeArrayDestroy( saGuids );
|
|
}
|
|
|
|
hr = ::StopTraceW( LoggerHandle, (LPCWSTR)LoggerName, pLoggerInfo );
|
|
|
|
if( LoggerName.CompareNoCase( cszGlobalLogger ) == 0 ){
|
|
hr = DeleteGlobalLogger( pLoggerInfo );
|
|
}
|
|
|
|
G_FREE( pLoggerInfo );
|
|
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CEventTrace::StartGlobalLogger(
|
|
IN PEVENT_TRACE_PROPERTIES pLoggerInfo
|
|
)
|
|
{
|
|
return (SetGlobalLoggerSettings( 1L, pLoggerInfo, 0 ));
|
|
}
|
|
|
|
HRESULT
|
|
CEventTrace::DeleteGlobalLogger(
|
|
IN PEVENT_TRACE_PROPERTIES pLoggerInfo
|
|
)
|
|
{
|
|
return (SetGlobalLoggerSettings( 0L, pLoggerInfo, 0 ) );
|
|
}
|
|
|
|
HRESULT
|
|
CEventTrace::ExecMethod(
|
|
const CInstance& Instance,
|
|
const BSTR bstrMethodName,
|
|
CInstance *pInParams,
|
|
CInstance *pOutParams,
|
|
long lFlags
|
|
)
|
|
{
|
|
HRESULT hr = WBEM_E_PROVIDER_NOT_CAPABLE;
|
|
HRESULT hResult = ERROR_SUCCESS;
|
|
|
|
if( _wcsicmp( bstrMethodName, L"FlushTrace") == 0 ){
|
|
hResult = WmiFlushTrace( Instance );
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
if( _wcsicmp( bstrMethodName, L"StopTrace") == 0 ){
|
|
hResult = WmiStopTrace( Instance );
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
if( _wcsicmp( bstrMethodName, L"EnableTrace") == 0 ){
|
|
|
|
bool bEnable;
|
|
SAFEARRAY *saGuids = NULL;
|
|
SAFEARRAY *saLevel = NULL;
|
|
SAFEARRAY *saFlags = NULL;
|
|
VARIANT vArray;
|
|
TRACEHANDLE LoggerHandle;
|
|
|
|
pInParams->Getbool( L"Enable", bEnable );
|
|
|
|
pInParams->GetStringArray( L"Guid", saGuids );
|
|
pInParams->GetVariant( L"Flags", vArray );
|
|
saFlags = vArray.parray;
|
|
pInParams->GetVariant( L"Level", vArray );
|
|
saLevel = vArray.parray;
|
|
|
|
Instance.GetWBEMINT64( L"LoggerId", LoggerHandle );
|
|
|
|
hResult = WmiEnableTrace( Instance, bEnable, saFlags, saLevel, saGuids, LoggerHandle );
|
|
|
|
if( NULL != saGuids ){
|
|
SafeArrayDestroy( saGuids );
|
|
}
|
|
if( NULL != saFlags ){
|
|
SafeArrayDestroy( saFlags );
|
|
}
|
|
if( NULL != saLevel ){
|
|
SafeArrayDestroy( saLevel );
|
|
}
|
|
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
pOutParams->SetDWORD( L"ReturnValue", hResult );
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
|