224 lines
5 KiB
C++
224 lines
5 KiB
C++
#define INCL_INETSRV_INCS
|
|
#include "smtpinc.h"
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Function: CheckInstanceId
|
|
//
|
|
// Synopsis: Callback from IIS_SERVICE iterator
|
|
//
|
|
// Arguments: void
|
|
//
|
|
// Returns: TRUE is success, else FALSE
|
|
//
|
|
// History:
|
|
//
|
|
//----------------------------------------------------------------
|
|
|
|
BOOL
|
|
CheckInstanceId(
|
|
PVOID pvContext,
|
|
PVOID pvContext1,
|
|
PIIS_SERVER_INSTANCE pInstance
|
|
)
|
|
{
|
|
PSMTP_SERVER_INSTANCE pSmtpInstance = (PSMTP_SERVER_INSTANCE)pInstance ;
|
|
DWORD dwInstanceId = (DWORD)((DWORD_PTR)pvContext) ;
|
|
PSMTP_SERVER_INSTANCE* ppSmtpInstance = (PSMTP_SERVER_INSTANCE*)pvContext1 ;
|
|
|
|
//
|
|
// Check this instance for its id - if it matches the id we are looking for
|
|
// return FALSE to discontinue the iteration.
|
|
//
|
|
if( dwInstanceId == pSmtpInstance->QueryInstanceId() )
|
|
{
|
|
// found it
|
|
if(!pSmtpInstance->IsShuttingDown())
|
|
{
|
|
//reference it first
|
|
pSmtpInstance->Reference();
|
|
|
|
*ppSmtpInstance = pSmtpInstance ;
|
|
return FALSE ;
|
|
}
|
|
else
|
|
{
|
|
//lie and say we did not find the instance
|
|
//if we are shutting down
|
|
*ppSmtpInstance = NULL;
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
// did not find it - continue iteration
|
|
return TRUE;
|
|
}
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Function: FindIISInstance
|
|
//
|
|
// Synopsis: Returns an instance pointer for the given ID
|
|
//
|
|
// Arguments: pointer to an SMTP server calss and instance ID
|
|
//
|
|
// Returns: pointer to an SMTP instance class
|
|
//
|
|
// History:
|
|
//
|
|
//----------------------------------------------------------------
|
|
PSMTP_SERVER_INSTANCE
|
|
FindIISInstance(
|
|
PSMTP_IIS_SERVICE pService,
|
|
DWORD dwInstanceId
|
|
)
|
|
|
|
{
|
|
PFN_INSTANCE_ENUM pfnInstanceEnum = NULL ;
|
|
PSMTP_SERVER_INSTANCE pInstance = NULL ;
|
|
|
|
TraceFunctEnter("FindIISInstance");
|
|
|
|
pService->AcquireServiceShareLock();
|
|
//
|
|
// Iterate over all instances
|
|
//
|
|
pfnInstanceEnum = (PFN_INSTANCE_ENUM)&CheckInstanceId;
|
|
if( !pService->EnumServiceInstances(
|
|
(PVOID)(SIZE_T)dwInstanceId,
|
|
(PVOID)&pInstance,
|
|
pfnInstanceEnum
|
|
) ) {
|
|
|
|
ErrorTrace(0,"Error enumerating instances");
|
|
}
|
|
|
|
//if we found an instance, but it's not running, or the service is
|
|
//not running, then dereference the instance and leave
|
|
if(pInstance && ( (pInstance->QueryServerState() != MD_SERVER_STATE_STARTED)
|
|
|| (pService->QueryCurrentServiceState() != SERVICE_RUNNING)))
|
|
|
|
|
|
{
|
|
pInstance->Dereference();
|
|
pInstance = NULL;
|
|
}
|
|
|
|
pService->ReleaseServiceShareLock();
|
|
|
|
TraceFunctLeave();
|
|
|
|
return pInstance ;
|
|
}
|
|
|
|
|
|
BOOL CountInstances(
|
|
PVOID pvContext,
|
|
PVOID pvContext1,
|
|
PIIS_SERVER_INSTANCE pInstance
|
|
)
|
|
{
|
|
|
|
if(pInstance)
|
|
{
|
|
(*(DWORD*)pvContext)++;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL GetInstancePerfData(
|
|
PVOID pvContext,
|
|
PVOID pvContext1,
|
|
PIIS_SERVER_INSTANCE pInstance
|
|
)
|
|
{
|
|
|
|
DWORD dwInstanceId = (DWORD)((DWORD_PTR)pvContext) ;
|
|
PSMTP_STATISTICS_BLOCK pStatsBlock;
|
|
PSMTP_INSTANCE_LIST_ENTRY pInstanceInfo = NULL;
|
|
|
|
pStatsBlock = *(PSMTP_STATISTICS_BLOCK *) pvContext1;
|
|
|
|
if(pInstance->QueryInstanceId() <= (DWORD)((DWORD_PTR)pvContext))
|
|
{
|
|
pStatsBlock->dwInstance = pInstance->QueryInstanceId();
|
|
|
|
pInstanceInfo = ((SMTP_SERVER_INSTANCE *)pInstance)->GetSmtpInstanceInfo();
|
|
|
|
if(pInstanceInfo)
|
|
{
|
|
pInstanceInfo->pSmtpServerStatsObj->CopyToStatsBuffer(&(pStatsBlock->Stats_0));
|
|
}
|
|
//((SMTP_SERVER_INSTANCE *)pInstance)->GetSmtpInstanceInfo()->pSmtpServerStatsObj->CopyToStatsBuffer(&(pStatsBlock->Stats_0));
|
|
(*(PSMTP_STATISTICS_BLOCK *) pvContext1)++;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
PSMTP_STATISTICS_BLOCK_ARRAY GetServerPerfCounters(PSMTP_IIS_SERVICE pService)
|
|
{
|
|
DWORD NumInstances = 0;
|
|
DWORD dwAlloc = 0;
|
|
PSMTP_INSTANCE_LIST_ENTRY pSmtpInfo = NULL;
|
|
PSMTP_STATISTICS_BLOCK_ARRAY pSmtpStatsBlockArray = NULL;
|
|
PSMTP_STATISTICS_BLOCK pStatsBlock = NULL;
|
|
|
|
TraceFunctEnter("GetServerPerfCounters");
|
|
|
|
PFN_INSTANCE_ENUM pfnInstanceEnum = NULL ;
|
|
|
|
//Get the count of the number of instances first
|
|
pfnInstanceEnum = (PFN_INSTANCE_ENUM)&CountInstances;
|
|
|
|
if( !pService->EnumServiceInstances(
|
|
(PVOID)&NumInstances,
|
|
(PVOID)NULL,
|
|
pfnInstanceEnum
|
|
) )
|
|
{
|
|
|
|
ErrorTrace(0,"Error counting instances");
|
|
}
|
|
|
|
if (NumInstances == 0)
|
|
{
|
|
TraceFunctLeave();
|
|
return NULL;
|
|
}
|
|
|
|
//allocate memory to return to caller
|
|
dwAlloc = sizeof(SMTP_STATISTICS_BLOCK_ARRAY) + NumInstances * sizeof(SMTP_STATISTICS_BLOCK);
|
|
pSmtpStatsBlockArray = (PSMTP_STATISTICS_BLOCK_ARRAY)MIDL_user_allocate(dwAlloc);
|
|
if (!pSmtpStatsBlockArray)
|
|
{
|
|
TraceFunctLeave();
|
|
return NULL;
|
|
}
|
|
|
|
ZeroMemory(pSmtpStatsBlockArray, dwAlloc);
|
|
|
|
//fill in memory structure
|
|
pSmtpStatsBlockArray->cEntries = NumInstances;
|
|
pStatsBlock = pSmtpStatsBlockArray->aStatsBlock;
|
|
pfnInstanceEnum = (PFN_INSTANCE_ENUM)&GetInstancePerfData;
|
|
|
|
if( !pService->EnumServiceInstances(
|
|
(PVOID)(SIZE_T)NumInstances,
|
|
(PVOID)&pStatsBlock,
|
|
pfnInstanceEnum
|
|
) )
|
|
{
|
|
|
|
ErrorTrace(0,"Error counting instances");
|
|
}
|
|
|
|
|
|
TraceFunctLeave();
|
|
return pSmtpStatsBlockArray;
|
|
}
|
|
|