Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

651 lines
14 KiB

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
ltreq.c
Abstract:
This module contains
Author:
Nikhil Kamkolkar ([email protected])
Stephen Hou ([email protected])
Revision History:
19 Jun 1992 Initial Version ([email protected])
Notes: Tab stop: 4
--*/
#define LTREQ_H_LOCALS
#include "ltmain.h"
#include "ltreq.h"
// Define file id for errorlogging
#define FILENUM LTREQ
NDIS_STATUS
LtRequest(
IN NDIS_HANDLE MacBindingHandle,
IN PNDIS_REQUEST NdisRequest
)
/*++
Routine Description:
called by NDIS to query or set card/driver information on a binding
Arguments:
MacBindingHandle : the binding submitting the request
NdisRequest : the request we've been asked to satisfy
Return Values:
NDIS_STATUS_SUCCESS : if completed successfully
NDIS_STATUS_RESET_IN_PROGRESS : if the adapter's in the middle of a reset
NDIS_STATUS_ADAPTER_REMOVED : if the adapter's been closed
NDIS_STATUS_CLOSING : if the binding is closing down
NDIS_STATUS_NOT_SUPPORTED : if we do not support the requested action
--*/
{
NDIS_STATUS Status;
PLT_ADAPTER Adapter = ((PLT_OPEN)MacBindingHandle)->LtAdapter;
PLT_OPEN Open = (PLT_OPEN)MacBindingHandle;
if (Adapter->Flags & ADAPTER_RESET_IN_PROGRESS)
{
return(NDIS_STATUS_RESET_IN_PROGRESS);
}
switch (NdisRequest->RequestType)
{
case NdisRequestSetInformation:
case NdisRequestQueryInformation:
// increment count since we'll be in the binding with the request
LtReferenceBinding(Open,&Status);
if (Status == NDIS_STATUS_SUCCESS)
{
if (NdisRequest->RequestType == NdisRequestSetInformation)
{
Status = LtReqSetInformation(
Adapter,
Open,
NdisRequest->DATA.SET_INFORMATION.Oid,
NdisRequest->DATA.SET_INFORMATION.InformationBuffer,
NdisRequest->DATA.SET_INFORMATION.InformationBufferLength,
&(NdisRequest->DATA.SET_INFORMATION.BytesRead),
&(NdisRequest->DATA.SET_INFORMATION.BytesNeeded));
}
else
{
Status = LtReqQueryInformation(
Adapter,
Open,
NdisRequest->DATA.QUERY_INFORMATION.Oid,
NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer,
NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength,
&(NdisRequest->DATA.QUERY_INFORMATION.BytesWritten),
&(NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded),
FALSE);
}
// completed the request for the binding; outa there
LtDeReferenceBinding(Open);
}
break;
default:
// Unkown request
Status = NDIS_STATUS_NOT_SUPPORTED;
break;
}
return(Status);
}
NDIS_STATUS
LtReqQueryGlobalStatistics(
IN NDIS_HANDLE MacAdapterContext,
IN PNDIS_REQUEST NdisRequest
)
/*++
Routine Description:
called by NDIS to query or set global card/driver information
Arguments:
MacAdapterContext : the adapter the request is submitted on
NdisRequest : the request we've been asked to satisfy
Return Values:
NDIS_STATUS_SUCCESS : if completed successfully
NDIS_STATUS_RESET_IN_PROGRESS : if the adapter's in the middle of a reset
NDIS_STATUS_ADAPTER_REMOVED : if the adapter's been closed
NDIS_STATUS_CLOSING : if the binding is closing down
NDIS_STATUS_NOT_SUPPORTED : if we do not support the requested action
--*/
{
NDIS_STATUS Status;
PLT_ADAPTER Adapter = MacAdapterContext;
if (Adapter->Flags & ADAPTER_RESET_IN_PROGRESS)
{
return(NDIS_STATUS_RESET_IN_PROGRESS);
}
switch (NdisRequest->RequestType)
{
case NdisRequestQueryStatistics:
LtReferenceAdapter(Adapter,&Status);
if (Status != NDIS_STATUS_SUCCESS)
break;
Status = LtReqQueryInformation(
Adapter,
NULL,
NdisRequest->DATA.QUERY_INFORMATION.Oid,
NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer,
NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength,
&(NdisRequest->DATA.QUERY_INFORMATION.BytesWritten),
&(NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded),
TRUE);
LtDeReferenceAdapter(Adapter);
break;
default:
Status = NDIS_STATUS_NOT_SUPPORTED;
break;
}
return(Status);
}
STATIC
NDIS_STATUS
LtReqSetInformation(
IN PLT_ADAPTER Adapter,
IN PLT_OPEN Open,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN INT InformationBufferLength,
IN PUINT BytesRead,
IN PUINT BytesNeeded
)
/*++
Routine Description:
performs a set operation for a single OID.
Arguments:
Adapter : The adapter that the set is for
Open : The binding that the set is for
Oid : The OID to set
InformationBuffer : Holds the data to be set
InformationBufferLength : The length of InformationBuffer
BytesRead : If the call is successful, returns the number
of bytes read from InformationBuffer
BytesNeeded : If there is not enough data in InformationBuffer
to satisfy the request, returns the amount of
storage needed.
Return Value:
NDIS_STATUS_SUCCESS : if successful
NDIS_STATUS_INVALID_OID : if the oid is not supported
NDIS_STATUS_INVALID_DATA : if InformationBuffer contains bad data
NDIS_STATUS_INVALID_LENGTH : if the InformationBufferLength is incorrect
--*/
{
ULONG PacketFilter, NewLookAhead;
NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
//
// Now check for the most common OIDs
//
DBGPRINT(DBG_COMP_REQ,DBG_LEVEL_INFO,
("LtReqSetInformation: setting OID - 0x%.8lx\n", Oid));
switch (Oid)
{
case OID_GEN_CURRENT_PACKET_FILTER:
// Localtalk only supports Directed and broadcast packets.
// And the Lt firmware does not support PROMISCUSOUS mode.
// so return NDIS_STATUS_NOT_SUPPORTED for these packet filters.
if (InformationBufferLength != 4)
{
StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
break;
}
NdisMoveMemory(
(PVOID)&PacketFilter,
InformationBuffer,
sizeof(ULONG));
DBGPRINT(DBG_COMP_REQ,DBG_LEVEL_INFO,
("LtReqSetInformation: Requested packet filter is %x\n", PacketFilter));
if (PacketFilter == NDIS_PACKET_TYPE_BROADCAST ||
PacketFilter == NDIS_PACKET_TYPE_DIRECTED ||
PacketFilter == (NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_DIRECTED))
{
NdisAcquireSpinLock(&Adapter->Lock);
Adapter->GlobalPacketFilter |= PacketFilter;
Open->CurrentPacketFilter = PacketFilter;
NdisReleaseSpinLock(&Adapter->Lock);
*BytesRead = InformationBufferLength;
}
else
{
StatusToReturn = NDIS_STATUS_INVALID_DATA;
}
break;
case OID_GEN_CURRENT_LOOKAHEAD:
if (InformationBufferLength != 4)
{
StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
break;
}
NdisMoveMemory(
(PVOID)&NewLookAhead,
InformationBuffer,
sizeof(ULONG));
DBGPRINT(DBG_COMP_REQ,DBG_LEVEL_INFO,
("LtReqSetInformation: Requested Lookahead size is %d\n", NewLookAhead));
if ((NewLookAhead > LT_MAX_INDICATE_SIZE) ||
(NewLookAhead < LT_MIN_INDICATE_SIZE))
{
StatusToReturn = NDIS_STATUS_INVALID_DATA;
break;
}
NdisAcquireSpinLock(&Adapter->Lock);
// valid lookahead size, so set it
Open->CurrentLookAheadSize = NewLookAhead;
// adjust the global lookaheadsize
if (Adapter->GlobalLookAheadSize < NewLookAhead)
{
Adapter->GlobalLookAheadSize = NewLookAhead;
}
else
{
LtReqAdjustLookAhead(
&Adapter->GlobalLookAheadSize,
&Adapter->OpenBindings);
}
NdisReleaseSpinLock(&Adapter->Lock);
*BytesRead = 4;
break;
default:
StatusToReturn = NDIS_STATUS_INVALID_OID;
break;
}
return(StatusToReturn);
}
LtReqQueryInformation(
IN PLT_ADAPTER Adapter,
IN PLT_OPEN Open,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN INT InformationBufferLength,
IN PUINT BytesWritten,
IN PUINT BytesNeeded,
IN BOOLEAN Global
)
/*++
Routine Description:
performs a query operation for a single OID.
Arguments:
Adapter : The adapter that the query is for
Open : The binding that the query is for
Oid : The OID to query
InformationBuffer : Holds the result of the query.
InformationBufferLength : The length of InformationBuffer.
BytesWritten : If the call is successful, returns the
number of bytes written to InformationBuffer
BytesNeeded : If there is not enough room in InformationBuffer
to satisfy the request, returns the amount of
storage needed
Global : TRUE if the request originated from the adapter.
FALSE if the request came from a binding
Return Value:
NDIS_STATUS_SUCCESS : if successful
NDIS_STATUS_INVALID_OID : if the query is on an OID we do not support
NDIS_STATUS_BUFFER_TOO_SHORT: if InformationBufferLength is too small to
hold the information returned
--*/
{
UINT OidIndex;
ULONG GenericUlong;
USHORT GenericUshort;
PVOID SourceBuffer = &GenericUlong;
UINT SourceBufferLength = sizeof(ULONG);
PNDIS_OID SupportedOidArray = LtProtocolSupportedOids;
UINT SupportedOids = (sizeof(LtProtocolSupportedOids)/sizeof(ULONG));
static UCHAR VendorDescription[] = LT_VENDOR_DESCR;
static UCHAR VendorId[3] = LT_VENDOR_ID;
if (Global)
{
SupportedOidArray = LtGlobalSupportedOids;
SupportedOids = sizeof(LtGlobalSupportedOids)/sizeof(ULONG);
}
//
// Check that the OID is valid.
//
for (OidIndex=0; OidIndex < SupportedOids; OidIndex++)
{
if (Oid == SupportedOidArray[OidIndex])
{
break;
}
}
if (OidIndex == SupportedOids)
{
*BytesWritten = 0;
return(NDIS_STATUS_INVALID_OID);
}
switch (Oid)
{
case OID_GEN_SUPPORTED_LIST:
SourceBuffer = SupportedOidArray;
SourceBufferLength = SupportedOids * sizeof(ULONG);
break;
case OID_GEN_HARDWARE_STATUS:
GenericUlong = NdisHardwareStatusReady;
if (Adapter->Flags & ADAPTER_RESET_IN_PROGRESS)
{
GenericUlong = NdisHardwareStatusReset;
}
break;
case OID_GEN_MEDIA_SUPPORTED:
GenericUlong = NdisMediumLocalTalk;
break;
case OID_GEN_MEDIA_IN_USE:
GenericUlong = NdisMediumLocalTalk;
// if no binding exists then media is not in use
if (Global && Adapter->OpenCount == 0)
{
SourceBufferLength = 0;
}
break;
case OID_GEN_MAXIMUM_LOOKAHEAD:
GenericUlong = LT_MAX_INDICATE_SIZE;
break;
case OID_GEN_MAXIMUM_FRAME_SIZE:
GenericUlong = LT_MAXIMUM_PACKET_SIZE;
break;
case OID_GEN_LINK_SPEED:
GenericUlong = LT_LINK_SPEED;
break;
case OID_GEN_TRANSMIT_BUFFER_SPACE:
GenericUlong = LT_MAXIMUM_PACKET_SIZE;
break;
case OID_GEN_RECEIVE_BUFFER_SPACE:
// BUGBUG: need to determine number of recv buffers or in this case the
// amount of space for receives
GenericUlong = LT_MAXIMUM_PACKET_SIZE * 5;
break;
case OID_GEN_TRANSMIT_BLOCK_SIZE:
GenericUlong = 1;
break;
case OID_GEN_RECEIVE_BLOCK_SIZE:
// BUGBUG: need to determine number of recv buffers
GenericUlong = 5;
break;
case OID_GEN_VENDOR_ID:
SourceBuffer = VendorId;
SourceBufferLength = sizeof(VendorId);
break;
case OID_GEN_VENDOR_DESCRIPTION:
SourceBuffer = VendorDescription;
SourceBufferLength = sizeof(VendorDescription);
break;
case OID_GEN_CURRENT_PACKET_FILTER:
GenericUlong = Open->CurrentPacketFilter;
if (Global)
{
GenericUlong = Adapter->GlobalPacketFilter;
}
break;
case OID_GEN_CURRENT_LOOKAHEAD:
GenericUlong = Open->CurrentLookAheadSize;
if (Global)
{
GenericUlong = Adapter->GlobalLookAheadSize;
}
break;
case OID_GEN_DRIVER_VERSION:
GenericUshort = (LT_MAJOR_VERSION << 8) + LT_MINOR_VERSION;
SourceBuffer = &GenericUshort;
SourceBufferLength = sizeof(USHORT);
break;
case OID_GEN_MAXIMUM_TOTAL_SIZE:
GenericUlong = LT_MAXIMUM_PACKET_SIZE;
break;
case OID_GEN_XMIT_OK:
case OID_GEN_RCV_OK:
case OID_GEN_XMIT_ERROR:
case OID_GEN_RCV_ERROR:
case OID_GEN_RCV_NO_BUFFER:
OidIndex = (Oid & LT_OID_INDEX_MASK) - 1;
ASSERT(OidIndex < GM_ARRAY_SIZE);
GenericUlong = Adapter->GeneralMandatory[OidIndex];
break;
case OID_GEN_DIRECTED_BYTES_XMIT:
case OID_GEN_BROADCAST_BYTES_XMIT:
case OID_GEN_DIRECTED_BYTES_RCV:
case OID_GEN_BROADCAST_BYTES_RCV:
OidIndex = (Oid & LT_OID_INDEX_MASK) - 1;
ASSERT(OidIndex < GM_ARRAY_SIZE);
SourceBuffer = &Adapter->GeneralOptionalByteCount[OidIndex / 2];
SourceBufferLength = sizeof(LARGE_INTEGER);
break;
case OID_GEN_DIRECTED_FRAMES_XMIT:
case OID_GEN_BROADCAST_FRAMES_XMIT:
case OID_GEN_DIRECTED_FRAMES_RCV:
case OID_GEN_BROADCAST_FRAMES_RCV:
OidIndex = (Oid & LT_OID_INDEX_MASK) - 1;
ASSERT(OidIndex < GO_COUNT_ARRAY_SIZE);
GenericUlong = Adapter->GeneralOptionalFrameCount[OidIndex / 2];
break;
case OID_GEN_RCV_CRC_ERROR:
case OID_GEN_TRANSMIT_QUEUE_LENGTH:
OidIndex = (Oid & LT_OID_INDEX_MASK) - 1;
ASSERT(OidIndex < GO_ARRAY_SIZE);
GenericUlong = Adapter->GeneralOptional[OidIndex - GO_ARRAY_START];
break;
case OID_GEN_MAC_OPTIONS:
GenericUlong = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA;
break;
case OID_LTALK_CURRENT_NODE_ID:
SourceBuffer = &GenericUshort;
GenericUshort = Adapter->NodeId;
SourceBufferLength = 2;
break;
case OID_LTALK_IN_BROADCASTS:
case OID_LTALK_IN_LENGTH_ERRORS:
OidIndex = (Oid & LT_OID_INDEX_MASK) - 1;
ASSERT (OidIndex < MM_ARRAY_SIZE);
GenericUlong = Adapter->MediaMandatory[OidIndex];
break;
case OID_LTALK_OUT_NO_HANDLERS:
case OID_LTALK_DEFERS:
OidIndex = (Oid & LT_OID_INDEX_MASK) - 1;
ASSERT (OidIndex < MO_ARRAY_SIZE);
GenericUlong = Adapter->MediaOptional[OidIndex];
break;
default:
// should never get here
ASSERT(FALSE);
break;
}
if ((INT)SourceBufferLength > InformationBufferLength)
{
*BytesNeeded = SourceBufferLength;
return(NDIS_STATUS_BUFFER_TOO_SHORT);
}
NdisMoveMemory(
InformationBuffer,
SourceBuffer,
SourceBufferLength);
*BytesWritten = SourceBufferLength;
return(NDIS_STATUS_SUCCESS);
}
STATIC
VOID
LtReqAdjustLookAhead(
OUT PUINT GlobalLookAheadSize,
IN PLIST_ENTRY OpenBindings
)
/*++
Routine Description:
called by LtReqSetInformation to adjust the global lookahead size when
the previously largest lookahead size (on a binding) is adjusted
THIS ROUTINE IS CALLED WITH THE SPINLOCK HELD
Arguments:
GlobalLookAheadSize : the global lookahead param we're adjusting
OpenBindings : the list of bindings we need to traverse
Return Value:
none
--*/
{
PLT_OPEN Binding;
PLIST_ENTRY p = OpenBindings->Flink;
UINT MaxLookAheadSize = 0;
while(p != OpenBindings)
{
Binding = CONTAINING_RECORD(
p,
LT_OPEN,
Linkage);
if (Binding->CurrentLookAheadSize > MaxLookAheadSize)
{
MaxLookAheadSize = Binding->CurrentLookAheadSize;
}
p = p->Flink;
}
*GlobalLookAheadSize = MaxLookAheadSize;
}