|
|
/*++
Copyright (c) 1998-1999 Microsoft Corporation
Module Name:
ulperf.cpp
Abstract:
This is the main code for the ul.sys performance counter support object
Author:
Paul McDaniel (paulmcd) 11-May-1999
Revision History:
--*/
#include "precomp.h"
#include "ulperf.h"
//
// Globals
//
LONG g_lInit; HINSTANCE g_hInstance;
//
// Active "opens" reference count for Open/Close PerformanceData
//
ULONG OpenCount = 0;
//
// An open handle to the event log for error logging
//
HANDLE hEventLog;
//
// Initialize the constant portions of the HKEY_PERFORMANCE data structure.
// Certain parts (especially the name/help indices) will be
// updated at initialization time.
//
const UL_COUNTER_BLOCK CounterBlock;
UL_PERF_OBJECT_DEFINITION ObjectDefinition = { { // ObjectType
sizeof(UL_PERF_OBJECT_DEFINITION) + sizeof(UL_COUNTER_BLOCK), sizeof(UL_PERF_OBJECT_DEFINITION), sizeof(PERF_OBJECT_TYPE), UL_COUNTER_OBJECT, NULL, UL_COUNTER_OBJECT, NULL, PERF_DETAIL_ADVANCED, NUMBER_OF_UL_COUNTERS, -1, // DefaultCounter
PERF_NO_INSTANCES, 0, { 0, 0 }, { 0, 0 } },
{ // BytesSent
sizeof(PERF_COUNTER_DEFINITION), UL_BYTES_SENT_COUNTER, NULL, // assigned in OpenPerformanceData()
UL_BYTES_SENT_COUNTER, NULL, // assigned in OpenPerformanceData()
0, PERF_DETAIL_ADVANCED, PERF_COUNTER_COUNTER, 0, // assigned in OpenPerformanceData()
0 // assigned in OpenPerformanceData()
},
{ // BytesReceived
sizeof(PERF_COUNTER_DEFINITION), UL_BYTES_RECEIVED_COUNTER, NULL, UL_BYTES_RECEIVED_COUNTER, NULL, 0, PERF_DETAIL_ADVANCED, PERF_COUNTER_COUNTER, 0, 0 },
{ // CurrentConnections
sizeof(PERF_COUNTER_DEFINITION), UL_CURRENT_CONNECTIONS_NUMBER, NULL, UL_CURRENT_CONNECTIONS_NUMBER, NULL, 0, PERF_DETAIL_ADVANCED, PERF_COUNTER_RAWCOUNT, 0, 0 }, { // CurrentRequests
sizeof(PERF_COUNTER_DEFINITION), UL_CURRENT_REQUESTS_NUMBER, NULL, UL_CURRENT_REQUESTS_NUMBER, NULL, 0, PERF_DETAIL_ADVANCED, PERF_COUNTER_RAWCOUNT, 0, 0 },
{ // QueuedRequests
sizeof(PERF_COUNTER_DEFINITION), UL_QUEUED_REQUESTS_NUMBER, NULL, UL_QUEUED_REQUESTS_NUMBER, NULL, 0, PERF_DETAIL_ADVANCED, PERF_COUNTER_RAWCOUNT, 0, 0 }, { // AttachedProcesses
sizeof(PERF_COUNTER_DEFINITION), UL_ATTACHED_PROCESSES_NUMBER, NULL, UL_ATTACHED_PROCESSES_NUMBER, NULL, 0, PERF_DETAIL_ADVANCED, PERF_COUNTER_RAWCOUNT, 0, 0 }
};
DWORD OpenPerformanceData( LPWSTR lpDeviceNames ) { DWORD Error = NO_ERROR; HKEY hkey = NULL; DWORD size; DWORD type; DWORD dwFirstCounter; DWORD dwFirstHelp; DWORD i; PERF_COUNTER_DEFINITION * pctr;
//
// Since WINLOGON is multi-threaded and will call this routine in
// order to service remote performance queries, this library
// must keep track of how many times it has been opened (i.e.
// how many threads have accessed it). The registry routines will
// limit access to the initialization routine to only one thread
// at a time so synchronization (i.e. reentrancy) should not be
// a problem.
//
if (OpenCount == 0) {
//
// This is the *first* open.
//
// open event log interface
if (hEventLog == NULL) { hEventLog = RegisterEventSource( (LPTSTR)NULL, // Use Local Machine
APP_NAME // event log app name
// to find in registry
); }
//
// open the performance key
//
Error = RegOpenKeyEx( HKEY_LOCAL_MACHINE, REGISTRY_UL_INFORMATION L"\\Performance", 0, KEY_ALL_ACCESS, &hkey );
if( err == NO_ERROR ) { //
// Read the first counter DWORD.
//
size = sizeof(DWORD);
err = RegQueryValueEx( hkey, L"First Counter", NULL, &type, (LPBYTE)&dwFirstCounter, &size ); if( err == NO_ERROR ) { //
// Read the first help DWORD.
//
size = sizeof(DWORD);
err = RegQueryValueEx( hkey, L"First Help", NULL, &type, (LPBYTE)&dwFirstHelp, &size );
if ( err == NO_ERROR ) { //
// Update the object & counter name & help indicies.
//
ObjectDefinition.ObjectType.ObjectNameTitleIndex += dwFirstCounter; ObjectDefinition.ObjectType.ObjectHelpTitleIndex += dwFirstHelp;
#define ADJUST_VALUES(CounterName) \
do {\ ObjectDefinition.##CounterName.CounterNameTitleIndex \ += dwFirstCounter; \ ObjectDefinition.##CounterName.CounterHelpTitleIndex \ += dwFirstHelp; \ ObjectDefinition.##CounterName.CounterSize \ = sizeof(CounterBlock.##CounterName); \ ObjectDefinition.##CounterName.CounterOffset = \ DIFF((LPBYTE)&CounterBlock.##CounterName - (LPBYTE)&CounterBlock);\ } while (0)
ADJUST_VALUES(BytesSent); ADJUST_VALUES(BytesReceived); ADJUST_VALUES(CurrentConnections); ADJUST_VALUES(CurrentRequests); ADJUST_VALUES(QueuedRequests); ADJUST_VALUES(AttachedProcesses);
//
// Remember that we initialized OK.
//
fInitOK = TRUE;
} else { ReportEvent (hEventLog, EVENTLOG_ERROR_TYPE, 0, W3_UNABLE_READ_FIRST_HELP, (PSID)NULL, 0, sizeof(err), NULL, (PVOID)(&err)); } } else { ReportEvent (hEventLog, EVENTLOG_ERROR_TYPE, 0, W3_UNABLE_READ_FIRST_COUNTER, (PSID)NULL, 0, sizeof(err), NULL, (PVOID)(&err)); }
//
// Close the registry if we managed to actually open it.
//
if( hkey != NULL ) { RegCloseKey( hkey ); hkey = NULL; } } else { ReportEvent (hEventLog, EVENTLOG_ERROR_TYPE, 0, W3_UNABLE_OPEN_W3SVC_PERF_KEY, (PSID)NULL, 0, sizeof(err), NULL, (PVOID)(&err)); } }
//
// Bump open counter.
//
OpenCount += 1;
end: return Error;
} // OpenPerformanceData
DWORD CollectPerformanceData( LPWSTR lpwszValue, LPVOID *lppData, LPDWORD lpcbBytes, LPDWORD lpcObjectTypes ) {
}
DWORD WINAPI ClosePerformanceData( ) { //
// Clean up
//
OpenCount -= 1; if (OpenCount == 0) { if (hEventLog != NULL) { DeregisterEventSource(hEventLog); hEventLog = NULL; } }
return NO_ERROR; } // ClosePerformanceData
CUlPerfCounters::CUlPerfCounters() {
}
CUlPerfCounters::~CUlPerfCounters() {
}
//
// IWbemProviderInit
//
STDMETHODIMP CUlPerfCounters::Initialize(LPWSTR wszUser,LONG lFlags,LPWSTR wszNamespace,LPWSTR wszLocale,IWbemServices* pNamespace,IWbemContext* pCtx,IWbemProviderInitSink* pInitSink) { HRESULT Result;
ASSERT(pInitSink != NULL);
TRACE(L"ulperf!CUlPerfCounters::Initialize called\n");
//
// tell wbem we are ready to go.
//
Result = pInitSink->SetStatus(WBEM_S_INITIALIZED, 0);
return Result; } // CUlPerfCounters::Initialize
//
// IWbemServices
//
// Context.
// ========
STDMETHODIMP CUlPerfCounters::OpenNamespace(BSTR strNamespace, long lFlags, IWbemContext* pCtx, IWbemServices** ppWorkingNamespace, IWbemCallResult** ppResult) { return WBEM_E_METHOD_NOT_IMPLEMENTED; }
STDMETHODIMP CUlPerfCounters::CancelAsyncCall(IWbemObjectSink* pSink) { return WBEM_E_METHOD_NOT_IMPLEMENTED; }
STDMETHODIMP CUlPerfCounters::QueryObjectSink(long lFlags,IWbemObjectSink** ppResponseHandler) { return WBEM_E_METHOD_NOT_IMPLEMENTED; }
// Classes and instances.
// ======================
STDMETHODIMP CUlPerfCounters::GetObject(BSTR strObjectPath,long lFlags,IWbemContext* pCtx,IWbemClassObject** ppObject,IWbemCallResult** ppCallResult) { return WBEM_E_METHOD_NOT_IMPLEMENTED; }
STDMETHODIMP CUlPerfCounters::GetObjectAsync(BSTR strObjectPath,long lFlags,IWbemContext* pCtx,IWbemObjectSink* pResponseHandler) { IWbemClassObject pObj; HRESULT Result; CObjectPathParser PathParser; ParsedObjectPath *pParsedPath = NULL;
Result = WBEM_S_NO_ERROR;
//
// crack the object path
//
Result = PathParser.Parse(strObjectPath, &pParsedPath); if (Result != CObjectPathParser::NoError) return E_FAIL;
//
// create a perfctr object
//
pObject = new CComObject<CUlPerfCounterObject>; if (pObject == NULL) { Result = E_OUTOFMEMORY goto end; }
//
// init it
//
Result = pObject->Init(pParsedPath); if (FAILED(Result)) goto end;
//
// and hand it off to wbem
//
Result = pGroup->_InternalQueryInterface(IID_IWbemClassObject, (PVOID*)&pWbemObj); if (FAILED(Result)) goto end; Result = pHandler->Indicate(1, &pWbemObj); if (FAILED(Result)) goto end;
end: if (pParsedPath != NULL) { PathParser.Free(pParsedPath); pParsedPath = NULL; }
if (pWbemObj != NULL) { pWbemObj->Release(); pWbemObj = NULL; } pHandler->SetStatus(0, Result, NULL, NULL); return Result; }
// Class manipulation.
// ===================
STDMETHODIMP CUlPerfCounters::PutClass(IWbemClassObject* pObject,long lFlags,IWbemContext* pCtx,IWbemCallResult** ppCallResult) { return WBEM_E_METHOD_NOT_IMPLEMENTED; }
STDMETHODIMP CUlPerfCounters::PutClassAsync(IWbemClassObject* pObject,long lFlags,IWbemContext* pCtx,IWbemObjectSink* pResponseHandler) { return WBEM_E_METHOD_NOT_IMPLEMENTED; }
STDMETHODIMP CUlPerfCounters::DeleteClass(BSTR strClass,long lFlags,IWbemContext* pCtx,IWbemCallResult** ppCallResult) { return WBEM_E_METHOD_NOT_IMPLEMENTED; }
STDMETHODIMP CUlPerfCounters::DeleteClassAsync(BSTR strClass,long lFlags,IWbemContext* pCtx,IWbemObjectSink* pResponseHandler) { return WBEM_E_METHOD_NOT_IMPLEMENTED; }
STDMETHODIMP CUlPerfCounters::CreateClassEnum(BSTR strSuperclass,long lFlags,IWbemContext* pCtx,IEnumWbemClassObject** ppEnum) { return WBEM_E_METHOD_NOT_IMPLEMENTED; }
STDMETHODIMP CUlPerfCounters::CreateClassEnumAsync(BSTR strSuperclass,long lFlags,IWbemContext* pCtx,IWbemObjectSink* pResponseHandler) { return WBEM_E_METHOD_NOT_IMPLEMENTED; }
// Instances.
// ==========
STDMETHODIMP CUlPerfCounters::PutInstance(IWbemClassObject* pInst,long lFlags,IWbemContext* pCtx,IWbemCallResult** ppCallResult) { return WBEM_E_METHOD_NOT_IMPLEMENTED; }
STDMETHODIMP CUlPerfCounters::PutInstanceAsync(IWbemClassObject* pInst,long lFlags,IWbemContext* pCtx,IWbemObjectSink* pResponseHandler) { return WBEM_E_METHOD_NOT_IMPLEMENTED; }
STDMETHODIMP CUlPerfCounters::DeleteInstance(BSTR strObjectPath,long lFlags,IWbemContext* pCtx,IWbemCallResult** ppCallResult) { return WBEM_E_METHOD_NOT_IMPLEMENTED; }
STDMETHODIMP CUlPerfCounters::DeleteInstanceAsync(BSTR strObjectPath,long lFlags,IWbemContext* pCtx,IWbemObjectSink* pResponseHandler) { return WBEM_E_METHOD_NOT_IMPLEMENTED; }
STDMETHODIMP CUlPerfCounters::CreateInstanceEnum(BSTR strClass,long lFlags,IWbemContext* pCtx,IEnumWbemClassObject** ppEnum) { return WBEM_E_METHOD_NOT_IMPLEMENTED; }
STDMETHODIMP CUlPerfCounters::CreateInstanceEnumAsync(BSTR strClass,long lFlags,IWbemContext* pCtx,IWbemObjectSink* pResponseHandler) { return WBEM_E_METHOD_NOT_IMPLEMENTED; }
// Queries.
// ========
STDMETHODIMP CUlPerfCounters::ExecQuery(BSTR strQueryLanguage,BSTR strQuery,long lFlags,IWbemContext* pCtx,IEnumWbemClassObject** ppEnum) { return WBEM_E_METHOD_NOT_IMPLEMENTED; }
STDMETHODIMP CUlPerfCounters::ExecQueryAsync(BSTR strQueryLanguage,BSTR strQuery,long lFlags,IWbemContext* pCtx,IWbemObjectSink* pResponseHandler) { return WBEM_E_METHOD_NOT_IMPLEMENTED; }
STDMETHODIMP CUlPerfCounters::ExecNotificationQuery(BSTR strQueryLanguage,BSTR strQuery,long lFlags,IWbemContext* pCtx,IEnumWbemClassObject** ppEnum) { return WBEM_E_METHOD_NOT_IMPLEMENTED; }
STDMETHODIMP CUlPerfCounters::ExecNotificationQueryAsync(BSTR strQueryLanguage,BSTR strQuery,long lFlags,IWbemContext* pCtx,IWbemObjectSink* pResponseHandler) { return WBEM_E_METHOD_NOT_IMPLEMENTED; }
// Methods
// =======
STDMETHODIMP CUlPerfCounters::ExecMethod(BSTR strObjectPath,BSTR strMethodName,long lFlags,IWbemContext* pCtx,IWbemClassObject* pInParams,IWbemClassObject** ppOutParams,IWbemCallResult** ppCallResult) { return WBEM_E_METHOD_NOT_IMPLEMENTED; }
STDMETHODIMP CUlPerfCounters::ExecMethodAsync(BSTR strObjectPath,BSTR strMethodName,long lFlags,IWbemContext* pCtx,IWbemClassObject* pInParams,IWbemObjectSink* pResponseHandler) { return WBEM_E_METHOD_NOT_IMPLEMENTED; }
|