ReactOS 0.4.16-dev-122-g325d74c
conoutput.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Console Server DLL
4 * FILE: win32ss/user/winsrv/consrv/conoutput.c
5 * PURPOSE: General Console Output Functions
6 * PROGRAMMERS: Jeffrey Morlan
7 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
8 */
9
10/* INCLUDES *******************************************************************/
11
12#include "consrv.h"
13
14#define NDEBUG
15#include <debug.h>
16
17/* PUBLIC SERVER APIS *********************************************************/
18
19/*
20 * FIXME: This function MUST be moved from condrv/conoutput.c because only
21 * consrv knows how to manipulate VDM screenbuffers.
22 */
26 IN PCHAR_CELL CharInfo/*Buffer*/,
27 IN COORD CharInfoSize,
28 IN PSMALL_RECT WriteRegion);
33/* API_NUMBER: ConsolepInvalidateBitMapRect */
34CON_API(SrvInvalidateBitMapRect,
35 CONSOLE_INVALIDATEDIBITS, InvalidateDIBitsRequest)
36{
39
40 Status = ConSrvGetScreenBuffer(ProcessData,
41 InvalidateDIBitsRequest->OutputHandle,
43 if (!NT_SUCCESS(Status))
44 return Status;
45
46 ASSERT((PCONSOLE)Console == Buffer->Header.Console);
47
48 /* In text-mode only, draw the VDM buffer if present */
49 if (GetType(Buffer) == TEXTMODE_BUFFER && Console->VDMBuffer)
50 {
52
55 Console->VDMBuffer,
56 Console->VDMBufferSize,
57 &InvalidateDIBitsRequest->Region);
58 }
59
61 Buffer,
62 &InvalidateDIBitsRequest->Region);
63
65 return Status;
66}
67
70 // IN PGRAPHICS_SCREEN_BUFFER Buffer,
72 IN HPALETTE PaletteHandle,
73 IN UINT PaletteUsage);
74/* API_NUMBER: ConsolepSetPalette */
75CON_API(SrvSetConsolePalette,
76 CONSOLE_SETPALETTE, SetPaletteRequest)
77{
79 // PGRAPHICS_SCREEN_BUFFER Buffer;
81
82 // NOTE: Tests show that this function is used only for graphics screen buffers
83 // and otherwise it returns FALSE + sets last error to invalid handle.
84 // I think it's ridiculous, because if you are in text mode, simulating
85 // a change of VGA palette via DAC registers (done by a call to SetConsolePalette)
86 // cannot be done... So I allow it in ReactOS !
87 /*
88 Status = ConSrvGetGraphicsBuffer(ProcessData,
89 SetPaletteRequest->OutputHandle,
90 &Buffer, GENERIC_WRITE, TRUE);
91 */
92 Status = ConSrvGetScreenBuffer(ProcessData,
93 SetPaletteRequest->OutputHandle,
95 if (!NT_SUCCESS(Status))
96 return Status;
97
98 ASSERT((PCONSOLE)Console == Buffer->Header.Console);
99
100 /*
101 * Make the palette handle public, so that it can be
102 * used by other threads calling GDI functions on it.
103 * Indeed, the palette handle comes from a console app
104 * calling ourselves, running in CSRSS.
105 */
107 &SetPaletteRequest->PaletteHandle,
108 sizeof(SetPaletteRequest->PaletteHandle));
109
111 Buffer,
112 SetPaletteRequest->PaletteHandle,
113 SetPaletteRequest->Usage);
114
116 return Status;
117}
118
122 OUT PCONSOLE_CURSOR_INFO CursorInfo);
123/* API_NUMBER: ConsolepGetCursorInfo */
124CON_API(SrvGetConsoleCursorInfo,
125 CONSOLE_GETSETCURSORINFO, CursorInfoRequest)
126{
129
130 Status = ConSrvGetTextModeBuffer(ProcessData,
131 CursorInfoRequest->OutputHandle,
133 if (!NT_SUCCESS(Status))
134 return Status;
135
136 ASSERT((PCONSOLE)Console == Buffer->Header.Console);
137
139 Buffer,
140 &CursorInfoRequest->Info);
141
143 return Status;
144}
145
149 IN PCONSOLE_CURSOR_INFO CursorInfo);
150/* API_NUMBER: ConsolepSetCursorInfo */
151CON_API(SrvSetConsoleCursorInfo,
152 CONSOLE_GETSETCURSORINFO, CursorInfoRequest)
153{
156
157 Status = ConSrvGetTextModeBuffer(ProcessData,
158 CursorInfoRequest->OutputHandle,
160 if (!NT_SUCCESS(Status))
161 return Status;
162
163 ASSERT((PCONSOLE)Console == Buffer->Header.Console);
164
166 Buffer,
167 &CursorInfoRequest->Info);
168
170 return Status;
171}
172
177/* API_NUMBER: ConsolepSetCursorPosition */
178CON_API(SrvSetConsoleCursorPosition,
179 CONSOLE_SETCURSORPOSITION, SetCursorPositionRequest)
180{
183
184 Status = ConSrvGetTextModeBuffer(ProcessData,
185 SetCursorPositionRequest->OutputHandle,
187 if (!NT_SUCCESS(Status))
188 return Status;
189
190 ASSERT((PCONSOLE)Console == Buffer->Header.Console);
191
193 Buffer,
194 &SetCursorPositionRequest->Position);
195
197 return Status;
198}
199
200/* API_NUMBER: ConsolepCreateScreenBuffer */
201CON_API(SrvCreateConsoleScreenBuffer,
202 CONSOLE_CREATESCREENBUFFER, CreateScreenBufferRequest)
203{
206 // PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(Process);
208
210 TEXTMODE_BUFFER_INFO TextModeInfo = {{80, 25},
211 {80, 25},
214 TRUE,
216 GRAPHICS_BUFFER_INFO GraphicsInfo;
217 GraphicsInfo.Info = CreateScreenBufferRequest->GraphicsBufferInfo; // HACK for MSVC
218
219 if (CreateScreenBufferRequest->ScreenBufferType == CONSOLE_TEXTMODE_BUFFER)
220 {
221 ScreenBufferInfo = &TextModeInfo;
222
223 /*
224 * This is Windows behaviour, as described by MSDN and verified manually:
225 *
226 * The newly created screen buffer will copy some properties from the
227 * active screen buffer at the time that this function is called.
228 * The behavior is as follows:
229 * Font - copied from active screen buffer.
230 * Display Window Size - copied from active screen buffer.
231 * Buffer Size - matched to Display Window Size (NOT copied).
232 * Default Attributes (colors) - copied from active screen buffer.
233 * Default Popup Attributes (colors) - copied from active screen buffer.
234 */
235
236 /* If we have an active screen buffer, use its attributes as the new ones */
237 if (Console->ActiveBuffer && GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER)
238 {
240
241 TextModeInfo.ScreenAttrib = Buffer->ScreenDefaultAttrib;
242 TextModeInfo.PopupAttrib = Buffer->PopupDefaultAttrib;
243
244 TextModeInfo.CursorSize = Buffer->CursorInfo.dwSize;
245 TextModeInfo.IsCursorVisible = Buffer->CursorInfo.bVisible;
246
247 /* Use the current view size */
248 TextModeInfo.ScreenBufferSize = Buffer->ViewSize;
249 TextModeInfo.ViewSize = Buffer->ViewSize;
250 }
251 else
252 {
253 /* Use the current console size */
254 TextModeInfo.ScreenBufferSize = Console->ConsoleSize;
255 TextModeInfo.ViewSize = Console->ConsoleSize;
256 }
257
258 /* Normalize the screen buffer size if needed */
259 if (TextModeInfo.ScreenBufferSize.X == 0) TextModeInfo.ScreenBufferSize.X = 1;
260 if (TextModeInfo.ScreenBufferSize.Y == 0) TextModeInfo.ScreenBufferSize.Y = 1;
261 }
262 else if (CreateScreenBufferRequest->ScreenBufferType == CONSOLE_GRAPHICS_BUFFER)
263 {
264 /* Get information from the graphics buffer information structure */
265 if (!CsrValidateMessageBuffer(ApiMessage,
266 (PVOID*)&CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMapInfo,
267 CreateScreenBufferRequest->GraphicsBufferInfo.dwBitMapInfoLength,
268 sizeof(BYTE)))
269 {
271 }
272
273 ScreenBufferInfo = &GraphicsInfo;
274
275 /* Initialize shared variables */
276 // CreateScreenBufferRequest->GraphicsBufferInfo.hMutex
277 CreateScreenBufferRequest->hMutex = GraphicsInfo.Info.hMutex = INVALID_HANDLE_VALUE;
278 // CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap
279 CreateScreenBufferRequest->lpBitMap = GraphicsInfo.Info.lpBitMap = NULL;
280
281 /* A graphics screen buffer is never inheritable */
282 CreateScreenBufferRequest->InheritHandle = FALSE;
283 }
284 else
285 {
286 DPRINT1("Invalid ScreenBuffer type %lu\n", CreateScreenBufferRequest->ScreenBufferType);
288 }
289
292 Process->ProcessHandle,
293 CreateScreenBufferRequest->ScreenBufferType,
295 if (!NT_SUCCESS(Status))
296 return Status;
297
298 /* Insert the new handle inside the process handles table */
299 RtlEnterCriticalSection(&ProcessData->HandleTableLock);
300
301 Status = ConSrvInsertObject(ProcessData,
302 &CreateScreenBufferRequest->OutputHandle,
303 &Buff->Header,
304 CreateScreenBufferRequest->DesiredAccess,
305 CreateScreenBufferRequest->InheritHandle,
306 CreateScreenBufferRequest->ShareMode);
307
308 RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
309
310 if (!NT_SUCCESS(Status))
311 {
313 return Status;
314 }
315
316 if (CreateScreenBufferRequest->ScreenBufferType == CONSOLE_GRAPHICS_BUFFER)
317 {
319 /*
320 * Initialize the graphics buffer information structure
321 * and give it back to the client.
322 */
323 // CreateScreenBufferRequest->GraphicsBufferInfo.hMutex
324 CreateScreenBufferRequest->hMutex = Buffer->ClientMutex;
325 // CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap
326 CreateScreenBufferRequest->lpBitMap = Buffer->ClientBitMap;
327 }
328
329 return Status;
330}
331
335/* API_NUMBER: ConsolepSetActiveScreenBuffer */
336CON_API(SrvSetConsoleActiveScreenBuffer,
337 CONSOLE_SETACTIVESCREENBUFFER, SetScreenBufferRequest)
338{
341
342 Status = ConSrvGetScreenBuffer(ProcessData,
343 SetScreenBufferRequest->OutputHandle,
345 if (!NT_SUCCESS(Status))
346 return Status;
347
348 ASSERT((PCONSOLE)Console == Buffer->Header.Console);
349
351
353 return Status;
354}
355
356
357/* CSR THREADS FOR WriteConsole ***********************************************/
358
359static NTSTATUS
362 IN BOOLEAN CreateWaitBlock OPTIONAL);
363
364// Wait function CSR_WAIT_FUNCTION
365static BOOLEAN
366NTAPI
368 IN PCSR_THREAD WaitThread,
369 IN PCSR_API_MESSAGE WaitApiMessage,
370 IN PVOID WaitContext,
371 IN PVOID WaitArgument1,
372 IN PVOID WaitArgument2,
373 IN ULONG WaitFlags)
374{
376
377 DPRINT("WriteConsoleThread - WaitContext = 0x%p, WaitArgument1 = 0x%p, WaitArgument2 = 0x%p, WaitFlags = %lu\n", WaitContext, WaitArgument1, WaitArgument2, WaitFlags);
378
379 /*
380 * If we are notified of the process termination via a call
381 * to CsrNotifyWaitBlock triggered by CsrDestroyProcess or
382 * CsrDestroyThread, just return.
383 */
384 if (WaitFlags & CsrProcessTerminating)
385 {
387 goto Quit;
388 }
389
390 Status = DoWriteConsole(WaitApiMessage, WaitThread, FALSE);
391
392Quit:
393 if (Status != STATUS_PENDING)
394 {
395 WaitApiMessage->Status = Status;
396 }
397
398 return (Status == STATUS_PENDING ? FALSE : TRUE);
399}
400
404 IN BOOLEAN Unicode,
406 IN ULONG NumCharsToWrite,
407 OUT PULONG NumCharsWritten OPTIONAL);
408static NTSTATUS
411 IN BOOLEAN CreateWaitBlock OPTIONAL)
412{
414 PCONSOLE_WRITECONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest;
416
418 ULONG NrCharactersWritten = 0;
419 ULONG CharSize = (WriteConsoleRequest->Unicode ? sizeof(WCHAR) : sizeof(CHAR));
420
422 WriteConsoleRequest->OutputHandle,
424 if (!NT_SUCCESS(Status)) return Status;
425
426 /*
427 * For optimization purposes, Windows (and hence ReactOS, too, for
428 * compatibility reasons) uses a static buffer if no more than eighty
429 * bytes are written. Otherwise a new buffer is used.
430 * The client-side expects that we know this behaviour.
431 */
432 if (WriteConsoleRequest->UsingStaticBuffer &&
433 WriteConsoleRequest->NumBytes <= sizeof(WriteConsoleRequest->StaticBuffer))
434 {
435 /*
436 * Adjust the internal pointer, because its old value points to
437 * the static buffer in the original ApiMessage structure.
438 */
439 // WriteConsoleRequest->Buffer = WriteConsoleRequest->StaticBuffer;
440 Buffer = WriteConsoleRequest->StaticBuffer;
441 }
442 else
443 {
444 Buffer = WriteConsoleRequest->Buffer;
445 }
446
447 DPRINT("Calling ConDrvWriteConsole\n");
448 Status = ConDrvWriteConsole(ScreenBuffer->Header.Console,
450 WriteConsoleRequest->Unicode,
451 Buffer,
452 WriteConsoleRequest->NumBytes / CharSize, // NrCharactersToWrite
453 &NrCharactersWritten);
454 DPRINT("ConDrvWriteConsole returned (%d ; Status = 0x%08x)\n",
455 NrCharactersWritten, Status);
456
457 if (Status == STATUS_PENDING)
458 {
459 if (CreateWaitBlock)
460 {
462
463 if (!CsrCreateWait(&Console->WriteWaitQueue,
466 ApiMessage,
467 NULL))
468 {
469 /* Fail */
471 goto Quit;
472 }
473 }
474
475 /* Wait until we un-pause the console */
476 // Status = STATUS_PENDING;
477 }
478 else
479 {
480 /* We read all what we wanted. Set the number of bytes written. */
481 WriteConsoleRequest->NumBytes = NrCharactersWritten * CharSize;
482 }
483
484Quit:
486 return Status;
487}
488
489
490/* TEXT OUTPUT APIS ***********************************************************/
491
495 IN BOOLEAN Unicode,
496 OUT PCHAR_INFO CharInfo/*Buffer*/,
497 IN OUT PSMALL_RECT ReadRegion);
498/* API_NUMBER: ConsolepReadConsoleOutput */
499CON_API(SrvReadConsoleOutput,
500 CONSOLE_READOUTPUT, ReadOutputRequest)
501{
504 ULONG NumCells;
505 PCHAR_INFO CharInfo;
506
507 NumCells = ConioRectWidth(&ReadOutputRequest->ReadRegion) *
508 ConioRectHeight(&ReadOutputRequest->ReadRegion);
509
510 /*
511 * For optimization purposes, Windows (and hence ReactOS, too, for
512 * compatibility reasons) uses a static buffer if no more than one
513 * cell is read. Otherwise a new buffer is used.
514 * The client-side expects that we know this behaviour.
515 */
516 if (NumCells <= 1)
517 {
518 /*
519 * Adjust the internal pointer, because its old value points to
520 * the static buffer in the original ApiMessage structure.
521 */
522 // ReadOutputRequest->CharInfo = &ReadOutputRequest->StaticBuffer;
523 CharInfo = &ReadOutputRequest->StaticBuffer;
524 }
525 else
526 {
527 if (!CsrValidateMessageBuffer(ApiMessage,
528 (PVOID*)&ReadOutputRequest->CharInfo,
529 NumCells,
530 sizeof(CHAR_INFO)))
531 {
533 }
534
535 CharInfo = ReadOutputRequest->CharInfo;
536 }
537
538 Status = ConSrvGetTextModeBuffer(ProcessData,
539 ReadOutputRequest->OutputHandle,
541 if (!NT_SUCCESS(Status))
542 return Status;
543
544 ASSERT((PCONSOLE)Console == Buffer->Header.Console);
545
547 Buffer,
548 ReadOutputRequest->Unicode,
549 CharInfo,
550 &ReadOutputRequest->ReadRegion);
551
553 return Status;
554}
555
559 IN BOOLEAN Unicode,
560 IN PCHAR_INFO CharInfo/*Buffer*/,
561 IN OUT PSMALL_RECT WriteRegion);
562/* API_NUMBER: ConsolepWriteConsoleOutput */
563CON_API(SrvWriteConsoleOutput,
564 CONSOLE_WRITEOUTPUT, WriteOutputRequest)
565{
568 // PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(Process);
570 ULONG NumCells;
571 PCHAR_INFO CharInfo;
572
573 NumCells = ConioRectWidth(&WriteOutputRequest->WriteRegion) *
574 ConioRectHeight(&WriteOutputRequest->WriteRegion);
575
576 Status = ConSrvGetTextModeBuffer(ProcessData,
577 WriteOutputRequest->OutputHandle,
579 if (!NT_SUCCESS(Status))
580 return Status;
581
582 ASSERT((PCONSOLE)Console == Buffer->Header.Console);
583
584 /*
585 * Validate the message buffer if we do not use a process' heap buffer
586 * (CsrAllocateCaptureBuffer succeeded because we haven't allocated
587 * a too large (>= 64 kB, size of the CSR heap) data buffer).
588 */
589 if (!WriteOutputRequest->UseVirtualMemory)
590 {
591 /*
592 * For optimization purposes, Windows (and hence ReactOS, too, for
593 * compatibility reasons) uses a static buffer if no more than one
594 * cell is written. Otherwise a new buffer is used.
595 * The client-side expects that we know this behaviour.
596 */
597 if (NumCells <= 1)
598 {
599 /*
600 * Adjust the internal pointer, because its old value points to
601 * the static buffer in the original ApiMessage structure.
602 */
603 // WriteOutputRequest->CharInfo = &WriteOutputRequest->StaticBuffer;
604 CharInfo = &WriteOutputRequest->StaticBuffer;
605 }
606 else
607 {
608 if (!CsrValidateMessageBuffer(ApiMessage,
609 (PVOID*)&WriteOutputRequest->CharInfo,
610 NumCells,
611 sizeof(CHAR_INFO)))
612 {
614 goto Quit;
615 }
616
617 CharInfo = WriteOutputRequest->CharInfo;
618 }
619 }
620 else
621 {
622 /*
623 * This was not the case: we use a heap buffer. Retrieve its contents.
624 */
625 ULONG Size = NumCells * sizeof(CHAR_INFO);
626
628 if (CharInfo == NULL)
629 {
631 goto Quit;
632 }
633
634 Status = NtReadVirtualMemory(Process->ProcessHandle,
635 WriteOutputRequest->CharInfo,
636 CharInfo,
637 Size,
638 NULL);
639 if (!NT_SUCCESS(Status))
640 {
641 ConsoleFreeHeap(CharInfo);
642 // Status = STATUS_NO_MEMORY;
643 goto Quit;
644 }
645 }
646
648 Buffer,
649 WriteOutputRequest->Unicode,
650 CharInfo,
651 &WriteOutputRequest->WriteRegion);
652
653 /* Free the temporary buffer if we used the process' heap buffer */
654 if (WriteOutputRequest->UseVirtualMemory && CharInfo)
655 ConsoleFreeHeap(CharInfo);
656
657Quit:
659 return Status;
660}
661
662/* API_NUMBER: ConsolepWriteConsole */
663CON_API(SrvWriteConsole,
664 CONSOLE_WRITECONSOLE, WriteConsoleRequest)
665{
667
668 DPRINT("SrvWriteConsole\n");
669
670 /*
671 * For optimization purposes, Windows (and hence ReactOS, too, for
672 * compatibility reasons) uses a static buffer if no more than eighty
673 * bytes are written. Otherwise a new buffer is used.
674 * The client-side expects that we know this behaviour.
675 */
676 if (WriteConsoleRequest->UsingStaticBuffer &&
677 WriteConsoleRequest->NumBytes <= sizeof(WriteConsoleRequest->StaticBuffer))
678 {
679 /*
680 * Adjust the internal pointer, because its old value points to
681 * the static buffer in the original ApiMessage structure.
682 */
683 // WriteConsoleRequest->Buffer = WriteConsoleRequest->StaticBuffer;
684 }
685 else
686 {
687 if (!CsrValidateMessageBuffer(ApiMessage,
688 (PVOID)&WriteConsoleRequest->Buffer,
689 WriteConsoleRequest->NumBytes,
690 sizeof(BYTE)))
691 {
693 }
694 }
695
697
698 if (Status == STATUS_PENDING) *ReplyCode = CsrReplyPending;
699
700 return Status;
701}
702
706 IN CODE_TYPE CodeType,
708 IN ULONG NumCodesToRead,
709 IN PCOORD ReadCoord,
710 // OUT PCOORD EndCoord,
711 OUT PULONG NumCodesRead OPTIONAL);
712/* API_NUMBER: ConsolepReadConsoleOutputString */
713CON_API(SrvReadConsoleOutputString,
714 CONSOLE_READOUTPUTCODE, ReadOutputCodeRequest)
715{
718 ULONG CodeSize;
719 PVOID pCode;
720
721 switch (ReadOutputCodeRequest->CodeType)
722 {
723 case CODE_ASCII:
724 CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
725 break;
726
727 case CODE_UNICODE:
728 CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
729 break;
730
731 case CODE_ATTRIBUTE:
732 CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
733 break;
734
735 default:
737 }
738
739 /*
740 * For optimization purposes, Windows (and hence ReactOS, too, for
741 * compatibility reasons) uses a static buffer if no more than eighty
742 * bytes are read. Otherwise a new buffer is used.
743 * The client-side expects that we know this behaviour.
744 */
745 if (ReadOutputCodeRequest->NumCodes * CodeSize <= sizeof(ReadOutputCodeRequest->CodeStaticBuffer))
746 {
747 /*
748 * Adjust the internal pointer, because its old value points to
749 * the static buffer in the original ApiMessage structure.
750 */
751 // ReadOutputCodeRequest->pCode = ReadOutputCodeRequest->CodeStaticBuffer;
752 pCode = ReadOutputCodeRequest->CodeStaticBuffer;
753 }
754 else
755 {
756 if (!CsrValidateMessageBuffer(ApiMessage,
757 (PVOID*)&ReadOutputCodeRequest->pCode,
758 ReadOutputCodeRequest->NumCodes,
759 CodeSize))
760 {
762 }
763
764 pCode = ReadOutputCodeRequest->pCode;
765 }
766
767 Status = ConSrvGetTextModeBuffer(ProcessData,
768 ReadOutputCodeRequest->OutputHandle,
770 if (!NT_SUCCESS(Status))
771 {
772 ReadOutputCodeRequest->NumCodes = 0;
773 return Status;
774 }
775
776 ASSERT((PCONSOLE)Console == Buffer->Header.Console);
777
779 Buffer,
780 ReadOutputCodeRequest->CodeType,
781 pCode,
782 ReadOutputCodeRequest->NumCodes,
783 &ReadOutputCodeRequest->Coord,
784 // &ReadOutputCodeRequest->EndCoord,
785 &ReadOutputCodeRequest->NumCodes);
786
788 return Status;
789}
790
794 IN CODE_TYPE CodeType,
796 IN ULONG NumCodesToWrite,
797 IN PCOORD WriteCoord,
798 // OUT PCOORD EndCoord,
799 OUT PULONG NumCodesWritten OPTIONAL);
800/* API_NUMBER: ConsolepWriteConsoleOutputString */
801CON_API(SrvWriteConsoleOutputString,
802 CONSOLE_WRITEOUTPUTCODE, WriteOutputCodeRequest)
803{
806 ULONG CodeSize;
807 PVOID pCode;
808
809 switch (WriteOutputCodeRequest->CodeType)
810 {
811 case CODE_ASCII:
812 CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
813 break;
814
815 case CODE_UNICODE:
816 CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
817 break;
818
819 case CODE_ATTRIBUTE:
820 CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
821 break;
822
823 default:
825 }
826
827 /*
828 * For optimization purposes, Windows (and hence ReactOS, too, for
829 * compatibility reasons) uses a static buffer if no more than eighty
830 * bytes are written. Otherwise a new buffer is used.
831 * The client-side expects that we know this behaviour.
832 */
833 if (WriteOutputCodeRequest->NumCodes * CodeSize <= sizeof(WriteOutputCodeRequest->CodeStaticBuffer))
834 {
835 /*
836 * Adjust the internal pointer, because its old value points to
837 * the static buffer in the original ApiMessage structure.
838 */
839 // WriteOutputCodeRequest->pCode = WriteOutputCodeRequest->CodeStaticBuffer;
840 pCode = WriteOutputCodeRequest->CodeStaticBuffer;
841 }
842 else
843 {
844 if (!CsrValidateMessageBuffer(ApiMessage,
845 (PVOID*)&WriteOutputCodeRequest->pCode,
846 WriteOutputCodeRequest->NumCodes,
847 CodeSize))
848 {
850 }
851
852 pCode = WriteOutputCodeRequest->pCode;
853 }
854
855 Status = ConSrvGetTextModeBuffer(ProcessData,
856 WriteOutputCodeRequest->OutputHandle,
858 if (!NT_SUCCESS(Status))
859 {
860 WriteOutputCodeRequest->NumCodes = 0;
861 return Status;
862 }
863
864 ASSERT((PCONSOLE)Console == Buffer->Header.Console);
865
867 Buffer,
868 WriteOutputCodeRequest->CodeType,
869 pCode,
870 WriteOutputCodeRequest->NumCodes,
871 &WriteOutputCodeRequest->Coord,
872 // &WriteOutputCodeRequest->EndCoord,
873 &WriteOutputCodeRequest->NumCodes);
874
876 return Status;
877}
878
882 IN CODE_TYPE CodeType,
884 IN ULONG NumCodesToWrite,
885 IN PCOORD WriteCoord,
886 OUT PULONG NumCodesWritten OPTIONAL);
887/* API_NUMBER: ConsolepFillConsoleOutput */
888CON_API(SrvFillConsoleOutput,
889 CONSOLE_FILLOUTPUTCODE, FillOutputRequest)
890{
893 CODE_TYPE CodeType = FillOutputRequest->CodeType;
894
895 if ( (CodeType != CODE_ASCII ) &&
896 (CodeType != CODE_UNICODE ) &&
897 (CodeType != CODE_ATTRIBUTE) )
898 {
900 }
901
902 Status = ConSrvGetTextModeBuffer(ProcessData,
903 FillOutputRequest->OutputHandle,
905 if (!NT_SUCCESS(Status))
906 {
907 FillOutputRequest->NumCodes = 0;
908 return Status;
909 }
910
911 ASSERT((PCONSOLE)Console == Buffer->Header.Console);
912
914 Buffer,
915 CodeType,
916 FillOutputRequest->Code,
917 FillOutputRequest->NumCodes,
918 &FillOutputRequest->WriteCoord,
919 &FillOutputRequest->NumCodes);
920
922 return Status;
923}
924
928 OUT PCOORD ScreenBufferSize,
930 OUT PCOORD ViewOrigin,
932 OUT PCOORD MaximumViewSize,
934/* API_NUMBER: ConsolepGetScreenBufferInfo */
935CON_API(SrvGetConsoleScreenBufferInfo,
936 CONSOLE_GETSCREENBUFFERINFO, ScreenBufferInfoRequest)
937{
940
941 Status = ConSrvGetTextModeBuffer(ProcessData,
942 ScreenBufferInfoRequest->OutputHandle,
944 if (!NT_SUCCESS(Status))
945 return Status;
946
947 ASSERT((PCONSOLE)Console == Buffer->Header.Console);
948
950 Buffer,
951 &ScreenBufferInfoRequest->ScreenBufferSize,
952 &ScreenBufferInfoRequest->CursorPosition,
953 &ScreenBufferInfoRequest->ViewOrigin,
954 &ScreenBufferInfoRequest->ViewSize,
955 &ScreenBufferInfoRequest->MaximumViewSize,
956 &ScreenBufferInfoRequest->Attributes);
957
959 return Status;
960}
961
966/* API_NUMBER: ConsolepSetTextAttribute */
967CON_API(SrvSetConsoleTextAttribute,
968 CONSOLE_SETTEXTATTRIB, SetTextAttribRequest)
969{
972
973 Status = ConSrvGetTextModeBuffer(ProcessData,
974 SetTextAttribRequest->OutputHandle,
976 if (!NT_SUCCESS(Status))
977 return Status;
978
979 ASSERT((PCONSOLE)Console == Buffer->Header.Console);
980
982 Buffer,
983 SetTextAttribRequest->Attributes);
984
986 return Status;
987}
988
992 IN PCOORD Size);
993/* API_NUMBER: ConsolepSetScreenBufferSize */
994CON_API(SrvSetConsoleScreenBufferSize,
995 CONSOLE_SETSCREENBUFFERSIZE, SetScreenBufferSizeRequest)
996{
999
1000 Status = ConSrvGetTextModeBuffer(ProcessData,
1001 SetScreenBufferSizeRequest->OutputHandle,
1003 if (!NT_SUCCESS(Status))
1004 return Status;
1005
1006 ASSERT((PCONSOLE)Console == Buffer->Header.Console);
1007
1009 Buffer,
1010 &SetScreenBufferSizeRequest->Size);
1011
1013 return Status;
1014}
1015
1019 IN BOOLEAN Unicode,
1020 IN PSMALL_RECT ScrollRectangle,
1021 IN BOOLEAN UseClipRectangle,
1022 IN PSMALL_RECT ClipRectangle OPTIONAL,
1023 IN PCOORD DestinationOrigin,
1024 IN CHAR_INFO FillChar);
1025/* API_NUMBER: ConsolepScrollScreenBuffer */
1026CON_API(SrvScrollConsoleScreenBuffer,
1027 CONSOLE_SCROLLSCREENBUFFER, ScrollScreenBufferRequest)
1028{
1031
1032 Status = ConSrvGetTextModeBuffer(ProcessData,
1033 ScrollScreenBufferRequest->OutputHandle,
1035 if (!NT_SUCCESS(Status))
1036 return Status;
1037
1038 ASSERT((PCONSOLE)Console == Buffer->Header.Console);
1039
1041 Buffer,
1042 ScrollScreenBufferRequest->Unicode,
1043 &ScrollScreenBufferRequest->ScrollRectangle,
1044 ScrollScreenBufferRequest->UseClipRectangle,
1045 &ScrollScreenBufferRequest->ClipRectangle,
1046 &ScrollScreenBufferRequest->DestinationOrigin,
1047 ScrollScreenBufferRequest->Fill);
1048
1050 return Status;
1051}
1052
1056 IN BOOLEAN Absolute,
1057 IN PSMALL_RECT WindowRect);
1058/* API_NUMBER: ConsolepSetWindowInfo */
1059CON_API(SrvSetConsoleWindowInfo,
1060 CONSOLE_SETWINDOWINFO, SetWindowInfoRequest)
1061{
1063 // PCONSOLE_SCREEN_BUFFER Buffer;
1065
1066 DPRINT("SrvSetConsoleWindowInfo(0x%08x, %d, {L%d, T%d, R%d, B%d}) called\n",
1067 SetWindowInfoRequest->OutputHandle, SetWindowInfoRequest->Absolute,
1068 SetWindowInfoRequest->WindowRect.Left ,
1069 SetWindowInfoRequest->WindowRect.Top ,
1070 SetWindowInfoRequest->WindowRect.Right,
1071 SetWindowInfoRequest->WindowRect.Bottom);
1072
1073 // ConSrvGetScreenBuffer
1074 Status = ConSrvGetTextModeBuffer(ProcessData,
1075 SetWindowInfoRequest->OutputHandle,
1077 if (!NT_SUCCESS(Status))
1078 return Status;
1079
1080 ASSERT((PCONSOLE)Console == Buffer->Header.Console);
1081
1083 Buffer,
1084 SetWindowInfoRequest->Absolute,
1085 &SetWindowInfoRequest->WindowRect);
1086
1088 return Status;
1089}
1090
1091/* EOF */
UINT CALLBACK ClientThread(_Inout_ PVOID Parameter)
unsigned char BOOLEAN
CConsole Console
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
Definition: bufpool.h:45
char TextBuffer[BUFFERLEN]
Definition: combotst.c:45
NTSTATUS NTAPI ConDrvGetConsoleCursorInfo(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, OUT PCONSOLE_CURSOR_INFO CursorInfo)
Definition: conoutput.c:270
NTSTATUS NTAPI ConDrvSetConsoleCursorPosition(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, IN PCOORD Position)
Definition: conoutput.c:318
VOID NTAPI ConDrvDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer)
Definition: conoutput.c:130
NTSTATUS NTAPI ConDrvSetConsoleCursorInfo(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, IN PCONSOLE_CURSOR_INFO CursorInfo)
Definition: conoutput.c:288
NTSTATUS NTAPI ConDrvSetConsolePalette(IN PCONSOLE Console, IN PCONSOLE_SCREEN_BUFFER Buffer, IN HPALETTE PaletteHandle, IN UINT PaletteUsage)
Definition: conoutput.c:226
NTSTATUS NTAPI ConDrvSetConsoleActiveScreenBuffer(IN PCONSOLE Console, IN PCONSOLE_SCREEN_BUFFER Buffer)
Definition: conoutput.c:177
NTSTATUS ConDrvCreateScreenBuffer(OUT PCONSOLE_SCREEN_BUFFER *Buffer, IN PCONSOLE Console, IN HANDLE ProcessHandle OPTIONAL, IN ULONG BufferType, IN PVOID ScreenBufferInfo)
Definition: conoutput.c:85
NTSTATUS NTAPI ConDrvInvalidateBitMapRect(IN PCONSOLE Console, IN PCONSOLE_SCREEN_BUFFER Buffer, IN PSMALL_RECT Region)
Definition: conoutput.c:209
struct _CONSRV_CONSOLE * PCONSRV_CONSOLE
struct _CONSOLE_API_MESSAGE * PCONSOLE_API_MESSAGE
@ CODE_ASCII
Definition: conmsg.h:517
@ CODE_UNICODE
Definition: conmsg.h:518
@ CODE_ATTRIBUTE
Definition: conmsg.h:519
enum _CODE_TYPE CODE_TYPE
NTSTATUS NTAPI ConDrvReadConsoleOutput(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, IN BOOLEAN Unicode, OUT PCHAR_INFO CharInfo, IN OUT PSMALL_RECT ReadRegion)
Definition: text.c:569
NTSTATUS NTAPI ConDrvGetConsoleScreenBufferInfo(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, OUT PCOORD ScreenBufferSize, OUT PCOORD CursorPosition, OUT PCOORD ViewOrigin, OUT PCOORD ViewSize, OUT PCOORD MaximumViewSize, OUT PWORD Attributes)
Definition: text.c:1380
NTSTATUS NTAPI ConDrvSetConsoleWindowInfo(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, IN BOOLEAN Absolute, IN PSMALL_RECT WindowRect)
Definition: text.c:1579
NTSTATUS NTAPI ConDrvWriteConsoleOutput(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, IN BOOLEAN Unicode, IN PCHAR_INFO CharInfo, IN OUT PSMALL_RECT WriteRegion)
Definition: text.c:638
NTSTATUS NTAPI ConDrvSetConsoleTextAttribute(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, IN WORD Attributes)
Definition: text.c:1420
static NTSTATUS DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage, IN PCSR_THREAD ClientThread, IN BOOLEAN CreateWaitBlock OPTIONAL)
Definition: conoutput.c:409
NTSTATUS NTAPI ConDrvScrollConsoleScreenBuffer(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, IN BOOLEAN Unicode, IN PSMALL_RECT ScrollRectangle, IN BOOLEAN UseClipRectangle, IN PSMALL_RECT ClipRectangle OPTIONAL, IN PCOORD DestinationOrigin, IN CHAR_INFO FillChar)
Definition: text.c:1454
NTSTATUS NTAPI ConDrvWriteConsoleOutputString(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, IN CODE_TYPE CodeType, IN PVOID StringBuffer, IN ULONG NumCodesToWrite, IN PCOORD WriteCoord, OUT PULONG NumCodesWritten OPTIONAL)
Definition: text.c:1161
NTSTATUS NTAPI ConDrvWriteConsole(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER ScreenBuffer, IN BOOLEAN Unicode, IN PVOID StringBuffer, IN ULONG NumCharsToWrite, OUT PULONG NumCharsWritten OPTIONAL)
Definition: text.c:763
NTSTATUS NTAPI ConDrvWriteConsoleOutputVDM(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, IN PCHAR_CELL CharInfo, IN COORD CharInfoSize, IN PSMALL_RECT WriteRegion)
Definition: text.c:708
NTSTATUS NTAPI ConDrvFillConsoleOutput(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, IN CODE_TYPE CodeType, IN CODE_ELEMENT Code, IN ULONG NumCodesToWrite, IN PCOORD WriteCoord, OUT PULONG NumCodesWritten OPTIONAL)
Definition: text.c:1251
NTSTATUS NTAPI ConDrvSetConsoleScreenBufferSize(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, IN PCOORD Size)
Definition: text.c:1435
NTSTATUS NTAPI ConDrvReadConsoleOutputString(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, IN CODE_TYPE CodeType, OUT PVOID StringBuffer, IN ULONG NumCodesToRead, IN PCOORD ReadCoord, OUT PULONG NumCodesRead OPTIONAL)
Definition: text.c:942
static BOOLEAN NTAPI WriteConsoleThread(IN PLIST_ENTRY WaitList, IN PCSR_THREAD WaitThread, IN PCSR_API_MESSAGE WaitApiMessage, IN PVOID WaitContext, IN PVOID WaitArgument1, IN PVOID WaitArgument2, IN ULONG WaitFlags)
Definition: conoutput.c:367
#define ConSrvGetTextModeBuffer(ProcessData, Handle, Ptr, Access, LockConsole)
Definition: conoutput.h:12
#define ConSrvGetScreenBuffer(ProcessData, Handle, Ptr, Access, LockConsole)
Definition: conoutput.h:26
#define ConSrvReleaseScreenBuffer(Buff, IsConsoleLocked)
Definition: conoutput.h:33
#define ConsoleGetPerProcessData(Process)
Definition: consrv.h:37
BOOLEAN NTAPI CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage, IN PVOID *Buffer, IN ULONG ElementCount, IN ULONG ElementSize)
Definition: api.c:1430
#define CsrGetClientThread()
Definition: csrsrv.h:77
@ CsrProcessTerminating
Definition: csrsrv.h:85
@ CsrReplyPending
Definition: csrsrv.h:132
BOOLEAN NTAPI CsrCreateWait(IN PLIST_ENTRY WaitList, IN CSR_WAIT_FUNCTION WaitFunction, IN PCSR_THREAD CsrWaitThread, IN OUT PCSR_API_MESSAGE WaitApiMessage, IN PVOID WaitContext)
Definition: wait.c:209
#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:33
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GENERIC_READ
Definition: compat.h:135
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define ConioRectWidth(Rect)
Definition: readwrite.c:24
#define ConioRectHeight(Rect)
Definition: readwrite.c:22
unsigned short WORD
Definition: ntddk_ex.h:93
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
Status
Definition: gdiplustypes.h:25
@ ConsoleMakePalettePublic
Definition: ntuser.h:1800
NTSTATUS APIENTRY NtUserConsoleControl(IN CONSOLECONTROL ConsoleCtrl, IN PVOID ConsoleCtrlInfo, IN ULONG ConsoleCtrlInfoLength)
Definition: console.c:14
#define RTL_FIELD_SIZE(type, field)
Definition: kdb_expr.c:86
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
unsigned int UINT
Definition: ndis.h:50
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:408
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
CONSOLE_SCREEN_BUFFER_INFO ScreenBufferInfo
Definition: notevil.c:38
HANDLE ScreenBuffer
Definition: notevil.c:37
#define GENERIC_WRITE
Definition: nt_native.h:90
NTSTATUS NTAPI NtReadVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, OUT PVOID Buffer, IN SIZE_T NumberOfBytesToRead, OUT PSIZE_T NumberOfBytesRead OPTIONAL)
Definition: virtual.c:2816
#define STATUS_THREAD_IS_TERMINATING
Definition: ntstatus.h:311
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
static USHORT CursorPosition
Definition: pc98cons.c:20
#define TEXTMODE_BUFFER
Definition: pccons.c:21
WORD * PWORD
Definition: pedump.c:67
#define DPRINT
Definition: sndvol32.h:73
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
CONSOLE_IO_OBJECT Header
Definition: conio.h:58
CHAR StaticBuffer[80]
Definition: conmsg.h:239
BOOLEAN UsingStaticBuffer
Definition: conmsg.h:246
Definition: bl.h:1338
ULONG Y
Definition: bl.h:1340
ULONG X
Definition: bl.h:1339
CONSOLE_GRAPHICS_BUFFER_INFO Info
Definition: conio.h:142
Definition: typedefs.h:120
BOOLEAN IsCursorVisible
Definition: conio.h:121
USHORT PopupAttrib
Definition: conio.h:119
COORD ScreenBufferSize
Definition: conio.h:116
USHORT ScreenAttrib
Definition: conio.h:118
static COORD Position
Definition: mouse.c:34
static HPALETTE PaletteHandle
Definition: svga.c:215
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_In_ UCHAR _In_ UCHAR _In_ ULONG Code
Definition: wdfdevice.h:1701
#define DEFAULT_SCREEN_ATTRIB
Definition: settings.c:29
#define CSR_DEFAULT_CURSOR_SIZE
Definition: settings.c:26
#define DEFAULT_POPUP_ATTRIB
Definition: settings.c:30
#define CON_API(Name, TYPE, RequestName)
Definition: api.h:80
NTSTATUS ConSrvInsertObject(IN PCONSOLE_PROCESS_DATA ProcessData, OUT PHANDLE Handle, IN PCONSOLE_IO_OBJECT Object, IN ULONG Access, IN BOOLEAN Inheritable, IN ULONG ShareMode)
Definition: handle.c:227
#define ConsoleAllocHeap(Flags, Size)
Definition: heap.h:14
#define ConsoleFreeHeap(HeapBase)
Definition: heap.h:15
struct _TEXTMODE_SCREEN_BUFFER * PTEXTMODE_SCREEN_BUFFER
struct _GRAPHICS_SCREEN_BUFFER * PGRAPHICS_SCREEN_BUFFER
#define GetType(This)
Definition: conio.h:54
struct _CHAR_INFO CHAR_INFO
#define CONSOLE_TEXTMODE_BUFFER
Definition: wincon.h:62
#define CONSOLE_GRAPHICS_BUFFER
Definition: wincon.h:63
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193