mirror of https://github.com/tongzx/nt5src
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.
643 lines
20 KiB
643 lines
20 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 = TEXT ( "\\" );
|
|
LPCWSTR CSmTraceProviders::m_cszKernelLogger = TEXT ( "NT Kernel Logger" );
|
|
LPCWSTR CSmTraceProviders::m_cszDefaultNamespace = TEXT ( "root\\wmi" );
|
|
LPCWSTR CSmTraceProviders::m_cszTraceProviderClass = TEXT ( "EventTrace" );
|
|
LPCWSTR CSmTraceProviders::m_cszRegisteredGuidsClass = TEXT ( "RegisteredGuids" );
|
|
LPCWSTR CSmTraceProviders::m_cszDescription = TEXT ( "Description" );
|
|
LPCWSTR CSmTraceProviders::m_cszGuid = TEXT ( "Guid" );
|
|
|
|
//
|
|
// Constructor
|
|
CSmTraceProviders::CSmTraceProviders ( CSmTraceLogService* pSvc )
|
|
: m_pWbemServices ( NULL ),
|
|
m_pTraceLogService ( pSvc ),
|
|
m_iBootState ( -1 )
|
|
{
|
|
m_KernelTraceProvider.strDescription = _T("");
|
|
m_KernelTraceProvider.strGuid = _T("");
|
|
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 ) {
|
|
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;
|
|
}
|
|
} 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 )
|
|
{
|
|
IEnumWbemClassObject *pEnumProviders = NULL;
|
|
IEnumWbemClassObject *pEnumRegGuids = NULL;
|
|
CString strDescription;
|
|
CString strGuid;
|
|
CString strBracketedGuid;
|
|
IWbemClassObject* pRegisteredGuid = NULL;
|
|
BSTR bstrTemp;
|
|
INT iIndex;
|
|
CArray<PREGISTERED_GUID_DATA, PREGISTERED_GUID_DATA&> arrRegisteredGuids;
|
|
INT iIsEnabled =0;
|
|
HRESULT hr;
|
|
|
|
m_arrGenTraceProvider.RemoveAll ( );
|
|
|
|
hr = ConnectToServer( );
|
|
|
|
//If Connection Succeeded
|
|
if ( SUCCEEDED ( hr ) ) {
|
|
//Get the Registered Guids (Up to date Data) from Wbem.
|
|
MFC_TRY
|
|
bstrTemp = SysAllocString(m_cszRegisteredGuidsClass);
|
|
|
|
hr = m_pWbemServices->CreateInstanceEnum (
|
|
bstrTemp,
|
|
WBEM_FLAG_SHALLOW|WBEM_FLAG_USE_AMENDED_QUALIFIERS,
|
|
NULL,
|
|
&pEnumRegGuids );
|
|
::SysFreeString ( bstrTemp );
|
|
MFC_CATCH_HR
|
|
|
|
if ( SUCCEEDED ( hr ) ) {
|
|
ULONG uReturned = 1;
|
|
|
|
while(uReturned == 1)
|
|
{
|
|
pRegisteredGuid = NULL;
|
|
//---------------------------
|
|
// enumerate through the resultset.
|
|
hr = pEnumRegGuids->Next(
|
|
2000, // timeout in two seconds
|
|
1, // return just one instance
|
|
&pRegisteredGuid, // pointer to Registered Guid
|
|
&uReturned); // number obtained: one or zero
|
|
|
|
if ( SUCCEEDED(hr) && ( 1 == uReturned ))
|
|
{
|
|
VARIANT vValue ;
|
|
|
|
// Get the "GuidType" system property.
|
|
MFC_TRY
|
|
bstrTemp = SysAllocString(L"GuidType");
|
|
VariantInit ( &vValue );
|
|
vValue.vt = VT_I4;
|
|
|
|
hr = pRegisteredGuid->Get(
|
|
bstrTemp, // property name
|
|
0L,
|
|
&vValue, // output to this variant
|
|
NULL,
|
|
NULL);
|
|
|
|
::SysFreeString ( bstrTemp );
|
|
MFC_CATCH_HR
|
|
// Filter on GuidType == 0
|
|
if (SUCCEEDED(hr) && (0 == vValue.iVal)){
|
|
CString strProvider;
|
|
|
|
// Get the "InstanceName" system property.
|
|
MFC_TRY
|
|
bstrTemp = SysAllocString(L"InstanceName");
|
|
VariantClear ( &vValue );
|
|
vValue.vt = VT_BSTR;
|
|
|
|
hr = pRegisteredGuid->Get(
|
|
bstrTemp, // property name
|
|
0L,
|
|
&vValue, // output to this variant
|
|
NULL,
|
|
NULL);
|
|
|
|
::SysFreeString ( bstrTemp );
|
|
MFC_CATCH_HR
|
|
|
|
if (SUCCEEDED(hr)){
|
|
|
|
MFC_TRY
|
|
strProvider = ( LPWSTR )V_BSTR (&vValue);
|
|
|
|
bstrTemp = SysAllocString(L"IsEnabled");
|
|
VariantInit(&vValue);
|
|
vValue.vt = VT_BOOL;
|
|
hr = pRegisteredGuid->Get(
|
|
bstrTemp, // property name
|
|
0L,
|
|
&vValue, // output to this variant
|
|
NULL,
|
|
NULL);
|
|
|
|
::SysFreeString ( bstrTemp );
|
|
MFC_CATCH_HR
|
|
}
|
|
|
|
if ( SUCCEEDED(hr) ) {
|
|
PREGISTERED_GUID_DATA pRegGuidData = NULL;
|
|
|
|
iIsEnabled = vValue.boolVal ? 1 : 0;
|
|
|
|
MFC_TRY
|
|
pRegGuidData = new ( CRegisteredGuidData );
|
|
pRegGuidData->m_strGuid = strProvider;
|
|
pRegGuidData->m_iIsEnabled = iIsEnabled;
|
|
arrRegisteredGuids.Add(pRegGuidData);
|
|
MFC_CATCH_HR
|
|
|
|
}
|
|
}
|
|
|
|
VariantClear(&vValue);
|
|
pRegisteredGuid->Release();
|
|
|
|
}
|
|
} // end while
|
|
}
|
|
}
|
|
|
|
//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 ) ) {
|
|
EVENT_TRACE_PROPERTIES LoggerInfo;
|
|
|
|
TRACEHANDLE LoggerHandle = 0;
|
|
TCHAR szLoggerName[MAX_PATH];
|
|
TCHAR szLogFileName[MAX_PATH];
|
|
// Kernel trace provider. Need to pass GUID as name.
|
|
MFC_TRY
|
|
ZeroMemory ( &LoggerInfo, sizeof ( LoggerInfo ) );
|
|
LoggerInfo.Wnode.BufferSize = sizeof( LoggerInfo );
|
|
LoggerInfo.Wnode.Flags = WNODE_FLAG_TRACED_GUID;
|
|
szLoggerName[0] = 0;
|
|
szLogFileName[0] = 0;
|
|
|
|
LoggerInfo.Wnode.Guid = SystemTraceControlGuid;
|
|
|
|
Status = QueryTrace(LoggerHandle, m_cszKernelLogger, &LoggerInfo);
|
|
iIsEnabled = (Status == 0) ? 1 : 0;
|
|
m_KernelTraceProvider.strDescription = strDescription;
|
|
m_KernelTraceProvider.strGuid = strBracketedGuid;
|
|
m_KernelTraceProvider.iIsEnabled = iIsEnabled;
|
|
m_KernelTraceProvider.iIsActive = 1;
|
|
MFC_CATCH_HR
|
|
} else {
|
|
//loop on all the registered guids
|
|
INT iIsActive = 0;
|
|
for (iIndex = 0 ; iIndex < (INT)arrRegisteredGuids.GetSize(); iIndex ++){
|
|
if (0 == strGuid.CompareNoCase((LPCTSTR)(arrRegisteredGuids[iIndex]->m_strGuid))){
|
|
DWORD dwStatus;
|
|
|
|
iIsActive = 1;
|
|
|
|
dwStatus = AddProvider (
|
|
strDescription,
|
|
strBracketedGuid,
|
|
arrRegisteredGuids[iIndex]->m_iIsEnabled,
|
|
iIsActive );
|
|
|
|
if ( ERROR_OUTOFMEMORY == dwStatus ) {
|
|
hr = E_OUTOFMEMORY;
|
|
} else if ( ERROR_SUCCESS != dwStatus ) {
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
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 );
|
|
}
|
|
}
|
|
}
|
|
|
|
for (iIndex = 0 ; iIndex < (INT)arrRegisteredGuids.GetSize(); iIndex ++){
|
|
delete arrRegisteredGuids[iIndex];
|
|
}
|
|
|
|
arrRegisteredGuids.RemoveAll ( );
|
|
|
|
// Done with these objects.
|
|
if ( NULL != pEnumProviders ) {
|
|
pEnumProviders->Release ( );
|
|
}
|
|
|
|
if ( NULL != pEnumRegGuids ) {
|
|
pEnumRegGuids->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 ( );
|
|
}
|
|
|
|
|