/*++

*******************************************************************************
* Copyright (c) 1994-95 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 copyright work  Digi   International *
* Inc.    Except   as   permitted   by  federal  law,  17 USC 117, copying is *
* strictly prohibited.                                                        *
*                                                                             *
* Digi  International  Inc.  CONFIDENTIAL  -   (Digi    International    Inc. *
* Confidential  when   combined   with   the   aggregated  modules  for  this *
* product) OBJECT CODE ONLY SOURCE MATERIALS                                  *
*                                                                             *
* (C) COPYRIGHT Digi International Inc. 1994-95                               *
*                                                                             *
* All Rights Reserved                                                         *
*                                                                             *
* US   Government   Users   Restricted   Rights   -   Use,   duplication   or *
* disclosure  restricted by GSA ADP Schedule Contract with Digi International *
* Inc.                                                                        *
*                                                                             *
*******************************************************************************

Module Name:

   setquery.c

Abstract:

   This module contains routines to handle SetInformation and QueryInformation
	calls from Ndis.

Author:

   Michael Zarns

Revision History:

   $Log: /Components/Windows/NT/Sync/Lan/SETQUERY.C $
 * 
 * 2     12/06/96 2:26p Mikez
 * Fixed uninitialized return code for the OID_802_3_MULTICAST_LIST Set
 * Request, which caused NBF in NT 4.0 to fail to bind to our adapter.
 * 
 * 1     8/05/96 2:14p Mikez
 * 
 * 1     3/11/96 3:16p Mikez
 * Revision 1.2  1995/08/23  07:47:52  mikez
 * Fixed IP routing by adding ARP spoofing.  Added IPX routing support.
 * 
 * Revision 1.1  1995/08/16  12:40:18  mikez
 * Initial revision
 * 

--*/

#include "digilan.h"
#include "dxbreg.h"



NDIS_STATUS
DigiLanQueryInformation(
	IN NDIS_HANDLE MiniportAdapterContext,
	IN NDIS_OID Oid,
	IN PVOID InformationBuffer,
	IN ULONG InformationBufferLength,
	OUT PULONG BytesWritten,
	OUT PULONG BytesNeeded
	)
