|
|
/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
autodial.c
Abstract:
NT specific routines for interfacing with the RAS AutoDial driver (rasacd.sys).
Author:
Anthony Discolo (adiscolo) Aug 30, 1995
Revision History:
Who When What -------- -------- ---------------------------------------------- adiscolo 08-30-95 created
Notes:
--*/
#include "precomp.h"
#pragma hdrstop
#ifdef RASAUTODIAL
#include <acd.h>
#include <acdapi.h>
//
// Global variables
//
BOOLEAN fAcdLoadedG; ACD_DRIVER AcdDriverG; ULONG ulDriverIdG = 'Nbi ';
VOID NbiRetryTdiConnect( IN BOOLEAN fSuccess, IN PVOID *pArgs )
/*++
Routine Description:
This routine is called indirectly by the automatic connection driver to continue the connection process after an automatic connection has been made.
Arguments:
fSuccess - TRUE if the connection attempt was successful.
pArgs - a pointer to the argument vector
Return Value:
None.
--*/
{ NTSTATUS status; PDEVICE pDevice = pArgs[0]; PCONNECTION pConnection = pArgs[1]; PREQUEST pRequest = pArgs[2]; CTELockHandle ConnectionLH, DeviceLH; CTELockHandle CancelLH; BOOLEAN bLockFreed = FALSE;
//
// Check that the connection is valid. This references
// the connection.
//
#if notdef // DBG
DbgPrint("NbiRetryTdiConnect: fSuccess=%d, pConnection=0x%x\n", fSuccess, pConnection); #endif
status = NbiVerifyConnection(pConnection); if (!NT_SUCCESS(status)) { DbgPrint( "NbiRetryTdiConnect: NbiVerifyConnection failed on connection 0x%x (status=0x%x)\n", pConnection, status); return; }
NB_GET_CANCEL_LOCK( &CancelLH ); NB_GET_LOCK (&pConnection->Lock, &ConnectionLH); NB_GET_LOCK (&pDevice->Lock, &DeviceLH);
#if notdef // DBG
DbgPrint( "NbiRetryTdiConnect: AddressFile=0x%x, DisassociatePending=0x%x, ClosePending=0x%x\n", pConnection->AddressFile, pConnection->DisassociatePending, pConnection->ClosePending); #endif
if ((pConnection->AddressFile != NULL) && (pConnection->AddressFile != (PVOID)-1) && (pConnection->DisassociatePending == NULL) && (pConnection->ClosePending == NULL)) { NbiReferenceConnectionLock(pConnection, CREF_CONNECT); //
// Clear the AUTOCONNECTING flag since we
// done with the automatic connection attempt.
// Set the AUTOCONNECTED flag to prevent us
// from attempting an automatic connection
// for this connection again.
//
pConnection->Flags &= ~CONNECTION_FLAGS_AUTOCONNECTING; pConnection->Flags |= CONNECTION_FLAGS_AUTOCONNECTED;
pConnection->State = CONNECTION_STATE_CONNECTING; pConnection->Retries = pDevice->ConnectionCount; status = NbiTdiConnectFindName( pDevice, pRequest, pConnection, CancelLH, ConnectionLH, DeviceLH, &bLockFreed); } else { DbgPrint("NbiRetryTdiConnect: Connect on invalid connection 0x%x\n", pConnection);
pConnection->SubState = CONNECTION_SUBSTATE_C_DISCONN; NB_FREE_LOCK (&pDevice->Lock, DeviceLH); status = STATUS_INVALID_CONNECTION; } if (!bLockFreed) { NB_FREE_LOCK (&pConnection->Lock, ConnectionLH); NB_FREE_CANCEL_LOCK(CancelLH); } //
// Complete the irp if necessary.
//
if (status != STATUS_PENDING) { REQUEST_INFORMATION(pRequest) = 0; REQUEST_STATUS(pRequest) = status;
NbiCompleteRequest(pRequest); NbiFreeRequest(pDevice, pRequest); } NbiDereferenceConnection(pConnection, CREF_VERIFY); } /* NbiRetryTdiConnect */
BOOLEAN NbiCancelAutoDialRequest( IN PVOID pArg, IN ULONG ulFlags, IN ACD_CONNECT_CALLBACK pProc, IN USHORT nArgs, IN PVOID *pArgs ) { #if notdef // DBG
DbgPrint("NbiCancelAutodialRequest: pArg=0x%x\n", pArg); #endif
if (nArgs != 2) return FALSE;
return (pArgs[1] == pArg); } // NbiCancelAutoDialRequest
BOOLEAN NbiCancelTdiConnect( IN PDEVICE pDevice, IN PREQUEST pRequest, IN PCONNECTION pConnection )
/*++
DESCRIPTION This routine is called by the I/O system to cancel a connection when we are attempting to restore an automatic connection.
ARGUMENTS pDevice: a pointer to the device object for this driver
pRequest: a pointer to the irp to be cancelled
pConnection: a pointer to the connnection to be cancelled
RETURN VALUE TRUE if the request was canceled; FALSE otherwise.
--*/
{ ACD_ADDR addr;
//
// Get the address of the connection.
//
addr.fType = ACD_ADDR_NB; RtlCopyMemory(&addr.cNetbios, pConnection->RemoteName, 16); #ifdef notdef // DBG
DbgPrint( "NbiCancelTdiConnect: pIrp=0x%x, RemoteName=%-15.15s, pConnection=0x%x\n", pRequest, addr.cNetbios, pConnection); #endif
//
// Cancel the autodial request.
//
return (*AcdDriverG.lpfnCancelConnection)( ulDriverIdG, &addr, NbiCancelAutoDialRequest, pConnection); } // NbiCancelTdiConnect
BOOLEAN NbiAttemptAutoDial( IN PDEVICE pDevice, IN PCONNECTION pConnection, IN ULONG ulFlags, IN ACD_CONNECT_CALLBACK pProc, IN PREQUEST pRequest )
/*++
Routine Description:
Call the automatic connection driver to attempt an automatic connection.
Arguments:
pDevice - a pointer to the DEVICE structure for this connection
pConnection - a pointer to the CONNECTION block for this connection
ulFlags - connection flags to pass to the automatic connection driver
pProc - a callback procedure when the automatic connection completes
pRequest - a pointer to the request irp
Return Value:
TRUE if the automatic connection was started successfully, FALSE otherwise.
--*/
{ ACD_ADDR addr; PVOID pArgs[3]; BOOLEAN bSuccess;
//
// If we've already attempted an automatic connection
// on this connection, don't try it again.
//
if (pConnection->Flags & CONNECTION_FLAGS_AUTOCONNECTED) return FALSE; //
// Get the address of the connection.
//
addr.fType = ACD_ADDR_NB; RtlCopyMemory(&addr.cNetbios, pConnection->RemoteName, 16); #ifdef notdef // DBG
DbgPrint("NbiAttemptAutoDial: szAddr=%15.15s\n", addr.cNetbios); #endif
//
// Attempt to start the connection.
// NbiRetryTdiConnect() will be called
// when the connection process has completed.
//
pArgs[0] = pDevice; pArgs[1] = pConnection; pArgs[2] = pRequest; bSuccess = (*AcdDriverG.lpfnStartConnection)( ulDriverIdG, &addr, ulFlags, pProc, 3, pArgs); if (bSuccess) { //
// Set the AUTOCONNECTING flag so we know
// to also cancel the connection in the
// automatic connection driver if this
// request gets canceled.
//
pConnection->Flags |= CONNECTION_FLAGS_AUTOCONNECTING; }
return bSuccess;
} // NbiAttemptAutoDial
VOID NbiNoteNewConnection( IN PCONNECTION pConnection ) { NTSTATUS status; ACD_ADDR addr; ACD_ADAPTER adapter; ULONG i; TDI_ADDRESS_IPX tdiIpxAddress;
addr.fType = ACD_ADDR_NB; RtlCopyMemory(&addr.cNetbios, pConnection->RemoteName, 16); //
// Determine the mac address of the adapter
// over which the connection has been made.
//
status = (pConnection->Device->Bind.QueryHandler)( IPX_QUERY_IPX_ADDRESS, #if defined(_PNP_POWER)
&pConnection->LocalTarget.NicHandle, #else
pConnection->LocalTarget.NicId, #endif _PNP_POWER
&tdiIpxAddress, sizeof(TDI_ADDRESS_IPX), NULL); if (status != STATUS_SUCCESS) { #if notdef // DBG
DbgPrint("NbiNoteNewConnection: QueryHandler(IPX_QUERY_IPX_ADDRESS) failed (status=0x%x)\n", status); return; #endif
} //
// Copy the source mac address to identify
// the adapter.
//
adapter.fType = ACD_ADAPTER_MAC; for (i = 0; i < 6; i++) adapter.cMac[i] = tdiIpxAddress.NodeAddress[i]; #if notdef // DBG
DbgPrint( "NbiNoteNewConnection: address=%-15.15s, remote mac=%02x:%02x:%02x:%02x:%02x:%02x\n", addr.cNetbios, adapter.cMac[0], adapter.cMac[1], adapter.cMac[2], adapter.cMac[3], adapter.cMac[4], adapter.cMac[5]); #endif
//
// Simply notify the automatic connection driver
// that a successful connection has been made.
//
(*AcdDriverG.lpfnNewConnection)( &addr, &adapter); } // NbiNoteNewConnection
VOID NbiAcdBind() { NTSTATUS status; UNICODE_STRING nameString; IO_STATUS_BLOCK ioStatusBlock; PIRP pIrp; PFILE_OBJECT pAcdFileObject; PDEVICE_OBJECT pAcdDeviceObject; PACD_DRIVER pDriver = &AcdDriverG;
//
// Initialize the name of the automatic
// connection device.
//
RtlInitUnicodeString(&nameString, ACD_DEVICE_NAME); //
// Get the file and device objects for the
// device.
//
status = IoGetDeviceObjectPointer( &nameString, SYNCHRONIZE|GENERIC_READ|GENERIC_WRITE, &pAcdFileObject, &pAcdDeviceObject); if (status != STATUS_SUCCESS) return; //
// Reference the device object.
//
ObReferenceObject(pAcdDeviceObject); //
// Remove the reference IoGetDeviceObjectPointer()
// put on the file object.
//
ObDereferenceObject(pAcdFileObject); //
// Initialize our part of the ACD_DRIVER
// structure.
//
KeInitializeSpinLock(&AcdDriverG.SpinLock); AcdDriverG.ulDriverId = ulDriverIdG; AcdDriverG.fEnabled = FALSE; //
// Build a request to get the automatic
// connection driver entry points.
//
pIrp = IoBuildDeviceIoControlRequest( IOCTL_INTERNAL_ACD_BIND, pAcdDeviceObject, (PVOID)&pDriver, sizeof (pDriver), NULL, 0, TRUE, NULL, &ioStatusBlock); if (pIrp == NULL) { ObDereferenceObject(pAcdDeviceObject); return; } //
// Submit the request to the
// automatic connection driver.
//
status = IoCallDriver(pAcdDeviceObject, pIrp); fAcdLoadedG = (status == STATUS_SUCCESS); //
// Close the device.
//
ObDereferenceObject(pAcdDeviceObject); } // NbiAcdBind
VOID NbiAcdUnbind() { NTSTATUS status; UNICODE_STRING nameString; IO_STATUS_BLOCK ioStatusBlock; PIRP pIrp; PFILE_OBJECT pAcdFileObject; PDEVICE_OBJECT pAcdDeviceObject; PACD_DRIVER pDriver = &AcdDriverG;
//
// Don't bother to unbind if we
// didn't successfully bind in the
// first place.
//
if (!fAcdLoadedG) return; //
// Initialize the name of the automatic
// connection device.
//
RtlInitUnicodeString(&nameString, ACD_DEVICE_NAME); //
// Get the file and device objects for the
// device.
//
status = IoGetDeviceObjectPointer( &nameString, SYNCHRONIZE|GENERIC_READ|GENERIC_WRITE, &pAcdFileObject, &pAcdDeviceObject); if (status != STATUS_SUCCESS) return; //
// Reference the device object.
//
ObReferenceObject(pAcdDeviceObject); //
// Remove the reference IoGetDeviceObjectPointer()
// put on the file object.
//
ObDereferenceObject(pAcdFileObject); //
// Build a request to unbind from
// the automatic connection driver.
//
pIrp = IoBuildDeviceIoControlRequest( IOCTL_INTERNAL_ACD_UNBIND, pAcdDeviceObject, (PVOID)&pDriver, sizeof (pDriver), NULL, 0, TRUE, NULL, &ioStatusBlock); if (pIrp == NULL) { ObDereferenceObject(pAcdDeviceObject); return; } //
// Submit the request to the
// automatic connection driver.
//
status = IoCallDriver(pAcdDeviceObject, pIrp); //
// Close the device.
//
ObDereferenceObject(pAcdDeviceObject); } // NbiAcdUnbind
#endif // RASAUTODIAL
|