summaryrefslogtreecommitdiffstats
path: root/private/ntos/nbt/vxd/ncb.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/nbt/vxd/ncb.c')
-rw-r--r--private/ntos/nbt/vxd/ncb.c529
1 files changed, 529 insertions, 0 deletions
diff --git a/private/ntos/nbt/vxd/ncb.c b/private/ntos/nbt/vxd/ncb.c
new file mode 100644
index 000000000..534a822e6
--- /dev/null
+++ b/private/ntos/nbt/vxd/ncb.c
@@ -0,0 +1,529 @@
+/**********************************************************************/
+/** Microsoft Windows/NT **/
+/** Copyright(c) Microsoft Corp., 1993 **/
+/**********************************************************************/
+
+/*
+ NCB.c
+
+ This file contains the NCB Handler that the VNetBios driver calls
+
+ FILE HISTORY:
+ Johnl 25-Mar-1993 Created
+
+*/
+
+#include <nbtprocs.h>
+#include <debug.h>
+
+#ifdef CHICAGO
+
+#include <shell.h>
+
+#include <netvxd.h>
+
+//
+// Do this so the VXDINLINE in the header file doesn't conflict
+// with the actual function declaration in this file.
+//
+#define VNBT_NCB_X VNBT_NCB_X_CALL
+#define VNBT_LANA_MASK VNBT_LANA_MASK_CALL
+#include <vnbt.h>
+#undef VNBT_LANA_MASK
+#undef VNBT_NCB_X
+
+#endif ;; CHICAGO
+
+LANA_ENTRY LanaTable[NBT_MAX_LANAS] ;
+
+/*******************************************************************
+
+ NAME: VNBT_NCB_X
+
+ SYNOPSIS: All NCBs submitted by the VNetBios driver come through
+ here
+
+ ENTRY: pNCB - Pointer to submitted NCB
+ Ipaddr - this parm is used only by nbtstat -A, which directly
+ calls into VNBT_NCB_X
+ ipaddress to which to send AdapterStatus to
+
+ RETURNS: NCB Return code
+
+ NOTES:
+
+ HISTORY:
+ Johnl 25-Mar-1993 Created
+
+********************************************************************/
+
+ULONG
+_stdcall
+VNBT_NCB_X( PNCB pNCB,
+ PUCHAR pzDnsName,
+ PULONG pIpAddress,
+ PVOID pExtended,
+ ULONG fFlag )
+{
+ BOOL fAsync ;
+ tDEVICECONTEXT * pDeviceContext = NULL ;
+ NTSTATUS status = STATUS_SUCCESS ;
+ uchar errNCB = NRC_GOODRET ;
+ PBLOCKING_NCB_CONTEXT pBlkNcbContext;
+ ULONG Ipaddr = pIpAddress ? pIpAddress[0] : 0;
+
+ if ( !pNCB )
+ return NRC_INVADDRESS ;
+
+ pDeviceContext = GetDeviceContext( pNCB ) ;
+ if ( pDeviceContext == NULL )
+ return NRC_BRIDGE ;
+
+ if (!pDeviceContext->fDeviceUp)
+ return NRC_BRIDGE ;
+
+ fAsync = !!(pNCB->ncb_command & ASYNCH) ;
+
+ if (
+ ( pzDnsName != NULL )
+ && ( pIpAddress != NULL )
+ )
+ {
+ if ( fAsync )
+ {
+ return DoDnsResolveDirect( pNCB, pzDnsName, pIpAddress );
+ }
+ else
+ {
+ return (pNCB->ncb_retcode = pNCB->ncb_cmd_cplt = NRC_ILLCMD);
+ }
+ }
+ else if (
+ ( pIpAddress != NULL )
+ && ( Ipaddr != 0 )
+ && ( ( pNCB->ncb_command & ~ASYNCH ) != NCBASTAT )
+ )
+ {
+ IpToAscii( Ipaddr, &pNCB->ncb_callname[0] );
+ }
+
+ if ( !fAsync )
+ {
+ pBlkNcbContext = CTEAllocMem( sizeof(BLOCKING_NCB_CONTEXT) );
+ if (!pBlkNcbContext)
+ {
+ DbgPrint("VNBT_NCB_X: couldn't alloc pBlkNcbContext 1") ;
+ return NRC_NORESOURCES;
+ }
+
+ pBlkNcbContext->Verify = NBT_VERIFY_BLOCKING_NCB;
+ InitializeListHead(&pBlkNcbContext->Linkage);
+ pBlkNcbContext->pNCB = pNCB;
+
+ pBlkNcbContext->pWaitNCBBlock = CTEAllocMem( sizeof(CTEBlockStruc) );
+ if (!pBlkNcbContext->pWaitNCBBlock)
+ {
+ CTEFreeMem(pBlkNcbContext);
+ DbgPrint("VNBT_NCB_X: couldn't alloc pBlkNcbContext 2") ;
+ return NRC_NORESOURCES;
+ }
+
+ pBlkNcbContext->fNCBCompleted = FALSE ;
+
+ //
+ // The completion routine uses this flag to know if the thread is
+ // blocked and needs to be signaled.
+ //
+ pBlkNcbContext->fBlocked = FALSE;
+
+ InsertTailList(&NbtConfig.BlockingNcbs,&pBlkNcbContext->Linkage);
+ }
+
+ DbgPrint("VNBT_NCB_X: NCB Commmand Rcvd: 0x") ;
+ DbgPrintNum( pNCB->ncb_command ) ; DbgPrint(", (") ;
+ DbgPrintNum( (ULONG) pNCB ) ; DbgPrint(")\r\n") ;
+
+ pNCB->ncb_retcode = NRC_PENDING ;
+ pNCB->ncb_cmd_cplt = NRC_PENDING ;
+
+ switch ( pNCB->ncb_command & ~ASYNCH )
+ {
+ case NCBDGSEND:
+ case NCBDGSENDBC:
+ status = VxdDgramSend( pDeviceContext, pNCB ) ;
+ errNCB = MapTDIStatus2NCBErr( status ) ;
+ break ;
+
+ case NCBDGRECV:
+ case NCBDGRECVBC:
+ errNCB = VxdDgramReceive( pDeviceContext, pNCB ) ;
+ break ;
+
+ case NCBRECVANY:
+ errNCB = VxdReceiveAny( pDeviceContext, pNCB ) ;
+ break ;
+
+ case NCBCALL:
+ errNCB = VxdCall( pDeviceContext, pNCB ) ;
+ break ;
+
+ case NCBHANGUP:
+ errNCB = VxdHangup( pDeviceContext, pNCB ) ;
+ break ;
+
+ case NCBLISTEN:
+ errNCB = VxdListen( pDeviceContext, pNCB ) ;
+ break ;
+
+ case NCBRECV:
+ errNCB = VxdReceive( pDeviceContext, pNCB, TRUE ) ;
+ break ;
+
+ case NCBSEND:
+ case NCBSENDNA:
+ case NCBCHAINSEND:
+ case NCBCHAINSENDNA:
+ errNCB = VxdSend( pDeviceContext, pNCB ) ;
+ break ;
+
+#if 0
+ case NCBTRANSV:
+ errNCB = VxdTransceive( pDeviceContext, pNCB ) ;
+ break ;
+#endif
+
+ case NCBADDGRNAME:
+ case NCBADDNAME:
+ errNCB = VxdOpenName( pDeviceContext, pNCB ) ;
+ break ;
+
+ case NCBDELNAME:
+ errNCB = VxdCloseName( pDeviceContext, pNCB ) ;
+ break ;
+
+ case NCBASTAT:
+ errNCB = VxdAdapterStatus( pDeviceContext, pNCB, Ipaddr ) ;
+ break ;
+
+ case NCBSSTAT:
+ errNCB = VxdSessionStatus( pDeviceContext, pNCB ) ;
+ break ;
+
+ case NCBFINDNAME:
+ errNCB = VxdFindName( pDeviceContext, pNCB ) ;
+ break ;
+
+ case NCBRESET:
+ errNCB = VxdReset( pDeviceContext, pNCB ) ;
+ break ;
+
+ case NCBCANCEL:
+ if ( DoDnsCancelDirect( pNCB ) )
+ {
+ errNCB = NRC_GOODRET;
+ }
+ else
+ {
+ errNCB = VxdCancel( pDeviceContext, pNCB ) ;
+ }
+ break ;
+
+ //
+ // The following are no-ops that return success for compatibility
+ //
+ case NCBUNLINK:
+ case NCBTRACE:
+ CTEIoComplete( pNCB, STATUS_SUCCESS, 0 ) ;
+ break ;
+
+ default:
+ DbgPrint("VNBT_NCB_X - Unsupported command: ") ;
+ DbgPrintNum( pNCB->ncb_command & ~ASYNCH ) ;
+ DbgPrint("\n\r") ;
+ errNCB = NRC_ILLCMD ; // Bogus error for now
+ break ;
+ }
+
+Exit:
+ //
+ // If we aren't pending then set the codes
+ //
+ if ( errNCB != NRC_PENDING &&
+ errNCB != NRC_GOODRET )
+ {
+#ifdef DEBUG
+ DbgPrint("VNBT_NCB_X - Returning ") ;
+ DbgPrintNum( errNCB ) ;
+ DbgPrint(" to NCB submitter\n\r") ;
+#endif
+ pNCB->ncb_retcode = errNCB ;
+ pNCB->ncb_cmd_cplt = errNCB ;
+
+ //
+ // Errored NCBs don't have the completion routine called, so we
+ // in essence, complete it here. Note this will only set the
+ // state for the last Wait NCB (all others get NRC_IFBUSY).
+ //
+ if ( !fAsync )
+ {
+ ASSERT(pBlkNcbContext->Verify == NBT_VERIFY_BLOCKING_NCB);
+ pBlkNcbContext->fNCBCompleted = TRUE ;
+ }
+ }
+ else
+ {
+ //
+ // Some components (AKA server) don't like returning pending
+ //
+ errNCB = NRC_GOODRET ;
+
+ }
+
+ //
+ // Block until NCB completion if this wasn't an async NCB
+ //
+ if ( !fAsync )
+ {
+ ASSERT(pBlkNcbContext->Verify == NBT_VERIFY_BLOCKING_NCB);
+ if ( !pBlkNcbContext->fNCBCompleted )
+ {
+ pBlkNcbContext->fBlocked = TRUE;
+ CTEInitBlockStruc( pBlkNcbContext->pWaitNCBBlock ) ;
+ CTEBlock( pBlkNcbContext->pWaitNCBBlock ) ;
+ }
+ else
+ {
+ RemoveEntryList(&pBlkNcbContext->Linkage);
+ CTEFreeMem(pBlkNcbContext->pWaitNCBBlock);
+ CTEFreeMem(pBlkNcbContext);
+ }
+ }
+
+ return errNCB ;
+}
+
+/*******************************************************************
+
+ NAME: GetDeviceContext
+
+ SYNOPSIS: Retrieves the device context associated with the lana
+ specified in the NCB
+
+ ENTRY: pNCB - NCB to get the device context for
+
+ RETURNS: Device context or NULL if not found
+
+ NOTES: It is assumed that LanaTable is filled sequentially
+ with no holes.
+
+ HISTORY:
+ Johnl 30-Aug-1993 Created
+
+********************************************************************/
+
+tDEVICECONTEXT * GetDeviceContext( NCB * pNCB )
+{
+ int i ;
+
+ if ( !pNCB )
+ return NULL ;
+
+ for ( i = 0; i < NBT_MAX_LANAS; i++)
+ {
+ if ( LanaTable[i].pDeviceContext->iLana == pNCB->ncb_lana_num)
+ return LanaTable[i].pDeviceContext;
+ }
+
+ return NULL;
+}
+
+/*******************************************************************
+
+ NAME: NbtWouldLoopback
+
+ SYNOPSIS: Returns a BOOL that specifies whether the input
+ IP address would loop back to the local machine
+
+ ENTRY: IpAddr
+
+ RETURNS: TRUE if Nbt is bound to this address
+
+ NOTES: It is assumed that LanaTable is filled sequentially
+ with no holes.
+
+ HISTORY:
+ EarleH 28-Mar-1996 Created
+
+********************************************************************/
+
+BOOL
+NbtWouldLoopback(
+ ULONG IpAddr
+)
+{
+ int i ;
+
+ for ( i = 0; i < NBT_MAX_LANAS; i++)
+ {
+ if (
+ ( LanaTable[i].pDeviceContext )
+ && ( LanaTable[i].pDeviceContext->IpAddress == IpAddr )
+ )
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*******************************************************************
+
+ NAME: VNBT_LANA_MASK
+
+ SYNOPSIS: Returns a bit mask of LANA numbers being handled
+ by vnbt, with a DNS server configured
+
+ ENTRY: none
+
+ RETURNS: Bit mask of LANA numbers being handled by vnbt
+
+ NOTES:
+
+ HISTORY:
+ EarleH 26-Feb-1996 Created
+
+********************************************************************/
+
+ULONG
+_stdcall
+VNBT_LANA_MASK(
+ )
+{
+ int i;
+ ULONG mask = 0;
+
+ for ( i = 0 ; i < NBT_MAX_LANAS; i++)
+ {
+ if (
+ ( LanaTable[i].pDeviceContext )
+ && ( LanaTable[i].pDeviceContext->fDeviceUp )
+ && ( LanaTable[i].pDeviceContext->lDnsServerAddress )
+ && ( LanaTable[i].pDeviceContext->lDnsServerAddress != LOOP_BACK )
+ )
+ {
+ mask |= 1 << LanaTable[i].pDeviceContext->iLana;
+ }
+ }
+
+ return mask;
+}
+
+/*******************************************************************
+
+ NAME: MapTDIStatus2NCBErr
+
+ SYNOPSIS: Maps a TDI_STATUS error value to an Netbios NCR error value
+
+ ENTRY: tdistatus - TDI Status to map
+
+ RETURNS: The mapped error
+
+ NOTES:
+
+ HISTORY:
+ Johnl 15-Apr-1993 Created
+
+********************************************************************/
+
+uchar MapTDIStatus2NCBErr( TDI_STATUS tdistatus )
+{
+ uchar errNCB ;
+ if ( tdistatus == TDI_SUCCESS )
+ return NRC_GOODRET ;
+ else if ( tdistatus == TDI_PENDING )
+ return NRC_PENDING ;
+
+
+ switch ( tdistatus )
+ {
+ case TDI_NO_RESOURCES:
+ errNCB = NRC_NORES ;
+ break ;
+
+ case STATUS_CANCELLED:
+ errNCB = NRC_CMDCAN ;
+ break ;
+
+ case TDI_INVALID_CONNECTION:
+ case STATUS_CONNECTION_DISCONNECTED:
+ errNCB = NRC_SCLOSED ;
+ break ;
+
+ case TDI_CONNECTION_ABORTED:
+ errNCB = NRC_SABORT ;
+ break ;
+
+ case STATUS_TOO_MANY_COMMANDS:
+ errNCB = NRC_TOOMANY ;
+ break ;
+
+ case STATUS_OBJECT_NAME_COLLISION:
+ case STATUS_SHARING_VIOLATION:
+ errNCB = NRC_DUPNAME ;
+ break ;
+
+ case STATUS_DUPLICATE_NAME:
+ errNCB = NRC_INUSE ;
+ break ;
+
+ //
+ // Call NCB submitted with a name that can't be found
+ //
+ case STATUS_BAD_NETWORK_PATH:
+ errNCB = NRC_NOCALL ;
+ break ;
+
+ case STATUS_REMOTE_NOT_LISTENING:
+ errNCB = NRC_REMTFUL ;
+ break ;
+
+ case TDI_TIMED_OUT:
+ errNCB = NRC_CMDTMO ;
+ break ;
+
+ //
+ // Where the transport has more data available but the NCB's buffer is
+ // full
+ //
+ case TDI_BUFFER_OVERFLOW:
+ errNCB = NRC_INCOMP ;
+ break ;
+
+ case STATUS_INVALID_BUFFER_SIZE:
+ errNCB = NRC_BUFLEN ;
+ break ;
+
+ case STATUS_NETWORK_NAME_DELETED:
+ errNCB = NRC_NAMERR ;
+ break ;
+
+ case STATUS_NRC_ACTSES:
+ errNCB = NRC_ACTSES ;
+ break ;
+
+ default:
+ DbgPrint("MapTDIStatus2NCBErr - Unmapped STATUS/TDI error - " ) ;
+ DbgPrintNum( tdistatus ) ;
+ DbgPrint("\n\r") ;
+
+ case STATUS_UNSUCCESSFUL:
+ case TDI_INVALID_STATE:
+ case STATUS_INVALID_PARAMETER: // Generally detected bad struct. signature
+ case STATUS_UNEXPECTED_NETWORK_ERROR:
+ errNCB = NRC_SYSTEM ;
+ break ;
+ }
+
+ return errNCB ;
+}
+
+