/*++

Description:

	MiniportQueryInformation queries the capabilities and status of the miniport 
	driver.

Parameters:

	IN NDIS_HANDLE MiniportAdapterContext
		The handle returned from DigiLanInitialize.

	IN NDIS_OID Oid
		The OID (Object ID) being queried.

	IN PVOID InformationBuffer
		A buffer that will receive the information.

	IN ULONG InformationBufferLength
		The length in bytes of InformationBuffer.

	OUT PULONG BytesWritten
		The number of bytes written to InformationBuffer.

	OUT PULONG BytesNeeded
		The number of additional bytes needed to satisfy the OID.
Return Value:

	None

--*/
{
	PDIGILAN_LOGICAL_ADAPTER pAdapter;
	CHAR DigiLanDescription[] = "Digi Frame Relay Adapter";
	INT i;
	INT SupportedOids;
	PVOID SourceBuffer;
	ULONG SourceBufferLength;
	ULONG ulGeneric;
	USHORT usGeneric;
	NDIS_STATUS NdisStatus;

//
// Commented entries in SupportedOids array are optional or already handled by
// NDIS wrapper.
//
	static NDIS_OID DigiLanSupportedOids[] = 
	{
		OID_GEN_SUPPORTED_LIST,
		OID_GEN_HARDWARE_STATUS,
		OID_GEN_MEDIA_SUPPORTED,
		OID_GEN_MEDIA_IN_USE,
		OID_GEN_MAXIMUM_LOOKAHEAD,
		OID_GEN_MAXIMUM_FRAME_SIZE,
		OID_GEN_LINK_SPEED,
		OID_GEN_TRANSMIT_BUFFER_SPACE,
		OID_GEN_RECEIVE_BUFFER_SPACE,
		OID_GEN_TRANSMIT_BLOCK_SIZE,
		OID_GEN_RECEIVE_BLOCK_SIZE,
		OID_GEN_VENDOR_ID,
		OID_GEN_VENDOR_DESCRIPTION,
		OID_GEN_CURRENT_PACKET_FILTER,
		OID_GEN_CURRENT_LOOKAHEAD,
		OID_GEN_DRIVER_VERSION,
		OID_GEN_VENDOR_DRIVER_VERSION,
		OID_GEN_MAXIMUM_SEND_PACKETS,
		OID_GEN_MEDIA_CONNECT_STATUS,
#if NT5_BUILD
		OID_GEN_PHYSICAL_MEDIUM,
		OID_PNP_CAPABILITIES,	
#endif
		OID_GEN_MAXIMUM_TOTAL_SIZE,
		OID_GEN_PROTOCOL_OPTIONS,
		OID_GEN_MAC_OPTIONS,
		OID_GEN_XMIT_OK,
		OID_GEN_RCV_OK,
		OID_GEN_XMIT_ERROR,
		OID_GEN_RCV_ERROR,
		OID_GEN_RCV_NO_BUFFER,
//		OID_GEN_DIRECTED_BYTES_XMIT,
//		OID_GEN_DIRECTED_FRAMES_XMIT,
//		OID_GEN_MULTICAST_BYTES_XMIT,
//		OID_GEN_MULTICAST_FRAMES_XMIT,
//		OID_GEN_BROADCAST_BYTES_XMIT,
//		OID_GEN_BROADCAST_FRAMES_XMIT,
//		OID_GEN_DIRECTED_BYTES_RCV,
//		OID_GEN_DIRECTED_FRAMES_RCV,
//		OID_GEN_MULTICAST_BYTES_RCV,
//		OID_GEN_MULTICAST_FRAMES_RCV,
//		OID_GEN_BROADCAST_BYTES_RCV,
//		OID_GEN_BROADCAST_FRAMES_RCV,
//		OID_GEN_RCV_CRC_ERROR,
//		OID_GEN_TRANSMIT_QUEUE_LENGTH,
		OID_802_3_PERMANENT_ADDRESS,
		OID_802_3_CURRENT_ADDRESS,
		OID_802_3_MULTICAST_LIST,
		OID_802_3_MAXIMUM_LIST_SIZE,
		OID_802_3_RCV_ERROR_ALIGNMENT,
		OID_802_3_XMIT_ONE_COLLISION,
		OID_802_3_XMIT_MORE_COLLISIONS,
//		OID_802_3_XMIT_DEFERRED,
//		OID_802_3_XMIT_MAX_COLLISIONS,
//		OID_802_3_RCV_OVERRUN,
//		OID_802_3_XMIT_UNDERRUN,
//		OID_802_3_XMIT_HEARTBEAT_FAILURE,
//		OID_802_3_XMIT_TIMES_CRS_LOST,
//		OID_802_3_XMIT_LATE_COLLISIONS		
	};

	DigiDump( DIGIFLOW, ("Enter DigiLanQueryInformation\n") );

	pAdapter = (PDIGILAN_LOGICAL_ADAPTER)MiniportAdapterContext;

	//
	// Check that the OID is valid.
	//

	SupportedOids = sizeof(DigiLanSupportedOids)/sizeof(ULONG);

	for ( i = 0; i < SupportedOids; i++ )
	{
	  if ( Oid == DigiLanSupportedOids[i] )
	      break;
	}

	if ( i == SupportedOids ) 
	{
	  *BytesWritten = 0;
	  return NDIS_STATUS_INVALID_OID;
	}

	//
	// Initialize these once, since this is the majority
	// of cases.
	//

	SourceBuffer = &ulGeneric;
	SourceBufferLength = sizeof(ULONG);

	NdisStatus = NDIS_STATUS_SUCCESS; // the default status for most OID's

	switch ( Oid )
	{
		case OID_GEN_SUPPORTED_LIST:
			
			DigiDump( DIGIQUERYINFO, ("   OID_GEN_SUPPORTED_LIST\n") );
			SourceBuffer = &DigiLanSupportedOids;
			SourceBufferLength = sizeof( DigiLanSupportedOids );
			break;

		case OID_GEN_HARDWARE_STATUS:

			DigiDump( DIGIQUERYINFO, ("   OID_GEN_HARDWARE_STATUS\n") );
			ulGeneric = NdisHardwareStatusReady;
			break;

		case OID_GEN_MEDIA_SUPPORTED:

			DigiDump( DIGIQUERYINFO, ("   OID_GEN_MEDIA_SUPPORTED\n") );
			ulGeneric = NdisMedium802_3;
			break;

		case OID_GEN_MEDIA_IN_USE:
			
			DigiDump( DIGIQUERYINFO, ("   OID_GEN_MEDIA_IN_USE\n") );
			ulGeneric = NdisMedium802_3;
			break;

		case OID_GEN_MAXIMUM_LOOKAHEAD:
			
			DigiDump( DIGIQUERYINFO, ("   OID_GEN_MAXIMUM_LOOKAHEAD\n") );
			ulGeneric = 1500;			// BUGBUG - is this correct?
			break;

		case OID_GEN_MAXIMUM_FRAME_SIZE:
			
			DigiDump( DIGIQUERYINFO, ("   OID_GEN_MAXIMUM_FRAME_SIZE\n") );
			ulGeneric = 1500;			// BUGBUG - is this correct?
			break;

		case OID_GEN_MAXIMUM_TOTAL_SIZE:
			
			DigiDump( DIGIQUERYINFO, ("   OID_GEN_MAXIMUM_TOTAL_SIZE\n") );
			ulGeneric = 1514;			// BUGBUG - is this correct?
			break;

		case OID_GEN_LINK_SPEED:
			
			ulGeneric = (pAdapter->Speed)/100; // 100 baud units, Using CIR for FR, WAN baudrate for X.25
			DigiDump( DIGIQUERYINFO, ("   OID_GEN_LINK_SPEED, %d\n", pAdapter->Speed) );
			break;

		case OID_GEN_TRANSMIT_BUFFER_SPACE:
			
			DigiDump( DIGIQUERYINFO, ("   OID_GEN_TRANSMIT_BUFFER_SPACE\n") );
			ulGeneric = 0x8000;				// BUGBUG - is this correct?
			break;

		case OID_GEN_RECEIVE_BUFFER_SPACE:
			
			DigiDump( DIGIQUERYINFO, ("   OID_GEN_RECEIVE_BUFFER_SPACE\n") );
			ulGeneric = 0x8000;				// BUGBUG - is this correct?
			break;

		case OID_GEN_TRANSMIT_BLOCK_SIZE:
			
			DigiDump( DIGIQUERYINFO, ("   OID_GEN_TRANSMIT_BLOCK_SIZE\n") );
			ulGeneric = 64;				// BUGBUG - is this correct?
			break;

		case OID_GEN_RECEIVE_BLOCK_SIZE:
			
			DigiDump( DIGIQUERYINFO, ("   OID_GEN_RECEIVE_BLOCK_SIZE\n") );
			ulGeneric = 64;				// BUGBUG - is this correct?
			break;

		case OID_GEN_VENDOR_ID:
			
			DigiDump( DIGIQUERYINFO, ("   OID_GEN_VENDOR_ID\n") );
			ulGeneric = 0x00409304;		// BUGBUG - this is DigiX25's ID + 1 !!!
			break;

		case OID_GEN_VENDOR_DESCRIPTION:
			
			DigiDump( DIGIQUERYINFO, ("   OID_GEN_VENDOR_DESCRIPTION\n") );
			SourceBuffer = DigiLanDescription;
			SourceBufferLength = strlen( DigiLanDescription );
			break;
 
		case OID_GEN_CURRENT_PACKET_FILTER:

			DigiDump( DIGIQUERYINFO, ("   OID_GEN_CURRENT_PACKET_FILTER\n") );
			ulGeneric = pAdapter->PacketFilter;
			break;

		case OID_GEN_CURRENT_LOOKAHEAD:
			
			DigiDump( DIGIQUERYINFO, ("   OID_GEN_CURRENT_LOOKAHEAD\n") );
			ulGeneric = 1500;				// BUGBUG - is this correct?
			break;

		case OID_GEN_DRIVER_VERSION:
			
			DigiDump( DIGIQUERYINFO, ("   OID_GEN_DRIVER_VERSION\n") );
			usGeneric = ( DIGILAN_MAJOR_VERSION << 8 ) | DIGILAN_MINOR_VERSION;
			SourceBuffer = &usGeneric;
			SourceBufferLength = sizeof( USHORT );
			break;

		case OID_GEN_VENDOR_DRIVER_VERSION:
			
			DigiDump( DIGIQUERYINFO, ("   OID_GEN_VENDER_DRIVER_VERSION\n") );
			usGeneric = ( DXBVER_VERSION_MAJOR << 8 ) | DXBVER_VERSION_MINOR;
			SourceBuffer = &usGeneric;
			SourceBufferLength = sizeof( USHORT );
			break;

		case OID_GEN_MAXIMUM_SEND_PACKETS:

			DigiDump( DIGIQUERYINFO, ("   OID_GEN_MAXIMUM_SEND_PACKETS\n") );
			ulGeneric = DIGILAN_MAXIMUM_SEND_PACKETS;
			break;

		case OID_GEN_MEDIA_CONNECT_STATUS:

			ulGeneric = NdisMediaStateConnected;

			switch ( pAdapter->SyncProtocol.Id )
			{
				case PROTOCOL_FR:				
					if ( pAdapter->SyncProtocol.Private.FR.LinkState == LINK_INACTIVE ) ulGeneric = NdisMediaStateDisconnected;  
					break;

				case PROTOCOL_X25:
					if( pAdapter->SyncProtocol.Private.X25.State != 0x3 ) ulGeneric = NdisMediaStateDisconnected;
					break;
				default:
					DbgPrint("*** unknown protocol running...\n");
					break;
			}
		
			DigiDump( DIGIQUERYINFO, ("   OID_GEN_MEDIA_CONNECT_STATUS, %s\n", ulGeneric == NdisMediaStateConnected?"Connected":"Disconnected") );
			break;

#if NT5_BUILD

		case OID_GEN_PHYSICAL_MEDIUM:

			DigiDump( DIGIQUERYINFO, ("   OID_GEN_PHYSICAL_MEDIUM\n") );
			ulGeneric = 0x0;
			break;

#endif

		case OID_GEN_MAC_OPTIONS:
			
			DigiDump( DIGIQUERYINFO, ("   OID_GEN_MAC_OPTIONS\n") );
			ulGeneric = (					// BUGBUG - is this correct?
				NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
				NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
				NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
				NDIS_MAC_OPTION_NO_LOOPBACK
				);
			break;

		case OID_GEN_XMIT_OK:

			DigiDump( DIGIQUERYINFO, ("   OID_GEN_XMIT_OK\n") );
			ulGeneric = pAdapter->PacketsSent;
			break;

		case OID_GEN_RCV_OK:

			DigiDump( DIGIQUERYINFO, ("   OID_GEN_RCV_OK\n") );
			ulGeneric = pAdapter->PacketsReceived;
			break;

		case OID_GEN_XMIT_ERROR:

			DigiDump( DIGIQUERYINFO, ("   OID_GEN_XMIT_ERROR\n") );
			ulGeneric = pAdapter->SendPacketsDropped;
			break;

		case OID_GEN_RCV_ERROR:

			DigiDump( DIGIQUERYINFO, ("   OID_GEN_RCV_ERROR\n") );
			ulGeneric = pAdapter->RecvPacketsDropped;
			break;

		case OID_GEN_RCV_NO_BUFFER:

			DigiDump( DIGIQUERYINFO, ("   OID_GEN_RCV_NO_BUFFER\n") );
			ulGeneric = 0;			// BUGBUG - is this correct?
			break;

		case OID_802_3_RCV_ERROR_ALIGNMENT:

			DigiDump( DIGIQUERYINFO, ("   OID_802_3_RCV_ERROR_ALIGNMENT\n") );
			ulGeneric = 0;			// BUGBUG - is this correct?
			break;

		case OID_802_3_XMIT_ONE_COLLISION:

			DigiDump( DIGIQUERYINFO, ("   OID_802_3_XMIT_ONE_COLLISION\n") );
			ulGeneric = 0;			// BUGBUG - is this correct?
			break;

		case OID_802_3_XMIT_MORE_COLLISIONS:

			DigiDump( DIGIQUERYINFO, ("   OID_802_3_XMIT_MORE_COLLISIONS\n") );
			ulGeneric = 0;			// BUGBUG - is this correct?
			break;

		case OID_802_3_PERMANENT_ADDRESS:

			DigiDump( DIGIQUERYINFO, ("   OID_802_3_PERMANENT_ADDRESS\n") );
			SourceBuffer = pAdapter->PermanentNetworkAddress;
			SourceBufferLength = DIGILAN_LENGTH_OF_ADDRESS;
			break;

		case OID_802_3_CURRENT_ADDRESS:

			DigiDump( DIGIQUERYINFO, ("   OID_802_3_CURRENT_ADDRESS\n") );
			SourceBuffer = pAdapter->CurrentNetworkAddress;
			SourceBufferLength = DIGILAN_LENGTH_OF_ADDRESS;
			break;

		case OID_802_3_MULTICAST_LIST:

			DigiDump( DIGIQUERYINFO, ("   OID_802_3_MULTICAST_LIST\n") );
			SourceBuffer = pAdapter->Multicast.AddressList;
			SourceBufferLength = pAdapter->Multicast.Count * ETHERNET_MAC_ADDR_SIZE;
			break;

		case OID_802_3_MAXIMUM_LIST_SIZE:

			DigiDump( DIGIQUERYINFO, ("   OID_802_3_MAXIMUM_LIST_SIZE\n") );
			ulGeneric = DIGILAN_MAX_MULTICAST;
			break;

		case OID_WAN_PERMANENT_ADDRESS:
			//SDB:
			DigiDump( DIGIQUERYINFO, ("   OID_WAN_PERMANENT_ADDRESS\n") );
			SourceBuffer = pAdapter->PermanentNetworkAddress;
			SourceBufferLength = DIGILAN_LENGTH_OF_ADDRESS;
			break;

		case OID_WAN_CURRENT_ADDRESS:

			//SDB:
			DigiDump( DIGIQUERYINFO, ("   OID_WAN_CURRENT_ADDRESS\n") );
			SourceBuffer = pAdapter->CurrentNetworkAddress;
			SourceBufferLength = DIGILAN_LENGTH_OF_ADDRESS;
			break;

		case OID_WAN_QUALITY_OF_SERVICE:

			DigiDump( DIGIQUERYINFO, ("   OID_WAN_QUALITY_OF_SERVICE\n") );
			ulGeneric = NdisWanReliable;	// BUGBUG - is this correct?
			break;

		case OID_WAN_PROTOCOL_TYPE:

			DigiDump( DIGIQUERYINFO, ("   OID_WAN_PROTOCOL_TYPE\n") );
			DigiDump( (DIGIERRORS|DIGIQUERYINFO), ("   *** Should never get this!\n") );
			break;

		case OID_WAN_MEDIUM_SUBTYPE:

			DigiDump( DIGIQUERYINFO, ("   OID_WAN_MEDIUM_SUBTYPE\n") );
			ulGeneric = NdisWanMediumFrameRelay;
			break;

		case OID_WAN_HEADER_FORMAT:

			DigiDump( DIGIQUERYINFO, ("   OID_WAN_HEADER_FORMAT\n") );
			DigiDump( (DIGIERRORS|DIGIQUERYINFO), ("   *** Should never get this!\n") );
			break;
	
#if NT5_BUILD

		case OID_PNP_CAPABILITIES:
			// Publish driver's wakeup capabilities:
			// Note: We currently do not support any wakeup capabilities

			DigiDump( DIGIQUERYINFO, ("   OID_PNP_CAPABILITIES\n") );
			
			{
				PNDIS_PNP_CAPABILITIES pPnpCaps = (PNDIS_PNP_CAPABILITIES)SourceBuffer;
				
				pPnpCaps->Flags = 0;
				pPnpCaps->WakeUpCapabilities.MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
				pPnpCaps->WakeUpCapabilities.MinPatternWakeUp = NdisDeviceStateUnspecified;
				pPnpCaps->WakeUpCapabilities.MinLinkChangeWakeUp = NdisDeviceStateUnspecified;
				SourceBufferLength = sizeof( NDIS_PNP_CAPABILITIES );
			}			
			break;
#endif

		default:
			DigiDump( DIGIQUERYINFO, ("   Unknown OID\n") );
			DigiDump( (DIGIERRORS|DIGIQUERYINFO), ("   *** Should never get this!\n") );
			break;
	}

	if ( SourceBufferLength > InformationBufferLength )
	{
		*BytesNeeded = SourceBufferLength;
		DigiDump( DIGIQUERYINFO, ("   *** Invalid InformationBufferLength!\n") );
		return NDIS_STATUS_INVALID_LENGTH;
	}

	NdisMoveMemory( InformationBuffer, SourceBuffer, SourceBufferLength );
	*BytesWritten = SourceBufferLength;
		
	DigiDump( DIGIFLOW, ("Leave DigiLanQueryInformation\n") );
	return( NdisStatus );
}



