//--------------------------------------------------------------- // 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 // For ntrtl.h #include // RtlLargeInteger*() #include // For windows.h #include #include #include #include #include #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; }