阅读:1453回复:2
最高分奉送:在98Tdi驱动程序中,欲得到完整数据包,程序已好,可是蓝屏,谁能告诉我怎么回事。
开发环境: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检查无内存泄漏。 |
|
最新喜欢:linwn
|
沙发#
发布于:2003-11-19 09:15
用softice跟踪调试不就知道了?
|
|
|
板凳#
发布于:2003-11-19 09:23
同事已经帮我解决了,不准备放分了。另外因为当时蓝屏位置不固定,所以用softice也没有办法调试。
|
|
|