Leaked source code of windows server 2003
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.

299 lines
9.2 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. perfbrws.c
  5. Abstract:
  6. This file implements a Performance Object that presents
  7. Browser Performance object data
  8. Created:
  9. Bob Watson 22-Oct-1996
  10. Revision History
  11. --*/
  12. //
  13. // Include Files
  14. //
  15. #include <nt.h>
  16. #include <ntrtl.h>
  17. #include <nturtl.h>
  18. #include <windows.h>
  19. #include <assert.h>
  20. #include <winperf.h>
  21. #include <lmcons.h>
  22. #include <lmerr.h>
  23. #include <lmapibuf.h>
  24. #include <lmwksta.h>
  25. #include <lmbrowsr.h>
  26. #include <ntprfctr.h>
  27. #include <perfutil.h>
  28. #include "perfnet.h"
  29. #include "netsvcmc.h"
  30. #include "databrws.h"
  31. // BrowserStatFunction is used for collecting Browser Statistic Data
  32. typedef NET_API_STATUS (*PBROWSERQUERYSTATISTIC) (
  33. IN LPTSTR servername OPTIONAL,
  34. OUT LPBROWSER_STATISTICS *statistics
  35. );
  36. PBROWSERQUERYSTATISTIC BrowserStatFunction = NULL;
  37. HANDLE dllHandle = NULL;
  38. BOOL bInitBrwsOk = FALSE;
  39. DWORD APIENTRY
  40. OpenBrowserObject (
  41. IN LPWSTR lpValueName
  42. )
  43. /*++
  44. GetBrowserStatistic - Get the I_BrowserQueryStatistics entry point
  45. --*/
  46. {
  47. UINT dwOldMode;
  48. LONG status = ERROR_SUCCESS;
  49. HANDLE hDll = dllHandle;
  50. UNREFERENCED_PARAMETER (lpValueName);
  51. bInitBrwsOk = TRUE;
  52. if (hDll != NULL) { // Open already called once
  53. return status;
  54. }
  55. dwOldMode = SetErrorMode( SEM_FAILCRITICALERRORS );
  56. //
  57. // Dynamically link to netapi32.dll. If it's not there just return.
  58. //
  59. hDll = LoadLibraryW((LPCWSTR)L"NetApi32.Dll") ;
  60. if ( !hDll || hDll == INVALID_HANDLE_VALUE ) {
  61. status = GetLastError();
  62. ReportEvent (hEventLog,
  63. EVENTLOG_ERROR_TYPE,
  64. 0,
  65. PERFNET_UNABLE_OPEN_NETAPI32_DLL,
  66. NULL,
  67. 0,
  68. sizeof(DWORD),
  69. NULL,
  70. (LPVOID)&status);
  71. BrowserStatFunction = NULL;
  72. bInitBrwsOk = FALSE;
  73. } else {
  74. //
  75. // Replace the global handle atomically
  76. //
  77. if (InterlockedCompareExchangePointer(
  78. &dllHandle,
  79. hDll,
  80. NULL) != NULL) {
  81. FreeLibrary(hDll); // close the duplicate handle
  82. }
  83. //
  84. // Get the address of the service's main entry point. This
  85. // entry point has a well-known name.
  86. //
  87. BrowserStatFunction = (PBROWSERQUERYSTATISTIC)GetProcAddress (
  88. dllHandle, "I_BrowserQueryStatistics") ;
  89. if (BrowserStatFunction == NULL) {
  90. status = GetLastError();
  91. ReportEvent (hEventLog,
  92. EVENTLOG_ERROR_TYPE,
  93. 0,
  94. PERFNET_UNABLE_LOCATE_BROWSER_PERF_FN,
  95. NULL,
  96. 0,
  97. sizeof(DWORD),
  98. NULL,
  99. (LPVOID)&status);
  100. bInitBrwsOk = FALSE;
  101. }
  102. }
  103. SetErrorMode( dwOldMode );
  104. return status;
  105. }
  106. DWORD APIENTRY
  107. CollectBrowserObjectData(
  108. IN OUT LPVOID *lppData,
  109. IN OUT LPDWORD lpcbTotalBytes,
  110. IN OUT LPDWORD lpNumObjectTypes
  111. )
  112. /*++
  113. Routine Description:
  114. This routine will return the data for the Physical Disk object
  115. Arguments:
  116. IN OUT LPVOID *lppData
  117. IN: pointer to the address of the buffer to receive the completed
  118. PerfDataBlock and subordinate structures. This routine will
  119. append its data to the buffer starting at the point referenced
  120. by *lppData.
  121. OUT: points to the first byte after the data structure added by this
  122. routine. This routine updated the value at lppdata after appending
  123. its data.
  124. IN OUT LPDWORD lpcbTotalBytes
  125. IN: the address of the DWORD that tells the size in bytes of the
  126. buffer referenced by the lppData argument
  127. OUT: the number of bytes added by this routine is writted to the
  128. DWORD pointed to by this argument
  129. IN OUT LPDWORD NumObjectTypes
  130. IN: the address of the DWORD to receive the number of objects added
  131. by this routine
  132. OUT: the number of objects added by this routine is writted to the
  133. DWORD pointed to by this argument
  134. Returns:
  135. 0 if successful, else Win 32 error code of failure
  136. --*/
  137. {
  138. DWORD TotalLen; // Length of the total return block
  139. NTSTATUS Status = ERROR_SUCCESS;
  140. BROWSER_DATA_DEFINITION *pBrowserDataDefinition;
  141. BROWSER_COUNTER_DATA *pBCD;
  142. BROWSER_STATISTICS BrowserStatistics;
  143. LPBROWSER_STATISTICS pBrowserStatistics = &BrowserStatistics;
  144. //
  145. // Check for sufficient space for browser data
  146. //
  147. if (!bInitBrwsOk) {
  148. // function didn't initialize so bail out here
  149. *lpcbTotalBytes = (DWORD) 0;
  150. *lpNumObjectTypes = (DWORD) 0;
  151. return ERROR_SUCCESS;
  152. }
  153. TotalLen = sizeof(BROWSER_DATA_DEFINITION) +
  154. sizeof(BROWSER_COUNTER_DATA);
  155. if ( *lpcbTotalBytes < TotalLen ) {
  156. // not enough room in the buffer for 1 instance
  157. // so bail
  158. *lpcbTotalBytes = (DWORD) 0;
  159. *lpNumObjectTypes = (DWORD) 0;
  160. return ERROR_MORE_DATA;
  161. }
  162. //
  163. // Define objects data block
  164. //
  165. pBrowserDataDefinition = (BROWSER_DATA_DEFINITION *) *lppData;
  166. memcpy (pBrowserDataDefinition,
  167. &BrowserDataDefinition,
  168. sizeof(BROWSER_DATA_DEFINITION));
  169. //
  170. // Format and collect browser data
  171. //
  172. pBCD = (PBROWSER_COUNTER_DATA)&pBrowserDataDefinition[1];
  173. // test for quadword alignment of the structure
  174. assert (((DWORD)(pBCD) & 0x00000007) == 0);
  175. memset (pBrowserStatistics, 0, sizeof (BrowserStatistics));
  176. if ( BrowserStatFunction != NULL ) {
  177. Status = (*BrowserStatFunction) (NULL,
  178. &pBrowserStatistics
  179. );
  180. } else {
  181. Status = STATUS_INVALID_ADDRESS;
  182. }
  183. if (NT_SUCCESS(Status)) {
  184. pBCD->CounterBlock.ByteLength = QWORD_MULTIPLE(sizeof(BROWSER_COUNTER_DATA));
  185. pBCD->TotalAnnounce =
  186. pBCD->ServerAnnounce = BrowserStatistics.NumberOfServerAnnouncements.QuadPart;
  187. pBCD->TotalAnnounce +=
  188. pBCD->DomainAnnounce = BrowserStatistics.NumberOfDomainAnnouncements.QuadPart;
  189. pBCD->ElectionPacket = BrowserStatistics.NumberOfElectionPackets;
  190. pBCD->MailslotWrite = BrowserStatistics.NumberOfMailslotWrites;
  191. pBCD->ServerList = BrowserStatistics.NumberOfGetBrowserServerListRequests;
  192. pBCD->ServerEnum = BrowserStatistics.NumberOfServerEnumerations;
  193. pBCD->DomainEnum = BrowserStatistics.NumberOfDomainEnumerations;
  194. pBCD->OtherEnum = BrowserStatistics.NumberOfOtherEnumerations;
  195. pBCD->TotalEnum = BrowserStatistics.NumberOfServerEnumerations
  196. + BrowserStatistics.NumberOfDomainEnumerations
  197. + BrowserStatistics.NumberOfOtherEnumerations;
  198. pBCD->ServerAnnounceMiss = BrowserStatistics.NumberOfMissedServerAnnouncements;
  199. pBCD->MailslotDatagramMiss = BrowserStatistics.NumberOfMissedMailslotDatagrams;
  200. pBCD->ServerListMiss = BrowserStatistics.NumberOfMissedGetBrowserServerListRequests;
  201. pBCD->ServerAnnounceAllocMiss = BrowserStatistics.NumberOfFailedServerAnnounceAllocations;
  202. pBCD->MailslotAllocFail = BrowserStatistics.NumberOfFailedMailslotAllocations;
  203. pBCD->MailslotReceiveFail = BrowserStatistics.NumberOfFailedMailslotReceives;
  204. pBCD->MailslotWriteFail = BrowserStatistics.NumberOfFailedMailslotWrites;
  205. pBCD->MailslotOpenFail = BrowserStatistics.NumberOfFailedMailslotOpens;
  206. pBCD->MasterAnnounceDup = BrowserStatistics.NumberOfDuplicateMasterAnnouncements;
  207. pBCD->DatagramIllegal = BrowserStatistics.NumberOfIllegalDatagrams.QuadPart;
  208. } else {
  209. if (BrowserStatFunction != NULL) {
  210. ReportEvent (hEventLog,
  211. EVENTLOG_ERROR_TYPE,
  212. 0,
  213. PERFNET_UNABLE_LOCATE_BROWSER_PERF_FN,
  214. NULL,
  215. 0,
  216. sizeof(DWORD),
  217. NULL,
  218. (LPVOID)&Status);
  219. }
  220. //
  221. // Failure to access Browser: clear counters to 0
  222. //
  223. memset(pBCD, 0, sizeof(BROWSER_COUNTER_DATA));
  224. pBCD->CounterBlock.ByteLength = QWORD_MULTIPLE(sizeof(BROWSER_COUNTER_DATA));
  225. }
  226. *lpcbTotalBytes = pBrowserDataDefinition->BrowserObjectType.TotalByteLength
  227. = (DWORD) QWORD_MULTIPLE((LPBYTE) &pBCD[1] - (LPBYTE) pBrowserDataDefinition);
  228. *lppData = (LPVOID) (((LPBYTE) pBrowserDataDefinition) + *lpcbTotalBytes);
  229. *lpNumObjectTypes = 1;
  230. return ERROR_SUCCESS;
  231. }
  232. DWORD APIENTRY
  233. CloseBrowserObject ()
  234. {
  235. HANDLE hDll = dllHandle;
  236. bInitBrwsOk = FALSE;
  237. if (hDll != NULL) {
  238. if (InterlockedCompareExchangePointer(
  239. &dllHandle,
  240. NULL,
  241. hDll) == hDll) {
  242. FreeLibrary (hDll);
  243. }
  244. BrowserStatFunction = NULL;
  245. }
  246. return ERROR_SUCCESS;
  247. }