mirror of https://github.com/tongzx/nt5src
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.
223 lines
5.2 KiB
223 lines
5.2 KiB
/*++
|
|
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
connreq.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the connection request handling functions
|
|
|
|
Author:
|
|
|
|
Stefan Solomon 04/19/1995
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
|
|
VOID
|
|
DoConnectInterface(PVOID InterfaceIndex);
|
|
|
|
/*++
|
|
|
|
Function: ForwarderNotification
|
|
|
|
Descr: This is invoked in the router manager worker thread context
|
|
following a notification from the forwarder. It dequeues all
|
|
connection requests and calls DDM for each one of them.
|
|
|
|
--*/
|
|
|
|
VOID
|
|
ForwarderNotification(VOID)
|
|
{
|
|
DWORD rc;
|
|
PICB icbp;
|
|
HANDLE hDIMInterface;
|
|
ULONG nBytes = 0;
|
|
|
|
// Check if the signaled notification is valid or an error condition
|
|
rc = FwGetNotificationResult(&ConnReqOverlapped, &nBytes);
|
|
|
|
ACQUIRE_DATABASE_LOCK;
|
|
if (RouterOperState == OPER_STATE_UP) {
|
|
if(rc == NO_ERROR) {
|
|
if (((icbp = GetInterfaceByIndex(ConnRequest->IfIndex)) != NULL)
|
|
&& !icbp->ConnectionRequestPending) {
|
|
IF_LOG (EVENTLOG_INFORMATION_TYPE) {
|
|
WCHAR ByteCount[16];
|
|
LPWSTR StrArray[2]= {icbp->InterfaceNamep, ByteCount};
|
|
|
|
_ultow (nBytes-FIELD_OFFSET (FW_DIAL_REQUEST, Packet),
|
|
ByteCount, 10);
|
|
RouterLogInformationDataW (RMEventLogHdl,
|
|
ROUTERLOG_IPX_DEMAND_DIAL_PACKET,
|
|
2, StrArray,
|
|
nBytes-FIELD_OFFSET (FW_DIAL_REQUEST, Packet),
|
|
&ConnRequest->Packet[0]);
|
|
}
|
|
|
|
icbp->ConnectionRequestPending = TRUE;
|
|
if(RtlQueueWorkItem(DoConnectInterface, (PVOID)ConnRequest, 0) == STATUS_SUCCESS) {
|
|
|
|
// work item queued
|
|
WorkItemsPendingCounter++;
|
|
}
|
|
else
|
|
{
|
|
SS_ASSERT(FALSE);
|
|
}
|
|
ConnRequest = (PFW_DIAL_REQUEST)GlobalAlloc (GPTR, DIAL_REQUEST_BUFFER_SIZE);
|
|
if (ConnRequest==NULL) {
|
|
rc = GetLastError ();
|
|
Trace(CONNREQ_TRACE, "Cannot allocate Connecttion Request buffer, rc = %d\n", rc);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
Trace(CONNREQ_TRACE, "Error %d in FwGetNotificationResult\n", rc);
|
|
}
|
|
// now repost the IOCtl
|
|
if (ConnRequest!=NULL) {
|
|
rc = FwNotifyConnectionRequest(ConnRequest,
|
|
DIAL_REQUEST_BUFFER_SIZE,
|
|
&ConnReqOverlapped);
|
|
|
|
if(rc != NO_ERROR) {
|
|
GlobalFree (ConnRequest);
|
|
ConnRequest = NULL;
|
|
Trace(CONNREQ_TRACE, "Cannot repost the FwNotifyConnecttionRequest, rc = %d\n", rc);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
GlobalFree (ConnRequest);
|
|
}
|
|
RELEASE_DATABASE_LOCK;
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
DoConnectInterface(PVOID param)
|
|
{
|
|
#define connRequest ((PFW_DIAL_REQUEST)param)
|
|
PICB icbp;
|
|
HANDLE hDIMInterface;
|
|
DWORD rc;
|
|
|
|
|
|
ACQUIRE_DATABASE_LOCK;
|
|
|
|
if(RouterOperState != OPER_STATE_UP) {
|
|
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
if ((icbp = GetInterfaceByIndex(connRequest->IfIndex)) == NULL){
|
|
goto Exit;
|
|
}
|
|
|
|
hDIMInterface = icbp->hDIMInterface;
|
|
|
|
RELEASE_DATABASE_LOCK;
|
|
|
|
|
|
rc = (*ConnectInterface)(hDIMInterface, PID_IPX);
|
|
|
|
ACQUIRE_DATABASE_LOCK;
|
|
|
|
if((icbp = GetInterfaceByIndex(connRequest->IfIndex)) == NULL) {
|
|
|
|
goto Exit;
|
|
}
|
|
|
|
if (rc != PENDING) {
|
|
icbp->ConnectionRequestPending = FALSE;
|
|
|
|
// check if we failed right away
|
|
if(rc != NO_ERROR) {
|
|
|
|
// failed to request connection
|
|
Trace(CONNREQ_TRACE, "DoConnectInterface: ConnectInterface failed with rc= 0x%x for if # %d\n",
|
|
rc, connRequest->IfIndex);
|
|
|
|
FwConnectionRequestFailed(connRequest->IfIndex);
|
|
}
|
|
else
|
|
{
|
|
// Connection request has been succesfull right away and
|
|
// we will get notified via the connected adapter
|
|
Trace(CONNREQ_TRACE, "DoConnectInterface: ConnectInterface successful -> CONNECTED for if # %d\n",
|
|
connRequest->IfIndex);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// a connection request is pending
|
|
|
|
Trace(CONNREQ_TRACE, "DoConnectInterface: Connection request PENDING for if # %d\n",
|
|
connRequest->IfIndex);
|
|
|
|
}
|
|
|
|
Exit:
|
|
GlobalFree (connRequest);
|
|
WorkItemsPendingCounter--;
|
|
|
|
RELEASE_DATABASE_LOCK;
|
|
#undef connRequest
|
|
}
|
|
|
|
DWORD
|
|
RoutingProtocolConnectionRequest(ULONG ProtocolId,
|
|
ULONG InterfaceIndex)
|
|
{
|
|
PICB icbp;
|
|
HANDLE hDIMInterface;
|
|
DWORD rc;
|
|
|
|
ACQUIRE_DATABASE_LOCK;
|
|
|
|
if((icbp = GetInterfaceByIndex(InterfaceIndex)) == NULL) {
|
|
|
|
RELEASE_DATABASE_LOCK;
|
|
|
|
return ERROR_CAN_NOT_COMPLETE;
|
|
}
|
|
|
|
if (icbp->ConnectionRequestPending) {
|
|
RELEASE_DATABASE_LOCK;
|
|
|
|
return PENDING;
|
|
}
|
|
|
|
// ask DDM to make a connection for this interface
|
|
hDIMInterface = icbp->hDIMInterface;
|
|
icbp->ConnectionRequestPending = TRUE;
|
|
|
|
RELEASE_DATABASE_LOCK;
|
|
|
|
rc = (*ConnectInterface)(hDIMInterface, PID_IPX);
|
|
ACQUIRE_DATABASE_LOCK;
|
|
|
|
if((icbp = GetInterfaceByIndex(InterfaceIndex)) == NULL) {
|
|
RELEASE_DATABASE_LOCK;
|
|
|
|
return ERROR_CAN_NOT_COMPLETE;
|
|
}
|
|
|
|
if (rc != PENDING)
|
|
icbp->ConnectionRequestPending = FALSE;
|
|
RELEASE_DATABASE_LOCK;
|
|
|
|
return rc;
|
|
}
|