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.

223 lines
5.0 KiB

  1. #define INCL_INETSRV_INCS
  2. #include "smtpinc.h"
  3. //+---------------------------------------------------------------
  4. //
  5. // Function: CheckInstanceId
  6. //
  7. // Synopsis: Callback from IIS_SERVICE iterator
  8. //
  9. // Arguments: void
  10. //
  11. // Returns: TRUE is success, else FALSE
  12. //
  13. // History:
  14. //
  15. //----------------------------------------------------------------
  16. BOOL
  17. CheckInstanceId(
  18. PVOID pvContext,
  19. PVOID pvContext1,
  20. PIIS_SERVER_INSTANCE pInstance
  21. )
  22. {
  23. PSMTP_SERVER_INSTANCE pSmtpInstance = (PSMTP_SERVER_INSTANCE)pInstance ;
  24. DWORD dwInstanceId = (DWORD)((DWORD_PTR)pvContext) ;
  25. PSMTP_SERVER_INSTANCE* ppSmtpInstance = (PSMTP_SERVER_INSTANCE*)pvContext1 ;
  26. //
  27. // Check this instance for its id - if it matches the id we are looking for
  28. // return FALSE to discontinue the iteration.
  29. //
  30. if( dwInstanceId == pSmtpInstance->QueryInstanceId() )
  31. {
  32. // found it
  33. if(!pSmtpInstance->IsShuttingDown())
  34. {
  35. //reference it first
  36. pSmtpInstance->Reference();
  37. *ppSmtpInstance = pSmtpInstance ;
  38. return FALSE ;
  39. }
  40. else
  41. {
  42. //lie and say we did not find the instance
  43. //if we are shutting down
  44. *ppSmtpInstance = NULL;
  45. return FALSE;
  46. }
  47. }
  48. // did not find it - continue iteration
  49. return TRUE;
  50. }
  51. //+---------------------------------------------------------------
  52. //
  53. // Function: FindIISInstance
  54. //
  55. // Synopsis: Returns an instance pointer for the given ID
  56. //
  57. // Arguments: pointer to an SMTP server calss and instance ID
  58. //
  59. // Returns: pointer to an SMTP instance class
  60. //
  61. // History:
  62. //
  63. //----------------------------------------------------------------
  64. PSMTP_SERVER_INSTANCE
  65. FindIISInstance(
  66. PSMTP_IIS_SERVICE pService,
  67. DWORD dwInstanceId
  68. )
  69. {
  70. PFN_INSTANCE_ENUM pfnInstanceEnum = NULL ;
  71. PSMTP_SERVER_INSTANCE pInstance = NULL ;
  72. TraceFunctEnter("FindIISInstance");
  73. pService->AcquireServiceShareLock();
  74. //
  75. // Iterate over all instances
  76. //
  77. pfnInstanceEnum = (PFN_INSTANCE_ENUM)&CheckInstanceId;
  78. if( !pService->EnumServiceInstances(
  79. (PVOID)(SIZE_T)dwInstanceId,
  80. (PVOID)&pInstance,
  81. pfnInstanceEnum
  82. ) ) {
  83. ErrorTrace(0,"Error enumerating instances");
  84. }
  85. //if we found an instance, but it's not running, or the service is
  86. //not running, then dereference the instance and leave
  87. if(pInstance && ( (pInstance->QueryServerState() != MD_SERVER_STATE_STARTED)
  88. || (pService->QueryCurrentServiceState() != SERVICE_RUNNING)))
  89. {
  90. pInstance->Dereference();
  91. pInstance = NULL;
  92. }
  93. pService->ReleaseServiceShareLock();
  94. TraceFunctLeave();
  95. return pInstance ;
  96. }
  97. BOOL CountInstances(
  98. PVOID pvContext,
  99. PVOID pvContext1,
  100. PIIS_SERVER_INSTANCE pInstance
  101. )
  102. {
  103. if(pInstance)
  104. {
  105. (*(DWORD*)pvContext)++;
  106. }
  107. return TRUE;
  108. }
  109. BOOL GetInstancePerfData(
  110. PVOID pvContext,
  111. PVOID pvContext1,
  112. PIIS_SERVER_INSTANCE pInstance
  113. )
  114. {
  115. DWORD dwInstanceId = (DWORD)((DWORD_PTR)pvContext) ;
  116. PSMTP_STATISTICS_BLOCK pStatsBlock;
  117. PSMTP_INSTANCE_LIST_ENTRY pInstanceInfo = NULL;
  118. pStatsBlock = *(PSMTP_STATISTICS_BLOCK *) pvContext1;
  119. if(pInstance->QueryInstanceId() <= (DWORD)((DWORD_PTR)pvContext))
  120. {
  121. pStatsBlock->dwInstance = pInstance->QueryInstanceId();
  122. pInstanceInfo = ((SMTP_SERVER_INSTANCE *)pInstance)->GetSmtpInstanceInfo();
  123. if(pInstanceInfo)
  124. {
  125. pInstanceInfo->pSmtpServerStatsObj->CopyToStatsBuffer(&(pStatsBlock->Stats_0));
  126. }
  127. //((SMTP_SERVER_INSTANCE *)pInstance)->GetSmtpInstanceInfo()->pSmtpServerStatsObj->CopyToStatsBuffer(&(pStatsBlock->Stats_0));
  128. (*(PSMTP_STATISTICS_BLOCK *) pvContext1)++;
  129. return TRUE;
  130. }
  131. return FALSE;
  132. }
  133. PSMTP_STATISTICS_BLOCK_ARRAY GetServerPerfCounters(PSMTP_IIS_SERVICE pService)
  134. {
  135. DWORD NumInstances = 0;
  136. DWORD dwAlloc = 0;
  137. PSMTP_INSTANCE_LIST_ENTRY pSmtpInfo = NULL;
  138. PSMTP_STATISTICS_BLOCK_ARRAY pSmtpStatsBlockArray = NULL;
  139. PSMTP_STATISTICS_BLOCK pStatsBlock = NULL;
  140. TraceFunctEnter("GetServerPerfCounters");
  141. PFN_INSTANCE_ENUM pfnInstanceEnum = NULL ;
  142. //Get the count of the number of instances first
  143. pfnInstanceEnum = (PFN_INSTANCE_ENUM)&CountInstances;
  144. if( !pService->EnumServiceInstances(
  145. (PVOID)&NumInstances,
  146. (PVOID)NULL,
  147. pfnInstanceEnum
  148. ) )
  149. {
  150. ErrorTrace(0,"Error counting instances");
  151. }
  152. if (NumInstances == 0)
  153. {
  154. TraceFunctLeave();
  155. return NULL;
  156. }
  157. //allocate memory to return to caller
  158. dwAlloc = sizeof(SMTP_STATISTICS_BLOCK_ARRAY) + NumInstances * sizeof(SMTP_STATISTICS_BLOCK);
  159. pSmtpStatsBlockArray = (PSMTP_STATISTICS_BLOCK_ARRAY)MIDL_user_allocate(dwAlloc);
  160. if (!pSmtpStatsBlockArray)
  161. {
  162. TraceFunctLeave();
  163. return NULL;
  164. }
  165. ZeroMemory(pSmtpStatsBlockArray, dwAlloc);
  166. //fill in memory structure
  167. pSmtpStatsBlockArray->cEntries = NumInstances;
  168. pStatsBlock = pSmtpStatsBlockArray->aStatsBlock;
  169. pfnInstanceEnum = (PFN_INSTANCE_ENUM)&GetInstancePerfData;
  170. if( !pService->EnumServiceInstances(
  171. (PVOID)(SIZE_T)NumInstances,
  172. (PVOID)&pStatsBlock,
  173. pfnInstanceEnum
  174. ) )
  175. {
  176. ErrorTrace(0,"Error counting instances");
  177. }
  178. TraceFunctLeave();
  179. return pSmtpStatsBlockArray;
  180. }