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.

305 lines
9.9 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. perfrdr.c
  5. Abstract:
  6. This file implements a Performance Object that presents
  7. Redirector 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 <ntddnfs.h>
  19. #include <ntioapi.h>
  20. #include <windows.h>
  21. #include <assert.h>
  22. #include <srvfsctl.h>
  23. #include <winperf.h>
  24. #include <ntprfctr.h>
  25. #include <perfutil.h>
  26. #include "perfnet.h"
  27. #include "netsvcmc.h"
  28. #include "datardr.h"
  29. HANDLE hRdr = NULL;
  30. BOOL bRdrError = FALSE; // Log only one event per process
  31. DWORD APIENTRY
  32. OpenRedirObject (
  33. IN LPWSTR lpValueName
  34. )
  35. {
  36. UNICODE_STRING DeviceNameU;
  37. OBJECT_ATTRIBUTES ObjectAttributes;
  38. IO_STATUS_BLOCK IoStatusBlock;
  39. NTSTATUS status;
  40. HANDLE hLocalRdr = NULL;
  41. UNREFERENCED_PARAMETER (lpValueName);
  42. // open the handle to the server for data collection
  43. //
  44. // Now get access to the Redirector for its data
  45. //
  46. RtlInitUnicodeString(&DeviceNameU, DD_NFS_DEVICE_NAME_U);
  47. InitializeObjectAttributes(&ObjectAttributes,
  48. &DeviceNameU,
  49. OBJ_CASE_INSENSITIVE,
  50. NULL,
  51. NULL
  52. );
  53. status = NtCreateFile(&hLocalRdr,
  54. SYNCHRONIZE,
  55. &ObjectAttributes,
  56. &IoStatusBlock,
  57. NULL,
  58. FILE_ATTRIBUTE_NORMAL,
  59. FILE_SHARE_READ | FILE_SHARE_WRITE,
  60. FILE_OPEN_IF,
  61. FILE_SYNCHRONOUS_IO_NONALERT,
  62. NULL,
  63. 0
  64. );
  65. if (!NT_SUCCESS(status)) {
  66. if (!bRdrError) {
  67. ReportEvent (hEventLog,
  68. EVENTLOG_ERROR_TYPE,
  69. 0,
  70. PERFNET_UNABLE_OPEN_REDIR,
  71. NULL,
  72. 0,
  73. sizeof(DWORD),
  74. NULL,
  75. (LPVOID)&status);
  76. bRdrError = TRUE;
  77. }
  78. }
  79. else {
  80. if (InterlockedCompareExchangePointer(
  81. &hRdr,
  82. hLocalRdr,
  83. NULL) != NULL) {
  84. //
  85. // Replace only if the global handle is NULL
  86. //
  87. NtClose(hLocalRdr); // close duplicate handle
  88. }
  89. }
  90. return (DWORD)RtlNtStatusToDosError(status);
  91. }
  92. DWORD APIENTRY
  93. CollectRedirObjectData(
  94. IN OUT LPVOID *lppData,
  95. IN OUT LPDWORD lpcbTotalBytes,
  96. IN OUT LPDWORD lpNumObjectTypes
  97. )
  98. /*++
  99. Routine Description:
  100. This routine will return the data for the Physical Disk object
  101. Arguments:
  102. IN OUT LPVOID *lppData
  103. IN: pointer to the address of the buffer to receive the completed
  104. PerfDataBlock and subordinate structures. This routine will
  105. append its data to the buffer starting at the point referenced
  106. by *lppData.
  107. OUT: points to the first byte after the data structure added by this
  108. routine. This routine updated the value at lppdata after appending
  109. its data.
  110. IN OUT LPDWORD lpcbTotalBytes
  111. IN: the address of the DWORD that tells the size in bytes of the
  112. buffer referenced by the lppData argument
  113. OUT: the number of bytes added by this routine is writted to the
  114. DWORD pointed to by this argument
  115. IN OUT LPDWORD NumObjectTypes
  116. IN: the address of the DWORD to receive the number of objects added
  117. by this routine
  118. OUT: the number of objects added by this routine is writted to the
  119. DWORD pointed to by this argument
  120. Returns:
  121. 0 if successful, else Win 32 error code of failure
  122. --*/
  123. {
  124. DWORD TotalLen; // Length of the total return block
  125. NTSTATUS Status = ERROR_SUCCESS;
  126. IO_STATUS_BLOCK IoStatusBlock;
  127. RDR_DATA_DEFINITION *pRdrDataDefinition;
  128. RDR_COUNTER_DATA *pRCD;
  129. REDIR_STATISTICS RdrStatistics;
  130. if ( hRdr == NULL ) {
  131. // redir didn't get opened and it has already been logged
  132. *lpcbTotalBytes = (DWORD) 0;
  133. *lpNumObjectTypes = (DWORD) 0;
  134. return ERROR_SUCCESS;
  135. }
  136. //
  137. // Check for sufficient space for redirector data
  138. //
  139. TotalLen = sizeof(RDR_DATA_DEFINITION) +
  140. sizeof(RDR_COUNTER_DATA);
  141. if ( *lpcbTotalBytes < TotalLen ) {
  142. *lpcbTotalBytes = (DWORD) 0;
  143. *lpNumObjectTypes = (DWORD) 0;
  144. return ERROR_MORE_DATA;
  145. }
  146. //
  147. // Define objects data block
  148. //
  149. pRdrDataDefinition = (RDR_DATA_DEFINITION *) *lppData;
  150. memcpy (pRdrDataDefinition,
  151. &RdrDataDefinition,
  152. sizeof(RDR_DATA_DEFINITION));
  153. //
  154. // Format and collect redirector data
  155. //
  156. pRCD = (PRDR_COUNTER_DATA)&pRdrDataDefinition[1];
  157. // test for quadword alignment of the structure
  158. assert (((DWORD)(pRCD) & 0x00000007) == 0);
  159. pRCD->CounterBlock.ByteLength = QWORD_MULTIPLE(sizeof (RDR_COUNTER_DATA));
  160. Status = NtFsControlFile(hRdr,
  161. NULL,
  162. NULL,
  163. NULL,
  164. &IoStatusBlock,
  165. FSCTL_LMR_GET_STATISTICS,
  166. NULL,
  167. 0,
  168. &RdrStatistics,
  169. sizeof(RdrStatistics)
  170. );
  171. if (NT_SUCCESS(Status)) {
  172. // transfer Redir data
  173. pRCD->Bytes = RdrStatistics.BytesReceived.QuadPart +
  174. RdrStatistics.BytesTransmitted.QuadPart;
  175. pRCD->IoOperations = RdrStatistics.ReadOperations +
  176. RdrStatistics.WriteOperations;
  177. pRCD->Smbs = RdrStatistics.SmbsReceived.QuadPart +
  178. RdrStatistics.SmbsTransmitted.QuadPart;
  179. pRCD->BytesReceived = RdrStatistics.BytesReceived.QuadPart;
  180. pRCD->SmbsReceived = RdrStatistics.SmbsReceived.QuadPart;
  181. pRCD->PagingReadBytesRequested = RdrStatistics.PagingReadBytesRequested.QuadPart;
  182. pRCD->NonPagingReadBytesRequested = RdrStatistics.NonPagingReadBytesRequested.QuadPart;
  183. pRCD->CacheReadBytesRequested = RdrStatistics.CacheReadBytesRequested.QuadPart;
  184. pRCD->NetworkReadBytesRequested = RdrStatistics.NetworkReadBytesRequested.QuadPart;
  185. pRCD->BytesTransmitted = RdrStatistics.BytesTransmitted.QuadPart;
  186. pRCD->SmbsTransmitted = RdrStatistics.SmbsTransmitted.QuadPart;
  187. pRCD->PagingWriteBytesRequested = RdrStatistics.PagingWriteBytesRequested.QuadPart;
  188. pRCD->NonPagingWriteBytesRequested = RdrStatistics.NonPagingWriteBytesRequested.QuadPart;
  189. pRCD->CacheWriteBytesRequested = RdrStatistics.CacheWriteBytesRequested.QuadPart;
  190. pRCD->NetworkWriteBytesRequested = RdrStatistics.NetworkWriteBytesRequested.QuadPart;
  191. pRCD->ReadOperations = RdrStatistics.ReadOperations;
  192. pRCD->RandomReadOperations = RdrStatistics.RandomReadOperations;
  193. pRCD->ReadSmbs = RdrStatistics.ReadSmbs;
  194. pRCD->LargeReadSmbs = RdrStatistics.LargeReadSmbs;
  195. pRCD->SmallReadSmbs = RdrStatistics.SmallReadSmbs;
  196. pRCD->WriteOperations = RdrStatistics.WriteOperations;
  197. pRCD->RandomWriteOperations = RdrStatistics.RandomWriteOperations;
  198. pRCD->WriteSmbs = RdrStatistics.WriteSmbs;
  199. pRCD->LargeWriteSmbs = RdrStatistics.LargeWriteSmbs;
  200. pRCD->SmallWriteSmbs = RdrStatistics.SmallWriteSmbs;
  201. pRCD->RawReadsDenied = RdrStatistics.RawReadsDenied;
  202. pRCD->RawWritesDenied = RdrStatistics.RawWritesDenied;
  203. pRCD->NetworkErrors = RdrStatistics.NetworkErrors;
  204. pRCD->Sessions = RdrStatistics.Sessions;
  205. pRCD->Reconnects = RdrStatistics.Reconnects;
  206. pRCD->CoreConnects = RdrStatistics.CoreConnects;
  207. pRCD->Lanman20Connects = RdrStatistics.Lanman20Connects;
  208. pRCD->Lanman21Connects = RdrStatistics.Lanman21Connects;
  209. pRCD->LanmanNtConnects = RdrStatistics.LanmanNtConnects;
  210. pRCD->ServerDisconnects = RdrStatistics.ServerDisconnects;
  211. pRCD->HungSessions = RdrStatistics.HungSessions;
  212. pRCD->CurrentCommands = RdrStatistics.CurrentCommands;
  213. } else {
  214. //
  215. // Failure to access Redirector: clear counters to 0
  216. //
  217. if (!bRdrError) {
  218. ReportEvent (hEventLog,
  219. EVENTLOG_ERROR_TYPE,
  220. 0,
  221. PERFNET_UNABLE_READ_REDIR,
  222. NULL,
  223. 0,
  224. sizeof(DWORD),
  225. NULL,
  226. (LPVOID)&Status);
  227. bRdrError = TRUE;
  228. }
  229. memset(pRCD, 0, sizeof(RDR_COUNTER_DATA));
  230. pRCD->CounterBlock.ByteLength = QWORD_MULTIPLE(sizeof (RDR_COUNTER_DATA));
  231. }
  232. *lpcbTotalBytes = pRdrDataDefinition->RdrObjectType.TotalByteLength
  233. = (DWORD) QWORD_MULTIPLE((LPBYTE) &pRCD[1] - (LPBYTE) pRdrDataDefinition);
  234. * lppData = (LPVOID) (((LPBYTE) pRdrDataDefinition) + *lpcbTotalBytes);
  235. *lpNumObjectTypes = 1;
  236. return ERROR_SUCCESS;
  237. }
  238. DWORD APIENTRY
  239. CloseRedirObject ()
  240. {
  241. HANDLE hLocalRdr = hRdr;
  242. if (hLocalRdr != NULL) {
  243. if (InterlockedCompareExchangePointer(
  244. &hRdr,
  245. NULL,
  246. hLocalRdr) == hLocalRdr) {
  247. NtClose(hLocalRdr);
  248. }
  249. }
  250. return ERROR_SUCCESS;
  251. }