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.

408 lines
10 KiB

  1. /*----------------------------------------------------------------------------
  2. Cpsmon.cpp
  3. Implementation of pbsmon.dll -- the perfmon DLL for counting the number of
  4. times the phone book server was accessed
  5. since it started
  6. Copyright (c) 1997-1998 Microsoft Corporation
  7. All rights reserved.
  8. Authors:
  9. t-geetat Geeta Tarachandani
  10. History:
  11. 6/2/97 t-geetat Created
  12. --------------------------------------------------------------------------*/
  13. #include <windows.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <assert.h>
  17. #include "cpsmon.h"
  18. #include "CpsSym.h"
  19. #include "LoadData.h"
  20. BOOL g_bOpenOK =FALSE; // TRUE if Open went OK, FALSE otherwise
  21. DWORD g_dwNumOpens =0; // Active "opens" reference counts
  22. CPSMON_DATA_DEFINITION g_CpsMonDataDef;
  23. HANDLE g_hSharedFileMapping=NULL; // Handle to shared file map
  24. CCpsCounter *g_pCpsCounter=NULL; // Pointer to the shared object
  25. HANDLE g_hSemaphore=NULL; // Handle to semaphore for shared file
  26. //----------------------------------------------------------------------------
  27. //
  28. // Function: GetSemaphore
  29. //
  30. // Synopsis: This function gets hold of the semaphore for accessing shared file.
  31. //
  32. // Arguments: None.
  33. //
  34. // Returns: TRUE if succeeds, FALSE if fails.
  35. //
  36. // History: 06/02/97 t-geetat Created
  37. //
  38. //----------------------------------------------------------------------------
  39. BOOL GetSemaphore()
  40. {
  41. DWORD WaitRetValue = WaitForSingleObject( g_hSemaphore, INFINITE );
  42. switch( WaitRetValue )
  43. {
  44. case WAIT_OBJECT_0 : return TRUE ;
  45. case WAIT_ABANDONED : return TRUE;
  46. default : return FALSE;
  47. }
  48. return FALSE;
  49. }
  50. //----------------------------------------------------------------------------
  51. //
  52. // Function: OpenPerfMon
  53. //
  54. // Synopsis: This function opens & maps the shared memory used to pass
  55. // counter-values between the phone-book server & perfmon.dll
  56. // It also initializes the data-structures used to pass data back
  57. // to the registry
  58. //
  59. // Arguments: lpDeviceName -- Pointer to object ID of the device to be opened
  60. // --> Should be NULL.
  61. //
  62. // Returns: ERROR_SUCCESS if succeeds, GetLastError() if fails.
  63. //
  64. // History: 06/02/97 t-geetat Created
  65. //
  66. //----------------------------------------------------------------------------
  67. DWORD OpenPerfMon( LPWSTR lpDeviceName )
  68. {
  69. if ( g_bOpenOK )
  70. {
  71. g_dwNumOpens ++;
  72. return ERROR_SUCCESS;
  73. }
  74. /*--------------------
  75. * Open the semaphore
  76. *-------------------*/
  77. if(g_hSemaphore == NULL)
  78. {
  79. g_hSemaphore = OpenSemaphore(
  80. SYNCHRONIZE | SEMAPHORE_MODIFY_STATE, // Desired for sync
  81. FALSE, // Inheritance not desired
  82. SEMAPHORE_OBJECT ); // Semaphore name -- from "cpsmon.h"
  83. }
  84. if ( NULL == g_hSemaphore )
  85. {
  86. //
  87. // the phone book server DLL should create this Semaphore. So we can assume
  88. // the server has not been loaded yet. Just return silently.
  89. //
  90. return ERROR_SUCCESS;
  91. }
  92. /*-------------------------------------
  93. * Open shared memory ( if exists )
  94. *------------------------------------*/
  95. g_hSharedFileMapping = OpenFileMapping(
  96. FILE_MAP_READ, // Read only access desired
  97. FALSE, // Don't want to inherit
  98. SHARED_OBJECT); // from "cpsmon.h"
  99. if ( NULL == g_hSharedFileMapping )
  100. {
  101. goto CleanUp;
  102. }
  103. /*----------------------------------
  104. * Map the shared-file into memory
  105. *---------------------------------*/
  106. g_pCpsCounter = (CCpsCounter *)MapViewOfFileEx(
  107. g_hSharedFileMapping, // File mapping handle
  108. FILE_MAP_READ, // Read only access desired
  109. 0, // |_ File Offset
  110. 0, // |
  111. sizeof( CCpsCounter ), // no. of bytes to map
  112. NULL ); // Any address
  113. if ( NULL == g_pCpsCounter )
  114. {
  115. goto CleanUp;
  116. }
  117. /*------------------------------------------------
  118. * Initialize the data-structure g_CpsMonDataDef
  119. *-----------------------------------------------*/
  120. InitializeDataDef();
  121. /*-----------------------------------------------------------------
  122. * Update static data strucutures g_CpsMonDataDef by adding base to
  123. * the offset value in the structure.
  124. *-----------------------------------------------------------------*/
  125. if (!UpdateDataDefFromRegistry())
  126. {
  127. goto CleanUp;
  128. }
  129. /*-------------
  130. * Success :)
  131. *-------------*/
  132. g_bOpenOK = TRUE;
  133. g_dwNumOpens ++;
  134. return ERROR_SUCCESS;
  135. CleanUp :
  136. /*-------------
  137. * Failure :(
  138. *-------------*/
  139. if ( NULL != g_hSemaphore )
  140. {
  141. CloseHandle( g_hSemaphore );
  142. g_hSemaphore = NULL;
  143. }
  144. if ( NULL != g_hSharedFileMapping )
  145. {
  146. CloseHandle( g_hSharedFileMapping );
  147. g_hSharedFileMapping = NULL;
  148. }
  149. if ( NULL != g_pCpsCounter )
  150. {
  151. g_pCpsCounter = NULL;
  152. }
  153. return GetLastError();
  154. }
  155. //----------------------------------------------------------------------------
  156. //
  157. // Function: CollectPerfMon
  158. //
  159. // Synopsis: This function opens & maps the shared memory used to pass
  160. // counter-values between the phone-book server & perfmon.dll
  161. // It also initializes the data-structures used to pass data back
  162. // to the registry
  163. //
  164. // Arguments:
  165. // lpwszValue Pointer to wide character string passed by registry
  166. //
  167. // lppData IN : Pointer to address of buffer to receive completed
  168. // PerfDataBlock and subordinate structures This routine
  169. // appends its data to the buffer starting at *lppData.
  170. // OUT : Points to the first byte after the data structure added
  171. // by this routine.
  172. //
  173. // lpcbTotalBytes IN : Address of DWORD that tells the size in bytes
  174. // of the buffer *lppData.
  175. // OUT : The number of bytes added by this routine is
  176. // written to the DWORD pointed to by this arg.
  177. //
  178. // lpcObjectTypes IN : Address of DWORD to receive the number of
  179. // objects added by this routine
  180. // OUT : The number of objs. added by this routine.
  181. //
  182. // Returns: ERROR_SUCCESS if succeeds, GetLastError() if fails.
  183. //
  184. // History: 06/02/97 t-geetat Created
  185. //
  186. //----------------------------------------------------------------------------
  187. DWORD CollectPerfMon(
  188. IN LPWSTR lpwszValue,
  189. IN OUT LPVOID *lppData,
  190. IN OUT LPDWORD lpcbTotalBytes,
  191. IN OUT LPDWORD lpcObjectTypes
  192. )
  193. {
  194. DWORD dwQueryType;
  195. CPSMON_DATA_DEFINITION *pCpsMonDataDef;
  196. CPSMON_COUNTERS *pCpsMonCounters;
  197. DWORD SpaceNeeded = 0;
  198. //See if the semaphore was created after the intial OpenPerfmon.
  199. if(g_hSemaphore == NULL)
  200. {
  201. g_hSemaphore = OpenSemaphore(
  202. SYNCHRONIZE | SEMAPHORE_MODIFY_STATE, // Desired for sync
  203. FALSE, // Inheritance not desired
  204. SEMAPHORE_OBJECT ); // Semaphore name -- from "cpsmon.h"
  205. if(g_hSemaphore)
  206. {
  207. OpenPerfMon(NULL);
  208. }
  209. }
  210. if ( NULL == g_hSemaphore )
  211. {
  212. //
  213. // the phone book server DLL should create this Semaphore. So we can assume
  214. // the server has not been loaded yet. Just return silently.
  215. //
  216. *lpcbTotalBytes = (DWORD) 0;
  217. *lpcObjectTypes = (DWORD) 0;
  218. return ERROR_SUCCESS;
  219. }
  220. /*------------------------
  221. * Check if Open went OK
  222. *------------------------*/
  223. if ( !g_bOpenOK )
  224. {
  225. /*-----------------------------------------
  226. * Unable to continue because open failed
  227. *-----------------------------------------*/
  228. *lpcbTotalBytes = (DWORD) 0;
  229. *lpcObjectTypes = (DWORD) 0;
  230. return ERROR_SUCCESS;
  231. }
  232. /*------------------------------------
  233. * Retrieve the TYPE of the request
  234. *------------------------------------*/
  235. dwQueryType = GetQueryType( lpwszValue );
  236. if ( QUERY_FOREIGN == dwQueryType )
  237. {
  238. /*-------------------------------------
  239. * Unable to service non-NT requests
  240. *------------------------------------*/
  241. *lpcbTotalBytes = (DWORD) 0;
  242. *lpcObjectTypes = (DWORD) 0;
  243. return ERROR_SUCCESS;
  244. }
  245. if ( QUERY_ITEMS == dwQueryType )
  246. {
  247. /*-----------------------------------------------
  248. * The registry is asking for specifis objects.
  249. * Check if we're one of the chosen
  250. *-----------------------------------------------*/
  251. if ( !IsNumberInUnicodeList(
  252. g_CpsMonDataDef.m_CpsMonObjectType.ObjectNameTitleIndex,
  253. lpwszValue ) )
  254. {
  255. *lpcbTotalBytes = (DWORD) 0;
  256. *lpcObjectTypes = (DWORD) 0;
  257. return ERROR_SUCCESS;
  258. }
  259. }
  260. /*-------------------------------------------
  261. * We need space for header and the counters
  262. * Let's see if there's enough space
  263. *-------------------------------------------*/
  264. SpaceNeeded = sizeof(CPSMON_DATA_DEFINITION) + sizeof( CPSMON_COUNTERS );
  265. if ( SpaceNeeded > *lpcbTotalBytes )
  266. {
  267. *lpcbTotalBytes = (DWORD) 0;
  268. *lpcObjectTypes = (DWORD) 0;
  269. return ERROR_MORE_DATA;
  270. }
  271. /*-------------------------------------------------------------
  272. * Copy the initialized Object Type & the Counter Definitions
  273. * into the caller's data buffer
  274. *-------------------------------------------------------------*/
  275. pCpsMonDataDef = (CPSMON_DATA_DEFINITION *) *lppData;
  276. memmove( pCpsMonDataDef, &g_CpsMonDataDef, sizeof(CPSMON_DATA_DEFINITION) );
  277. /*--------------------------------
  278. * Now try to retrieve the data
  279. *-------------------------------*/
  280. pCpsMonCounters = (CPSMON_COUNTERS *)(pCpsMonDataDef + 1);
  281. if ( GetSemaphore() )
  282. {
  283. CPSMON_COUNTERS CpsMonCounters = {
  284. // The PERF_COUNTER_BLOCK structure
  285. { { sizeof( CPSMON_COUNTERS )}, 0},
  286. // The RAW counters
  287. g_pCpsCounter->m_dwTotalHits,
  288. g_pCpsCounter->m_dwNoUpgradeHits,
  289. g_pCpsCounter->m_dwDeltaUpgradeHits,
  290. g_pCpsCounter->m_dwFullUpgradeHits,
  291. g_pCpsCounter->m_dwErrors,
  292. // The RATE counters
  293. g_pCpsCounter->m_dwTotalHits,
  294. g_pCpsCounter->m_dwNoUpgradeHits,
  295. g_pCpsCounter->m_dwDeltaUpgradeHits,
  296. g_pCpsCounter->m_dwFullUpgradeHits,
  297. g_pCpsCounter->m_dwErrors,
  298. };
  299. memmove( pCpsMonCounters, &CpsMonCounters, sizeof(CPSMON_COUNTERS) );
  300. }
  301. ReleaseSemaphore( g_hSemaphore, 1, NULL );
  302. /*-------------------------------
  303. * Update arguements for return
  304. *------------------------------*/
  305. *lppData = (LPBYTE)(*lppData) + SpaceNeeded;
  306. *lpcObjectTypes = 1;
  307. *lpcbTotalBytes = SpaceNeeded;
  308. /*--------------------
  309. * Success at last :)
  310. *-------------------*/
  311. return ERROR_SUCCESS;
  312. }
  313. //----------------------------------------------------------------------------
  314. //
  315. // Function: ClosePerfMon
  316. //
  317. // Synopsis: This function closes the open handles to the shared file and semaphore
  318. //
  319. // Arguments: None
  320. //
  321. // Returns: ERROR_SUCCESS
  322. //
  323. // History: 06/03/97 t-geetat Created
  324. //
  325. //----------------------------------------------------------------------------
  326. DWORD ClosePerfMon()
  327. {
  328. g_dwNumOpens --;
  329. if ( NULL != g_hSharedFileMapping )
  330. {
  331. CloseHandle( g_hSharedFileMapping );
  332. }
  333. if ( NULL != g_hSemaphore )
  334. {
  335. CloseHandle(g_hSemaphore);
  336. }
  337. return ERROR_SUCCESS;
  338. }