Source code of Windows XP (NT5)
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

/*++
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 ( );
}