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.

304 lines
8.5 KiB

  1. //////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2001 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // receive.cpp
  7. //
  8. // Abstract:
  9. // This module contains code which implements receive
  10. // commands from the dll
  11. //
  12. //////////////////////////////////////////////////////////
  13. #include "stdafx.h"
  14. ///////////////////////////////////////////////////////////////////////
  15. // Public functions
  16. ///////////////////////////////////////////////////////////////////////
  17. // --------------------------------------------------------------------
  18. //
  19. // Function: DoReceiveDatagram
  20. //
  21. // Arguments: TdiHandle -- handle of address object
  22. // pInTransportAddress -- TA for receiving on
  23. // pOutTransportAddress -- full TA data was received on
  24. // ppucBuffer -- buffer to stuff with received data
  25. //
  26. // Returns: length of data in buffer (0 if none or error)
  27. //
  28. // Descript: This function causes the driver to receive a datagram
  29. //
  30. //---------------------------------------------------------------------
  31. ULONG
  32. DoReceiveDatagram(ULONG ulTdiHandle,
  33. PTRANSPORT_ADDRESS pInTransportAddress,
  34. PTRANSPORT_ADDRESS pOutTransportAddress,
  35. PUCHAR *ppucBuffer)
  36. {
  37. PUCHAR pucBuffer = (PUCHAR)LocalAllocateMemory(ulMAX_BUFFER_LENGTH);
  38. if (!pucBuffer)
  39. {
  40. return 0;
  41. }
  42. SEND_BUFFER SendBuffer; // arguments for command
  43. //
  44. // set up arguments
  45. //
  46. SendBuffer.TdiHandle = ulTdiHandle;
  47. SendBuffer.COMMAND_ARGS.SendArgs.ulBufferLength = ulMAX_BUFFER_LENGTH;
  48. SendBuffer.COMMAND_ARGS.SendArgs.pucUserModeBuffer = pucBuffer;
  49. //
  50. // if passed in a transport address to receive on
  51. //
  52. if (pInTransportAddress)
  53. {
  54. memcpy(&SendBuffer.COMMAND_ARGS.SendArgs.TransAddr,
  55. pInTransportAddress,
  56. (FIELD_OFFSET(TRANSPORT_ADDRESS, Address)
  57. + FIELD_OFFSET(TA_ADDRESS, Address)
  58. + pInTransportAddress->Address[0].AddressLength));
  59. }
  60. //
  61. // else, set the number of addresses field to 0
  62. //
  63. else
  64. {
  65. SendBuffer.COMMAND_ARGS.SendArgs.TransAddr.TAAddressCount = 0;
  66. }
  67. //
  68. // call the driver
  69. //
  70. RECEIVE_BUFFER ReceiveBuffer; // return info from command
  71. NTSTATUS lStatus = TdiLibDeviceIO(ulRECEIVEDATAGRAM,
  72. &SendBuffer,
  73. &ReceiveBuffer);
  74. //
  75. // deal with results -- assume no packet received or error occurred
  76. //
  77. ULONG ulBufferLength = 0;
  78. *ppucBuffer = NULL;
  79. //
  80. // will return with success but ulBufferLength = 0 if there is no
  81. // packet available
  82. //
  83. if (lStatus == STATUS_SUCCESS)
  84. {
  85. ulBufferLength = ReceiveBuffer.RESULTS.RecvDgramRet.ulBufferLength;
  86. }
  87. if (ulBufferLength)
  88. {
  89. if (pOutTransportAddress)
  90. {
  91. memcpy(pOutTransportAddress,
  92. &ReceiveBuffer.RESULTS.RecvDgramRet.TransAddr,
  93. (FIELD_OFFSET(TRANSPORT_ADDRESS, Address)
  94. + FIELD_OFFSET(TA_ADDRESS, Address)
  95. + ReceiveBuffer.RESULTS.RecvDgramRet.TransAddr.TaAddress.AddressLength));
  96. }
  97. *ppucBuffer = pucBuffer;
  98. }
  99. else
  100. {
  101. LocalFreeMemory(pucBuffer);
  102. }
  103. return ulBufferLength;
  104. }
  105. // --------------------------------------------------------------------
  106. //
  107. // Function: DoReceive
  108. //
  109. // Arguments: TdiHandle -- handle of endpoint object
  110. // ppucBuffer -- buffer to stuff with received data
  111. //
  112. // Returns: length of data in buffer (0 if error)
  113. //
  114. // Descript: This function causes the driver to receive data sent
  115. // over a connection
  116. //
  117. //---------------------------------------------------------------------
  118. ULONG
  119. DoReceive(ULONG ulTdiHandle,
  120. PUCHAR *ppucBuffer)
  121. {
  122. PUCHAR pucBuffer = (PUCHAR)LocalAllocateMemory(ulMAX_BUFFER_LENGTH);
  123. if (!pucBuffer)
  124. {
  125. return 0;
  126. }
  127. SEND_BUFFER SendBuffer; // arguments for command
  128. //
  129. // set up arguments
  130. //
  131. SendBuffer.TdiHandle = ulTdiHandle;
  132. SendBuffer.COMMAND_ARGS.SendArgs.ulBufferLength = ulMAX_BUFFER_LENGTH;
  133. SendBuffer.COMMAND_ARGS.SendArgs.pucUserModeBuffer = pucBuffer;
  134. //
  135. // call the driver
  136. //
  137. RECEIVE_BUFFER ReceiveBuffer; // return info from command
  138. NTSTATUS lStatus = TdiLibDeviceIO(ulRECEIVE,
  139. &SendBuffer,
  140. &ReceiveBuffer);
  141. //
  142. // deal with results -- assume no data or error
  143. //
  144. *ppucBuffer = NULL;
  145. ULONG ulBufferLength = 0; // data length to return
  146. //
  147. // will return success with 0 bufferlength if no packet available
  148. //
  149. if (lStatus == STATUS_SUCCESS)
  150. {
  151. ulBufferLength = ReceiveBuffer.RESULTS.RecvDgramRet.ulBufferLength;
  152. }
  153. if (ulBufferLength)
  154. {
  155. *ppucBuffer = pucBuffer;
  156. }
  157. else
  158. {
  159. LocalFreeMemory(pucBuffer);
  160. }
  161. return ulBufferLength;
  162. }
  163. // ---------------------------------------
  164. //
  165. // Function: DoPostReceiveBuffer
  166. //
  167. // Arguments: TdiHandle -- handle for address object or endpoint
  168. // ulBufferLength -- length of buffer to post for receive
  169. //
  170. // Returns: status of command
  171. //
  172. // Descript: This function allocates a buffer, which it then passed to
  173. // the driver. The driver locks the buffer down, and posts it
  174. // for a receive or receivedatagram.
  175. //
  176. // ----------------------------------------
  177. VOID
  178. DoPostReceiveBuffer(ULONG ulTdiHandle,
  179. ULONG ulBufferLength)
  180. {
  181. NTSTATUS lStatus; // status of command
  182. RECEIVE_BUFFER ReceiveBuffer; // return info from command
  183. SEND_BUFFER SendBuffer; // arguments for command
  184. //
  185. // set up arguments
  186. //
  187. SendBuffer.TdiHandle = ulTdiHandle;
  188. SendBuffer.COMMAND_ARGS.SendArgs.ulBufferLength = ulBufferLength;
  189. PUCHAR pucBuffer = (PUCHAR)LocalAllocateMemory(ulBufferLength);
  190. if (pucBuffer)
  191. {
  192. SendBuffer.COMMAND_ARGS.SendArgs.pucUserModeBuffer = pucBuffer;
  193. //
  194. // call the driver
  195. //
  196. lStatus = TdiLibDeviceIO(ulPOSTRECEIVEBUFFER,
  197. &SendBuffer,
  198. &ReceiveBuffer);
  199. if (lStatus != STATUS_SUCCESS)
  200. {
  201. _tprintf(TEXT("DoPostReceiveBuffer: failure, status = %s\n"), TdiLibStatusMessage(lStatus));
  202. LocalFreeMemory(pucBuffer);
  203. }
  204. }
  205. else
  206. {
  207. _putts(TEXT("DoPostReceiveBuffer: failed to allocate buffer\n"));
  208. }
  209. }
  210. // ------------------------------------------
  211. //
  212. // Function: DoFetchReceiveBuffer
  213. //
  214. // Arguments: TdiHandle -- handle of address object or endpoint
  215. // pulBufferLength -- length of data returned
  216. // ppDataBuffer -- allocated buffer with data
  217. //
  218. // Returns: status of operation
  219. //
  220. // Descript: This function retrieves the oldest posted buffer. If no
  221. // data is available, it will cancel the appropriate irp
  222. // It then returns the data to the caller as appropriate
  223. //
  224. // -------------------------------------------
  225. ULONG
  226. DoFetchReceiveBuffer(ULONG ulTdiHandle,
  227. PUCHAR *ppDataBuffer)
  228. {
  229. NTSTATUS lStatus; // status of command
  230. RECEIVE_BUFFER ReceiveBuffer; // return info from command
  231. SEND_BUFFER SendBuffer; // arguments for command
  232. ULONG ulBufferLength = 0;
  233. //
  234. // set up arguments
  235. //
  236. SendBuffer.TdiHandle = ulTdiHandle;
  237. *ppDataBuffer = NULL;
  238. //
  239. // call the driver
  240. //
  241. lStatus = TdiLibDeviceIO(ulFETCHRECEIVEBUFFER,
  242. &SendBuffer,
  243. &ReceiveBuffer);
  244. if (lStatus == STATUS_SUCCESS)
  245. {
  246. PUCHAR pucTempBuffer = ReceiveBuffer.RESULTS.RecvDgramRet.pucUserModeBuffer;
  247. ulBufferLength = ReceiveBuffer.RESULTS.RecvDgramRet.ulBufferLength;
  248. if (ulBufferLength)
  249. {
  250. *ppDataBuffer = pucTempBuffer;
  251. }
  252. else if (pucTempBuffer)
  253. {
  254. LocalFreeMemory(pucTempBuffer);
  255. }
  256. }
  257. return ulBufferLength;
  258. }
  259. ////////////////////////////////////////////////////////////////////
  260. // end of file receive.cpp
  261. ////////////////////////////////////////////////////////////////////