驱动程序中的线程不发送数据包

时间:2013-05-21 16:45:50

标签: multithreading filter driver packet ndis

我有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);
        }
    }
}

该功能以PsCreateSystemThread中的DriverEntry开头 但这不是发送我的数据包。
我试着用这个:

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秒发送一次数据包?

1 个答案:

答案 0 :(得分:0)

NDIS6编程模型是异步的。这意味着当您致电NdisFSendNetBufferLists时,您实际上放弃了NBL的所有权。在通过FilterReturnNetBufferLists回调将NBL返回到您的过滤器之前,您无法重复使用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之前不要再发送NBL。

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