Beispiel #1
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;
    }
}
Beispiel #2
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;
    }
}