Exemple #1
0
NTSTATUS
NTAPI
RawChannelOEcho(IN PSAC_CHANNEL Channel,
                IN PCHAR String,
                IN ULONG Length)
{
    NTSTATUS Status = STATUS_SUCCESS;

    CHECK_PARAMETER1(Channel);
    CHECK_PARAMETER2(String);

    if (Length)
    {
        Status = ConMgrWriteData(Channel, String, Length);
        if (NT_SUCCESS(Status)) ConMgrFlushData(Channel);
    }

    return Status;
}
Exemple #2
0
NTSTATUS
NTAPI
RawChannelOFlush(IN PSAC_CHANNEL Channel)
{
    NTSTATUS Status;
    ULONG ByteCount;
    CHAR Dummy;
    CHECK_PARAMETER1(Channel);

    while (ChannelHasNewOBufferData(Channel))
    {
        Status = RawChannelORead(Channel, &Dummy, sizeof(Dummy), &ByteCount);
        if (!NT_SUCCESS(Status)) return Status;

        CHECK_PARAMETER_WITH_STATUS(ByteCount == 1, STATUS_UNSUCCESSFUL);

        Status = ConMgrWriteData(Channel, &Dummy, sizeof(Dummy));
        if (!NT_SUCCESS(Status)) return Status;
    }

    return ConMgrFlushData(Channel);
}
Exemple #3
0
NTSTATUS
NTAPI
VTUTF8ChannelOFlush(IN PSAC_CHANNEL Channel)
{
    NTSTATUS Status;
    PSAC_VTUTF8_SCREEN Screen;
    INT Color[2], Position[2];
    ULONG Utf8ProcessedCount, Utf8Count, R, C, ForeColor, BackColor, Attribute;
    PWCHAR TmpBuffer;
    BOOLEAN Overflow = FALSE;
    CHECK_PARAMETER(Channel);

    /* Set the cell buffer position */
    Screen = (PSAC_VTUTF8_SCREEN)Channel->OBuffer;

    /* Allocate a temporary buffer */
    TmpBuffer = SacAllocatePool(40, GLOBAL_BLOCK_TAG);
    if (!TmpBuffer)
    {
        Status = STATUS_NO_MEMORY;
        goto Quickie;
    }

    /* First, clear the screen */
    Status = VTUTF8ChannelAnsiDispatch(Channel,
                                       SacAnsiClearScreen,
                                       NULL,
                                       0);
    if (!NT_SUCCESS(Status)) goto Quickie;

    /* Next, reset the cursor position */
    Position[1] = 0;
    Position[0] = 0;
    Status = VTUTF8ChannelAnsiDispatch(Channel,
                                       SacAnsiSetPosition,
                                       Position,
                                       sizeof(Position));
    if (!NT_SUCCESS(Status)) goto Quickie;

    /* Finally, reset the attributes */
    Status = VTUTF8ChannelAnsiDispatch(Channel,
                                       SacAnsiClearAttributes,
                                       NULL,
                                       0);
    if (!NT_SUCCESS(Status)) goto Quickie;

    /* Now set the current cell attributes */
    Attribute = Channel->CellFlags;
    Status = VTUTF8ChannelProcessAttributes(Channel, Attribute);
    if (!NT_SUCCESS(Status)) goto Quickie;

    /* And set the current cell colors */
    ForeColor = Channel->CellForeColor;
    BackColor = Channel->CellBackColor;
    Color[1] = BackColor;
    Color[0] = ForeColor;
    Status = VTUTF8ChannelAnsiDispatch(Channel,
                                       SacAnsiSetColors,
                                       Color,
                                       sizeof(Color));
    if (!NT_SUCCESS(Status)) goto Quickie;

    /* Now loop all the characters in the cell buffer */
    for (R = 0; R < SAC_VTUTF8_ROW_HEIGHT; R++)
    {
        /* Across every row */
        for (C = 0; C < SAC_VTUTF8_COL_WIDTH; C++)
        {
            /* Check if there's been a change in colors */
            if ((Screen->Cell[R][C].CellBackColor != BackColor) ||
                (Screen->Cell[R][C].CellForeColor != ForeColor))
            {
                /* New colors are being drawn -- are we also on a new row now? */
                if (Overflow)
                {
                    /* Reposition the cursor correctly */
                    Position[1] = R;
                    Position[0] = C;
                    Status = VTUTF8ChannelAnsiDispatch(Channel,
                                                       SacAnsiSetPosition,
                                                       Position,
                                                       sizeof(Position));
                    if (!NT_SUCCESS(Status)) goto Quickie;
                    Overflow = FALSE;
                }

                /* Cache the new colors */
                ForeColor = Screen->Cell[R][C].CellForeColor;
                BackColor = Screen->Cell[R][C].CellBackColor;

                /* Set them on the screen */
                Color[1] = BackColor;
                Color[0] = ForeColor;
                Status = VTUTF8ChannelAnsiDispatch(Channel,
                                                   SacAnsiSetColors,
                                                   Color,
                                                   sizeof(Color));
                if (!NT_SUCCESS(Status)) goto Quickie;
            }

            /* Check if there's been a change in attributes */
            if (Screen->Cell[R][C].CellFlags != Attribute)
            {
                /* Yep! Are we also on a new row now? */
                if (Overflow)
                {
                    /* Reposition the cursor correctly */
                    Position[1] = R;
                    Position[0] = C;
                    Status = VTUTF8ChannelAnsiDispatch(Channel,
                                                       SacAnsiSetPosition,
                                                       Position,
                                                       sizeof(Position));
                    if (!NT_SUCCESS(Status)) goto Quickie;
                    Overflow = FALSE;
                }

                /* Set the new attributes on screen */
                Attribute = Screen->Cell[R][C].CellFlags;
                Status = VTUTF8ChannelProcessAttributes(Channel, Attribute);
                if (!NT_SUCCESS(Status)) goto Quickie;
            }

            /* Time to write the character -- are we on a new row now? */
            if (Overflow)
            {
                /* Reposition the cursor correctly */
                Position[1] = R;
                Position[0] = C;
                Status = VTUTF8ChannelAnsiDispatch(Channel,
                                                   SacAnsiSetPosition,
                                                   Position,
                                                   sizeof(Position));
                if (!NT_SUCCESS(Status)) goto Quickie;
                Overflow = FALSE;
            }

            /* Write the character into our temporary buffer */
            *TmpBuffer = Screen->Cell[R][C].Char;
            TmpBuffer[1] = UNICODE_NULL;

            /* Convert it to UTF-8 */
            if (!SacTranslateUnicodeToUtf8(TmpBuffer,
                                           1,
                                           Utf8ConversionBuffer,
                                           Utf8ConversionBufferSize,
                                           &Utf8Count,
                                           &Utf8ProcessedCount))
            {
                /* Bail out if this failed */
                Status = STATUS_UNSUCCESSFUL;
                goto Quickie;
            }

            /* Make sure we have a remaining valid character */
            if (Utf8Count)
            {
                /* Write it out on the wire */
                Status = ConMgrWriteData(Channel, Utf8ConversionBuffer, Utf8Count);
                if (!NT_SUCCESS(Status)) goto Quickie;
            }
        }

        /* All the characters on the row are done, indicate we need a reset */
        Overflow = TRUE;
    }

    /* Everything is done, set the positition one last time */
    Position[1] = Channel->CursorRow;
    Position[0] = Channel->CursorCol;
    Status = VTUTF8ChannelAnsiDispatch(Channel,
                                       SacAnsiSetPosition,
                                       Position,
                                       sizeof(Position));
    if (!NT_SUCCESS(Status)) goto Quickie;

    /* Set the current attribute one last time */
    Status = VTUTF8ChannelProcessAttributes(Channel, Channel->CellFlags);
    if (!NT_SUCCESS(Status)) goto Quickie;

    /* Set the current colors one last time */
    Color[1] = Channel->CellBackColor;
    Color[0] = Channel->CellForeColor;
    Status = VTUTF8ChannelAnsiDispatch(Channel,
                                       SacAnsiSetColors,
                                       Color,
                                       sizeof(Color));
    if (!NT_SUCCESS(Status)) goto Quickie;

    /* Flush all the data out on the wire */
    Status = ConMgrFlushData(Channel);

Quickie:
    /* We're done, free the temporary buffer */
    if (TmpBuffer) SacFreePool(TmpBuffer);

    /* Indicate that all new data has been flushed now */
    if (NT_SUCCESS(Status))
    {
        _InterlockedExchange(&Channel->ChannelHasNewOBufferData, 0);
    }

    /* Return the result */
    return Status;
}
Exemple #4
0
NTSTATUS
NTAPI
VTUTF8ChannelAnsiDispatch(IN PSAC_CHANNEL Channel,
                          IN SAC_ANSI_DISPATCH AnsiCode,
                          IN INT* Data,
                          IN ULONG Length)
{
    NTSTATUS Status = STATUS_SUCCESS;
    PCHAR LocalBuffer = NULL, Tmp;
    INT l;
    CHECK_PARAMETER1(Channel);

    /* Check which ANSI sequence we should output */
    switch (AnsiCode)
    {
        /* Send the [2J (Clear Screen and Reset Cursor) */
        case SacAnsiClearScreen:
            Tmp = "\x1B[2J";
            break;

        /* Send the [0J (Clear From Position Till End Of Screen) */
        case SacAnsiClearEndOfScreen:
            Tmp = "\x1B[0J";
            break;

        /* Send the [0K (Clear from Position Till End Of Line) */
        case SacAnsiClearEndOfLine:
            Tmp = "\x1B[0K";
            break;

        /* Send a combination of two [#m attribute changes */
        case SacAnsiSetColors:

            /* Allocate a small local buffer for it */
            LocalBuffer = SacAllocatePool(SAC_VTUTF8_COL_WIDTH, GLOBAL_BLOCK_TAG);
            CHECK_ALLOCATION(LocalBuffer);

            /* Caller should have sent two colors as two integers */
            if (!(Data) || (Length != 8))
            {
                Status = STATUS_INVALID_PARAMETER;
                break;
            }

            /* Create the escape sequence string */
            l = sprintf(LocalBuffer, "\x1B[%dm\x1B[%dm", Data[1], Data[0]);
            ASSERT((l + 1)*sizeof(UCHAR) < SAC_VTUTF8_COL_WIDTH);
            ASSERT(LocalBuffer);
            Tmp = LocalBuffer;
            break;

        /* Send the [#;#H (Cursor Position) sequence */
        case SacAnsiSetPosition:

            /* Allocate a small local buffer for it */
            LocalBuffer = SacAllocatePool(SAC_VTUTF8_COL_WIDTH, GLOBAL_BLOCK_TAG);
            CHECK_ALLOCATION(LocalBuffer);

            /* Caller should have sent the position as two integers */
            if (!(Data) || (Length != 8))
            {
                Status = STATUS_INVALID_PARAMETER;
                break;
            }

            /* Create the escape sequence string */
            l = sprintf(LocalBuffer, "\x1B[%d;%dH", Data[1] + 1, Data[0] + 1);
            ASSERT((l + 1)*sizeof(UCHAR) < SAC_VTUTF8_COL_WIDTH);
            ASSERT(LocalBuffer);
            Tmp = LocalBuffer;
            break;

        /* Send the [0m sequence (Set Attribute 0) */
        case SacAnsiClearAttributes:
            Tmp = "\x1B[0m";
            break;

        /* Send the [7m sequence (Set Attribute 7) */
        case SacAnsiSetInverseAttribute:
            Tmp = "\x1B[7m";
            break;

        /* Send the [27m sequence (Set Attribute 27) */
        case SacAnsiClearInverseAttribute:
            Tmp = "\x1B[27m";
            break;

        /* Send the [5m sequence (Set Attribute 5) */
        case SacAnsiSetBlinkAttribute:
            Tmp = "\x1B[5m";
            break;

        /* Send the [25m sequence (Set Attribute 25) */
        case SacAnsiClearBlinkAttribute:
            Tmp = "\x1B[25m";
            break;

        /* Send the [1m sequence (Set Attribute 1) */
        case SacAnsiSetBoldAttribute:
            Tmp = "\x1B[1m";
            break;

        /* Send the [22m sequence (Set Attribute 22) */
        case SacAnsiClearBoldAttribute:
            Tmp = "\x1B[22m";
            break;

        /* We don't recognize it */
        default:
            Status = STATUS_INVALID_PARAMETER;
            break;
    }

    /* Did everything work above? */
    if (NT_SUCCESS(Status))
    {
        /* Go write out the sequence */
        Status = ConMgrWriteData(Channel, Tmp, strlen(Tmp));
        if (NT_SUCCESS(Status))
        {
            /* Now flush it */
            Status = ConMgrFlushData(Channel);
        }
    }

    /* Free the temporary buffer, if any, and return the status */
    if (LocalBuffer) SacFreePool(LocalBuffer);
    return Status;
}
Exemple #5
0
NTSTATUS
NTAPI
VTUTF8ChannelOEcho(IN PSAC_CHANNEL Channel,
                   IN PCHAR String,
                   IN ULONG Size)
{
    NTSTATUS Status = STATUS_SUCCESS;
    PWSTR pwch;
    ULONG i, k, TranslatedCount, UTF8TranslationSize;
    BOOLEAN Result;
    CHECK_PARAMETER1(Channel);
    CHECK_PARAMETER2(String);

    /* Return success if there's nothing to echo */
    if (!(Size / sizeof(WCHAR))) return Status;

    /* Start with the input string */
    pwch = (PWCHAR)String;

    /* First, figure out how much is outside of the block length alignment */
    k = (Size / sizeof(WCHAR)) % MAX_UTF8_ENCODE_BLOCK_LENGTH;
    if (k)
    {
        /* Translate the misaligned portion */
        Result = SacTranslateUnicodeToUtf8(pwch,
                                           k,
                                           Utf8ConversionBuffer,
                                           Utf8ConversionBufferSize,
                                           &UTF8TranslationSize,
                                           &TranslatedCount);
        ASSERT(k == TranslatedCount);
        if (!Result)
        {
            /* If we couldn't translate, write failure to break out below */
            Status = STATUS_UNSUCCESSFUL;
        }
        else
        {
            /* Write the misaligned portion into the buffer */
            Status = ConMgrWriteData(Channel,
                                     Utf8ConversionBuffer,
                                     UTF8TranslationSize);
        }

        /* If translation or write failed, bail out */
        if (!NT_SUCCESS(Status)) goto Return;
    }

    /* Push the string to its new location (this could be a noop if aligned) */
    pwch += k;

    /* Now figure out how many aligned blocks we have, and loop each one */
    k = (Size / sizeof(WCHAR)) / MAX_UTF8_ENCODE_BLOCK_LENGTH;
    for (i = 0; i < k; i++)
    {
        /* Translate the aligned block */
        Result = SacTranslateUnicodeToUtf8(pwch,
                                           MAX_UTF8_ENCODE_BLOCK_LENGTH,
                                           Utf8ConversionBuffer,
                                           Utf8ConversionBufferSize,
                                           &UTF8TranslationSize,
                                           &TranslatedCount);
        ASSERT(MAX_UTF8_ENCODE_BLOCK_LENGTH == TranslatedCount);
        ASSERT(UTF8TranslationSize > 0);
        if (!Result)
        {
            /* Set failure here, we'll break out below */
            Status = STATUS_UNSUCCESSFUL;
        }
        else
        {
            /* Move the string location to the next aligned block */
            pwch += MAX_UTF8_ENCODE_BLOCK_LENGTH;

            /* Write the aligned block into the buffer */
            Status = ConMgrWriteData(Channel,
                                     Utf8ConversionBuffer,
                                     UTF8TranslationSize);
        }

        /* If translation or write failed, bail out */
        if (!NT_SUCCESS(Status)) break;
    }

Return:
    ASSERT(pwch == (PWSTR)(String + Size));
    if (NT_SUCCESS(Status)) Status = ConMgrFlushData(Channel);
    return Status;
}