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

📄 io.c

📁 鼠标Windows驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
    int                 i, numReads;

    KeInitializeEvent(&event, NotificationEvent, FALSE);

    if (!NT_SUCCESS(status)) {
        return status;
    }

    self = DeviceExtension->Self;
    irp = DeviceExtension->ReadIrp;

    Print(DeviceExtension, DBG_SS_TRACE, ("Read pending...\n"));

    *ActualBytesRead = 0;
    while (*ActualBytesRead < Buflen) {

        KeClearEvent(&event);
        IoReuseIrp(irp, STATUS_SUCCESS);

        irp->AssociatedIrp.SystemBuffer = ReadBuffer;

        stack = IoGetNextIrpStackLocation(irp);
        stack->Parameters.Read.Length = 1;
        stack->Parameters.Read.ByteOffset.QuadPart = (LONGLONG) 0;
        stack->MajorFunction = IRP_MJ_READ;

        //
        // Hook a completion routine for when the device completes.
        //
        IoSetCompletionRoutine(irp,
                               SerialMouseReadSerialPortComplete,
                               &event,
                               TRUE,
                               TRUE,
                               TRUE);


        status = IoCallDriver(DeviceExtension->TopOfStack, irp);

        if (status == STATUS_PENDING) {
            //
            // Wait for the IRP
            //
            status = KeWaitForSingleObject(&event,
                                           Executive,
                                           KernelMode,
                                           FALSE,
                                           NULL);

            if (status == STATUS_SUCCESS) {
                status = irp->IoStatus.Status;
            }
        }

        if (!NT_SUCCESS(status) || status == STATUS_TIMEOUT) {
            Print(DeviceExtension, DBG_SS_NOISE,
                  ("IO Call failed with status %x\n", status));
            return status;
        }

        *ActualBytesRead += (USHORT) irp->IoStatus.Information;
        ReadBuffer += (USHORT) irp->IoStatus.Information;
    }

    return status;
}

NTSTATUS
SerialMouseWriteSerialPort (
    PDEVICE_EXTENSION   DeviceExtension,
    PCHAR               WriteBuffer,
    ULONG               NumBytes,
    PIO_STATUS_BLOCK    IoStatusBlock
    )
/*++

Routine Description:
    Performs a synchronous write on the serial port.  Used during setup so that
    the device can be configured.

Return value:
    NTSTATUS - STATUS_SUCCESS if the read was successful, error code otherwise

--*/
{
    NTSTATUS        status;
    PIRP            irp;
    LARGE_INTEGER   startingOffset;
    KEVENT          event;

    int             i, numReads;

    startingOffset.QuadPart = (LONGLONG) 0;

    KeInitializeEvent(&event,
                      NotificationEvent,
                      FALSE);

    Print(DeviceExtension, DBG_SS_TRACE, ("Write pending...\n"));

    //
    // Create a new IRP because there's a chance that it might get cancelled.
    // Can't cancel irps that I received.
    // IRP_MJ_READ with completion routine
    //
    if (NULL == (irp = IoBuildSynchronousFsdRequest(
                IRP_MJ_WRITE,
                DeviceExtension->TopOfStack,
                WriteBuffer,
                NumBytes,
                &startingOffset,
                &event,
                IoStatusBlock
                ))) {
        Print(DeviceExtension, DBG_SS_ERROR, ("Failed to allocate IRP\n"));

        return STATUS_INSUFFICIENT_RESOURCES;
    }

    status = IoCallDriver(DeviceExtension->TopOfStack, irp);

    if (status == STATUS_PENDING) {

        // I don't know at this time if I can wait with the default time of
        // 200 ms as I'm doing.  In the help file for IoBuildSynchronousFsdRequest
        // I think that it says I can't, but I'm not quite sure.
        // Presently I will.  I'll cancel the Irp if it isn't done.
        status = KeWaitForSingleObject(
                            &event,
                            Executive,
                            KernelMode,
                            FALSE, // Not alertable
                            NULL);
    }

    status = IoStatusBlock->Status;

    if (!NT_SUCCESS(status)) {
        Print(DeviceExtension, DBG_SS_ERROR,
              ("IO Call failed with status %x\n",
              status
              ));
        return status;
    }

    if (!NT_SUCCESS(status)) {
        Print(DeviceExtension, DBG_SS_ERROR,
              ("IO Call failed with status %x\n",
              status
              ));
    }

    return status;
}

NTSTATUS
SerialMouseWait (
    IN PDEVICE_EXTENSION    DeviceExtension,
    IN LONG                 Timeout
    )
