Problem when Sending irp to write file

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/