⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iocomp.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
        if (NT_SUCCESS(Status))
        {
            /* Protect writing the handle in SEH */
            _SEH_TRY
            {
                /* Write the handle back */
                *IoCompletionHandle = hIoCompletionHandle;
            }
            _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
            {
                /* Get the exception code */
                Status = _SEH_GetExceptionCode();
            }
            _SEH_END;
        }
   }

   /* Return Status */
   return Status;
}

NTSTATUS
NTAPI
NtOpenIoCompletion(OUT PHANDLE IoCompletionHandle,
                   IN ACCESS_MASK DesiredAccess,
                   IN POBJECT_ATTRIBUTES ObjectAttributes)
{
    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
    HANDLE hIoCompletionHandle;
    NTSTATUS Status = STATUS_SUCCESS;
    PAGED_CODE();

    /* Check if this was a user-mode call */
    if (PreviousMode != KernelMode)
    {
        /* Wrap probing in SEH */
        _SEH_TRY
        {
            /* Probe the handle */
            ProbeForWriteHandle(IoCompletionHandle);
        }
        _SEH_HANDLE
        {
            /* Get the exception code */
            Status = _SEH_GetExceptionCode();
        }
        _SEH_END;

        /* Fail on exception */
        if (!NT_SUCCESS(Status)) return Status;
    }

    /* Open the Object */
    Status = ObOpenObjectByName(ObjectAttributes,
                                IoCompletionType,
                                PreviousMode,
                                NULL,
                                DesiredAccess,
                                NULL,
                                &hIoCompletionHandle);
    if (NT_SUCCESS(Status))
    {
        /* Protect writing the handle in SEH */
        _SEH_TRY
        {
            /* Write the handle back */
            *IoCompletionHandle = hIoCompletionHandle;
        }
        _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
        {
            /* Get the exception code */
            Status = _SEH_GetExceptionCode();
        }
        _SEH_END;
    }

    /* Return Status */
    return Status;
}

NTSTATUS
NTAPI
NtQueryIoCompletion(IN  HANDLE IoCompletionHandle,
                    IN  IO_COMPLETION_INFORMATION_CLASS IoCompletionInformationClass,
                    OUT PVOID IoCompletionInformation,
                    IN  ULONG IoCompletionInformationLength,
                    OUT PULONG ResultLength OPTIONAL)
{
    PKQUEUE Queue;
    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
    NTSTATUS Status = STATUS_SUCCESS;
    PAGED_CODE();

    /* Check buffers and parameters */
    Status = DefaultQueryInfoBufferCheck(IoCompletionInformationClass,
                                         IoCompletionInfoClass,
                                         sizeof(IoCompletionInfoClass) /
                                         sizeof(IoCompletionInfoClass[0]),
                                         IoCompletionInformation,
                                         IoCompletionInformationLength,
                                         ResultLength,
                                         PreviousMode);
    if (!NT_SUCCESS(Status)) return Status;

    /* Get the Object */
    Status = ObReferenceObjectByHandle(IoCompletionHandle,
                                       IO_COMPLETION_QUERY_STATE,
                                       IoCompletionType,
                                       PreviousMode,
                                       (PVOID*)&Queue,
                                       NULL);
    if (NT_SUCCESS(Status))
    {
        /* Protect write in SEH */
        _SEH_TRY
        {
            /* Return Info */
            ((PIO_COMPLETION_BASIC_INFORMATION)IoCompletionInformation)->
                Depth = KeReadStateQueue(Queue);

            /* Dereference the queue */
            ObDereferenceObject(Queue);

            /* Return Result Length if needed */
            if (ResultLength)
            {
                *ResultLength = sizeof(IO_COMPLETION_BASIC_INFORMATION);
            }
        }
        _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
        {
            /* Get exception code */
            Status = _SEH_GetExceptionCode();
        }
        _SEH_END;
    }

    /* Return Status */
    return Status;
}

