|
标 题: 【原创】NDIS中间层驱动开发在Win7系统下和Windows XP系统下的区别
作 者: tianhz
时 间: 2011-07-21,14:58:04
链 接: http://bbs.pediy.com/showthread.php?t=137545
NDIS中间层驱动的开发在Win7系统上和Windows XP系统上有差别。
我把NDIS中间层的讨论分成2块。 windows 7系统和Windows XP系统。
(一)在 Windows XP系统上进行开发
平时很多朋友包括我在内,我们都在XP系统上使用NDIS5.1的框架来进行程序开发。我们都使用
Microsoft WDK提供的 NDIS 的 Passthru例子,在这个例子上做进一步的修改,来达到我们的目地。
在Passthru工程的 DriverEntry函数里面,我们都看见如下的代码:
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
NDIS_STATUS Status;
NDIS_PROTOCOL_CHARACTERISTICS PChars;
NDIS_MINIPORT_CHARACTERISTICS MChars;
PNDIS_CONFIGURATION_PARAMETER Param;
NDIS_STRING Name;
NDIS_HANDLE WrapperHandle;
UNICODE_STRING nameString, linkString;
UINT FuncIndex;
PDEVICE_OBJECT MyDeviceObject;
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
Status = NDIS_STATUS_SUCCESS;
//申请自旋锁 以到达资源共享的同步访问
NdisAllocateSpinLock(&GlobalLock);
//调用NdisMInitializeWrapper函数来保存在NdisWrapperHandle返回的句柄
NdisMInitializeWrapper(&NdisWrapperHandle, DriverObject, RegistryPath, NULL);
do
{
//调用NdisMInitializeWrapper函数来保存在WrapperHandle返回的句柄
NdisMInitializeWrapper(&WrapperHandle, DriverObject, RegistryPath, NULL);
//对于MiniportCharacteristics组件,如果驱动程序不用导出MiniportXxx这样的函数,则必须赋值为NULL。
//如果要导出任何新版本的V4.0或V5.0的MiniportXxx函数,那么中间层驱动程序的主版本必须是V4.0,并且提供4.0或5.0版本的MiniportCharacteristics组件.
NdisZeroMemory(&MChars, sizeof(NDIS_MINIPORT_CHARACTERISTICS));
MChars.MajorNdisVersion = PASSTHRU_MAJOR_NDIS_VERSION;
MChars.MinorNdisVersion = PASSTHRU_MINOR_NDIS_VERSION;
/***************************************************
下面开始注册中间层驱动程序的 MiniportXxx函数
***************************************************/
MChars.HaltHandler = MPHalt;
MChars.InitializeHandler = MPInitialize;
MChars.QueryInformationHandler = MPQueryInformation;
MChars.SetInformationHandler = MPSetInformation;
MChars.ResetHandler = MPReset;
MChars.SendHandler = NULL;
MChars.SendPacketsHandler = MPSendPackets;
MChars.TransferDataHandler = MPTransferData;
MChars.ReturnPacketHandler = MPReturnPacket;
MChars.CheckForHangHandler = NULL;
#ifdef NDIS51_MINIPORT
MChars.CancelSendPacketsHandler = MPCancelSendPackets;
MChars.PnPEventNotifyHandler = MPDevicePnPEvent;
MChars.AdapterShutdownHandler = MPAdapterShutdown;
#endif // NDIS51_MINIPORT
/*
传递上一步保存的句柄,并调用NdisIMRegisterLayeredMiniport函数来注册驱动程序的MiniportXxx系列函数。其中句柄NdisWrapperHandle是由先前的NdisMInitializeWrapper函数返回的。
当驱动程序调用NdisIMInitializeDeviceInstance函数,请求中间层驱动程序的MiniportInitialize函数对虚拟NIC进行初始化时,需要把句柄NdisWrapperHandle传入NDIS
当中间层驱动程序成功地绑定到一个或者多个NIC驱动程序上的时候, 或者是绑定到一个非NIC驱动程序上的时候也会调用NdisIMInitializeDeviceInstance函数。这样做使得中间层驱动程序可以初始化Miniport组件来接受虚拟NIC上的I/O请求
*/
Status = NdisIMRegisterLayeredMiniport(NdisWrapperHandle, &MChars, sizeof(MChars), &DriverHandle);
if (Status != NDIS_STATUS_SUCCESS)
{
break;
}
#ifndef WIN9X
NdisMRegisterUnloadHandler(NdisWrapperHandle, PtUnload);
#endif
//中间层驱动程序要做的事情:
//初始化NDIS_PROTOCOL_CHARACTERISTICS类型的结构. NDIS不再支持3.0版本的协议驱动.
//能够使用4.0或5.0版本的ProtocolCharacteristic结构体,协议驱动必须支持PNP即插即用功能.
NdisZeroMemory(&PChars, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
PChars.MajorNdisVersion = PASSTHRU_PROT_MAJOR_NDIS_VERSION;
PChars.MinorNdisVersion = PASSTHRU_PROT_MINOR_NDIS_VERSION;
NdisInitUnicodeString(&Name, L"Passthru");
PChars.Name = Name;
/*******************************************************
下面开始注册中间层驱动程序的 ProtocolXxx函数
这里主要是注册---下边界面向无连接的中间层驱动程序的ProtocolXxx函数
*******************************************************/
PChars.OpenAdapterCompleteHandler = PtOpenAdapterComplete;
PChars.CloseAdapterCompleteHandler = PtCloseAdapterComplete;
PChars.SendCompleteHandler = PtSendComplete;
PChars.TransferDataCompleteHandler = PtTransferDataComplete;
PChars.ResetCompleteHandler = PtResetComplete;
PChars.RequestCompleteHandler = PtRequestComplete;
PChars.ReceiveHandler = PtReceive;
PChars.ReceivePacketHandler = PtReceivePacket;
PChars.ReceiveCompleteHandler = PtReceiveComplete;
PChars.StatusHandler = PtStatus;
PChars.StatusCompleteHandler = PtStatusComplete;
PChars.BindAdapterHandler = PtBindAdapter;
PChars.UnbindAdapterHandler = PtUnbindAdapter;
PChars.UnloadHandler = PtUnloadProtocol;
PChars.PnPEventHandler= PtPNPHandler;
/*
如果驱动程序随后要绑定到底层的NDIS驱动程序上,则调用NdisRegisterProtocol函数来注册驱动程序的ProtocolXxx函数。
全局变量ProtHandle是在NDIS协议驱动里面的NdisRegisterProtocol函数里面初始化的,然后中间层驱动必须保存protHandle的值,并在将来NDIS中间层驱动程序的协议部分的函数调用中作为输入参数来传递.
*/
NdisRegisterProtocol(&Status, &ProtHandle,&PChars,
sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
if (Status != NDIS_STATUS_SUCCESS)
{
NdisIMDeregisterLayeredMiniport(DriverHandle);
break;
}
//如果驱动程序导出了MiniportXxx和ProtocolXxx这一些列的函数,那么就调用NdisIMAssociateMiniport函数向NDIS通告有关驱动程序的微端口低边界和协议高边界信息
NdisIMAssociateMiniport(DriverHandle, ProtHandle);
}
while (FALSE);
//----------------- 创建设备对象与符号连接----------------------------
RtlInitUnicodeString(&nameString, L"\\Device\\MyPassthru" );
RtlInitUnicodeString(&linkString, L"\\??\\MyPassthru");
for(FuncIndex = 0;
FuncIndex DriverUnload = FilterUnload;
FilterDriverHandle = NULL;
FILTER_INIT_LOCK(&FilterListLock);
InitializeListHead(&FilterModuleList);
// 把Filter驱动注册给NDIS
Status = NdisFRegisterFilterDriver(DriverObject,
(NDIS_HANDLE)FilterDriverObject,
&FChars,
&FilterDriverHandle);
if (Status != NDIS_STATUS_SUCCESS)
{
DEBUGP(DL_WARN, ("MSFilter: Register filter driver failed.\n"));
break;
}
//
// Initilize spin locks
//
Status = FilterRegisterDevice();
if (Status != NDIS_STATUS_SUCCESS)
{
NdisFDeregisterFilterDriver(FilterDriverHandle);
FILTER_FREE_LOCK(&FilterListLock);
DEBUGP(DL_WARN, ("MSFilter: Register device for the filter driver failed.\n"));
break;
}
}
while(bFalse);
DEBUGP(DL_TRACE, ("FilterRegisterOptions\n"));
ASSERT(NdisFilterDriverHandle == FilterDriverHandle);
ASSERT(FilterDriverContext == (NDIS_HANDLE)FilterDriverObject);
if ((NdisFilterDriverHandle != (NDIS_HANDLE)FilterDriverHandle) ||
(FilterDriverContext != (NDIS_HANDLE)FilterDriverObject))
{
return NDIS_STATUS_INVALID_PARAMETER;
}
DEBUGP(DL_TRACE, ("FilterAttach: NdisFilterHandle %p\n", NdisFilterHandle));
do
{
ASSERT(FilterDriverContext == (NDIS_HANDLE)FilterDriverObject);
if (FilterDriverContext != (NDIS_HANDLE)FilterDriverObject)
{
Status = NDIS_STATUS_INVALID_PARAMETER;
break;
}
if ((AttachParameters->MiniportMediaType != NdisMedium802_3)
&& (AttachParameters->MiniportMediaType != NdisMediumWan))
{
DEBUGP(DL_ERROR, ("MSFilter: Doesn't support media type other than NdisMedium802_3.\n"));
Status = NDIS_STATUS_INVALID_PARAMETER;
break;
}
Size = sizeof(MS_FILTER) +
AttachParameters->FilterModuleGuidName->Length +
AttachParameters->BaseMiniportInstanceName->Length +
AttachParameters->BaseMiniportName->Length;
pFilter = (PMS_FILTER)FILTER_ALLOC_MEM(NdisFilterHandle, Size);
if (pFilter == NULL)
{
DEBUGP(DL_WARN, ("MSFilter: Failed to allocate context structure.\n"));
Status = NDIS_STATUS_RESOURCES;
break;
}
NdisZeroMemory(pFilter, sizeof(MS_FILTER));
pFilter->FilterModuleName.Length = pFilter->FilterModuleName.MaximumLength = AttachParameters->FilterModuleGuidName->Length;
pFilter->FilterModuleName.Buffer = (PWSTR)((PUCHAR)pFilter + sizeof(MS_FILTER));
NdisMoveMemory(pFilter->FilterModuleName.Buffer,
AttachParameters->FilterModuleGuidName->Buffer,
pFilter->FilterModuleName.Length);
pFilter->MiniportFriendlyName.Length = pFilter->MiniportFriendlyName.MaximumLength = AttachParameters->BaseMiniportInstanceName->Length;
pFilter->MiniportFriendlyName.Buffer = (PWSTR)((PUCHAR)pFilter->FilterModuleName.Buffer + pFilter->FilterModuleName.Length);
NdisMoveMemory(pFilter->MiniportFriendlyName.Buffer,
AttachParameters->BaseMiniportInstanceName->Buffer,
pFilter->MiniportFriendlyName.Length);
pFilter->MiniportName.Length = pFilter->MiniportName.MaximumLength = AttachParameters->BaseMiniportName->Length;
pFilter->MiniportName.Buffer = (PWSTR)((PUCHAR)pFilter->MiniportFriendlyName.Buffer +
pFilter->MiniportFriendlyName.Length);
NdisMoveMemory(pFilter->MiniportName.Buffer,
AttachParameters->BaseMiniportName->Buffer,
pFilter->MiniportName.Length);
pFilter->MiniportIfIndex = AttachParameters->BaseMiniportIfIndex;
pFilter->TrackReceives = TRUE;
pFilter->TrackSends = TRUE;
pFilter->FilterHandle = NdisFilterHandle;
NdisZeroMemory(&FilterAttributes, sizeof(NDIS_FILTER_ATTRIBUTES));
FilterAttributes.Header.Revision = NDIS_FILTER_ATTRIBUTES_REVISION_1;
FilterAttributes.Header.Size = sizeof(NDIS_FILTER_ATTRIBUTES);
FilterAttributes.Header.Type = NDIS_OBJECT_TYPE_FILTER_ATTRIBUTES;
FilterAttributes.Flags = 0;
Status = NdisFSetAttributes(NdisFilterHandle,
pFilter, //pFilter参数的功能是,为过滤模块指定环境上下文
&FilterAttributes);
if (Status != NDIS_STATUS_SUCCESS)
{
DEBUGP(DL_WARN, ("MSFilter: Failed to set attributes.\n"));
break;
}
pFilter->State = FilterPaused;
FILTER_ACQUIRE_LOCK(&FilterListLock, bFalse);
InsertHeadList(&FilterModuleList, &pFilter->FilterModuleLink);
FILTER_RELEASE_LOCK(&FilterListLock, bFalse);
}
while (bFalse);
if (Status != NDIS_STATUS_SUCCESS)
{
if (pFilter != NULL)
{
FILTER_FREE_MEM(pFilter);
}
}
DEBUGP(DL_TRACE, ("NDISLWF FilterPause: FilterInstance %p\n", FilterModuleContext));
FILTER_ASSERT(pFilter->State == FilterRunning);
FILTER_ACQUIRE_LOCK(&pFilter->Lock, bFalse);
pFilter->State = FilterPausing;
FILTER_RELEASE_LOCK(&pFilter->Lock, bFalse);
Status = NDIS_STATUS_SUCCESS;
pFilter->State = FilterPaused;
DEBUGP(DL_TRACE, ("FilterRestart: FilterModuleContext %p\n", FilterModuleContext));
FILTER_ASSERT(pFilter->State == FilterPaused);
ConfigObject.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;
ConfigObject.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;
ConfigObject.Header.Size = sizeof(NDIS_CONFIGURATION_OBJECT);
ConfigObject.NdisHandle = FilterDriverHandle;
ConfigObject.Flags = 0;
Status = NdisOpenConfigurationEx(&ConfigObject, &ConfigurationHandle);
if (Status != NDIS_STATUS_SUCCESS)
{
#if 0
//
// The code is here just to demonstrate how to call NDIS to write an eventlog. If drivers need to write
// an event log.
//
PWCHAR ErrorString = L"Ndislwf";
DEBUGP(DL_WARN, ("FilterRestart: Cannot open configuration.\n"));
NdisWriteEventLogEntry(FilterDriverObject,
EVENT_NDIS_DRIVER_FAILURE,
0,
1,
&ErrorString,
sizeof(Status),
&Status);
#endif
}
if (Status == NDIS_STATUS_SUCCESS)
{
NdisCloseConfiguration(ConfigurationHandle);
}
NdisRestartAttributes = RestartParameters->RestartAttributes;
if (NdisRestartAttributes != NULL)
{
PNDIS_RESTART_ATTRIBUTES NextAttributes;
ASSERT(NdisRestartAttributes->Oid == OID_GEN_MINIPORT_RESTART_ATTRIBUTES);
NdisGeneralAttributes = (PNDIS_RESTART_GENERAL_ATTRIBUTES)NdisRestartAttributes->Data;
NdisGeneralAttributes->LookaheadSize = 128;
NextAttributes = NdisRestartAttributes->Next;
while (NextAttributes != NULL)
{
NextAttributes = NextAttributes->Next;
}
}
pFilter->State = FilterRunning;
Status = NDIS_STATUS_SUCCESS;
if (Status != NDIS_STATUS_SUCCESS)
{
pFilter->State = FilterPaused;
}
DEBUGP(DL_TRACE, ("FilterDetach: FilterInstance %p\n", FilterModuleContext));
FILTER_ASSERT(pFilter->State == FilterPaused);
if (pFilter->FilterName.Buffer != NULL)
{
FILTER_FREE_MEM(pFilter->FilterName.Buffer);
}
FILTER_ACQUIRE_LOCK(&FilterListLock, bFalse);
RemoveEntryList(&pFilter->FilterModuleLink);
FILTER_RELEASE_LOCK(&FilterListLock, bFalse);
FILTER_FREE_MEM(pFilter);
DEBUGP(DL_TRACE, ("FilterUnload\n"));
FilterDeregisterDevice();
NdisFDeregisterFilterDriver(FilterDriverHandle);
#if DBG
FILTER_ACQUIRE_LOCK(&FilterListLock, bFalse);
ASSERT(IsListEmpty(&FilterModuleList));
FILTER_RELEASE_LOCK(&FilterListLock, bFalse);
#endif
FILTER_FREE_LOCK(&FilterListLock);
DEBUGP(DL_TRACE, ("FilterOidRequest: Request %p.\n", Request));
do
{
Status = NdisAllocateCloneOidRequest(pFilter->FilterHandle,
Request,
FILTER_TAG,
&ClonedRequest);
if (Status != NDIS_STATUS_SUCCESS)
{
DEBUGP(DL_WARN, ("FilerOidRequest: Cannot Clone Request\n"));
break;
}
Context = (PFILTER_REQUEST_CONTEXT)(&ClonedRequest->SourceReserved[0]);
*Context = Request;
bSubmitted = TRUE;
ClonedRequest->RequestId = Request->RequestId;
pFilter->PendingOidRequest = ClonedRequest;
//Filter Driver可以调用NdisFOidRequest引发一个OID查询和设置请求给下层驱动。
Status = NdisFOidRequest(pFilter->FilterHandle, ClonedRequest);
if (Status != NDIS_STATUS_PENDING)
{
FilterOidRequestComplete(pFilter, ClonedRequest, Status);
Status = NDIS_STATUS_PENDING;
}
}while (bFalse);
if (bSubmitted == FALSE)
{
switch(Request->RequestType)
{
case NdisRequestMethod:
Request->DATA.METHOD_INFORMATION.BytesRead = 0;
Request->DATA.METHOD_INFORMATION.BytesNeeded = 0;
Request->DATA.METHOD_INFORMATION.BytesWritten = 0;
break;
case NdisRequestSetInformation:
Request->DATA.SET_INFORMATION.BytesRead = 0;
Request->DATA.SET_INFORMATION.BytesNeeded = 0;
break;
case NdisRequestQueryInformation:
case NdisRequestQueryStatistics:
default:
Request->DATA.QUERY_INFORMATION.BytesWritten = 0;
Request->DATA.QUERY_INFORMATION.BytesNeeded = 0;
break;
}
}
DEBUGP(DL_TRACE, ("FilterOidRequestComplete, Request %p.\n", Request));
Context = (PFILTER_REQUEST_CONTEXT)(&Request->SourceReserved[0]);
OriginalRequest = (*Context);
if (OriginalRequest == NULL)
{
filterInternalRequestComplete(pFilter, Request, Status);
return;
}
FILTER_ACQUIRE_LOCK(&pFilter->Lock, bFalse);
ASSERT(pFilter->PendingOidRequest == Request);
pFilter->PendingOidRequest = NULL;
FILTER_RELEASE_LOCK(&pFilter->Lock, bFalse);
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);
/*
如果FilterOidRequest返回NDIS_STATUS_PENDING,就必须在OID请求完成后调用NdisFOidRequestComplete 来通知上层驱动求请求完成。在这种情况下,请求的结果通过NdisFOidRequestComplete的OidRequest参数返回给上层驱动,并通过Status参数返回请求完成的最终状态。
要转发OID请求到下层驱动,Filter Driver必须调用NdisFOidRequest。
如果一个OID请求不能被转发到下层驱动应该当立即返回。
要完成一个请求且不转发可以直接返回NDIS_STATUS_SUCCESS或其它错误状态
或返回NDIS_STATUS_PENDING后调用NdisFOidRequestComplete。
*/
NdisFOidRequestComplete(pFilter->FilterHandle, OriginalRequest, Status);
DEBUGP(DL_TRACE, ("FilterStaus, IndicateStatus = %8x.\n", StatusIndication->StatusCode));
#if DBG
FILTER_ACQUIRE_LOCK(&pFilter->Lock, bFalse);
ASSERT(pFilter->bIndicating == FALSE);
pFilter->bIndicating = TRUE;
FILTER_RELEASE_LOCK(&pFilter->Lock, bFalse);
#endif
NdisFIndicateStatus(pFilter->FilterHandle, StatusIndication);
#if DBG
FILTER_ACQUIRE_LOCK(&pFilter->Lock, bFalse);
ASSERT(pFilter->bIndicating == TRUE);
pFilter->bIndicating = FALSE;
FILTER_RELEASE_LOCK(&pFilter->Lock, bFalse);
#endif
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(bFalse);
break;
}
//Filter Driver要下层驱动转发收到的事件,转发事件要用到NdisFDevicePnPEventNotify例程
NdisFDevicePnPEventNotify(pFilter->FilterHandle, NetDevicePnPEvent);
DEBUGP(DL_TRACE, ("SendNBLComplete, NetBufferList: %p.\n", NetBufferLists));
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, ("SendNetBufferList: NBL = %p.\n", NetBufferLists));
do
{
DispatchLevel = NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendFlags);
#if DBG
FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);
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);
}
NdisFSendNetBufferLists(pFilter->FilterHandle, NetBufferLists, PortNumber, SendFlags);
}
while (bFalse);
DEBUGP(DL_TRACE, ("ReturnNetBufferLists, NetBufferLists is %p.\n", NetBufferLists));
if (pFilter->TrackReceives)
{
while (CurrNbl)
{
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, ("ReceiveNetBufferList: NetBufferLists = %p.\n", NetBufferLists));
do
{
DispatchLevel = NDIS_TEST_RECEIVE_AT_DISPATCH_LEVEL(ReceiveFlags);
#if DBG
FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);
if (pFilter->State != FilterRunning)
{
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);
if (NDIS_TEST_RECEIVE_CAN_PEND(ReceiveFlags))
{
ReturnFlags = 0;
if (NDIS_TEST_RECEIVE_AT_DISPATCH_LEVEL(ReceiveFlags))
{
NDIS_SET_RETURN_FLAG(ReturnFlags, NDIS_RETURN_FLAGS_DISPATCH_LEVEL);
}
NdisFReturnNetBufferLists(pFilter->FilterHandle, NetBufferLists, ReturnFlags);
}
break;
}
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);
#endif
ASSERT(NumberOfNetBufferLists >= 1);
/*--------------------------------------------------------------------------------------*/
//在这里添加我们的代码
/*---------------------------------------------------------------------------------------*/
if (pFilter->TrackReceives)
{
FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);
pFilter->OutstandingRcvs += NumberOfNetBufferLists;
Ref = pFilter->OutstandingRcvs;
FILTER_LOG_RCV_REF(1, pFilter, NetBufferLists, Ref);
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);
}
/************************************************************
调用 NdisFIndicateReceiveNetBufferLists来指示发送数据。
如果Filter Driver设置了NdisFIndicateReceiveNetBufferLists的状态为NDIS_STATUS_SUCCESS, NDIS通过驱动的FilterReturnNetBufferLists 返回指示数据。
如果Filter Driver设置了NdisFIndicateReceiveNetBufferLists的ReceiveFlags值为
NDIS_RECEIVE_FLAGS_RESOURCES,那么在函数返回后Filter Driver会立即恢复对
NET_BUFFER_LIST的所有权,这时Filter Driver必须立即处理这个NET_BUFFER_LIST的返回。
在这种情况下是不会调用FilterReturnNetBufferLists返回NET_BUFFER_LIST结构的。
************************************************************/
NdisFIndicateReceiveNetBufferLists(
pFilter->FilterHandle,
NetBufferLists,
PortNumber,
NumberOfNetBufferLists,
ReceiveFlags);
if (NDIS_TEST_RECEIVE_CANNOT_PEND(ReceiveFlags) && pFilter->TrackReceives)
{
FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);
pFilter->OutstandingRcvs -= NumberOfNetBufferLists;
Ref = pFilter->OutstandingRcvs;
FILTER_LOG_RCV_REF(2, pFilter, NetBufferLists, Ref);
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);
}
} while (bFalse);
DEBUGP(DL_TRACE, (" |
|