224 lines
5.2 KiB
C
224 lines
5.2 KiB
C
|
/*++
|
||
|
|
||
|
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;
|
||
|
}
|