📄 miniport.c
字号:
//
// Let the miniport below handle these OIDs:
//
case OID_PNP_ADD_WAKE_UP_PATTERN:
case OID_PNP_REMOVE_WAKE_UP_PATTERN:
case OID_PNP_ENABLE_WAKE_UP:
bForwardRequest = TRUE;
break;
case OID_PNP_SET_POWER:
//
// Store new power state and succeed the request.
//
*BytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE);
if (InformationBufferLength < *BytesNeeded)
{
Status = NDIS_STATUS_INVALID_LENGTH;
break;
}
NewDeviceState = (*(PNDIS_DEVICE_POWER_STATE)InformationBuffer);
//
// Check if the VELAN adapter goes from lower power state to D0
//
if ((MUX_IS_LOW_POWER_STATE(pVElan->MPDevicePowerState))
&& (!MUX_IS_LOW_POWER_STATE(NewDeviceState)))
{
//
// Indicate the media status is necessary
//
if (pVElan->LastIndicatedStatus != pVElan->LatestUnIndicateStatus)
{
NdisMIndicateStatus(pVElan->MiniportAdapterHandle,
pVElan->LatestUnIndicateStatus,
(PVOID)NULL,
0);
NdisMIndicateStatusComplete(pVElan->MiniportAdapterHandle);
pVElan->LastIndicatedStatus = pVElan->LatestUnIndicateStatus;
}
}
//
// Check if the VELAN adapter goes from D0 to lower power state
//
if ((!MUX_IS_LOW_POWER_STATE(pVElan->MPDevicePowerState))
&& (MUX_IS_LOW_POWER_STATE(NewDeviceState)))
{
//
// Initialize LastUnIndicateStatus
//
pVElan->LatestUnIndicateStatus = pVElan->LastIndicatedStatus;
}
NdisMoveMemory(&pVElan->MPDevicePowerState,
InformationBuffer,
*BytesNeeded);
DBGPRINT(MUX_INFO, ("SetInfo: VElan %p, new miniport power state --- %d\n",
pVElan, pVElan->MPDevicePowerState));
break;
case OID_802_3_MULTICAST_LIST:
Status = MPSetMulticastList(pVElan,
InformationBuffer,
InformationBufferLength,
BytesRead,
BytesNeeded);
break;
case OID_GEN_CURRENT_PACKET_FILTER:
if (InformationBufferLength != sizeof(ULONG))
{
Status = NDIS_STATUS_INVALID_LENGTH;
*BytesNeeded = sizeof(ULONG);
break;
}
NdisMoveMemory(&PacketFilter, InformationBuffer, sizeof(ULONG));
*BytesRead = sizeof(ULONG);
Status = MPSetPacketFilter(pVElan,
PacketFilter);
break;
case OID_GEN_CURRENT_LOOKAHEAD:
#if IEEE_VLAN_SUPPORT
//
// In order to simplify parsing and to avoid excessive
// copying, we need the tag header also to be present in the
// lookahead buffer. Make sure that the driver below
// includes that.
//
*(UNALIGNED PULONG)InformationBuffer += VLAN_TAG_HEADER_SIZE;
#endif
bForwardRequest = TRUE;
break;
#if IEEE_VLAN_SUPPORT
case OID_GEN_VLAN_ID:
if (InformationBufferLength != sizeof(ULONG))
{
Status = NDIS_STATUS_INVALID_LENGTH;
*BytesNeeded = sizeof(ULONG);
break;
}
NdisMoveMemory(&(pVElan->VlanId), InformationBuffer, sizeof(ULONG));
break;
#endif
default:
Status = NDIS_STATUS_INVALID_OID;
break;
}
if (bForwardRequest == FALSE)
{
if (Status == NDIS_STATUS_SUCCESS)
{
*BytesRead = InformationBufferLength;
}
}
else
{
//
// Send this request to the binding below.
//
Status = MPForwardRequest(pVElan,
NdisRequestSetInformation,
Oid,
InformationBuffer,
InformationBufferLength,
BytesRead,
BytesNeeded);
}
return(Status);
}
VOID
MPReturnPacket(
IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET Packet
)
/*++
Routine Description:
NDIS Miniport entry point called whenever protocols are done with
a packet that we had indicated up and they had queued up for returning
later.
Arguments:
MiniportAdapterContext - pointer to VELAN structure
Packet - packet being returned.
Return Value:
None.
--*/
{
PVELAN pVElan = (PVELAN)MiniportAdapterContext;
PNDIS_PACKET pOriginalPacket;
PMUX_RECV_RSVD pRecvRsvd;
pRecvRsvd = MUX_RSVD_FROM_RECV_PACKET(Packet);
pOriginalPacket = pRecvRsvd->pOriginalPacket;
//
// Reclaim our packet.
//
#if IEEE_VLAN_SUPPORT
//
// If we did remove the tag header from the received packet,
// we would have allocated a buffer to describe the "untagged"
// header (see PtHandleRcvTagging); free it.
//
if (pRecvRsvd->AllocatedNdisBuffer != NULL)
{
ASSERT(pRecvRsvd->AllocatedNdisBuffer == NDIS_PACKET_FIRST_NDIS_BUFFER(Packet));
NdisFreeBuffer(NDIS_PACKET_FIRST_NDIS_BUFFER(Packet));
}
#endif
NdisFreePacket(Packet);
//
// Return the original packet received at our protocol
// edge, if any.
//
// NOTE that we might end up calling NdisReturnPackets
// multiple times with the same "lower" packet, based on
// the number of VELANs to which we had indicated that
// packet. The number of times we do so should match
// the return value from our PtReceivePacket handler.
//
if (pOriginalPacket != NULL)
{
NdisReturnPackets(&pOriginalPacket, 1);
}
else
{
//
// If no original packet, then we have been called
// here to reclaim a packet used to forward up
// a non-packet receive (see PtReceive). There
// is nothing more to be done.
//
}
MUX_DECR_PENDING_RECEIVES(pVElan);
}
NDIS_STATUS
MPTransferData(
OUT PNDIS_PACKET Packet,
OUT PUINT BytesTransferred,
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_HANDLE MiniportReceiveContext,
IN UINT ByteOffset,
IN UINT BytesToTransfer
)
/*++
Routine Description:
Miniport's transfer data handler. This is called if we had
indicated receive data using a non-packet API, for e.g. if
the lookahead buffer did not contain the entire data.
We need to forward this to the miniport below to that it can
copy in the rest of the data. We call NdisTransferData to do so.
However, when that completes (see PtTransferDataComplete), we
have to get back at the VELAN from which this packet came so that
we can complete this request with the right MiniportAdapterHandle.
We therefore allocate a new packet, pointing to the same buffer
as the packet just passed in, and use reserved space in the packet
to hold a backpointer to the VELAN from which this came.
Arguments:
Packet Destination packet
BytesTransferred Place to return how much data was copied
MiniportAdapterContext Pointer to the VELAN structure
MiniportReceiveContext Context
ByteOffset Offset into the packet for copying data
BytesToTransfer How much to copy.
Return Value:
Status of transfer
--*/
{
PVELAN pVElan = (PVELAN)MiniportAdapterContext;
NDIS_STATUS Status;
PNDIS_PACKET MyPacket;
PMUX_TD_RSVD pTDReserved;
#if IEEE_VLAN_SUPPORT
PMUX_RCV_CONTEXT pMuxRcvContext;
#endif
do
{
NdisAllocatePacket(&Status,
&MyPacket,
pVElan->SendPacketPoolHandle);
if (Status != NDIS_STATUS_SUCCESS)
{
break;
}
pTDReserved = MUX_RSVD_FROM_TD_PACKET(MyPacket);
pTDReserved->pOriginalPacket = Packet;
pTDReserved->pVElan = pVElan;
NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet) |
MUX_SEND_PACKET_FLAGS;
NDIS_PACKET_FIRST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(Packet);
NDIS_PACKET_LAST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(Packet);
#ifdef WIN9X
//
// Work around the fact that NDIS does not initialize this
// field on Win9x.
//
NDIS_PACKET_VALID_COUNTS(MyPacket) = FALSE;
#endif // WIN9X
#if IEEE_VLAN_SUPPORT
//
// Check if the original received packet did contain a
// VLAN tag header. If so, make sure we get the upcoming
// call to NdisTransferData to skip the tag header.
//
pMuxRcvContext = (PMUX_RCV_CONTEXT)MiniportReceiveContext;
if (pMuxRcvContext->TagHeaderLen == VLAN_TAG_HEADER_SIZE)
{
//
// There was a tag header in the received packet.
//
ByteOffset += VLAN_TAG_HEADER_SIZE;
//
// Copy the 8021Q info into the packet
//
NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, Ieee8021QInfo) =
pMuxRcvContext->NdisPacket8021QInfo.Value;
}
//
// Get back the lower driver's receive context for this indication.
//
MiniportReceiveContext = pMuxRcvContext->MacRcvContext;
#endif
NdisTransferData(&Status,
pVElan->pAdapt->BindingHandle,
MiniportReceiveContext,
ByteOffset,
BytesToTransfer,
MyPacket,
BytesTransferred);
if (Status != NDIS_STATUS_PENDING)
{
PtTransferDataComplete(pVElan->pAdapt,
MyPacket,
Status,
*BytesTransferred);
Status = NDIS_STATUS_PENDING;
}
}
while (FALSE);
return(Status);
}
VOID
MPHalt(
IN NDIS_HANDLE MiniportAdapterContext
)
/*++
Routine Description:
Halt handler. Add any further clean-up for the VELAN to this
function.
We wait for all pending I/O on the VELAN to complete and then
unlink the VELAN from the adapter.
Arguments:
MiniportAdapterContext Pointer to the pVElan
Return Value:
None.
--*/
{
PVELAN pVElan = (PVELAN)MiniportAdapterContext;
DBGPRINT(MUX_LOUD, ("==>MiniportHalt: VELAN %p\n", pVElan));
//
// Mark the VELAN so that we don't send down any new requests or
// sends to the adapter below, or new receives/indications to
// protocols above.
//
pVElan->MiniportHalting = TRUE;
//
// Update the packet filter on the underlying adapter if needed.
//
if (pVElan->PacketFilter != 0)
{
MPSetPacketFilter(pVElan, 0);
}
//
// Wait for any outstanding sends or requests to complete.
//
while (pVElan->OutstandingSends)
{
DBGPRINT(MUX_INFO, ("MiniportHalt: VELAN %p has %d outstanding sends\n",
pVElan, pVElan->OutstandingSends));
NdisMSleep(20000);
}
//
// Wait for all outstanding indications to be completed and
// any pended receive packets to be returned to us.
//
while (pVElan->OutstandingReceives)
{
DBGPRINT(MUX_INFO, ("MiniportHalt: VELAN %p has %d outstanding receives\n",
pVElan, pVElan->OutstandingReceives));
NdisMSleep(20000);
}
//
// Delete the ioctl interface that was created when the miniport
// was created.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -