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.
620 lines
19 KiB
620 lines
19 KiB
/*++
|
|
|
|
Copyright (C) 1998-1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
smtprov.cpp
|
|
|
|
Abstract:
|
|
|
|
This object is used to store the list of all current
|
|
trace providers in the system.
|
|
|
|
--*/
|
|
|
|
#include "Stdafx.h"
|
|
#include <wbemidl.h>
|
|
#include <initguid.h>
|
|
#include <wmistr.h>
|
|
#include <evntrace.h>
|
|
#include "smtracsv.h"
|
|
#include "smtprov.h"
|
|
|
|
USE_HANDLE_MACROS("SMLOGCFG(smtprov.cpp)");
|
|
|
|
#define WIN32_FROM_HRESULT(x)((x) & 0x0000FFFF)
|
|
|
|
LPCWSTR CSmTraceProviders::m_cszBackslash = L"\\";
|
|
LPCWSTR CSmTraceProviders::m_cszKernelLogger = KERNEL_LOGGER_NAMEW; // From evntrace.h
|
|
LPCWSTR CSmTraceProviders::m_cszDefaultNamespace = L"root\\wmi";
|
|
LPCWSTR CSmTraceProviders::m_cszTraceProviderClass = L"EventTrace";
|
|
LPCWSTR CSmTraceProviders::m_cszDescription = L"Description";
|
|
LPCWSTR CSmTraceProviders::m_cszGuid = L"Guid";
|
|
|
|
//
|
|
// Constructor
|
|
CSmTraceProviders::CSmTraceProviders ( CSmTraceLogService* pSvc )
|
|
: m_pWbemServices ( NULL ),
|
|
m_pTraceLogService ( pSvc ),
|
|
m_iBootState ( -1 )
|
|
{
|
|
m_KernelTraceProvider.strDescription = L"";
|
|
m_KernelTraceProvider.strGuid = L"";
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Destructor
|
|
CSmTraceProviders::~CSmTraceProviders ( )
|
|
{
|
|
ASSERT ( 0 == (INT)m_arrGenTraceProvider.GetSize ( ) );
|
|
m_arrGenTraceProvider.RemoveAll ( );
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Open function. Initialize provider array from Wbem.
|
|
//
|
|
DWORD
|
|
CSmTraceProviders::Open ( const CString& rstrMachineName )
|
|
{
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
DWORD dwLength;
|
|
CString strTemp;
|
|
|
|
MFC_TRY
|
|
if ( !rstrMachineName.IsEmpty ( ) ) {
|
|
m_strMachineName = rstrMachineName;
|
|
if ( 0 != lstrcmpi ( m_cszBackslash, m_strMachineName.Left(1) ) ) {
|
|
strTemp = m_cszBackslash;
|
|
strTemp += m_cszBackslash;
|
|
m_strMachineName = strTemp + m_strMachineName;
|
|
}
|
|
} else {
|
|
|
|
// get the local machine name & default name space if the caller
|
|
// has passed in a NULL machine name
|
|
|
|
dwLength = MAX_COMPUTERNAME_LENGTH + 1;
|
|
|
|
if ( GetComputerName (
|
|
m_strMachineName.GetBufferSetLength( dwLength ),
|
|
&dwLength ) ) {
|
|
m_strMachineName.ReleaseBuffer();
|
|
strTemp = m_cszBackslash;
|
|
strTemp += m_cszBackslash;
|
|
m_strMachineName = strTemp + m_strMachineName;
|
|
} else {
|
|
dwStatus = GetLastError();
|
|
m_strMachineName.ReleaseBuffer();
|
|
}
|
|
}
|
|
MFC_CATCH_DWSTATUS
|
|
|
|
if ( ERROR_SUCCESS != dwStatus ) {
|
|
m_strMachineName.Empty();
|
|
}
|
|
|
|
return dwStatus;
|
|
}
|
|
|
|
//
|
|
// Close Function
|
|
// Frees allocated memory
|
|
//
|
|
DWORD
|
|
CSmTraceProviders::Close ( )
|
|
{
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
|
|
m_arrGenTraceProvider.RemoveAll ( );
|
|
|
|
if ( NULL != m_pWbemServices ) {
|
|
m_pWbemServices->Release ( );
|
|
m_pWbemServices = NULL;
|
|
}
|
|
|
|
return dwStatus;
|
|
}
|
|
|
|
//
|
|
// AddProvider
|
|
// Add the specified provider strings to the array
|
|
//
|
|
DWORD
|
|
CSmTraceProviders::AddProvider (
|
|
const CString& rstrDescription,
|
|
const CString& rstrGuid,
|
|
INT iIsEnabled,
|
|
INT iIsActive )
|
|
{
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
|
|
SLQ_TRACE_PROVIDER slqTProv;
|
|
|
|
// If inactive, cannot be enabled.
|
|
ASSERT ( ( 0 == iIsActive ) ? ( 0 == iIsEnabled ) : TRUE );
|
|
|
|
MFC_TRY
|
|
slqTProv.strDescription = rstrDescription;
|
|
slqTProv.strGuid = rstrGuid;
|
|
slqTProv.iIsEnabled = iIsEnabled;
|
|
slqTProv.iIsActive = iIsActive;
|
|
|
|
m_arrGenTraceProvider.Add( slqTProv );
|
|
MFC_CATCH_DWSTATUS
|
|
|
|
return dwStatus;
|
|
}
|
|
|
|
|
|
//
|
|
// ConnectToServer
|
|
// Connects to the Wbem server.
|
|
//
|
|
HRESULT
|
|
CSmTraceProviders::ConnectToServer ( void )
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
|
|
if ( NULL == m_pWbemServices ) {
|
|
IWbemLocator *pWbemLocator = NULL;
|
|
IWbemServices *pWbemServices = NULL;
|
|
|
|
// connect to locator
|
|
hr = CoCreateInstance (
|
|
CLSID_WbemLocator,
|
|
0,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IWbemLocator,
|
|
( LPVOID * )&pWbemLocator );
|
|
|
|
if ( SUCCEEDED (hr) ) {
|
|
BSTR bstrTemp = NULL;
|
|
CString strNamespace;
|
|
|
|
MFC_TRY
|
|
strNamespace = m_strMachineName;
|
|
strNamespace += m_cszBackslash;
|
|
strNamespace += m_cszDefaultNamespace;
|
|
bstrTemp = strNamespace.AllocSysString();
|
|
MFC_CATCH_HR
|
|
|
|
if ( SUCCEEDED ( hr ) ) {
|
|
// try to connect to the service
|
|
hr = pWbemLocator->ConnectServer (
|
|
bstrTemp,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
0L,
|
|
0,
|
|
0,
|
|
&pWbemServices );
|
|
|
|
::SysFreeString ( bstrTemp );
|
|
}
|
|
|
|
if ( SUCCEEDED ( hr ) ) {
|
|
hr = CoSetProxyBlanket((IUnknown*)pWbemServices,
|
|
RPC_C_AUTHN_WINNT,
|
|
RPC_C_AUTHZ_NONE,
|
|
NULL,
|
|
RPC_C_AUTHN_LEVEL_PKT,
|
|
RPC_C_IMP_LEVEL_IMPERSONATE,
|
|
NULL,
|
|
EOAC_NONE);
|
|
}
|
|
// free the locator
|
|
pWbemLocator->Release ( );
|
|
}
|
|
|
|
if ( SUCCEEDED ( hr ) ) {
|
|
m_pWbemServices = pWbemServices;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// GetBootState
|
|
// Connects to the registry.
|
|
//
|
|
HRESULT
|
|
CSmTraceProviders::GetBootState ( INT& riBootState )
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
|
|
if ( -1 == m_iBootState ) {
|
|
HKEY hKeyMachine;
|
|
|
|
ASSERT ( NULL != m_pTraceLogService );
|
|
|
|
hKeyMachine = m_pTraceLogService->GetMachineKey ( );
|
|
|
|
if ( NULL != hKeyMachine ) {
|
|
HKEY hKeyOption;
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
|
|
dwStatus = RegOpenKeyEx (
|
|
hKeyMachine,
|
|
(LPCWSTR)L"System\\CurrentControlSet\\Control\\Safeboot\\Option",
|
|
0,
|
|
KEY_READ,
|
|
&hKeyOption );
|
|
|
|
// The Option key and OptionValue value only exist if booting in
|
|
// safe mode, so failure indicates Normal mode (0).
|
|
// Safe mode = 1, Safe mode with network = 2.
|
|
if ( ERROR_SUCCESS == dwStatus ) {
|
|
DWORD dwType = 0;
|
|
DWORD dwBufSize = sizeof (INT );
|
|
|
|
dwStatus = RegQueryValueExW (
|
|
hKeyOption,
|
|
L"OptionValue",
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)&m_iBootState,
|
|
&dwBufSize);
|
|
|
|
if ( ERROR_SUCCESS != dwStatus ) {
|
|
// Normal mode
|
|
m_iBootState = 0;
|
|
}
|
|
RegCloseKey(hKeyOption);
|
|
} else {
|
|
// Normal mode
|
|
m_iBootState = 0;
|
|
}
|
|
|
|
} else {
|
|
// Unable to access registry
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
}
|
|
|
|
riBootState = m_iBootState;
|
|
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// SyncWithConfiguration
|
|
// Reads the current list of providers from Wbem
|
|
// and reloads the internal values to match
|
|
//
|
|
HRESULT
|
|
CSmTraceProviders::SyncWithConfiguration ( void )
|
|
{
|
|
typedef struct _LOG_INFO {
|
|
EVENT_TRACE_PROPERTIES Properties;
|
|
WCHAR szLoggerName[MAX_PATH+1]; // Must follow Properties
|
|
} LOG_INFO, FAR* PLOG_INFO;
|
|
|
|
IEnumWbemClassObject *pEnumProviders = NULL;
|
|
CString strDescription;
|
|
CString strGuid;
|
|
CString strBracketedGuid;
|
|
BSTR bstrTemp;
|
|
INT iIndex;
|
|
INT iIsEnabled =0;
|
|
HRESULT hr;
|
|
|
|
PTRACE_GUID_PROPERTIES* arrGuidProperties = NULL;
|
|
ULONG ulGuidCount;
|
|
PVOID pGuidStorage = NULL;
|
|
|
|
m_arrGenTraceProvider.RemoveAll ( );
|
|
|
|
hr = ConnectToServer( );
|
|
|
|
if ( SUCCEEDED ( hr ) ) {
|
|
hr = LoadGuidArray( &pGuidStorage, &ulGuidCount );
|
|
}
|
|
|
|
if ( SUCCEEDED ( hr ) ) {
|
|
arrGuidProperties = (PTRACE_GUID_PROPERTIES *)pGuidStorage;
|
|
ASSERT ( NULL != arrGuidProperties );
|
|
}
|
|
|
|
//If Connection succeeded and registered Guids gathered.
|
|
if ( SUCCEEDED ( hr ) ) {
|
|
|
|
// Create an enumerator of the Trace Provider class
|
|
MFC_TRY
|
|
bstrTemp = SysAllocString(m_cszTraceProviderClass);
|
|
hr = m_pWbemServices->CreateClassEnum (
|
|
bstrTemp,
|
|
WBEM_FLAG_SHALLOW|WBEM_FLAG_USE_AMENDED_QUALIFIERS,
|
|
NULL,
|
|
&pEnumProviders );
|
|
::SysFreeString ( bstrTemp );
|
|
MFC_CATCH_HR
|
|
|
|
if ( SUCCEEDED ( hr ) ) {
|
|
BSTR bsDescription = NULL;
|
|
BSTR bsGuid = NULL;
|
|
VARIANT vValue;
|
|
DWORD dwRtnCount;
|
|
IWbemQualifierSet *pQualSet = NULL;
|
|
IWbemClassObject *pThisClass = NULL;
|
|
WCHAR szSystemTraceControlGuid[39];
|
|
ULONG Status;
|
|
|
|
VariantInit ( &vValue );
|
|
ZeroMemory ( szSystemTraceControlGuid, sizeof ( szSystemTraceControlGuid ) );
|
|
|
|
::StringFromGUID2( SystemTraceControlGuid, szSystemTraceControlGuid, 39);
|
|
|
|
MFC_TRY
|
|
bsDescription = SysAllocString(m_cszDescription);
|
|
bsGuid = SysAllocString(m_cszGuid);
|
|
MFC_CATCH_HR
|
|
|
|
if ( SUCCEEDED ( hr ) ) {
|
|
|
|
iIsEnabled = 0;
|
|
|
|
while ( SUCCEEDED ( hr ) ) {
|
|
hr = pEnumProviders->Next (
|
|
0, // timeout
|
|
1, // return only 1 object
|
|
&pThisClass,
|
|
&dwRtnCount );
|
|
|
|
if ( SUCCEEDED ( hr ) ) {
|
|
// no more classes
|
|
if ( dwRtnCount == 0 ) break;
|
|
|
|
pThisClass->GetQualifierSet ( &pQualSet );
|
|
if ( pQualSet != NULL ) {
|
|
|
|
hr = pQualSet->Get ( bsGuid, 0, &vValue, 0 );
|
|
if ( SUCCEEDED ( hr ) ) {
|
|
strGuid = ( LPWSTR )V_BSTR ( &vValue );
|
|
VariantClear ( &vValue );
|
|
|
|
hr = pQualSet->Get ( bsDescription, 0, &vValue, 0 );
|
|
if ( SUCCEEDED ( hr ) ) {
|
|
strDescription = ( LPWSTR )V_BSTR ( &vValue );
|
|
VariantClear ( &vValue );
|
|
} else {
|
|
hr = ERROR_SUCCESS;
|
|
strDescription = strGuid;
|
|
}
|
|
}
|
|
|
|
|
|
pQualSet->Release();
|
|
}
|
|
|
|
// The Win2000 Kernel trace provider is handled separately.
|
|
if ( SUCCEEDED ( hr ) ) {
|
|
MFC_TRY
|
|
if ( L'{' != strGuid[0] ) {
|
|
strBracketedGuid.Format ( L"{%s}", strGuid );
|
|
} else {
|
|
strBracketedGuid = strGuid;
|
|
}
|
|
MFC_CATCH_HR
|
|
|
|
if ( 0 == strBracketedGuid.CompareNoCase( szSystemTraceControlGuid ) ) {
|
|
PLOG_INFO pLoggerInfo = NULL;
|
|
|
|
TRACEHANDLE LoggerHandle = 0;
|
|
|
|
// Kernel trace provider. Need to pass GUID as name.
|
|
MFC_TRY
|
|
|
|
pLoggerInfo = new LOG_INFO;
|
|
ZeroMemory ( pLoggerInfo, sizeof ( LOG_INFO ) );
|
|
pLoggerInfo->Properties.LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
|
|
pLoggerInfo->Properties.Wnode.BufferSize = sizeof( LOG_INFO );
|
|
pLoggerInfo->Properties.Wnode.Flags = WNODE_FLAG_TRACED_GUID;
|
|
|
|
pLoggerInfo->Properties.Wnode.Guid = SystemTraceControlGuid;
|
|
|
|
Status = QueryTrace(LoggerHandle, m_cszKernelLogger, &(pLoggerInfo->Properties) );
|
|
iIsEnabled = (Status == 0) ? 1 : 0;
|
|
m_KernelTraceProvider.strDescription = strDescription;
|
|
m_KernelTraceProvider.strGuid = strBracketedGuid;
|
|
m_KernelTraceProvider.iIsEnabled = iIsEnabled;
|
|
m_KernelTraceProvider.iIsActive = 1;
|
|
MFC_CATCH_HR
|
|
|
|
if ( NULL != pLoggerInfo ) {
|
|
delete pLoggerInfo;
|
|
}
|
|
|
|
} else {
|
|
//loop on all the registered guids
|
|
INT iIsActive = 0;
|
|
GUID guidTemp; // Todo: Init
|
|
BOOL bSuccess;
|
|
|
|
ZeroMemory ( &guidTemp, sizeof (GUID) );
|
|
|
|
bSuccess = wGUIDFromString (strGuid, &guidTemp );
|
|
|
|
if ( bSuccess ) {
|
|
|
|
for (iIndex = 0 ; iIndex < (INT)ulGuidCount; iIndex ++){
|
|
if ( guidTemp == arrGuidProperties[iIndex]->Guid ) {
|
|
DWORD dwStatus;
|
|
|
|
iIsActive = 1;
|
|
|
|
dwStatus = AddProvider (
|
|
strDescription,
|
|
strBracketedGuid,
|
|
arrGuidProperties[iIndex]->IsEnable,
|
|
iIsActive );
|
|
|
|
if ( ERROR_OUTOFMEMORY == dwStatus ) {
|
|
hr = E_OUTOFMEMORY;
|
|
} else if ( ERROR_SUCCESS != dwStatus ) {
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
} // Todo: Error message on invalid Guid string.
|
|
|
|
if ( 0 == iIsActive ) {
|
|
DWORD dwStatus;
|
|
|
|
dwStatus = AddProvider (
|
|
strDescription,
|
|
strBracketedGuid,
|
|
0,
|
|
iIsActive );
|
|
|
|
if ( ERROR_OUTOFMEMORY == dwStatus ) {
|
|
hr = E_OUTOFMEMORY;
|
|
} else if ( ERROR_SUCCESS != dwStatus ) {
|
|
hr = E_FAIL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pThisClass->Release ( );
|
|
|
|
}
|
|
}
|
|
::SysFreeString ( bsGuid );
|
|
::SysFreeString ( bsDescription );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Done with these objects.
|
|
|
|
if ( NULL != pGuidStorage ) {
|
|
G_FREE ( pGuidStorage );
|
|
}
|
|
|
|
if ( NULL != pEnumProviders ) {
|
|
pEnumProviders->Release ( );
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// Get specified provider in provider list
|
|
//
|
|
SLQ_TRACE_PROVIDER*
|
|
CSmTraceProviders::GetProviderInfo ( INT iIndex )
|
|
{
|
|
return &m_arrGenTraceProvider[iIndex];
|
|
}
|
|
|
|
//
|
|
// Return a pointer to the Kernel provider.
|
|
//
|
|
SLQ_TRACE_PROVIDER*
|
|
CSmTraceProviders::GetKernelProviderInfo ( void )
|
|
{
|
|
return &m_KernelTraceProvider;
|
|
}
|
|
|
|
//
|
|
// Return the index of the provider specified by Guid
|
|
//
|
|
INT
|
|
CSmTraceProviders::IndexFromGuid ( const CString& rstrGuid )
|
|
{
|
|
int iIndex;
|
|
int iCount = (INT)m_arrGenTraceProvider.GetSize ( );
|
|
|
|
for ( iIndex = 0; iIndex < iCount; iIndex++ ) {
|
|
if ( 0 == m_arrGenTraceProvider[iIndex].strGuid.CompareNoCase( rstrGuid ) ) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Signal not found with -1.
|
|
if ( iIndex == iCount ) {
|
|
iIndex = -1;
|
|
}
|
|
return iIndex;
|
|
}
|
|
|
|
//
|
|
// Get provider list count
|
|
//
|
|
INT
|
|
CSmTraceProviders::GetGenProvCount ( )
|
|
{
|
|
return (INT)m_arrGenTraceProvider.GetSize ( );
|
|
}
|
|
|
|
//
|
|
// LoadGuidArray copied from evntrprv.cpp 9/12/01
|
|
//
|
|
|
|
HRESULT
|
|
CSmTraceProviders::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 = ERROR_SUCCESS;
|
|
|
|
do {
|
|
dwSize = nGuidArray * (sizeof(TRACE_GUID_PROPERTIES) + sizeof(PTRACE_GUID_PROPERTIES));
|
|
|
|
MFC_TRY
|
|
*Storage = G_ALLOC(dwSize);
|
|
MFC_CATCH_HR
|
|
|
|
if ( FAILED (hr) || *Storage == NULL) {
|
|
if (*Storage == NULL) {
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
break;
|
|
} else {
|
|
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;
|
|
}
|
|
|