windows-nt/Source/XPSP1/NT/net/rras/ipx/ipxwan/adptmgr.c
2020-09-26 16:20:57 +08:00

320 lines
5.4 KiB
C

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
adptmgr.c
Abstract:
This module contains the adapter management functions
Author:
Stefan Solomon 12/02/1996
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
#define ADAPTER_INDEX_HASH_TABLE_SIZE 32
#define adpthashindex(AdapterIndex) (AdapterIndex) % ADAPTER_INDEX_HASH_TABLE_SIZE
LIST_ENTRY AdapterHT[ADAPTER_INDEX_HASH_TABLE_SIZE];
LIST_ENTRY DiscardedAdaptersList;
HANDLE AdapterConfigPortHandle;
VOID
CreateAdapter(ULONG AdapterIndex,
PADAPTER_INFO AdapterInfo);
VOID
DeleteAdapter(ULONG AdapterIndex);
/*++
Function: StartAdapterManager
Descr: opens the IPX stack notification port for ipxwan
--*/
DWORD
StartAdapterManager(VOID)
{
ADAPTERS_GLOBAL_PARAMETERS AdptGlobalParameters;
DWORD rc, i;
Trace(ADAPTER_TRACE, "StartAdapterManager: Entered\n");
// create adapter config port
if((AdapterConfigPortHandle = IpxWanCreateAdapterConfigurationPort(
hWaitableObject[ADAPTER_NOTIFICATION_EVENT],
&AdptGlobalParameters)) == INVALID_HANDLE_VALUE) {
// can't create config port
return ERROR_CAN_NOT_COMPLETE;
}
// create adapters hash table
for(i=0; i<ADAPTER_INDEX_HASH_TABLE_SIZE; i++) {
InitializeListHead(&AdapterHT[i]);
}
// create discarded adapters list
InitializeListHead(&DiscardedAdaptersList);
return NO_ERROR;
}
/*++
Function: AddToAdapterHt
Descr: Adds the adapter control block to the hash table of adapters
Remark: >> called with database lock held <<
--*/
VOID
AddToAdapterHt(PACB acbp)
{
int hv;
PLIST_ENTRY lep;
PACB list_acbp;
// insert in index hash table
hv = adpthashindex(acbp->AdapterIndex);
InsertTailList(&AdapterHT[hv], &acbp->Linkage);
}
/*++
Function: RemoveFromAdapterHt
Descr:
Remark: >> called with database lock held <<
--*/
VOID
RemoveFromAdapterHt(PACB acbp)
{
RemoveEntryList(&acbp->Linkage);
}
/*++
Function: GetAdapterByIndex
Descr:
Remark: >> called with database lock held <<
--*/
PACB
GetAdapterByIndex(ULONG AdptIndex)
{
PACB acbp;
PLIST_ENTRY lep;
int hv;
hv = adpthashindex(AdptIndex);
lep = AdapterHT[hv].Flink;
while(lep != &AdapterHT[hv])
{
acbp = CONTAINING_RECORD(lep, ACB, Linkage);
if (acbp->AdapterIndex == AdptIndex) {
return acbp;
}
lep = acbp->Linkage.Flink;
}
return NULL;
}
/*++
Function: StopAdapterManager
Descr: Closes the IPX notification port
--*/
VOID
StopAdapterManager(VOID)
{
DWORD rc;
ULONG AdapterIndex;
Trace(ADAPTER_TRACE, "StopAdapterManager: Entered\n");
// Close the IPX stack notification port
IpxDeleteAdapterConfigurationPort(AdapterConfigPortHandle);
}
/*++
Function: AdapterNotification
Descr: Processes adapter notification events
--*/
VOID
AdapterNotification(VOID)
{
ADAPTER_INFO AdapterInfo;
ULONG AdapterIndex;
ULONG AdapterConfigurationStatus;
ULONG AdapterNameSize;
LPWSTR AdapterNameBuffer;
DWORD rc;
Trace(ADAPTER_TRACE, "AdapterNotification: Entered\n");
while((rc = IpxGetQueuedAdapterConfigurationStatus(
AdapterConfigPortHandle,
&AdapterIndex,
&AdapterConfigurationStatus,
&AdapterInfo)) == NO_ERROR) {
switch(AdapterConfigurationStatus) {
case ADAPTER_CREATED:
// got the adapter name, create the adapter
CreateAdapter(AdapterIndex,
&AdapterInfo);
break;
case ADAPTER_DELETED:
DeleteAdapter(AdapterIndex);
break;
default:
SS_ASSERT(FALSE);
break;
}
}
}
/*++
Function: CreateAdapter
Descr:
--*/
VOID
CreateAdapter(ULONG AdapterIndex,
PADAPTER_INFO AdapterInfo)
{
PACB acbp;
Trace(ADAPTER_TRACE, "CreateAdapter: Entered for adpt# %d", AdapterIndex);
if((acbp = (PACB)GlobalAlloc(GPTR, sizeof(ACB))) == NULL) {
Trace(ADAPTER_TRACE, "CreateAdapter: Cannot allocate adapter control block\n");
IpxcpConfigDone(AdapterInfo->ConnectionId,
NULL,
NULL,
NULL,
FALSE);
return;
}
ACQUIRE_DATABASE_LOCK;
acbp->AdapterIndex = AdapterIndex;
acbp->ConnectionId = AdapterInfo->ConnectionId;
acbp->Discarded = FALSE;
InitializeCriticalSection(&acbp->AdapterLock);
AddToAdapterHt(acbp);
ACQUIRE_ADAPTER_LOCK(acbp);
RELEASE_DATABASE_LOCK;
// initialize and start the protocol negotiation on this adapter
StartIpxwanProtocol(acbp);
RELEASE_ADAPTER_LOCK(acbp);
}
/*++
Function: DeleteAdapter
Descr:
Remark: If adapter gets deleted IPXCP is also informed by PPP that
the connection has been terminated.
--*/
VOID
DeleteAdapter(ULONG AdapterIndex)
{
PACB acbp;
ACQUIRE_DATABASE_LOCK;
if((acbp = GetAdapterByIndex(AdapterIndex)) == NULL) {
RELEASE_DATABASE_LOCK;
return;
}
Trace(ADAPTER_TRACE, "DeleteAdapter: Entered for adpt# %d", AdapterIndex);
ACQUIRE_ADAPTER_LOCK(acbp);
StopIpxwanProtocol(acbp);
RemoveFromAdapterHt(acbp);
if(acbp->RefCount) {
InsertTailList(&DiscardedAdaptersList, &acbp->Linkage);
acbp->Discarded = TRUE;
Trace(ADAPTER_TRACE, "DeleteAdapter: adpt# %d still referenced, inserted in discarded list", AdapterIndex);
RELEASE_ADAPTER_LOCK(acbp);
}
else
{
DeleteCriticalSection(&acbp->AdapterLock);
Trace(ADAPTER_TRACE, "DeleteAdapter: adpt# %d not referenced, free CB", AdapterIndex);
GlobalFree(acbp);
}
RELEASE_DATABASE_LOCK;
}