阅读:5705回复:17
tdi过滤驱动里自己分配一个irp,TdiBuildQueryInformation,蓝屏
晕阿,大家帮忙看下问题出在哪里,谢谢!
NTSTATUS completegettcpportbyfile(IN PDEVICE_OBJECT DeviceObject,IN PIRP irp,IN PVOID context){ __asm int 3; if(irp->PendingReturned){ IoMarkIrpPending(irp); } return STATUS_MORE_PROCESSING_REQUIRED;//自己分配的irp必须返回这个! } int gettcpportbyfile(PFILE_OBJECT file){//return -1 error,0 not tcp,other port number PIRP newirp; void* pooladdr; PMDL pmdl; int stat; int tmp; __asm int 3; newirp=IoAllocateIrp(plowerdev->StackSize,0);//分配新的irp pooladdr=ExAllocatePool(NonPagedPool,4096);//内存池 pmdl=IoAllocateMdl(pooladdr,4096,0,0,0);//内存池对应的mdl if(pmdl==0){ #ifdef bydbg DbgPrint("bytdiflt.sys:cannot alloc MDL at gettcpportbyfile.\n"); DbgBreakPoint(); #endif ExFreePool(pooladdr); IoFreeIrp(newirp); return -1; } /// TdiBuildQueryInformation(newirp,plowerdev,file,completegettcpportbyfile, 0,TDI_QUERY_ADDRESS_INFO,pmdl); stat=IoCallDriver(plowerdev,newirp); if(NT_SUCCESS(stat)){ if(((TDI_ADDRESS_INFO*)pooladdr)->Address.Address[0].AddressType==TDI_ADDRESS_TYPE_IP) {stat=((TDI_ADDRESS_IP*)(& ((TDI_ADDRESS_INFO*)pooladdr)->Address.Address[0].Address[0])) ->sin_port; //my_ntohs tmp=(UCHAR)stat; stat>>=8; stat|=(tmp<<8); } else {stat=0;} } else {stat=-1;} /// //IoCompleteRequest(newirp, IO_NO_INCREMENT);自己创建的不需要了 IoFreeIrp(newirp); IoFreeMdl(pmdl); ExFreePool(pooladdr); return stat; } |
|
|
沙发#
发布于:2005-08-01 10:43
stat=IoCallDriver(plowerdev,newirp);这句调用发出以后返回以前,完成例程被调用以前,发生的在tdi.sys中的page_error_in_nonpaged_area的bugcheck
|
|
|
板凳#
发布于:2005-08-01 14:57
如果IoCallDriver返回pending,不蓝才怪
好像对完成例程的作用并不太清楚? |
|
地板#
发布于:2005-08-01 15:00
对stat == STATUS_PENDING没做处理
|
|
地下室#
发布于:2005-08-01 15:28
IoCallDriver函数根本就没有返回,是返回前就死了的,应该和stat == STATUS_PENDING没有什么关系吧?可能我上面没有叙述清楚
|
|
|
5楼#
发布于:2005-08-01 16:39
TdiBuildQueryInformation前增加
KeInitializeEvent(&Event, NotificationEvent, TRUE); KeClearEvent(&Event); irp->UserEvent = &Event; irp->UserIosb = &IoStatus; 在status = IoCallDriver(deviceObject, irp);后增加 if (status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); status = IoStatus.Status; } |
|
|
6楼#
发布于:2005-08-01 16:40
还有Complete中增加
if (Irp->UserEvent) { KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, FALSE); } |
|
|
7楼#
发布于:2005-08-02 00:11
MmBuildMdlForNonPagedPool(pmdl);
|
|
8楼#
发布于:2005-08-02 10:09
tdi query_information这个irp不会返回pending,所以同步不是主要问题,这两天我发现主要存在2个问题:
一是我原来用的IoAllocateIrp后面跟着TdiBuildQueryInformation,ddk说应该用TdiBuildInternalDeviceControlIrp,就先改成它试试看; 二是原来没有MmBuildMdlForNonPagedPool,只是IoAllocateMdl,肯定不行,加上它 现在发现IoCallDriver里查询时还好,但是运行到系统自带的完成例程时崩溃,PFN_LIST_CORRUPT,(TdiBuildInternalDeviceControlIrp不用自己设置完成例程),大家帮忙看看呀,我都要崩溃了。 int gettcpportbyfile(PFILE_OBJECT file){//return -1 error,0 not tcp,other port number PIRP newirp; void* pooladdr; PMDL pmdl; int stat; int tmp; IO_STATUS_BLOCK iosb; KEVENT event; /// __asm int 3; if(KeGetCurrentIrql()>PASSIVE_LEVEL){return -1;} KeInitializeEvent(&event,NotificationEvent,0); newirp=TdiBuildInternalDeviceControlIrp(TDI_QUERY_INFORMATION,plowerdev,file,&event,&iosb); pooladdr=ExAllocatePool(NonPagedPool,4096);//内存池 pmdl=IoAllocateMdl(pooladdr,4096,0,0,0);//内存池对应的mdl MmBuildMdlForNonPagedPool(pmdl);//这个不能没有 if(pmdl==0){ #ifdef bydbg DbgPrint("bytdiflt.sys:cannot alloc MDL at gettcpportbyfile.\n"); DbgBreakPoint(); #endif ExFreePool(pooladdr); IoFreeIrp(newirp); return -1; } /// TdiBuildQueryInformation(newirp,plowerdev,file,0, 0,TDI_QUERY_ADDRESS_INFO,pmdl);//不提供完成例程,按照TdiBuildInternalDeviceControlIrp的事件自动完成 stat=IoCallDriver(plowerdev,newirp); if(stat==STATUS_PENDING){ KeWaitForSingleObject(&event, Executive,KernelMode,0,0); stat=iosb.Status; }//同步irp完成 if(NT_SUCCESS(stat)){ if(((TDI_ADDRESS_INFO*)pooladdr)->Address.Address[0].AddressType==TDI_ADDRESS_TYPE_IP) {stat=((TDI_ADDRESS_IP*)(& ((TDI_ADDRESS_INFO*)pooladdr)->Address.Address[0].Address[0])) ->sin_port; //my_ntohs tmp=(UCHAR)stat; stat>>=8; stat|=(tmp<<8); } else {stat=0; #ifdef bydbg DbgPrint("bytdiflt:non-tcp file called tcp's irp.\n"); DbgBreakPoint(); #endif } } else {stat=-1;} /// //IoCompleteRequest(newirp, IO_NO_INCREMENT);//自己创建的不需要了,否则蓝屏 IoFreeIrp(newirp); IoFreeMdl(pmdl); ExFreePool(pooladdr); return stat; } |
|
|
9楼#
发布于:2005-08-02 10:45
我给你一段好了!!
NTSTATUS AllocateMdlAndIrp(IN PVOID BufVAddress, IN ULONG BufLength, IN UCHAR StackSize, IN BOOLEAN IsNonPage, PIRP* Irp, PMDL* Mdl) { PMDL TempMdl = IoAllocateMdl(BufVAddress, BufLength, FALSE, FALSE, NULL); if(TempMdl) { __try { if(IsNonPage) { MmBuildMdlForNonPagedPool(TempMdl); } else { MmProbeAndLockPages(TempMdl, KernelMode, IoModifyAccess); // __try } PIRP TempIrp = IoAllocateIrp(StackSize, FALSE); if(TempIrp) { *Mdl = TempMdl; *Irp = TempIrp; return STATUS_SUCCESS; } } __except(EXCEPTION_EXECUTE_HANDLER){} IoFreeMdl(TempMdl); } *Mdl = NULL; *Irp = NULL; return STATUS_INSUFFICIENT_RESOURCES; } VOID FreeMdlAndIrp(IN PIRP Irp, IN PMDL Mdl, IN BOOLEAN IsNonPage) { PMDL PrevMdl, NextMdl; if(Irp) { PrevMdl = Irp->MdlAddress; while(PrevMdl) { NextMdl = PrevMdl->Next; if(PrevMdl == Mdl) { Mdl = NULL; } if(!IsNonPage) //if(PrevMdl->MdlFlags |= MDL_PAGES_LOCKED) { MmUnlockPages(PrevMdl); } IoFreeMdl(PrevMdl); PrevMdl = NextMdl; } IoFreeIrp(Irp); } PrevMdl = Mdl; while(PrevMdl) { NextMdl = PrevMdl->Next; if(!IsNonPage) //if(PrevMdl->MdlFlags |= MDL_PAGES_LOCKED) { MmUnlockPages(PrevMdl); } IoFreeMdl(PrevMdl); PrevMdl = NextMdl; } return; } ////////////////////////////////////////////////////////////////////////// NTSTATUS iSpTdiCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context) { UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(Context); Irp->UserIosb->Information = Irp->IoStatus.Information; Irp->UserIosb->Status = Irp->IoStatus.Status; KeSetEvent(Irp->UserEvent, IO_NETWORK_INCREMENT, FALSE); return STATUS_MORE_PROCESSING_REQUIRED; } NTSTATUS iSpTdiSendIrpSynchronous(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG WaitTime) { IO_STATUS_BLOCK Iosb; KEVENT WaitEvent; NTSTATUS NtStatus; KeInitializeEvent(&WaitEvent, NotificationEvent, FALSE); Irp->UserEvent = &WaitEvent; Irp->UserIosb = &Iosb; NtStatus = IoCallDriver(DeviceObject, Irp); if(NtStatus == STATUS_PENDING) { LARGE_INTEGER OutTime; OutTime.QuadPart = WaitTime*(-10000000); KeWaitForSingleObject(&WaitEvent, Executive, KernelMode, FALSE, WaitTime==0?NULL:&OutTime); if(NtStatus != STATUS_TIMEOUT) { NtStatus = Iosb.Status; } else { IoCancelIrp(Irp); KeWaitForSingleObject(&WaitEvent, Executive, KernelMode, FALSE, NULL); NtStatus = STATUS_CANCELLED; } } return NtStatus; } NTSTATUS iSpTdiQueryInformation(IN PDEVICE_OBJECT PDOTransport, IN PFILE_OBJECT PFOTransport, IN ULONG InfoType, IN ULONG InfoLength, OUT PVOID InfoBuffer) { PIRP Irp; PMDL Mdl; NTSTATUS NtStatus = AllocateMdlAndIrp(InfoBuffer, InfoLength, PDOTransport->StackSize, TRUE, &Irp, &Mdl); if(NT_SUCCESS(NtStatus)) { TdiBuildQueryInformation(Irp, PDOTransport, PFOTransport, iSpTdiCompletionRoutine, NULL, InfoType, Mdl); NtStatus = iSpTdiSendIrpSynchronous(PDOTransport, Irp, 0); FreeMdlAndIrp(Irp, Mdl, TRUE); } return NtStatus; } |
|
10楼#
发布于:2005-08-02 21:19
ldljlzw兄的代码是可以成功的,谢谢你了!不过我还是想知道
KeInitializeEvent(&event,NotificationEvent,0); newirp=TdiBuildInternalDeviceControlIrp(TDI_QUERY_INFORMATION,plowerdev,file,&event,&iosb); pooladdr=ExAllocatePool(NonPagedPool,4096);//内存池 pmdl=IoAllocateMdl(pooladdr,4096,0,0,0);//内存池对应的mdl MmBuildMdlForNonPagedPool(pmdl);//这个不能没有 TdiBuildQueryInformation(newirp,plowerdev,file,0, 0,TDI_QUERY_ADDRESS_INFO,pmdl);//不提供完成例程,按照TdiBuildInternalDeviceControlIrp的事件自动完成 stat=IoCallDriver(plowerdev,newirp); if(stat==STATUS_PENDING){ KeWaitForSingleObject(&event, Executive,KernelMode,0,0); stat=iosb.Status; }//同步irp完成 这种使用TdiBuildInternalDeviceControlIrp()的方法错在哪里了,会产生PFN_LIST_CORRUPT的bugcheck?ddk可是说应该用这个的啊,而不是ldljlzw兄使用的IoAllocateIrp,那位老大能解释一下呢?谢谢 |
|
|
11楼#
发布于:2005-08-03 00:09
下面是引用baiyuanfan于2005-08-02 21:19发表的: KeInitializeEvent(&event,NotificationEvent,0); 改为: KeInitializeEvent(&event,SynchronizationEvent,FALSE); 还有 KeWaitForSingleObject(&event, Executive,KernelMode,0,0); 可以改为 KeWaitForSingleObject(&event, Executive,KernelMode,TRUE,NULL); 试试 |
|
12楼#
发布于:2005-08-03 06:17
跟KeInitializeEvent和KeWaitForSingleObject没有关系,在系统的IoCompleteRequest的执行过程中产生PFN_LIST_CORRUPT的bugcheck,IoCallDriver还没有返回
|
|
|
13楼#
发布于:2005-08-03 09:20
但是这个看来没有什么问题,NT 源代码里都是这样用的!!!
|
|
14楼#
发布于:2005-08-03 09:22
这是从NT源代码中取来的:
// // Create an event for the synchronous I/O requests that we'll be issuing. // KeInitializeEvent (&Event, SynchronizationEvent, FALSE); Irp = TdiBuildInternalDeviceControlIrp (TDI_ASSOCIATE_ADDRESS, DeviceObject, ConnectionObject, &Event, &Iosb); TdiBuildAssociateAddress (Irp, DeviceObject, ConnectionObject, NULL, NULL, AddressHandle); Status = IoCallDriver(DeviceObject, Irp); if(Status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, NULL); } Status = Irp->IoStatus.Status; |
|
15楼#
发布于:2005-08-03 09:29
只一个问题你是否注意了!就是TDI_QUERY_ADDRESS_INFO要用TDI的Transport设备对象和文件对象,还不是Connection设备对象和文件对象,这是有区别的!
|
|
16楼#
发布于:2005-08-04 22:22
更郁闷的是换成用IoAllocateIrp的方式,
KeInitializeEvent(&event,SynchronizationEvent,0); pooladdr=ExAllocatePool(NonPagedPool,4096); pmdl=IoAllocateMdl(pooladdr,4096,0,0,0); MmBuildMdlForNonPagedPool(pmdl); newirp=IoAllocateIrp(plowerdev->StackSize,0); TdiBuildQueryInformation(newirp,plowerdev,file,completegettcpportbyfile, 0,TDI_QUERY_ADDRESS_INFO,pmdl); newirp->UserEvent = &event; newirp->UserIosb = &iosb; /// stat=IoCallDriver(plowerdev,newirp); if(stat==STATUS_PENDING){ KeWaitForSingleObject(&event, Executive,KernelMode,0,0); stat=iosb.Status; }//同步irp完成 就能成功,但是 if(KeGetCurrentIrql()>PASSIVE_LEVEL){return -1;} KeInitializeEvent(&event,SynchronizationEvent,0); newirp=TdiBuildInternalDeviceControlIrp(TDI_QUERY_INFORMATION,plowerdev,file,&event,&iosb); pooladdr=ExAllocatePool(NonPagedPool,4096);//内存池 pmdl=IoAllocateMdl(pooladdr,4096,0,0,0);//内存池对应的mdl MmBuildMdlForNonPagedPool(pmdl);//这个不能没有 TdiBuildQueryInformation(newirp,plowerdev,file,0, 0,TDI_QUERY_ADDRESS_INFO,pmdl); stat=IoCallDriver(plowerdev,newirp); if(stat==STATUS_PENDING){ KeWaitForSingleObject(&event, Executive,KernelMode,0,0); stat=iosb.Status; }//同步irp完成 就会发生pfn_list_corrupt,我实在看不出来这两个有什么区别?? |
|
|
17楼#
发布于:2010-04-12 23:10
我顶起啊 什么问题呢?
|
|
|