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.

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