阅读:3375回复:3
自己写的kernel代码老是蓝屏,大侠们帮我看看
参考一位大侠的资料,尝试写一个小东东:向文件系统的FDO发送Irp来删除某个文件,代码如下:
#include "stdio.h" #include <ntddk.h> #include "sys.h" //常量定义; #define DEVICE_TYPE_SYSMON0x8266//DDK指出0-7fffh是被系统保留了 #define NT_DEVICE_NAMEL"\\Device\\FSYS"//内核设备名 #define DOS_DEVICE_NAMEL"\\DosDevices\\FSYS"//符号连接设备名 //全局变量定义; PDRIVER_OBJECTgOwenDriverObject;//本驱动程序对象 PDEVICE_OBJECTgCtrlDeviceObject;//用控制设备对象域 #pragma code_seg("PAGE") VOID Unload(PDRIVER_OBJECT DriverObject) { UNICODE_STRING Win32DeviceName; RtlInitUnicodeString(&Win32DeviceName,DOS_DEVICE_NAME); IoDeleteSymbolicLink(&Win32DeviceName); IoDeleteDevice(gCtrlDeviceObject); #if (DBG) { DbgPrint (("-------------------Unload OK\n")); } #endif return; } NTSTATUS IoCompletion(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context) { KeSetEvent((PRKEVENT)Context, IO_DISK_INCREMENT, 0); return STATUS_MORE_PROCESSING_REQUIRED; } NTSTATUS FDeleteFile(PUNICODE_STRING filename) { HANDLEhf; NTSTATUSlns; IO_STATUS_BLOCK iosb; OBJECT_ATTRIBUTES oba; PFILE_OBJECTpfo; 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); 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 //if(pbuffer_nopaged){ExFreePool((PVOID)pbuffer_nopaged);} return lns; } NTSTATUS DeviceIrpCreate( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { IoCompleteRequest( Irp, IO_NO_INCREMENT ); return STATUS_SUCCESS; } NTSTATUS DeviceIrpClose( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { IoCompleteRequest( Irp, IO_NO_INCREMENT ); return STATUS_SUCCESS; } NTSTATUS DeviceIrpControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { //if(KeGetCurrentIrql()>PASSIVE_LEVEL) NTSTATUS ns=STATUS_SUCCESS; PVOIDppath; PIO_STACK_LOCATION pisl=IoGetCurrentIrpStackLocation (Irp); if(pisl->Parameters.DeviceIoControl.IoControlCode==IRQ_DELFILE) { UNICODE_STRING fn; ppath=ExAllocatePoolWithTag(PagedPool,pisl->Parameters.DeviceIoControl.InputBufferLength,'FINB'); if(ppath) { #if (DBG) { DbgPrint("ExAllocatePoolWithTag success1"); DbgPrint("Input buffer is %ws",Irp->AssociatedIrp.SystemBuffer); } #endif RtlCopyBytes(ppath,Irp->AssociatedIrp.SystemBuffer,pisl->Parameters.DeviceIoControl.InputBufferLength); RtlInitUnicodeString(&fn,(PCWSTR)ppath); #if (DBG) { DbgPrint("Input buffer is %ws\nppath is %ws\nfn is %ws\n",Irp->AssociatedIrp.SystemBuffer,ppath,fn.Buffer); } #endif ns=FDeleteFile(&fn); } } Irp->IoStatus.Status=ns; Irp->IoStatus.Information=0; IoCompleteRequest( Irp, IO_NO_INCREMENT ); if(ppath) ExFreePool(ppath); return STATUS_SUCCESS; } #pragma code_seg("INIT") NTSTATUS//驱动程序入口; DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath) { NTSTATUSStatus; UNICODE_STRINGNtDeviceName; UNICODE_STRINGWin32DeviceName; //保存自己的驱动程序对象,备用 gOwenDriverObject=DriverObject; //初始化Unicode字符串, 创建设备对象; RtlInitUnicodeString(&NtDeviceName,NT_DEVICE_NAME); Status=IoCreateDevice( DriverObject,0,&NtDeviceName, DEVICE_TYPE_SYSMON,0,FALSE,&gCtrlDeviceObject); if (!NT_SUCCESS(Status)) return Status; //初始化Unicode字符串, 创建Win32符号连接,以便Win32程序能够访问; RtlInitUnicodeString(&Win32DeviceName,DOS_DEVICE_NAME); Status=IoCreateSymbolicLink(&Win32DeviceName,&NtDeviceName); if (!NT_SUCCESS(Status)) { IoDeleteDevice( gCtrlDeviceObject ); return Status; } //填写驱动程序Dispatch例程 DriverObject->MajorFunction[IRP_MJ_CREATE]=DeviceIrpCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE]=DeviceIrpClose; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=DeviceIrpControl; //填写处理Unload例程 DriverObject->DriverUnload =Unload; #if (DBG) { DbgPrint("DriverObject=%x RegistryPath=%x\n",DriverObject,RegistryPath); } #endif return Status; } 如果向pdo发送Irp则蓝屏报fastfat.sys错,如果不执行IoCreateDriver,则执行到if(mdl){IoFreeMdl(mdl);}以后,无论是什么语句都会蓝屏,报错BAD_POOL_HEADER 我估计是我构建的Irp有问题,但我实在不知道哪儿有问题,大侠们帮我看看,小弟在此谢过!!!! |
|
沙发#
发布于:2009-04-10 16:58
蓝屏没人问啊
![]() |
|
|
板凳#
发布于:2009-04-10 17:01
我也参考大牛代码写个东东 也是蓝屏啊 不知道怎么回事啊
![]() |
|
|
地板#
发布于:2010-01-22 14:13
IoFreeMdl的内存应该在Nonpaged pool中申请。出现19号蓝屏,是在释放内存的时候,发现内存前面4个字节所保存的Tag与指定不符。
不要用在栈中申请的Buffer。用AllocatePoolWithTag 试试 |
|
|