📄 miniport.c
字号:
0x02 | (((UCHAR)pVElan->VElanNumber & 0x3f) << 3);
ETH_COPY_NETWORK_ADDRESS(
pVElan->CurrentAddress,
pVElan->PermanentAddress);
DBGPRINT(MUX_LOUD, ("%d CurrentAddress %s\n",
pVElan->VElanNumber, MacAddrToString(&pVElan->CurrentAddress)));
DBGPRINT(MUX_LOUD, ("%d PermanentAddress %s\n",
pVElan->VElanNumber, MacAddrToString(&pVElan->PermanentAddress)));
}
#ifdef NDIS51_MINIPORT
VOID
MPCancelSendPackets(
IN NDIS_HANDLE MiniportAdapterContext,
IN PVOID CancelId
)
/*++
Routine Description:
The miniport entry point to handle cancellation of all send packets
that match the given CancelId. If we have queued any packets that match
this, then we should dequeue them and call NdisMSendComplete for all
such packets, with a status of NDIS_STATUS_REQUEST_ABORTED.
We should also call NdisCancelSendPackets in turn, on each lower binding
that this adapter corresponds to. This is to let miniports below cancel
any matching packets.
Arguments:
MiniportAdapterContext - pointer to VELAN structure
CancelId - ID of packets to be cancelled.
Return Value:
None
--*/
{
PVELAN pVElan = (PVELAN)MiniportAdapterContext;
//
// If we queue packets on our VELAN/adapter structure, this would be
// the place to acquire a spinlock to it, unlink any packets whose
// Id matches CancelId, release the spinlock and call NdisMSendComplete
// with NDIS_STATUS_REQUEST_ABORTED for all unlinked packets.
//
//
// Next, pass this down so that we let the miniport(s) below cancel
// any packets that they might have queued.
//
NdisCancelSendPackets(pVElan->pAdapt->BindingHandle, CancelId);
return;
}
VOID
MPDevicePnPEvent(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_DEVICE_PNP_EVENT DevicePnPEvent,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength
)
/*++
Routine Description:
This handler is called to notify us of PnP events directed to
our miniport device object.
Arguments:
MiniportAdapterContext - pointer to VELAN structure
DevicePnPEvent - the event
InformationBuffer - Points to additional event-specific information
InformationBufferLength - length of above
Return Value:
None
--*/
{
// TBD - add code/comments about processing this.
UNREFERENCED_PARAMETER(MiniportAdapterContext);
UNREFERENCED_PARAMETER(DevicePnPEvent);
UNREFERENCED_PARAMETER(InformationBuffer);
UNREFERENCED_PARAMETER(InformationBufferLength);
return;
}
VOID
MPAdapterShutdown(
IN NDIS_HANDLE MiniportAdapterContext
)
/*++
Routine Description:
This handler is called to notify us of an impending system shutdown.
Since this is not a hardware driver, there isn't anything specific
we need to do about this.
Arguments:
MiniportAdapterContext - pointer to VELAN structure
Return Value:
None
--*/
{
UNREFERENCED_PARAMETER(MiniportAdapterContext);
return;
}
#endif // NDIS51_MINIPORT
VOID
MPUnload(
IN PDRIVER_OBJECT DriverObject
)
{
NDIS_STATUS Status;
#if !DBG
UNREFERENCED_PARAMETER(DriverObject);
#endif
DBGPRINT(MUX_LOUD, ("==> MPUnload: DriverObj %p\n", DriverObject));
NdisDeregisterProtocol(&Status, ProtHandle);
DBGPRINT(MUX_LOUD, ("<== MPUnload \n"));
}
#if IEEE_VLAN_SUPPORT
NDIS_STATUS
MPHandleSendTagging(
IN PVELAN pVElan,
IN PNDIS_PACKET Packet,
IN OUT PNDIS_PACKET MyPacket
)
/*++
Routine Description:
This function is called when the driver supports IEEE802Q tagging.
It checks the packet to be sent on a VELAN and inserts a tag header
if necessary.
Arguments:
PVELAN - pointer to VELAN structure
Packet - pointer to original packet
MyPacket - pointer to the new allocated packet
Return Value:
NDIS_STATUS_SUCCESS if the packet was successfully parsed
and hence should be passed down to the lower driver. NDIS_STATUS_XXX
otherwise.
--*/
{
NDIS_PACKET_8021Q_INFO NdisPacket8021qInfo;
PVOID pEthTagBuffer;
PNDIS_BUFFER pNdisBuffer;
PVOID pVa;
ULONG BufferLength;
PNDIS_BUFFER pFirstBuffer;
PNDIS_BUFFER pSecondBuffer;
NDIS_STATUS Status;
NDIS_STATUS Status2;
PVOID pStartVa = NULL;
BOOLEAN IsFirstVa;
PVLAN_TAG_HEADER pTagHeader;
PUSHORT pTpid;
ULONG BytesToSkip;
PUSHORT pTypeLength;
//
// Add tag header here
//
Status = NDIS_STATUS_SUCCESS;
NdisPacket8021qInfo.Value = NDIS_PER_PACKET_INFO_FROM_PACKET(
MyPacket,
Ieee8021QInfo);
do
{
//
// If the vlan ID of the virtual miniport is 0, the miniport should act like it doesn't
// support VELAN tag processing
//
if (pVElan->VlanId == 0)
{
break;
}
//
// Insert a tag only if we have a configured VLAN ID
//
//
// We don't support E-RIF
//
if (NdisPacket8021qInfo.TagHeader.CanonicalFormatId)
{
//
// skip the packet, return NDIS_STATUS_FAILURE
//
Status = NDIS_STATUS_INVALID_PACKET;
break;
}
//
// The Vlan Id must be the same as the configured VLAN ID if it is non-zero
//
if ((NdisPacket8021qInfo.TagHeader.VlanId)
&& (NdisPacket8021qInfo.TagHeader.VlanId != pVElan->VlanId))
{
Status = NDIS_STATUS_INVALID_PACKET;
break;
}
//
// Find the virtual address after the Ethernet Header
//
BytesToSkip = ETH_HEADER_SIZE;
pNdisBuffer = NDIS_PACKET_FIRST_NDIS_BUFFER(Packet);
IsFirstVa = TRUE;
//
// Assume the Ethernet Header is in the first buffer of the packet.
// The following loop is to find the start address of the data after
// the ethernet header. This may be either in the first NDIS buffer
// or in the second.
//
while (TRUE)
{
#ifdef NDIS51_MINIPORT
NdisQueryBufferSafe(pNdisBuffer, &pVa, (PUINT)&BufferLength, NormalPagePriority);
#else
NdisQueryBuffer(pNdisBuffer, &pVa, &BufferLength);
#endif
//
// The query can fail if the system is low on resources.
//
if (pVa == NULL)
{
break;
}
//
// Remember the start of the ethernet header for later.
//
if (IsFirstVa)
{
pStartVa = pVa;
IsFirstVa = FALSE;
}
//
// Have we gone far enough into the packet?
//
if (BytesToSkip == 0)
{
break;
}
//
// Does the current buffer contain bytes past the Ethernet
// header? If so, stop.
//
if (BufferLength > BytesToSkip)
{
pVa = (PVOID)((PUCHAR)pVa + BytesToSkip);
BufferLength -= BytesToSkip;
break;
}
//
// We haven't gone past the Ethernet header yet, so go
// to the next buffer.
//
BytesToSkip -= BufferLength;
pNdisBuffer = NDIS_BUFFER_LINKAGE(pNdisBuffer);
}
if (pVa == NULL)
{
Status = NDIS_STATUS_RESOURCES;
break;
}
//
// Allocate space for the Ethernet + VLAN tag header.
//
pEthTagBuffer = NdisAllocateFromNPagedLookasideList(&pVElan->TagLookaside);
//
// Memory allocation failed, can't send out the packet
//
if (pEthTagBuffer == NULL)
{
Status = NDIS_STATUS_RESOURCES;
break;
}
//
// Allocate NDIS buffers for the Ethernet + VLAN tag header and
// the data that follows these.
//
NdisAllocateBuffer(&Status,
&pSecondBuffer,
pVElan->BufferPoolHandle,
pVa, // byte following the Eth+tag headers
BufferLength);
NdisAllocateBuffer(&Status2,
&pFirstBuffer,
pVElan->BufferPoolHandle,
pEthTagBuffer,
ETH_HEADER_SIZE + VLAN_TAG_HEADER_SIZE);
if (Status != NDIS_STATUS_SUCCESS || Status2 != NDIS_STATUS_SUCCESS)
{
//
// One of the buffer allocations failed.
//
if (Status == NDIS_STATUS_SUCCESS)
{
NdisFreeBuffer(pSecondBuffer);
}
if (Status2 == NDIS_STATUS_SUCCESS)
{
NdisFreeBuffer(pFirstBuffer);
}
NdisFreeToNPagedLookasideList(&pVElan->TagLookaside, pEthTagBuffer);
Status = NDIS_STATUS_RESOURCES;
break;
}
//
// All allocations were successful, now prepare the packet
// to be sent down to the lower driver.
//
NDIS_PACKET_FIRST_NDIS_BUFFER(MyPacket) = NDIS_BUFFER_LINKAGE(pNdisBuffer);
NdisChainBufferAtFront(MyPacket, pSecondBuffer)
NdisChainBufferAtFront(MyPacket, pFirstBuffer)
//
// Prepare the Ethernet and tag headers.
//
NdisMoveMemory(pEthTagBuffer, pStartVa, 2 * ETH_LENGTH_OF_ADDRESS);
pTpid = (PUSHORT)((PUCHAR)pEthTagBuffer + 2 * ETH_LENGTH_OF_ADDRESS);
*pTpid = TPID;
pTagHeader = (PVLAN_TAG_HEADER)(pTpid + 1);
//
// Write Ieee 802Q info to packet frame
//
INITIALIZE_TAG_HEADER_TO_ZERO(pTagHeader);
if (NdisPacket8021qInfo.Value)
{
SET_USER_PRIORITY_TO_TAG(pTagHeader, NdisPacket8021qInfo.TagHeader.UserPriority);
}
else
{
SET_USER_PRIORITY_TO_TAG(pTagHeader, 0);
}
SET_CANONICAL_FORMAT_ID_TO_TAG (pTagHeader, 0);
if (NdisPacket8021qInfo.TagHeader.VlanId)
{
SET_VLAN_ID_TO_TAG (pTagHeader, NdisPacket8021qInfo.TagHeader.VlanId);
}
else
{
SET_VLAN_ID_TO_TAG (pTagHeader, pVElan->VlanId);
}
pTypeLength = (PUSHORT)((PUCHAR)pTagHeader + sizeof(pTagHeader->TagInfo));
*pTypeLength = *((PUSHORT)((PUCHAR)pStartVa + 2 * ETH_LENGTH_OF_ADDRESS));
//
// Clear the Ieee8021QInfo field in packet being sent down
// to prevent double tag insertion!
//
NDIS_PER_PACKET_INFO_FROM_PACKET(MyPacket, Ieee8021QInfo) = 0;
}
while (FALSE);
return Status;
}
#endif // IEEE_VLAN_SUPPORT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -