Example #1
0
static NTSTATUS
ReadInputBuffer(IN PGET_INPUT_INFO InputInfo,
                IN BOOL Wait,   // TRUE --> Read ; FALSE --> Peek
                IN PCSR_API_MESSAGE ApiMessage,
                IN BOOL CreateWaitBlock OPTIONAL)
{
    NTSTATUS Status;
    PCONSOLE_GETINPUT GetInputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetInputRequest;
    PCONSOLE_INPUT_BUFFER InputBuffer = InputInfo->InputBuffer;

    // GetInputRequest->InputsRead = 0;

    Status = ConDrvGetConsoleInput(InputBuffer->Header.Console,
                                   InputBuffer,
                                   Wait,
                                   GetInputRequest->Unicode,
                                   GetInputRequest->InputRecord,
                                   GetInputRequest->Length,
                                   &GetInputRequest->InputsRead);

    if (Status == STATUS_PENDING)
    {
        /* We haven't completed a read, so start a wait */
        return WaitBeforeReading(InputInfo,
                                 ApiMessage,
                                 ReadInputBufferThread,
                                 CreateWaitBlock);
    }
    else
    {
        /* We read all what we wanted, we return the error code we were given */
        return Status;
        // return STATUS_SUCCESS;
    }
}
Example #2
0
static NTSTATUS
ReadChars(IN PGET_INPUT_INFO InputInfo,
          IN PCSR_API_MESSAGE ApiMessage,
          IN BOOL CreateWaitBlock OPTIONAL)
{
    NTSTATUS Status;
    PCONSOLE_READCONSOLE ReadConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadConsoleRequest;
    PCONSOLE_INPUT_BUFFER InputBuffer = InputInfo->InputBuffer;
    CONSOLE_READCONSOLE_CONTROL ReadControl;

    ReadControl.nLength           = sizeof(CONSOLE_READCONSOLE_CONTROL);
    ReadControl.nInitialChars     = ReadConsoleRequest->NrCharactersRead;
    ReadControl.dwCtrlWakeupMask  = ReadConsoleRequest->CtrlWakeupMask;
    ReadControl.dwControlKeyState = ReadConsoleRequest->ControlKeyState;

    Status = ConDrvReadConsole(InputBuffer->Header.Console,
                               InputBuffer,
                               ReadConsoleRequest->Unicode,
                               ReadConsoleRequest->Buffer,
                               &ReadControl,
                               ReadConsoleRequest->NrCharactersToRead,
                               &ReadConsoleRequest->NrCharactersRead);

    ReadConsoleRequest->ControlKeyState = ReadControl.dwControlKeyState;

    if (Status == STATUS_PENDING)
    {
        /* We haven't completed a read, so start a wait */
        return WaitBeforeReading(InputInfo,
                                 ApiMessage,
                                 ReadCharsThread,
                                 CreateWaitBlock);
    }
    else
    {
        /* We read all what we wanted, we return the error code we were given */
        return Status;
        // return STATUS_SUCCESS;
    }
}
Example #3
0
static NTSTATUS
ReadInputBuffer(IN PGET_INPUT_INFO InputInfo,
                IN PCSR_API_MESSAGE ApiMessage,
                IN BOOLEAN CreateWaitBlock OPTIONAL)
{
    NTSTATUS Status;
    PCONSOLE_GETINPUT GetInputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetInputRequest;
    PCONSOLE_INPUT_BUFFER InputBuffer = InputInfo->InputBuffer;
    ULONG NumEventsRead;

    PINPUT_RECORD InputRecord;

    /*
     * For optimization purposes, Windows (and hence ReactOS, too, for
     * compatibility reasons) uses a static buffer if no more than five
     * input records are read. Otherwise a new buffer is used.
     * The client-side expects that we know this behaviour.
     */
    if (GetInputRequest->NumRecords <= sizeof(GetInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD))
    {
        /*
         * Adjust the internal pointer, because its old value points to
         * the static buffer in the original ApiMessage structure.
         */
        // GetInputRequest->RecordBufPtr = GetInputRequest->RecordStaticBuffer;
        InputRecord = GetInputRequest->RecordStaticBuffer;
    }
    else
    {
        InputRecord = GetInputRequest->RecordBufPtr;
    }

    NumEventsRead = 0;
    Status = ConDrvGetConsoleInput(InputBuffer->Header.Console,
                                   InputBuffer,
                                   (GetInputRequest->Flags & CONSOLE_READ_KEEPEVENT) != 0,
                                   (GetInputRequest->Flags & CONSOLE_READ_CONTINUE ) == 0,
                                   InputRecord,
                                   GetInputRequest->NumRecords,
                                   &NumEventsRead);

    if (Status == STATUS_PENDING)
    {
        /* We haven't completed a read, so start a wait */
        return WaitBeforeReading(InputInfo,
                                 ApiMessage,
                                 ReadInputBufferThread,
                                 CreateWaitBlock);
    }
    else
    {
        /*
         * We read all what we wanted. Set the number of events read and
         * return the error code we were given.
         */
        GetInputRequest->NumRecords = NumEventsRead;

        if (NT_SUCCESS(Status))
        {
            /* Now translate everything to ANSI */
            if (!GetInputRequest->Unicode)
            {
                for (; NumEventsRead > 0; --NumEventsRead)
                {
                    ConioInputEventToAnsi(InputBuffer->Header.Console, --InputRecord);
                }
            }
        }

        return Status;
        // return STATUS_SUCCESS;
    }
}
Example #4
0
static NTSTATUS
ReadChars(IN PGET_INPUT_INFO InputInfo,
          IN PCSR_API_MESSAGE ApiMessage,
          IN BOOLEAN CreateWaitBlock OPTIONAL)
{
    NTSTATUS Status;
    PCONSOLE_READCONSOLE ReadConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadConsoleRequest;
    PCONSOLE_INPUT_BUFFER InputBuffer = InputInfo->InputBuffer;
    CONSOLE_READCONSOLE_CONTROL ReadControl;

    UNICODE_STRING ExeName;

    PVOID Buffer;
    ULONG NrCharactersRead = 0;
    ULONG CharSize = (ReadConsoleRequest->Unicode ? sizeof(WCHAR) : sizeof(CHAR));

    /* Retrieve the executable name, if needed */
    if (ReadConsoleRequest->InitialNumBytes == 0 &&
        ReadConsoleRequest->ExeLength <= sizeof(ReadConsoleRequest->StaticBuffer))
    {
        ExeName.Length = ExeName.MaximumLength = ReadConsoleRequest->ExeLength;
        ExeName.Buffer = (PWCHAR)ReadConsoleRequest->StaticBuffer;
    }
    else
    {
        ExeName.Length = ExeName.MaximumLength = 0;
        ExeName.Buffer = NULL;
    }

    /* Build the ReadControl structure */
    ReadControl.nLength           = sizeof(CONSOLE_READCONSOLE_CONTROL);
    ReadControl.nInitialChars     = ReadConsoleRequest->InitialNumBytes / CharSize;
    ReadControl.dwCtrlWakeupMask  = ReadConsoleRequest->CtrlWakeupMask;
    ReadControl.dwControlKeyState = ReadConsoleRequest->ControlKeyState;

    /*
     * For optimization purposes, Windows (and hence ReactOS, too, for
     * compatibility reasons) uses a static buffer if no more than eighty
     * bytes are read. Otherwise a new buffer is used.
     * The client-side expects that we know this behaviour.
     */
    if (ReadConsoleRequest->CaptureBufferSize <= sizeof(ReadConsoleRequest->StaticBuffer))
    {
        /*
         * Adjust the internal pointer, because its old value points to
         * the static buffer in the original ApiMessage structure.
         */
        // ReadConsoleRequest->Buffer = ReadConsoleRequest->StaticBuffer;
        Buffer = ReadConsoleRequest->StaticBuffer;
    }
    else
    {
        Buffer = ReadConsoleRequest->Buffer;
    }

    DPRINT("Calling ConDrvReadConsole(%wZ)\n", &ExeName);
    Status = ConDrvReadConsole(InputBuffer->Header.Console,
                               InputBuffer,
                               ReadConsoleRequest->Unicode,
                               Buffer,
                               &ReadControl,
                               &ExeName,
                               ReadConsoleRequest->NumBytes / CharSize, // NrCharactersToRead
                               &NrCharactersRead);
    DPRINT("ConDrvReadConsole returned (%d ; Status = 0x%08x)\n",
           NrCharactersRead, Status);

    // ReadConsoleRequest->ControlKeyState = ReadControl.dwControlKeyState;

    if (Status == STATUS_PENDING)
    {
        /* We haven't completed a read, so start a wait */
        return WaitBeforeReading(InputInfo,
                                 ApiMessage,
                                 ReadCharsThread,
                                 CreateWaitBlock);
    }
    else
    {
        /*
         * We read all what we wanted. Set the number of bytes read and
         * return the error code we were given.
         */
        ReadConsoleRequest->NumBytes = NrCharactersRead * CharSize;
        ReadConsoleRequest->ControlKeyState = ReadControl.dwControlKeyState;

        return Status;
        // return STATUS_SUCCESS;
    }
}