mirror of https://github.com/lianthony/NT4.0
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.
930 lines
24 KiB
930 lines
24 KiB
/**********************************************************************/
|
|
/** Microsoft Windows **/
|
|
/** Copyright(c) Microsoft Corp., 1993 **/
|
|
/**********************************************************************/
|
|
|
|
/*
|
|
|
|
Init.c
|
|
|
|
Contains VxD initialization code
|
|
|
|
|
|
FILE HISTORY:
|
|
Johnl 24-Mar-1993 Created
|
|
|
|
*/
|
|
|
|
#include <nbtprocs.h>
|
|
#include <tdiinfo.h>
|
|
#include <ipinfo.h>
|
|
#include <dhcpinfo.h>
|
|
#include <nbtinfo.h>
|
|
#include <hosts.h>
|
|
|
|
int Init( void ) ;
|
|
int RegisterLana( int Lana ) ;
|
|
|
|
NTSTATUS
|
|
NbtReadRegistry(
|
|
OUT tNBTCONFIG *pConfig
|
|
) ;
|
|
|
|
extern char DNSSectionName[]; // Section where we find DNS domain name
|
|
|
|
VOID GetDNSInfo( VOID );
|
|
|
|
ULONG GetDhcpOption( PUCHAR ValueName, ULONG DefaultValue );
|
|
|
|
VOID ParseDomainNames(
|
|
PUCHAR *ppDomainName,
|
|
PUCHAR *ppDNSDomains
|
|
);
|
|
|
|
//******************* Pageable Routine Declarations ****************
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma CTEMakePageable(INIT, Init)
|
|
#pragma CTEMakePageable(PAGE, NbtReadRegistry)
|
|
#pragma CTEMakePageable(PAGE, GetDNSInfo)
|
|
#pragma CTEMakePageable(PAGE, CreateDeviceObject)
|
|
#pragma CTEMakePageable(PAGE, GetDhcpOption)
|
|
#endif
|
|
//******************* Pageable Routine Declarations ****************
|
|
|
|
//
|
|
// Initialized in VNBT_Device_Init with the protocol(s) this driver sits
|
|
// on. Note that we currently only support one. This should *not* be in
|
|
// the initialization data segments.
|
|
//
|
|
TDIDispatchTable * TdiDispatch ;
|
|
UCHAR LanaBase ;
|
|
BOOL fInInit = TRUE ;
|
|
|
|
//
|
|
// Used in conjunction with the CHECK_INT_TABLE macro
|
|
//
|
|
#ifdef DEBUG
|
|
BYTE abVecTbl[256] ;
|
|
DWORD DebugFlags = DBGFLAG_ALL | DBGFLAG_KDPRINTS ;
|
|
char DBOut[4096] ;
|
|
int iCurPos = 0 ;
|
|
|
|
void NbtDebugOut( char * str )
|
|
{
|
|
if ( DebugFlags & (DBGFLAG_AUX_OUTPUT | DBGFLAG_ERROR) )
|
|
CTEPrint( str ) ;
|
|
|
|
iCurPos += strlen( str ) + 1 ;
|
|
|
|
if ( iCurPos >= sizeof(DBOut) )
|
|
iCurPos = 0;
|
|
}
|
|
|
|
#endif // DEBUG
|
|
|
|
#pragma BEGIN_INIT
|
|
|
|
//
|
|
// While reading initialization parameters, we may need to go to
|
|
// the DHCP driver. This communicates to the init routine which device
|
|
// we are currently interested in.
|
|
// 0xfffffff means get the requested option for any IP address.
|
|
//
|
|
// MUST BE IN NETWORK ORDER!!!
|
|
//
|
|
ULONG CurrentIP = 0xffffffff ;
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: Init
|
|
|
|
SYNOPSIS: Performs all driver initialization
|
|
|
|
RETURNS: TRUE if initialization successful, FALSE otherwise
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
Johnl 24-Mar-1993 Created
|
|
|
|
********************************************************************/
|
|
|
|
int Init( void )
|
|
{
|
|
NTSTATUS status ;
|
|
int i ;
|
|
ULONG ulTmp ;
|
|
int Retval;
|
|
|
|
|
|
Retval = FALSE;
|
|
|
|
if ( CTEInitialize() )
|
|
{
|
|
DbgPrint("Init: CTEInitialize succeeded\n\r") ;
|
|
}
|
|
else
|
|
goto fail_init;
|
|
|
|
INIT_NULL_PTR_CHECK() ;
|
|
|
|
#ifdef DEBUG
|
|
InitializeListHead(&DbgMemList);
|
|
DbgLeakCheck = 0;
|
|
#endif
|
|
|
|
#ifdef CHICAGO
|
|
//
|
|
// Tell TDI who to call if someone underneath unloads
|
|
//
|
|
CTESetUnloadNotifyProc( (CTENotifyRtn)VxdUnload );
|
|
|
|
//
|
|
// prepare to read a bunch of parms from the registry
|
|
//
|
|
VxdOpenNdis();
|
|
#endif
|
|
|
|
CTERefillMem() ;
|
|
CTEZeroMemory( pNbtGlobConfig, sizeof(*pNbtGlobConfig));
|
|
|
|
status = NbtReadRegistry( pNbtGlobConfig ) ;
|
|
if ( !NT_SUCCESS( status ) )
|
|
{
|
|
DbgPrint("Init: NbtReadRegistry failed\n\r") ;
|
|
goto fail_init;
|
|
}
|
|
|
|
InitializeListHead(&pNbtGlobConfig->DelayedEvents);
|
|
|
|
InitializeListHead(&pNbtGlobConfig->BlockingNcbs);
|
|
|
|
status = InitNotOs() ;
|
|
if ( !NT_SUCCESS( status ) )
|
|
{
|
|
DbgPrint("Init: InitNotOs failed\n\r") ;
|
|
goto fail_init;
|
|
}
|
|
|
|
status = InitTimersNotOs() ;
|
|
if ( !NT_SUCCESS( status ) )
|
|
{
|
|
DbgPrint("Init: InitTimersNotOs failed\n\r") ;
|
|
StopInitTimers() ;
|
|
goto fail_init;
|
|
}
|
|
|
|
#ifdef CHICAGO
|
|
|
|
//
|
|
// if name server and/or dns server are defined in registry, read them now
|
|
//
|
|
SaveNameDnsServerAddrs();
|
|
|
|
//
|
|
// Register an IP notification routine when new adapters are added or
|
|
// DHCP brings up an address
|
|
//
|
|
|
|
if ( !IPRegisterAddrChangeHandler( IPNotification, TRUE))
|
|
{
|
|
DbgPrint("Init: Failed to register with IP driver\r\n") ;
|
|
StopInitTimers() ;
|
|
goto fail_init;
|
|
}
|
|
#else
|
|
//
|
|
// Find all the active Lanas
|
|
//
|
|
|
|
if ( !GetActiveLanasFromIP() )
|
|
{
|
|
DbgPrint("Init: Failed to get addresses from IP driver\r\n") ;
|
|
StopInitTimers() ;
|
|
goto fail_init;
|
|
}
|
|
|
|
#endif
|
|
|
|
//
|
|
// find out where hosts file is, what's the domain name etc.
|
|
//
|
|
GetDNSInfo();
|
|
|
|
//
|
|
// Get the NCB timeout timer going
|
|
//
|
|
if ( !CheckForTimedoutNCBs( NULL, NULL) )
|
|
{
|
|
DbgPrint("Init: CheckForTimedoutNCBs failed\n\r") ;
|
|
StopInitTimers() ;
|
|
goto fail_init;
|
|
}
|
|
|
|
fInInit = FALSE ;
|
|
CTERefillMem() ;
|
|
Retval = TRUE ;
|
|
|
|
|
|
fail_init:
|
|
|
|
#ifdef CHICAGO
|
|
VxdCloseNdis();
|
|
#endif
|
|
|
|
return( Retval );
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
NTSTATUS
|
|
NbtReadRegistry(
|
|
OUT tNBTCONFIG *pConfig
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called to get information from the registry,
|
|
starting at RegistryPath to get the parameters.
|
|
|
|
Arguments:
|
|
|
|
pNbtConfig - ptr to global configuration strucuture for NBT
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS - STATUS_SUCCESS if everything OK, STATUS_INSUFFICIENT_RESOURCES
|
|
otherwise.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS Status = STATUS_SUCCESS ;
|
|
int i;
|
|
|
|
CTEPagedCode();
|
|
|
|
//
|
|
// Initialize the Configuration data structure
|
|
//
|
|
CTEZeroMemory(pConfig,sizeof(tNBTCONFIG));
|
|
|
|
ReadParameters( pConfig, NULL );
|
|
|
|
//
|
|
// Allocate necessary memory for lmhosts support if a lmhosts file
|
|
// was specified (was read from .ini file in ReadParameters)
|
|
//
|
|
if ( pConfig->pLmHosts )
|
|
{
|
|
if ( !VxdInitLmHostsSupport( pConfig->pLmHosts,
|
|
260 /*strlen(pConfig->pLmHosts)+1*/ ))
|
|
{
|
|
return STATUS_INSUFFICIENT_RESOURCES ;
|
|
}
|
|
|
|
pConfig->EnableLmHosts = TRUE ;
|
|
}
|
|
else
|
|
{
|
|
pConfig->EnableLmHosts = FALSE ;
|
|
}
|
|
|
|
// keep the size around for allocating memory, so that when we run over
|
|
// OSI, only this value should change (in theory at least)
|
|
pConfig->SizeTransportAddress = sizeof(TDI_ADDRESS_IP);
|
|
|
|
// fill in the node type value that is put into all name service Pdus
|
|
// that go out identifying this node type
|
|
switch (NodeType)
|
|
{
|
|
case BNODE:
|
|
pConfig->PduNodeType = 0;
|
|
break;
|
|
case PNODE:
|
|
pConfig->PduNodeType = 1 << 13;
|
|
break;
|
|
case MNODE:
|
|
pConfig->PduNodeType = 1 << 14;
|
|
break;
|
|
case MSNODE:
|
|
pConfig->PduNodeType = 3 << 13;
|
|
break;
|
|
|
|
}
|
|
|
|
LanaBase = (UCHAR) CTEReadSingleIntParameter( NULL,
|
|
VXD_LANABASE_NAME,
|
|
VXD_DEF_LANABASE,
|
|
0 ) ;
|
|
CTEZeroMemory( LanaTable, NBT_MAX_LANAS * sizeof( LANA_ENTRY )) ;
|
|
|
|
return Status;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: GetDNSInfo
|
|
|
|
SYNOPSIS: Gets path to windows dir, then appends hosts to it
|
|
|
|
RETURNS: Nothing
|
|
|
|
NOTES: If something goes wrong, path is set to NULL
|
|
|
|
HISTORY:
|
|
Koti 13-July-1994 Created
|
|
|
|
********************************************************************/
|
|
|
|
VOID GetDNSInfo( VOID )
|
|
{
|
|
|
|
PUCHAR pszWinPath;
|
|
PUCHAR pszHosts="hosts";
|
|
PUCHAR pszHostsPath=NULL;
|
|
#ifdef CHICAGO
|
|
PUCHAR pszParmName="Domain";
|
|
PUCHAR pszParm2Name = "SearchList";
|
|
#else
|
|
PUCHAR pszParmName="DomainName";
|
|
PUCHAR pszParm2Name = "DNSDomains";
|
|
#endif
|
|
PUCHAR pszDomName;
|
|
PUCHAR pchTmp;
|
|
int len;
|
|
|
|
|
|
CTEPagedCode();
|
|
|
|
NbtConfig.pHosts = NULL;
|
|
|
|
//
|
|
// Remember, pszWinPath has '\' at the end: (i.e. Get_Config_Directory
|
|
// returns pointer to "c:\windows\" )
|
|
//
|
|
pszWinPath = VxdWindowsPath();
|
|
|
|
//
|
|
// doc implies Get_Config_Directory can't fail! But we are paranoid...
|
|
//
|
|
|
|
if (pszWinPath == NULL)
|
|
{
|
|
pszHostsPath = NULL;
|
|
return;
|
|
}
|
|
|
|
len = strlen(pszWinPath) + strlen(pszHosts) + 1;
|
|
|
|
//
|
|
// allocate memory to hold "c:\windows\hosts" or whatever
|
|
//
|
|
pszHostsPath = CTEAllocInitMem( len );
|
|
if (pszHostsPath == NULL)
|
|
return;
|
|
|
|
strcpy(pszHostsPath, pszWinPath);
|
|
strcat(pszHostsPath, pszHosts);
|
|
|
|
NbtConfig.pHosts = pszHostsPath;
|
|
|
|
NbtConfig.pDomainName = NULL;
|
|
//
|
|
// chicago gets the string from the registry, snowball from system.ini
|
|
//
|
|
NbtConfig.pDNSDomains = NULL;
|
|
|
|
#ifdef CHICAGO
|
|
if ( !CTEReadIniString( NULL, pszParmName, &pchTmp ) )
|
|
{
|
|
NbtConfig.pDomainName = pchTmp;
|
|
}
|
|
|
|
if ( !CTEReadIniString( NULL, pszParm2Name, &pchTmp ) )
|
|
{
|
|
if (pchTmp[0] != '\0')
|
|
{
|
|
NbtConfig.pDNSDomains = pchTmp;
|
|
}
|
|
else
|
|
{
|
|
CTEMemFree(pchTmp);
|
|
}
|
|
}
|
|
#else
|
|
pchTmp = GetProfileString( pszParmName, NULL, DNSSectionName );
|
|
if ( pchTmp != NULL )
|
|
{
|
|
if ( pszDomName = CTEAllocInitMem( strlen( pchTmp ) + 1 ) )
|
|
{
|
|
strcpy( pszDomName, pchTmp ) ;
|
|
|
|
NbtConfig.pDomainName = pszDomName;
|
|
}
|
|
}
|
|
|
|
pchTmp = GetProfileString( pszParm2Name, NULL, DNSSectionName );
|
|
if ( pchTmp != NULL && pchTmp[0] != '\0')
|
|
{
|
|
if ( pszDomName = CTEAllocInitMem( strlen( pchTmp ) + 1) )
|
|
{
|
|
strcpy( pszDomName, pchTmp ) ;
|
|
|
|
NbtConfig.pDNSDomains = pszDomName;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
ParseDomainNames( &NbtConfig.pDomainName, &NbtConfig.pDNSDomains);
|
|
|
|
return;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: ParseDomainNames
|
|
|
|
SYNOPSIS: Extracts heirarchical domain names from the primary DNS
|
|
domain name, and prepends any found to the domains list.
|
|
|
|
ENTRY: ppDomainName - pointer to pointer to primary DNS domain name
|
|
ppDNSDomains - pointer to pointer to other DNS domain names
|
|
|
|
EXIT: *ppDNSDomains updated with pointer to new DNS domains list
|
|
if any other heirarchical levels found in *ppDomainName.
|
|
|
|
RETURNS: nothing
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
EarleH 10-Jan-1996 Created
|
|
|
|
********************************************************************/
|
|
|
|
VOID ParseDomainNames(
|
|
PUCHAR *ppDomainName,
|
|
PUCHAR *ppDNSDomains
|
|
)
|
|
{
|
|
PUCHAR pStr;
|
|
UINT iCount;
|
|
PUCHAR pDomainName = *ppDomainName, pDNSDomains = *ppDNSDomains, pNewDNSDomains;
|
|
|
|
if ( pDomainName != NULL )
|
|
{
|
|
for ( iCount = 0, pStr = pDomainName ; pStr[0] != '\0' ; pStr++ )
|
|
{
|
|
if ( pStr[0] == '.' )
|
|
{
|
|
iCount += strlen ( pStr );
|
|
}
|
|
}
|
|
if ( pDNSDomains != NULL )
|
|
{
|
|
iCount += strlen ( pDNSDomains );
|
|
if ( iCount )
|
|
{
|
|
iCount++; // for the separator
|
|
}
|
|
}
|
|
if (iCount++) // ++ for the terminator
|
|
{
|
|
pNewDNSDomains = CTEAllocInitMem( iCount );
|
|
if ( pNewDNSDomains != NULL )
|
|
{
|
|
pNewDNSDomains[0] = '\0';
|
|
for ( pStr = pDomainName ; pStr[0] != '\0' ; pStr++ )
|
|
{
|
|
if ( pStr[0] == '.' )
|
|
{
|
|
pStr++;
|
|
if ( pNewDNSDomains[0] != '\0' )
|
|
{
|
|
strcat ( pNewDNSDomains, "," );
|
|
}
|
|
strcat ( pNewDNSDomains, pStr );
|
|
}
|
|
}
|
|
if ( pDNSDomains != NULL )
|
|
{
|
|
strcat ( pNewDNSDomains, "," );
|
|
strcat ( pNewDNSDomains, pDNSDomains );
|
|
CTEMemFree( pDNSDomains );
|
|
}
|
|
if ( pNewDNSDomains[0] != '\0' )
|
|
{
|
|
*ppDNSDomains = pNewDNSDomains;
|
|
}
|
|
else
|
|
{
|
|
*ppDNSDomains = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#pragma END_INIT
|
|
|
|
#ifndef CHICAGO
|
|
#pragma BEGIN_INIT
|
|
#endif
|
|
/*******************************************************************
|
|
|
|
NAME: CreateDeviceObject
|
|
|
|
SYNOPSIS: Initializes the device list of the global configuration
|
|
structure
|
|
|
|
ENTRY: pConfig - Pointer to global config structure
|
|
IpAddr - IP Address for this adapter
|
|
IpMask - IP Mask for this adapter
|
|
IpNameServer - IP Address of the name server for this adapter
|
|
IpBackupServer - IP Address of the backup name server for
|
|
this adapter
|
|
IpDnsServer - IP Address of the dns server for this adapter
|
|
IpDnsBackupServer - IP Address of the backup dns server
|
|
MacAddr - hardware address of the adapter for this IP addr
|
|
IpIndex - Index of the IP Address in the IP Driver's address
|
|
table (used for setting address by DHCP)
|
|
|
|
EXIT: The device list in pConfig will be fully initialized
|
|
|
|
RETURNS: STATUS_SUCCESS if successful, error otherwise
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
Johnl 14-Apr-1993 Created
|
|
|
|
********************************************************************/
|
|
|
|
NTSTATUS CreateDeviceObject(
|
|
IN tNBTCONFIG *pConfig,
|
|
IN ULONG IpAddr,
|
|
IN ULONG IpMask,
|
|
IN ULONG IpNameServer,
|
|
IN ULONG IpBackupServer,
|
|
IN ULONG IpDnsServer,
|
|
IN ULONG IpDnsBackupServer,
|
|
IN UCHAR MacAddr[],
|
|
IN UCHAR IpIndex
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
tDEVICECONTEXT * pDeviceContext, *pDevtmp;
|
|
ULONG ulTmp ;
|
|
NCB * pNCB ;
|
|
DHCPNotify dn ;
|
|
PLIST_ENTRY pEntry;
|
|
ULONG Adapter;
|
|
ULONG PreviousNodeType;
|
|
|
|
CTEPagedCode();
|
|
|
|
pDeviceContext = CTEAllocInitMem(sizeof( tDEVICECONTEXT )) ;
|
|
if ( !pDeviceContext )
|
|
return STATUS_INSUFFICIENT_RESOURCES ;
|
|
|
|
//
|
|
// zero out the data structure
|
|
//
|
|
CTEZeroMemory( pDeviceContext, sizeof(tDEVICECONTEXT) );
|
|
|
|
// put a verifier value into the structure so that we can check that
|
|
// we are operating on the right data when the OS passes a device context
|
|
// to NBT
|
|
pDeviceContext->Verify = NBT_VERIFY_DEVCONTEXT;
|
|
|
|
//
|
|
// we aren't up yet: don't want ncb's coming in before we are ready!
|
|
//
|
|
pDeviceContext->fDeviceUp = FALSE;
|
|
|
|
// setup the spin lock);
|
|
CTEInitLock(&pDeviceContext->SpinLock);
|
|
pDeviceContext->LockNumber = DEVICE_LOCK;
|
|
pDeviceContext->lNameServerAddress = IpNameServer ;
|
|
pDeviceContext->lBackupServer = IpBackupServer ;
|
|
pDeviceContext->lDnsServerAddress = IpDnsServer ;
|
|
pDeviceContext->lDnsBackupServer = IpDnsBackupServer ;
|
|
|
|
// copy the mac addresss
|
|
CTEMemCopy(&pDeviceContext->MacAddress.Address[0], MacAddr, 6);
|
|
|
|
//
|
|
// if the node type is set to Bnode by default then switch to Hnode if
|
|
// there are any WINS servers configured.
|
|
//
|
|
PreviousNodeType = NodeType;
|
|
|
|
if ((NodeType & DEFAULT_NODE_TYPE) &&
|
|
(IpNameServer || IpBackupServer))
|
|
{
|
|
NodeType = MSNODE;
|
|
if (PreviousNodeType & PROXY)
|
|
NodeType |= PROXY;
|
|
}
|
|
|
|
//
|
|
// start the refresh timer (if we had already started it, this function
|
|
// just returns success)
|
|
//
|
|
status = StartRefreshTimer();
|
|
|
|
if ( !NT_SUCCESS( status ) )
|
|
{
|
|
CTEFreeMem( pDeviceContext ) ;
|
|
return( status ) ;
|
|
}
|
|
|
|
|
|
// initialize the pDeviceContext data structure. There is one of
|
|
// these data structured tied to each "device" that NBT exports
|
|
// to higher layers (i.e. one for each network adapter that it
|
|
// binds to.
|
|
// The initialization sets the forward link equal to the back link equal
|
|
// to the list head
|
|
InitializeListHead(&pDeviceContext->UpConnectionInUse);
|
|
InitializeListHead(&pDeviceContext->LowerConnection);
|
|
InitializeListHead(&pDeviceContext->LowerConnFreeHead);
|
|
InitializeListHead(&pDeviceContext->RcvAnyFromAnyHead);
|
|
InitializeListHead(&pDeviceContext->RcvDGAnyFromAnyHead);
|
|
InitializeListHead(&pDeviceContext->PartialRcvHead) ;
|
|
|
|
InitializeListHead(&pDeviceContext->DelayedEvents);
|
|
|
|
//
|
|
// Pick an adapter number that hasn't been used yet
|
|
//
|
|
Adapter = 1;
|
|
for ( pEntry = pConfig->DeviceContexts.Flink;
|
|
pEntry != &pConfig->DeviceContexts;
|
|
pEntry = pEntry->Flink )
|
|
{
|
|
pDevtmp = CONTAINING_RECORD( pEntry, tDEVICECONTEXT, Linkage );
|
|
|
|
if ( !(pDevtmp->AdapterNumber & Adapter) )
|
|
break;
|
|
|
|
Adapter <<= 1;
|
|
}
|
|
|
|
pDeviceContext->AdapterNumber = Adapter ;
|
|
pDeviceContext->IPIndex = IpIndex ;
|
|
NbtConfig.AdapterCount++ ;
|
|
if ( NbtConfig.AdapterCount > 1 )
|
|
{
|
|
NbtConfig.MultiHomed = TRUE ;
|
|
}
|
|
|
|
//
|
|
// Allocate our name table and session table watching for both a
|
|
// minimum and a maximum size.
|
|
//
|
|
|
|
pDeviceContext->cMaxNames = (UCHAR) min( pConfig->lRegistryMaxNames, MAX_NCB_NUMS ) ;
|
|
|
|
pDeviceContext->cMaxSessions = (UCHAR) min( pConfig->lRegistryMaxSessions, MAX_NCB_NUMS ) ;
|
|
|
|
//
|
|
// Add one to the table size for the zeroth element (used for permanent
|
|
// name in the name table). The user accessible table goes from 1 to n
|
|
//
|
|
|
|
if ( !(pDeviceContext->pNameTable = (tCLIENTELE**)
|
|
CTEAllocInitMem((USHORT)((pDeviceContext->cMaxNames+1) * sizeof(tADDRESSELE*)))) ||
|
|
!(pDeviceContext->pSessionTable = (tCONNECTELE**)
|
|
CTEAllocInitMem((pDeviceContext->cMaxSessions+1) * sizeof(tCONNECTELE*))))
|
|
{
|
|
return STATUS_INSUFFICIENT_RESOURCES ;
|
|
}
|
|
|
|
CTEZeroMemory( &pDeviceContext->pNameTable[0],
|
|
(pDeviceContext->cMaxNames+1)*sizeof(tCLIENTELE*)) ;
|
|
CTEZeroMemory( &pDeviceContext->pSessionTable[0],
|
|
(pDeviceContext->cMaxSessions+1)*sizeof(tCONNECTELE*) ) ;
|
|
pDeviceContext->iNcbNum = 1 ;
|
|
pDeviceContext->iLSNum = 1 ;
|
|
|
|
// add this new device context on to the List in the configuration
|
|
// data structure
|
|
InsertTailList(&pConfig->DeviceContexts,&pDeviceContext->Linkage);
|
|
|
|
//
|
|
// IpAddr can be 0 only in wfw case (when dhcp hasn't yet obtained one)
|
|
// (in case of chicago, we will never come this far if ipaddr is 0)
|
|
//
|
|
if (!IpAddr)
|
|
{
|
|
pDeviceContext->IpAddress = 0;
|
|
goto Skip_tdiaddr_init;
|
|
}
|
|
|
|
//
|
|
// open the required address objects with the underlying transport provider
|
|
//
|
|
status = NbtCreateAddressObjects(
|
|
IpAddr,
|
|
IpMask,
|
|
pDeviceContext);
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
KdPrint(("Failed to create the Address Object, status=%lC\n",status));
|
|
return(status);
|
|
}
|
|
|
|
// this call must converse with the transport underneath to create
|
|
// connections and associate them with the session address object
|
|
status = NbtInitConnQ(
|
|
&pDeviceContext->LowerConnFreeHead,
|
|
sizeof(tLOWERCONNECTION),
|
|
NBT_NUM_INITIAL_CONNECTIONS,
|
|
pDeviceContext);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
CDbgPrint( DBGFLAG_ERROR,
|
|
("CreateDeviceObject: NbtInitConnQ Failed!")) ;
|
|
|
|
return(status);
|
|
}
|
|
|
|
//
|
|
// Add the permanent name for this adapter
|
|
//
|
|
status = NbtAddPermanentName( pDeviceContext ) ;
|
|
if ( !NT_SUCCESS( status ))
|
|
{
|
|
return status ;
|
|
}
|
|
|
|
Skip_tdiaddr_init:
|
|
|
|
//
|
|
// ok, we are ready to function! (we are setting this to TRUE even if
|
|
// there is no ipaddr yet (in case of wfw only) so that rdr,srv etc. can
|
|
// add names without error
|
|
//
|
|
pDeviceContext->fDeviceUp = TRUE;
|
|
|
|
#ifndef CHICAGO
|
|
//
|
|
// Set up a DHCP notification for this device in case the IP address
|
|
// changes
|
|
//
|
|
dn.dn_pfnNotifyRoutine = AddrChngNotification ;
|
|
dn.dn_pContext = pDeviceContext ;
|
|
|
|
status = DhcpSetInfo( DHCP_SET_NOTIFY_HANDLER,
|
|
pDeviceContext->IPIndex,
|
|
&dn,
|
|
sizeof( dn )) ;
|
|
if ( status )
|
|
{
|
|
ASSERT(0);
|
|
CDbgPrint( DBGFLAG_ERROR,
|
|
("CreateDeviceObject: Warning - Setting Dhcp notification handler failed")) ;
|
|
}
|
|
#endif //!CHICAGO
|
|
|
|
return(STATUS_SUCCESS);
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: GetDhcpOption
|
|
|
|
SYNOPSIS: Checks to see if the passed .ini parameter is a potential
|
|
DHCP option. If it is, it calls DHCP to get the option.
|
|
|
|
This routine is called when retrieving parameters from
|
|
the .ini file if the parameter is not found.
|
|
|
|
ENTRY: ValueName - String of .ini parameter name
|
|
DefaultValue - Value to return if not a DHCP option or
|
|
DHCP didn't have the option
|
|
|
|
RETURNS: DHCP option value or DefaultValue if an error occurred.
|
|
If the requested parameter is a string option (such as
|
|
scopeid), then a pointer to an allocated string is
|
|
returned.
|
|
|
|
NOTES: Name Server address is handled in GetNameServerAddress
|
|
|
|
HISTORY:
|
|
Johnl 17-Dec-1993 Created
|
|
|
|
********************************************************************/
|
|
|
|
#define OPTION_NETBIOS_SCOPE_OPTION 47
|
|
#define OPTION_NETBIOS_NODE_TYPE 46
|
|
#define OPTION_BROADCAST_ADDRESS 28
|
|
|
|
struct
|
|
{
|
|
PUCHAR pchParamName ;
|
|
ULONG DhcpOptionID ;
|
|
} OptionMapping[] =
|
|
{ { WS_NODE_TYPE, OPTION_NETBIOS_NODE_TYPE },
|
|
{ NBT_SCOPEID, OPTION_NETBIOS_SCOPE_OPTION },
|
|
{ WS_ALLONES_BCAST, OPTION_BROADCAST_ADDRESS }
|
|
} ;
|
|
#define NUM_OPTIONS (sizeof(OptionMapping)/sizeof(OptionMapping[0]))
|
|
|
|
|
|
ULONG GetDhcpOption( PUCHAR ValueName, ULONG DefaultValue )
|
|
{
|
|
int i ;
|
|
ULONG Val ;
|
|
TDI_STATUS tdistatus ;
|
|
ULONG Size ;
|
|
INT OptionId ;
|
|
PUCHAR pStrVal ;
|
|
|
|
CTEPagedCode();
|
|
|
|
//
|
|
// Is this parameter a DHCP option?
|
|
//
|
|
for ( i = 0 ; i < NUM_OPTIONS ; i++ )
|
|
{
|
|
if ( !strcmp( OptionMapping[i].pchParamName, ValueName ))
|
|
goto FoundOption ;
|
|
}
|
|
|
|
return DefaultValue ;
|
|
|
|
FoundOption:
|
|
|
|
switch ( OptionId = OptionMapping[i].DhcpOptionID )
|
|
{
|
|
case OPTION_NETBIOS_SCOPE_OPTION: // String options go here
|
|
|
|
//
|
|
// Get the size of the string resource, then get the option
|
|
//
|
|
|
|
Size = MAX_SCOPE_LENGTH+1 ;
|
|
pStrVal = CTEAllocInitMem( Size );
|
|
if (pStrVal == NULL)
|
|
{
|
|
DbgPrint("GetDhcpOption: failed to allocate memory") ;
|
|
return 0 ;
|
|
}
|
|
|
|
tdistatus = DhcpQueryOption( CurrentIP,
|
|
OptionId,
|
|
pStrVal,
|
|
&Size ) ;
|
|
|
|
if ( tdistatus == TDI_SUCCESS )
|
|
{
|
|
DbgPrint("GetDhcpOption: Successfully retrieved option ID ") ;
|
|
DbgPrintNum( OptionId ) ; DbgPrint("\r\n") ;
|
|
return (ULONG) pStrVal ;
|
|
}
|
|
else
|
|
{
|
|
DbgPrint("GetDhcpOption: returned error = 0x ") ;
|
|
DbgPrintNum( tdistatus ) ; DbgPrint("\r\n") ;
|
|
CTEMemFree( pStrVal ) ;
|
|
return 0 ;
|
|
}
|
|
|
|
default: // ULONG options go here
|
|
Size = sizeof( Val ) ;
|
|
tdistatus = DhcpQueryOption( CurrentIP,
|
|
OptionId,
|
|
&Val,
|
|
&Size ) ;
|
|
break ;
|
|
}
|
|
|
|
switch ( tdistatus )
|
|
{
|
|
case TDI_SUCCESS:
|
|
case TDI_BUFFER_OVERFLOW: // May be more then one, only take the 1st
|
|
DbgPrint("GetDhcpOption: Successfully retrieved option ID ") ;
|
|
DbgPrintNum( OptionId ) ; DbgPrint("\r\n") ;
|
|
return Val ;
|
|
|
|
case TDI_INVALID_PARAMETER: // Option not found
|
|
DbgPrint("GetDhcpOption: Failed to retrieve option ID ") ;
|
|
DbgPrintNum( OptionId ) ; DbgPrint("\r\n") ;
|
|
return DefaultValue ;
|
|
|
|
default:
|
|
ASSERT( FALSE ) ;
|
|
break ;
|
|
}
|
|
|
|
return DefaultValue ;
|
|
}
|
|
|
|
#ifndef CHICAGO
|
|
#pragma END_INIT
|
|
#endif
|
|
|
|
|