1256 lines
34 KiB
C
1256 lines
34 KiB
C
|
#include <ndis.h>
|
|||
|
#include <efilter.h>
|
|||
|
#include <tfilter.h>
|
|||
|
#include <ffilter.h>
|
|||
|
|
|||
|
#include "debug.h"
|
|||
|
#include "loop.h"
|
|||
|
|
|||
|
STATIC NDIS_OID LoopGlobalSupportedOids[] = {
|
|||
|
|
|||
|
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_MAC_OPTIONS,
|
|||
|
OID_GEN_PROTOCOL_OPTIONS,
|
|||
|
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_MAXIMUM_TOTAL_SIZE,
|
|||
|
|
|||
|
OID_GEN_XMIT_OK,
|
|||
|
OID_GEN_RCV_OK,
|
|||
|
OID_GEN_XMIT_ERROR,
|
|||
|
OID_GEN_RCV_ERROR,
|
|||
|
OID_GEN_RCV_NO_BUFFER,
|
|||
|
|
|||
|
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_5_PERMANENT_ADDRESS,
|
|||
|
OID_802_5_CURRENT_ADDRESS,
|
|||
|
OID_802_5_CURRENT_FUNCTIONAL,
|
|||
|
OID_802_5_CURRENT_GROUP,
|
|||
|
OID_802_5_LAST_OPEN_STATUS,
|
|||
|
OID_802_5_CURRENT_RING_STATUS,
|
|||
|
OID_802_5_CURRENT_RING_STATE,
|
|||
|
|
|||
|
OID_802_5_LINE_ERRORS,
|
|||
|
OID_802_5_LOST_FRAMES,
|
|||
|
|
|||
|
OID_FDDI_LONG_PERMANENT_ADDR,
|
|||
|
OID_FDDI_LONG_CURRENT_ADDR,
|
|||
|
OID_FDDI_LONG_MULTICAST_LIST,
|
|||
|
OID_FDDI_LONG_MAX_LIST_SIZE,
|
|||
|
OID_FDDI_SHORT_PERMANENT_ADDR,
|
|||
|
OID_FDDI_SHORT_CURRENT_ADDR,
|
|||
|
OID_FDDI_SHORT_MULTICAST_LIST,
|
|||
|
OID_FDDI_SHORT_MAX_LIST_SIZE,
|
|||
|
|
|||
|
OID_LTALK_CURRENT_NODE_ID,
|
|||
|
|
|||
|
OID_ARCNET_PERMANENT_ADDRESS,
|
|||
|
OID_ARCNET_CURRENT_ADDRESS
|
|||
|
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
STATIC NDIS_OID LoopProtocolSupportedOids[] = {
|
|||
|
|
|||
|
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_MAC_OPTIONS,
|
|||
|
OID_GEN_PROTOCOL_OPTIONS,
|
|||
|
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_MAXIMUM_TOTAL_SIZE,
|
|||
|
|
|||
|
OID_802_3_PERMANENT_ADDRESS,
|
|||
|
OID_802_3_CURRENT_ADDRESS,
|
|||
|
OID_802_3_MULTICAST_LIST,
|
|||
|
OID_802_3_MAXIMUM_LIST_SIZE,
|
|||
|
|
|||
|
OID_802_5_PERMANENT_ADDRESS,
|
|||
|
OID_802_5_CURRENT_ADDRESS,
|
|||
|
OID_802_5_CURRENT_FUNCTIONAL,
|
|||
|
OID_802_5_CURRENT_GROUP,
|
|||
|
|
|||
|
OID_FDDI_LONG_PERMANENT_ADDR,
|
|||
|
OID_FDDI_LONG_CURRENT_ADDR,
|
|||
|
OID_FDDI_LONG_MULTICAST_LIST,
|
|||
|
OID_FDDI_LONG_MAX_LIST_SIZE,
|
|||
|
OID_FDDI_SHORT_PERMANENT_ADDR,
|
|||
|
OID_FDDI_SHORT_CURRENT_ADDR,
|
|||
|
OID_FDDI_SHORT_MULTICAST_LIST,
|
|||
|
OID_FDDI_SHORT_MAX_LIST_SIZE,
|
|||
|
|
|||
|
OID_LTALK_CURRENT_NODE_ID,
|
|||
|
|
|||
|
OID_ARCNET_PERMANENT_ADDRESS,
|
|||
|
OID_ARCNET_CURRENT_ADDRESS
|
|||
|
|
|||
|
};
|
|||
|
|
|||
|
STATIC
|
|||
|
NDIS_STATUS
|
|||
|
LoopQueryInformation(
|
|||
|
IN PLOOP_ADAPTER Adapter,
|
|||
|
IN PLOOP_OPEN Open,
|
|||
|
IN NDIS_OID Oid,
|
|||
|
IN BOOLEAN Global,
|
|||
|
IN PVOID InformationBuffer,
|
|||
|
IN UINT InformationBufferLength,
|
|||
|
OUT PUINT BytesWritten,
|
|||
|
OUT PUINT BytesNeeded
|
|||
|
);
|
|||
|
|
|||
|
STATIC
|
|||
|
NDIS_STATUS
|
|||
|
LoopSetInformation(
|
|||
|
IN PLOOP_ADAPTER Adapter,
|
|||
|
IN PLOOP_OPEN Open,
|
|||
|
IN PNDIS_REQUEST NdisRequest
|
|||
|
);
|
|||
|
|
|||
|
STATIC
|
|||
|
VOID
|
|||
|
LoopAdjustLookahead(
|
|||
|
IN PLOOP_ADAPTER Adapter
|
|||
|
);
|
|||
|
|
|||
|
STATIC
|
|||
|
ULONG
|
|||
|
LoopQueryPacketFilter(
|
|||
|
IN PLOOP_ADAPTER Adapter
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
NDIS_STATUS
|
|||
|
LoopRequest(
|
|||
|
IN NDIS_HANDLE MacBindingHandle,
|
|||
|
IN PNDIS_REQUEST NdisRequest
|
|||
|
)
|
|||
|
{
|
|||
|
PLOOP_ADAPTER Adapter = PLOOP_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
|
|||
|
NDIS_STATUS StatusToReturn;
|
|||
|
|
|||
|
DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO, (" --> LoopRequest\n"));
|
|||
|
|
|||
|
NdisAcquireSpinLock(&Adapter->Lock);
|
|||
|
Adapter->References++;
|
|||
|
|
|||
|
if (! Adapter->ResetInProgress) {
|
|||
|
PLOOP_OPEN Open;
|
|||
|
|
|||
|
Open = PLOOP_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
|
|||
|
|
|||
|
DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO, ("Request from binding %lx\n",Open));
|
|||
|
|
|||
|
if (! Open->BindingClosing) {
|
|||
|
|
|||
|
switch (NdisRequest->RequestType) {
|
|||
|
|
|||
|
case NdisRequestSetInformation:
|
|||
|
|
|||
|
Open->References++;
|
|||
|
StatusToReturn = LoopSetInformation(
|
|||
|
Adapter,
|
|||
|
Open,
|
|||
|
NdisRequest
|
|||
|
);
|
|||
|
Open->References--;
|
|||
|
break;
|
|||
|
|
|||
|
case NdisRequestQueryInformation:
|
|||
|
|
|||
|
Open->References++;
|
|||
|
StatusToReturn = LoopQueryInformation(
|
|||
|
Adapter,
|
|||
|
Open,
|
|||
|
NdisRequest->DATA.QUERY_INFORMATION.Oid,
|
|||
|
FALSE,
|
|||
|
NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer,
|
|||
|
NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength,
|
|||
|
&(NdisRequest->DATA.QUERY_INFORMATION.BytesWritten),
|
|||
|
&(NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded)
|
|||
|
);
|
|||
|
Open->References--;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
// Unkown request
|
|||
|
|
|||
|
StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
|
|||
|
break;
|
|||
|
}
|
|||
|
} else {
|
|||
|
StatusToReturn = NDIS_STATUS_CLOSING;
|
|||
|
}
|
|||
|
} else
|
|||
|
StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS;
|
|||
|
|
|||
|
Adapter->References--;
|
|||
|
NdisReleaseSpinLock(&Adapter->Lock);
|
|||
|
|
|||
|
return StatusToReturn;
|
|||
|
}
|
|||
|
|
|||
|
NDIS_STATUS
|
|||
|
LoopQueryGlobalStats(
|
|||
|
IN NDIS_HANDLE MacAdapterContext,
|
|||
|
IN PNDIS_REQUEST NdisRequest
|
|||
|
)
|
|||
|
{
|
|||
|
NDIS_STATUS StatusToReturn;
|
|||
|
PLOOP_ADAPTER Adapter = PLOOP_ADAPTER_FROM_CONTEXT_HANDLE(MacAdapterContext);
|
|||
|
|
|||
|
DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO, (" --> LoopQueryGlobalStats\n"));
|
|||
|
|
|||
|
DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO, ("Request from adapter %lx\n",Adapter));
|
|||
|
|
|||
|
NdisAcquireSpinLock(&Adapter->Lock);
|
|||
|
Adapter->References++;
|
|||
|
|
|||
|
if (! Adapter->ResetInProgress) {
|
|||
|
|
|||
|
if (NdisRequest->RequestType == NdisRequestQueryStatistics) {
|
|||
|
|
|||
|
StatusToReturn = LoopQueryInformation(
|
|||
|
Adapter,
|
|||
|
NULL,
|
|||
|
NdisRequest->DATA.QUERY_INFORMATION.Oid,
|
|||
|
TRUE,
|
|||
|
NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer,
|
|||
|
NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength,
|
|||
|
&(NdisRequest->DATA.QUERY_INFORMATION.BytesWritten),
|
|||
|
&(NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded)
|
|||
|
);
|
|||
|
}
|
|||
|
else
|
|||
|
StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
|
|||
|
|
|||
|
} else
|
|||
|
StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS;
|
|||
|
|
|||
|
Adapter->References--;
|
|||
|
NdisReleaseSpinLock(&Adapter->Lock);
|
|||
|
return StatusToReturn;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
STATIC
|
|||
|
NDIS_STATUS
|
|||
|
LoopSetInformation(
|
|||
|
IN PLOOP_ADAPTER Adapter,
|
|||
|
IN PLOOP_OPEN Open,
|
|||
|
IN PNDIS_REQUEST NdisRequest
|
|||
|
)
|
|||
|
{
|
|||
|
NDIS_STATUS StatusToReturn;
|
|||
|
ULONG PacketFilter, CurrentLookahead;
|
|||
|
NDIS_OID Oid = NdisRequest->DATA.SET_INFORMATION.Oid;
|
|||
|
PVOID InformationBuffer = NdisRequest->DATA.SET_INFORMATION.InformationBuffer;
|
|||
|
INT InformationBufferLength = NdisRequest->DATA.SET_INFORMATION.InformationBufferLength;
|
|||
|
|
|||
|
DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO, (" --> LoopSetInformation\n"));
|
|||
|
|
|||
|
NdisRequest->DATA.SET_INFORMATION.BytesRead = 0;
|
|||
|
NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0;
|
|||
|
|
|||
|
//
|
|||
|
// Now check for the most common OIDs
|
|||
|
//
|
|||
|
|
|||
|
DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO, ("OID = %lx\n",Oid));
|
|||
|
switch (Oid) {
|
|||
|
|
|||
|
case OID_GEN_CURRENT_PACKET_FILTER:
|
|||
|
|
|||
|
if (InformationBufferLength != 4) {
|
|||
|
|
|||
|
StatusToReturn = NDIS_STATUS_INVALID_DATA;
|
|||
|
break;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
NdisMoveMemory(
|
|||
|
(PVOID)&PacketFilter,
|
|||
|
InformationBuffer,
|
|||
|
sizeof(ULONG)
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
switch (Adapter->Medium) {
|
|||
|
case NdisMedium802_3:
|
|||
|
case NdisMediumDix:
|
|||
|
|
|||
|
StatusToReturn = EthFilterAdjust(
|
|||
|
Adapter->Filter.Eth,
|
|||
|
Open->NdisFilterHandle,
|
|||
|
NdisRequest,
|
|||
|
PacketFilter,
|
|||
|
TRUE
|
|||
|
);
|
|||
|
break;
|
|||
|
|
|||
|
case NdisMedium802_5:
|
|||
|
|
|||
|
StatusToReturn = TrFilterAdjust(
|
|||
|
Adapter->Filter.Tr,
|
|||
|
Open->NdisFilterHandle,
|
|||
|
NdisRequest,
|
|||
|
PacketFilter,
|
|||
|
TRUE
|
|||
|
);
|
|||
|
break;
|
|||
|
|
|||
|
case NdisMediumFddi:
|
|||
|
|
|||
|
StatusToReturn = FddiFilterAdjust(
|
|||
|
Adapter->Filter.Fddi,
|
|||
|
Open->NdisFilterHandle,
|
|||
|
NdisRequest,
|
|||
|
PacketFilter,
|
|||
|
TRUE
|
|||
|
);
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
if (PacketFilter == (PacketFilter & Adapter->MediumPacketFilters)) {
|
|||
|
|
|||
|
Open->CurrentPacketFilter = PacketFilter;
|
|||
|
StatusToReturn = NDIS_STATUS_SUCCESS;
|
|||
|
|
|||
|
} else
|
|||
|
StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
|
|||
|
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
NdisRequest->DATA.SET_INFORMATION.BytesRead = InformationBufferLength;
|
|||
|
break;
|
|||
|
|
|||
|
case OID_GEN_CURRENT_LOOKAHEAD:
|
|||
|
|
|||
|
if (InformationBufferLength != 4) {
|
|||
|
|
|||
|
StatusToReturn = NDIS_STATUS_INVALID_DATA;
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
NdisMoveMemory(
|
|||
|
(PVOID)&CurrentLookahead,
|
|||
|
InformationBuffer,
|
|||
|
sizeof(ULONG)
|
|||
|
);
|
|||
|
|
|||
|
if (CurrentLookahead > LOOP_MAX_LOOKAHEAD) {
|
|||
|
|
|||
|
StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if (CurrentLookahead >= Adapter->MaxLookAhead)
|
|||
|
Adapter->MaxLookAhead = CurrentLookahead;
|
|||
|
else {
|
|||
|
if (Open->CurrentLookAhead == Adapter->MaxLookAhead)
|
|||
|
LoopAdjustLookahead(Adapter);
|
|||
|
}
|
|||
|
|
|||
|
Open->CurrentLookAhead = CurrentLookahead;
|
|||
|
StatusToReturn = NDIS_STATUS_SUCCESS;
|
|||
|
|
|||
|
NdisRequest->DATA.SET_INFORMATION.BytesRead = 4;
|
|||
|
break;
|
|||
|
|
|||
|
case OID_802_3_MULTICAST_LIST:
|
|||
|
|
|||
|
if (Adapter->Medium != NdisMedium802_3) {
|
|||
|
StatusToReturn = NDIS_STATUS_INVALID_OID;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if ((InformationBufferLength % ETH_LENGTH_OF_ADDRESS) != 0) {
|
|||
|
StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
StatusToReturn = EthChangeFilterAddresses(
|
|||
|
Adapter->Filter.Eth,
|
|||
|
Open->NdisFilterHandle,
|
|||
|
NdisRequest,
|
|||
|
(UINT)(InformationBufferLength/ETH_LENGTH_OF_ADDRESS),
|
|||
|
InformationBuffer,
|
|||
|
TRUE
|
|||
|
);
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case OID_802_5_CURRENT_FUNCTIONAL:
|
|||
|
|
|||
|
if (Adapter->Medium != NdisMedium802_5) {
|
|||
|
StatusToReturn = NDIS_STATUS_INVALID_OID;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if (InformationBufferLength != TR_LENGTH_OF_FUNCTIONAL) {
|
|||
|
StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
StatusToReturn = TrChangeFunctionalAddress(
|
|||
|
Adapter->Filter.Tr,
|
|||
|
Open->NdisFilterHandle,
|
|||
|
NdisRequest,
|
|||
|
InformationBuffer,
|
|||
|
TRUE
|
|||
|
);
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case OID_802_5_CURRENT_GROUP:
|
|||
|
|
|||
|
if (Adapter->Medium != NdisMedium802_5) {
|
|||
|
StatusToReturn = NDIS_STATUS_INVALID_OID;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if (InformationBufferLength != TR_LENGTH_OF_FUNCTIONAL) {
|
|||
|
StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
StatusToReturn = TrChangeGroupAddress(
|
|||
|
Adapter->Filter.Tr,
|
|||
|
Open->NdisFilterHandle,
|
|||
|
NdisRequest,
|
|||
|
InformationBuffer,
|
|||
|
TRUE
|
|||
|
);
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case OID_FDDI_LONG_MULTICAST_LIST:
|
|||
|
|
|||
|
if (Adapter->Medium != NdisMediumFddi) {
|
|||
|
StatusToReturn = NDIS_STATUS_INVALID_OID;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if ((InformationBufferLength % FDDI_LENGTH_OF_LONG_ADDRESS) != 0) {
|
|||
|
StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
StatusToReturn = FddiChangeFilterLongAddresses(
|
|||
|
Adapter->Filter.Fddi,
|
|||
|
Open->NdisFilterHandle,
|
|||
|
NdisRequest,
|
|||
|
(UINT)(InformationBufferLength/FDDI_LENGTH_OF_LONG_ADDRESS),
|
|||
|
InformationBuffer,
|
|||
|
TRUE
|
|||
|
);
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case OID_FDDI_SHORT_MULTICAST_LIST:
|
|||
|
|
|||
|
if (Adapter->Medium != NdisMediumFddi) {
|
|||
|
StatusToReturn = NDIS_STATUS_INVALID_OID;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if ((InformationBufferLength % FDDI_LENGTH_OF_SHORT_ADDRESS) != 0) {
|
|||
|
StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
StatusToReturn = FddiChangeFilterShortAddresses(
|
|||
|
Adapter->Filter.Fddi,
|
|||
|
Open->NdisFilterHandle,
|
|||
|
NdisRequest,
|
|||
|
(UINT)(InformationBufferLength/FDDI_LENGTH_OF_SHORT_ADDRESS),
|
|||
|
InformationBuffer,
|
|||
|
TRUE
|
|||
|
);
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case OID_GEN_PROTOCOL_OPTIONS:
|
|||
|
|
|||
|
StatusToReturn = NDIS_STATUS_SUCCESS;
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
StatusToReturn = NDIS_STATUS_INVALID_OID;
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
return(StatusToReturn);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
STATIC
|
|||
|
NDIS_STATUS
|
|||
|
LoopQueryInformation(
|
|||
|
IN PLOOP_ADAPTER Adapter,
|
|||
|
IN PLOOP_OPEN Open,
|
|||
|
IN NDIS_OID Oid,
|
|||
|
IN BOOLEAN Global,
|
|||
|
IN PVOID InformationBuffer,
|
|||
|
IN UINT InformationBufferLength,
|
|||
|
OUT PUINT BytesWritten,
|
|||
|
OUT PUINT BytesNeeded
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
INT i;
|
|||
|
PNDIS_OID SupportedOidArray;
|
|||
|
INT SupportedOids;
|
|||
|
PVOID SourceBuffer;
|
|||
|
UINT SourceBufferLength;
|
|||
|
ULONG GenericUlong;
|
|||
|
USHORT GenericUshort;
|
|||
|
static UCHAR VendorDescription[] = "MS LoopBack Driver";
|
|||
|
static UCHAR VendorId[3] = {0xFF, 0xFF, 0xFF};
|
|||
|
|
|||
|
DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO, (" --> LoopQueryInformation\n"));
|
|||
|
|
|||
|
DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
|
|||
|
("OID = %lx, Global = %c\n",Oid,(Global)?'Y':'N'));
|
|||
|
|
|||
|
//
|
|||
|
// Check that the OID is valid.
|
|||
|
//
|
|||
|
|
|||
|
if (Global) {
|
|||
|
SupportedOidArray = LoopGlobalSupportedOids;
|
|||
|
SupportedOids = sizeof(LoopGlobalSupportedOids)/sizeof(ULONG);
|
|||
|
}
|
|||
|
else {
|
|||
|
SupportedOidArray = LoopProtocolSupportedOids;
|
|||
|
SupportedOids = sizeof(LoopProtocolSupportedOids)/sizeof(ULONG);
|
|||
|
}
|
|||
|
|
|||
|
for (i=0; i<SupportedOids; i++) {
|
|||
|
if (Oid == SupportedOidArray[i])
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if ((i == SupportedOids) || (((Oid & OID_TYPE) != OID_TYPE_GENERAL) &&
|
|||
|
(((Adapter->Medium == NdisMedium802_3) && ((Oid & OID_TYPE) != OID_TYPE_802_3)) ||
|
|||
|
((Adapter->Medium == NdisMedium802_5) && ((Oid & OID_TYPE) != OID_TYPE_802_5)) ||
|
|||
|
((Adapter->Medium == NdisMediumFddi) && ((Oid & OID_TYPE) != OID_TYPE_FDDI)) ||
|
|||
|
((Adapter->Medium == NdisMediumLocalTalk) && ((Oid & OID_TYPE) != OID_TYPE_LTALK)) ||
|
|||
|
((Adapter->Medium == NdisMediumArcnet878_2) && ((Oid & OID_TYPE) != OID_TYPE_ARCNET))))) {
|
|||
|
*BytesWritten = 0;
|
|||
|
return NDIS_STATUS_INVALID_OID;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Initialize these once, since this is the majority
|
|||
|
// of cases.
|
|||
|
//
|
|||
|
|
|||
|
SourceBuffer = (PVOID)&GenericUlong;
|
|||
|
SourceBufferLength = sizeof(ULONG);
|
|||
|
|
|||
|
switch (Oid & OID_TYPE_MASK) {
|
|||
|
|
|||
|
case OID_TYPE_GENERAL_OPERATIONAL:
|
|||
|
|
|||
|
switch (Oid) {
|
|||
|
|
|||
|
case OID_GEN_MAC_OPTIONS:
|
|||
|
|
|||
|
GenericUlong = (ULONG)(0);
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case OID_GEN_SUPPORTED_LIST:
|
|||
|
|
|||
|
SourceBuffer = SupportedOidArray;
|
|||
|
SourceBufferLength = SupportedOids * sizeof(ULONG);
|
|||
|
break;
|
|||
|
|
|||
|
case OID_GEN_HARDWARE_STATUS:
|
|||
|
|
|||
|
if (Adapter->ResetInProgress)
|
|||
|
GenericUlong = NdisHardwareStatusReset;
|
|||
|
else
|
|||
|
GenericUlong = NdisHardwareStatusReady;
|
|||
|
break;
|
|||
|
|
|||
|
case OID_GEN_MEDIA_SUPPORTED:
|
|||
|
case OID_GEN_MEDIA_IN_USE:
|
|||
|
|
|||
|
GenericUlong = Adapter->Medium;
|
|||
|
break;
|
|||
|
|
|||
|
case OID_GEN_MAXIMUM_LOOKAHEAD:
|
|||
|
|
|||
|
GenericUlong = LOOP_MAX_LOOKAHEAD;
|
|||
|
break;
|
|||
|
|
|||
|
case OID_GEN_MAXIMUM_FRAME_SIZE:
|
|||
|
|
|||
|
GenericUlong = Adapter->MediumMaxFrameLen;
|
|||
|
break;
|
|||
|
|
|||
|
case OID_GEN_LINK_SPEED:
|
|||
|
|
|||
|
GenericUlong = Adapter->MediumLinkSpeed;
|
|||
|
break;
|
|||
|
|
|||
|
case OID_GEN_TRANSMIT_BUFFER_SPACE:
|
|||
|
|
|||
|
GenericUlong = Adapter->MediumMaxPacketLen;
|
|||
|
break;
|
|||
|
|
|||
|
case OID_GEN_RECEIVE_BUFFER_SPACE:
|
|||
|
|
|||
|
GenericUlong = Adapter->MediumMaxPacketLen;
|
|||
|
break;
|
|||
|
|
|||
|
case OID_GEN_TRANSMIT_BLOCK_SIZE:
|
|||
|
|
|||
|
GenericUlong = 1;
|
|||
|
break;
|
|||
|
|
|||
|
case OID_GEN_RECEIVE_BLOCK_SIZE:
|
|||
|
|
|||
|
GenericUlong = 1;
|
|||
|
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:
|
|||
|
|
|||
|
switch (Adapter->Medium) {
|
|||
|
case NdisMedium802_3:
|
|||
|
case NdisMediumDix:
|
|||
|
if (Global)
|
|||
|
GenericUlong = ETH_QUERY_FILTER_CLASSES(Adapter->Filter.Eth);
|
|||
|
else
|
|||
|
GenericUlong = ETH_QUERY_PACKET_FILTER(Adapter->Filter.Eth,
|
|||
|
Open->NdisFilterHandle);
|
|||
|
break;
|
|||
|
case NdisMedium802_5:
|
|||
|
if (Global)
|
|||
|
GenericUlong = TR_QUERY_FILTER_CLASSES(Adapter->Filter.Tr);
|
|||
|
else
|
|||
|
GenericUlong = TR_QUERY_PACKET_FILTER(Adapter->Filter.Tr,
|
|||
|
Open->NdisFilterHandle);
|
|||
|
break;
|
|||
|
case NdisMediumFddi:
|
|||
|
if (Global)
|
|||
|
GenericUlong = FDDI_QUERY_FILTER_CLASSES(Adapter->Filter.Fddi);
|
|||
|
else
|
|||
|
GenericUlong = FDDI_QUERY_PACKET_FILTER(Adapter->Filter.Fddi,
|
|||
|
Open->NdisFilterHandle);
|
|||
|
break;
|
|||
|
default:
|
|||
|
if (Global)
|
|||
|
GenericUlong = LoopQueryPacketFilter(Adapter);
|
|||
|
else
|
|||
|
GenericUlong = Open->CurrentPacketFilter;
|
|||
|
break;
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case OID_GEN_CURRENT_LOOKAHEAD:
|
|||
|
|
|||
|
if (Global)
|
|||
|
GenericUlong = Adapter->MaxLookAhead;
|
|||
|
else
|
|||
|
GenericUlong = Open->CurrentLookAhead;
|
|||
|
break;
|
|||
|
|
|||
|
case OID_GEN_DRIVER_VERSION:
|
|||
|
|
|||
|
GenericUshort = (LOOP_MAJOR_VERSION << 8) + LOOP_MINOR_VERSION;
|
|||
|
SourceBuffer = &GenericUshort;
|
|||
|
SourceBufferLength = sizeof(USHORT);
|
|||
|
break;
|
|||
|
|
|||
|
case OID_GEN_MAXIMUM_TOTAL_SIZE:
|
|||
|
|
|||
|
GenericUlong = Adapter->MediumMaxPacketLen;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
ASSERT(FALSE);
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case OID_TYPE_GENERAL_STATISTICS:
|
|||
|
|
|||
|
if (Global) {
|
|||
|
|
|||
|
NDIS_OID MaskOid = (Oid & OID_INDEX_MASK) - 1;
|
|||
|
|
|||
|
switch (Oid & OID_REQUIRED_MASK) {
|
|||
|
|
|||
|
case OID_REQUIRED_MANDATORY:
|
|||
|
|
|||
|
ASSERT (MaskOid < GM_ARRAY_SIZE);
|
|||
|
|
|||
|
GenericUlong = Adapter->GeneralMandatory[MaskOid];
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
ASSERT(FALSE);
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// None of the general stats are available per-open.
|
|||
|
//
|
|||
|
|
|||
|
ASSERT(FALSE);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case OID_TYPE_802_3_OPERATIONAL:
|
|||
|
|
|||
|
switch (Oid) {
|
|||
|
|
|||
|
case OID_802_3_PERMANENT_ADDRESS:
|
|||
|
|
|||
|
SourceBuffer = Adapter->PermanentAddress;
|
|||
|
SourceBufferLength = ETH_LENGTH_OF_ADDRESS;
|
|||
|
break;
|
|||
|
case OID_802_3_CURRENT_ADDRESS:
|
|||
|
|
|||
|
SourceBuffer = Adapter->CurrentAddress;
|
|||
|
SourceBufferLength = ETH_LENGTH_OF_ADDRESS;
|
|||
|
break;
|
|||
|
|
|||
|
case OID_802_3_MULTICAST_LIST:
|
|||
|
|
|||
|
{
|
|||
|
NDIS_STATUS StatusToReturn;
|
|||
|
UINT NumAddresses;
|
|||
|
|
|||
|
if (Global) {
|
|||
|
|
|||
|
NumAddresses = ETH_NUMBER_OF_GLOBAL_FILTER_ADDRESSES(Adapter->Filter.Eth);
|
|||
|
if ((NumAddresses * ETH_LENGTH_OF_ADDRESS) > InformationBufferLength) {
|
|||
|
|
|||
|
*BytesNeeded = (NumAddresses * ETH_LENGTH_OF_ADDRESS);
|
|||
|
return NDIS_STATUS_INVALID_LENGTH;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
EthQueryGlobalFilterAddresses(
|
|||
|
&StatusToReturn,
|
|||
|
Adapter->Filter.Eth,
|
|||
|
InformationBufferLength,
|
|||
|
&NumAddresses,
|
|||
|
InformationBuffer
|
|||
|
);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
NumAddresses = EthNumberOfOpenFilterAddresses(
|
|||
|
Adapter->Filter.Eth,
|
|||
|
Open->NdisFilterHandle
|
|||
|
);
|
|||
|
|
|||
|
if ((NumAddresses * ETH_LENGTH_OF_ADDRESS) > InformationBufferLength) {
|
|||
|
|
|||
|
*BytesNeeded = (NumAddresses * ETH_LENGTH_OF_ADDRESS);
|
|||
|
return NDIS_STATUS_INVALID_LENGTH;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
EthQueryOpenFilterAddresses(
|
|||
|
&StatusToReturn,
|
|||
|
Adapter->Filter.Eth,
|
|||
|
Open->NdisFilterHandle,
|
|||
|
InformationBufferLength,
|
|||
|
&NumAddresses,
|
|||
|
InformationBuffer
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Should not be an error since we held the spinlock
|
|||
|
// nothing should have changed.
|
|||
|
//
|
|||
|
|
|||
|
ASSERT(StatusToReturn == NDIS_STATUS_SUCCESS);
|
|||
|
|
|||
|
*BytesWritten = NumAddresses * ETH_LENGTH_OF_ADDRESS;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return NDIS_STATUS_SUCCESS;
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case OID_802_3_MAXIMUM_LIST_SIZE:
|
|||
|
|
|||
|
GenericUlong = LOOP_ETH_MAX_MULTICAST_ADDRESS;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
ASSERT(FALSE);
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case OID_TYPE_802_3_STATISTICS:
|
|||
|
|
|||
|
switch (Oid) {
|
|||
|
|
|||
|
case OID_802_3_RCV_ERROR_ALIGNMENT:
|
|||
|
case OID_802_3_XMIT_ONE_COLLISION:
|
|||
|
case OID_802_3_XMIT_MORE_COLLISIONS:
|
|||
|
|
|||
|
GenericUlong = 0;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
ASSERT(FALSE);
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case OID_TYPE_802_5_OPERATIONAL:
|
|||
|
|
|||
|
switch (Oid) {
|
|||
|
|
|||
|
case OID_802_5_PERMANENT_ADDRESS:
|
|||
|
|
|||
|
SourceBuffer = Adapter->PermanentAddress;
|
|||
|
SourceBufferLength = TR_LENGTH_OF_ADDRESS;
|
|||
|
break;
|
|||
|
|
|||
|
case OID_802_5_CURRENT_ADDRESS:
|
|||
|
|
|||
|
SourceBuffer = Adapter->CurrentAddress;
|
|||
|
SourceBufferLength = TR_LENGTH_OF_ADDRESS;
|
|||
|
break;
|
|||
|
|
|||
|
case OID_802_5_CURRENT_FUNCTIONAL:
|
|||
|
|
|||
|
if (Global)
|
|||
|
GenericUlong = TR_QUERY_FILTER_ADDRESSES(Adapter->Filter.Tr);
|
|||
|
else
|
|||
|
GenericUlong = TR_QUERY_FILTER_BINDING_ADDRESS(
|
|||
|
Adapter->Filter.Tr,
|
|||
|
Open->NdisFilterHandle);
|
|||
|
|
|||
|
GenericUlong = (ULONG)(((GenericUlong >> 24) & 0xFF) |
|
|||
|
((GenericUlong >> 8) & 0xFF00) |
|
|||
|
((GenericUlong << 8) & 0xFF0000) |
|
|||
|
((GenericUlong << 24) & 0xFF000000));
|
|||
|
break;
|
|||
|
|
|||
|
case OID_802_5_CURRENT_GROUP:
|
|||
|
|
|||
|
GenericUlong = TR_QUERY_FILTER_Group(Adapter->Filter.Tr);
|
|||
|
|
|||
|
GenericUlong = (ULONG)(((GenericUlong >> 24) & 0xFF) |
|
|||
|
((GenericUlong >> 8) & 0xFF00) |
|
|||
|
((GenericUlong << 8) & 0xFF0000) |
|
|||
|
((GenericUlong << 24) & 0xFF000000));
|
|||
|
break;
|
|||
|
|
|||
|
case OID_802_5_LAST_OPEN_STATUS:
|
|||
|
|
|||
|
// just return 0 since we never return NDIS_STATUS_OPEN_ERROR
|
|||
|
|
|||
|
GenericUlong = 0;
|
|||
|
break;
|
|||
|
|
|||
|
case OID_802_5_CURRENT_RING_STATUS:
|
|||
|
|
|||
|
// need to verify validity
|
|||
|
|
|||
|
GenericUlong = NDIS_RING_SINGLE_STATION;
|
|||
|
break;
|
|||
|
|
|||
|
case OID_802_5_CURRENT_RING_STATE:
|
|||
|
|
|||
|
// might want to return NdisRingStateClosed if there are no bindings
|
|||
|
|
|||
|
GenericUlong = NdisRingStateOpened;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
ASSERT(FALSE);
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case OID_TYPE_802_5_STATISTICS:
|
|||
|
|
|||
|
switch (Oid) {
|
|||
|
|
|||
|
case OID_802_5_LINE_ERRORS:
|
|||
|
case OID_802_5_LOST_FRAMES:
|
|||
|
|
|||
|
GenericUlong = 0;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
ASSERT(FALSE);
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case OID_TYPE_FDDI_OPERATIONAL:
|
|||
|
|
|||
|
switch (Oid) {
|
|||
|
|
|||
|
case OID_FDDI_LONG_PERMANENT_ADDR:
|
|||
|
|
|||
|
SourceBuffer = Adapter->PermanentAddress;
|
|||
|
SourceBufferLength = FDDI_LENGTH_OF_LONG_ADDRESS;
|
|||
|
break;
|
|||
|
|
|||
|
case OID_FDDI_LONG_CURRENT_ADDR:
|
|||
|
|
|||
|
SourceBuffer = Adapter->CurrentAddress;
|
|||
|
SourceBufferLength = FDDI_LENGTH_OF_LONG_ADDRESS;
|
|||
|
break;
|
|||
|
|
|||
|
case OID_FDDI_LONG_MULTICAST_LIST:
|
|||
|
|
|||
|
{
|
|||
|
NDIS_STATUS StatusToReturn;
|
|||
|
UINT NumAddresses;
|
|||
|
|
|||
|
if (Global) {
|
|||
|
|
|||
|
NumAddresses = FDDI_NUMBER_OF_GLOBAL_FILTER_LONG_ADDRESSES(Adapter->Filter.Fddi);
|
|||
|
if ((NumAddresses * FDDI_LENGTH_OF_LONG_ADDRESS) > InformationBufferLength) {
|
|||
|
|
|||
|
*BytesNeeded = (NumAddresses * FDDI_LENGTH_OF_LONG_ADDRESS);
|
|||
|
return NDIS_STATUS_INVALID_LENGTH;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
FddiQueryGlobalFilterLongAddresses(
|
|||
|
&StatusToReturn,
|
|||
|
Adapter->Filter.Fddi,
|
|||
|
InformationBufferLength,
|
|||
|
&NumAddresses,
|
|||
|
InformationBuffer
|
|||
|
);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
NumAddresses = FddiNumberOfOpenFilterLongAddresses(
|
|||
|
Adapter->Filter.Fddi,
|
|||
|
Open->NdisFilterHandle
|
|||
|
);
|
|||
|
|
|||
|
if ((NumAddresses * FDDI_LENGTH_OF_LONG_ADDRESS) > InformationBufferLength) {
|
|||
|
|
|||
|
*BytesNeeded = (NumAddresses * FDDI_LENGTH_OF_LONG_ADDRESS);
|
|||
|
return NDIS_STATUS_INVALID_LENGTH;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
FddiQueryOpenFilterLongAddresses(
|
|||
|
&StatusToReturn,
|
|||
|
Adapter->Filter.Fddi,
|
|||
|
Open->NdisFilterHandle,
|
|||
|
InformationBufferLength,
|
|||
|
&NumAddresses,
|
|||
|
InformationBuffer
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Should not be an error since we held the spinlock
|
|||
|
// nothing should have changed.
|
|||
|
//
|
|||
|
|
|||
|
ASSERT(StatusToReturn == NDIS_STATUS_SUCCESS);
|
|||
|
|
|||
|
*BytesWritten = NumAddresses * FDDI_LENGTH_OF_LONG_ADDRESS;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return NDIS_STATUS_SUCCESS;
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case OID_FDDI_LONG_MAX_LIST_SIZE:
|
|||
|
|
|||
|
GenericUlong = LOOP_FDDI_MAX_MULTICAST_LONG;
|
|||
|
break;
|
|||
|
|
|||
|
case OID_FDDI_SHORT_PERMANENT_ADDR:
|
|||
|
|
|||
|
SourceBuffer = Adapter->PermanentAddress;
|
|||
|
SourceBufferLength = FDDI_LENGTH_OF_SHORT_ADDRESS;
|
|||
|
break;
|
|||
|
|
|||
|
case OID_FDDI_SHORT_CURRENT_ADDR:
|
|||
|
|
|||
|
SourceBuffer = Adapter->CurrentAddress;
|
|||
|
SourceBufferLength = FDDI_LENGTH_OF_SHORT_ADDRESS;
|
|||
|
break;
|
|||
|
|
|||
|
case OID_FDDI_SHORT_MULTICAST_LIST:
|
|||
|
|
|||
|
{
|
|||
|
NDIS_STATUS StatusToReturn;
|
|||
|
UINT NumAddresses;
|
|||
|
|
|||
|
if (Global) {
|
|||
|
|
|||
|
NumAddresses = FDDI_NUMBER_OF_GLOBAL_FILTER_SHORT_ADDRESSES(Adapter->Filter.Fddi);
|
|||
|
if ((NumAddresses * FDDI_LENGTH_OF_SHORT_ADDRESS) > InformationBufferLength) {
|
|||
|
|
|||
|
*BytesNeeded = (NumAddresses * FDDI_LENGTH_OF_SHORT_ADDRESS);
|
|||
|
return NDIS_STATUS_INVALID_LENGTH;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
FddiQueryGlobalFilterShortAddresses(
|
|||
|
&StatusToReturn,
|
|||
|
Adapter->Filter.Fddi,
|
|||
|
InformationBufferLength,
|
|||
|
&NumAddresses,
|
|||
|
InformationBuffer
|
|||
|
);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
NumAddresses = FddiNumberOfOpenFilterShortAddresses(
|
|||
|
Adapter->Filter.Fddi,
|
|||
|
Open->NdisFilterHandle
|
|||
|
);
|
|||
|
|
|||
|
if ((NumAddresses * FDDI_LENGTH_OF_SHORT_ADDRESS) > InformationBufferLength) {
|
|||
|
|
|||
|
*BytesNeeded = (NumAddresses * FDDI_LENGTH_OF_SHORT_ADDRESS);
|
|||
|
return NDIS_STATUS_INVALID_LENGTH;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
FddiQueryOpenFilterShortAddresses(
|
|||
|
&StatusToReturn,
|
|||
|
Adapter->Filter.Fddi,
|
|||
|
Open->NdisFilterHandle,
|
|||
|
InformationBufferLength,
|
|||
|
&NumAddresses,
|
|||
|
InformationBuffer
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Should not be an error since we held the spinlock
|
|||
|
// nothing should have changed.
|
|||
|
//
|
|||
|
|
|||
|
ASSERT(StatusToReturn == NDIS_STATUS_SUCCESS);
|
|||
|
|
|||
|
*BytesWritten = NumAddresses * FDDI_LENGTH_OF_SHORT_ADDRESS;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return NDIS_STATUS_SUCCESS;
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case OID_FDDI_SHORT_MAX_LIST_SIZE:
|
|||
|
|
|||
|
GenericUlong = LOOP_FDDI_MAX_MULTICAST_SHORT;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
ASSERT(FALSE);
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case OID_TYPE_LTALK_OPERATIONAL:
|
|||
|
|
|||
|
switch(Oid) {
|
|||
|
case OID_LTALK_CURRENT_NODE_ID:
|
|||
|
|
|||
|
SourceBuffer = Adapter->CurrentAddress;
|
|||
|
SourceBufferLength = 1;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
ASSERT(FALSE);
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case OID_TYPE_ARCNET_OPERATIONAL:
|
|||
|
|
|||
|
switch(Oid) {
|
|||
|
case OID_ARCNET_PERMANENT_ADDRESS:
|
|||
|
|
|||
|
SourceBuffer = Adapter->PermanentAddress;
|
|||
|
SourceBufferLength = 1;
|
|||
|
break;
|
|||
|
|
|||
|
case OID_ARCNET_CURRENT_ADDRESS:
|
|||
|
|
|||
|
SourceBuffer = Adapter->CurrentAddress;
|
|||
|
SourceBufferLength = 1;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
ASSERT(FALSE);
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
ASSERT(FALSE);
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if (SourceBufferLength > InformationBufferLength) {
|
|||
|
*BytesNeeded = SourceBufferLength;
|
|||
|
return NDIS_STATUS_BUFFER_TOO_SHORT;
|
|||
|
}
|
|||
|
|
|||
|
NdisMoveMemory(
|
|||
|
InformationBuffer,
|
|||
|
SourceBuffer,
|
|||
|
SourceBufferLength);
|
|||
|
|
|||
|
*BytesWritten = SourceBufferLength;
|
|||
|
|
|||
|
return NDIS_STATUS_SUCCESS;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
STATIC
|
|||
|
VOID
|
|||
|
LoopAdjustLookahead(
|
|||
|
IN PLOOP_ADAPTER Adapter
|
|||
|
)
|
|||
|
{
|
|||
|
PLOOP_OPEN Open;
|
|||
|
PLIST_ENTRY OpenCurrentLink;
|
|||
|
ULONG Lookahead=0;
|
|||
|
|
|||
|
OpenCurrentLink = Adapter->OpenBindings.Flink;
|
|||
|
|
|||
|
while(OpenCurrentLink != &Adapter->OpenBindings) {
|
|||
|
|
|||
|
Open = CONTAINING_RECORD(
|
|||
|
OpenCurrentLink,
|
|||
|
LOOP_OPEN,
|
|||
|
OpenList
|
|||
|
);
|
|||
|
|
|||
|
if (Open->CurrentLookAhead > Lookahead)
|
|||
|
Lookahead = Open->CurrentLookAhead;
|
|||
|
|
|||
|
OpenCurrentLink = OpenCurrentLink->Flink;
|
|||
|
}
|
|||
|
|
|||
|
Adapter->MaxLookAhead = Lookahead;
|
|||
|
}
|
|||
|
|
|||
|
STATIC
|
|||
|
ULONG
|
|||
|
LoopQueryPacketFilter(
|
|||
|
IN PLOOP_ADAPTER Adapter
|
|||
|
)
|
|||
|
{
|
|||
|
PLOOP_OPEN Open;
|
|||
|
PLIST_ENTRY OpenCurrentLink;
|
|||
|
ULONG Filter=0;
|
|||
|
|
|||
|
OpenCurrentLink = Adapter->OpenBindings.Flink;
|
|||
|
|
|||
|
while(OpenCurrentLink != &Adapter->OpenBindings) {
|
|||
|
|
|||
|
Open = CONTAINING_RECORD(
|
|||
|
OpenCurrentLink,
|
|||
|
LOOP_OPEN,
|
|||
|
OpenList
|
|||
|
);
|
|||
|
|
|||
|
Filter |= Open->CurrentPacketFilter;
|
|||
|
OpenCurrentLink = OpenCurrentLink->Flink;
|
|||
|
}
|
|||
|
|
|||
|
return Filter;
|
|||
|
}
|