/*++

Routine Description:
    Performs a wait for the specified time.
    NB: Negative time is relative to the current time.  Positive time
    represents an absolute time to wait until.

Return value:
    NTSTATUS

--*/
{
    LARGE_INTEGER time;

    time.QuadPart = (LONGLONG) Timeout;

    Print(DeviceExtension, DBG_READ_NOISE,
          ("waiting for %d micro secs\n", Timeout));

    if (KeSetTimer(&DeviceExtension->DelayTimer,
                   time,
                   NULL)) {
        Print(DeviceExtension, DBG_SS_INFO, ("Timer already set\n"));
    }

    return KeWaitForSingleObject(&DeviceExtension->DelayTimer,
                                 Executive,
                                 KernelMode,
                                 FALSE,             // Not allertable
                                 NULL);             // No timeout structure
}

NTSTATUS
SerialMouseInitializePort(
    PDEVICE_EXTENSION DeviceExtension
    )
{
    NTSTATUS        status;
    KEVENT          event;
    IO_STATUS_BLOCK iosb;
    SERIAL_TIMEOUTS serialTimeouts;
    SERIAL_HANDFLOW serialHandFlow;

    KeInitializeEvent(&event, NotificationEvent, FALSE);

    status =
        SerialMouseIoSyncInternalIoctlEx(IOCTL_SERIAL_INTERNAL_BASIC_SETTINGS,
                                         DeviceExtension->TopOfStack,
                                         &event,
                                         &iosb,
                                         NULL,
                                         0,
                                         &DeviceExtension->SerialBasicSettings,
                                         sizeof(SERIAL_BASIC_SETTINGS));

    //
    // In case we are running on a port that does not support basic settings
    //
    if (!NT_SUCCESS(status)) {
        SerialMouseIoSyncIoctlEx(IOCTL_SERIAL_GET_TIMEOUTS,
                                 DeviceExtension->TopOfStack,
                                 &event,
                                 &iosb,
                                 NULL,
                                 0,
                                 &DeviceExtension->SerialBasicSettings.Timeouts,
                                 sizeof(SERIAL_TIMEOUTS));

        RtlZeroMemory(&serialTimeouts, sizeof(SERIAL_TIMEOUTS));

        SerialMouseIoSyncIoctlEx(IOCTL_SERIAL_SET_TIMEOUTS,
                                 DeviceExtension->TopOfStack,
                                 &event,
                                 &iosb,
                                 &serialTimeouts,
                                 sizeof(SERIAL_TIMEOUTS),
                                 NULL,
                                 0);

        SerialMouseIoSyncIoctlEx(IOCTL_SERIAL_GET_HANDFLOW,
                                 DeviceExtension->TopOfStack,
                                 &event,
                                 &iosb,
                                 NULL,
                                 0,
                                 &DeviceExtension->SerialBasicSettings.HandFlow,
                                 sizeof(SERIAL_HANDFLOW));

        serialHandFlow.ControlHandShake = SERIAL_DTR_CONTROL;
        serialHandFlow.FlowReplace = SERIAL_RTS_CONTROL;
        serialHandFlow.XonLimit = 0;
        serialHandFlow.XoffLimit = 0;

        status = SerialMouseIoSyncIoctlEx(IOCTL_SERIAL_SET_HANDFLOW,
                                          DeviceExtension->TopOfStack,
                                          &event,
                                          &iosb,
                                          &serialHandFlow,
                                          sizeof(SERIAL_HANDFLOW),
                                          NULL,
                                          0);
    }

    return status;
}

VOID
SerialMouseRestorePort(
    PDEVICE_EXTENSION DeviceExtension
    )
{
    KEVENT          event;
    IO_STATUS_BLOCK iosb;
    NTSTATUS        status;

    KeInitializeEvent(&event, NotificationEvent, FALSE);

    status =
        SerialMouseIoSyncInternalIoctlEx(IOCTL_SERIAL_INTERNAL_RESTORE_SETTINGS,
                                         DeviceExtension->TopOfStack,
                                         &event,
                                         &iosb,
                                         &DeviceExtension->SerialBasicSettings,
                                         sizeof(SERIAL_BASIC_SETTINGS),
                                         NULL,
                                         0);
    //
    // 4-24 Once serial.sys supports this new IOCTL, this code can be removed
    //
    if (!NT_SUCCESS(status)) {
        SerialMouseIoSyncIoctlEx(IOCTL_SERIAL_SET_TIMEOUTS,
                                 DeviceExtension->TopOfStack,
                                 &event,
                                 &iosb,
                                 &DeviceExtension->SerialBasicSettings.Timeouts,
                                 sizeof(SERIAL_TIMEOUTS),
                                 NULL,
                                 0);

        SerialMouseIoSyncIoctlEx(IOCTL_SERIAL_SET_HANDFLOW,
                                 DeviceExtension->TopOfStack,
                                 &event,
                                 &iosb,
                                 &DeviceExtension->SerialBasicSettings.HandFlow,
                                 sizeof(SERIAL_HANDFLOW),
                                 NULL,
                                 0);
    }
}

⌨️ 快捷键说明

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