darkread
驱动牛犊
驱动牛犊
  • 注册日期2003-01-13
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
阅读:9266回复:32

对胡老大的代码的注释,大家进来指导一下吧

楼主#
更多 发布于:2004-04-03 16:02
下面是我对huyg的代码的注释,因为功底很浅,漏洞百出,希望各位高人能够指点一下,看的不爽大家只管骂,但是不要再让我回去查ddk了,上面很多在ddk中说的很是模棱两可的,抑或是我的E文太差实在是看不懂
第一部分
void CopyPacket2Buffer(IN PNDIS_PACKET pPacket,IN OUT PUCHAR pBuff,IN OUT PUINT pLength)
{
PNDIS_BUFFER BuffDT;// buffer指示符,
PUCHAR BuffVA;//Buffer的虚拟地址
UINT BuffLen;//Buffer的长度

*pLength=0;//数据包内容的总长度,开始先置零
BuffLen=0;//Buffer的长度,开始先置零

NdisQueryPacket(pPacket,NULL,NULL,&BuffDT,NULL);//查询Packet的信息,这里查的是Packet的Buffer指示符的链表第一个的

while(BuffDT!=(PNDIS_BUFFER)NULL)//如果Buffer指示符不为NULL,则读取其中的内容
{
NdisQueryBuffer(BuffDT,&BuffVA,&BuffLen);//得到BuffDT指向的那个Buffer的虚拟地BuffVA,和长度BuffLen
NdisMoveMemory(pBuff,BuffVA,BuffLen);//将BuffVA其中的内容,移动到pBuff指向的那块区域
pBuff=pBuff+BuffLen;//pBuff指针后移,前BuffLen个字节已经填入数据
*pLength+=BuffLen;//记录pBuff中填入数据的总长度
NdisGetNextBuffer(BuffDT,&BuffDT);//获得Buffer指示符链表中的下一个Buffer指示符
}
return;
}

//数据传输完备,如果调用了TransferData(),就必须要调用TransferDataComplete,因为Ndis必须遵守谁申请谁释放的原则
VOID
PtTransferDataComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet,
IN NDIS_STATUS Status,
IN UINT BytesTransferred
)
/*++

Routine Description:
Same as the Send above, all sends need to be completed on the Primary's MiniportHandle

Arguments:

Return Value:

--*/
{
PADAPT pAdapt =(PADAPT)ProtocolBindingContext;//得到ProtocolBind的信息
PUCHAR pPacketContent;//数据包的内容就提取出来后就放在这里,我想是从Packet的Buffer中提取出来的把吧
PRSVD Rsvd;//暂时还不知道干什么的
UINT OffsetSize,Result,PacketLen;//偏移量,结果,包的长度(应该是指以太网帧的长度吧)

PNDIS_BUFFER pPacketBuffer;//Buffer指示符,我想它应该指向的是Packet中的Buffer
PNDIS_PACKET pBakPacket;//Packet指示符,这个是在Ndis中新创建的Packet,感觉上向上层传送的应该就是这个了而不是Packet
PNDIS_BUFFER pBakBuffer;//Buffer指示符,备份用的,作用还是有点模糊

PUCHAR pBakContent;//以太网帧的内容应该是放在这里的,pPacketContent已经有了,这里为什么还是要加一个,暂时还不清楚,
UINT BufferLen;//Buffer的长度,应该是实际内容的长度吧

DBGPRINT(("In PtTransferDataCompleten"));

//
// Returning the Send on the Primary, will point to itself if there is no LBFO
//
pAdapt = pAdapt->pPrimaryAdapt;//得到第一设备,那为什么还要第一句“PADAPT pAdapt =(PADAPT)ProtocolBindingContext”呢?
Rsvd =(PRSVD)(Packet->MiniportReserved);//不懂
pBakPacket=(PNDIS_PACKET)(Rsvd->OriginalPkt);//不懂,好像是从微端口获取,Packet的指针,看了后面,回头再写一点把
//这个pBakPacket是不是就是那些还在微端口中的数据啊??

if(pAdapt->MiniportHandle)//是否有微端口绑定,没有话,那也就是不可能有数据上传了
{
if(pBakPacket==NULL)//如果没有,那是什么一种情况,不清楚,感觉是数据已经上传的意思吧,通知miniport释放资源
NdisMTransferDataComplete(pAdapt->MiniportHandle,Packet,Status,BytesTransferred);
else
{

Status=NdisAllocateMemory(&pPacketContent,BUFFER_SIZE,0,HighestAcceptableMax);//分配内存给pPacketContent,
//BUFFER_SIZE的大小取决于MTU,比他大就行了,因为一个以太网帧不可能大于它的最大可传输单元(MTU)的,Huyg的值是2000

//上面有这样一句pBakPacket=(PNDIS_PACKET)(Rsvd->OriginalPkt),那么下面这句的意思就是把pBakPacket中的以太网帧的
//内容保存在pPacketContent中了,OffsetSize就是pPacketContent长度了
CopyPacket2Buffer(pBakPacket,pPacketContent,&OffsetSize);
//同上,保存的是Packet的中的以太网帧的内容,放在pBakPacket的内容之后
CopyPacket2Buffer(Packet,pPacketContent+OffsetSize,&PacketLen);
//Packet是pPacketContent的内容的长度
PacketLen+=OffsetSize;
//从pBakPacket的Buffer链表中废除pBakBuffer
NdisUnchainBufferAtFront(pBakPacket,&pBakBuffer);
//安全的查询pBakBuffer(Buffer指示符)的情况,起始地址,内容长度,32是权限,等于哪个级别不清楚
//ddk上说运行NdisQueryBufferSafe在IRQL <= DISPATCH_LEVEL. 上,大概就是32了
NdisQueryBufferSafe(pBakBuffer,&pBakContent,&BufferLen,32);
//释放pBakBuffer(释放的是指示符)
NdisFreeBuffer(pBakBuffer);
//释放pBakBuffer中所指向的缓冲区
NdisFreeMemory(pBakContent,BUFFER_SIZE,0);
//这个地方很奇怪了,这个指针好像指向的是Packet->MiniportReserved->OriginalPkt的内容,既然在这里释放,那它到底是属于谁的
//imd的还是miniport的
NdisFreePacket(pBakPacket);
//MiniportReserved的值置零,不指向任何地方
memset(Packet->MiniportReserved,0,sizeof(Packet->MiniportReserved));

//从Packet的Buffer链表中废除pPacketBuffer
NdisUnchainBufferAtFront(Packet,&pPacketBuffer);
//安全查询pPacketBuffer的虚拟地址,长度
NdisQueryBufferSafe(pPacketBuffer,&pBakContent,&BufferLen,32);
//释放pPacketBuffer指向的Buffer指示符
NdisFreeBuffer(pPacketBuffer);
//释放pPacketBuffer指向的Buffer指示符指向的那块缓冲区
NdisFreeMemory(pBakContent,BUFFER_SIZE,0);
//请求分配Buffer指示符
NdisAllocateBuffer(&Status,&pPacketBuffer,pAdapt->RecvBufferPoolHandle,pPacketContent,PacketLen);
//将它挂到Packet的Buffer指示符链表的最前端
NdisChainBufferAtFront(Packet,pPacketBuffer);
//下面两句话不知道是什么意思,因为不知道Private是干什么的,ddk上有,看了也不明白
//猜测是在维护链表,哪个链表,不清楚了,作用也不清楚
Packet->Private.Head->Next=NULL;
Packet->Private.Tail=NULL;
//设置包头14个字节
NDIS_SET_PACKET_HEADER_SIZE(Packet,14);
//调用和介质无关的Indicate函数通知上层协议,
NdisMIndicateReceivePacket(pAdapt->MiniportHandle,&Packet,1);

if(NDIS_GET_PACKET_STATUS(Packet)!=NDIS_STATUS_PENDING)//返回后如果是NDIS_STATUS_PENDING(悬挂)则调用函数释放
{
MPReturnPacket((NDIS_HANDLE)pAdapt,Packet);
}
}
return;
}
待续....

[编辑 -  4/3/04 by  darkread]

[编辑 -  4/3/04 by  darkread]
darkread
驱动牛犊
驱动牛犊
  • 注册日期2003-01-13
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-04-03 17:24
第二部分

NDIS_STATUS
PtReceive(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_HANDLE MacReceiveContext,
IN PVOID HeaderBuffer,
IN UINT HeaderBufferSize,
IN PVOID LookAheadBuffer,
IN UINT LookAheadBufferSize,
IN UINT PacketSize
)
/*++

Routine Description:
LBFO - need to use primary for all receives

Arguments:


Return Value:

--*/
{
PADAPT OutAdapt,pAdapt =(PADAPT)ProtocolBindingContext;
PNDIS_PACKET MyPacket, Packet,MyPacket1;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;

/* PUCHAR pEnetAddrDest=NULL;
UINT nDataSize=0,i;
PNDIS_BUFFER pNdisBuffer=NULL;
UCHAR *BufferVa=NULL;

PMACHEADER pMACHeader=NULL;
PIPHEADER pIPHeader=NULL;
PICMPHEADER pICMPHeader=NULL;
PTCPHEADER pTCPHeader=NULL;
PUDPHEADER pUDPHeader=NULL;
*/

PNDIS_BUFFER pPacketBuffer,pBakBuffer;//Buffer指示符,第一个是Packet的,第二个应该是在本函数生成的
PUCHAR pPacketContent,pBakContent;//把以太网帧的内容提取出来应该就放在这里了
UINT PacketLen;//包的长度把,暂时还不知道是Packet的,还是以太网帧的

UINT OffsetSize; //偏移量
UINT BytesTransferred;//已经传输的数据,好像后面写的是0
//以下三行是传说中的初始化了,为什么是传说中的呢?因为我对第一行实在是不了解
PRSVD Rsvd=NULL;
PVOID MediaSpecificInfo=NULL;
ULONG MediaSpecificSize=0;

//如果MiniPort == NULL,那么就是说没有底层设备,当然就没有什么以太网帧啦,这个好理解
//但是TransferDataComplete()中的也有类似的一句就不是这么好理解了
if(!pAdapt->MiniportHandle)
{
Status = NDIS_STATUS_FAILURE;
}
else do
{
//
// We should not be getting Receives on a Secondary, this is just specific to our LBFO driver
//

if(pAdapt->isSecondary)
{
DBGPRINT("PASSTHRU GETTING RECIEVES ON SECONDARY\n");
ASSERT(0);
}

//
// If this was indicated by the miniport below as a packet, then get that packet pointer and indicate
// it as a packet as well(with appropriate status). This way the OOB stuff is accessible to the
// transport above us.
//
Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext);
if(Packet != NULL)//如果能够不等于NULL就好办了
{
//
// Get a packet off the pool and indicate that up
//
NdisDprAllocatePacket(&Status,
&MyPacket,
pAdapt->RecvPacketPoolHandle);

if(Status == NDIS_STATUS_SUCCESS)
{
MyPacket->Private.Head = Packet->Private.Head;
MyPacket->Private.Tail = Packet->Private.Tail;

//
// Get the original packet(it could be the same packet as one received or a different one
// based on # of layered MPs) and set it on the indicated packet so the OOB stuff is visible
// correctly at the top.
//
NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet));
NDIS_SET_PACKET_HEADER_SIZE(MyPacket, HeaderBufferSize);

//
// Set Packet Flags
//
NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);

//
// Make sure the status is set to NDIS_STATUS_RESOURCES.
//
NDIS_SET_PACKET_STATUS(MyPacket, NDIS_STATUS_RESOURCES);

NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1);

ASSERT(NDIS_GET_PACKET_STATUS(MyPacket) == NDIS_STATUS_RESOURCES);
NdisDprFreePacket(MyPacket);
break;
}
}

//
// Fall through if the miniport below us has either not indicated a packet or we could not
// allocate one
//
//说明Packet中的数据已经全部上来了,LookAheadBufferSize我猜测是属于IMD的,不知道对不对
//因为LookAheadBufferSize比PacketSize大,是不是就是说Packet的Buffer中的以太网帧的内容都在
//LookAheadBuffer中了呢?
else if(PacketSize<=LookAheadBufferSize)
{
//给pPacketContent分配内存,HighestAcceptableMax必须=-1
Status=NdisAllocateMemory(&pPacketContent,BUFFER_SIZE,0,HighestAcceptableMax);
if(Status!=NDIS_STATUS_SUCCESS)
{
DbgPrint("PTReceive:NdisAllocateMemory Failed\n");
return(NDIS_STATUS_NOT_ACCEPTED);
}
if(pPacketContent==NULL)
{
DbgPrint("PTReceive:pPacketContent==NULL\n");
return(NDIS_STATUS_NOT_ACCEPTED);
}

NdisZeroMemory(pPacketContent,BUFFER_SIZE);//将pPacketContent指向的内容置零,也即使刚分配的区域置零
//把HeaderBuffer(是不是叫以太网帧头部缓冲区)的内容放到pPacketContent中区
NdisMoveMemory(pPacketContent,HeaderBuffer,HeaderBufferSize);
//把LookAheadBuffer中的数据放在pPacketContent指向的区域,而且是跟在HeaderBuffer的后面
//这样,一个以太网帧的数据就都有了,是吧???但是很奇怪,这里为什么不是PacketSize呢??
NdisMoveMemory(pPacketContent+HeaderBufferSize,LookAheadBuffer,LookAheadBufferSize);
//这个以太网帧的长度,
PacketLen=PacketSize+HeaderBufferSize;

//下面部分莫非就是传说中的重新组包??,如果是就好了
//分配一个Packet指示符MyPacket,带Dpr的好像快一点
NdisDprAllocatePacket(&Status,&MyPacket,pAdapt->RecvPacketPoolHandle);

if(Status==NDIS_STATUS_SUCCESS)//如果MyPacket分配成功,则继续
{
//分配一个Buffer指示符,pPacketBuffer指向那个指示符
//并且将pPacketContent指向的地址传给那个分配的指示符,也就是所指示符所指向的真正的那块Buffer就是pPacketContent
//指向的那块区域
NdisAllocateBuffer(&Status,&pPacketBuffer,pAdapt->RecvBufferPoolHandle,pPacketContent,PacketLen);
//把这个指示符挂在MyPacket的指示符链表的第一个
NdisChainBufferAtFront(MyPacket,pPacketBuffer);
//修整工作,只是不知道干什么的而已,
MyPacket->Private.Head->Next=NULL;
MyPacket->Private.Tail=NULL;
//老问题了,这两句也不懂
Rsvd=(PRSVD)(MyPacket->MiniportReserved);
Rsvd->OriginalPkt=NULL;
//设置MyPacket的报头的大小,应该是重新组包了,因为它用的包头大小是HeaderBufferSize
NDIS_SET_PACKET_HEADER_SIZE(MyPacket,HeaderBufferSize);
//告诉上层协议驱动,有数据包,不过是我重新组包的了
NdisMIndicateReceivePacket(pAdapt->MiniportHandle,&MyPacket,1);
//如果是NDIS_STATUS_PENDING(悬挂),在释放资源
//我想可能这里的悬挂就是完成的意思把
if(NDIS_GET_PACKET_STATUS(MyPacket)!=NDIS_STATUS_PENDING)
{
DBGPRINT(("In PtReceive And Free Memory\n"));
NdisFreeBuffer(pPacketBuffer);
NdisFreeMemory(pPacketContent,BUFFER_SIZE,0);
NdisDprFreePacket(MyPacket);
}
}
break;
}
else
{
//看着看着好像又不是huyg的程序了,就当是吧
//********这中情况,应该就是数据还没有完全上来的情况了*********//
//这里是分配存放以太网帧的空间了
Status=NdisAllocateMemory(&pPacketContent,BUFFER_SIZE,0,HighestAcceptableMax);
if(Status!=NDIS_STATUS_SUCCESS)//如果失败,则DbgPrint
{
DbgPrint("PtReceive:NdisAllocateMemory Failed.\n");
return(NDIS_STATUS_NOT_ACCEPTED);
}
if(pPacketContent==NULL)//如果失败,则DbgPrint,这里的失败应该是没有空间了吧
{
DbgPrint("PTReceive:pPacketContent==NULL\n");
return(NDIS_STATUS_NOT_ACCEPTED);
}
//pPacketContent指向的空间置零
NdisZeroMemory(pPacketContent,BUFFER_SIZE);

//获取Packet指示符
NdisDprAllocatePacket(&Status,&MyPacket,pAdapt->RecvPacketPoolHandle);

//分配pBakContent指向的空间,我突然想到了,这里分配了两块空间,是不是
//一块是放已经上来的数据,而另一块放的是还在下面的数据
//分析下去看,但愿是这样的
Status=NdisAllocateMemory(&pBakContent,BUFFER_SIZE,0,HighestAcceptableMax);
//下面两个if是显示分配空间出错的情况的
if(Status!=NDIS_STATUS_SUCCESS)
{
DbgPrint("PtReceive:NdisAllocateMemory Failed.\n");
return(NDIS_STATUS_NOT_ACCEPTED);
}
if(pBakContent==NULL)
{
DbgPrint("PTReceive:pPacketContent==NULL\n");
return(NDIS_STATUS_NOT_ACCEPTED);
}
//对pBakContent指向的那块空间置零
NdisZeroMemory(pBakContent,BUFFER_SIZE);
//把HeaderBuffer中的数据放到pBakContent指向的那块空间中去
NdisMoveMemory(pBakContent,HeaderBuffer,HeaderBufferSize);
//然后把LookAheadBuffer中的数据放在HeaderBuffer的后面
NdisMoveMemory(pBakContent+HeaderBufferSize,LookAheadBuffer,LookAheadBufferSize);
//包的长度记录在PacketLen中,这里的包的意思应该是以太网帧
PacketLen=HeaderBufferSize+PacketSize;
//分配一个Buffer指示符,用pPacketBuffer指向它,并把pPacketContent指向的那块空间中挂接上来
//这块Buffer指示符所指向的Buffer的大小是PacketSize-LookAheadBufferSize,看样子我是对的,
//pPacketContent指向的那块空间中的数据是没有传上来的
NdisAllocateBuffer(&Status,&pPacketBuffer,pAdapt->RecvBufferPoolHandle,pPacketContent,PacketSize-LookAheadBufferSize);

//把pPacketBuffer指向的Buffer指示符,挂接到MyPacket的Buffer指示符链表中
NdisChainBufferAtFront(MyPacket,pPacketBuffer);
//不知道干什么的
MyPacket->Private.Head->Next=NULL;
MyPacket->Private.Tail=NULL;

//OffsetSize表示的是已经传上来的数据的大小吧,
//又有问题了,请网上数10行,PacketSize-LookAheadBufferSize中的PacketSize中应该不包含HeadBufferSize的吧,
OffsetSize=HeaderBufferSize+LookAheadBufferSize;

//分配一个Packet指示符,叫用MyPacket1指向它
NdisDprAllocatePacket(&Status,&MyPacket1,pAdapt->RecvPacketPoolHandle);
//再分配一个Buffer指示符,用pBakBuffer指向它,挂接的真正的空间(buffer)是pBakContent,大小OffsetSize
NdisAllocateBuffer(&Status,&pBakBuffer,pAdapt->RecvBufferPoolHandle,pBakContent,OffsetSize);
//将pBakBuffer指向的Buffer指示符挂接在MyPacket1的Buffer链表的第一个
NdisChainBufferAtFront(MyPacket1,pBakBuffer);

//这两句 不懂!!!!!!!!!!!!!!!
Rsvd=(PRSVD)(MyPacket->MiniportReserved);
Rsvd->OriginalPkt=(PNDIS_PACKET)MyPacket1;

//设置包头大小
NDIS_SET_PACKET_HEADER_SIZE(MyPacket,HeaderBufferSize);

//调用NdisTransferData()把下面的数据调上来
NdisTransferData(&Status,pAdapt->BindingHandle,MacReceiveContext,LookAheadBufferSize,PacketSize-LookAheadBufferSize,MyPacket,&BytesTransferred);

if(Status!=NDIS_STATUS_PENDING)//监察是否完成,完成则释放资源
{
PtTransferDataComplete((NDIS_HANDLE)pAdapt,MyPacket,Status,BytesTransferred);
}
break;

}
pAdapt->IndicateRcvComplete = TRUE;//不懂

/*
switch(pAdapt->Medium)
{
case NdisMedium802_3:
{
NdisMEthIndicateReceive(pAdapt->MiniportHandle,
MacReceiveContext,
HeaderBuffer,
HeaderBufferSize,
LookAheadBuffer,
LookAheadBufferSize,
PacketSize);
break;
}
case NdisMedium802_5:
NdisMTrIndicateReceive(pAdapt->MiniportHandle,
MacReceiveContext,
HeaderBuffer,
HeaderBufferSize,
LookAheadBuffer,
LookAheadBufferSize,
PacketSize);
break;

case NdisMediumFddi:
NdisMFddiIndicateReceive(pAdapt->MiniportHandle,
MacReceiveContext,
HeaderBuffer,
HeaderBufferSize,
LookAheadBuffer,
LookAheadBufferSize,
PacketSize);
break;

default:
ASSERT(0);
break;
}
*/
} while(FALSE);

DBGPRINT(("In PtReceive\n"));

return Status;
}

待续......
darkread
驱动牛犊
驱动牛犊
  • 注册日期2003-01-13
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-04-03 17:31
第三部分
VOID
MPReturnPacket(
IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET Packet
)
/*++

Routine Description:


Arguments:


Return Value:


--*/
{
PADAPT pAdapt = (PADAPT)MiniportAdapterContext;
PNDIS_PACKET MyPacket;
PRSVD Resvd;
PNDIS_BUFFER pNdisBuffer;
PUCHAR pPacketContent;
UINT BufferLen;

Resvd = (PRSVD)(Packet->MiniportReserved);
MyPacket = Resvd->OriginalPkt;

if(MyPacket)
{
NdisFreePacket(Packet);
NdisReturnPackets(&MyPacket, 1);
}
/*=========================================================================
I Add This Code for NdisIndicateReceivePacket
=========================================================================*/
else
{
DBGPRINT(("In MPReturnPacket And Free Memory\n"));
//Packet的Buffer链表的第一个元素摘下,地址给pNdisBuffer
NdisUnchainBufferAtFront(Packet,&pNdisBuffer);
//查询这个Buffer指示符的信息,有Buffer的虚拟地址,长度,32是权限
NdisQueryBufferSafe(pNdisBuffer,(PVOID *)&pPacketContent,&BufferLen,32);
//释放Buffer指示符
NdisFreeBuffer(pNdisBuffer);
//释放Buffer空间
NdisFreeMemory(pPacketContent,BUFFER_SIZE,0);
//释放Packet指示符
NdisFreePacket(Packet);
DBGPRINT(("In MPReturnPacket And Free Memory\n"));
}
}
未完待续...
satanmonkey
驱动牛犊
驱动牛犊
  • 注册日期2004-03-19
  • 最后登录2018-05-26
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望40点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-04-04 19:53
原始的代码哪里能弄到?
darkread
驱动牛犊
驱动牛犊
  • 注册日期2003-01-13
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-04-04 20:18
passthru代码是DDK的
贴的代码的胡老大的,
上面的英文注释也是胡老大的
中文注释是我的,因为是边看边写的,所以有前后不一致的地方,如果有错请题出来,骂出来也欢迎,只要别让我在去查DDK就好
darkread
驱动牛犊
驱动牛犊
  • 注册日期2003-01-13
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-04-06 17:57
大家都帮忙看看啊
版主asmsys,帮忙指点一下
asmsys
驱动老牛
驱动老牛
  • 注册日期2002-03-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-04-06 18:02
//这两句 不懂!!!!!!!!!!!!!!!
Rsvd=(PRSVD)(MyPacket->MiniportReserved);
Rsvd->OriginalPkt=(PNDIS_PACKET)MyPacket1;
就是说,这是半个包,等调用NdisTransferData取得后半部分时,就从MyPacket1中取出前半部分,然后合成一个完整的包。
鉴于此,以上关于pBakPacket和REVD的注解都应修改。



[编辑 -  4/6/04 by  asmsys]
asmsys
驱动老牛
驱动老牛
  • 注册日期2002-03-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-04-06 18:05
//数据传输完备,如果调用了TransferData(),就必须要调用TransferDataComplete,因为Ndis必须遵守谁申请谁释放的原则
========================================================
应该是NdisTransferData()吧。
如果返回的不是NDIS-STATUS-PENDING,PtTransferDataComplete就不被调用。这是应注意提前释放资源。
asmsys
驱动老牛
驱动老牛
  • 注册日期2002-03-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-04-06 18:12
//安全的查询pBakBuffer(Buffer指示符)的情况,起始地址,内容长度,32是权限,等于哪个级别不清楚
=======================================================
32 别瞎说,看DDK:
Priority
Indicates the priority of the request as one of the following:
LowPagePriority
Specifies a low priority. It is acceptable for NdisQueryBufferSafe to fail if system resources are low.
NormalPagePriority
Specifies a normal priority. It is acceptable for NdisQueryBufferSafe to fail if system resources are low.
HighPagePriority
Specifies a high priority. It is not acceptable for NdisQueryBufferSafe to fail unless system resources are exhausted.
darkread
驱动牛犊
驱动牛犊
  • 注册日期2003-01-13
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-04-06 20:26
asmsys
Rsvd=(PRSVD)(MyPacket->MiniportReserved);
Rsvd->OriginalPkt=(PNDIS_PACKET)MyPacket1;
这两句还是有点小问题
如果是在PtReceive()中
Packet(也就是传入的那个Packet描述符)中的MiniportReserved中放的是什么啊
darkread
驱动牛犊
驱动牛犊
  • 注册日期2003-01-13
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2004-04-06 20:29
还有就是
MyPacket->Private.Head->Next=NULL;
MyPacket->Private.Tail=NULL;
这两句是干什么的,应该是维护一个链表吧,具体是怎么样的,这两天看代码看的做梦都是Packet了,您就帮一下忙吧,
youngyt
驱动牛犊
驱动牛犊
  • 注册日期2003-11-23
  • 最后登录2006-12-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2004-04-07 08:31
还有就是
MyPacket->Private.Head->Next=NULL;
MyPacket->Private.Tail=NULL;
这两句是干什么的,应该是维护一个链表吧,具体是怎么样的,这两天看代码看的做梦都是Packet了,您就帮一下忙吧,


一个Packet中有一个指向一块buffer的指针,那块buffer又有指向一片内存(这里就是放包的内容的地方)的指针。一般来说,一个PACKET不止一块MEMORY,因为BUFFER和MEMORY之间是有对应关系的,所以只要将那些散开的BUFFER链到一起就能组成一个完整的包了。
但是我们自己分配包的时候,为了方便一次性就分配一个足够大的MEMORY,然后分配一个BUFFER链到PACKET上就足够了。
那么MyPacket->Private.Head就是这个BUFFER链的头指针,MyPacket->Private.Tail就是这个BUFFER链的尾指针,我们只有一块BUFFER,不然理解,一个链表只有头结点有内容,那么MyPacket->Private.Head就不为NULL,那么它的next结点无内容,所以指向NULL,同理尾结点也指向空。
asmsys
驱动老牛
驱动老牛
  • 注册日期2002-03-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2004-04-07 08:52
asmsys
Rsvd=(PRSVD)(MyPacket->MiniportReserved);
Rsvd->OriginalPkt=(PNDIS_PACKET)MyPacket1;
这两句还是有点小问题
如果是在PtReceive()中
Packet(也就是传入的那个Packet描述符)中的MiniportReserved中放的是什么啊
 

Rsvd是供包的制造者用的,一般用来在开始时放入一些有用的数据供做回收处理。Rsvd的结构也是可以自己定义的,只有你制造的包,你才可以访问里边的东西,不是你的包,比如是下层发上来的包,你没有必要知道他是啥子东西。即使你知道下层放的是什么,对你来说一般也没什么用。
youngyt
驱动牛犊
驱动牛犊
  • 注册日期2003-11-23
  • 最后登录2006-12-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2004-04-07 09:02
asmsys
Rsvd=(PRSVD)(MyPacket->MiniportReserved);
Rsvd->OriginalPkt=(PNDIS_PACKET)MyPacket1;
这两句还是有点小问题
如果是在PtReceive()中
Packet(也就是传入的那个Packet描述符)中的MiniportReserved中放的是什么啊


今天起了个大早,发现有我知道的问题,多打点字说说,以前我也遇到同样的问题,摸了好半天才懂。

reserved为保留区,有两块,一个是ProtocolReserved,一个是MiniportReserved。顾名思意,一个是为协议层保留的,一个是为MINIPORT保留的。

在接收包的时候,IM接收到下面Miniport传上来的包描述符Packet(注意扣字眼),在PtReceive中你有两种处理方法:
1.什么都不做直接上指,先是分配一个新包描述符MyPacket,将得到的包描述符的相关信息拷贝到新的包描述符中,注意两个包描述符其实描述了同一块包内容。上指前将(MyPacket->MiniportReserved)->OriginalPkt = Packet
这有什么用呢?等下再说。
2.你要修改包内容,那你得将Packet所指向的内容CopyPacket2Buffer(这个函数你好像会用了),改完了再链到MyPacket上去,接着上指MyPacket,上指前将(MyPacket->MiniportReserved)->OriginalPkt = NULL

