阅读:1155回复:0
关于文件系统Irp的问题
得到文件系统的DeviceObject后,我自己构建Irp发送给它时需要判断其数据访问方式为DIRECT_IO还是BUFFER_IO还是其他的,如果设备数据访问方式为DO_BUFFERED_IO时,pirp->AssociatedIrp.SystemBuffer需要指向的Buffer必须是在未分页池中申请的吗,大家看看我下面这段代码有问题吗???
NTSTATUS FDeleteFile(PUNICODE_STRING filename) { HANDLE hf; NTSTATUS lns; IO_STATUS_BLOCK iosb; OBJECT_ATTRIBUTES oba; PFILE_OBJECT pfo; KEVENT event; PIRP pirp; PMDL mdl; FILE_DISPOSITION_INFORMATION buffer,*pbuffer_nopaged; PIO_STACK_LOCATION pisl; DEVICE_OBJECT *pdo; if(KeGetCurrentIrql() >PASSIVE_LEVEL) { return STATUS_SUCCESS; } InitializeObjectAttributes( &oba,filename,OBJ_KERNEL_HANDLE|OBJ_CASE_INSENSITIVE,0,0); lns=IoCreateFile(&hf,DELETE|GENERIC_READ,&oba,&iosb,0,FILE_ATTRIBUTE_NORMAL,FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE,FILE_OPEN,0,0,0,0,0,IO_FORCE_ACCESS_CHECK | IO_NO_PARAMETER_CHECKING); if(!NT_SUCCESS(lns)) { #if (DBG) { DbgPrint ("-------------------IoCreateFile error\n"); DbgPrint ("filename.buffer:%ws\n.lenght:%d\n.maxlen:%d",filename->Buffer,filename->Length,filename->MaximumLength); DbgPrint ("Obj name:%ws",oba.ObjectName->Buffer); DbgPrint ("Status:%x",lns); } #endif return lns; } lns=ObReferenceObjectByHandle(hf,DELETE,*IoFileObjectType,KernelMode,(PVOID *)&pfo,0); if(!NT_SUCCESS(lns)) { #if (DBG) { DbgPrint ("-------------------ObReferenceObjectByHandle error\n"); } #endif return lns; } if(pfo->Vpb!=NULL&&pfo->Vpb->DeviceObject!=NULL) { pdo=pfo->Vpb->DeviceObject; } else pdo=pfo->DeviceObject; pirp=IoAllocateIrp(pdo->StackSize,FALSE); if(!pirp) { #if (DBG) { DbgPrint ("-------------------IoAllocateIrp\n"); } #endif return lns; } buffer.DeleteFile=TRUE; pbuffer_nopaged=(FILE_DISPOSITION_INFORMATION *)ExAllocatePool(NonPagedPool,sizeof(FILE_DISPOSITION_INFORMATION)); if(pbuffer_nopaged) { RtlZeroMemory(pbuffer_nopaged,sizeof(FILE_DISPOSITION_INFORMATION)); pbuffer_nopaged->DeleteFile=TRUE; } if(pdo->Flags & DO_BUFFERED_IO) { if(pbuffer_nopaged) pirp->AssociatedIrp.SystemBuffer=(PVOID)pbuffer_nopaged;//buffered io else pirp->AssociatedIrp.SystemBuffer=(PVOID)&buffer; #if (DBG) { DbgPrint("DO_BUFFERED_IO"); } #endif } else if(pdo->Flags & DO_DIRECT_IO) { mdl=IoAllocateMdl((PVOID)&buffer,sizeof(FILE_DISPOSITION_INFORMATION),0,0,0); MmBuildMdlForNonPagedPool(mdl); pirp->MdlAddress=mdl;//direct io #if (DBG) { DbgPrint("DO_DIRECT_IO"); } #endif } else { pirp->UserBuffer=(PVOID)&buffer;//neither i/o, use kernel buffer } pisl=IoGetCurrentIrpStackLocation (pirp); pisl->FileObject=pfo; pisl->MajorFunction=IRP_MJ_SET_INFORMATION; pisl->Parameters.SetFile.Length = sizeof(FILE_DISPOSITION_INFORMATION); pisl->Parameters.SetFile.FileInformationClass = FileDispositionInformation; pisl->Parameters.SetFile.DeleteHandle = hf; KeInitializeEvent(&event, NotificationEvent, FALSE); IoSetCompletionRoutine(pirp,IoCompletion,&event,1,1,1); #if (DBG) { DbgPrint ("-------------------IoSetCompletionRoutine\n"); DbgPrint ("Device name:%ws",pdo->DriverObject->DriverName.Buffer); } #endif /*lns=IoCallDriver(pdo,pirp);//如果执行该句,系统蓝屏报告Fastfat.sys错误 if(lns==STATUS_PENDING) { KeWaitForSingleObject(&event, Executive,KernelMode,0,0); lns=pirp->IoStatus.Status; } lns=pirp->IoStatus.Information;//bytes read */ IoFreeIrp(pirp); if(mdl){IoFreeMdl(mdl);}//if DO_DIRECT_IO////如果不执行IoCallDriver则下面无论是什么语句都会蓝屏报BAD_POOL_HEADER //if(pbuffer_nopaged){ExFreePool((PVOID)pbuffer_nopaged);} return lns; } 大侠们帮我看看呀,初学,太多东西不懂 |
|