NDIS_STATUS
DigiLanSetInformation(
	IN NDIS_HANDLE MiniportAdapterContext,
	IN NDIS_OID Oid,
	IN PVOID pInformationBuffer,
	IN ULONG InformationBufferLength,
	OUT PULONG pBytesRead,
	OUT PULONG pBytesNeeded
	)
/*++

Description:

	DigiLanSetInformation allows other layers of the network software (e.g., a 
	transport driver) to control the miniport driver by changing information that 
	the miniport driver maintains in its OIDs, such as the packet filters or 
	multicast addresses.

Parameters:

	MiniportAdapterContext
		The handle returned from MiniportInitialize.

	Oid
		The OID. Any of the settable NDIS Global OIDs can be used. 

	pInformationBuffer
		A buffer that will receive the information.

	InformationBufferLength
		The length in bytes of InformationBuffer.

	pBytesRead
		The number of bytes read from InformationBuffer.
	
	pBytesNeeded
		The number of additional bytes needed to satisfy the OID.

Return Value:

	NDIS_STATUS_SUCCESS, or one of the following status values:
	NDIS_STATUS_INVALID_DATA
	NDIS_STATUS_INVALID_LENGTH
	NDIS_STATUS_INVALID_OID
	NDIS_STATUS_NOT_ACCEPTED
	NDIS_STATUS_NOT_SUPPORTED
	NDIS_STATUS_PENDING
	NDIS_STATUS_RESOURCES

--*/
{
	PDIGILAN_LOGICAL_ADAPTER pAdapter;
	NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
	ULONG PacketFilter;

	pAdapter = (PDIGILAN_LOGICAL_ADAPTER)( MiniportAdapterContext );

	DigiDump( DIGIFLOW, ("Enter DigiLanSetInformation\n") );


	switch ( Oid )
	{
		case OID_GEN_CURRENT_PACKET_FILTER:
			DigiDump( 
				DIGISETINFO, 
				("   OID_GEN_CURRENT_PACKET_FILTER: 0x%x\n", 
				*(PULONG)pInformationBuffer ) );

			if (InformationBufferLength != 4) 
			{
				*pBytesNeeded = 4;
				Status = NDIS_STATUS_INVALID_LENGTH;
				break;
			}

			NdisMoveMemory( 
				&PacketFilter,
				pInformationBuffer,
				sizeof(ULONG) );

			// Note: Packet filtering is done in DigiLanGetMsgCompletionRoutine.
			if ( PacketFilter & ~(
					NDIS_PACKET_TYPE_PROMISCUOUS | 
					NDIS_PACKET_TYPE_MULTICAST | 
					NDIS_PACKET_TYPE_DIRECTED | 
					NDIS_PACKET_TYPE_BROADCAST | 
					NDIS_PACKET_TYPE_ALL_MULTICAST |
					0 ) )
			{
				//
				// Invalid or unsupported packet filter
				//
				DigiDump( 
					DIGIERRORS, 
					("   *** This filter is not supported!\n", 
					PacketFilter) );

				*pBytesRead = 4;
				*pBytesNeeded = 0;

				Status = NDIS_STATUS_NOT_SUPPORTED;
				break;
			}

			pAdapter->PacketFilter = PacketFilter;
			Status = NDIS_STATUS_SUCCESS;
			break;

		case OID_GEN_CURRENT_LOOKAHEAD:

			//
			// No need to record requested lookahead length since we
			// always indicate the whole packet.
			//

			DigiDump( 
				DIGISETINFO, 
				("   OID_GEN_CURRENT_LOOKAHEAD: 0x%x\n", 
				*(PULONG)pInformationBuffer ) );

			*pBytesRead = 4;
			*pBytesNeeded = 0;
			Status = NDIS_STATUS_SUCCESS;
			break;

		case OID_GEN_PROTOCOL_OPTIONS:

			//
			// This is a nice feature (of the protocol driver), but we have no need 
			// for it.  Accept the Oid, but don't use it.
			//

			DigiDump( 
				DIGISETINFO, 
				("   OID_GEN_PROTOCOL_OPTIONS: 0x%x\n",
				*(PULONG)( pInformationBuffer )) );
			break;

		case OID_802_3_MULTICAST_LIST:
		{
			PVOID pTemp;
			DigiDump( DIGISETINFO, ("   OID_802_3_MULTICAST_LIST\n") );

			//
			// Sanity check
			//

			// SDB: Allow NDIS to set a NULL multicast list:

#if 0
			if ( ( InformationBufferLength % ETHERNET_MAC_ADDR_SIZE ) ||
                 ( InformationBufferLength == 0 ) )
#endif
			if ( InformationBufferLength % ETHERNET_MAC_ADDR_SIZE )
			{
				// Error: The multicast list is not a multiple of ETHERNET_MAC_ADDR_SIZE
				DigiDump( DIGIERRORS,
					(" *** DigiLan Set Info: Invalid Multicast List Length 0x%x\n",
						InformationBufferLength
					));
				Status = NDIS_STATUS_INVALID_DATA;
				break;
			}

			if ( InformationBufferLength == 0 )
			{
				// Free resources of current address list:
				if ( pAdapter->Multicast.AddressList != 0 )
				{
					DigiFreeMem( pAdapter->Multicast.AddressList );
					pAdapter->Multicast.AddressList = 0;
				}

				pAdapter->Multicast.Count = 0;

				*pBytesRead   = InformationBufferLength;
				*pBytesNeeded = 0;
				Status        = NDIS_STATUS_SUCCESS;
				break;
			}

			// -- Alloc space for list		

			pTemp = DigiAllocMem( NonPagedPool, InformationBufferLength );

			if ( !pTemp )
			{
				DigiDump( 
					DIGIERRORS, 
					("*** DigiLan Set Multicast List: could not alloc mem!\n") );
				Status = NDIS_STATUS_RESOURCES;
				break;
			}
			
			// -- Free the previous address list:		
			
			if ( pAdapter->Multicast.AddressList != 0 )
				DigiFreeMem( pAdapter->Multicast.AddressList );

			// -- Store new list:
			
			NdisMoveMemory( pTemp, pInformationBuffer, InformationBufferLength );
			pAdapter->Multicast.AddressList = pTemp;

			pAdapter->Multicast.Count = InformationBufferLength / ETHERNET_MAC_ADDR_SIZE;

			*pBytesRead = InformationBufferLength;
			*pBytesNeeded = 0;
			Status = NDIS_STATUS_SUCCESS;
			break;
		}

		default:

			DigiDump( 
				DIGISETINFO, 
				("*** DigiLanSetInformation: Oid not supported!\n"
				"   Oid:  0x%x\n"
				"   Data: 0x%x\n"
				"   Len:  0x%x\n",
				Oid,
				*(PULONG)pInformationBuffer,
				InformationBufferLength) );

			Status = NDIS_STATUS_NOT_SUPPORTED;
			break;
	}

	DigiDump( DIGIFLOW, ("Leave DigiFrSetInformation\n") );
	
	return( Status );
}