NTSTATUS
NTAPI
NtRemoveIoCompletion(IN HANDLE IoCompletionHandle,
                     OUT PVOID *KeyContext,
                     OUT PVOID *ApcContext,
                     OUT PIO_STATUS_BLOCK IoStatusBlock,
                     IN PLARGE_INTEGER Timeout OPTIONAL)
{
    LARGE_INTEGER SafeTimeout;
    PKQUEUE Queue;
    PIO_COMPLETION_PACKET Packet;
    PLIST_ENTRY ListEntry;
    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
    NTSTATUS Status = STATUS_SUCCESS;
    PIRP Irp;
    PVOID Apc, Key;
    IO_STATUS_BLOCK IoStatus;
    PAGED_CODE();

    /* Check if the call was from user mode */
    if (PreviousMode != KernelMode)
    {
        /* Protect probes in SEH */
        _SEH_TRY
        {
            /* Probe the pointers */
            ProbeForWritePointer(KeyContext);
            ProbeForWritePointer(ApcContext);

            /* Probe the I/O Status Block */
            ProbeForWriteIoStatusBlock(IoStatusBlock);
            if (Timeout)
            {
                /* Probe and capture the timeout */
                SafeTimeout = ProbeForReadLargeInteger(Timeout);
                Timeout = &SafeTimeout;
            }
        }
        _SEH_HANDLE
        {
            /* Get the exception code */
            Status = _SEH_GetExceptionCode();
        }
        _SEH_END;

        /* Fail on exception */
        if (!NT_SUCCESS(Status)) return Status;
    }

    /* Open the Object */
    Status = ObReferenceObjectByHandle(IoCompletionHandle,
                                       IO_COMPLETION_MODIFY_STATE,
                                       IoCompletionType,
                                       PreviousMode,
                                       (PVOID*)&Queue,
                                       NULL);
    if (NT_SUCCESS(Status))
    {
        /* Remove queue */
        ListEntry = KeRemoveQueue(Queue, PreviousMode, Timeout);

        /* If we got a timeout or user_apc back, return the status */
        if (((NTSTATUS)ListEntry == STATUS_TIMEOUT) ||
            ((NTSTATUS)ListEntry == STATUS_USER_APC))
        {
            /* Set this as the status */
            Status = (NTSTATUS)ListEntry;
        }
        else
        {
            /* Get the Packet Data */
            Packet = CONTAINING_RECORD(ListEntry,
                                       IO_COMPLETION_PACKET,
                                       ListEntry);

            /* Check if this is piggybacked on an IRP */
            if (Packet->PacketType == IrpCompletionPacket)
            {
                /* Get the IRP */
                Irp = CONTAINING_RECORD(ListEntry,
                                        IRP,
                                        Tail.Overlay.ListEntry);

                /* Save values */
                Key = Irp->Tail.CompletionKey;
                Apc = Irp->Overlay.AsynchronousParameters.UserApcContext;
                IoStatus = Irp->IoStatus;

                /* Free the IRP */
                IoFreeIrp(Irp);
            }
            else
            {
                /* Save values */
                Key = Packet->Key;
                Apc = Packet->Context;
                IoStatus = Packet->IoStatus;

                /* Free the packet */
                IopFreeIoCompletionPacket(Packet);
            }

            /* Enter SEH to write back the values */
            _SEH_TRY
            {
                /* Write the values to caller */
                *ApcContext = Apc;
                *KeyContext = Key;
                *IoStatusBlock = IoStatus;
            }
            _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
            {
                /* Get the exception code */
                Status = _SEH_GetExceptionCode();
            }
            _SEH_END;
        }

        /* Dereference the Object */
        ObDereferenceObject(Queue);
    }

    /* Return status */
    return Status;
}

NTSTATUS
NTAPI
NtSetIoCompletion(IN HANDLE IoCompletionPortHandle,
                  IN PVOID CompletionKey,
                  IN PVOID CompletionContext,
                  IN NTSTATUS CompletionStatus,
                  IN ULONG CompletionInformation)
{
    NTSTATUS Status;
    PKQUEUE Queue;
    PAGED_CODE();

    /* Get the Object */
    Status = ObReferenceObjectByHandle(IoCompletionPortHandle,
                                       IO_COMPLETION_MODIFY_STATE,
                                       IoCompletionType,
                                       ExGetPreviousMode(),
                                       (PVOID*)&Queue,
                                       NULL);
    if (NT_SUCCESS(Status))
    {
        /* Set the Completion */
        Status = IoSetIoCompletion(Queue,
                                   CompletionKey,
                                   CompletionContext,
                                   CompletionStatus,
                                   CompletionInformation,
                                   TRUE);

        /* Dereference the object */
        ObDereferenceObject(Queue);
    }

    /* Return status */
    return Status;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -