|
|
/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
send.c
Abstract:
This module contains code which processes all send NCB's including both session and datagram based transfers.
Author:
Colin Watson (ColinW) 12-Sep-1991
Environment:
Kernel mode
Revision History:
--*/
#include "nb.h"
NTSTATUS NbSend( IN PDNCB pdncb, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp, IN ULONG Buffer2Length ) /*++
Routine Description:
This routine is called to send a buffer full of data.
Arguments:
pdncb - Pointer to the NCB.
Irp - Pointer to the request packet representing the I/O request.
IrpSp - Pointer to current IRP stack frame.
Buffer2Length - Length of user provided buffer for data.
Return Value:
The function value is the status of the operation.
--*/
{ PFCB pfcb = IrpSp->FileObject->FsContext2; PCB pcb; PPCB ppcb; PDEVICE_OBJECT DeviceObject; KIRQL OldIrql; // Used when SpinLock held.
LOCK( pfcb, OldIrql );
ppcb = FindCb( pfcb, pdncb, FALSE);
if ( ppcb == NULL ) { // FindCb has put the error in the NCB
UNLOCK( pfcb, OldIrql ); if ( pdncb->ncb_retcode == NRC_SCLOSED ) { // Tell dll to hangup the connection.
return STATUS_HANGUP_REQUIRED; } else { return STATUS_SUCCESS; } } pcb = *ppcb;
if ( (pcb->DeviceObject == NULL) || (pcb->ConnectionObject == NULL)) { UNLOCK( pfcb, OldIrql ); NCB_COMPLETE( pdncb, NRC_SCLOSED ); return STATUS_INVALID_DEVICE_REQUEST; }
TdiBuildSend (Irp, pcb->DeviceObject, pcb->ConnectionObject, NbCompletionPDNCB, pdncb, Irp->MdlAddress, (((pdncb->ncb_command & ~ASYNCH) == NCBSENDNA ) || ((pdncb->ncb_command & ~ASYNCH) == NCBCHAINSENDNA ))? TDI_SEND_NO_RESPONSE_EXPECTED : 0, Buffer2Length);
DeviceObject = pcb->DeviceObject;
InsertTailList(&pcb->SendList, &pdncb->ncb_next); pdncb->irp = Irp; pdncb->pfcb = pfcb; pdncb->tick_count = pcb->SendTimeout;
UNLOCK( pfcb, OldIrql );
IoMarkIrpPending( Irp ); IoCallDriver (DeviceObject, Irp);
IF_NBDBG (NB_DEBUG_SEND) { NbPrint(( "NB SEND submit: %X\n", Irp->IoStatus.Status )); }
//
// Transport will complete the request. Return pending so that
// netbios does not complete as well.
//
return STATUS_PENDING;
}
NTSTATUS NbSendDatagram( IN PDNCB pdncb, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp, IN ULONG Buffer2Length ) /*++
Routine Description:
This routine is called to SendDatagram a buffer full of data.
Arguments:
pdncb - Pointer to the NCB.
Irp - Pointer to the request packet representing the I/O request.
IrpSp - Pointer to current IRP stack frame.
Buffer2Length - Length of user provided buffer for data.
Return Value:
The function value is the status of the operation.
--*/
{ PFCB pfcb = IrpSp->FileObject->FsContext2; PPAB ppab; PAB pab; PDEVICE_OBJECT DeviceObject; KIRQL OldIrql; // Used when SpinLock held.
IF_NBDBG (NB_DEBUG_SEND) { NbPrint(( "NB SEND Datagram submit, pdncb %lx\n", pdncb )); }
LOCK( pfcb, OldIrql ); ppab = FindAbUsingNum( pfcb, pdncb, pdncb->ncb_num );
if ( ppab == NULL ) { // FindAb has put the error in the NCB
UNLOCK( pfcb, OldIrql ); return STATUS_SUCCESS; } pab = *ppab;
pdncb->Information.RemoteAddressLength = sizeof(TA_NETBIOS_ADDRESS); pdncb->Information.RemoteAddress = &pdncb->RemoteAddress;
pdncb->RemoteAddress.TAAddressCount = 1; pdncb->RemoteAddress.Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS; pdncb->RemoteAddress.Address[0].Address[0].NetbiosNameType = TDI_ADDRESS_TYPE_NETBIOS;
if ( (pdncb->ncb_command & ~ASYNCH) == NCBDGSENDBC ) { PPAB ppab255 = FindAbUsingNum( pfcb, pdncb, MAXIMUM_ADDRESS );
if ( ppab255 == NULL ) { // FindAb has put the error in the NCB
UNLOCK( pfcb, OldIrql ); return STATUS_SUCCESS; }
pdncb->RemoteAddress.Address[0].AddressLength = (*ppab255)->NameLength;
RtlMoveMemory( pdncb->RemoteAddress.Address[0].Address[0].NetbiosName, &(*ppab255)->Name, (*ppab255)->NameLength );
} else {
pdncb->RemoteAddress.Address[0].AddressLength = sizeof (TDI_ADDRESS_NETBIOS);
RtlMoveMemory( pdncb->RemoteAddress.Address[0].Address[0].NetbiosName, pdncb->ncb_callname, NCBNAMSZ ); }
pdncb->Information.UserDataLength = 0; pdncb->Information.UserData = NULL; pdncb->Information.OptionsLength = 0; pdncb->Information.Options = NULL;
TdiBuildSendDatagram (Irp, pab->DeviceObject, pab->AddressObject, NbCompletionPDNCB, pdncb, Irp->MdlAddress, Buffer2Length, &pdncb->Information);
DeviceObject = pab->DeviceObject; pdncb->irp = Irp; pdncb->pfcb = pfcb;
UNLOCK( pfcb, OldIrql );
IoMarkIrpPending( Irp ); IoCallDriver (DeviceObject, Irp);
IF_NBDBG (NB_DEBUG_SEND) { NbPrint(( "NB SEND Datagram submit: %X\n", Irp->IoStatus.Status )); }
//
// Transport will complete the request. Return pending so that
// netbios does not complete as well.
//
return STATUS_PENDING;
}
|