NDIS5.X中在Filter Driver实例上实现代码的截获COPY、重发发送不成功问题

黔笛 2016-08-23 09:09:07
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;
PNET_BUFFER_LIST CurrNbl;
BOOLEAN DispatchLevel;
BOOLEAN bFalse = FALSE;

PNET_BUFFER pCurrentNB;
PMDL pMdl;
PNET_BUFFER_LIST pCopyNBL = NULL;
UINT NetBufferDataLength = 0;
UINT mdlOffSet = 0;
UINT offset = 0;
PUCHAR pOriginalMdlData = NULL;
PUCHAR pNewBufferData = NULL;
UINT OriginalMdlDataLen = 0;
UINT NewBufferDataLen = 0;
//UINT BytesToCopy = 0;
PNET_BUFFER_LIST pNewNetBufferList = NULL;
PNET_BUFFER_LIST pNewNetBufferListTail = NULL;
DEBUGP(DL_TRACE, ("===>SendNetBufferList: NBL = %p.\n", NetBufferLists));

do
{

DispatchLevel = NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendFlags);

if (pFilter->TrackSends)
{
FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);
CurrNbl = NetBufferLists;
while (CurrNbl)
{
pFilter->OutstandingSends++;
FILTER_LOG_SEND_REF(1, pFilter, CurrNbl, pFilter->OutstandingSends);
pCurrentNB = NET_BUFFER_LIST_FIRST_NB(CurrNbl);
while(pCurrentNB)
{
NetBufferDataLength = NET_BUFFER_DATA_LENGTH(pCurrentNB);
DEBUGP(DL_TEST,("This NetBufferDataLength is %d\n",NetBufferDataLength));

//BytesToCopy = NetBufferDataLength - mdlOffSet;
pCopyNBL = allocateNetBuffAndNetBufferList(pFilter,2048);

//Ensure the pCopyNBL is not NULL
if(pCopyNBL != NULL)
{
pCopyNBL->SourceHandle = pFilter->FilterHandle;
//NET_BUFFER_DATA_LENGTH(NET_BUFFER_LIST_FIRST_NB(pCopyNBL)) = NetBufferDataLength;
if(pNewNetBufferList == NULL && pNewNetBufferListTail == NULL)
{
pNewNetBufferList = pNewNetBufferListTail = pCopyNBL;
}
else
{
pNewNetBufferListTail->Next = pCopyNBL;
pNewNetBufferListTail = pCopyNBL;
}

NdisQueryMdl(NET_BUFFER_FIRST_MDL(NET_BUFFER_LIST_FIRST_NB(pCopyNBL)),(PVOID)&pNewBufferData,&NewBufferDataLen,NormalPagePriority);
DEBUGP(DL_TEST,("The NewBufferDataLen is %d\n",NewBufferDataLen));
}
else
{
DEBUGP(DL_TEST,("SQVDS:Test the allocateNetBuffAndNetBufferList:allocateNetBuffAndNetBufferList failed!\n"));
break;
}

//pMdl = NET_BUFFER_CURRENT_MDL(pCurrentNB);
pMdl = NET_BUFFER_FIRST_MDL(pCurrentNB);
//mdlOffSet = NET_BUFFER_CURRENT_MDL_OFFSET(pCurrentNB);
DEBUGP(DL_TEST,("This NetBuffer's Mdl off set is %d\n",mdlOffSet));
while(pMdl)
{
NdisQueryMdl(pMdl,(PVOID)&pOriginalMdlData,&OriginalMdlDataLen,NormalPagePriority);
DEBUGP(DL_TEST,("The OriginalMdlDataLen is %d\n",OriginalMdlDataLen));
//NdisMoveMemory(pNewBufferData+offset, pOriginalMdlData+mdlOffSet,pMdl->ByteCount - mdlOffSet);
NdisMoveMemory(pNewBufferData+offset,pOriginalMdlData,pMdl->ByteCount);
//offset += (pMdl->ByteCount - mdlOffSet);
offset += pMdl->ByteCount;
pMdl = pMdl->Next;
//mdlOffSet = 0;
}
DEBUGP(DL_TEST,("After the copy finish, the offset is %d\n",offset));
NET_BUFFER_DATA_LENGTH(NET_BUFFER_LIST_FIRST_NB(pCopyNBL)) = offset;
offset = 0;
pCurrentNB = NET_BUFFER_NEXT_NB(pCurrentNB);
}
CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);
}
pNewNetBufferListTail->Next = NULL;
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);
}
else
{
DEBUGP(DL_TEST,("The track is not TRUE.......................SQVDS!\n"));
}
//SendFlags = NDIS_SEND_FLAGS_DISPATCH_LEVEL;
//To tell the
NdisFSendNetBufferListsComplete(pFilter->FilterHandle, NetBufferLists, DispatchLevel?NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL:0);
NdisFSendNetBufferLists(pFilter->FilterHandle, pNewNetBufferList, PortNumber, SendFlags);
DEBUGP(DL_TEST,("NdisFSendNetBufferLists finish!\n"));
}
while (bFalse);

DEBUGP(DL_TRACE, ("<===SendNetBufferList. \n"));
}

代码如上,想实现截获原报文并copy一份出来,然后通知上层驱动报文已经发送,其实没法送,这个时候发送自己copy过来的报文,copy后的报文被我简化,一个NetBufferList中只有一个NetBuffer,一个NetBuffer中只有一个MDL(2048字节)
目前调试信息是,Windbg显示下层驱动已经调用FilterSendNetBufferListsComplete,但是实际装上驱动后计算机的网络是不通的,装上驱动重连网络Ip地址都没有分配下来
...全文
635 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

1,318

社区成员

发帖
与我相关
我的任务
社区描述
主要是开发驱动技术
社区管理员
  • 驱动程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