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.

913 lines
28 KiB

  1. /////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2001 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // receive
  7. //
  8. // Abstract:
  9. // This module contains code which deals with receiving data
  10. //
  11. //////////////////////////////////////////////////////////
  12. #include "sysvars.h"
  13. //////////////////////////////////////////////////////////////
  14. // private constants, types, and prototypes
  15. //////////////////////////////////////////////////////////////
  16. const PCHAR strFunc1 = "TSReceive";
  17. const PCHAR strFunc2 = "TSReceiveHandler";
  18. const PCHAR strFunc3 = "TSRcvExpeditedHandler";
  19. const PCHAR strFunc4 = "TSChainedReceiveHandler";
  20. const PCHAR strFunc5 = "TSChainedRcvExpeditedHandler";
  21. const PCHAR strFuncP1 = "TSReceiveComplete";
  22. const PCHAR strFuncP2 = "TSShowReceiveInfo";
  23. const PCHAR strFuncP3 = "TSGetRestOfData";
  24. const PCHAR strFuncP4 = "TSCommonReceive";
  25. const PCHAR strFuncP5 = "TSCommonChainedReceive";
  26. //
  27. // completion context
  28. //
  29. struct RECEIVE_CONTEXT
  30. {
  31. PMDL pLowerMdl; // mdl from lower irp
  32. PRECEIVE_DATA pReceiveData; // above structure
  33. PADDRESS_OBJECT pAddressObject;
  34. BOOLEAN fIsExpedited;
  35. };
  36. typedef RECEIVE_CONTEXT *PRECEIVE_CONTEXT;
  37. //
  38. // completion function
  39. //
  40. TDI_STATUS
  41. TSReceiveComplete(
  42. PDEVICE_OBJECT DeviceObject,
  43. PIRP Irp,
  44. PVOID Context
  45. );
  46. PIRP
  47. TSGetRestOfData(
  48. PADDRESS_OBJECT pAddressObject,
  49. PRECEIVE_DATA pReceiveData,
  50. BOOLEAN fIsExpedited
  51. );
  52. VOID
  53. TSShowReceiveInfo(
  54. PADDRESS_OBJECT pAddressObject,
  55. CONNECTION_CONTEXT ConnectionContext,
  56. ULONG ulReceiveFlags,
  57. ULONG ulBytesIndicated,
  58. ULONG ulBytesAvailable,
  59. PVOID pvTsdu,
  60. BOOLEAN fIsChained
  61. );
  62. TDI_STATUS
  63. TSCommonReceive(
  64. PADDRESS_OBJECT pAddressObject,
  65. ULONG ulBytesTotal,
  66. ULONG ulBytesIndicated,
  67. ULONG ulReceiveFlags,
  68. PVOID pvTsdu,
  69. BOOLEAN fIsExpedited,
  70. PULONG pulBytesTaken,
  71. PIRP *pIoRequestPacket
  72. );
  73. TDI_STATUS
  74. TSCommonChainedReceive(
  75. PADDRESS_OBJECT pAddressObject,
  76. ULONG ulReceiveLength,
  77. ULONG ulStartingOffset,
  78. PMDL pReceiveMdl,
  79. BOOLEAN fIsExpedited,
  80. PVOID pvTsduDescriptor
  81. );
  82. //////////////////////////////////////////////////////////////
  83. // public functions
  84. //////////////////////////////////////////////////////////////
  85. // -----------------------------------------------------------------
  86. //
  87. // Function: TSReceive
  88. //
  89. // Arguments: pEndpointObject -- current endpoint
  90. // pIrp -- completion information
  91. //
  92. // Returns: NTSTATUS (normally pending)
  93. //
  94. // Descript: This function receives data over a connection
  95. //
  96. // ----------------------------------------------------------------------------
  97. NTSTATUS
  98. TSReceive(PENDPOINT_OBJECT pEndpoint,
  99. PSEND_BUFFER pSendBuffer,
  100. PRECEIVE_BUFFER pReceiveBuffer)
  101. {
  102. PADDRESS_OBJECT pAddressObject = pEndpoint->pAddressObject;
  103. //
  104. // assume no packet
  105. //
  106. pReceiveBuffer->RESULTS.RecvDgramRet.ulBufferLength = 0;
  107. if (pAddressObject)
  108. {
  109. PRECEIVE_DATA pReceiveData;
  110. //
  111. // just get the first packet from the queue
  112. // check expedited list First
  113. //
  114. TSAcquireSpinLock(&pAddressObject->TdiSpinLock);
  115. pReceiveData = pAddressObject->pHeadRcvExpData;
  116. if (pReceiveData)
  117. {
  118. //
  119. // fix up the lists as necessary
  120. //
  121. if (pReceiveData->pNextReceiveData)
  122. {
  123. pReceiveData->pNextReceiveData->pPrevReceiveData = NULL;
  124. }
  125. else
  126. {
  127. pAddressObject->pTailRcvExpData = NULL;
  128. }
  129. pAddressObject->pHeadRcvExpData = pReceiveData->pNextReceiveData;
  130. }
  131. //
  132. // if no expedited receives, check normal list
  133. //
  134. else
  135. {
  136. pReceiveData = pAddressObject->pHeadReceiveData;
  137. if (pReceiveData)
  138. {
  139. //
  140. // fix up the lists as necessary
  141. //
  142. if (pReceiveData->pNextReceiveData)
  143. {
  144. pReceiveData->pNextReceiveData->pPrevReceiveData = NULL;
  145. }
  146. else
  147. {
  148. pAddressObject->pTailReceiveData = NULL;
  149. }
  150. pAddressObject->pHeadReceiveData = pReceiveData->pNextReceiveData;
  151. }
  152. }
  153. TSReleaseSpinLock(&pAddressObject->TdiSpinLock);
  154. //
  155. // if we got a packet to return, then lets return it..
  156. // and release its memory
  157. //
  158. if (pReceiveData)
  159. {
  160. //
  161. // show debug, if it is turned on, and only if we actually
  162. // are returning a packet
  163. //
  164. if (ulDebugLevel & ulDebugShowCommand)
  165. {
  166. DebugPrint1("\nCommand = ulRECEIVE\n"
  167. "FileObject = %p\n",
  168. pEndpoint);
  169. }
  170. if (pReceiveData->ulBufferLength > pSendBuffer->COMMAND_ARGS.SendArgs.ulBufferLength)
  171. {
  172. pReceiveData->ulBufferLength = pSendBuffer->COMMAND_ARGS.SendArgs.ulBufferLength;
  173. }
  174. //
  175. // attempt to lock down the memory
  176. //
  177. PMDL pMdl = TSMakeMdlForUserBuffer(pSendBuffer->COMMAND_ARGS.SendArgs.pucUserModeBuffer,
  178. pReceiveData->ulBufferLength,
  179. IoModifyAccess);
  180. if (pMdl)
  181. {
  182. RtlCopyMemory(MmGetSystemAddressForMdl(pMdl),
  183. pReceiveData->pucDataBuffer,
  184. pReceiveData->ulBufferLength);
  185. TSFreeUserBuffer(pMdl);
  186. }
  187. else
  188. {
  189. pReceiveData->ulBufferLength = 0;
  190. }
  191. pReceiveBuffer->RESULTS.RecvDgramRet.ulBufferLength = pReceiveData->ulBufferLength;
  192. TSFreeMemory(pReceiveData->pucDataBuffer);
  193. TSFreeMemory(pReceiveData);
  194. }
  195. }
  196. return STATUS_SUCCESS;
  197. }
  198. // -----------------------------------------------
  199. //
  200. // Function: TSReceiveHandler
  201. //
  202. // Arguments: pvTdiEventContext -- really pointer to our AddressObject
  203. // Connection_Context -- really pointer to our Endpoint
  204. // ReceiveFlags -- nature of received data
  205. // ulBytesIndicated --- length of data in buffer
  206. // ulBytesTotal -- total length of datagram
  207. // pulBytesTaken -- stuff with bytes used by this driver
  208. // pvTsdu -- data buffer
  209. // pIoRequestPacket -- pIrp in case not all data received
  210. //
  211. // Returns: STATUS_DATA_NOT_ACCEPTED (we didn't want data)
  212. // STATUS_SUCCESS (we used all data & are done with it)
  213. // STATUS_MORE_PROCESSING_REQUIRED -- we supplied an IRP for rest
  214. //
  215. // Descript: Event handler for incoming receives on connection
  216. //
  217. // -----------------------------------------------
  218. TDI_STATUS
  219. TSReceiveHandler(PVOID pvTdiEventContext,
  220. CONNECTION_CONTEXT ConnectionContext,
  221. ULONG ulReceiveFlags,
  222. ULONG ulBytesIndicated,
  223. ULONG ulBytesTotal,
  224. PULONG pulBytesTaken,
  225. PVOID pvTsdu,
  226. PIRP *ppIoRequestPacket)
  227. {
  228. PADDRESS_OBJECT pAddressObject = (PADDRESS_OBJECT)pvTdiEventContext;
  229. if (ulDebugLevel & ulDebugShowHandlers)
  230. {
  231. DebugPrint1("\n >>>> %s\n", strFunc2);
  232. TSShowReceiveInfo(pAddressObject,
  233. ConnectionContext,
  234. ulReceiveFlags,
  235. ulBytesIndicated,
  236. ulBytesTotal,
  237. pvTsdu,
  238. FALSE);
  239. }
  240. return TSCommonReceive(pAddressObject,
  241. ulBytesTotal,
  242. ulBytesIndicated,
  243. ulReceiveFlags,
  244. pvTsdu,
  245. ((ulReceiveFlags & TDI_RECEIVE_EXPEDITED) != 0),
  246. pulBytesTaken,
  247. ppIoRequestPacket);
  248. }
  249. // -----------------------------------------------
  250. //
  251. // Function: TSRcvExpeditedHandler
  252. //
  253. // Arguments: pvTdiEventContext -- really pointer to our AddressObject
  254. // Connection_Context -- really pointer to our Endpoint
  255. // ReceiveFlags -- nature of received data
  256. // ulBytesIndicated --- length of data in buffer
  257. // ulBytesTotal -- total length of datagram
  258. // pulBytesTaken -- stuff with bytes used by this driver
  259. // pvTsdu -- data buffer
  260. // pIoRequestPacket -- pIrp in case not all data received
  261. //
  262. // Returns: STATUS_DATA_NOT_ACCEPTED (we didn't want data)
  263. // STATUS_SUCCESS (we used all data & are done with it)
  264. // STATUS_MORE_PROCESSING_REQUIRED -- we supplied an IRP for rest
  265. //
  266. // Descript: Event handler for incoming expedited receives on connection
  267. //
  268. // -----------------------------------------------
  269. TDI_STATUS
  270. TSRcvExpeditedHandler(PVOID pvTdiEventContext,
  271. CONNECTION_CONTEXT ConnectionContext,
  272. ULONG ulReceiveFlags,
  273. ULONG ulBytesIndicated,
  274. ULONG ulBytesTotal,
  275. PULONG pulBytesTaken,
  276. PVOID pvTsdu,
  277. PIRP *ppIoRequestPacket)
  278. {
  279. PADDRESS_OBJECT pAddressObject = (PADDRESS_OBJECT)pvTdiEventContext;
  280. if (ulDebugLevel & ulDebugShowHandlers)
  281. {
  282. DebugPrint1("\n >>>> %s\n", strFunc3);
  283. TSShowReceiveInfo(pAddressObject,
  284. ConnectionContext,
  285. ulReceiveFlags,
  286. ulBytesIndicated,
  287. ulBytesTotal,
  288. pvTsdu,
  289. FALSE);
  290. }
  291. return TSCommonReceive(pAddressObject,
  292. ulBytesTotal,
  293. ulBytesIndicated,
  294. ulReceiveFlags,
  295. pvTsdu,
  296. TRUE,
  297. pulBytesTaken,
  298. ppIoRequestPacket);
  299. }
  300. // -----------------------------------------------
  301. //
  302. // Function: TSChainedReceiveHandler
  303. //
  304. // Arguments: pvTdiEventContext -- really pointer to our AddressObject
  305. // Connection_Context -- really pointer to our Endpoint
  306. // ReceiveFlags -- nature of received data
  307. // ulReceiveLength --- length of data in buffer
  308. // ulStartingOffset -- total length of datagram
  309. // pReceiveMdl -- data buffer
  310. // pTsduDescriptor -- returns value for TdiReturnChainedReceives
  311. //
  312. // Returns: STATUS_DATA_NOT_ACCEPTED (we didn't want data)
  313. // STATUS_SUCCESS (we used all data & are done with it)
  314. // STATUS_MORE_PROCESSING_REQUIRED -- we supplied an IRP for rest
  315. //
  316. // Descript: Event handler for incoming receives on connection
  317. //
  318. // -----------------------------------------------
  319. TDI_STATUS
  320. TSChainedReceiveHandler(PVOID pvTdiEventContext,
  321. CONNECTION_CONTEXT ConnectionContext,
  322. ULONG ulReceiveFlags,
  323. ULONG ulReceiveLength,
  324. ULONG ulStartingOffset,
  325. PMDL pReceiveMdl,
  326. PVOID pvTsduDescriptor)
  327. {
  328. PADDRESS_OBJECT pAddressObject = (PADDRESS_OBJECT)pvTdiEventContext;
  329. if (ulDebugLevel & ulDebugShowHandlers)
  330. {
  331. DebugPrint1("\n >>>> %s\n", strFunc4);
  332. TSShowReceiveInfo(pAddressObject,
  333. ConnectionContext,
  334. ulReceiveFlags,
  335. ulReceiveLength,
  336. ulStartingOffset,
  337. pReceiveMdl,
  338. TRUE);
  339. }
  340. return TSCommonChainedReceive(pAddressObject,
  341. ulReceiveLength,
  342. ulStartingOffset,
  343. pReceiveMdl,
  344. ((ulReceiveFlags & TDI_RECEIVE_EXPEDITED) != 0),
  345. pvTsduDescriptor);
  346. }
  347. // -----------------------------------------------
  348. //
  349. // Function: TSChainedRcvExpeditedHandler
  350. //
  351. // Arguments: pvTdiEventContext -- really pointer to our AddressObject
  352. // Connection_Context -- really pointer to our Endpoint
  353. // ReceiveFlags -- nature of received data
  354. // ulReceiveLength --- length of data in buffer
  355. // ulStartingOffset -- total length of datagram
  356. // pReceiveMdl -- data buffer
  357. // pTsduDescriptor -- returns value for TdiReturnChainedReceives
  358. //
  359. // Returns: STATUS_DATA_NOT_ACCEPTED (we didn't want data)
  360. // STATUS_SUCCESS (we used all data & are done with it)
  361. // STATUS_MORE_PROCESSING_REQUIRED -- we supplied an IRP for rest
  362. //
  363. // Descript: Event handler for incoming receives on connection
  364. //
  365. // -----------------------------------------------
  366. TDI_STATUS
  367. TSChainedRcvExpeditedHandler(PVOID pvTdiEventContext,
  368. CONNECTION_CONTEXT ConnectionContext,
  369. ULONG ulReceiveFlags,
  370. ULONG ulReceiveLength,
  371. ULONG ulStartingOffset,
  372. PMDL pReceiveMdl,
  373. PVOID pvTsduDescriptor)
  374. {
  375. PADDRESS_OBJECT pAddressObject = (PADDRESS_OBJECT)pvTdiEventContext;
  376. if (ulDebugLevel & ulDebugShowHandlers)
  377. {
  378. DebugPrint1("\n >>>> %s\n", strFunc5);
  379. TSShowReceiveInfo(pAddressObject,
  380. ConnectionContext,
  381. ulReceiveFlags,
  382. ulReceiveLength,
  383. ulStartingOffset,
  384. pReceiveMdl,
  385. TRUE);
  386. }
  387. return TSCommonChainedReceive(pAddressObject,
  388. ulReceiveLength,
  389. ulStartingOffset,
  390. pReceiveMdl,
  391. TRUE,
  392. pvTsduDescriptor);
  393. }
  394. /////////////////////////////////////////////////////////////
  395. // private functions
  396. /////////////////////////////////////////////////////////////
  397. // ---------------------------------------------------------
  398. //
  399. // Function: TSReceiveComplete
  400. //
  401. // Arguments: pDeviceObject -- device object that called Receive/Datagram
  402. // pIrp -- IRP used in the call
  403. // pContext -- context used for the call
  404. //
  405. // Returns: status of operation (STATUS_MORE_PROCESSING_REQUIRED)
  406. //
  407. // Descript: Gets the result of the receive, stuffs result into
  408. // receive buffer, completes the IRP from the dll, and
  409. // cleans up the Irp and associated data from the receive
  410. //
  411. // ---------------------------------------------------------
  412. #pragma warning(disable: UNREFERENCED_PARAM)
  413. TDI_STATUS
  414. TSReceiveComplete(PDEVICE_OBJECT pDeviceObject,
  415. PIRP pLowerIrp,
  416. PVOID pvContext)
  417. {
  418. PRECEIVE_CONTEXT pReceiveContext = (PRECEIVE_CONTEXT)pvContext;
  419. NTSTATUS lStatus = pLowerIrp->IoStatus.Status;
  420. ULONG ulBytesCopied = (ULONG)pLowerIrp->IoStatus.Information;
  421. PADDRESS_OBJECT pAddressObject = pReceiveContext->pAddressObject;
  422. PRECEIVE_DATA pReceiveData = pReceiveContext->pReceiveData;
  423. if (NT_SUCCESS(lStatus))
  424. {
  425. if (ulDebugLevel & ulDebugShowCommand)
  426. {
  427. DebugPrint2("%s: %u BytesCopied\n",
  428. strFuncP1,
  429. ulBytesCopied);
  430. }
  431. pReceiveData->ulBufferUsed += ulBytesCopied;
  432. if (pReceiveData->ulBufferUsed >= pReceiveData->ulBufferLength)
  433. {
  434. TSPacketReceived(pAddressObject,
  435. pReceiveData,
  436. pReceiveContext->fIsExpedited);
  437. }
  438. else
  439. {
  440. DebugPrint1("%s: Data Incomplete\n", strFuncP1);
  441. TSFreeMemory(pReceiveData->pucDataBuffer);
  442. TSFreeMemory(pReceiveData);
  443. }
  444. }
  445. else
  446. {
  447. DebugPrint2("%s: Completed with status 0x%08x\n",
  448. strFuncP1,
  449. lStatus);
  450. TSFreeMemory(pReceiveData->pucDataBuffer);
  451. TSFreeMemory(pReceiveData);
  452. }
  453. //
  454. // now cleanup
  455. //
  456. TSFreeIrp(pLowerIrp, pAddressObject->pIrpPool);
  457. TSFreeBuffer(pReceiveContext->pLowerMdl);
  458. TSFreeMemory(pReceiveContext);
  459. return TDI_MORE_PROCESSING;
  460. }
  461. #pragma warning(default: UNREFERENCED_PARAM)
  462. // ---------------------------------
  463. //
  464. // Function: TSShowReceiveInfo
  465. //
  466. // Arguments: pAddressObject -- the address object associated with this endpoint
  467. // ConnectionContext -- endpoint of this connection
  468. // ulReceiveFlags -- info about the receive
  469. // ulBytesIndicated -- bytes indicated up
  470. // ulBytesAvailable -- total bytes (or starting offset)
  471. // pvTsdu -- ptr to the data (or to its mdl)
  472. // fIsChained -- if TRUE, then this is chained receive
  473. //
  474. // Returns: none
  475. //
  476. // Descript: shows info passed to receive handler
  477. //
  478. // --------------------------------
  479. VOID
  480. TSShowReceiveInfo(PADDRESS_OBJECT pAddressObject,
  481. CONNECTION_CONTEXT ConnectionContext,
  482. ULONG ulReceiveFlags,
  483. ULONG ulBytesIndicated,
  484. ULONG ulBytesAvailable,
  485. PVOID pvTsdu,
  486. BOOLEAN fIsChained)
  487. {
  488. DebugPrint3("pAddressObject = %p\n"
  489. "pEndpoint = %p\n"
  490. "ulReceiveFlags = 0x%08x\n",
  491. pAddressObject,
  492. ConnectionContext,
  493. ulReceiveFlags);
  494. if (ulReceiveFlags & TDI_RECEIVE_NORMAL)
  495. {
  496. DebugPrint0(" TDI_RECEIVE_NORMAL\n");
  497. }
  498. if (ulReceiveFlags & TDI_RECEIVE_EXPEDITED)
  499. {
  500. DebugPrint0(" TDI_RECEIVE_EXPEDITED\n");
  501. }
  502. if (ulReceiveFlags & TDI_RECEIVE_ENTIRE_MESSAGE)
  503. {
  504. DebugPrint0(" TDI_RECEIVE_ENTIRE_MESSAGE\n");
  505. }
  506. if (ulReceiveFlags & TDI_RECEIVE_AT_DISPATCH_LEVEL)
  507. {
  508. DebugPrint0(" TDI_RECEIVE_AT_DISPATCH_LEVEL\n");
  509. }
  510. if (fIsChained)
  511. {
  512. DebugPrint3("ReceiveLength = %u\n"
  513. "StartingOffset = 0x%08x\n"
  514. "pMdl = %p\n",
  515. ulBytesIndicated,
  516. ulBytesAvailable,
  517. pvTsdu);
  518. }
  519. else
  520. {
  521. DebugPrint3("BytesIndicated = %u\n"
  522. "TotalBytes = %u\n"
  523. "pDataBuffer = %p\n",
  524. ulBytesIndicated,
  525. ulBytesAvailable,
  526. pvTsdu);
  527. }
  528. }
  529. // ------------------------------------------------------
  530. //
  531. // Function: TSGetRestOfData
  532. //
  533. // Arguments: pAddressObject -- address object we are receiving on
  534. // pReceiveData -- what we have received so far..
  535. //
  536. // Returns: Irp to return to transport, to get rest of data (NULL if error)
  537. //
  538. // Descript: This function sets up the IRP to get the rest of a datagram
  539. // that was only partially delivered via the event handler
  540. //
  541. // -------------------------------------------------
  542. PIRP
  543. TSGetRestOfData(PADDRESS_OBJECT pAddressObject,
  544. PRECEIVE_DATA pReceiveData,
  545. BOOLEAN fIsExpedited)
  546. {
  547. PUCHAR pucDataBuffer = pReceiveData->pucDataBuffer + pReceiveData->ulBufferUsed;
  548. ULONG ulBufferLength = pReceiveData->ulBufferLength - pReceiveData->ulBufferUsed;
  549. PRECEIVE_CONTEXT pReceiveContext = NULL;
  550. PMDL pReceiveMdl = NULL;
  551. //
  552. // allocate all the necessary structures
  553. // our context
  554. //
  555. if ((TSAllocateMemory((PVOID *)&pReceiveContext,
  556. sizeof(RECEIVE_CONTEXT),
  557. strFuncP3,
  558. "ReceiveContext")) != STATUS_SUCCESS)
  559. {
  560. goto cleanup;
  561. }
  562. //
  563. // then the actual mdl
  564. //
  565. pReceiveMdl = TSAllocateBuffer(pucDataBuffer,
  566. ulBufferLength);
  567. if (pReceiveMdl)
  568. {
  569. //
  570. // set up the completion context
  571. //
  572. pReceiveContext->pLowerMdl = pReceiveMdl;
  573. pReceiveContext->pReceiveData = pReceiveData;
  574. pReceiveContext->pAddressObject = pAddressObject;
  575. pReceiveContext->fIsExpedited = fIsExpedited;
  576. //
  577. // finally, the irp itself
  578. //
  579. PIRP pLowerIrp = TSAllocateIrp(pAddressObject->pEndpoint->GenHead.pDeviceObject,
  580. pAddressObject->pIrpPool);
  581. if (pLowerIrp)
  582. {
  583. //
  584. // if made it to here, everything is correctly allocated
  585. // set up the irp for the call
  586. //
  587. #pragma warning(disable: CONSTANT_CONDITIONAL)
  588. TdiBuildReceive(pLowerIrp,
  589. pAddressObject->pEndpoint->GenHead.pDeviceObject,
  590. pAddressObject->pEndpoint->GenHead.pFileObject,
  591. TSReceiveComplete,
  592. pReceiveContext,
  593. pReceiveMdl,
  594. TDI_RECEIVE_NORMAL,
  595. ulBufferLength);
  596. #pragma warning(default: CONSTANT_CONDITIONAL)
  597. return pLowerIrp;
  598. }
  599. }
  600. //
  601. // get here if there was an allocation failure
  602. // need to clean up everything else...
  603. //
  604. cleanup:
  605. if (pReceiveContext)
  606. {
  607. TSFreeMemory(pReceiveContext);
  608. }
  609. if (pReceiveMdl)
  610. {
  611. TSFreeBuffer(pReceiveMdl);
  612. }
  613. return NULL;
  614. }
  615. // ---------------------------------------------
  616. //
  617. // Function: TSCommonReceive
  618. //
  619. // Arguments: see TSReceiveHandler
  620. //
  621. // Returns: status to return to protocol
  622. //
  623. // Descript: Common code for TSReceiveHandler and
  624. // TSRcvExpeditedHandler. Pretty much all the work is
  625. // done here
  626. //
  627. // ---------------------------------------------
  628. TDI_STATUS
  629. TSCommonReceive(PADDRESS_OBJECT pAddressObject,
  630. ULONG ulBytesTotal,
  631. ULONG ulBytesIndicated,
  632. ULONG ulReceiveFlags,
  633. PVOID pvTsdu,
  634. BOOLEAN fIsExpedited,
  635. PULONG pulBytesTaken,
  636. PIRP *pIoRequestPacket)
  637. {
  638. //
  639. // check for a bad condition -- more bytes indicated that total
  640. //
  641. if (ulBytesIndicated > ulBytesTotal)
  642. {
  643. DebugPrint2("%u bytes indicated > %u bytes total\n",
  644. ulBytesIndicated,
  645. ulBytesTotal);
  646. return TDI_NOT_ACCEPTED;
  647. }
  648. PRECEIVE_DATA pReceiveData;
  649. if ( (TSAllocateMemory((PVOID *)&pReceiveData,
  650. sizeof(RECEIVE_DATA),
  651. strFuncP4,
  652. "ReceiveData")) == STATUS_SUCCESS)
  653. {
  654. PUCHAR pucDataBuffer = NULL;
  655. if ((TSAllocateMemory((PVOID *)&pucDataBuffer,
  656. ulBytesTotal,
  657. strFuncP4,
  658. "DataBuffer")) == STATUS_SUCCESS)
  659. {
  660. pReceiveData->pucDataBuffer = pucDataBuffer;
  661. pReceiveData->ulBufferLength = ulBytesTotal;
  662. }
  663. else
  664. {
  665. TSFreeMemory(pReceiveData);
  666. return TDI_NOT_ACCEPTED;
  667. }
  668. }
  669. else
  670. {
  671. return TDI_NOT_ACCEPTED;
  672. }
  673. //
  674. // copy the data indicated to us into the buffer
  675. //
  676. TdiCopyLookaheadData(pReceiveData->pucDataBuffer,
  677. pvTsdu,
  678. ulBytesIndicated,
  679. ulReceiveFlags);
  680. pReceiveData->ulBufferUsed = ulBytesIndicated;
  681. //
  682. // first case -- entire packet indicated to us
  683. //
  684. if (ulBytesIndicated == ulBytesTotal)
  685. {
  686. TSPacketReceived(pAddressObject,
  687. pReceiveData,
  688. fIsExpedited);
  689. *pulBytesTaken = ulBytesTotal;
  690. *pIoRequestPacket = NULL;
  691. return TDI_SUCCESS;
  692. }
  693. //
  694. // second case -- only part of data indicated up
  695. //
  696. else
  697. {
  698. PIRP pLowerIrp = TSGetRestOfData(pAddressObject,
  699. pReceiveData,
  700. fIsExpedited);
  701. if (pLowerIrp)
  702. {
  703. //
  704. // need to do this since we are bypassing IoCallDriver
  705. //
  706. IoSetNextIrpStackLocation(pLowerIrp);
  707. *pulBytesTaken = ulBytesIndicated;
  708. *pIoRequestPacket = pLowerIrp;
  709. return TDI_MORE_PROCESSING;
  710. }
  711. else
  712. {
  713. DebugPrint1("%s: unable to get rest of packet\n", strFuncP4);
  714. TSFreeMemory(pReceiveData->pucDataBuffer);
  715. TSFreeMemory(pReceiveData);
  716. return TDI_NOT_ACCEPTED;
  717. }
  718. }
  719. }
  720. // ---------------------------------------------
  721. //
  722. // Function: TSCommonChainedReceive
  723. //
  724. // Arguments: see TStChainedRcvhandler
  725. //
  726. // Returns: status
  727. //
  728. // Descript: Common code for TSChainedReceiveHandler and
  729. // TSChainedRcvExpeditedHandler. Pretty much all the work is
  730. // done here
  731. //
  732. // ---------------------------------------------
  733. TDI_STATUS
  734. TSCommonChainedReceive(PADDRESS_OBJECT pAddressObject,
  735. ULONG ulReceiveLength,
  736. ULONG ulStartingOffset,
  737. PMDL pReceiveMdl,
  738. BOOLEAN fIsExpedited,
  739. PVOID pvTsduDescriptor)
  740. {
  741. PRECEIVE_DATA pReceiveData;
  742. if ((TSAllocateMemory((PVOID *)&pReceiveData,
  743. sizeof(RECEIVE_DATA),
  744. strFuncP5,
  745. "ReceiveData")) == STATUS_SUCCESS)
  746. {
  747. PUCHAR pucDataBuffer;
  748. if((TSAllocateMemory((PVOID *)&pucDataBuffer,
  749. ulReceiveLength,
  750. strFuncP5,
  751. "DataBuffer")) == STATUS_SUCCESS)
  752. {
  753. ULONG ulBytesCopied;
  754. TdiCopyMdlToBuffer(pReceiveMdl,
  755. ulStartingOffset,
  756. pucDataBuffer,
  757. 0,
  758. ulReceiveLength,
  759. &ulBytesCopied);
  760. //
  761. // if successfully copied all data
  762. //
  763. if (ulBytesCopied == ulReceiveLength)
  764. {
  765. pReceiveData->pucDataBuffer = pucDataBuffer;
  766. pReceiveData->ulBufferLength = ulReceiveLength;
  767. pReceiveData->ulBufferUsed = ulReceiveLength;
  768. TSPacketReceived(pAddressObject,
  769. pReceiveData,
  770. fIsExpedited);
  771. return TDI_SUCCESS;
  772. }
  773. //
  774. // error in copying data!
  775. //
  776. else
  777. {
  778. DebugPrint1("%s: error copying data\n", strFuncP5);
  779. TSFreeMemory(pucDataBuffer);
  780. TSFreeMemory(pReceiveData);
  781. }
  782. }
  783. else // unable to allocate pucDataBuffer
  784. {
  785. TSFreeMemory(pReceiveData);
  786. }
  787. }
  788. return TDI_NOT_ACCEPTED;
  789. }
  790. ///////////////////////////////////////////////////////////////////////////////
  791. // end of file receive.cpp
  792. ///////////////////////////////////////////////////////////////////////////////