ReactOS 0.4.15-dev-7924-g5949c20
vtutf8chan.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Drivers
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: drivers/sac/driver/vtutf8chan.c
5 * PURPOSE: Driver for the Server Administration Console (SAC) for EMS
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include "sacdrv.h"
12
13/* GLOBALS ********************************************************************/
14
17
19{
31};
32
33/* FUNCTIONS ******************************************************************/
34
36VOID
38{
39 ASSERT(Channel->CursorRow < SAC_VTUTF8_ROW_HEIGHT);
40 ASSERT(Channel->CursorCol < SAC_VTUTF8_COL_WIDTH);
41}
42
47{
48 /* If the first character is invalid, fail early */
49 if ((*String < L'0') || (*String > L'9')) return FALSE;
50
51 /* Otherwise, initialize the output and loop the string */
52 *Number = 0;
53 while ((*String >= L'0') && (*String <= L'9'))
54 {
55 /* Save the first decimal */
56 *Number = 10 * *Number;
57
58 /* Compute and add the second one */
59 *Number += *++String - L'0';
60 }
61
62 /* All done */
63 return TRUE;
64}
65
69 IN SAC_ANSI_DISPATCH AnsiCode,
70 IN INT* Data,
72{
74 PCHAR LocalBuffer = NULL, Tmp;
75 INT l;
76 CHECK_PARAMETER1(Channel);
77
78 /* Check which ANSI sequence we should output */
79 switch (AnsiCode)
80 {
81 /* Send the [2J (Clear Screen and Reset Cursor) */
83 Tmp = "\x1B[2J";
84 break;
85
86 /* Send the [0J (Clear From Position Till End Of Screen) */
88 Tmp = "\x1B[0J";
89 break;
90
91 /* Send the [0K (Clear from Position Till End Of Line) */
93 Tmp = "\x1B[0K";
94 break;
95
96 /* Send a combination of two [#m attribute changes */
98
99 /* Allocate a small local buffer for it */
101 CHECK_ALLOCATION(LocalBuffer);
102
103 /* Caller should have sent two colors as two integers */
104 if (!(Data) || (Length != 8))
105 {
107 break;
108 }
109
110 /* Create the escape sequence string */
111 l = sprintf(LocalBuffer, "\x1B[%dm\x1B[%dm", Data[1], Data[0]);
112 ASSERT((l + 1)*sizeof(UCHAR) < SAC_VTUTF8_COL_WIDTH);
113 ASSERT(LocalBuffer);
114 Tmp = LocalBuffer;
115 break;
116
117 /* Send the [#;#H (Cursor Position) sequence */
119
120 /* Allocate a small local buffer for it */
122 CHECK_ALLOCATION(LocalBuffer);
123
124 /* Caller should have sent the position as two integers */
125 if (!(Data) || (Length != 8))
126 {
128 break;
129 }
130
131 /* Create the escape sequence string */
132 l = sprintf(LocalBuffer, "\x1B[%d;%dH", Data[1] + 1, Data[0] + 1);
133 ASSERT((l + 1)*sizeof(UCHAR) < SAC_VTUTF8_COL_WIDTH);
134 ASSERT(LocalBuffer);
135 Tmp = LocalBuffer;
136 break;
137
138 /* Send the [0m sequence (Set Attribute 0) */
140 Tmp = "\x1B[0m";
141 break;
142
143 /* Send the [7m sequence (Set Attribute 7) */
145 Tmp = "\x1B[7m";
146 break;
147
148 /* Send the [27m sequence (Set Attribute 27) */
150 Tmp = "\x1B[27m";
151 break;
152
153 /* Send the [5m sequence (Set Attribute 5) */
155 Tmp = "\x1B[5m";
156 break;
157
158 /* Send the [25m sequence (Set Attribute 25) */
160 Tmp = "\x1B[25m";
161 break;
162
163 /* Send the [1m sequence (Set Attribute 1) */
165 Tmp = "\x1B[1m";
166 break;
167
168 /* Send the [22m sequence (Set Attribute 22) */
170 Tmp = "\x1B[22m";
171 break;
172
173 /* We don't recognize it */
174 default:
176 break;
177 }
178
179 /* Did everything work above? */
180 if (NT_SUCCESS(Status))
181 {
182 /* Go write out the sequence */
183 Status = ConMgrWriteData(Channel, Tmp, strlen(Tmp));
184 if (NT_SUCCESS(Status))
185 {
186 /* Now flush it */
187 Status = ConMgrFlushData(Channel);
188 }
189 }
190
191 /* Free the temporary buffer, if any, and return the status */
192 if (LocalBuffer) SacFreePool(LocalBuffer);
193 return Status;
194}
195
197NTAPI
199 IN UCHAR Attribute)
200{
202 CHECK_PARAMETER(Channel);
203
204 /* Set bold if needed */
206 Attribute & SAC_CELL_FLAG_BOLD ?
209 NULL,
210 0);
211 if (!NT_SUCCESS(Status)) return Status;
212
213 /* Set blink if needed */
215 Attribute & SAC_CELL_FLAG_BLINK ?
218 NULL,
219 0);
220 if (!NT_SUCCESS(Status)) return Status;
221
222 /* Set inverse if needed */
223 return VTUTF8ChannelAnsiDispatch(Channel,
224 Attribute & SAC_CELL_FLAG_INVERTED ?
227 NULL,
228 0);
229}
230
231//
232// This function is the guts of the sequences that SAC supports.
233//
234// It is written to conform to the way that Microsoft's SAC driver interprets
235// the ANSI standard. If you want to extend and/or "fix" it, please use a flag
236// that can be set in the Registry to enable "extended" ANSI support or etc...
237//
238// Hermes, I'm looking at you, buddy.
239//
240ULONG
241NTAPI
244{
245 ULONG Number, Number2, Number3, i, Action, Result;
246 PWCHAR Sequence;
249
250 /* Microsoft's driver does this after the O(n) check below. Be smarter. */
251 if (String[1] != VT_ANSI_COMMAND) return 0;
252
253 /* Now that we know it's a valid command, look through the common cases */
254 for (i = 0; i < RTL_NUMBER_OF(SacStaticEscapeStrings); i++)
255 {
256 /* Check if an optimized sequence was detected */
257 if (!wcsncmp(String + 1,
258 SacStaticEscapeStrings[i].Sequence,
260 {
261 /* Yep, return the right action, length, and set optionals to 1 */
264 Number = Number2 = Number3 = 1;
265 goto ProcessString;
266 }
267 }
268
269 /* It's a more complex sequence, start parsing it */
270 Result = 0;
271 Sequence = String + 2;
272
273 /* First, check for the cursor sequences. This is useless due to above. */
274 switch (*Sequence)
275 {
278 goto ProcessString;
279
282 goto ProcessString;
283
285 Action = SacCursorLeft; //bug
286 goto ProcessString;
287
289 Action = SacCursorRight; //bug
290 goto ProcessString;
291
294 goto ProcessString;
295
296 default:
297 break;
298 }
299
300 /* This must be a sequence starting with ESC[# */
301 if (!VTUTF8ChannelScanForNumber(Sequence, &Number)) return 0;
302 while ((*Sequence >= L'0') && (*Sequence <= L'9')) Sequence++;
303
304 /* Check if this is ESC[#m */
305 if (*Sequence == VT_ANSI_SET_ATTRIBUTE_CHAR)
306 {
307 /* Some attribute is being set, go over the ones we support */
308 switch (Number)
309 {
310 /* Make the font standard */
311 case Normal:
313 break;
314
315 /* Make the font bold */
316 case Bold:
318 break;
319
320 /* Make the font blink */
321 case SlowBlink:
323 break;
324
325 /* Make the font colors inverted */
326 case Inverse:
328 break;
329
330 /* Make the font standard intensity */
331 case BoldOff:
333 break;
334
335 /* Turn off blinking */
336 case BlinkOff:
338 break;
339
340 /* Turn off inverted colors */
341 case InverseOff:
343 break;
344
345 /* Something else... */
346 default:
347
348 /* Is a background color being set? */
350 {
351 /* Nope... is it the foreground color? */
352 if ((Number < SetColorStart) || (Number > SetColorMax))
353 {
354 /* Nope. SAC expects no other attributes so bail out */
355 ASSERT(FALSE);
356 return 0;
357 }
358
359 /* Yep -- the number will tell us which */
361 }
362 else
363 {
364 /* Yep -- the number will tell us which */
366 }
367 break;
368 }
369
370 /* In all cases, we're done here */
371 goto ProcessString;
372 }
373
374 /* The only allowed possibility now is ESC[#;# */
375 if (*Sequence != VT_ANSI_SEPARATOR_CHAR) return 0;
376 Sequence++;
377 if (!VTUTF8ChannelScanForNumber(Sequence, &Number2)) return 0;
378 while ((*Sequence >= L'0') && (*Sequence <= L'9')) Sequence++;
379
380 /* There's two valid forms accepted at this point: ESC[#;#m and ESC[#;#H */
381 switch (*Sequence)
382 {
383 /* This is ESC[#;#m -- used to set both colors at once */
386 goto ProcessString;
387
388 /* This is ESC[#;#H -- used to set the cursor position */
391 goto ProcessString;
392
393 /* Finally, this *could* be ESC[#;#; -- we'll keep parsing */
395 Sequence++;
396 break;
397
398 /* Abandon anything else */
399 default:
400 return 0;
401 }
402
403 /* The SAC seems to accept a few more possibilities if a ';' follows... */
404 switch (*Sequence)
405 {
406 /* Both ESC[#;#;H and ESC[#;#;f are really the same command */
409 /* It's unclear why MS doesn't allow the HVP sequence on its own */
411 goto ProcessString;
412
413 /* And this is the ESC[#;#;r command to set the scroll region... */
415 /* Again, not clear why ESC[#;#r isn't supported */
417 goto ProcessString;
418
419 /* Anything else must be ESC[#;#;# */
420 default:
421 break;
422 }
423
424 /* Get the last "#" */
425 if (!VTUTF8ChannelScanForNumber(Sequence, &Number3)) return 0;
426 while ((*Sequence >= L'0') && (*Sequence <= L'9')) Sequence++;
427
428 /* And now the only remaining possibility is ESC[#;#;#;m */
429 if (*Sequence == VT_ANSI_SET_ATTRIBUTE_CHAR)
430 {
431 /* Which sets both color and attributes in one command */
433 goto ProcessString;
434 }
435
436 /* No other sequences supported */
437 return 0;
438
439ProcessString:
440 /* Unless we got here from the optimized path, calculate the length */
441 if (!Result) Result = Sequence - String + 1;
442
443 /* Get the current cell buffer */
444 Screen = (PSAC_VTUTF8_SCREEN)Channel->OBuffer;
446
447 /* Handle all the supported SAC ANSI commands */
448 switch (Action)
449 {
450 case SacCursorUp:
451 /* Check if we are scrolling too high */
452 if (Channel->CursorRow < Number)
453 {
454 /* Reset the row to the top */
455 Channel->CursorRow = 0;
456 }
457 else
458 {
459 /* We're fine -- scroll up by that much */
460 Channel->CursorRow -= Number;
461 }
462
463 /* All done */
465 break;
466
467 case SacCursorDown:
468 /* Check if we are scrolling too low */
469 if (Channel->CursorRow >= SAC_VTUTF8_ROW_HEIGHT)
470 {
471 /* Reset the row to the bottom */
472 Channel->CursorRow = SAC_VTUTF8_ROW_HEIGHT;
473 }
474 else
475 {
476 /* We're fine -- scroll down by that much */
477 Channel->CursorRow += Number;
478 }
479
480 /* All done */
482 break;
483
484 case SacCursorLeft:
485 /* Check if we're scrolling too much to the left */
486 if (Channel->CursorCol < Number)
487 {
488 /* Reset the column to the left-most margin */
489 Channel->CursorCol = 0;
490 }
491 else
492 {
493 /* We're fine -- scroll left by that much */
494 Channel->CursorCol -= Number;
495 }
496
497 /* All done */
499 break;
500
501 case SacCursorRight:
502 /* Check if we're scrolling too much to the right */
503 if (Channel->CursorCol >= SAC_VTUTF8_COL_WIDTH)
504 {
505 /* Reset the column to the right-most margin */
506 Channel->CursorCol = SAC_VTUTF8_COL_WIDTH;
507 }
508 else
509 {
510 /* We're fine -- scroll right by that much */
511 Channel->CursorCol += Number;
512 }
513
514 /* All done */
516 break;
517
518 case SacFontNormal:
519 /* Reset the cell attributes */
520 Channel->CellFlags = 0;
521 Channel->CellBackColor = SetBackColorBlack;
522 Channel->CellForeColor = SetColorWhite;
523 break;
524
525 case SacFontBlink:
526 /* Set the appropriate flag */
527 Channel->CellFlags |= SAC_CELL_FLAG_BLINK;
528 break;
529
530 case SacFontBlinkOff:
531 /* Clear the appropriate flag */
532 Channel->CellFlags &= ~SAC_CELL_FLAG_BLINK;
533 break;
534
535 case SacFontBold:
536 /* Set the appropriate flag */
537 Channel->CellFlags |= SAC_CELL_FLAG_BOLD;
538 break;
539
540 case SacFontBoldOff:
541 /* Clear the appropriate flag */
542 Channel->CellFlags &= ~SAC_CELL_FLAG_BOLD;
543 break;
544
545 case SacFontInverse:
546 /* Set the appropriate flag */
547 Channel->CellFlags |= SAC_CELL_FLAG_INVERTED;
548 break;
549
551 /* Clear the appropriate flag */
552 Channel->CellFlags &= ~SAC_CELL_FLAG_INVERTED;
553 break;
554
556 /* Loop all columns in this line past the current position */
557 for (i = Channel->CursorCol; i < SAC_VTUTF8_COL_WIDTH; i++)
558 {
559 /* Replace everything after the current position with blanks */
560 Screen->Cell[Channel->CursorRow][i].CellFlags = Channel->CellFlags;
561 Screen->Cell[Channel->CursorRow][i].CellBackColor = Channel->CellForeColor;
562 Screen->Cell[Channel->CursorRow][i].CellForeColor = Channel->CellBackColor;
563 Screen->Cell[Channel->CursorRow][i].Char = L' ';
564 }
565 break;
566
568 /* Loop all columns in this line, before the current position */
569 for (i = 0; i < (Channel->CursorCol + 1); i++)
570 {
571 /* Replace everything after the current position with blanks */
572 Screen->Cell[Channel->CursorRow][i].CellFlags = Channel->CellFlags;
573 Screen->Cell[Channel->CursorRow][i].CellBackColor = Channel->CellForeColor;
574 Screen->Cell[Channel->CursorRow][i].CellForeColor = Channel->CellBackColor;
575 Screen->Cell[Channel->CursorRow][i].Char = L' ';
576 }
577 break;
578
579 case SacEraseLine:
580 /* Loop all the columns in this line */
581 for (i = 0; i < SAC_VTUTF8_COL_WIDTH; i++)
582 {
583 /* Replace them all with blanks */
584 Screen->Cell[Channel->CursorRow][i].CellFlags = Channel->CellFlags;
585 Screen->Cell[Channel->CursorRow][i].CellBackColor = Channel->CellForeColor;
586 Screen->Cell[Channel->CursorRow][i].CellForeColor = Channel->CellBackColor;
587 Screen->Cell[Channel->CursorRow][i].Char = L' ';
588 }
589 break;
590
592 ASSERT(FALSE); // todo
593 break;
594
596 ASSERT(FALSE); // todo
597 break;
598
599 case SacEraseScreen:
600 ASSERT(FALSE); // todo
601 break;
602
604 ASSERT(FALSE); // todo
605 break;
606
608 ASSERT(FALSE); // todo
609 break;
610
611 case SacSetColors:
612 /* Set the cell colors */
613 Channel->CellForeColor = Number;
614 Channel->CellBackColor = Number2;
615 break;
616
618 /* Set the cell back color */
619 Channel->CellBackColor = Number;
620 break;
621
622 case SacSetFontColor:
623 /* Set the cell text color */
624 Channel->CellForeColor = Number;
625 break;
626
628 /* Set the cell flag and colors */
629 Channel->CellFlags = Number;
630 Channel->CellForeColor = Number2;
631 Channel->CellBackColor = Number3;
632 break;
633
634 default:
635 /* Unknown, do nothing */
636 break;
637 }
638
639 /* Return the length of the sequence */
640 return Result;
641}
642
644NTAPI
646{
648 ULONG R, C;
649 CHECK_PARAMETER(Channel);
650
651 /* Set the current channel cell parameters */
652 Channel->CellFlags = 0;
653 Channel->CellBackColor = SetBackColorBlack;
654 Channel->CellForeColor = SetColorWhite;
655
656 /* Set the cell buffer position */
657 Screen = (PSAC_VTUTF8_SCREEN)Channel->OBuffer;
658
659 /* Loop the output buffer height by width */
660 for (R = 0; R < SAC_VTUTF8_ROW_HEIGHT; R++)
661 {
662 for (C = 0; C < SAC_VTUTF8_COL_WIDTH; C++)
663 {
664 /* For every character, set the defaults */
665 Screen->Cell[R][C].Char = L' ';
666 Screen->Cell[R][C].CellBackColor = SetBackColorBlack;
667 Screen->Cell[R][C].CellForeColor = SetColorWhite;
668 }
669 }
670
671 /* All done */
672 return STATUS_SUCCESS;
673}
674
676NTAPI
678{
680 CHECK_PARAMETER(Channel);
681
682 /* Allocate the output buffer */
684 CHECK_ALLOCATION(Channel->OBuffer);
685
686 /* Allocate the input buffer */
688 CHECK_ALLOCATION(Channel->IBuffer);
689
690 /* Initialize the output stream */
691 Status = VTUTF8ChannelOInit(Channel);
692 if (NT_SUCCESS(Status)) return Status;
693
694 /* Reset all flags and return success */
695 _InterlockedExchange(&Channel->ChannelHasNewOBufferData, 0);
696 _InterlockedExchange(&Channel->ChannelHasNewIBufferData, 0);
697 return STATUS_SUCCESS;
698}
699
701NTAPI
703{
704 CHECK_PARAMETER(Channel);
705
706 /* Free the buffer and then destroy the channel */
707 if (Channel->OBuffer) SacFreePool(Channel->OBuffer);
708 if (Channel->IBuffer) SacFreePool(Channel->IBuffer);
709 return ChannelDestroy(Channel);
710}
711
713NTAPI
718{
719 ASSERT(FALSE);
721}
722
724NTAPI
726{
729 INT Color[2], Position[2];
730 ULONG Utf8ProcessedCount, Utf8Count, R, C, ForeColor, BackColor, Attribute;
731 PWCHAR TmpBuffer;
732 BOOLEAN Overflow = FALSE;
733 CHECK_PARAMETER(Channel);
734
735 /* Set the cell buffer position */
736 Screen = (PSAC_VTUTF8_SCREEN)Channel->OBuffer;
737
738 /* Allocate a temporary buffer */
739 TmpBuffer = SacAllocatePool(40, GLOBAL_BLOCK_TAG);
740 if (!TmpBuffer)
741 {
743 goto Quickie;
744 }
745
746 /* First, clear the screen */
749 NULL,
750 0);
751 if (!NT_SUCCESS(Status)) goto Quickie;
752
753 /* Next, reset the cursor position */
754 Position[1] = 0;
755 Position[0] = 0;
758 Position,
759 sizeof(Position));
760 if (!NT_SUCCESS(Status)) goto Quickie;
761
762 /* Finally, reset the attributes */
765 NULL,
766 0);
767 if (!NT_SUCCESS(Status)) goto Quickie;
768
769 /* Now set the current cell attributes */
770 Attribute = Channel->CellFlags;
771 Status = VTUTF8ChannelProcessAttributes(Channel, Attribute);
772 if (!NT_SUCCESS(Status)) goto Quickie;
773
774 /* And set the current cell colors */
775 ForeColor = Channel->CellForeColor;
776 BackColor = Channel->CellBackColor;
777 Color[1] = BackColor;
778 Color[0] = ForeColor;
781 Color,
782 sizeof(Color));
783 if (!NT_SUCCESS(Status)) goto Quickie;
784
785 /* Now loop all the characters in the cell buffer */
786 for (R = 0; R < SAC_VTUTF8_ROW_HEIGHT; R++)
787 {
788 /* Across every row */
789 for (C = 0; C < SAC_VTUTF8_COL_WIDTH; C++)
790 {
791 /* Check if there's been a change in colors */
792 if ((Screen->Cell[R][C].CellBackColor != BackColor) ||
793 (Screen->Cell[R][C].CellForeColor != ForeColor))
794 {
795 /* New colors are being drawn -- are we also on a new row now? */
796 if (Overflow)
797 {
798 /* Reposition the cursor correctly */
799 Position[1] = R;
800 Position[0] = C;
803 Position,
804 sizeof(Position));
805 if (!NT_SUCCESS(Status)) goto Quickie;
806 Overflow = FALSE;
807 }
808
809 /* Cache the new colors */
810 ForeColor = Screen->Cell[R][C].CellForeColor;
811 BackColor = Screen->Cell[R][C].CellBackColor;
812
813 /* Set them on the screen */
814 Color[1] = BackColor;
815 Color[0] = ForeColor;
818 Color,
819 sizeof(Color));
820 if (!NT_SUCCESS(Status)) goto Quickie;
821 }
822
823 /* Check if there's been a change in attributes */
824 if (Screen->Cell[R][C].CellFlags != Attribute)
825 {
826 /* Yep! Are we also on a new row now? */
827 if (Overflow)
828 {
829 /* Reposition the cursor correctly */
830 Position[1] = R;
831 Position[0] = C;
834 Position,
835 sizeof(Position));
836 if (!NT_SUCCESS(Status)) goto Quickie;
837 Overflow = FALSE;
838 }
839
840 /* Set the new attributes on screen */
841 Attribute = Screen->Cell[R][C].CellFlags;
842 Status = VTUTF8ChannelProcessAttributes(Channel, Attribute);
843 if (!NT_SUCCESS(Status)) goto Quickie;
844 }
845
846 /* Time to write the character -- are we on a new row now? */
847 if (Overflow)
848 {
849 /* Reposition the cursor correctly */
850 Position[1] = R;
851 Position[0] = C;
854 Position,
855 sizeof(Position));
856 if (!NT_SUCCESS(Status)) goto Quickie;
857 Overflow = FALSE;
858 }
859
860 /* Write the character into our temporary buffer */
861 *TmpBuffer = Screen->Cell[R][C].Char;
862 TmpBuffer[1] = UNICODE_NULL;
863
864 /* Convert it to UTF-8 */
865 if (!SacTranslateUnicodeToUtf8(TmpBuffer,
866 1,
869 &Utf8Count,
870 &Utf8ProcessedCount))
871 {
872 /* Bail out if this failed */
874 goto Quickie;
875 }
876
877 /* Make sure we have a remaining valid character */
878 if (Utf8Count)
879 {
880 /* Write it out on the wire */
881 Status = ConMgrWriteData(Channel, Utf8ConversionBuffer, Utf8Count);
882 if (!NT_SUCCESS(Status)) goto Quickie;
883 }
884 }
885
886 /* All the characters on the row are done, indicate we need a reset */
887 Overflow = TRUE;
888 }
889
890 /* Everything is done, set the position one last time */
891 Position[1] = Channel->CursorRow;
892 Position[0] = Channel->CursorCol;
895 Position,
896 sizeof(Position));
897 if (!NT_SUCCESS(Status)) goto Quickie;
898
899 /* Set the current attribute one last time */
900 Status = VTUTF8ChannelProcessAttributes(Channel, Channel->CellFlags);
901 if (!NT_SUCCESS(Status)) goto Quickie;
902
903 /* Set the current colors one last time */
904 Color[1] = Channel->CellBackColor;
905 Color[0] = Channel->CellForeColor;
908 Color,
909 sizeof(Color));
910 if (!NT_SUCCESS(Status)) goto Quickie;
911
912 /* Flush all the data out on the wire */
913 Status = ConMgrFlushData(Channel);
914
915Quickie:
916 /* We're done, free the temporary buffer */
917 if (TmpBuffer) SacFreePool(TmpBuffer);
918
919 /* Indicate that all new data has been flushed now */
920 if (NT_SUCCESS(Status))
921 {
922 _InterlockedExchange(&Channel->ChannelHasNewOBufferData, 0);
923 }
924
925 /* Return the result */
926 return Status;
927}
928
930NTAPI
933 IN ULONG Size)
934{
936 ULONG i, EscapeSize, R, C;
937 PWSTR pwch;
938 CHECK_PARAMETER1(Channel);
941
942 /* Loop every character */
943 Screen = (PSAC_VTUTF8_SCREEN)Channel->OBuffer;
944 for (i = 0; i < Size; i++)
945 {
946 /* Check what the character is */
947 pwch = &String[i];
948 switch (*pwch)
949 {
950 /* It's an escape sequence... */
951 case L'\x1B':
952
953 /* Send it to the parser, see how long the sequence was */
954 EscapeSize = VTUTF8ChannelConsumeEscapeSequence(Channel, pwch);
955 if (EscapeSize)
956 {
957 /* Consume that many characters for next time*/
958 i += EscapeSize - 1;
959 }
960 else
961 {
962 /* Invalid escape sequence, skip just the ESC character */
963 i++;
964 }
965
966 /* Keep going*/
967 break;
968
969 /* It's a line feed */
970 case L'\n':
971
972 /* Simply reset the column to zero on the current line */
973 Channel->CursorCol = 0;
974 break;
975
976 /* It's a carriage feed */
977 case L'\r':
978
979 /* Move to the next row */
980 Channel->CursorRow++;
981
982 /* Check if we hit the last row on the screen */
983 if (Channel->CursorRow >= SAC_VTUTF8_ROW_HEIGHT)
984 {
985 /* Go over every row before the last one */
986 for (R = 0; R < (SAC_VTUTF8_ROW_HEIGHT - 1); R++)
987 {
988 /* Sanity check, since we always copy one row below */
990
991 /* Loop every character on the row */
992 for (C = 0; C < SAC_VTUTF8_COL_WIDTH; C++)
993 {
994 /* And replace it with one from the row below */
995 Screen->Cell[R][C] = Screen->Cell[R + 1][C];
996 }
997 }
998
999 /* Now we're left with the before-last row, zero it out */
1000 ASSERT(R == (SAC_VTUTF8_ROW_HEIGHT - 1));
1001 RtlZeroMemory(&Screen->Cell[R], sizeof(Screen->Cell[R]));
1002
1003 /* Reset the row back by one */
1004 Channel->CursorRow--;
1006 }
1007 break;
1008
1009 /* It's a TAB character */
1010 case L'\t':
1011
1012 /* Loop the remaining characters until a multiple of 4 */
1014 for (C = (4 - Channel->CursorCol % 4); C; C--)
1015 {
1016 /* Fill each remaining character with a space */
1018 Screen->Cell[Channel->CursorRow][Channel->CursorCol].CellFlags = Channel->CellFlags;
1019 Screen->Cell[Channel->CursorRow][Channel->CursorCol].CellBackColor = Channel->CellBackColor;
1020 Screen->Cell[Channel->CursorRow][Channel->CursorCol].CellForeColor = Channel->CellForeColor;
1021 Screen->Cell[Channel->CursorRow][Channel->CursorCol].Char = L' ';
1022
1023 /* Move to the next character position, but don't overflow */
1024 Channel->CursorCol++;
1025 if (Channel->CursorCol >= SAC_VTUTF8_COL_WIDTH)
1026 {
1027 Channel->CursorCol = SAC_VTUTF8_COL_WIDTH - 1;
1028 }
1029 }
1030
1031 /* All done, move to the next one */
1033 break;
1034
1035 /* It's a backspace or delete character */
1036 case L'\b':
1037 case L'\x7F':
1038
1039 /* Move back one character, unless we had nothing typed */
1040 if (Channel->CursorCol) Channel->CursorCol--;
1042 break;
1043
1044 /* It's some other character */
1045 default:
1046
1047 /* Is it non-printable? Ignore it and keep parsing */
1048 if (*pwch < L' ') continue;
1049
1050 /* Otherwise, print it out with the current attributes */
1052 Screen->Cell[Channel->CursorRow][Channel->CursorCol].CellFlags = Channel->CellFlags;
1053 Screen->Cell[Channel->CursorRow][Channel->CursorCol].CellBackColor = Channel->CellBackColor;
1054 Screen->Cell[Channel->CursorRow][Channel->CursorCol].CellForeColor = Channel->CellForeColor;
1055 Screen->Cell[Channel->CursorRow][Channel->CursorCol].Char = *pwch;
1056
1057 /* Move forward one character, but make sure not to overflow */
1058 Channel->CursorCol++;
1059 if (Channel->CursorCol == SAC_VTUTF8_COL_WIDTH)
1060 {
1061 Channel->CursorCol = SAC_VTUTF8_COL_WIDTH - 1;
1062 }
1063
1064 /* All done, move to the next one */
1066 break;
1067 }
1068 }
1069
1070 /* Parsing of the input string completed -- string was written */
1072 return STATUS_SUCCESS;
1073}
1074
1076NTAPI
1078 IN PCHAR String,
1079 IN ULONG Size)
1080{
1082 PWSTR pwch;
1083 ULONG i, k, TranslatedCount, UTF8TranslationSize;
1085 CHECK_PARAMETER1(Channel);
1087
1088 /* Return success if there's nothing to echo */
1089 if (!(Size / sizeof(WCHAR))) return Status;
1090
1091 /* Start with the input string */
1092 pwch = (PWCHAR)String;
1093
1094 /* First, figure out how much is outside of the block length alignment */
1095 k = (Size / sizeof(WCHAR)) % MAX_UTF8_ENCODE_BLOCK_LENGTH;
1096 if (k)
1097 {
1098 /* Translate the misaligned portion */
1100 k,
1103 &UTF8TranslationSize,
1104 &TranslatedCount);
1105 ASSERT(k == TranslatedCount);
1106 if (!Result)
1107 {
1108 /* If we couldn't translate, write failure to break out below */
1110 }
1111 else
1112 {
1113 /* Write the misaligned portion into the buffer */
1114 Status = ConMgrWriteData(Channel,
1116 UTF8TranslationSize);
1117 }
1118
1119 /* If translation or write failed, bail out */
1120 if (!NT_SUCCESS(Status)) goto Return;
1121 }
1122
1123 /* Push the string to its new location (this could be a noop if aligned) */
1124 pwch += k;
1125
1126 /* Now figure out how many aligned blocks we have, and loop each one */
1127 k = (Size / sizeof(WCHAR)) / MAX_UTF8_ENCODE_BLOCK_LENGTH;
1128 for (i = 0; i < k; i++)
1129 {
1130 /* Translate the aligned block */
1135 &UTF8TranslationSize,
1136 &TranslatedCount);
1137 ASSERT(MAX_UTF8_ENCODE_BLOCK_LENGTH == TranslatedCount);
1138 ASSERT(UTF8TranslationSize > 0);
1139 if (!Result)
1140 {
1141 /* Set failure here, we'll break out below */
1143 }
1144 else
1145 {
1146 /* Move the string location to the next aligned block */
1148
1149 /* Write the aligned block into the buffer */
1150 Status = ConMgrWriteData(Channel,
1152 UTF8TranslationSize);
1153 }
1154
1155 /* If translation or write failed, bail out */
1156 if (!NT_SUCCESS(Status)) break;
1157 }
1158
1159Return:
1160 ASSERT(pwch == (PWSTR)(String + Size));
1161 if (NT_SUCCESS(Status)) Status = ConMgrFlushData(Channel);
1162 return Status;
1163}
1164
1166NTAPI
1168 IN PCHAR String,
1169 IN ULONG Length)
1170{
1172 CHECK_PARAMETER1(Channel);
1174
1175 /* Call the lower level function */
1176 Status = VTUTF8ChannelOWrite2(Channel, (PWCHAR)String, Length / sizeof(WCHAR));
1177 if (NT_SUCCESS(Status))
1178 {
1179 /* Is the channel enabled for output? */
1180 if ((ConMgrIsWriteEnabled(Channel)) && (Channel->WriteEnabled))
1181 {
1182 /* Go ahead and output it */
1184 }
1185 else
1186 {
1187 /* Otherwise, just remember that we have new data */
1188 _InterlockedExchange(&Channel->ChannelHasNewOBufferData, 1);
1189 }
1190 }
1191
1192 /* We're done */
1193 return Status;
1194}
1195
1196ULONG
1197NTAPI
1199{
1200 ASSERT(Channel);
1201 ASSERT((Channel->IBufferIndex % sizeof(WCHAR)) == 0);
1202 ASSERT(Channel->IBufferIndex < SAC_VTUTF8_IBUFFER_SIZE);
1203
1204 /* Return the current buffer index */
1205 return Channel->IBufferIndex;
1206}
1207
1208VOID
1209NTAPI
1211 IN ULONG BufferIndex)
1212{
1214 ASSERT(Channel);
1215 ASSERT((Channel->IBufferIndex % sizeof(WCHAR)) == 0);
1216 ASSERT(Channel->IBufferIndex < SAC_VTUTF8_IBUFFER_SIZE);
1217
1218 /* Set the new index, and if it's not zero, it means we have data */
1219 Channel->IBufferIndex = BufferIndex;
1220 _InterlockedExchange(&Channel->ChannelHasNewIBufferData, BufferIndex != 0);
1221
1222 /* If we have new data, and an event has been registered... */
1223 if (!(Channel->IBufferIndex) &&
1224 (Channel->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT))
1225 {
1226 /* Go ahead and signal it */
1227 ChannelClearEvent(Channel, HasNewDataEvent);
1229 }
1230}
1231
1233NTAPI
1235 IN PCHAR Buffer,
1238{
1239 ULONG CopyChars, ReadLength;
1240 CHECK_PARAMETER1(Channel);
1243
1244 /* Assume failure */
1245 *ReturnBufferSize = 0;
1246
1247 /* Check how many bytes are in the buffer */
1248 if (Channel->ChannelInputBufferLength(Channel) == 0)
1249 {
1250 /* Apparently nothing. Make sure the flag indicates so too */
1252 }
1253 else
1254 {
1255 /* Use the smallest number of bytes either in the buffer or requested */
1256 ReadLength = min(Channel->ChannelInputBufferLength(Channel) * sizeof(WCHAR),
1257 BufferSize);
1258
1259 /* Do some cheezy buffer alignment */
1260 CopyChars = ReadLength / sizeof(WCHAR);
1261 ReadLength = CopyChars * sizeof(WCHAR);
1262 ASSERT(CopyChars <= Channel->ChannelInputBufferLength(Channel));
1263
1264 /* Copy them into the caller's buffer */
1265 RtlCopyMemory(Buffer, Channel->IBuffer, ReadLength);
1266
1267 /* Update the channel's index past the copied (read) bytes */
1270
1271 /* Are there still bytes that haven't been read yet? */
1272 if (Channel->ChannelInputBufferLength(Channel))
1273 {
1274 /* Shift them up in the buffer */
1275 RtlMoveMemory(Channel->IBuffer,
1276 &Channel->IBuffer[ReadLength],
1277 Channel->ChannelInputBufferLength(Channel) *
1278 sizeof(WCHAR));
1279 }
1280
1281 /* Return the number of bytes we actually copied */
1283 }
1284
1285 /* Return success */
1286 return STATUS_SUCCESS;
1287}
1288
1290NTAPI
1292 OUT PBOOLEAN BufferStatus)
1293{
1294 CHECK_PARAMETER1(Channel);
1295
1296 /* If the index is beyond the length, the buffer must be full */
1297 *BufferStatus = VTUTF8ChannelGetIBufferIndex(Channel) > SAC_VTUTF8_IBUFFER_SIZE;
1298 return STATUS_SUCCESS;
1299}
1300
1301ULONG
1302NTAPI
1304{
1305 ASSERT(Channel);
1306
1307 /* The index is the length, so divide by two to get character count */
1308 return VTUTF8ChannelGetIBufferIndex(Channel) / sizeof(WCHAR);
1309}
1310
1311WCHAR
1312NTAPI
1314{
1315 PWCHAR LastCharLocation;
1316 WCHAR LastChar = 0;
1317 ASSERT(Channel);
1318
1319 /* Check if there's anything to read in the buffer */
1320 if (Channel->ChannelInputBufferLength(Channel))
1321 {
1322 /* Go back one character */
1325 sizeof(WCHAR));
1326
1327 /* Read it, and clear its current value */
1328 LastCharLocation = (PWCHAR)&Channel->IBuffer[VTUTF8ChannelGetIBufferIndex(Channel)];
1329 LastChar = *LastCharLocation;
1330 *LastCharLocation = UNICODE_NULL;
1331 }
1332
1333 /* Return the last character */
1334 return LastChar;
1335}
1336
1338NTAPI
1340 IN PCHAR Buffer,
1342{
1344 BOOLEAN IsFull;
1345 ULONG Index, i;
1346 CHECK_PARAMETER1(Channel);
1349
1350 /* First, check if the input buffer still has space */
1351 Status = VTUTF8ChannelIBufferIsFull(Channel, &IsFull);
1352 if (!NT_SUCCESS(Status)) return Status;
1353 if (IsFull) return STATUS_UNSUCCESSFUL;
1354
1355 /* Get the current buffer index */
1358 {
1360 }
1361
1362 /* Copy the new data */
1363 for (i = 0; i < BufferSize; i++)
1364 {
1365 /* Convert the character */
1369 {
1370 /* Write it into the buffer */
1371 *(PWCHAR)&Channel->IBuffer[VTUTF8ChannelGetIBufferIndex(Channel)] =
1373
1374 /* Update the index */
1376 VTUTF8ChannelSetIBufferIndex(Channel, Index + sizeof(WCHAR));
1377 }
1378 }
1379
1380 /* Signal the event, if one was set */
1381 if (Channel->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT)
1382 {
1383 ChannelSetEvent(Channel, HasNewDataEvent);
1384 }
1385
1386 /* All done */
1387 return STATUS_SUCCESS;
1388}
ULONG ReadLength
unsigned char BOOLEAN
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
LONG NTSTATUS
Definition: precomp.h:26
#define C(c)
Definition: builtin.c:4556
r l[0]
Definition: byte_order.h:168
NTSTATUS NTAPI ChannelDestroy(IN PSAC_CHANNEL Channel)
Definition: channel.c:77
Definition: bufpool.h:45
Definition: terminate.cpp:24
BOOLEAN NTAPI ConMgrIsWriteEnabled(IN PSAC_CHANNEL Channel)
Definition: conmgr.c:155
NTSTATUS NTAPI ConMgrWriteData(IN PSAC_CHANNEL Channel, IN PVOID Buffer, IN ULONG BufferLength)
Definition: conmgr.c:111
NTSTATUS NTAPI ConMgrFlushData(IN PSAC_CHANNEL Channel)
Definition: conmgr.c:139
#define BufferSize
Definition: mmc.h:75
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
@ Screen
Definition: console.h:34
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
long __cdecl _InterlockedExchange(_Interlocked_operand_ long volatile *_Target, long _Value)
#define ASSERT(a)
Definition: mode.c:44
#define for
Definition: utility.h:88
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define min(a, b)
Definition: monoChain.cc:55
int k
Definition: mpi.c:3369
#define UNICODE_NULL
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:207
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:650
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define L(x)
Definition: ntvdm.h:50
#define VT_ANSI_ESCAPE
Definition: sacdrv.h:1484
#define CHECK_PARAMETER2(x)
Definition: sacdrv.h:58
#define VT_ANSI_CURSOR_LEFT
Definition: sacdrv.h:1497
#define SacAllocatePool(Length, Tag)
Definition: sacdrv.h:24
#define VT_ANSI_ERASE_LINE_CHAR
Definition: sacdrv.h:1499
ULONG Utf8ConversionBufferSize
Definition: util.c:18
#define VT_ANSI_CURSOR_LEFT_CHAR
Definition: sacdrv.h:1496
#define VT_ANSI_ERASE_START_LINE
Definition: sacdrv.h:1501
@ Inverse
Definition: sacdrv.h:1385
@ SetBackColorBlack
Definition: sacdrv.h:1445
@ SetBackColorStart
Definition: sacdrv.h:1444
@ BoldOff
Definition: sacdrv.h:1412
@ Normal
Definition: sacdrv.h:1378
@ SetColorWhite
Definition: sacdrv.h:1432
@ SlowBlink
Definition: sacdrv.h:1383
@ SetBackColorMax
Definition: sacdrv.h:1453
@ InverseOff
Definition: sacdrv.h:1417
@ Bold
Definition: sacdrv.h:1379
@ SetColorStart
Definition: sacdrv.h:1424
@ SetColorMax
Definition: sacdrv.h:1433
@ BlinkOff
Definition: sacdrv.h:1415
#define VT_ANSI_CURSOR_RIGHT_CHAR
Definition: sacdrv.h:1493
#define VT_ANSI_CURSOR_RIGHT
Definition: sacdrv.h:1494
#define VT_ANSI_CURSOR_UP_CHAR
Definition: sacdrv.h:1487
#define CHECK_PARAMETER1(x)
Definition: sacdrv.h:56
#define CHECK_PARAMETER_WITH_STATUS(Condition, Status)
Definition: sacdrv.h:47
#define VT_ANSI_COMMAND
Definition: sacdrv.h:1485
#define VT_ANSI_ERASE_UP_SCREEN
Definition: sacdrv.h:1506
BOOLEAN NTAPI SacTranslateUtf8ToUnicode(IN CHAR Utf8Char, IN PCHAR Utf8Buffer, OUT PWCHAR Utf8Value)
Definition: util.c:41
#define SAC_CELL_FLAG_INVERTED
Definition: sacdrv.h:181
#define SAC_CELL_FLAG_BOLD
Definition: sacdrv.h:180
BOOLEAN NTAPI SacTranslateUnicodeToUtf8(IN PWCHAR SourceBuffer, IN ULONG SourceBufferLength, OUT PCHAR DestinationBuffer, IN ULONG DestinationBufferSize, OUT PULONG UTF8Count, OUT PULONG ProcessedCount)
Definition: util.c:91
#define VT_ANSI_CURSOR_DOWN_CHAR
Definition: sacdrv.h:1490
#define VT_ANSI_CUP_CURSOR_CHAR
Definition: sacdrv.h:1515
#define VT_ANSI_SET_ATTRIBUTE_CHAR
Definition: sacdrv.h:1512
#define VT_ANSI_HVP_CURSOR_CHAR
Definition: sacdrv.h:1514
#define CHECK_ALLOCATION(x)
Definition: sacdrv.h:64
#define VT_220_BACKTAB
Definition: sacdrv.h:1510
#define SAC_VTUTF8_OBUFFER_SIZE
Definition: sacdrv.h:161
#define ChannelSetEvent(Channel, x)
Definition: sacdrv.h:99
#define ChannelClearEvent(Channel, x)
Definition: sacdrv.h:114
#define VT_ANSI_ERASE_ENTIRE_SCREEN
Definition: sacdrv.h:1507
FORCEINLINE BOOLEAN ChannelHasNewIBufferData(IN PSAC_CHANNEL Channel)
Definition: sacdrv.h:1361
PCHAR Utf8ConversionBuffer
Definition: util.c:17
#define MAX_UTF8_ENCODE_BLOCK_LENGTH
Definition: sacdrv.h:160
#define VT_ANSI_CURSOR_DOWN
Definition: sacdrv.h:1491
#define VT_ANSI_SCROLL_CHAR
Definition: sacdrv.h:1516
#define VT_ANSI_ERASE_ENTIRE_LINE
Definition: sacdrv.h:1502
#define VT_ANSI_CURSOR_UP
Definition: sacdrv.h:1488
@ SacFontBoldOff
Definition: sacdrv.h:224
@ SacCursorLeft
Definition: sacdrv.h:219
@ SacFontBold
Definition: sacdrv.h:223
@ SacEraseScreen
Definition: sacdrv.h:233
@ SacFontInverse
Definition: sacdrv.h:225
@ SacSetBackgroundColor
Definition: sacdrv.h:237
@ SacEraseLine
Definition: sacdrv.h:230
@ SacSetColorsAndAttributes
Definition: sacdrv.h:239
@ SacFontBlinkOff
Definition: sacdrv.h:222
@ SacCursorUp
Definition: sacdrv.h:216
@ SacFontNormal
Definition: sacdrv.h:220
@ SacCursorRight
Definition: sacdrv.h:218
@ SacSetCursorPosition
Definition: sacdrv.h:234
@ SacFontInverseOff
Definition: sacdrv.h:226
@ SacEraseEndOfLine
Definition: sacdrv.h:228
@ SacFontBlink
Definition: sacdrv.h:221
@ SacEraseEndOfScreen
Definition: sacdrv.h:231
@ SacEraseStartOfLine
Definition: sacdrv.h:229
@ SacEraseStartOfScreen
Definition: sacdrv.h:232
@ SacSetFontColor
Definition: sacdrv.h:238
@ SacCursorDown
Definition: sacdrv.h:217
@ SacBackTab
Definition: sacdrv.h:227
@ SacSetScrollRegion
Definition: sacdrv.h:235
@ SacSetColors
Definition: sacdrv.h:236
#define CHECK_PARAMETER(x)
Definition: sacdrv.h:54
#define VT_ANSI_ERASE_DOWN_SCREEN
Definition: sacdrv.h:1505
struct _SAC_VTUTF8_SCREEN * PSAC_VTUTF8_SCREEN
#define VT_ANSI_SEPARATOR_CHAR
Definition: sacdrv.h:1513
#define GLOBAL_BLOCK_TAG
Definition: sacdrv.h:142
#define VT_ANSI_ERASE_END_LINE
Definition: sacdrv.h:1500
enum _SAC_ANSI_DISPATCH SAC_ANSI_DISPATCH
@ SacAnsiSetColors
Definition: sacdrv.h:250
@ SacAnsiClearEndOfLine
Definition: sacdrv.h:249
@ SacAnsiClearBlinkAttribute
Definition: sacdrv.h:256
@ SacAnsiSetInverseAttribute
Definition: sacdrv.h:253
@ SacAnsiSetBoldAttribute
Definition: sacdrv.h:257
@ SacAnsiClearInverseAttribute
Definition: sacdrv.h:254
@ SacAnsiClearBoldAttribute
Definition: sacdrv.h:258
@ SacAnsiClearAttributes
Definition: sacdrv.h:252
@ SacAnsiClearScreen
Definition: sacdrv.h:247
@ SacAnsiSetBlinkAttribute
Definition: sacdrv.h:255
@ SacAnsiSetPosition
Definition: sacdrv.h:251
@ SacAnsiClearEndOfScreen
Definition: sacdrv.h:248
#define SAC_CELL_FLAG_BLINK
Definition: sacdrv.h:179
#define SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT
Definition: sacdrv.h:171
#define SAC_VTUTF8_ROW_HEIGHT
Definition: sacdrv.h:159
#define SAC_VTUTF8_COL_WIDTH
Definition: sacdrv.h:157
#define SacFreePool(Pointer)
Definition: sacdrv.h:26
#define SAC_VTUTF8_IBUFFER_SIZE
Definition: sacdrv.h:162
_Check_return_ _CRTIMP int __cdecl wcsncmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
_In_ DWORD _In_ DWORD ReturnBufferSize
Definition: setupapi.h:1897
#define R(b, x)
Definition: sha2.c:134
#define STATUS_SUCCESS
Definition: shellext.h:65
static COORD Position
Definition: mouse.c:34
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
int32_t INT
Definition: typedefs.h:58
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
WCHAR IncomingUnicodeValue
Definition: vtutf8chan.c:16
FORCEINLINE VOID VTUTF8ChannelAssertCursor(IN PSAC_CHANNEL Channel)
Definition: vtutf8chan.c:37
NTSTATUS NTAPI VTUTF8ChannelOFlush(IN PSAC_CHANNEL Channel)
Definition: vtutf8chan.c:725
NTSTATUS NTAPI VTUTF8ChannelOWrite2(IN PSAC_CHANNEL Channel, IN PWCHAR String, IN ULONG Size)
Definition: vtutf8chan.c:931
CHAR IncomingUtf8ConversionBuffer[4]
Definition: vtutf8chan.c:15
ULONG NTAPI VTUTF8ChannelGetIBufferIndex(IN PSAC_CHANNEL Channel)
Definition: vtutf8chan.c:1198
BOOLEAN NTAPI VTUTF8ChannelScanForNumber(IN PWCHAR String, OUT PULONG Number)
Definition: vtutf8chan.c:45
NTSTATUS NTAPI VTUTF8ChannelOEcho(IN PSAC_CHANNEL Channel, IN PCHAR String, IN ULONG Size)
Definition: vtutf8chan.c:1077
NTSTATUS NTAPI VTUTF8ChannelOInit(IN PSAC_CHANNEL Channel)
Definition: vtutf8chan.c:645
VOID NTAPI VTUTF8ChannelSetIBufferIndex(IN PSAC_CHANNEL Channel, IN ULONG BufferIndex)
Definition: vtutf8chan.c:1210
NTSTATUS NTAPI VTUTF8ChannelIWrite(IN PSAC_CHANNEL Channel, IN PCHAR Buffer, IN ULONG BufferSize)
Definition: vtutf8chan.c:1339
NTSTATUS NTAPI VTUTF8ChannelORead(IN PSAC_CHANNEL Channel, IN PCHAR Buffer, IN ULONG BufferSize, OUT PULONG ByteCount)
Definition: vtutf8chan.c:714
NTSTATUS NTAPI VTUTF8ChannelCreate(IN PSAC_CHANNEL Channel)
Definition: vtutf8chan.c:677
NTSTATUS NTAPI VTUTF8ChannelIBufferIsFull(IN PSAC_CHANNEL Channel, OUT PBOOLEAN BufferStatus)
Definition: vtutf8chan.c:1291
ULONG NTAPI VTUTF8ChannelIBufferLength(IN PSAC_CHANNEL Channel)
Definition: vtutf8chan.c:1303
NTSTATUS NTAPI VTUTF8ChannelProcessAttributes(IN PSAC_CHANNEL Channel, IN UCHAR Attribute)
Definition: vtutf8chan.c:198
SAC_STATIC_ESCAPE_STRING SacStaticEscapeStrings[]
Definition: vtutf8chan.c:18
ULONG NTAPI VTUTF8ChannelConsumeEscapeSequence(IN PSAC_CHANNEL Channel, IN PWCHAR String)
Definition: vtutf8chan.c:242
NTSTATUS NTAPI VTUTF8ChannelOWrite(IN PSAC_CHANNEL Channel, IN PCHAR String, IN ULONG Length)
Definition: vtutf8chan.c:1167
NTSTATUS NTAPI VTUTF8ChannelAnsiDispatch(IN PSAC_CHANNEL Channel, IN SAC_ANSI_DISPATCH AnsiCode, IN INT *Data, IN ULONG Length)
Definition: vtutf8chan.c:68
NTSTATUS NTAPI VTUTF8ChannelIRead(IN PSAC_CHANNEL Channel, IN PCHAR Buffer, IN ULONG BufferSize, IN PULONG ReturnBufferSize)
Definition: vtutf8chan.c:1234
WCHAR NTAPI VTUTF8ChannelIReadLast(IN PSAC_CHANNEL Channel)
Definition: vtutf8chan.c:1313
NTSTATUS NTAPI VTUTF8ChannelDestroy(IN PSAC_CHANNEL Channel)
Definition: vtutf8chan.c:702
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
#define FORCEINLINE
Definition: wdftypes.h:67
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1099
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175