【问题标题】:Thread in driver don't send packets驱动程序中的线程不发送数据包
【发布时间】:2013-05-16 12:46:22
【问题描述】:

我有this NDIS Filter Driver。我尝试在我的驱动程序中启动一个线程,该线程将每 10 秒发送一次数据包。

为此,我使用以下代码:

LARGE_INTEGER TimePrev, TimeNow;
void ThreadedAction()
{
    while(1)
    {
        KeQuerySystemTime(&TimeNow);
        if(NBLtoSend && (TimeNow.QuadPart - TimePrev.QuadPart)>100000000)
        {
            NdisFSendNetBufferLists(NBLtoSend->SourceHandle, NBLtoSend, 0, 0);
            KeQuerySystemTime(&TimePrev);
        }
    }
}

该函数以DriverEntry 中的PsCreateSystemThread 开头。
但这不是发送我的数据包。
我尝试使用这个:

void ThreadedAction()
{
    while(1)
    {
        if(NBLtoSend)
        {
            NdisFSendNetBufferLists(NBLtoSend->SourceHandle, NBLtoSend, 0, 0);
        }
    }
}

此代码不停地发送我的数据包。

以下代码每 10 秒用我的数据包创建一个新文件(CreateFileS 是我的函数),但不发送我的数据包

LARGE_INTEGER TimePrev, TimeNow;
void ThreadedAction()
{
    while(1)
    {
        KeQuerySystemTime(&TimeNow);
        if(NBLtoSend && (TimeNow.QuadPart - TimePrev.QuadPart)>100000000)
        {
            PMDL pmdl = NET_BUFFER_CURRENT_MDL(NET_BUFFER_LIST_FIRST_NB(NBLtoSend));
            CreateFileS(NULL,(char*)MmGetMdlVirtualAddress(pmdl),MmGetMdlByteCount(pmdl));
            NdisFSendNetBufferLists(NBLtoSend->SourceHandle, NBLtoSend, 0, 0);
            KeQuerySystemTime(&TimePrev);
        }
    }
}

为什么会这样,我该怎么做才能每 10 秒发送一次数据包?

【问题讨论】:

    标签: multithreading filter driver packet ndis


    【解决方案1】:

    NDIS6 编程模型是异步的。这意味着当您拨打NdisFSendNetBufferLists 时,您实际上放弃了NBL 的所有权。在通过 FilterReturnNetBufferLists 回调将 NBL 返回到您的过滤器之前,您不能重复使用它。

    首先,您需要将代码更改为如下所示:

    PNET_BUFFER_LIST NblToSend;
    
    void FilterReturnNetBufferLists(PNET_BUFFER_LIST NblChain)
    {
        for each Nbl in NblChain
        {
            if(Nbl->SourceHandle == MyFilterHandle)
                NblToSend = Nbl;
            else
                NdisFReturnNetBufferLists(Nbl);
        }
    }
    
    void ThreadedAction()
    {
        while(1)
        {
            if(NBLtoSend)
            {
                PNET_BUFFER_LIST TempNbl = NblToSend;
                NblToSend = NULL;
                NdisFSendNetBufferLists(TempNbl);
            }
        }
    }
    

    这样,您就遵守了 NDIS 规则:在 NBL 归还给您之前,请勿再次发送。

    接下来,循环非常低效。在实现时,循环将消耗 100% 的 CPU,忙着倒计时纳秒,直到发送另一个数据包的时间。相反,use a timer。系统会在 10 秒后调用你的线程。

    【讨论】:

    • 1. 你确定是FilterReturnNetBufferLists 而不是FilterSendNetBufferListsComplete2. 如果问题是因为我将NBL的所有权传递给了NDIS,为什么它在第一次调用时没有发送?为什么在我不检查时间的情况下它会发送数据包? 3.我不使用计时器,因为这个线程还做其他事情,我想一直执行。
    • 1.是的,愚蠢的我。我的意思是FilerSendNetBufferListsComplete
    • 2.我不确定这个问题是什么意思;你能改写一下吗?
    • 您说我的代码无法发送数据包,因为“在通过 FilterReturnNetBufferLists 回调将 NBL 返回到您的过滤器之前,您无法重用 NBL”。在第一次执行代码时,我不重用 NBL,也没有放弃 NBL 的所有权。那为什么包没有在第一次发送?
    • 当您致电NdisFSendNetBufferLists 时,即放弃了 NBL 的所有权。在通过FilterSendNetBufferListsComplete 回复您之前,您无法再次触摸 NBL。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 2018-05-20
    • 2020-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多