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.

243 lines
5.7 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. send.c
  5. Abstract:
  6. This module contains code which processes all send NCB's including
  7. both session and datagram based transfers.
  8. Author:
  9. Colin Watson (ColinW) 12-Sep-1991
  10. Environment:
  11. Kernel mode
  12. Revision History:
  13. --*/
  14. #include "nb.h"
  15. NTSTATUS
  16. NbSend(
  17. IN PDNCB pdncb,
  18. IN PIRP Irp,
  19. IN PIO_STACK_LOCATION IrpSp,
  20. IN ULONG Buffer2Length
  21. )
  22. /*++
  23. Routine Description:
  24. This routine is called to send a buffer full of data.
  25. Arguments:
  26. pdncb - Pointer to the NCB.
  27. Irp - Pointer to the request packet representing the I/O request.
  28. IrpSp - Pointer to current IRP stack frame.
  29. Buffer2Length - Length of user provided buffer for data.
  30. Return Value:
  31. The function value is the status of the operation.
  32. --*/
  33. {
  34. PFCB pfcb = IrpSp->FileObject->FsContext2;
  35. PCB pcb;
  36. PPCB ppcb;
  37. PDEVICE_OBJECT DeviceObject;
  38. KIRQL OldIrql; // Used when SpinLock held.
  39. LOCK( pfcb, OldIrql );
  40. ppcb = FindCb( pfcb, pdncb, FALSE);
  41. if ( ppcb == NULL ) {
  42. // FindCb has put the error in the NCB
  43. UNLOCK( pfcb, OldIrql );
  44. if ( pdncb->ncb_retcode == NRC_SCLOSED ) {
  45. // Tell dll to hangup the connection.
  46. return STATUS_HANGUP_REQUIRED;
  47. } else {
  48. return STATUS_SUCCESS;
  49. }
  50. }
  51. pcb = *ppcb;
  52. if ( (pcb->DeviceObject == NULL) || (pcb->ConnectionObject == NULL)) {
  53. UNLOCK( pfcb, OldIrql );
  54. NCB_COMPLETE( pdncb, NRC_SCLOSED );
  55. return STATUS_INVALID_DEVICE_REQUEST;
  56. }
  57. TdiBuildSend (Irp,
  58. pcb->DeviceObject,
  59. pcb->ConnectionObject,
  60. NbCompletionPDNCB,
  61. pdncb,
  62. Irp->MdlAddress,
  63. (((pdncb->ncb_command & ~ASYNCH) == NCBSENDNA ) ||
  64. ((pdncb->ncb_command & ~ASYNCH) == NCBCHAINSENDNA ))?
  65. TDI_SEND_NO_RESPONSE_EXPECTED : 0,
  66. Buffer2Length);
  67. DeviceObject = pcb->DeviceObject;
  68. InsertTailList(&pcb->SendList, &pdncb->ncb_next);
  69. pdncb->irp = Irp;
  70. pdncb->pfcb = pfcb;
  71. pdncb->tick_count = pcb->SendTimeout;
  72. UNLOCK( pfcb, OldIrql );
  73. IoMarkIrpPending( Irp );
  74. IoCallDriver (DeviceObject, Irp);
  75. IF_NBDBG (NB_DEBUG_SEND) {
  76. NbPrint(( "NB SEND submit: %X\n", Irp->IoStatus.Status ));
  77. }
  78. //
  79. // Transport will complete the request. Return pending so that
  80. // netbios does not complete as well.
  81. //
  82. return STATUS_PENDING;
  83. }
  84. NTSTATUS
  85. NbSendDatagram(
  86. IN PDNCB pdncb,
  87. IN PIRP Irp,
  88. IN PIO_STACK_LOCATION IrpSp,
  89. IN ULONG Buffer2Length
  90. )
  91. /*++
  92. Routine Description:
  93. This routine is called to SendDatagram a buffer full of data.
  94. Arguments:
  95. pdncb - Pointer to the NCB.
  96. Irp - Pointer to the request packet representing the I/O request.
  97. IrpSp - Pointer to current IRP stack frame.
  98. Buffer2Length - Length of user provided buffer for data.
  99. Return Value:
  100. The function value is the status of the operation.
  101. --*/
  102. {
  103. PFCB pfcb = IrpSp->FileObject->FsContext2;
  104. PPAB ppab;
  105. PAB pab;
  106. PDEVICE_OBJECT DeviceObject;
  107. KIRQL OldIrql; // Used when SpinLock held.
  108. IF_NBDBG (NB_DEBUG_SEND) {
  109. NbPrint(( "NB SEND Datagram submit, pdncb %lx\n", pdncb ));
  110. }
  111. LOCK( pfcb, OldIrql );
  112. ppab = FindAbUsingNum( pfcb, pdncb, pdncb->ncb_num );
  113. if ( ppab == NULL ) {
  114. // FindAb has put the error in the NCB
  115. UNLOCK( pfcb, OldIrql );
  116. return STATUS_SUCCESS;
  117. }
  118. pab = *ppab;
  119. pdncb->Information.RemoteAddressLength = sizeof(TA_NETBIOS_ADDRESS);
  120. pdncb->Information.RemoteAddress = &pdncb->RemoteAddress;
  121. pdncb->RemoteAddress.TAAddressCount = 1;
  122. pdncb->RemoteAddress.Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS;
  123. pdncb->RemoteAddress.Address[0].Address[0].NetbiosNameType =
  124. TDI_ADDRESS_TYPE_NETBIOS;
  125. if ( (pdncb->ncb_command & ~ASYNCH) == NCBDGSENDBC ) {
  126. PPAB ppab255 = FindAbUsingNum( pfcb, pdncb, MAXIMUM_ADDRESS );
  127. if ( ppab255 == NULL ) {
  128. // FindAb has put the error in the NCB
  129. UNLOCK( pfcb, OldIrql );
  130. return STATUS_SUCCESS;
  131. }
  132. pdncb->RemoteAddress.Address[0].AddressLength = (*ppab255)->NameLength;
  133. RtlMoveMemory(
  134. pdncb->RemoteAddress.Address[0].Address[0].NetbiosName,
  135. &(*ppab255)->Name,
  136. (*ppab255)->NameLength
  137. );
  138. } else {
  139. pdncb->RemoteAddress.Address[0].AddressLength = sizeof (TDI_ADDRESS_NETBIOS);
  140. RtlMoveMemory(
  141. pdncb->RemoteAddress.Address[0].Address[0].NetbiosName,
  142. pdncb->ncb_callname,
  143. NCBNAMSZ
  144. );
  145. }
  146. pdncb->Information.UserDataLength = 0;
  147. pdncb->Information.UserData = NULL;
  148. pdncb->Information.OptionsLength = 0;
  149. pdncb->Information.Options = NULL;
  150. TdiBuildSendDatagram (Irp,
  151. pab->DeviceObject,
  152. pab->AddressObject,
  153. NbCompletionPDNCB,
  154. pdncb,
  155. Irp->MdlAddress,
  156. Buffer2Length,
  157. &pdncb->Information);
  158. DeviceObject = pab->DeviceObject;
  159. pdncb->irp = Irp;
  160. pdncb->pfcb = pfcb;
  161. UNLOCK( pfcb, OldIrql );
  162. IoMarkIrpPending( Irp );
  163. IoCallDriver (DeviceObject, Irp);
  164. IF_NBDBG (NB_DEBUG_SEND) {
  165. NbPrint(( "NB SEND Datagram submit: %X\n", Irp->IoStatus.Status ));
  166. }
  167. //
  168. // Transport will complete the request. Return pending so that
  169. // netbios does not complete as well.
  170. //
  171. return STATUS_PENDING;
  172. }