📄 filter.c
字号:
FILTER_ACQUIRE_LOCK(&pFilter->Lock, FALSE);
ASSERT(pFilter->PendingOidRequest == Request);
pFilter->PendingOidRequest = NULL;
FILTER_RELEASE_LOCK(&pFilter->Lock, FALSE);
//
// Copy the information from the returned request to the original request
//
switch(Request->RequestType)
{
case NdisRequestMethod:
OriginalRequest->DATA.METHOD_INFORMATION.OutputBufferLength = Request->DATA.METHOD_INFORMATION.OutputBufferLength;
OriginalRequest->DATA.METHOD_INFORMATION.BytesRead = Request->DATA.METHOD_INFORMATION.BytesRead;
OriginalRequest->DATA.METHOD_INFORMATION.BytesNeeded = Request->DATA.METHOD_INFORMATION.BytesNeeded;
OriginalRequest->DATA.METHOD_INFORMATION.BytesWritten = Request->DATA.METHOD_INFORMATION.BytesWritten;
break;
case NdisRequestSetInformation:
OriginalRequest->DATA.SET_INFORMATION.BytesRead = Request->DATA.SET_INFORMATION.BytesRead;
OriginalRequest->DATA.SET_INFORMATION.BytesNeeded = Request->DATA.SET_INFORMATION.BytesNeeded;
break;
case NdisRequestQueryInformation:
case NdisRequestQueryStatistics:
default:
OriginalRequest->DATA.QUERY_INFORMATION.BytesWritten = Request->DATA.QUERY_INFORMATION.BytesWritten;
OriginalRequest->DATA.QUERY_INFORMATION.BytesNeeded = Request->DATA.QUERY_INFORMATION.BytesNeeded;
break;
}
(*Context) = NULL;
NdisFreeCloneOidRequest(pFilter->FilterHandle, Request);
NdisFOidRequestComplete(pFilter->FilterHandle, OriginalRequest, Status);
DEBUGP(DL_TRACE, ("<===FilterOidRequestComplete.\n"));
}
VOID
FilterStatus(
IN NDIS_HANDLE FilterModuleContext,
IN PNDIS_STATUS_INDICATION StatusIndication
)
/*++
Routine Description:
Indicate Status Handle
Arguments:
FilterModuleContext: Pointer to our filter
GeneralStatus:
StatusBuffer:
StatusBufferSize:
Return Value:
NONE
NOTE: called at <= DISPATCH_LEVEL
FILTER driver may call NdisFIndicateStatus to generate status indication to all higher layer modules.
--*/
{
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext;
NDIS_STATUS GeneralStatus = StatusIndication->StatusCode;
PVOID StatusBuffer = StatusIndication->StatusBuffer;
UINT StatusBufferSize = StatusIndication->StatusBufferSize;
DEBUGP(DL_TRACE, ("===>FilterStaus, IndicateStatus = %8x.\n", GeneralStatus));
#if DBG
FILTER_ACQUIRE_LOCK(&pFilter->Lock, FALSE);
ASSERT(pFilter->bIndicating == FALSE);
pFilter->bIndicating = TRUE;
FILTER_RELEASE_LOCK(&pFilter->Lock, FALSE);
#endif
// Now, No status need to handle by the filter. May get one later
//
NdisFIndicateStatus(pFilter->FilterHandle, StatusIndication);
#if DBG
FILTER_ACQUIRE_LOCK(&pFilter->Lock, FALSE);
ASSERT(pFilter->bIndicating == TRUE);
pFilter->bIndicating = FALSE;
FILTER_RELEASE_LOCK(&pFilter->Lock, FALSE);
#endif
DEBUGP(DL_TRACE, ("<===FilterStaus.\n"));
}
VOID
FilterDevicePnPEventNotify(
IN NDIS_HANDLE FilterModuleContext,
IN PNET_DEVICE_PNP_EVENT NetDevicePnPEvent
)
/*++
Routine Description:
FilterPnpEvent handler
Arguments:
FilterModuleContext: Pointer to our filter
NetPnPEvent: Pointer to an PnP event
Return Value:
NONE
NOTE: called at PASSIVE_LEVEL
--*/
{
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
NDIS_DEVICE_PNP_EVENT DevicePnPEvent = NetDevicePnPEvent->DevicePnPEvent;
PVOID InformationBuffer = NetDevicePnPEvent->InformationBuffer;
ULONG InformationBufferLength = NetDevicePnPEvent->InformationBufferLength;
DEBUGP(DL_TRACE, ("===>FilterDevicePnPEventNotify: NetPnPEvent = %p.\n", NetDevicePnPEvent));
switch (DevicePnPEvent)
{
case NdisDevicePnPEventQueryRemoved:
case NdisDevicePnPEventRemoved:
case NdisDevicePnPEventSurpriseRemoved:
case NdisDevicePnPEventQueryStopped:
case NdisDevicePnPEventStopped:
case NdisDevicePnPEventPowerProfileChanged:
case NdisDevicePnPEventFilterListChanged:
break;
default:
DEBUGP(DL_ERROR, ("FilterDevicePnPEventNotify: Invalid event.\n"));
FILTER_ASSERT(FALSE);
break;
}
NdisFDevicePnPEventNotify(pFilter->FilterHandle, NetDevicePnPEvent);
DEBUGP(DL_TRACE, ("<===FilterDevicePnPEventNotify\n"));
}
NDIS_STATUS
FilterNetPnPEvent(
IN NDIS_HANDLE FilterModuleContext,
IN PNET_PNP_EVENT_NOTIFICATION NetPnPEventNotification
)
{
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
Status = NdisFNetPnPEvent(pFilter->FilterHandle, NetPnPEventNotification);
return Status;
}
VOID
FilterSendNetBufferListsComplete(
IN NDIS_HANDLE FilterModuleContext,
IN PNET_BUFFER_LIST NetBufferLists,
IN ULONG SendCompleteFlags
)
/*++
Routine Description:
SendNetBufferListComplete
Arguments:
Return Value:
NONE
--*/
{
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext;
ULONG NumOfSendCompletes = 0;
BOOLEAN DispatchLevel;
PNET_BUFFER_LIST CurrNbl;
DEBUGP(DL_TRACE, ("===>SendNBLComplete, NetBufferList: %p.\n", NetBufferLists));
//
// if necessary, undo any modifications to the NetBufferList thate were performed "on the way down"
//
if (pFilter->TrackSends)
{
CurrNbl = NetBufferLists;
while (CurrNbl)
{
NumOfSendCompletes++;
CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);
}
DispatchLevel = NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendCompleteFlags);
FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);
pFilter->OutstandingSends -= NumOfSendCompletes;
FILTER_LOG_SEND_REF(2, pFilter, PrevNbl, pFilter->OutstandingSends);
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);
}
NdisFSendNetBufferListsComplete(pFilter->FilterHandle, NetBufferLists, SendCompleteFlags);
DEBUGP(DL_TRACE, ("<===SendNBLComplete.\n"));
}
VOID
FilterSendNetBufferLists(
IN NDIS_HANDLE FilterModuleContext,
IN PNET_BUFFER_LIST NetBufferLists,
IN NDIS_PORT_NUMBER PortNumber,
IN ULONG SendFlags
)
/*++
Routine Description:
Send Net Buffer List handler
This function is an optional function for filter drivers. If provided, NDIS
will call this function to transmit a linked list of NetBuffers, described by a
NetBuferList, over the network. If this handler is NULL, NDIS will skip calling
this fitler when sending a NetBufferList and will call the next lower fitler
in the stack with a non_NULL FilterSendNetBufferList handleror the miniport driver.
A filter that doesn't provide a FilerSendNetBufferList handler can not initiate a
send o its own.
Arguments:
FilterModuleContext: Pointer to our filter context area.
NetBufferLists: Pointer to a List of NetBufferLists.
PortNumber - Port Number to which this send is targetted
SendFlags- Specifies if the call is at DISPATCH_LEVEL
Return Value:
NDIS_STATUS_SUCCESS:
NDIS_STATUS_PENDING:
NDIS_STATUS_INVALID_PACKET:
NDIS_STATUS_RESOURCES:
NDIS_STATUS_FAILURE:
NOTE: The filter will act like a passthru filter.
--*/
{
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PNET_BUFFER_LIST CurrNbl;
BOOLEAN DispatchLevel;
DEBUGP(DL_TRACE, ("===>SendNetBufferList: NBL = %p.\n", NetBufferLists));
do
{
DispatchLevel = NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendFlags);
#if DBG
//
// we should never get packets to send if we are not in running state
//
FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);
//
// If the filter is not in running state, fail the send
//
if (pFilter->State != FilterRunning)
{
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);
CurrNbl = NetBufferLists;
while (CurrNbl)
{
NET_BUFFER_LIST_STATUS(CurrNbl) = NDIS_STATUS_PAUSED;
CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);
}
NdisFSendNetBufferListsComplete(pFilter->FilterHandle,
NetBufferLists,
DispatchLevel ? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0);
break;
}
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);
#endif
if (pFilter->TrackSends)
{
FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);
CurrNbl = NetBufferLists;
while (CurrNbl)
{
pFilter->OutstandingSends++;
FILTER_LOG_SEND_REF(1, pFilter, CurrNbl, pFilter->OutstandingSends);
CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);
}
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);
}
//
// If necessary, queue the NetBufferList in a local structure for later processing
//
NdisFSendNetBufferLists(pFilter->FilterHandle, NetBufferLists, PortNumber, SendFlags);
}
while (FALSE);
DEBUGP(DL_TRACE, ("<===SendNetBufferList: Status = %8x.\n", Status));
}
VOID
FilterReturnNetBufferLists(
IN NDIS_HANDLE FilterModuleContext,
IN PNET_BUFFER_LIST NetBufferLists,
IN ULONG ReturnFlags
)
/*++
Routine Description:
FilerReturnNetBufferLists handler
FilterReturnNetBufferLists is an optional function. If provided NDIS calls
FitlerReturnNetBufferLists to return the ownership of one or more NetBufferLists
and their embedded NetBuffers to the filter driver. If this handler is NULL, NDIS
will skip calling this fitler when returning NetBufferLists to the underlying
miniport and will call the next lower fitler in the stack with a non_NULL
FilterReturnNetBufferLists handler or the miniport driver. A filter that doesn't
provide a FitlerReturnNetBufferLists handler cannot initiate a receive indication
on its own.
Arguments:
FitlerInstanceContext: Pointer to our filter context area.
NetBufferLists: A linked list of NetBufferLists that filter driver indicated by a
previous call to NdisFIndicateReceiveNetBufferLists.
ReturnFlags: Flags specifying if the caller is at DISPATCH_LEVEL
Return Value:
NONE
--*/
{
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext;
PNET_BUFFER_LIST CurrNbl = NULL;
UINT NumOfNetBufferLists = 0;
BOOLEAN DispatchLevel;
ULONG Ref;
DEBUGP(DL_TRACE, ("===>ReturnNetBufferLists, NetBufferLists is %p.\n", NetBufferLists));
if (pFilter->TrackReceives)
{
while (CurrNbl)
{
//
// Undo the operations it did with the NetBufferList on the receive indication
//
NumOfNetBufferLists ++;
CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);
}
}
NdisFReturnNetBufferLists(pFilter->FilterHandle, NetBufferLists, ReturnFlags);
if (pFilter->TrackReceives)
{
DispatchLevel = NDIS_TEST_RETURN_AT_DISPATCH_LEVEL(ReturnFlags);
FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);
pFilter->OutstandingRcvs -= NumOfNetBufferLists;
Ref = pFilter->OutstandingRcvs;
FILTER_LOG_RCV_REF(3, pFilter, NetBufferLists, Ref);
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);
}
DEBUGP(DL_TRACE, ("<===ReturnNetBufferLists.\n"));
}
VOID
FilterReceiveNetBufferLists(
IN NDIS_HANDLE FilterModuleContext,
IN PNET_BUFFER_LIST NetBufferLists,
IN NDIS_PORT_NUMBER PortNumber,
IN ULONG NumberOfNetBufferLists,
IN ULONG ReceiveFlags
)
/*++
Routine Description:
FilerReceiveNetBufferLists is an optional function for filter drivers.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -