ReactOS  0.4.13-dev-100-gc8611ae
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 {
24  { VT_220_BACKTAB, 3, SacBackTab },
31 };
32 
33 /* FUNCTIONS ******************************************************************/
34 
36 VOID
38 {
39  ASSERT(Channel->CursorRow < SAC_VTUTF8_ROW_HEIGHT);
40  ASSERT(Channel->CursorCol < SAC_VTUTF8_COL_WIDTH);
41 }
42 
43 BOOLEAN
44 NTAPI
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 
67 NTAPI
69  IN SAC_ANSI_DISPATCH AnsiCode,
70  IN INT* Data,
71  IN ULONG Length)
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) */
82  case SacAnsiClearScreen:
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 */
97  case SacAnsiSetColors:
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 */
118  case SacAnsiSetPosition:
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 
196 NTSTATUS
197 NTAPI
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 //
240 ULONG
241 NTAPI
243  IN PWCHAR String)
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... */
414  case VT_ANSI_SCROLL_CHAR:
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 
439 ProcessString:
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;
445  VTUTF8ChannelAssertCursor(Channel);
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 */
464  VTUTF8ChannelAssertCursor(Channel);
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 */
481  VTUTF8ChannelAssertCursor(Channel);
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 */
498  VTUTF8ChannelAssertCursor(Channel);
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 */
515  VTUTF8ChannelAssertCursor(Channel);
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 
550  case SacFontInverseOff:
551  /* Clear the appropriate flag */
552  Channel->CellFlags &= ~SAC_CELL_FLAG_INVERTED;
553  break;
554 
555  case SacEraseEndOfLine:
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 
567  case SacEraseStartOfLine:
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 
591  case SacEraseEndOfScreen:
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 
607  case SacSetScrollRegion:
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 
643 NTSTATUS
644 NTAPI
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 
675 NTSTATUS
676 NTAPI
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 
700 NTSTATUS
701 NTAPI
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 
712 NTSTATUS
713 NTAPI
715  IN PCHAR Buffer,
718 {
719  ASSERT(FALSE);
720  return STATUS_NOT_IMPLEMENTED;
721 }
722 
723 NTSTATUS
724 NTAPI
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 
915 Quickie:
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 
929 NTSTATUS
930 NTAPI
932  IN PWCHAR String,
933  IN ULONG Size)
934 {
936  ULONG i, EscapeSize, R, C;
937  PWSTR pwch;
938  CHECK_PARAMETER1(Channel);
940  VTUTF8ChannelAssertCursor(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 */
989  ASSERT((R + 1) < SAC_VTUTF8_ROW_HEIGHT);
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--;
1005  VTUTF8ChannelAssertCursor(Channel);
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 */
1013  VTUTF8ChannelAssertCursor(Channel);
1014  for (C = (4 - Channel->CursorCol % 4); C; C--)
1015  {
1016  /* Fill each remaining character with a space */
1017  VTUTF8ChannelAssertCursor(Channel);
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 */
1032  VTUTF8ChannelAssertCursor(Channel);
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--;
1041  VTUTF8ChannelAssertCursor(Channel);
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 */
1051  VTUTF8ChannelAssertCursor(Channel);
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 */
1065  VTUTF8ChannelAssertCursor(Channel);
1066  break;
1067  }
1068  }
1069 
1070  /* Parsing of the input string completed -- string was written */
1071  VTUTF8ChannelAssertCursor(Channel);
1072  return STATUS_SUCCESS;
1073 }
1074 
1075 NTSTATUS
1076 NTAPI
1078  IN PCHAR String,
1079  IN ULONG Size)
1080 {
1082  PWSTR pwch;
1083  ULONG i, k, TranslatedCount, UTF8TranslationSize;
1084  BOOLEAN Result;
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 
1159 Return:
1160  ASSERT(pwch == (PWSTR)(String + Size));
1161  if (NT_SUCCESS(Status)) Status = ConMgrFlushData(Channel);
1162  return Status;
1163 }
1164 
1165 NTSTATUS
1166 NTAPI
1168  IN PCHAR String,
1169  IN ULONG Length)
1170 {
1171  NTSTATUS Status;
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 */
1183  Status = VTUTF8ChannelOEcho(Channel, String, Length);
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 
1196 ULONG
1197 NTAPI
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 
1208 VOID
1209 NTAPI
1211  IN ULONG BufferIndex)
1212 {
1213  NTSTATUS Status;
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 
1232 NTSTATUS
1233 NTAPI
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 */
1251  ASSERT(ChannelHasNewIBufferData(Channel) == FALSE);
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 */
1269  VTUTF8ChannelGetIBufferIndex(Channel) - ReadLength);
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 */
1282  *ReturnBufferSize = ReadLength;
1283  }
1284 
1285  /* Return success */
1286  return STATUS_SUCCESS;
1287 }
1288 
1289 NTSTATUS
1290 NTAPI
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 
1301 ULONG
1302 NTAPI
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 
1311 WCHAR
1312 NTAPI
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 */
1324  VTUTF8ChannelGetIBufferIndex(Channel) -
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 
1337 NTSTATUS
1338 NTAPI
1340  IN PCHAR Buffer,
1342 {
1343  NTSTATUS Status;
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 }
signed char * PCHAR
Definition: retypes.h:7
ULONG NTAPI VTUTF8ChannelConsumeEscapeSequence(IN PSAC_CHANNEL Channel, IN PWCHAR String)
Definition: vtutf8chan.c:242
#define IN
Definition: typedefs.h:38
PCHAR Utf8ConversionBuffer
Definition: util.c:17
#define R(b, x)
Definition: sha2.c:134
#define C(name, bit)
Definition: cpu.h:208
BOOLEAN NTAPI ConMgrIsWriteEnabled(IN PSAC_CHANNEL Channel)
Definition: conmgr.c:155
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
ULONG Utf8ConversionBufferSize
Definition: util.c:18
ULONG NTAPI VTUTF8ChannelIBufferLength(IN PSAC_CHANNEL Channel)
Definition: vtutf8chan.c:1303
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define CHECK_ALLOCATION(x)
Definition: sacdrv.h:64
#define VT_ANSI_ERASE_DOWN_SCREEN
Definition: sacdrv.h:1504
enum _SAC_ANSI_DISPATCH SAC_ANSI_DISPATCH
struct _SAC_VTUTF8_SCREEN * PSAC_VTUTF8_SCREEN
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define VT_ANSI_HVP_CURSOR_CHAR
Definition: sacdrv.h:1513
NTSTATUS NTAPI VTUTF8ChannelIRead(IN PSAC_CHANNEL Channel, IN PCHAR Buffer, IN ULONG BufferSize, IN PULONG ReturnBufferSize)
Definition: vtutf8chan.c:1234
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
uint16_t * PWSTR
Definition: typedefs.h:54
long __cdecl _InterlockedExchange(_Interlocked_operand_ long volatile *_Target, long _Value)
VOID NTAPI VTUTF8ChannelSetIBufferIndex(IN PSAC_CHANNEL Channel, IN ULONG BufferIndex)
Definition: vtutf8chan.c:1210
static COORD Position
Definition: mouse.c:34
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
#define VT_ANSI_CURSOR_UP
Definition: sacdrv.h:1487
NTSTATUS NTAPI VTUTF8ChannelCreate(IN PSAC_CHANNEL Channel)
Definition: vtutf8chan.c:677
#define SAC_VTUTF8_ROW_HEIGHT
Definition: sacdrv.h:158
_In_ DWORD _In_ DWORD ReturnBufferSize
Definition: setupapi.h:1891
static WCHAR String[]
Definition: stringtable.c:55
uint16_t * PWCHAR
Definition: typedefs.h:54
#define VT_ANSI_SEPARATOR_CHAR
Definition: sacdrv.h:1512
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_LEFT
Definition: sacdrv.h:1496
BOOLEAN NTAPI SacTranslateUtf8ToUnicode(IN CHAR Utf8Char, IN PCHAR Utf8Buffer, OUT PWCHAR Utf8Value)
Definition: util.c:41
NTSTATUS NTAPI VTUTF8ChannelOWrite2(IN PSAC_CHANNEL Channel, IN PWCHAR String, IN ULONG Size)
Definition: vtutf8chan.c:931
int32_t INT
Definition: typedefs.h:56
WCHAR IncomingUnicodeValue
Definition: vtutf8chan.c:16
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define GLOBAL_BLOCK_TAG
Definition: sacdrv.h:141
NTSTATUS NTAPI ChannelDestroy(IN PSAC_CHANNEL Channel)
Definition: channel.c:77
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define VT_ANSI_ESCAPE
Definition: sacdrv.h:1483
#define VT_ANSI_ERASE_UP_SCREEN
Definition: sacdrv.h:1505
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
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define UNICODE_NULL
NTSTATUS NTAPI VTUTF8ChannelOFlush(IN PSAC_CHANNEL Channel)
Definition: vtutf8chan.c:725
NTSTATUS NTAPI VTUTF8ChannelOInit(IN PSAC_CHANNEL Channel)
Definition: vtutf8chan.c:645
WCHAR NTAPI VTUTF8ChannelIReadLast(IN PSAC_CHANNEL Channel)
Definition: vtutf8chan.c:1313
unsigned char BOOLEAN
#define VT_ANSI_COMMAND
Definition: sacdrv.h:1484
smooth NULL
Definition: ftsmooth.c:416
#define FORCEINLINE
Definition: ntbasedef.h:221
_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:426
Definition: bufpool.h:45
#define CHECK_PARAMETER(x)
Definition: sacdrv.h:54
#define SacAllocatePool(Length, Tag)
Definition: sacdrv.h:24
#define VT_ANSI_CURSOR_LEFT_CHAR
Definition: sacdrv.h:1495
Definition: sacdrv.h:1378
r l[0]
Definition: byte_order.h:167
#define SAC_VTUTF8_IBUFFER_SIZE
Definition: sacdrv.h:161
NTSTATUS NTAPI VTUTF8ChannelDestroy(IN PSAC_CHANNEL Channel)
Definition: vtutf8chan.c:702
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:636
NTSTATUS NTAPI VTUTF8ChannelIWrite(IN PSAC_CHANNEL Channel, IN PCHAR Buffer, IN ULONG BufferSize)
Definition: vtutf8chan.c:1339
#define VT_ANSI_CURSOR_DOWN
Definition: sacdrv.h:1490
NTSTATUS NTAPI ConMgrFlushData(IN PSAC_CHANNEL Channel)
Definition: conmgr.c:139
FORCEINLINE BOOLEAN ChannelHasNewIBufferData(IN PSAC_CHANNEL Channel)
Definition: sacdrv.h:1360
#define MAX_UTF8_ENCODE_BLOCK_LENGTH
Definition: sacdrv.h:159
#define ChannelSetEvent(Channel, x)
Definition: sacdrv.h:98
#define VT_ANSI_CURSOR_RIGHT_CHAR
Definition: sacdrv.h:1492
#define VT_ANSI_CUP_CURSOR_CHAR
Definition: sacdrv.h:1514
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT
Definition: sacdrv.h:170
#define VT_ANSI_ERASE_ENTIRE_SCREEN
Definition: sacdrv.h:1506
#define VT_220_BACKTAB
Definition: sacdrv.h:1509
_In_ PLIST_ENTRY _In_ PSTRING _In_ USHORT _In_opt_ PSTRING _In_opt_ PSTRING _In_ ULONG _In_ ULONG Action
Definition: fsrtlfuncs.h:738
#define VT_ANSI_CURSOR_RIGHT
Definition: sacdrv.h:1493
static const UCHAR Index[8]
Definition: usbohci.c:18
#define BufferSize
Definition: classpnp.h:419
#define SacFreePool(Pointer)
Definition: sacdrv.h:26
FORCEINLINE VOID VTUTF8ChannelAssertCursor(IN PSAC_CHANNEL Channel)
Definition: vtutf8chan.c:37
#define for
Definition: utility.h:88
#define VT_ANSI_CURSOR_UP_CHAR
Definition: sacdrv.h:1486
#define CHECK_PARAMETER1(x)
Definition: sacdrv.h:56
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_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)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
unsigned char UCHAR
Definition: xmlstorage.h:181
char * PBOOLEAN
Definition: retypes.h:11
static const WCHAR L[]
Definition: oid.c:1250
NTSTATUS NTAPI VTUTF8ChannelProcessAttributes(IN PSAC_CHANNEL Channel, IN UCHAR Attribute)
Definition: vtutf8chan.c:198
ULONG NTAPI VTUTF8ChannelGetIBufferIndex(IN PSAC_CHANNEL Channel)
Definition: vtutf8chan.c:1198
NTSTATUS NTAPI VTUTF8ChannelAnsiDispatch(IN PSAC_CHANNEL Channel, IN SAC_ANSI_DISPATCH AnsiCode, IN INT *Data, IN ULONG Length)
Definition: vtutf8chan.c:68
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define SAC_VTUTF8_COL_WIDTH
Definition: sacdrv.h:156
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:204
BOOLEAN NTAPI VTUTF8ChannelScanForNumber(IN PWCHAR String, OUT PULONG Number)
Definition: vtutf8chan.c:45
#define ChannelClearEvent(Channel, x)
Definition: sacdrv.h:113
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1060
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI ConMgrWriteData(IN PSAC_CHANNEL Channel, IN PVOID Buffer, IN ULONG BufferLength)
Definition: conmgr.c:111
NTSTATUS NTAPI VTUTF8ChannelORead(IN PSAC_CHANNEL Channel, IN PCHAR Buffer, IN ULONG BufferSize, OUT PULONG ByteCount)
Definition: vtutf8chan.c:714
#define VT_ANSI_SCROLL_CHAR
Definition: sacdrv.h:1515
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
SAC_STATIC_ESCAPE_STRING SacStaticEscapeStrings[]
Definition: vtutf8chan.c:18
#define CHECK_PARAMETER_WITH_STATUS(Condition, Status)
Definition: sacdrv.h:47
#define VT_ANSI_ERASE_ENTIRE_LINE
Definition: sacdrv.h:1501
Definition: ttei6.cpp:27
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
#define CHECK_PARAMETER2(x)
Definition: sacdrv.h:58
#define SAC_CELL_FLAG_BOLD
Definition: sacdrv.h:179
NTSTATUS NTAPI VTUTF8ChannelOWrite(IN PSAC_CHANNEL Channel, IN PCHAR String, IN ULONG Length)
Definition: vtutf8chan.c:1167
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
Definition: console.h:34
#define VT_ANSI_CURSOR_DOWN_CHAR
Definition: sacdrv.h:1489
#define SAC_VTUTF8_OBUFFER_SIZE
Definition: sacdrv.h:160
NTSTATUS NTAPI VTUTF8ChannelIBufferIsFull(IN PSAC_CHANNEL Channel, OUT PBOOLEAN BufferStatus)
Definition: vtutf8chan.c:1291
#define SAC_CELL_FLAG_BLINK
Definition: sacdrv.h:178
return STATUS_SUCCESS
Definition: btrfs.c:2725
#define SAC_CELL_FLAG_INVERTED
Definition: sacdrv.h:180
#define VT_ANSI_SET_ATTRIBUTE_CHAR
Definition: sacdrv.h:1511
NTSTATUS NTAPI VTUTF8ChannelOEcho(IN PSAC_CHANNEL Channel, IN PCHAR String, IN ULONG Size)
Definition: vtutf8chan.c:1077
int k
Definition: mpi.c:3369
#define VT_ANSI_ERASE_START_LINE
Definition: sacdrv.h:1500
#define VT_ANSI_ERASE_END_LINE
Definition: sacdrv.h:1499
#define VT_ANSI_ERASE_LINE_CHAR
Definition: sacdrv.h:1498
CHAR IncomingUtf8ConversionBuffer[4]
Definition: vtutf8chan.c:15