到重点了,为了很好地释放内存,这个保留区就派上用场了,我假设上指完后的状态不是NDIS_PENDING,那么要求马上释放资源:
           Resvd = (PRECV_RSVD)(MyPacket->MiniportReserved);
OriginalPacket = Resvd->OriginalPkt;
if(OriginalPacket != NULL)
{
 FreePacket(MyPacket);
             NdisReturnPackets(&OriginalPacket, 1);
}
else
{
}
如果保留区的原始包不为空,那它就是指向原先Miniport上传上的的包描述符,那就是系统自已分配的Packet,直接调用NdisReturnPackets释放这个PACKET就行了。
如果为空,说明这个包是我们自己申请的,里面CHAIN的内存也是我们申请的,那么在这里就要调用一大堆FreePacket,FreeBuffer,FreeMemory等等一系列的动作了。

说了这么多,也不知讲清楚了没有。 :) :D
dlmufox
驱动牛犊
驱动牛犊
  • 注册日期2003-10-05
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2004-04-07 09:38
讲的非常的好,我以前也摸索了好半天才搞懂
coohaze
驱动牛犊
驱动牛犊
  • 注册日期2003-02-21
  • 最后登录2008-12-16
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2004-04-07 11:19
怎么XPDDK里面PassThru的ADAPT和2000DDK里面不一样呢?
youngyt
驱动牛犊
驱动牛犊
  • 注册日期2003-11-23
  • 最后登录2006-12-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2004-04-09 09:19
楼主该散分了。 :D
wywwwl
驱动大牛
驱动大牛
  • 注册日期2002-08-16
  • 最后登录2018-04-07
  • 粉丝1
  • 关注0
  • 积分-10分
  • 威望135点
  • 贡献值6点
  • 好评度76点
  • 原创分0分
  • 专家分0分
  • 社区居民
17楼#
发布于:2004-04-09 09:28
9494
楼主写的不错!大家会给你分的!
琢磨悟真知
darkread
驱动牛犊
驱动牛犊
  • 注册日期2003-01-13
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2004-04-09 11:34
我不结帖的一个原因是我还在开发之中,我想把我在学习NDIS中碰到得我问题集合起来,为以后的初学者提供一个比较好的教材,因为我在学习之中碰到了许多问题,一个一个很分散,有时候找不到,心里非常着急,却又无能为力,很惨的
不知道大家同不同意我的想法,如果同意大家请多多帮忙,把经常碰到的问题和他的解决方案都放上来,好不好
dlmufox
驱动牛犊
驱动牛犊
  • 注册日期2003-10-05
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2004-04-10 08:48
支持,非常的支持,身边只有我一个人研究ndis真实辛苦呀,坚决的支持楼主
上一页
游客

返回顶部