windows-nt/Source/XPSP1/NT/net/netbios/sys/send.c

244 lines
5.5 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
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;
}