#define DISK_NAME L"\\Device\\Harddisk0\\DR0"
#pragma LOCKEDCODE
NTSTATUS
FltReadWriteSectorsCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
KIRQL oldirql = KeGetCurrentIrql();
if(oldirql < DISPATCH_LEVEL)
KeRaiseIrql(DISPATCH_LEVEL,&oldirql); UNREFERENCED_PARAMETER(DeviceObject); if (Irp->AssociatedIrp.SystemBuffer && (Irp->Flags & IRP_DEALLOCATE_BUFFER))
{
ExFreePool(Irp->AssociatedIrp.SystemBuffer);
}
else if (Irp->MdlAddress != NULL)
{
PMDL mdl,nextMdl;
for (mdl = Irp->MdlAddress; mdl != NULL; mdl = nextMdl)
{
nextMdl = mdl->Next;
MmUnlockPages( mdl );
IoFreeMdl( mdl );
}
Irp->MdlAddress = NULL;
} if(Context)
{
ExFreePool(Context);
} IoFreeIrp(Irp); KeLowerIrql(oldirql);
return STATUS_MORE_PROCESSING_REQUIRED;
}#pragma PAGEDCODE
NTSTATUS ReadWriteDisk(PULONG_PTR information ,ULONG MajorFunction,
PVOID Buffer,ULONG Length,PLARGE_INTEGER StartingOffset,BOOLEAN Wait)
{
NTSTATUS ntStatus = STATUS_SUCCESS; UNICODE_STRING DeviceName;
PDEVICE_OBJECT DeviceObject = NULL;
PFILE_OBJECT FileObject = NULL;
KEVENT AsynEvent;
IO_STATUS_BLOCK status_block;
PIRP pNewIrp ;
PIO_STACK_LOCATION stack;
RtlInitUnicodeString(&DeviceName,DISK_NAME);//L"\\Device\\Harddisk0\\DR0"
ntStatus = IoGetDeviceObjectPointer(&DeviceName,FILE_ALL_ACCESS,&FileObject,&DeviceObject);
if(!NT_SUCCESS(ntStatus))
{
KdPrint(("Get Harddisk0-DR0 Failed\n"));
information = 0;
ntStatus = STATUS_UNSUCCESSFUL;
return ntStatus;
}
else
KdPrint(("Get Harddisk0-DR0 Succeed\n")); pNewIrp = IoBuildAsynchronousFsdRequest(MajorFunction, DeviceObject,
Buffer, Length, StartingOffset, &status_block);
if (NULL == pNewIrp)
{
KdPrint(("IoBuildAsynchronousFsdRequest Failed\n"));
information = 0;
ObDereferenceObject(FileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}KdPrint(("IoBuildAsynchronousFsdRequest Succeed\n"));
PVOID context = ExAllocatePool(NonPagedPool, sizeof(KEVENT) );
if (NULL == context)
{
KdPrint(("ExAllocatePool Failed\n"));
ObDereferenceObject(FileObject);
IoFreeIrp(pNewIrp);
return STATUS_INSUFFICIENT_RESOURCES;
}KdPrint(("ExAllocatePool Succeed\n"));
IoSetCompletionRoutineEx(
DeviceObject,
pNewIrp,
FltReadWriteSectorsCompletion,
context,
TRUE,
TRUE,
TRUE); IoCallDriver(DeviceObject, pNewIrp);
//ObDereferenceObject(FileObject);
return STATUS_PENDING;
}以上代码是在NT式驱动的IRP_MJ_READ派遣例程中调用的(pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKRead;)。
代码如下:
#pragma PAGEDCODE
NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp)
{
KdPrint(("Test3\n"));
PULONG_PTR information = 0;
UCHAR* bTemp = (UCHAR*)ExAllocatePool(NonPagedPool, 512 ); LARGE_INTEGER StartSector;
StartSector.QuadPart = 0x10000;
return ReadWriteDisk(information ,IRP_MJ_READ,
bTemp,512,&StartSector,TRUE);
}我先加载了驱动程序,然后写了AP在其中用ReadFile调用此驱动程序,当我执行此AP后便会蓝屏。操作系统为WIN7 home版。dump文件内容如下:
KERNEL_MODE_EXCEPTION_NOT_HANDLED_M (1000008e)
This is a very common bugcheck. Usually the exception address pinpoints
the driver/function that caused the problem. Always note this address
as well as the link date of the driver/image that contains this address.
Some common problems are exception code 0x80000003. This means a hard
coded breakpoint or assertion was hit, but this system was booted
/NODEBUG. This is not supposed to happen as developers should never have
hardcoded breakpoints in retail code, but ...
If this happens, make sure a debugger gets connected, and the
system is booted /DEBUG. This will let us see why this breakpoint is
happening.
Arguments:
Arg1: c0000005, The exception code that was not handled
Arg2: 836bb933, The address that the exception occurred at
Arg3: 9f132a10, Trap Frame
Arg4: 00000000FAULTING_MODULE: 8361f000 ntDEBUG_FLR_IMAGE_TIMESTAMP: 49ee8cbaEXCEPTION_CODE: (NTSTATUS) 0xc0000005 - "0x%08lx"FAULTING_IP:
nt+9c933
836bb933 8b400c mov eax,dword ptr [eax+0Ch]TRAP_FRAME: 9f132a10 -- (.trap 0xffffffff9f132a10)
ErrCode = 00000000
eax=00000000 ebx=85fc4e40 ecx=85fc4e98 edx=00000000 esi=9f132b00 edi=00000001
eip=836bb933 esp=9f132a84 ebp=9f132a84 iopl=0 nv up ei pl nz na po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010202
nt+0x9c933:
836bb933 8b400c mov eax,dword ptr [eax+0Ch] ds:0023:0000000c=????????
Resetting default scopeCUSTOMER_CRASH_COUNT: 1DEFAULT_BUCKET_ID: WRONG_SYMBOLSBUGCHECK_STR: 0x8ECURRENT_IRQL: 0LAST_CONTROL_TRANSFER: from 843f0afb to 836bb933STACK_TEXT:
WARNING: Stack unwind information not available. Following frames may be wrong.
9f132a84 843f0afb 00000000 85fc4e40 86018dc8 nt+0x9c933
9f132ae0 84202aeb 85fc4e40 9f132b00 9f132b2c fileinfo+0x1afb
9f132b4c 842059f0 9f132ba0 874ab6c8 00000000 fltmgr+0x2aeb
9f132b64 84205f01 9f132ba0 00000000 85fd6030 fltmgr+0x59f0
9f132b88 842063ba 03132b01 85fd6030 00000000 fltmgr+0x5f01
9f132bb8 83650ad1 85fd6030 874ab6c8 85fe1ef0 fltmgr+0x63ba
9f132bd0 9596d859 879225f8 00000000 00000208 nt+0x31ad1
9f132c10 9596d9a4 00000000 00000003 85f67d70 HelloDDK+0x859
9f132c44 83650ad1 85fe1ef0 86876ca0 86876ca0 HelloDDK+0x9a4
9f132c5c 83848177 86876ca0 86876d10 85abb830 nt+0x31ad1
9f132c7c 83853e2f 85fe1ef0 85abb830 00000001 nt+0x229177
9f132d08 836573fa 85fe1ef0 86876ca0 00000000 nt+0x234e2f
9f132d34 76ec8244 badb0d00 002ef8c8 00000000 nt+0x383fa
9f132d38 badb0d00 002ef8c8 00000000 00000000 0x76ec8244
9f132d3c 002ef8c8 00000000 00000000 00000000 0xbadb0d00
9f132d40 00000000 00000000 00000000 00000000 0x2ef8c8
STACK_COMMAND: kbFOLLOWUP_IP:
fileinfo+1afb
843f0afb ?? ???SYMBOL_STACK_INDEX: 1SYMBOL_NAME: fileinfo+1afbFOLLOWUP_NAME: MachineOwnerMODULE_NAME: fileinfoIMAGE_NAME: fileinfo.sysBUCKET_ID: WRONG_SYMBOLSFollowup: MachineOwner
---------
#pragma LOCKEDCODE
NTSTATUS
FltReadWriteSectorsCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
KIRQL oldirql = KeGetCurrentIrql();
if(oldirql < DISPATCH_LEVEL)
KeRaiseIrql(DISPATCH_LEVEL,&oldirql); UNREFERENCED_PARAMETER(DeviceObject); if (Irp->AssociatedIrp.SystemBuffer && (Irp->Flags & IRP_DEALLOCATE_BUFFER))
{
ExFreePool(Irp->AssociatedIrp.SystemBuffer);
}
else if (Irp->MdlAddress != NULL)
{
PMDL mdl,nextMdl;
for (mdl = Irp->MdlAddress; mdl != NULL; mdl = nextMdl)
{
nextMdl = mdl->Next;
MmUnlockPages( mdl );
IoFreeMdl( mdl );
}
Irp->MdlAddress = NULL;
} if(Context)
{
ExFreePool(Context);
} IoFreeIrp(Irp); KeLowerIrql(oldirql);
return STATUS_MORE_PROCESSING_REQUIRED;
}#pragma PAGEDCODE
NTSTATUS ReadWriteDisk(PULONG_PTR information ,ULONG MajorFunction,
PVOID Buffer,ULONG Length,PLARGE_INTEGER StartingOffset,BOOLEAN Wait)
{
NTSTATUS ntStatus = STATUS_SUCCESS; UNICODE_STRING DeviceName;
PDEVICE_OBJECT DeviceObject = NULL;
PFILE_OBJECT FileObject = NULL;
KEVENT AsynEvent;
IO_STATUS_BLOCK status_block;
PIRP pNewIrp ;
PIO_STACK_LOCATION stack;
RtlInitUnicodeString(&DeviceName,DISK_NAME);//L"\\Device\\Harddisk0\\DR0"
ntStatus = IoGetDeviceObjectPointer(&DeviceName,FILE_ALL_ACCESS,&FileObject,&DeviceObject);
if(!NT_SUCCESS(ntStatus))
{
KdPrint(("Get Harddisk0-DR0 Failed\n"));
information = 0;
ntStatus = STATUS_UNSUCCESSFUL;
return ntStatus;
}
else
KdPrint(("Get Harddisk0-DR0 Succeed\n")); pNewIrp = IoBuildAsynchronousFsdRequest(MajorFunction, DeviceObject,
Buffer, Length, StartingOffset, &status_block);
if (NULL == pNewIrp)
{
KdPrint(("IoBuildAsynchronousFsdRequest Failed\n"));
information = 0;
ObDereferenceObject(FileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}KdPrint(("IoBuildAsynchronousFsdRequest Succeed\n"));
PVOID context = ExAllocatePool(NonPagedPool, sizeof(KEVENT) );
if (NULL == context)
{
KdPrint(("ExAllocatePool Failed\n"));
ObDereferenceObject(FileObject);
IoFreeIrp(pNewIrp);
return STATUS_INSUFFICIENT_RESOURCES;
}KdPrint(("ExAllocatePool Succeed\n"));
IoSetCompletionRoutineEx(
DeviceObject,
pNewIrp,
FltReadWriteSectorsCompletion,
context,
TRUE,
TRUE,
TRUE); IoCallDriver(DeviceObject, pNewIrp);
//ObDereferenceObject(FileObject);
return STATUS_PENDING;
}以上代码是在NT式驱动的IRP_MJ_READ派遣例程中调用的(pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKRead;)。
代码如下:
#pragma PAGEDCODE
NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp)
{
KdPrint(("Test3\n"));
PULONG_PTR information = 0;
UCHAR* bTemp = (UCHAR*)ExAllocatePool(NonPagedPool, 512 ); LARGE_INTEGER StartSector;
StartSector.QuadPart = 0x10000;
return ReadWriteDisk(information ,IRP_MJ_READ,
bTemp,512,&StartSector,TRUE);
}我先加载了驱动程序,然后写了AP在其中用ReadFile调用此驱动程序,当我执行此AP后便会蓝屏。操作系统为WIN7 home版。dump文件内容如下:
KERNEL_MODE_EXCEPTION_NOT_HANDLED_M (1000008e)
This is a very common bugcheck. Usually the exception address pinpoints
the driver/function that caused the problem. Always note this address
as well as the link date of the driver/image that contains this address.
Some common problems are exception code 0x80000003. This means a hard
coded breakpoint or assertion was hit, but this system was booted
/NODEBUG. This is not supposed to happen as developers should never have
hardcoded breakpoints in retail code, but ...
If this happens, make sure a debugger gets connected, and the
system is booted /DEBUG. This will let us see why this breakpoint is
happening.
Arguments:
Arg1: c0000005, The exception code that was not handled
Arg2: 836bb933, The address that the exception occurred at
Arg3: 9f132a10, Trap Frame
Arg4: 00000000FAULTING_MODULE: 8361f000 ntDEBUG_FLR_IMAGE_TIMESTAMP: 49ee8cbaEXCEPTION_CODE: (NTSTATUS) 0xc0000005 - "0x%08lx"FAULTING_IP:
nt+9c933
836bb933 8b400c mov eax,dword ptr [eax+0Ch]TRAP_FRAME: 9f132a10 -- (.trap 0xffffffff9f132a10)
ErrCode = 00000000
eax=00000000 ebx=85fc4e40 ecx=85fc4e98 edx=00000000 esi=9f132b00 edi=00000001
eip=836bb933 esp=9f132a84 ebp=9f132a84 iopl=0 nv up ei pl nz na po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010202
nt+0x9c933:
836bb933 8b400c mov eax,dword ptr [eax+0Ch] ds:0023:0000000c=????????
Resetting default scopeCUSTOMER_CRASH_COUNT: 1DEFAULT_BUCKET_ID: WRONG_SYMBOLSBUGCHECK_STR: 0x8ECURRENT_IRQL: 0LAST_CONTROL_TRANSFER: from 843f0afb to 836bb933STACK_TEXT:
WARNING: Stack unwind information not available. Following frames may be wrong.
9f132a84 843f0afb 00000000 85fc4e40 86018dc8 nt+0x9c933
9f132ae0 84202aeb 85fc4e40 9f132b00 9f132b2c fileinfo+0x1afb
9f132b4c 842059f0 9f132ba0 874ab6c8 00000000 fltmgr+0x2aeb
9f132b64 84205f01 9f132ba0 00000000 85fd6030 fltmgr+0x59f0
9f132b88 842063ba 03132b01 85fd6030 00000000 fltmgr+0x5f01
9f132bb8 83650ad1 85fd6030 874ab6c8 85fe1ef0 fltmgr+0x63ba
9f132bd0 9596d859 879225f8 00000000 00000208 nt+0x31ad1
9f132c10 9596d9a4 00000000 00000003 85f67d70 HelloDDK+0x859
9f132c44 83650ad1 85fe1ef0 86876ca0 86876ca0 HelloDDK+0x9a4
9f132c5c 83848177 86876ca0 86876d10 85abb830 nt+0x31ad1
9f132c7c 83853e2f 85fe1ef0 85abb830 00000001 nt+0x229177
9f132d08 836573fa 85fe1ef0 86876ca0 00000000 nt+0x234e2f
9f132d34 76ec8244 badb0d00 002ef8c8 00000000 nt+0x383fa
9f132d38 badb0d00 002ef8c8 00000000 00000000 0x76ec8244
9f132d3c 002ef8c8 00000000 00000000 00000000 0xbadb0d00
9f132d40 00000000 00000000 00000000 00000000 0x2ef8c8
STACK_COMMAND: kbFOLLOWUP_IP:
fileinfo+1afb
843f0afb ?? ???SYMBOL_STACK_INDEX: 1SYMBOL_NAME: fileinfo+1afbFOLLOWUP_NAME: MachineOwnerMODULE_NAME: fileinfoIMAGE_NAME: fileinfo.sysBUCKET_ID: WRONG_SYMBOLSFollowup: MachineOwner
---------
另外 需要在irpSp->Flags 加SL_FORCE_DIRECT_WRITE标志位.
自己GOOGLE MS的文档.
DeviceObject必须是DR0设备, 而不是DR0的过滤设备...是DR0设备,用winobj看到PhysicalDrive0的符号链接为:\Device\Harddisk0\DR0。
另外 需要在irpSp->Flags 加SL_FORCE_DIRECT_WRITE标志位.自己GOOGLE MS的文档.
没看明白……
!devobj DeviceObject
你自己看看是不是DR0设备.你创建完IRP后有IRP堆栈, irpSp->Flags |= SL_FORCE_DIRECT_WRITE; 一下就好.
!devobj DeviceObject
你自己看看是不是DR0设备.
那这个应该咋整呢?下面代码是我再XP下在驱动中读取磁盘的代码,它是ok的。在win7下不行,然后改着改着就成了上面的破样子……
#define DISK_NAME L"\\Device\\Harddisk0\\DR0"
NTSTATUS ReadWriteDisk(PULONG_PTR information ,ULONG MajorFunction,
PVOID Buffer,ULONG Length,PLARGE_INTEGER StartingOffset,BOOLEAN Wait)
{
NTSTATUS ntStatus = STATUS_SUCCESS; UNICODE_STRING DeviceName;
PDEVICE_OBJECT DeviceObject = NULL;
PFILE_OBJECT FileObject = NULL;
KEVENT AsynEvent;
IO_STATUS_BLOCK status_block;
//LARGE_INTEGER offset ;//= RtlConvertLongToLargeInteger(0);
PIRP pNewIrp ;
PIO_STACK_LOCATION stack;
PAGED_CODE();
RtlInitUnicodeString(&DeviceName,DISK_NAME);//L"\\Device\\Harddisk0\\DR0"
ntStatus = IoGetDeviceObjectPointer(&DeviceName,FILE_ALL_ACCESS,&FileObject,&DeviceObject);
if(!NT_SUCCESS(ntStatus))
{
KdPrint(("ReadWriteDisk Failed\n"));
information = 0;
ntStatus = STATUS_UNSUCCESSFUL;
return ntStatus;
} pNewIrp = IoBuildAsynchronousFsdRequest(MajorFunction, DeviceObject,
Buffer, Length, StartingOffset, &status_block);
if (!pNewIrp)
{
information = 0;
return STATUS_INSUFFICIENT_RESOURCES;
} if (Wait)
{
KeInitializeEvent(&AsynEvent, NotificationEvent, FALSE);
IoSetCompletionRoutine(pNewIrp, FltReadWriteSectorsCompletion,
&AsynEvent, TRUE, TRUE, TRUE); ntStatus = IoCallDriver(DeviceObject, pNewIrp);
if (STATUS_PENDING == ntStatus)
{
KeWaitForSingleObject(&AsynEvent, Executive, KernelMode, FALSE, NULL);
ntStatus = status_block.Status;
}
}
else
{
IoSetCompletionRoutine(pNewIrp, FltReadWriteSectorsCompletion,
NULL, TRUE, TRUE, TRUE);
pNewIrp->UserIosb = NULL;
ntStatus = IoCallDriver(DeviceObject, pNewIrp);
} ObDereferenceObject(FileObject);
KdPrint(("ReadWriteDisk OK\n"));
return ntStatus;
}
NTSTATUS
FltReadWriteSectorsCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
PMDL mdl; UNREFERENCED_PARAMETER(DeviceObject); if (Irp->AssociatedIrp.SystemBuffer && (Irp->Flags & IRP_DEALLOCATE_BUFFER))
{
ExFreePool(Irp->AssociatedIrp.SystemBuffer);
} while (Irp->MdlAddress)
{
mdl = Irp->MdlAddress;
Irp->MdlAddress = mdl->Next;
MmUnlockPages(mdl);
IoFreeMdl(mdl);
} if (Irp->PendingReturned && (Context != NULL))
{
*Irp->UserIosb = Irp->IoStatus;
KeSetEvent((PKEVENT) Context, IO_DISK_INCREMENT, FALSE);
} IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
是我读写磁盘的问题,只要我不
IoSetCompletionRoutineEx;
IoCallDriver(DeviceObject, pNewIrp);
就没有问题。是不是用Try/Catch就能截下出错的地方
枚举\Driver\Disk驱动对象的所有设备.
找出DR0设备.
IRP对着DR0设备直接发. 不然会BSOD.
IoGetDeviceObjectPointer 没用, 看文档.
The IoGetDeviceObjectPointer routine returns a pointer to the top object in the named device object's stack.
看看DeviceObject和IRP是否正确。
大概扫了一眼代码,感觉问题不少。
函数调用要判断返回值,根据返回值决定接下来如何处理。
磁盘驱动最好不要用PAGEDCODE。
如果要返回STATUS_PENDING,应先调用IoMarkIrpPending。
提升IRQL的目的是什么?这个应该很少用到。
本来完成例程函数中是没有提升IRQL和设置PAGEDCODE的,只是蓝屏找不到错误就加上去看看了。MSDN中有说完成例程应该设计成DISPATCH_LEVEL等级,所以就整成这样了。前辈所说的设置断点单步调试,是说用WinDbg吧?
如果我本机是XP,要调试的驱动是在Win7下,那么这样连接的话本机的windbg是要用win7版本的吗……