wolf
驱动牛犊
驱动牛犊
  • 注册日期2001-06-21
  • 最后登录2009-04-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1453回复:2

最高分奉送:在98Tdi驱动程序中,欲得到完整数据包,程序已好,可是蓝屏,谁能告诉我怎么回事。

楼主#
更多 发布于:2003-11-12 10:35
开发环境:Vc++6.0,ddk,vtoolsd
源代码基础:Vtoolsd中的Hooktdi sample;
增加代码如下。

typedef VOID (*SecondReceive_CallBack)(           // Call back
  PVOID

Context,
  TDI_STATUS FinalStatus,
  unsigned long ByteCount
  );

VOID Recv_CallBack(PVOID Context,
TDI_STATUS FinalStatus,
unsigned long ByteCount);
void* _cdecl MyNew(size_t n)
{
PVOID p;
DWORD handle;
DWORD nPages = (n+0xFFF) >> 12;

_PageAllocate(nPages, PG_SYS, 0, 0, 0, 0, 0, 0, &handle, &p);

return handle;
}

void _cdecl MyDel(void* p)
{
if (p == 0)
return;

_PageFree(p, 0);
}


// This is the hook for receive events

struct MyRecvContext{

// EventRcvBuffer *Buffer;
PVOID EventContext;
PVOID ConnectionContext;
uint Available;
ulong Flags;
PVOID VirtualAddress;
USHORT erb_flag;
};

