windows-nt/Source/XPSP1/NT/inetsrv/iis/svcs/smtp/server/findiis.cxx
2020-09-26 16:20:57 +08:00

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