|
|
//---------------------------------------------------------------
// File: perfsmtp.c
//
// Synopsis: This file implements the Extensible Performance
// Objects for the SMTP service.
//
// Copyright (C) 1996 Microsoft Corporation
// All rights reserved.
//
// Authors: toddch - based on rkamicar, keithmo source
//----------------------------------------------------------------
#ifdef THIS_FILE
#undef THIS_FILE
#endif
static char __szTraceSourceFile[] = __FILE__; #define THIS_FILE __szTraceSourceFile
#define NOTRACE
#define INITGUID
#include <nt.h> // For ntrtl.h
#include <ntrtl.h> // RtlLargeInteger*()
#include <nturtl.h> // For windows.h
#include <windows.h>
#include <winperf.h>
#include <lm.h>
#include <string.h>
#include <stdio.h>
#include "smtpdata.h" // The counter descriptions
#include "smtpctrs.h" // more counter descriptions
#include "perfutil.h" // Perfmon support
#include "smtps.h" // Registry Key strings.
#include "smtpapi.h" // RPC interface wrappers
#include "dbgtrace.h"
//
// Private globals.
//
DWORD cOpens = 0; // Active "opens" reference count.
BOOL fInitOK = FALSE; // TRUE if DLL initialized OK.
//
// Public prototypes.
//
PM_OPEN_PROC OpenSmtpPerformanceData; PM_COLLECT_PROC CollectSmtpPerformanceData; PM_CLOSE_PROC CloseSmtpPerformanceData;
//
// Public functions.
//
/*******************************************************************
NAME: OpenSmtpPerformanceData
SYNOPSIS: Initializes the data structures used to communicate performance counters with the registry.
ENTRY: lpDeviceNames - Pointer to object ID of each device to be opened.
RETURNS: DWORD - Win32 status code.
HISTORY: KeithMo 07-Jun-1993 Created.
********************************************************************/ DWORD APIENTRY OpenSmtpPerformanceData(LPWSTR lpDeviceNames) { PERF_COUNTER_DEFINITION *pctr; DWORD i; DWORD dwFirstCounter = 0; DWORD dwFirstHelp = 0; DWORD err = NO_ERROR; HKEY hkey = NULL; DWORD size; DWORD type; BOOL fOpenRegKey = FALSE;
#ifndef NOTRACE
//
// make sure that tracing is enabled
//
InitAsyncTrace(); #endif
//
// we need to have another level of scoping here for TraceFunctEnter()
// to work
//
{ TraceFunctEnter("OpenSmtpPerformanceData");
//
// Since SCREG 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(!fInitOK) { //
// This is the *first* open - update the indicies in
// our table with the offset of our counters within the
// perfmon key.
//
DebugTrace(0, "Initializing.");
//
// Open the service's Performance key and get the
// offsets of our counters within the PerfLib MULTI_SZ.
//
err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SMTP_PERFORMANCE_KEY, 0, KEY_READ, &hkey); if(err == NO_ERROR) { fOpenRegKey = TRUE; size = sizeof(DWORD);
err = RegQueryValueEx(hkey, "First Counter", NULL, &type, (LPBYTE)&dwFirstCounter, &size); } else { DebugTrace(0, "No 'First Counter' key (err = %d) in '%s'", err, SMTP_PERFORMANCE_KEY); } if(err == NO_ERROR) { size = sizeof(DWORD);
err = RegQueryValueEx(hkey, "First Help", NULL, &type, (LPBYTE)&dwFirstHelp, &size); } else { DebugTrace(0, "No 'First Help' key (err = %d) in '%s'", err, SMTP_PERFORMANCE_KEY); }
if (NO_ERROR == err) { //
// Update the object & counter name & help indicies.
//
SmtpDataDefinition.SmtpObjectType.ObjectNameTitleIndex += dwFirstCounter; SmtpDataDefinition.SmtpObjectType.ObjectHelpTitleIndex += dwFirstHelp; pctr = &SmtpDataDefinition.SmtpBytesSentTtl; for(i = 0; i < NUMBER_OF_SMTP_COUNTERS; i++) { pctr->CounterNameTitleIndex += dwFirstCounter; pctr->CounterHelpTitleIndex += dwFirstHelp; pctr++; } //
// Remember that we initialized OK.
//
fInitOK = TRUE; } else { DebugTrace(0, "No 'First Help' key (err = %d) in '%s'", err, SMTP_PERFORMANCE_KEY); }
if (fOpenRegKey) { err = RegCloseKey(hkey); // This should never fail!
_ASSERT(err == ERROR_SUCCESS); } } //
// Bump open counter.
//
cOpens++;
TraceFunctLeave(); } // end of TraceFunctEnter() scoping
return NO_ERROR;
} // OpenSmtpPerformanceData
/*******************************************************************
NAME: CollectSmtpPerformanceData
SYNOPSIS: Initializes the data structures used to communicate
ENTRY: lpValueName - The name of the value to retrieve.
lppData - On entry contains a pointer to the buffer to receive the completed PerfDataBlock & subordinate structures. On exit, points to the first bytes *after* the data structures added by this routine.
lpcbTotalBytes - On entry contains a pointer to the size (in BYTEs) of the buffer referenced by lppData. On exit, contains the number of BYTEs added by this routine.
lpNumObjectTypes - Receives the number of objects added by this routine.
RETURNS: DWORD - Win32 status code. MUST be either NO_ERROR or ERROR_MORE_DATA.
HISTORY: KeithMo 07-Jun-1993 Created.
********************************************************************/ DWORD APIENTRY CollectSmtpPerformanceData(LPWSTR lpValueName, LPVOID * lppData, LPDWORD lpcbTotalBytes, LPDWORD lpNumObjectTypes) { DWORD dwQueryType; ULONG cbRequired; DWORD * pdwCounter; DWORD * pdwEndCounter; unsigned __int64 * pliCounter; SMTP_COUNTER_BLOCK * pCounterBlock; SMTP_DATA_DEFINITION * pSmtpDataDefinition; SMTP_INSTANCE_DEFINITION * pSmtpInstanceDefinition; SMTP_INSTANCE_DEFINITION * pInstanceTotalDefinition; PSMTP_STATISTICS_BLOCK_ARRAY pSmtpStatsBlockArray; PSMTP_STATISTICS_BLOCK pSmtpStatsBlock; LPSMTP_STATISTICS_0 pSmtpStats; NET_API_STATUS neterr; DWORD dwInstance; DWORD dwInstanceIndex; DWORD dwInstanceCount; CHAR temp[INSTANCE_NAME_SIZE]; DWORD ii;
TraceFunctEnter("CollectSmtpPerformanceData");
// DebugTrace(0, " lpValueName = %08lX (%ls)", lpValueName, lpValueName);
DebugTrace(0, " lppData = %08lX (%08lX)", lppData, *lppData); DebugTrace(0, " lpcbTotalBytes = %08lX (%08lX)", lpcbTotalBytes, *lpcbTotalBytes); DebugTrace(0, " lpNumObjectTypes= %08lX (%08lX)", lpNumObjectTypes, *lpNumObjectTypes);
//
// No need to even try if we failed to open...
//
if(!fInitOK) { ErrorTrace(0, "Initialization failed, aborting.");
*lpcbTotalBytes = 0; *lpNumObjectTypes = 0;
//
// According to the Performance Counter design, this
// is a successful exit. Go figure.
//
TraceFunctLeave(); return NO_ERROR; }
//
// Determine the query type.
//
dwQueryType = GetQueryType(lpValueName);
if(dwQueryType == QUERY_FOREIGN) { ErrorTrace(0, "Foreign queries not supported.");
//
// We don't do foreign queries.
//
*lpcbTotalBytes = 0; *lpNumObjectTypes = 0;
TraceFunctLeave(); return NO_ERROR; }
if(dwQueryType == QUERY_ITEMS) { //
// The registry is asking for a specific object. Let's
// see if we're one of the chosen.
//
if(!IsNumberInUnicodeList( SmtpDataDefinition.SmtpObjectType.ObjectNameTitleIndex, lpValueName)) { ErrorTrace(0, "%ls not a supported object type.", lpValueName);
*lpcbTotalBytes = 0; *lpNumObjectTypes = 0;
TraceFunctLeave(); return NO_ERROR; } }
//
// Query the statistics and see if there has been enough space allocated.
// The number of instances will be returned in dwInstanceCount
//
neterr = SmtpQueryStatistics( NULL, 0, (LPBYTE *) &pSmtpStatsBlockArray);
if( neterr != NERR_Success ) { *lpcbTotalBytes = 0; *lpNumObjectTypes = 0;
TraceFunctLeave(); return NO_ERROR; }
//
// Check the space requirement add one to the number of instances for the totals.
//
dwInstanceCount = pSmtpStatsBlockArray->cEntries; if(*lpcbTotalBytes < (sizeof(SMTP_DATA_DEFINITION) + (dwInstanceCount + 1) * (sizeof(SMTP_INSTANCE_DEFINITION) + SIZE_OF_SMTP_PERFORMANCE_DATA))) { ErrorTrace(0, "%lu bytes of buffer insufficient, need %lu.", *lpcbTotalBytes, cbRequired);
//
// Nope.
//
*lpcbTotalBytes = 0; *lpNumObjectTypes = 0;
//
// Free the returned buffer
//
NetApiBufferFree((LPBYTE)pSmtpStatsBlockArray);
TraceFunctLeave(); return ERROR_MORE_DATA; }
//
// Copy the (constant, initialized) Object Type and counter definitions
// to the caller's data buffer
//
pSmtpDataDefinition = (SMTP_DATA_DEFINITION *)*lppData; CopyMemory(pSmtpDataDefinition, &SmtpDataDefinition, sizeof(SMTP_DATA_DEFINITION));
//
// Initialize the Total Instance
//
pSmtpInstanceDefinition = (SMTP_INSTANCE_DEFINITION *)(pSmtpDataDefinition + 1);
pInstanceTotalDefinition = pSmtpInstanceDefinition; CopyMemory(pInstanceTotalDefinition, &SmtpInstanceDefinition, sizeof(SMTP_INSTANCE_DEFINITION));
//
// For the Total Instance update the namelength, insert the name, add 1 for null.
//
sprintf(temp,"_Total");
pInstanceTotalDefinition->PerfInstanceDef.NameLength = 2 * (MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,temp,-1, (pInstanceTotalDefinition->InstanceName),INSTANCE_NAME_SIZE)) + 1;
ZeroMemory((PVOID)(pInstanceTotalDefinition + 1),SIZE_OF_SMTP_PERFORMANCE_DATA);
//
// Begin looping through Instances.
//
pSmtpStatsBlock = pSmtpStatsBlockArray->aStatsBlock;
for (ii = 0; ii < dwInstanceCount; ii++)
{ dwInstance = pSmtpStatsBlock->dwInstance; pSmtpStats = &(pSmtpStatsBlock->Stats_0);
//
// Copy the (constant, initialized) Instance Definition to the block for the instance.
//
pSmtpInstanceDefinition = (SMTP_INSTANCE_DEFINITION *)((DWORD_PTR)pSmtpInstanceDefinition + sizeof(SMTP_INSTANCE_DEFINITION) + SIZE_OF_SMTP_PERFORMANCE_DATA);
CopyMemory(pSmtpInstanceDefinition, &SmtpInstanceDefinition, sizeof(SMTP_INSTANCE_DEFINITION));
//
// update the namelength, insert the name, add 1 for null.
//
sprintf(temp,"SMTP %u", dwInstance); pSmtpInstanceDefinition->PerfInstanceDef.NameLength = 2 * (MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,temp,-1, (pSmtpInstanceDefinition->InstanceName),INSTANCE_NAME_SIZE)) + 1;
//
// Fill in the counter block.
//
pCounterBlock = (SMTP_COUNTER_BLOCK *)(pSmtpInstanceDefinition + 1);
pCounterBlock->PerfCounterBlock.ByteLength = SIZE_OF_SMTP_PERFORMANCE_DATA;
//
// Get the pointer to the first (unsigned __int64) counter. This
// pointer *must* be quadword aligned.
//
pliCounter = (unsigned __int64 *)(pCounterBlock + 1);
DebugTrace(0, "pSmtpDataDefinition = %08lX", pSmtpDataDefinition); DebugTrace(0, "pCounterBlock = %08lX", pCounterBlock); DebugTrace(0, "ByteLength = %08lX", pCounterBlock->PerfCounterBlock.ByteLength); DebugTrace(0, "pliCounter = %08lX", pliCounter);
//
// Move the 'unsigned __int64's into the buffer.
//
*pliCounter++ = pSmtpStats->BytesSentTotal; *pliCounter++ = pSmtpStats->BytesSentTotal; *pliCounter++ = pSmtpStats->BytesRcvdTotal; *pliCounter++ = pSmtpStats->BytesRcvdTotal; *pliCounter++ = pSmtpStats->BytesSentTotal + pSmtpStats->BytesRcvdTotal; *pliCounter++ = pSmtpStats->BytesSentTotal + pSmtpStats->BytesRcvdTotal;
*pliCounter++ = pSmtpStats->BytesSentMsg; *pliCounter++ = pSmtpStats->BytesSentMsg; *pliCounter++ = pSmtpStats->BytesRcvdMsg; *pliCounter++ = pSmtpStats->BytesRcvdMsg; *pliCounter++ = pSmtpStats->BytesSentMsg + pSmtpStats->BytesRcvdMsg; *pliCounter++ = pSmtpStats->BytesSentMsg + pSmtpStats->BytesRcvdMsg;
//
// Now move the DWORDs into the buffer.
//
pdwCounter = (DWORD *)pliCounter;
DebugTrace(0, "pdwCounter = %08lX", pdwCounter);
// Messages Received
*pdwCounter++ = pSmtpStats->NumMsgRecvd; *pdwCounter++ = pSmtpStats->NumMsgRecvd; *pdwCounter++ = pSmtpStats->NumRcptsRecvd; *pdwCounter++ = pSmtpStats->NumMsgRecvd * 100; *pdwCounter++ = pSmtpStats->NumRcptsRecvdLocal; *pdwCounter++ = pSmtpStats->NumRcptsRecvd; *pdwCounter++ = pSmtpStats->NumRcptsRecvdRemote; *pdwCounter++ = pSmtpStats->NumRcptsRecvd; *pdwCounter++ = pSmtpStats->MsgsRefusedDueToSize; *pdwCounter++ = pSmtpStats->MsgsRefusedDueToNoCAddrObjects; *pdwCounter++ = pSmtpStats->MsgsRefusedDueToNoMailObjects;
// MTA Deliveries
*pdwCounter++ = pSmtpStats->NumMsgsDelivered; *pdwCounter++ = pSmtpStats->NumMsgsDelivered; *pdwCounter++ = pSmtpStats->NumDeliveryRetries; *pdwCounter++ = pSmtpStats->NumDeliveryRetries; *pdwCounter++ = pSmtpStats->NumMsgsDelivered * 100; *pdwCounter++ = pSmtpStats->NumMsgsForwarded; *pdwCounter++ = pSmtpStats->NumMsgsForwarded; *pdwCounter++ = pSmtpStats->NumNDRGenerated; *pdwCounter++ = pSmtpStats->LocalQueueLength; *pdwCounter++ = pSmtpStats->RetryQueueLength; *pdwCounter++ = pSmtpStats->NumMailFileHandles; *pdwCounter++ = pSmtpStats->NumQueueFileHandles; *pdwCounter++ = pSmtpStats->CatQueueLength;
// Messages Sent
*pdwCounter++ = pSmtpStats->NumMsgsSent; *pdwCounter++ = pSmtpStats->NumMsgsSent; *pdwCounter++ = pSmtpStats->NumSendRetries; *pdwCounter++ = pSmtpStats->NumSendRetries; *pdwCounter++ = pSmtpStats->NumMsgsSent * 100; *pdwCounter++ = pSmtpStats->NumRcptsSent; *pdwCounter++ = pSmtpStats->NumMsgsSent * 100; *pdwCounter++ = pSmtpStats->RemoteQueueLength;
// DNS lookups
*pdwCounter++ = pSmtpStats->NumDnsQueries; *pdwCounter++ = pSmtpStats->NumDnsQueries; *pdwCounter++ = pSmtpStats->RemoteRetryQueueLength;
// Connections
*pdwCounter++ = pSmtpStats->NumConnInOpen; *pdwCounter++ = pSmtpStats->NumConnInOpen - pSmtpStats->NumConnInClose; *pdwCounter++ = pSmtpStats->NumConnOutOpen; *pdwCounter++ = pSmtpStats->NumConnOutOpen - pSmtpStats->NumConnOutClose; *pdwCounter++ = pSmtpStats->NumConnOutRefused;
*pdwCounter++ = pSmtpStats->NumProtocolErrs; *pdwCounter++ = pSmtpStats->NumProtocolErrs;
*pdwCounter++ = pSmtpStats->DirectoryDrops; *pdwCounter++ = pSmtpStats->DirectoryDrops; *pdwCounter++ = pSmtpStats->RoutingTableLookups; *pdwCounter++ = pSmtpStats->RoutingTableLookups; *pdwCounter++ = pSmtpStats->ETRNMessages; *pdwCounter++ = pSmtpStats->ETRNMessages;
// new AQueue counters
*pdwCounter++ = pSmtpStats->MsgsBadmailNoRecipients; *pdwCounter++ = pSmtpStats->MsgsBadmailHopCountExceeded; *pdwCounter++ = pSmtpStats->MsgsBadmailFailureGeneral; *pdwCounter++ = pSmtpStats->MsgsBadmailBadPickupFile; *pdwCounter++ = pSmtpStats->MsgsBadmailEvent; *pdwCounter++ = pSmtpStats->MsgsBadmailNdrOfDsn; *pdwCounter++ = pSmtpStats->MsgsPendingRouting; *pdwCounter++ = pSmtpStats->MsgsPendingUnreachableLink; *pdwCounter++ = pSmtpStats->SubmittedMessages; *pdwCounter++ = pSmtpStats->DSNFailures; *pdwCounter++ = pSmtpStats->MsgsInLocalDelivery;
// Cat counters
*pdwCounter++ = pSmtpStats->CatPerfBlock.CatSubmissions; *pdwCounter++ = pSmtpStats->CatPerfBlock.CatCompletions; *pdwCounter++ = pSmtpStats->CatPerfBlock.CurrentCategorizations; *pdwCounter++ = pSmtpStats->CatPerfBlock.SucceededCategorizations; *pdwCounter++ = pSmtpStats->CatPerfBlock.HardFailureCategorizations; *pdwCounter++ = pSmtpStats->CatPerfBlock.RetryFailureCategorizations; *pdwCounter++ = pSmtpStats->CatPerfBlock.RetryOutOfMemory; *pdwCounter++ = pSmtpStats->CatPerfBlock.RetryDSLogon; *pdwCounter++ = pSmtpStats->CatPerfBlock.RetryDSConnection; *pdwCounter++ = pSmtpStats->CatPerfBlock.RetryGeneric; *pdwCounter++ = pSmtpStats->CatPerfBlock.MessagesSubmittedToQueueing; *pdwCounter++ = pSmtpStats->CatPerfBlock.MessagesCreated; *pdwCounter++ = pSmtpStats->CatPerfBlock.MessagesAborted; *pdwCounter++ = pSmtpStats->CatPerfBlock.PreCatRecipients; *pdwCounter++ = pSmtpStats->CatPerfBlock.PostCatRecipients; *pdwCounter++ = pSmtpStats->CatPerfBlock.NDRdRecipients; *pdwCounter++ = pSmtpStats->CatPerfBlock.UnresolvedRecipients; *pdwCounter++ = pSmtpStats->CatPerfBlock.AmbiguousRecipients; *pdwCounter++ = pSmtpStats->CatPerfBlock.IllegalRecipients; *pdwCounter++ = pSmtpStats->CatPerfBlock.LoopRecipients; *pdwCounter++ = pSmtpStats->CatPerfBlock.GenericFailureRecipients; *pdwCounter++ = pSmtpStats->CatPerfBlock.RecipsInMemory; *pdwCounter++ = pSmtpStats->CatPerfBlock.UnresolvedSenders; *pdwCounter++ = pSmtpStats->CatPerfBlock.AmbiguousSenders; *pdwCounter++ = pSmtpStats->CatPerfBlock.AddressLookups; *pdwCounter++ = pSmtpStats->CatPerfBlock.AddressLookupCompletions; *pdwCounter++ = pSmtpStats->CatPerfBlock.AddressLookupsNotFound; *pdwCounter++ = pSmtpStats->CatPerfBlock.MailmsgDuplicateCollisions;
*pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.Connections; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.ConnectFailures; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.OpenConnections; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.Binds; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.BindFailures; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.Searches; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.PagedSearches; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.SearchFailures; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.PagedSearchFailures; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.SearchesCompleted; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.PagedSearchesCompleted; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.SearchCompletionFailures; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.PagedSearchCompletionFailures; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.GeneralCompletionFailures; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.AbandonedSearches; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.PendingSearches; *pdwCounter++ = 0; // padding
_ASSERT((BYTE *)pdwCounter - (BYTE *)pCounterBlock == SIZE_OF_SMTP_PERFORMANCE_DATA);
pdwEndCounter = pdwCounter;
//
// Increment the Total Block.
//
pCounterBlock = (SMTP_COUNTER_BLOCK *)(pInstanceTotalDefinition + 1);
pCounterBlock->PerfCounterBlock.ByteLength = SIZE_OF_SMTP_PERFORMANCE_DATA;
//
// Get the pointer to the first (unsigned __int64) counter. This
// pointer *must* be quadword aligned.
//
pliCounter = (unsigned __int64 *)(pCounterBlock + 1);
//
// Increment the 'unsigned __int64's in the buffer.
//
*pliCounter++ = *pliCounter + pSmtpStats->BytesSentTotal; *pliCounter++ = *pliCounter + pSmtpStats->BytesSentTotal; *pliCounter++ = *pliCounter + pSmtpStats->BytesRcvdTotal; *pliCounter++ = *pliCounter + pSmtpStats->BytesRcvdTotal; *pliCounter++ = *pliCounter + pSmtpStats->BytesSentTotal + pSmtpStats->BytesRcvdTotal; *pliCounter++ = *pliCounter + pSmtpStats->BytesSentTotal + pSmtpStats->BytesRcvdTotal;
*pliCounter++ = *pliCounter + pSmtpStats->BytesSentMsg; *pliCounter++ = *pliCounter + pSmtpStats->BytesSentMsg; *pliCounter++ = *pliCounter + pSmtpStats->BytesRcvdMsg; *pliCounter++ = *pliCounter + pSmtpStats->BytesRcvdMsg; *pliCounter++ = *pliCounter + pSmtpStats->BytesSentMsg + pSmtpStats->BytesRcvdMsg; *pliCounter++ = *pliCounter + pSmtpStats->BytesSentMsg + pSmtpStats->BytesRcvdMsg;
//
// Increment the DWORDs in the buffer.
//
pdwCounter = (DWORD *)pliCounter;
// Increment the Messages Received
*pdwCounter++ = *pdwCounter + pSmtpStats->NumMsgRecvd; *pdwCounter++ = *pdwCounter + pSmtpStats->NumMsgRecvd; *pdwCounter++ = *pdwCounter + pSmtpStats->NumRcptsRecvd; *pdwCounter++ = *pdwCounter + pSmtpStats->NumMsgRecvd * 100; *pdwCounter++ = *pdwCounter + pSmtpStats->NumRcptsRecvdLocal; *pdwCounter++ = *pdwCounter + pSmtpStats->NumRcptsRecvd; *pdwCounter++ = *pdwCounter + pSmtpStats->NumRcptsRecvdRemote; *pdwCounter++ = *pdwCounter + pSmtpStats->NumRcptsRecvd; *pdwCounter++ = *pdwCounter + pSmtpStats->MsgsRefusedDueToSize; *pdwCounter++ = *pdwCounter + pSmtpStats->MsgsRefusedDueToNoCAddrObjects; *pdwCounter++ = *pdwCounter + pSmtpStats->MsgsRefusedDueToNoMailObjects;
// Increment the MTA Deliveries
*pdwCounter++ = *pdwCounter + pSmtpStats->NumMsgsDelivered; *pdwCounter++ = *pdwCounter + pSmtpStats->NumMsgsDelivered; *pdwCounter++ = *pdwCounter + pSmtpStats->NumDeliveryRetries; *pdwCounter++ = *pdwCounter + pSmtpStats->NumDeliveryRetries; *pdwCounter++ = *pdwCounter + pSmtpStats->NumMsgsDelivered * 100; *pdwCounter++ = *pdwCounter + pSmtpStats->NumMsgsForwarded; *pdwCounter++ = *pdwCounter + pSmtpStats->NumMsgsForwarded; *pdwCounter++ = *pdwCounter + pSmtpStats->NumNDRGenerated; *pdwCounter++ = *pdwCounter + pSmtpStats->LocalQueueLength; *pdwCounter++ = *pdwCounter + pSmtpStats->RetryQueueLength; *pdwCounter++ = *pdwCounter + pSmtpStats->NumMailFileHandles; *pdwCounter++ = *pdwCounter + pSmtpStats->NumQueueFileHandles; *pdwCounter++ = *pdwCounter + pSmtpStats->CatQueueLength;
// Increment the Messages Sent
*pdwCounter++ = *pdwCounter + pSmtpStats->NumMsgsSent; *pdwCounter++ = *pdwCounter + pSmtpStats->NumMsgsSent; *pdwCounter++ = *pdwCounter + pSmtpStats->NumSendRetries; *pdwCounter++ = *pdwCounter + pSmtpStats->NumSendRetries; *pdwCounter++ = *pdwCounter + pSmtpStats->NumMsgsSent * 100; *pdwCounter++ = *pdwCounter + pSmtpStats->NumRcptsSent; *pdwCounter++ = *pdwCounter + pSmtpStats->NumMsgsSent * 100; *pdwCounter++ = *pdwCounter + pSmtpStats->RemoteQueueLength;
// Increment the DNS lookups
*pdwCounter++ = *pdwCounter + pSmtpStats->NumDnsQueries; *pdwCounter++ = *pdwCounter + pSmtpStats->NumDnsQueries; *pdwCounter++ = *pdwCounter + pSmtpStats->RemoteRetryQueueLength;
// Increment the Connections
*pdwCounter++ = *pdwCounter + pSmtpStats->NumConnInOpen; *pdwCounter++ = *pdwCounter + pSmtpStats->NumConnInOpen - pSmtpStats->NumConnInClose; *pdwCounter++ = *pdwCounter + pSmtpStats->NumConnOutOpen; *pdwCounter++ = *pdwCounter + pSmtpStats->NumConnOutOpen - pSmtpStats->NumConnOutClose; *pdwCounter++ = *pdwCounter + pSmtpStats->NumConnOutRefused;
*pdwCounter++ = *pdwCounter + pSmtpStats->NumProtocolErrs; *pdwCounter++ = *pdwCounter + pSmtpStats->NumProtocolErrs;
*pdwCounter++ = *pdwCounter +pSmtpStats->DirectoryDrops; *pdwCounter++ = *pdwCounter +pSmtpStats->DirectoryDrops; *pdwCounter++ = *pdwCounter +pSmtpStats->RoutingTableLookups; *pdwCounter++ = *pdwCounter +pSmtpStats->RoutingTableLookups; *pdwCounter++ = *pdwCounter +pSmtpStats->ETRNMessages; *pdwCounter++ = *pdwCounter +pSmtpStats->ETRNMessages;
*pdwCounter++ = *pdwCounter +pSmtpStats->MsgsBadmailNoRecipients; *pdwCounter++ = *pdwCounter +pSmtpStats->MsgsBadmailHopCountExceeded; *pdwCounter++ = *pdwCounter +pSmtpStats->MsgsBadmailFailureGeneral; *pdwCounter++ = *pdwCounter +pSmtpStats->MsgsBadmailBadPickupFile; *pdwCounter++ = *pdwCounter +pSmtpStats->MsgsBadmailEvent; *pdwCounter++ = *pdwCounter +pSmtpStats->MsgsBadmailNdrOfDsn; *pdwCounter++ = *pdwCounter +pSmtpStats->MsgsPendingRouting; *pdwCounter++ = *pdwCounter +pSmtpStats->MsgsPendingUnreachableLink; *pdwCounter++ = *pdwCounter +pSmtpStats->SubmittedMessages; *pdwCounter++ = *pdwCounter +pSmtpStats->DSNFailures; *pdwCounter++ = *pdwCounter +pSmtpStats->MsgsInLocalDelivery;
// Cat counters
*pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.CatSubmissions; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.CatCompletions; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.CurrentCategorizations; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.SucceededCategorizations; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.HardFailureCategorizations; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.RetryFailureCategorizations; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.RetryOutOfMemory; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.RetryDSLogon; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.RetryDSConnection; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.RetryGeneric; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.MessagesSubmittedToQueueing; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.MessagesCreated; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.MessagesAborted; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.PreCatRecipients; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.PostCatRecipients; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.NDRdRecipients; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.UnresolvedRecipients; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.AmbiguousRecipients; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.IllegalRecipients; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.LoopRecipients; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.GenericFailureRecipients; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.RecipsInMemory; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.UnresolvedSenders; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.AmbiguousSenders; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.AddressLookups; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.AddressLookupCompletions; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.AddressLookupsNotFound; *pdwCounter++ = *pdwCounter +pSmtpStats->CatPerfBlock.MailmsgDuplicateCollisions; //
// LDAP counters are already global
//
*pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.Connections; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.ConnectFailures; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.OpenConnections; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.Binds; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.BindFailures; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.Searches; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.PagedSearches; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.SearchFailures; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.PagedSearchFailures; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.SearchesCompleted; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.PagedSearchesCompleted; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.SearchCompletionFailures; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.PagedSearchCompletionFailures; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.GeneralCompletionFailures; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.AbandonedSearches; *pdwCounter++ = pSmtpStats->CatPerfBlock.LDAPPerfBlock.PendingSearches; *pdwCounter++ = 0; // padding
_ASSERT((BYTE *)pdwCounter - (BYTE *)pCounterBlock == SIZE_OF_SMTP_PERFORMANCE_DATA);
//
// Increment in the returned statistics block
//
pSmtpStatsBlock++; }
//
// Free the API buffer.
//
//MIDL_user_free((LPBYTE)pSmtpStats);
NetApiBufferFree((LPBYTE)pSmtpStatsBlockArray);
dwInstanceCount++; // for the _Totals instance.
pSmtpDataDefinition->SmtpObjectType.TotalByteLength = sizeof(SMTP_DATA_DEFINITION) + dwInstanceCount * (sizeof(SMTP_INSTANCE_DEFINITION) + SIZE_OF_SMTP_PERFORMANCE_DATA); pSmtpDataDefinition->SmtpObjectType.NumInstances = dwInstanceCount;
//
// Update arguments for return.
//
*lppData = (PVOID) pdwEndCounter; *lpNumObjectTypes = 1; *lpcbTotalBytes = (DWORD)((BYTE *)pdwEndCounter - (BYTE *)pSmtpDataDefinition);
DebugTrace(0, "pData = %08lX", *lppData); DebugTrace(0, "NumObjectTypes = %08lX", *lpNumObjectTypes); DebugTrace(0, "cbTotalBytes = %08lX", *lpcbTotalBytes); DebugTrace(0, "sizeof *pSmtpStat = %08lX", sizeof *pSmtpStats);
//
// Success! Honest!!
//
TraceFunctLeave(); return NO_ERROR;
} // CollectSmtpPerformanceData
/*******************************************************************
NAME: CloseSmtpPerformanceData
SYNOPSIS: Terminates the performance counters.
RETURNS: DWORD - Win32 status code.
HISTORY: KeithMo 07-Jun-1993 Created.
********************************************************************/ DWORD APIENTRY CloseSmtpPerformanceData(VOID) { TraceFunctEnter("CloseSmtpPerformanceData"); //
// No real cleanup to do here.
//
cOpens--;
TraceFunctLeave(); //
// shuts down and flushes all trace statements
//
#ifndef NOTRACE
TermAsyncTrace(); #endif
return NO_ERROR; }
|