设为首页 收藏本站
查看: 703|回复: 0

NDIS中间层驱动开发在Win7系统下和Windows XP系统下的区别

[复制链接]

尚未签到

发表于 2015-5-16 08:21:21 | 显示全部楼层 |阅读模式
  标 题: 【原创】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, ("

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-67367-1-1.html 上篇帖子: 如何允许 WinXP 和 Win7 自动创建 dump 文件 下篇帖子: win7环境的delphi6 不兼容老版本的ado.
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表