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.

342 lines
12 KiB

  1. /*++
  2. Copyright (c) 2000-2000 Microsoft Corporation
  3. Module Name:
  4. Query.c
  5. Abstract:
  6. This module implements Query handling routines
  7. for the PGM Transport
  8. Author:
  9. Mohammad Shabbir Alam (MAlam) 3-30-2000
  10. Revision History:
  11. --*/
  12. #include "precomp.h"
  13. #ifdef FILE_LOGGING
  14. #include "query.tmh"
  15. #endif // FILE_LOGGING
  16. //******************* Pageable Routine Declarations ****************
  17. #ifdef ALLOC_PRAGMA
  18. // #pragma alloc_text(PAGE, PgmQueryInformation) Should not be pageable!
  19. #endif
  20. //******************* Pageable Routine Declarations ****************
  21. //----------------------------------------------------------------------------
  22. NTSTATUS
  23. QueryAddressCompletion(
  24. IN PDEVICE_OBJECT pDeviceContext,
  25. IN PIRP pIrp,
  26. IN PVOID Context
  27. )
  28. /*++
  29. Routine Description:
  30. This routine handles the completion event when the Query address
  31. Information completes.
  32. Arguments:
  33. IN pDeviceContext -- unused.
  34. IN pIrp -- Supplies Irp that the transport has finished processing.
  35. IN Context -- not used
  36. Return Value:
  37. NTSTATUS - Final status of the set event operation
  38. --*/
  39. {
  40. tTDI_QUERY_ADDRESS_INFO *pTdiQueryInfo;
  41. PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
  42. tCOMMON_SESSION_CONTEXT *pSession = pIrpSp->FileObject->FsContext;
  43. if ((NT_SUCCESS (pIrp->IoStatus.Status)) &&
  44. (pTdiQueryInfo = (tTDI_QUERY_ADDRESS_INFO *) MmGetSystemAddressForMdlSafe (pIrp->MdlAddress,
  45. HighPagePriority)))
  46. {
  47. if (PGM_VERIFY_HANDLE3 (pSession, PGM_VERIFY_SESSION_UNASSOCIATED,
  48. PGM_VERIFY_SESSION_SEND, PGM_VERIFY_SESSION_RECEIVE))
  49. {
  50. PgmTrace (LogAllFuncs, ("QueryAddressCompletion: " \
  51. "Tdi IpAddress=<%x>, Port=<%x>\n",
  52. ((PTDI_ADDRESS_IP) &pTdiQueryInfo->IpAddress.Address[0].Address)->in_addr,
  53. ((PTDI_ADDRESS_IP) &pTdiQueryInfo->IpAddress.Address[0].Address)->sin_port));
  54. //
  55. // Save the transport's address information in our own structure!
  56. //
  57. pSession->TdiIpAddress =((PTDI_ADDRESS_IP) &pTdiQueryInfo->IpAddress.Address[0].Address)->in_addr;
  58. pSession->TdiPort = ((PTDI_ADDRESS_IP) &pTdiQueryInfo->IpAddress.Address[0].Address)->sin_port;
  59. }
  60. else
  61. {
  62. PgmTrace (LogError, ("QueryAddressCompletion: ERROR -- " \
  63. "Invalid Session Context <%p>\n", pSession));
  64. }
  65. }
  66. else
  67. {
  68. PgmTrace (LogError, ("QueryAddressCompletion: ERROR -- " \
  69. "Transport returned <%x>, pTdiQueryInfo=<%p>\n", pIrp->IoStatus.Status, pTdiQueryInfo));
  70. }
  71. //
  72. // Must return a non-error status otherwise the IO system will not copy
  73. // back into the users buffer.
  74. //
  75. return (STATUS_SUCCESS);
  76. }
  77. //----------------------------------------------------------------------------
  78. NTSTATUS
  79. QueryProviderCompletion(
  80. IN PDEVICE_OBJECT pDeviceContext,
  81. IN PIRP pIrp,
  82. IN PVOID Context
  83. )
  84. /*++
  85. Routine Description:
  86. This routine handles the completion event when the Query Provider
  87. Information completes. This routine must decrement the MaxDgramSize
  88. and max send size by the respective NBT header sizes.
  89. Arguments:
  90. IN pDeviceContext -- unused.
  91. IN pIrp -- Supplies Irp that the transport has finished processing.
  92. IN Context -- not used
  93. Return Value:
  94. The final status from the operation (success or an exception).
  95. --*/
  96. {
  97. PTDI_PROVIDER_INFO pProvider;
  98. if ((NT_SUCCESS (pIrp->IoStatus.Status)) &&
  99. (pProvider = (PTDI_PROVIDER_INFO) MmGetSystemAddressForMdlSafe (pIrp->MdlAddress, HighPagePriority)))
  100. {
  101. //
  102. // Set the correct service flags to indicate what Pgm supports.
  103. //
  104. pProvider->ServiceFlags = TDI_SERVICE_MESSAGE_MODE |
  105. TDI_SERVICE_CONNECTION_MODE |
  106. TDI_SERVICE_ERROR_FREE_DELIVERY |
  107. TDI_SERVICE_MULTICAST_SUPPORTED |
  108. TDI_SERVICE_NO_ZERO_LENGTH |
  109. TDI_SERVICE_FORCE_ACCESS_CHECK |
  110. TDI_SERVICE_ROUTE_DIRECTED;
  111. /*
  112. ISSUE: Do we need: TDI_SERVICE_INTERNAL_BUFFERING ?
  113. TDI_SERVICE_FORCE_ACCESS_CHECK ?
  114. TDI_SERVICE_CONNECTIONLESS_MODE ?
  115. TDI_SERVICE_DELAYED_ACCEPTANCE ?
  116. TDI_SERVICE_BROADCAST_SUPPORTED ?
  117. */
  118. pProvider->MinimumLookaheadData = 1;
  119. //
  120. // The following data is for Streams
  121. //
  122. pProvider->MaxSendSize = SENDER_MAX_WINDOW_SIZE_PACKETS;
  123. if (pProvider->MaxDatagramSize > PGM_MAX_FEC_DATA_HEADER_LENGTH)
  124. {
  125. pProvider->MaxDatagramSize -= PGM_MAX_FEC_DATA_HEADER_LENGTH;
  126. }
  127. else
  128. {
  129. pProvider->MaxDatagramSize = 0;
  130. }
  131. PgmTrace (LogAllFuncs, ("QueryProviderCompletion: " \
  132. "SvcFlags=<%x> MaxSendSize=<%d>, MaxDgramSize=<%d>\n",
  133. pProvider->ServiceFlags, pProvider->MaxSendSize, pProvider->MaxDatagramSize));
  134. }
  135. else
  136. {
  137. PgmTrace (LogError, ("QueryProviderCompletion: ERROR -- " \
  138. "Transport returned <%x>, pProvider=<%p>\n", pIrp->IoStatus.Status, pProvider));
  139. }
  140. //
  141. // Must return a non-error status otherwise the IO system will not copy
  142. // back into the users buffer.
  143. //
  144. return (STATUS_SUCCESS);
  145. }
  146. //----------------------------------------------------------------------------
  147. NTSTATUS
  148. PgmQueryInformation(
  149. IN tPGM_DEVICE *pPgmDevice,
  150. IN PIRP pIrp,
  151. IN PIO_STACK_LOCATION pIrpSp
  152. )
  153. /*++
  154. Routine Description:
  155. This routine performs the TdiQueryInformation request for the transport
  156. provider.
  157. Arguments:
  158. IN pPgmDevice -- Pgm's Device object context
  159. IN pIrp -- Client's request Irp
  160. IN pIrpSp -- current request's stack pointer
  161. Return Value:
  162. NTSTATUS - Final status of the set event operation
  163. --*/
  164. {
  165. NTSTATUS status = STATUS_NOT_IMPLEMENTED;
  166. ULONG Size, BytesCopied = 0;
  167. PTDI_REQUEST_KERNEL_QUERY_INFORMATION Query;
  168. tTDI_QUERY_ADDRESS_INFO TdiQueryInfo;
  169. tADDRESS_CONTEXT *pAddress = pIrpSp->FileObject->FsContext;
  170. tCOMMON_SESSION_CONTEXT *pSession = pIrpSp->FileObject->FsContext;
  171. Query = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION) &pIrpSp->Parameters;
  172. switch (Query->QueryType)
  173. {
  174. case TDI_QUERY_PROVIDER_INFO:
  175. {
  176. PgmTrace (LogAllFuncs, ("PgmQueryInformation: " \
  177. "[TDI_QUERY_PROVIDER_INFO]:\n"));
  178. TdiBuildQueryInformation (pIrp,
  179. pPgmDevice->pControlDeviceObject,
  180. pPgmDevice->pControlFileObject,
  181. QueryProviderCompletion,
  182. NULL,
  183. TDI_QUERY_PROVIDER_INFO,
  184. pIrp->MdlAddress);
  185. status = IoCallDriver (pPgmDevice->pControlDeviceObject, pIrp);
  186. //
  187. // we must return the next drivers ret code back to the IO subsystem
  188. //
  189. status = STATUS_PENDING;
  190. break;
  191. }
  192. case TDI_QUERY_ADDRESS_INFO:
  193. {
  194. if (pIrp->MdlAddress)
  195. {
  196. if (PGM_VERIFY_HANDLE2 (pAddress, PGM_VERIFY_ADDRESS, PGM_VERIFY_ADDRESS_DOWN))
  197. {
  198. PgmZeroMemory (&TdiQueryInfo, sizeof (tTDI_QUERY_ADDRESS_INFO));
  199. TdiQueryInfo.ActivityCount = 1;
  200. TdiQueryInfo.IpAddress.TAAddressCount = 1;
  201. TdiQueryInfo.IpAddress.Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
  202. TdiQueryInfo.IpAddress.Address[0].AddressLength = sizeof(TDI_ADDRESS_IP);
  203. ((PTDI_ADDRESS_IP) &TdiQueryInfo.IpAddress.Address[0].Address)->in_addr =
  204. htonl (pAddress->ReceiverMCastAddr);
  205. ((PTDI_ADDRESS_IP) &TdiQueryInfo.IpAddress.Address[0].Address)->sin_port =
  206. htons (pAddress->ReceiverMCastPort);
  207. //
  208. // Due to the structure being Unaligned, we cannot reference the address
  209. // and port fields directly!
  210. //
  211. Size = offsetof (tTDI_QUERY_ADDRESS_INFO, IpAddress.Address[0].Address)
  212. + sizeof(TDI_ADDRESS_IP);
  213. status = TdiCopyBufferToMdl (&TdiQueryInfo, 0, Size, pIrp->MdlAddress, 0, &BytesCopied);
  214. pIrp->IoStatus.Information = BytesCopied;
  215. PgmTrace (LogAllFuncs, ("PgmQueryInformation: " \
  216. "[ADDRESS_INFO]: pAddress=<%p>, Copied=<%d/%d>\n", pAddress, BytesCopied, Size));
  217. break;
  218. }
  219. else if (PGM_VERIFY_HANDLE2 (pSession, PGM_VERIFY_SESSION_SEND, PGM_VERIFY_SESSION_RECEIVE))
  220. {
  221. if ((pAddress = pSession->pAssociatedAddress) &&
  222. (PGM_VERIFY_HANDLE (pAddress, PGM_VERIFY_ADDRESS)))
  223. {
  224. TdiBuildQueryInformation (pIrp,
  225. pAddress->pDeviceObject,
  226. pAddress->pFileObject,
  227. QueryAddressCompletion,
  228. NULL,
  229. TDI_QUERY_ADDRESS_INFO,
  230. pIrp->MdlAddress);
  231. PgmTrace (LogAllFuncs, ("PgmQueryInformation: " \
  232. "[ADDRESS_INFO]: pSession=<%p>, querying transport ...\n", pSession));
  233. status = IoCallDriver (pPgmDevice->pControlDeviceObject, pIrp);
  234. //
  235. // we must return the next drivers ret code back to the IO subsystem
  236. //
  237. status = STATUS_PENDING;
  238. }
  239. else
  240. {
  241. PgmTrace (LogError, ("PgmQueryInformation: ERROR -- " \
  242. "[ADDRESS_INFO]: pSession=<%p>, Invalid pAddress=<%p>\n", pSession, pAddress));
  243. status = STATUS_INVALID_HANDLE;
  244. }
  245. break;
  246. }
  247. else // neither an address nor a connect context!
  248. {
  249. PgmTrace (LogError, ("PgmQueryInformation: ERROR -- " \
  250. "[TDI_QUERY_ADDRESS_INFO]: Invalid Handle=<%p>\n", pIrpSp->FileObject->FsContext));
  251. status = STATUS_INVALID_HANDLE;
  252. }
  253. }
  254. else
  255. {
  256. PgmTrace (LogError, ("PgmQueryInformation: ERROR -- " \
  257. "[TDI_QUERY_ADDRESS_INFO]: No Mdl, pIrp=<%p>\n", pIrp));
  258. status = STATUS_UNSUCCESSFUL;
  259. }
  260. break;
  261. }
  262. default:
  263. {
  264. PgmTrace (LogError, ("PgmQueryInformation: ERROR -- " \
  265. "Query=<%d> not Implemented!\n", Query->QueryType));
  266. break;
  267. }
  268. }
  269. return (status);
  270. }
  271. //----------------------------------------------------------------------------