#include #include #include #include #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; iMedium == 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; }