Exemple #1
0
NTSTATUS
IopIrpCreate(
    OUT PIRP* ppIrp,
    IN IRP_TYPE Type,
    IN PIO_FILE_OBJECT pFileObject
    )
{
    NTSTATUS status = 0;
    int EE = 0;
    PIRP pIrp = NULL;

    status = IopIrpCreateDetached(&pIrp);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

    status = IopIrpAttach(pIrp, Type, pFileObject);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

cleanup:
    if (status)
    {
        IopIrpDereference(&pIrp);
    }

    *ppIrp = pIrp;

    IO_LOG_LEAVE_ON_STATUS_EE(status, EE);
    return status;
}
Exemple #2
0
static
NTSTATUS
IopContinueAsyncCloseFile(
    IN PIO_FILE_OBJECT FileHandle,
    IN OPTIONAL PIO_ASYNC_COMPLETE_CALLBACK Callback,
    IN OPTIONAL PVOID CallbackContext,
    OUT PIO_STATUS_BLOCK IoStatusBlock
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    int EE = 0;
    PIRP pIrp = NULL;
    IO_ASYNC_CONTROL_BLOCK asyncControlBlock = { 0 };
    PIO_ASYNC_CONTROL_BLOCK useAsyncControlBlock = NULL;
    BOOLEAN isOpen = FALSE;

    //
    // If the create never completed successfully, we do not want
    // to send a CLOSE IRP.
    //

    // TODO -- There is probably still a small race window
    // wrt create and device rundown.  The fix may involve
    // changing when IopFileObjectRemoveDispatched() is called
    // from IopIrpCompleteInternal() so that it is called
    // after the switch on the IRP type.

    IopFileObjectLock(FileHandle);
    isOpen = IsSetFlag(FileHandle->Flags, FILE_OBJECT_FLAG_CREATE_DONE);
    IopFileObjectUnlock(FileHandle);

    if (!isOpen)
    {
        status = STATUS_SUCCESS;
        GOTO_CLEANUP_EE(EE);
    }

    //
    // The file was actually opened, so do rest of close cleanup.
    //

    status = IopFileObjectGetCloseIrp(FileHandle, &pIrp);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

    status = IopIrpAttach(pIrp, IRP_TYPE_CLOSE, FileHandle);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

    if (Callback)
    {
        asyncControlBlock.Callback = Callback;
        asyncControlBlock.CallbackContext = CallbackContext;
        useAsyncControlBlock = &asyncControlBlock;
    }

    status = IopIrpDispatch(
                    pIrp,
                    useAsyncControlBlock,
                    IoStatusBlock);
    if (STATUS_PENDING == status)
    {
        IoDereferenceAsyncCancelContext(&asyncControlBlock.AsyncCancelContext);
    }
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

cleanup:
    IopIrpDereference(&pIrp);

    if (!useAsyncControlBlock && IoStatusBlock && (STATUS_PENDING != status))
    {
        IO_STATUS_BLOCK ioStatusBlock = { 0 };

        ioStatusBlock.Status = status;
        *IoStatusBlock = ioStatusBlock;
    }

    IO_LOG_LEAVE_ON_STATUS_EE(status, EE);

    return status;
}