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