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.
 
 
 
 
 
 

853 lines
32 KiB

//---------------------------------------------------------------
// 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;
}