VOID Recv_CallBack(PVOID Context,
TDI_STATUS FinalStatus,
unsigned long ByteCount)
{
struct HandleInfo *EventContext = NULL;
struct MyRecvContext *pMyCon = NULL;
TDI_STATUS status;
PVOID ConnectionContext;
ulong Flags;

int iSendLength = 0;
int iAvaildLength = 0;
char *pSendBuf = NULL;
struct HandleInfo* p ;
UINT MyTaken = 0;
EventRcvBuffer MyBuffer;
//=======================================================

dprintf(\"into Recv_CallBack HookTdi line  = %d \\n\",__LINE__);
//check :pMyCon->erb_flag

pMyCon = Context;
EventContext = pMyCon->EventContext;
p= (struct HandleInfo*)EventContext;


ConnectionContext = pMyCon->ConnectionContext;
Flags = pMyCon->Flags;

//=======================================================
iSendLength = ByteCount;
iAvaildLength = ByteCount;
pSendBuf = pMyCon->VirtualAddress;

while(iSendLength >0)
{
status = p->pReceiveEventHandler(
p->Context,
ConnectionContext,
Flags,
iSendLength,
iAvaildLength,
&MyTaken,
pSendBuf,
&MyBuffer);
if(TDI_SUCCESS == status)
{
_asm int 3;
iSendLength = iSendLength -  MyTaken;
iAvaildLength = iAvaildLength - MyTaken;
pSendBuf=pSendBuf+MyTaken;
continue;
}
else if(TDI_MORE_PROCESSING == status)
{
iSendLength = iSendLength -  MyTaken;
iAvaildLength = iAvaildLength - MyTaken;
if((iSendLength<=0)||(iAvaildLength<=0))
{
break;
}
pSendBuf=pSendBuf+MyTaken;

if(MyBuffer.erb_size<iSendLength)
{
memcpy(MyBuffer.erb_buffer->VirtualAddress,pSendBuf,MyBuffer.erb_size);
*MyBuffer.erb_flags = TDI_RECEIVE_NORMAL | TDI_RECEIVE_ENTIRE_MESSAGE;
((SecondReceive_CallBack)MyBuffer.erb_rtn)(
MyBuffer.erb_context,
0,
MyBuffer.erb_size);
iSendLength = iSendLength -  MyBuffer.erb_size;
iAvaildLength = iAvaildLength - MyBuffer.erb_size;
if((iSendLength<=0)||(iAvaildLength<=0))
{
break;
}
pSendBuf=pSendBuf+MyBuffer.erb_size;
continue;
}
memcpy(MyBuffer.erb_buffer->VirtualAddress,pSendBuf,iSendLength);
*MyBuffer.erb_flags = TDI_RECEIVE_NORMAL | TDI_RECEIVE_ENTIRE_MESSAGE;
((SecondReceive_CallBack)MyBuffer.erb_rtn)(
MyBuffer.erb_context,
0,
iSendLength);
dprintf(\"HookTdi line  = %d \\n\",__LINE__);
break;
}
else
{
_asm int 3;
return ;
}
}
//=======================================================

MyDel(pMyCon->VirtualAddress);
MyDel(pMyCon);
dprintf(\"Out Recv_CallBack HookTdi line  = %d \\n\",__LINE__);
}


TDI_STATUS MyReceiveEventHandler(
PVOID EventContext,
PVOID ConnectionContext,
ulong Flags,
uint Indicated,
uint Available,
uint *Taken,
uchar *Data,
EventRcvBuffer *Buffer
)
{
struct MyRecvContext *pMyCon = NULL;

dprintf(\"into MyReceiveEventHandler HookTdi line  = %d \\n\",__LINE__);

pMyCon = Buffer->erb_context = MyNew(sizeof (struct MyRecvContext));
/*
if(Available < BUFFER_SIZE)
{
Buffer->erb_buffer->VirtualAddress = malloc(Available);
Buffer->erb_size = Available;
pMyCon->Available = Available;
}
else
{
Buffer->erb_buffer->VirtualAddress = malloc(BUFFER_SIZE);
Buffer->erb_size = BUFFER_SIZE;
pMyCon->Available = BUFFER_SIZE;
}
*/
pMyCon->VirtualAddress = Buffer->erb_buffer->VirtualAddress = MyNew(Available);
pMyCon->Available = Buffer->erb_size = Available;

pMyCon->ConnectionContext = ConnectionContext;
pMyCon->EventContext = EventContext;
pMyCon->Flags = Flags;

Buffer->erb_flags = &pMyCon->erb_flag;
Buffer->erb_rtn = Recv_CallBack;

*Taken = 0;

dprintf(\"out MyReceiveEventHandler HookTdi line  = %d \\n\",__LINE__);

return TDI_MORE_PROCESSING;
}

情况一:在内存分配函数中使用如下代码。可以打开网页(www.google.com)3次后蓝屏。

void* _cdecl MyNew(size_t n)
{
PVOID p;
DWORD handle;
DWORD nPages = (n+0xFFF) >> 12;

_PageAllocate(nPages, PG_SYS, 0, 0, 0, 0, 0, 0, &handle, &p);

return handle;
}

void _cdecl MyDel(void* p)
{
if (p == 0)
return;

_PageFree(p, 0);
}

情况二:在内存分配函数中使用如下代码。第一次上网就蓝屏。

void* _cdecl MyNew(size_t n)
{
PVOID p;
DWORD handle;
DWORD nPages = (n+0xFFF) >> 12;

_PageAllocate(nPages, PG_SYS, 0, 0, 0, 0, 0, PAGEFIXED, &handle, &p);

return handle;
}

void _cdecl MyDel(void* p)
{
if (p == 0)
return;

_PageFree(p, 0);
}

情况三:在内存分配函数中使用如下代码。第一次上网就蓝屏。

void* _cdecl MyNew(size_t n)
{
return malloc (n);
}

void _cdecl MyDel(void* p)
{
free(p);
}


根据经验,应该是内存问题,可是我没有驱动下的内存泄漏检测工具。将代码修正为Vc环境之后,用BondCheck检查无内存泄漏。

最新喜欢:

linwnlinwn
Wolf
yongliliu
驱动小牛
驱动小牛
  • 注册日期2003-10-20
  • 最后登录2007-09-28
  • 粉丝0
  • 关注0
  • 积分11分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-11-19 09:15
用softice跟踪调试不就知道了?
成功不是天上掉下来的免费的丰盛的晚餐!
wolf
驱动牛犊
驱动牛犊
  • 注册日期2001-06-21
  • 最后登录2009-04-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-11-19 09:23
同事已经帮我解决了,不准备放分了。另外因为当时蓝屏位置不固定,所以用softice也没有办法调试。
Wolf
游客

返回顶部