9265958ae1169348608337358df889c0f589060a
[reactos.git] / reactos / win32ss / user / winsrv / consrv / conoutput.c
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 #include "console.h"
14 #include "include/conio.h"
15 #include "include/term.h"
16 #include "conoutput.h"
17 #include "handle.h"
18
19 #define NDEBUG
20 #include <debug.h>
21
22
23 /* PRIVATE FUNCTIONS **********************************************************/
24
25
26 /* PUBLIC SERVER APIS *********************************************************/
27
28 NTSTATUS NTAPI
29 ConDrvInvalidateBitMapRect(IN PCONSOLE Console,
30 IN PCONSOLE_SCREEN_BUFFER Buffer,
31 IN PSMALL_RECT Region);
32 CSR_API(SrvInvalidateBitMapRect)
33 {
34 NTSTATUS Status;
35 PCONSOLE_INVALIDATEDIBITS InvalidateDIBitsRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.InvalidateDIBitsRequest;
36 PCONSOLE_SCREEN_BUFFER Buffer;
37
38 DPRINT("SrvInvalidateBitMapRect\n");
39
40 Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
41 InvalidateDIBitsRequest->OutputHandle,
42 &Buffer, GENERIC_READ, TRUE);
43 if (!NT_SUCCESS(Status)) return Status;
44
45 Status = ConDrvInvalidateBitMapRect(Buffer->Header.Console,
46 Buffer,
47 &InvalidateDIBitsRequest->Region);
48
49 ConSrvReleaseScreenBuffer(Buffer, TRUE);
50 return Status;
51 }
52
53 NTSTATUS NTAPI
54 ConDrvSetConsolePalette(IN PCONSOLE Console,
55 // IN PGRAPHICS_SCREEN_BUFFER Buffer,
56 IN PCONSOLE_SCREEN_BUFFER Buffer,
57 IN HPALETTE PaletteHandle,
58 IN UINT PaletteUsage);
59 CSR_API(SrvSetConsolePalette)
60 {
61 NTSTATUS Status;
62 PCONSOLE_SETPALETTE SetPaletteRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetPaletteRequest;
63 // PGRAPHICS_SCREEN_BUFFER Buffer;
64 PCONSOLE_SCREEN_BUFFER Buffer;
65
66 DPRINT1("SrvSetConsolePalette\n");
67
68 // NOTE: Tests show that this function is used only for graphics screen buffers
69 // and otherwise it returns FALSE + sets last error to invalid handle.
70 // I think it's ridiculous, because if you are in text mode, simulating
71 // a change of VGA palette via DAC registers (done by a call to SetConsolePalette)
72 // cannot be done... So I allow it in ReactOS !
73 /*
74 Status = ConSrvGetGraphicsBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
75 SetPaletteRequest->OutputHandle,
76 &Buffer, GENERIC_WRITE, TRUE);
77 */
78 Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
79 SetPaletteRequest->OutputHandle,
80 &Buffer, GENERIC_WRITE, TRUE);
81 if (!NT_SUCCESS(Status)) return Status;
82
83 DPRINT1("ConDrvSetConsolePalette calling...\n");
84
85 Status = ConDrvSetConsolePalette(Buffer->Header.Console,
86 Buffer,
87 SetPaletteRequest->PaletteHandle,
88 SetPaletteRequest->Usage);
89
90 DPRINT1("ConDrvSetConsolePalette returned Status 0x%08lx\n", Status);
91
92 ConSrvReleaseScreenBuffer(Buffer, TRUE);
93 return Status;
94 }
95
96 NTSTATUS NTAPI
97 ConDrvGetConsoleCursorInfo(IN PCONSOLE Console,
98 IN PTEXTMODE_SCREEN_BUFFER Buffer,
99 OUT PCONSOLE_CURSOR_INFO CursorInfo);
100 CSR_API(SrvGetConsoleCursorInfo)
101 {
102 NTSTATUS Status;
103 PCONSOLE_GETSETCURSORINFO CursorInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.CursorInfoRequest;
104 PTEXTMODE_SCREEN_BUFFER Buffer;
105
106 DPRINT("SrvGetConsoleCursorInfo\n");
107
108 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
109 CursorInfoRequest->OutputHandle,
110 &Buffer, GENERIC_READ, TRUE);
111 if (!NT_SUCCESS(Status)) return Status;
112
113 Status = ConDrvGetConsoleCursorInfo(Buffer->Header.Console,
114 Buffer,
115 &CursorInfoRequest->Info);
116
117 ConSrvReleaseScreenBuffer(Buffer, TRUE);
118 return Status;
119 }
120
121 NTSTATUS NTAPI
122 ConDrvSetConsoleCursorInfo(IN PCONSOLE Console,
123 IN PTEXTMODE_SCREEN_BUFFER Buffer,
124 IN PCONSOLE_CURSOR_INFO CursorInfo);
125 CSR_API(SrvSetConsoleCursorInfo)
126 {
127 NTSTATUS Status;
128 PCONSOLE_GETSETCURSORINFO CursorInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.CursorInfoRequest;
129 PTEXTMODE_SCREEN_BUFFER Buffer;
130
131 DPRINT("SrvSetConsoleCursorInfo\n");
132
133 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
134 CursorInfoRequest->OutputHandle,
135 &Buffer, GENERIC_WRITE, TRUE);
136 if (!NT_SUCCESS(Status)) return Status;
137
138 Status = ConDrvSetConsoleCursorInfo(Buffer->Header.Console,
139 Buffer,
140 &CursorInfoRequest->Info);
141
142 ConSrvReleaseScreenBuffer(Buffer, TRUE);
143 return Status;
144 }
145
146 NTSTATUS NTAPI
147 ConDrvSetConsoleCursorPosition(IN PCONSOLE Console,
148 IN PTEXTMODE_SCREEN_BUFFER Buffer,
149 IN PCOORD Position);
150 CSR_API(SrvSetConsoleCursorPosition)
151 {
152 NTSTATUS Status;
153 PCONSOLE_SETCURSORPOSITION SetCursorPositionRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetCursorPositionRequest;
154 PTEXTMODE_SCREEN_BUFFER Buffer;
155
156 DPRINT("SrvSetConsoleCursorPosition\n");
157
158 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
159 SetCursorPositionRequest->OutputHandle,
160 &Buffer, GENERIC_WRITE, TRUE);
161 if (!NT_SUCCESS(Status)) return Status;
162
163 Status = ConDrvSetConsoleCursorPosition(Buffer->Header.Console,
164 Buffer,
165 &SetCursorPositionRequest->Position);
166
167 ConSrvReleaseScreenBuffer(Buffer, TRUE);
168 return Status;
169 }
170
171 CSR_API(SrvCreateConsoleScreenBuffer)
172 {
173 NTSTATUS Status = STATUS_INVALID_PARAMETER;
174 PCONSOLE_CREATESCREENBUFFER CreateScreenBufferRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.CreateScreenBufferRequest;
175 PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
176 PCONSOLE Console;
177 PCONSOLE_SCREEN_BUFFER Buff;
178
179 PVOID ScreenBufferInfo = NULL;
180 TEXTMODE_BUFFER_INFO TextModeInfo = {{80, 25},
181 DEFAULT_SCREEN_ATTRIB,
182 DEFAULT_POPUP_ATTRIB ,
183 TRUE,
184 CSR_DEFAULT_CURSOR_SIZE};
185 GRAPHICS_BUFFER_INFO GraphicsInfo;
186 GraphicsInfo.Info = CreateScreenBufferRequest->GraphicsBufferInfo; // HACK for MSVC
187
188 DPRINT("SrvCreateConsoleScreenBuffer\n");
189
190 Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
191 if (!NT_SUCCESS(Status)) return Status;
192
193 if (CreateScreenBufferRequest->ScreenBufferType == CONSOLE_TEXTMODE_BUFFER)
194 {
195 ScreenBufferInfo = &TextModeInfo;
196
197 /*
198 if (Console->ActiveBuffer)
199 {
200 TextModeInfo.ScreenBufferSize = Console->ActiveBuffer->ScreenBufferSize;
201 if (TextModeInfo.ScreenBufferSize.X == 0) TextModeInfo.ScreenBufferSize.X = 80;
202 if (TextModeInfo.ScreenBufferSize.Y == 0) TextModeInfo.ScreenBufferSize.Y = 25;
203
204 TextModeInfo.ScreenAttrib = Console->ActiveBuffer->ScreenBuffer.TextBuffer.ScreenDefaultAttrib;
205 TextModeInfo.PopupAttrib = Console->ActiveBuffer->ScreenBuffer.TextBuffer.PopupDefaultAttrib;
206
207 TextModeInfo.IsCursorVisible = Console->ActiveBuffer->CursorInfo.bVisible;
208 TextModeInfo.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize;
209 }
210 */
211
212 /*
213 * This is Windows' behaviour
214 */
215
216 /* Use the current console size. Regularize it if needed. */
217 TextModeInfo.ScreenBufferSize = Console->ConsoleSize;
218 if (TextModeInfo.ScreenBufferSize.X == 0) TextModeInfo.ScreenBufferSize.X = 1;
219 if (TextModeInfo.ScreenBufferSize.Y == 0) TextModeInfo.ScreenBufferSize.Y = 1;
220
221 /* If we have an active screen buffer, use its attributes as the new ones */
222 if (Console->ActiveBuffer && GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER)
223 {
224 PTEXTMODE_SCREEN_BUFFER Buffer = (PTEXTMODE_SCREEN_BUFFER)Console->ActiveBuffer;
225
226 TextModeInfo.ScreenAttrib = Buffer->ScreenDefaultAttrib;
227 TextModeInfo.PopupAttrib = Buffer->PopupDefaultAttrib;
228
229 TextModeInfo.IsCursorVisible = Buffer->CursorInfo.bVisible;
230 TextModeInfo.CursorSize = Buffer->CursorInfo.dwSize;
231 }
232 }
233 else if (CreateScreenBufferRequest->ScreenBufferType == CONSOLE_GRAPHICS_BUFFER)
234 {
235 /* Get infos from the graphics buffer information structure */
236 if (!CsrValidateMessageBuffer(ApiMessage,
237 (PVOID*)&CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMapInfo,
238 1,
239 CreateScreenBufferRequest->GraphicsBufferInfo.dwBitMapInfoLength))
240 {
241 Status = STATUS_INVALID_PARAMETER;
242 goto Quit;
243 }
244
245 ScreenBufferInfo = &GraphicsInfo;
246
247 /* Initialize shared variables */
248 CreateScreenBufferRequest->GraphicsBufferInfo.hMutex = GraphicsInfo.Info.hMutex = INVALID_HANDLE_VALUE;
249 CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap = GraphicsInfo.Info.lpBitMap = NULL;
250
251 /* A graphics screen buffer is never inheritable */
252 CreateScreenBufferRequest->Inheritable = FALSE;
253 }
254
255 Status = ConDrvCreateScreenBuffer(&Buff,
256 Console,
257 CreateScreenBufferRequest->ScreenBufferType,
258 ScreenBufferInfo);
259 if (!NT_SUCCESS(Status)) goto Quit;
260
261 /* Insert the new handle inside the process handles table */
262 RtlEnterCriticalSection(&ProcessData->HandleTableLock);
263
264 Status = ConSrvInsertObject(ProcessData,
265 &CreateScreenBufferRequest->OutputHandle,
266 &Buff->Header,
267 CreateScreenBufferRequest->Access,
268 CreateScreenBufferRequest->Inheritable,
269 CreateScreenBufferRequest->ShareMode);
270
271 RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
272
273 if (!NT_SUCCESS(Status)) goto Quit;
274
275 if (CreateScreenBufferRequest->ScreenBufferType == CONSOLE_GRAPHICS_BUFFER)
276 {
277 PGRAPHICS_SCREEN_BUFFER Buffer = (PGRAPHICS_SCREEN_BUFFER)Buff;
278 /*
279 * Initialize the graphics buffer information structure
280 * and give it back to the client.
281 */
282 CreateScreenBufferRequest->GraphicsBufferInfo.hMutex = Buffer->ClientMutex;
283 CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap = Buffer->ClientBitMap;
284 }
285
286 Quit:
287 ConSrvReleaseConsole(Console, TRUE);
288 return Status;
289 }
290
291 NTSTATUS NTAPI
292 ConDrvSetConsoleActiveScreenBuffer(IN PCONSOLE Console,
293 IN PCONSOLE_SCREEN_BUFFER Buffer);
294 CSR_API(SrvSetConsoleActiveScreenBuffer)
295 {
296 NTSTATUS Status;
297 PCONSOLE_SETACTIVESCREENBUFFER SetScreenBufferRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetScreenBufferRequest;
298 PCONSOLE_SCREEN_BUFFER Buffer;
299
300 DPRINT("SrvSetConsoleActiveScreenBuffer\n");
301
302 Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
303 SetScreenBufferRequest->OutputHandle,
304 &Buffer, GENERIC_WRITE, TRUE);
305 if (!NT_SUCCESS(Status)) return Status;
306
307 Status = ConDrvSetConsoleActiveScreenBuffer(Buffer->Header.Console,
308 Buffer);
309
310 ConSrvReleaseScreenBuffer(Buffer, TRUE);
311 return Status;
312 }
313
314
315 /* CSR THREADS FOR WriteConsole ***********************************************/
316
317 static NTSTATUS
318 DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage,
319 IN PCSR_THREAD ClientThread,
320 IN BOOL CreateWaitBlock OPTIONAL);
321
322 // Wait function CSR_WAIT_FUNCTION
323 static BOOLEAN
324 NTAPI
325 WriteConsoleThread(IN PLIST_ENTRY WaitList,
326 IN PCSR_THREAD WaitThread,
327 IN PCSR_API_MESSAGE WaitApiMessage,
328 IN PVOID WaitContext,
329 IN PVOID WaitArgument1,
330 IN PVOID WaitArgument2,
331 IN ULONG WaitFlags)
332 {
333 NTSTATUS Status;
334
335 DPRINT("WriteConsoleThread - WaitContext = 0x%p, WaitArgument1 = 0x%p, WaitArgument2 = 0x%p, WaitFlags = %lu\n", WaitContext, WaitArgument1, WaitArgument2, WaitFlags);
336
337 /*
338 * If we are notified of the process termination via a call
339 * to CsrNotifyWaitBlock triggered by CsrDestroyProcess or
340 * CsrDestroyThread, just return.
341 */
342 if (WaitFlags & CsrProcessTerminating)
343 {
344 Status = STATUS_THREAD_IS_TERMINATING;
345 goto Quit;
346 }
347
348 Status = DoWriteConsole(WaitApiMessage,
349 WaitThread,
350 FALSE);
351
352 Quit:
353 if (Status != STATUS_PENDING)
354 {
355 WaitApiMessage->Status = Status;
356 }
357
358 return (Status == STATUS_PENDING ? FALSE : TRUE);
359 }
360
361 NTSTATUS NTAPI
362 ConDrvWriteConsole(IN PCONSOLE Console,
363 IN PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
364 IN BOOLEAN Unicode,
365 IN PVOID StringBuffer,
366 IN ULONG NumCharsToWrite,
367 OUT PULONG NumCharsWritten OPTIONAL);
368 static NTSTATUS
369 DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage,
370 IN PCSR_THREAD ClientThread,
371 IN BOOL CreateWaitBlock OPTIONAL)
372 {
373 NTSTATUS Status;
374 PCONSOLE_WRITECONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest;
375 PTEXTMODE_SCREEN_BUFFER ScreenBuffer;
376
377 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(ClientThread->Process),
378 WriteConsoleRequest->OutputHandle,
379 &ScreenBuffer, GENERIC_WRITE, FALSE);
380 if (!NT_SUCCESS(Status)) return Status;
381
382 Status = ConDrvWriteConsole(ScreenBuffer->Header.Console,
383 ScreenBuffer,
384 WriteConsoleRequest->Unicode,
385 WriteConsoleRequest->Buffer,
386 WriteConsoleRequest->NrCharactersToWrite,
387 &WriteConsoleRequest->NrCharactersWritten);
388
389 if (Status == STATUS_PENDING)
390 {
391 if (CreateWaitBlock)
392 {
393 if (!CsrCreateWait(&ScreenBuffer->Header.Console->WriteWaitQueue,
394 WriteConsoleThread,
395 ClientThread,
396 ApiMessage,
397 NULL))
398 {
399 /* Fail */
400 Status = STATUS_NO_MEMORY;
401 goto Quit;
402 }
403 }
404
405 /* Wait until we un-pause the console */
406 // Status = STATUS_PENDING;
407 }
408
409 Quit:
410 ConSrvReleaseScreenBuffer(ScreenBuffer, FALSE);
411 return Status;
412 }
413
414
415 /* TEXT OUTPUT APIS ***********************************************************/
416
417 NTSTATUS NTAPI
418 ConDrvReadConsoleOutput(IN PCONSOLE Console,
419 IN PTEXTMODE_SCREEN_BUFFER Buffer,
420 IN BOOLEAN Unicode,
421 OUT PCHAR_INFO CharInfo/*Buffer*/,
422 IN PCOORD BufferSize,
423 IN PCOORD BufferCoord,
424 IN OUT PSMALL_RECT ReadRegion);
425 CSR_API(SrvReadConsoleOutput)
426 {
427 NTSTATUS Status;
428 PCONSOLE_READOUTPUT ReadOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadOutputRequest;
429 PTEXTMODE_SCREEN_BUFFER Buffer;
430
431 DPRINT("SrvReadConsoleOutput\n");
432
433 if (!CsrValidateMessageBuffer(ApiMessage,
434 (PVOID*)&ReadOutputRequest->CharInfo,
435 ReadOutputRequest->BufferSize.X * ReadOutputRequest->BufferSize.Y,
436 sizeof(CHAR_INFO)))
437 {
438 return STATUS_INVALID_PARAMETER;
439 }
440
441 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
442 ReadOutputRequest->OutputHandle,
443 &Buffer, GENERIC_READ, TRUE);
444 if (!NT_SUCCESS(Status)) return Status;
445
446 Status = ConDrvReadConsoleOutput(Buffer->Header.Console,
447 Buffer,
448 ReadOutputRequest->Unicode,
449 ReadOutputRequest->CharInfo,
450 &ReadOutputRequest->BufferSize,
451 &ReadOutputRequest->BufferCoord,
452 &ReadOutputRequest->ReadRegion);
453
454 ConSrvReleaseScreenBuffer(Buffer, TRUE);
455 return Status;
456 }
457
458 NTSTATUS NTAPI
459 ConDrvWriteConsoleOutput(IN PCONSOLE Console,
460 IN PTEXTMODE_SCREEN_BUFFER Buffer,
461 IN BOOLEAN Unicode,
462 IN PCHAR_INFO CharInfo/*Buffer*/,
463 IN PCOORD BufferSize,
464 IN PCOORD BufferCoord,
465 IN OUT PSMALL_RECT WriteRegion);
466 CSR_API(SrvWriteConsoleOutput)
467 {
468 NTSTATUS Status;
469 PCONSOLE_WRITEOUTPUT WriteOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputRequest;
470 PTEXTMODE_SCREEN_BUFFER Buffer;
471
472 DPRINT("SrvWriteConsoleOutput\n");
473
474 if (!CsrValidateMessageBuffer(ApiMessage,
475 (PVOID*)&WriteOutputRequest->CharInfo,
476 WriteOutputRequest->BufferSize.X * WriteOutputRequest->BufferSize.Y,
477 sizeof(CHAR_INFO)))
478 {
479 return STATUS_INVALID_PARAMETER;
480 }
481
482 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
483 WriteOutputRequest->OutputHandle,
484 &Buffer, GENERIC_WRITE, TRUE);
485 if (!NT_SUCCESS(Status)) return Status;
486
487 Status = ConDrvWriteConsoleOutput(Buffer->Header.Console,
488 Buffer,
489 WriteOutputRequest->Unicode,
490 WriteOutputRequest->CharInfo,
491 &WriteOutputRequest->BufferSize,
492 &WriteOutputRequest->BufferCoord,
493 &WriteOutputRequest->WriteRegion);
494
495 ConSrvReleaseScreenBuffer(Buffer, TRUE);
496 return Status;
497 }
498
499 CSR_API(SrvWriteConsole)
500 {
501 NTSTATUS Status;
502 PCONSOLE_WRITECONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest;
503
504 DPRINT("SrvWriteConsole\n");
505
506 if (!CsrValidateMessageBuffer(ApiMessage,
507 (PVOID)&WriteConsoleRequest->Buffer,
508 WriteConsoleRequest->BufferSize,
509 sizeof(BYTE)))
510 {
511 return STATUS_INVALID_PARAMETER;
512 }
513
514 Status = DoWriteConsole(ApiMessage,
515 CsrGetClientThread(),
516 TRUE);
517
518 if (Status == STATUS_PENDING) *ReplyCode = CsrReplyPending;
519
520 return Status;
521 }
522
523 NTSTATUS NTAPI
524 ConDrvReadConsoleOutputString(IN PCONSOLE Console,
525 IN PTEXTMODE_SCREEN_BUFFER Buffer,
526 IN CODE_TYPE CodeType,
527 OUT PVOID StringBuffer,
528 IN ULONG NumCodesToRead,
529 IN PCOORD ReadCoord,
530 OUT PCOORD EndCoord,
531 OUT PULONG CodesRead);
532 CSR_API(SrvReadConsoleOutputString)
533 {
534 NTSTATUS Status;
535 PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadOutputCodeRequest;
536 PTEXTMODE_SCREEN_BUFFER Buffer;
537 ULONG CodeSize;
538
539 DPRINT("SrvReadConsoleOutputString\n");
540
541 switch (ReadOutputCodeRequest->CodeType)
542 {
543 case CODE_ASCII:
544 CodeSize = sizeof(CHAR);
545 break;
546
547 case CODE_UNICODE:
548 CodeSize = sizeof(WCHAR);
549 break;
550
551 case CODE_ATTRIBUTE:
552 CodeSize = sizeof(WORD);
553 break;
554
555 default:
556 return STATUS_INVALID_PARAMETER;
557 }
558
559 if (!CsrValidateMessageBuffer(ApiMessage,
560 (PVOID*)&ReadOutputCodeRequest->pCode.pCode,
561 ReadOutputCodeRequest->NumCodesToRead,
562 CodeSize))
563 {
564 return STATUS_INVALID_PARAMETER;
565 }
566
567 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
568 ReadOutputCodeRequest->OutputHandle,
569 &Buffer, GENERIC_READ, TRUE);
570 if (!NT_SUCCESS(Status)) return Status;
571
572 Status = ConDrvReadConsoleOutputString(Buffer->Header.Console,
573 Buffer,
574 ReadOutputCodeRequest->CodeType,
575 ReadOutputCodeRequest->pCode.pCode,
576 ReadOutputCodeRequest->NumCodesToRead,
577 &ReadOutputCodeRequest->ReadCoord,
578 &ReadOutputCodeRequest->EndCoord,
579 &ReadOutputCodeRequest->CodesRead);
580
581 ConSrvReleaseScreenBuffer(Buffer, TRUE);
582 return Status;
583 }
584
585 NTSTATUS NTAPI
586 ConDrvWriteConsoleOutputString(IN PCONSOLE Console,
587 IN PTEXTMODE_SCREEN_BUFFER Buffer,
588 IN CODE_TYPE CodeType,
589 IN PVOID StringBuffer,
590 IN ULONG NumCodesToWrite,
591 IN PCOORD WriteCoord /*,
592 OUT PCOORD EndCoord,
593 OUT PULONG CodesWritten */);
594 CSR_API(SrvWriteConsoleOutputString)
595 {
596 NTSTATUS Status;
597 PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputCodeRequest;
598 PTEXTMODE_SCREEN_BUFFER Buffer;
599 ULONG CodeSize;
600
601 DPRINT("SrvWriteConsoleOutputString\n");
602
603 switch (WriteOutputCodeRequest->CodeType)
604 {
605 case CODE_ASCII:
606 CodeSize = sizeof(CHAR);
607 break;
608
609 case CODE_UNICODE:
610 CodeSize = sizeof(WCHAR);
611 break;
612
613 case CODE_ATTRIBUTE:
614 CodeSize = sizeof(WORD);
615 break;
616
617 default:
618 return STATUS_INVALID_PARAMETER;
619 }
620
621 if (!CsrValidateMessageBuffer(ApiMessage,
622 (PVOID*)&WriteOutputCodeRequest->pCode.pCode,
623 WriteOutputCodeRequest->Length,
624 CodeSize))
625 {
626 return STATUS_INVALID_PARAMETER;
627 }
628
629 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
630 WriteOutputCodeRequest->OutputHandle,
631 &Buffer, GENERIC_WRITE, TRUE);
632 if (!NT_SUCCESS(Status)) return Status;
633
634 Status = ConDrvWriteConsoleOutputString(Buffer->Header.Console,
635 Buffer,
636 WriteOutputCodeRequest->CodeType,
637 WriteOutputCodeRequest->pCode.pCode,
638 WriteOutputCodeRequest->Length, // NumCodesToWrite,
639 &WriteOutputCodeRequest->Coord /*, // WriteCoord,
640 &WriteOutputCodeRequest->EndCoord,
641 &WriteOutputCodeRequest->NrCharactersWritten */);
642
643 // WriteOutputCodeRequest->NrCharactersWritten = Written;
644
645 ConSrvReleaseScreenBuffer(Buffer, TRUE);
646 return Status;
647 }
648
649 NTSTATUS NTAPI
650 ConDrvFillConsoleOutput(IN PCONSOLE Console,
651 IN PTEXTMODE_SCREEN_BUFFER Buffer,
652 IN CODE_TYPE CodeType,
653 IN PVOID Code,
654 IN ULONG NumCodesToWrite,
655 IN PCOORD WriteCoord /*,
656 OUT PULONG CodesWritten */);
657 CSR_API(SrvFillConsoleOutput)
658 {
659 NTSTATUS Status;
660 PCONSOLE_FILLOUTPUTCODE FillOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.FillOutputRequest;
661 PTEXTMODE_SCREEN_BUFFER Buffer;
662 USHORT CodeType = FillOutputRequest->CodeType;
663
664 DPRINT("SrvFillConsoleOutput\n");
665
666 if ( (CodeType != CODE_ASCII ) &&
667 (CodeType != CODE_UNICODE ) &&
668 (CodeType != CODE_ATTRIBUTE) )
669 {
670 return STATUS_INVALID_PARAMETER;
671 }
672
673 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
674 FillOutputRequest->OutputHandle,
675 &Buffer, GENERIC_WRITE, TRUE);
676 if (!NT_SUCCESS(Status)) return Status;
677
678 Status = ConDrvFillConsoleOutput(Buffer->Header.Console,
679 Buffer,
680 CodeType,
681 &FillOutputRequest->Code,
682 FillOutputRequest->Length, // NumCodesToWrite,
683 &FillOutputRequest->Coord /*, // WriteCoord,
684 &FillOutputRequest->NrCharactersWritten */);
685
686 // FillOutputRequest->NrCharactersWritten = Written;
687
688 ConSrvReleaseScreenBuffer(Buffer, TRUE);
689 return Status;
690 }
691
692 NTSTATUS NTAPI
693 ConDrvGetConsoleScreenBufferInfo(IN PCONSOLE Console,
694 IN PTEXTMODE_SCREEN_BUFFER Buffer,
695 OUT PCONSOLE_SCREEN_BUFFER_INFO ScreenBufferInfo);
696 CSR_API(SrvGetConsoleScreenBufferInfo)
697 {
698 NTSTATUS Status;
699 PCONSOLE_GETSCREENBUFFERINFO ScreenBufferInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ScreenBufferInfoRequest;
700 PTEXTMODE_SCREEN_BUFFER Buffer;
701
702 DPRINT("SrvGetConsoleScreenBufferInfo\n");
703
704 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
705 ScreenBufferInfoRequest->OutputHandle,
706 &Buffer, GENERIC_READ, TRUE);
707 if (!NT_SUCCESS(Status)) return Status;
708
709 Status = ConDrvGetConsoleScreenBufferInfo(Buffer->Header.Console,
710 Buffer,
711 &ScreenBufferInfoRequest->Info);
712
713 ConSrvReleaseScreenBuffer(Buffer, TRUE);
714 return Status;
715 }
716
717 NTSTATUS NTAPI
718 ConDrvSetConsoleTextAttribute(IN PCONSOLE Console,
719 IN PTEXTMODE_SCREEN_BUFFER Buffer,
720 IN WORD Attribute);
721 CSR_API(SrvSetConsoleTextAttribute)
722 {
723 NTSTATUS Status;
724 PCONSOLE_SETTEXTATTRIB SetTextAttribRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetTextAttribRequest;
725 PTEXTMODE_SCREEN_BUFFER Buffer;
726
727 DPRINT("SrvSetConsoleTextAttribute\n");
728
729 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
730 SetTextAttribRequest->OutputHandle,
731 &Buffer, GENERIC_WRITE, TRUE);
732 if (!NT_SUCCESS(Status)) return Status;
733
734 Status = ConDrvSetConsoleTextAttribute(Buffer->Header.Console,
735 Buffer,
736 SetTextAttribRequest->Attrib);
737
738 ConSrvReleaseScreenBuffer(Buffer, TRUE);
739 return Status;
740 }
741
742 NTSTATUS NTAPI
743 ConDrvSetConsoleScreenBufferSize(IN PCONSOLE Console,
744 IN PTEXTMODE_SCREEN_BUFFER Buffer,
745 IN PCOORD Size);
746 CSR_API(SrvSetConsoleScreenBufferSize)
747 {
748 NTSTATUS Status;
749 PCONSOLE_SETSCREENBUFFERSIZE SetScreenBufferSizeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetScreenBufferSizeRequest;
750 PTEXTMODE_SCREEN_BUFFER Buffer;
751
752 DPRINT("SrvSetConsoleScreenBufferSize\n");
753
754 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
755 SetScreenBufferSizeRequest->OutputHandle,
756 &Buffer, GENERIC_WRITE, TRUE);
757 if (!NT_SUCCESS(Status)) return Status;
758
759 Status = ConDrvSetConsoleScreenBufferSize(Buffer->Header.Console,
760 Buffer,
761 &SetScreenBufferSizeRequest->Size);
762
763 ConSrvReleaseScreenBuffer(Buffer, TRUE);
764 return Status;
765 }
766
767 NTSTATUS NTAPI
768 ConDrvScrollConsoleScreenBuffer(IN PCONSOLE Console,
769 IN PTEXTMODE_SCREEN_BUFFER Buffer,
770 IN BOOLEAN Unicode,
771 IN PSMALL_RECT ScrollRectangle,
772 IN BOOLEAN UseClipRectangle,
773 IN PSMALL_RECT ClipRectangle OPTIONAL,
774 IN PCOORD DestinationOrigin,
775 IN CHAR_INFO FillChar);
776 CSR_API(SrvScrollConsoleScreenBuffer)
777 {
778 NTSTATUS Status;
779 PCONSOLE_SCROLLSCREENBUFFER ScrollScreenBufferRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ScrollScreenBufferRequest;
780 PTEXTMODE_SCREEN_BUFFER Buffer;
781
782 DPRINT("SrvScrollConsoleScreenBuffer\n");
783
784 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
785 ScrollScreenBufferRequest->OutputHandle,
786 &Buffer, GENERIC_WRITE, TRUE);
787 if (!NT_SUCCESS(Status)) return Status;
788
789 Status = ConDrvScrollConsoleScreenBuffer(Buffer->Header.Console,
790 Buffer,
791 ScrollScreenBufferRequest->Unicode,
792 &ScrollScreenBufferRequest->ScrollRectangle,
793 ScrollScreenBufferRequest->UseClipRectangle,
794 &ScrollScreenBufferRequest->ClipRectangle,
795 &ScrollScreenBufferRequest->DestinationOrigin,
796 ScrollScreenBufferRequest->Fill);
797
798 ConSrvReleaseScreenBuffer(Buffer, TRUE);
799 return Status;
800 }
801
802 NTSTATUS NTAPI
803 ConDrvSetConsoleWindowInfo(IN PCONSOLE Console,
804 IN PTEXTMODE_SCREEN_BUFFER Buffer,
805 IN BOOLEAN Absolute,
806 IN PSMALL_RECT WindowRect);
807 CSR_API(SrvSetConsoleWindowInfo)
808 {
809 NTSTATUS Status;
810 PCONSOLE_SETWINDOWINFO SetWindowInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetWindowInfoRequest;
811 // PCONSOLE_SCREEN_BUFFER Buffer;
812 PTEXTMODE_SCREEN_BUFFER Buffer;
813
814 DPRINT1("SrvSetConsoleWindowInfo(0x%08x, %d, {L%d, T%d, R%d, B%d}) called\n",
815 SetWindowInfoRequest->OutputHandle, SetWindowInfoRequest->Absolute,
816 SetWindowInfoRequest->WindowRect.Left ,
817 SetWindowInfoRequest->WindowRect.Top ,
818 SetWindowInfoRequest->WindowRect.Right,
819 SetWindowInfoRequest->WindowRect.Bottom);
820
821 // ConSrvGetScreenBuffer
822 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
823 SetWindowInfoRequest->OutputHandle,
824 &Buffer, GENERIC_READ, TRUE);
825 if (!NT_SUCCESS(Status)) return Status;
826
827 Status = ConDrvSetConsoleWindowInfo(Buffer->Header.Console,
828 Buffer,
829 SetWindowInfoRequest->Absolute,
830 &SetWindowInfoRequest->WindowRect);
831
832 ConSrvReleaseScreenBuffer(Buffer, TRUE);
833 return Status;
834 }
835
836 /* EOF */