Hi.
I'm writting a file system filter. In Dispatch routine , i want to send irp to write file. But if the current process is "System", it bug checks .
Thanks any help would be appreciated.
The related code is here.
//////////////////////////////////////////////////////////////////////////
NTSTATUS
IoCompletionRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
*Irp->UserIosb = Irp->IoStatus;
if (Irp->UserEvent)
KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, 0);
if (Irp->MdlAddress)
{
IoFreeMdl(Irp->MdlAddress);
Irp->MdlAddress = NULL;
}
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS
IrpFileCreate(
IN PUNICODE_STRING FileName,
IN ACCESS_MASK DesiredAccess,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PDEVICE_OBJECT DeviceObject,
//note | micromath: according original source,
// the way to get RealDevice is to open drive's handle,
// get fileObject, and ReadDevice = fileObject->Vpb->RealDevice
// we can get it in HookDrive() in fpfilter.c , store in hookExt
IN PDEVICE_OBJECT RealDevice,
OUT PFILE_OBJECT* FileObject
)
{
NTSTATUS status;
KEVENT event;
PIRP irp;
IO_STATUS_BLOCK ioStatus;
PIO_STACK_LOCATION irpSp;
IO_SECURITY_CONTEXT securityContext;
ACCESS_STATE accessState;
OBJECT_ATTRIBUTES objectAttributes;
PFILE_OBJECT fileObject;
AUX_ACCESS_DATA auxData;
RtlZeroMemory(&auxData, sizeof(AUX_ACCESS_DATA));
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (irp == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
InitializeObjectAttributes(&objectAttributes, NULL, OBJ_CASE_INSENSITIVE, 0, NULL);
status = ObCreateObject(KernelMode,
*IoFileObjectType,
&objectAttributes,
KernelMode,
NULL,
sizeof(FILE_OBJECT),
0,
0,
(PVOID *)&fileObject);
if (!NT_SUCCESS(status))
{
IoFreeIrp(irp);
return status;
}
RtlZeroMemory(fileObject, sizeof(FILE_OBJECT));
fileObject->Type = IO_TYPE_FILE;
fileObject->Size = sizeof(FILE_OBJECT);
fileObject->DeviceObject = RealDevice;
//fileObject->RelatedFileObject = NULL;
fileObject->Flags = FO_SYNCHRONOUS_IO;
fileObject->FileName.MaximumLength = FileName->MaximumLength;
fileObject->FileName.Buffer = ExAllocatePool(NonPagedPool, FileName->MaximumLength);
if (fileObject->FileName.Buffer == NULL)
{
IoFreeIrp(irp);
ObDereferenceObject(fileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyUnicodeString(&fileObject->FileName, FileName);
KeInitializeEvent(&fileObject->Lock, SynchronizationEvent, FALSE);
KeInitializeEvent(&fileObject->Event, NotificationEvent, FALSE);
irp->MdlAddress = NULL;
irp->Flags |= IRP_CREATE_OPERATION | IRP_SYNCHRONOUS_API;
irp->RequestorMode = KernelMode;
irp->UserIosb = &ioStatus;
irp->UserEvent = &event;
irp->PendingReturned = FALSE;
irp->Cancel = FALSE;
irp->CancelRoutine = NULL;
irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
irp->Tail.Overlay.AuxiliaryBuffer = NULL;
irp->Tail.Overlay.OriginalFileObject = fileObject;
status = SeCreateAccessState( &accessState,
&auxData,
DesiredAccess,
IoGetFileObjectGenericMapping());
if (!NT_SUCCESS(status))
{
IoFreeIrp(irp);
ExFreePool(fileObject->FileName.Buffer);
ObDereferenceObject(fileObject);
return status;
}
securityContext.SecurityQos = NULL;
securityContext.AccessState = &accessState;
securityContext.DesiredAccess = DesiredAccess;
securityContext.FullCreateOptions = 0;
irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_CREATE;
irpSp->DeviceObject = DeviceObject;
irpSp->FileObject = fileObject;
irpSp->Parameters.Create.SecurityContext = &securityContext;
irpSp->Parameters.Create.Options = (CreateDisposition << 24) | CreateOptions;
irpSp->Parameters.Create.FileAttributes = (USHORT)FileAttributes;
irpSp->Parameters.Create.ShareAccess = (USHORT)ShareAccess;
irpSp->Parameters.Create.EaLength = 0;
IoSetCompletionRoutine(irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
status = IoCallDriver(DeviceObject, irp);
if (status == STATUS_PENDING)
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
status = ioStatus.Status;
if (!NT_SUCCESS(status))
{
ExFreePool(fileObject->FileName.Buffer);
fileObject->FileName.Length = 0;
fileObject->DeviceObject = NULL;
ObDereferenceObject(fileObject);
}
else
{
InterlockedIncrement(&fileObject->DeviceObject->ReferenceCount);
if (fileObject->Vpb)
{
InterlockedIncrement(&fileObject->Vpb->ReferenceCount);
}
*FileObject = fileObject;
*IoStatusBlock = ioStatus;
}
return status;
}
NTSTATUS
IrpFileClose(
IN PDEVICE_OBJECT DeviceObject,
IN PFILE_OBJECT FileObject
)
{
NTSTATUS status;
KEVENT event;
PIRP irp;
PVPB vpb;
IO_STATUS_BLOCK ioStatusBlock;
PIO_STACK_LOCATION irpSp;
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (irp == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
irp->Tail.Overlay.OriginalFileObject = FileObject;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->RequestorMode = KernelMode;
irp->UserEvent = &event;
irp->UserIosb = &irp->IoStatus;
irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE)NULL;
irp->Flags = IRP_SYNCHRONOUS_API | IRP_CLOSE_OPERATION;
irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_CLEANUP;
irpSp->FileObject = FileObject;
status = IoCallDriver(DeviceObject, irp);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject( &event,
UserRequest,
KernelMode,
FALSE,
NULL);
}
IoReuseIrp(irp , STATUS_SUCCESS);
KeClearEvent(&event);
irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_CLOSE;
irpSp->FileObject = FileObject;
irp->UserIosb = &ioStatusBlock;
irp->UserEvent = &event;
irp->Tail.Overlay.OriginalFileObject = FileObject;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->AssociatedIrp.SystemBuffer = (PVOID)NULL;
irp->Flags = IRP_CLOSE_OPERATION | IRP_SYNCHRONOUS_API;
vpb = FileObject->Vpb;
if (vpb && !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN))
{
InterlockedDecrement(&vpb->ReferenceCount);
FileObject->Flags |= FO_FILE_OPEN_CANCELLED;
}
status = IoCallDriver(DeviceObject, irp);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject( &event,
Executive,
KernelMode,
FALSE,
NULL);
}
IoFreeIrp(irp);
status = ioStatusBlock.Status ;
return status;
}
NTSTATUS
IrpFileWrite(
IN PDEVICE_OBJECT DeviceObject,
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN ULONG Length,
IN PVOID Buffer,
OUT PIO_STATUS_BLOCK IoStatusBlock
)
{
NTSTATUS status;
KEVENT event;
PIRP irp;
PIO_STACK_LOCATION irpSp;
IO_STATUS_BLOCK ioStatus;
if (ByteOffset == NULL)
{
if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
return STATUS_INVALID_PARAMETER;
ByteOffset = &FileObject->CurrentByteOffset;
}
if (FileObject->Vpb == 0 || FileObject->Vpb->RealDevice == NULL)
return STATUS_UNSUCCESSFUL;
//deviceObject = FileObject->Vpb->DeviceObject;
irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (irp == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
irp->MdlAddress = IoAllocateMdl(Buffer, Length, FALSE, TRUE, NULL);
if (irp->MdlAddress == NULL)
{
IoFreeIrp(irp);
return STATUS_INSUFFICIENT_RESOURCES;;
}
MmBuildMdlForNonPagedPool(irp->MdlAddress);
irp->Flags = IRP_WRITE_OPERATION ;
irp->RequestorMode = KernelMode;
irp->UserIosb = &ioStatus;
irp->UserEvent = &event;
irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject = FileObject;
irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_WRITE;
irpSp->MinorFunction = IRP_MN_NORMAL;
irpSp->DeviceObject = DeviceObject ;
irpSp->FileObject = FileObject;
irpSp->Parameters.Write.Length = Length;
irpSp->Parameters.Write.ByteOffset = *ByteOffset;
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
IoSetCompletionRoutine(irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
status = IoCallDriver(DeviceObject , irp);
if (status == STATUS_PENDING)
status = KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
status = ioStatus.Status ;
*IoStatusBlock = ioStatus;
return status;
}
///////////////////////////////////////////////////////////
And the bug check is
IRQL_NOT_LESS_OR_EQUAL (a)
An attempt was made to access a pageable (or completely invalid) address at an
interrupt request level (IRQL) that is too high. This is usually
caused by drivers using improper addresses.
If a kernel debugger is available get the stack backtrace.
Arguments:
Arg1: 00002a64, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000001, bitfield :
bit 0 : value 0 = read operation, 1 = write operation
bit 3 : value 0 = not an execute operation, 1 = execute operation (only on chips which support this level of status)
Arg4: 806e5a16, address which referenced memory
Debugging Details:
WRITE_ADDRESS: 00002a64
CURRENT_IRQL: 2
FAULTING_IP:
hal!KeAcquireInStackQueuedSpinLock+26
806e5a16 8711 xchg edx,dword ptr [ecx]
DEFAULT_BUCKET_ID: DRIVER_FAULT
BUGCHECK_STR: 0xA
PROCESS_NAME: System
TRAP_FRAME: f8af129c -- (.trap 0xfffffffff8af129c)
ErrCode = 00000002
eax=f8af1320 ebx=c00000d8 ecx=00002a64 edx=f8af1320 esi=00002a30 edi=821b58b8
eip=806e5a16 esp=f8af1310 ebp=f8af132c iopl=0 nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010246
hal!KeAcquireInStackQueuedSpinLock+0x26:
806e5a16 8711 xchg edx,dword ptr [ecx] ds:0023:00002a64=????????
Resetting default scope
LAST_CONTROL_TRANSFER: from 804f9afd to 8052b5d8
STACK_TEXT:
f8af0e50 804f9afd 00000003 f8af11ac 00000000 nt!RtlpBreakWithStatusInstruction
f8af0e9c 804fa6e8 00000003 00002a64 806e5a16 nt!KiBugCheckDebugBreak+0x19
f8af127c 805446d0 0000000a 00002a64 00000002 nt!KeBugCheck2+0x574
f8af127c 806e5a16 0000000a 00002a64 00000002 nt!KiTrap0E+0x238
f8af132c f835e844 00002a30 00000001 f8af135c hal!KeAcquireInStackQueuedSpinLock+0x26
f8af133c f83609ac f8af143c e11d14b8 00000001 Ntfs!NtfsAcquireResourceShared+0x20
f8af135c f8385dc2 f8af143c e11d14b8 e11d1580 Ntfs!NtfsAcquireSharedFcb+0x25
f8af13c4 f83844b4 f8af143c 820d7508 820d7608 Ntfs!NtfsCommonQueryInformation+0x138
f8af1428 f83844ed f8af143c 820d7508 00000001 Ntfs!NtfsFsdDispatchSwitch+0x12a
f8af154c 804efeb1 8215b3c0 820d7508 820115f8 Ntfs!NtfsFsdDispatchWait+0x1c
f8af155c f687d75f 00000005 820d75e4 575c3a43 nt!IopfCallDriver+0x31
f8af1984 f687df8a 821d1720 820d7508 f8af1b90 syswatch!DispatchHook+0x42f [c:\drv\active\syswatch\sys\fpfilter.c @ 4352]
f8af1994 804efeb1 821d1720 820d7508 820d762c syswatch!DriverDispatch+0x2a [c:\drv\active\syswatch\sys\fpfilter.c @ 4888]
f8af19a4 f64fd3d6 820d7518 8200f868 00000000 nt!IopfCallDriver+0x31
WARNING: Stack unwind information not available. Following frames may be wrong.
f8af1b90 f64fd5dd 81f6d830 820d7508 804efeb1 FILEM701+0x83d6
f8af1bd8 80582218 81f6d830 00000792 00000009 FILEM701+0x85dd
f8af1c48 8058231d 81d9bf10 821e9000 00000000 nt!IopQueryNameInternal+0x1c4
f8af1c68 805c34f9 81d9bf10 821e9000 e1ab57f8 nt!IopQueryName+0x1b
f8af1d38 8061faf5 81d9bf10 e1ab57f8 00000808 nt!ObQueryNameString+0xcd
f8af1d7c 80538757 81fcdd18 00000000 821b58b8 nt!CcPfGetFileNamesWorkerRoutine+0xb7
f8af1dac 805cf794 81fcdd18 00000000 00000000 nt!ExpWorkerThread+0xef
f8af1ddc 805460ce 80538668 00000001 00000000 nt!PspSystemThreadStartup+0x34
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16
STACK_COMMAND: kb
FOLLOWUP_IP:
syswatch!DispatchHook+42f [c:\drv\active\syswatch\sys\fpfilter.c @ 4352]
f687d75f 8be5 mov esp,ebp
FAULTING_SOURCE_CODE:
4348: // Return the results of the call to the caller
4349: //
4350: return IoCallDriver( hookExt->DeviceBelow, Irp );
4351:
4352: }
4353:
4354:
4355:
4356:
4357:
SYMBOL_STACK_INDEX: b
SYMBOL_NAME: syswatch!DispatchHook+42f
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: syswatch
IMAGE_NAME: syswatch.sys
DEBUG_FLR_IMAGE_TIMESTAMP: 4b2eec55
FAILURE_BUCKET_ID: 0xA_syswatch!DispatchHook+42f
BUCKET_ID: 0xA_syswatch!DispatchHook+42f
Followup: MachineOwner
好玩贺卡等你发,邮箱贺卡全新上线!
http://card.mail.cn.yahoo.com/