/*++
*******************************************************************************
* Copyright (c) 1990-99 Digi International Inc., All Rights Reserved				*
* 																										*
* This software contains proprietary and confidential information of Digi		*
* International Inc.  By accepting transfer of this copy, Recipient agrees		*
* to retain this software in confidence, to prevent disclosure to others,		*
* and to make no use of this software other than that for which it was			*
* delivered.  This is an unpublished copyrighted work of Digi International	*
* Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly	*
* prohibited.																						*
* 																										*
* Restricted Rights Legend																		*
*																										*
* Use, duplication, or disclosure by the Government is subject to					*
* restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in			*
* Technical Data and Computer Software clause at DFARS 252.227-7031 or			*
* subparagraphs (c)(1) and (2) of the Commercial Computer Software -				*
* Restricted Rights at 48 CFR 52.227-19, as applicable.								*
*																										*
* Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343				*
*																										*
*******************************************************************************

Module Name:

   digiisdn.c

Abstract:

	This driver is an ndis wan miniport supporting ISDN calls on both BRI and PRI 
	lines.  Firmware support is included for both version 1 (implemented on DataFire 
	PRIme adapter) and version 2 (implemented on dense adapters) of the Spider ISDN API.

   This module contains required NT kernelmode driver entry and unload routines.  
   Also, any driver global driver.

Author:

   Michael Zarns

--*/

#include "digiisdn.h"

#if NT5_BUILD
// Don't use MEMPRINT in 5.0 yet, due to MS bugs in registering Shutdown handler to 
// stop our memprint thread!
#else
#define ISDN_USE_MEMPRINT
#endif

// Global pointer to driver object.  Set by DriverEntry, used for event logging.
PDRIVER_OBJECT gpDriverObject = NULL;

// Set nonzero to force DriverEntry to return failure, causing driver to be unloaded.
STATIC ULONG DigiDontLoadDriver = FALSE;

// Set nonzero to enable event logging of calls.
STATIC ULONG gfCallLogging;

// NdisWan wrapper handle.  Received from Ndis by InitializeWrapper (DriverEntry), 
// used for RegisterMiniport (DriverEntry), and TerminateWrapper (MinportHalt).
NDIS_HANDLE ghWrapper;


VOID
DriverUnload(
	IN PDRIVER_OBJECT pDriverObject )
/*++

Description:

	Last chance to cleanup before driver is unloaded.  Everything allocated or started 
	in DriverEntry or otherwise should be freed, destroyed or stopped before returning 
	from DriverUnload.

--*/
{
	UNREFERENCED_PARAMETER( pDriverObject );
	DigiDump( DIGIINIT, ( "ISDN!DriverUnload\n" ) );

#ifdef ISDN_USE_MEMPRINT
	MemPrintQuit();
#endif

	DigiDisplayMemoryLeaks();
}


// DriverEntry can be discarded after initialization
NTSTATUS DriverEntry( IN PDRIVER_OBJECT  pDriverObject,
                      IN PUNICODE_STRING pRegistryPath );
#pragma alloc_text( INIT, DriverEntry )


NTSTATUS
DriverEntry(
	IN PDRIVER_OBJECT pDriverObject, 
	IN PUNICODE_STRING pRegistryPath )
/*++

Description:

	Driver main entrypoint.  NT calls this routine when first loading the driver.

Parameters:

	pDriverObject
		Driver object defines the driver entrypoints, etc.

	pRegistryPath
		Complete path to driver registry key.  Driver global config params are stored 
		here.  i.e. \Registry\System\ControlSet001\DigiIsdn.  

Return Value:

	STATUS_SUCCESS or error.

--*/
{
	NTSTATUS Status;

	DigiInitMem( 'ndsI' );

#ifdef ISDN_USE_MEMPRINT
	MemPrintInitialize( "\\SystemRoot\\digiisdn.log" );
#endif

	DigiDebugInit( pRegistryPath, DIGIERROR|DIGIWARN|DIGITAPIOID|DIGIWANOID|DIGILANOID|DIGISTATE|DIGICALL|DIGIMP|DIGIINIT, DEBUGMODE_CONSOLE );
//	DigiDebugInit( pRegistryPath, DIGIERROR|DIGIWARN, DEBUGMODE_CONSOLE );
#if DBG
	(void)DbgPrint( "\nISDN!DriverEntry:\n"
	                      "   gDebugMask         = 0x%x\n"
	                      "   gDebugMode         = 0x%x\n"
	                      "   DigiDontLoadDriver = 0x%x\n\n",
	                      &gDebugMask, &gDebugMode, &DigiDontLoadDriver );
#endif
   gpDriverObject = pDriverObject;

	if ( DigiDbgBreakOnEntryEnabled() )
		DbgBreakPoint();
	if ( DigiDontLoadDriver )
	{
		Status = STATUS_CANCELLED;
		goto Exit;
	}

	NdisMInitializeWrapper( &ghWrapper, pDriverObject, pRegistryPath, NULL );

	{
		// Common fields
		NDIS_MINIPORT_CHARACTERISTICS Characteristics = {0};
		Characteristics.InitializeHandler       = IsdnInitialize;
		Characteristics.HaltHandler             = IsdnHalt;
		Characteristics.QueryInformationHandler = IsdnQueryInfo;
		Characteristics.SetInformationHandler   = IsdnSetInfo;

//#define ISDN_CONDIS
#if NT5_BUILD && defined(ISDN_CONDIS)
#pragma message( "\nBuilding NT5 NDIS5 CoNdis miniport!\n" )
		// NDIS 5 fields
		Characteristics.MajorNdisVersion      = 5;	// NT5: we're an NDIS 5.0 CoNdis driver
		Characteristics.CoCreateVcHandler     = IsdnCoCreateVc;
		Characteristics.CoDeleteVcHandler     = IsdnCoDeleteVc;
		Characteristics.CoActivateVcHandler   = IsdnCoActivateVc;
		Characteristics.CoDeactivateVcHandler = IsdnCoDeactivateVc;
		Characteristics.CoSendPacketsHandler  = IsdnCoSendPackets;
		Characteristics.CoRequestHandler      = IsdnCoRequest;
#else
		// NDIS 3 or 4 specific fields
#ifdef NDIS40_MINIPORT
#pragma message( "\nBuilding NDIS4 miniport!\n" )
		Characteristics.MajorNdisVersion    = 4;	// NT4: we're an NDIS 4.0 wan miniport driver
#else
#pragma message( "\nBuilding NDIS3 miniport!\n" )
		Characteristics.MajorNdisVersion    = 3;	// NT4: we're an NDIS 3.0 wan miniport driver
#endif

		Characteristics.Reserved            = NDIS_USE_WAN_WRAPPER;
		Characteristics.WanSendHandler      = IsdnSend;
		Characteristics.CheckForHangHandler = IsdnCheckForHang;
		Characteristics.ResetHandler        = IsdnReset;

#endif
		Status = NdisMRegisterMiniport( ghWrapper, &Characteristics, sizeof Characteristics );
	}

Exit:

	DigiDump( DIGIINIT, ( "ISDN!DriverEntry: Leave, status 0x%08x\n", Status ) );

	if ( NT_ERROR( Status ) )
	{
		MemPrintQuit();
		DigiDisplayMemoryLeaks();
	}

	return Status;
}
