Sync up with trunk r61578.
[reactos.git] / 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 BOOLEAN 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, WaitThread, FALSE);
355
356 Quit:
357 if (Status != STATUS_PENDING)
358 {
359 WaitApiMessage->Status = Status;
360 }
361
362 return (Status == STATUS_PENDING ? FALSE : TRUE);
363 }
364
365 NTSTATUS NTAPI
366 ConDrvWriteConsole(IN PCONSOLE Console,
367 IN PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
368 IN BOOLEAN Unicode,
369 IN PVOID StringBuffer,
370 IN ULONG NumCharsToWrite,
371 OUT PULONG NumCharsWritten OPTIONAL);
372 static NTSTATUS
373 DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage,
374 IN PCSR_THREAD ClientThread,
375 IN BOOLEAN CreateWaitBlock OPTIONAL)
376 {
377 NTSTATUS Status;
378 PCONSOLE_WRITECONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest;
379 PTEXTMODE_SCREEN_BUFFER ScreenBuffer;
380
381 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(ClientThread->Process),
382 WriteConsoleRequest->OutputHandle,
383 &ScreenBuffer, GENERIC_WRITE, FALSE);
384 if (!NT_SUCCESS(Status)) return Status;
385
386 Status = ConDrvWriteConsole(ScreenBuffer->Header.Console,
387 ScreenBuffer,
388 WriteConsoleRequest->Unicode,
389 WriteConsoleRequest->Buffer,
390 WriteConsoleRequest->NrCharactersToWrite,
391 &WriteConsoleRequest->NrCharactersWritten);
392
393 if (Status == STATUS_PENDING)
394 {
395 if (CreateWaitBlock)
396 {
397 if (!CsrCreateWait(&ScreenBuffer->Header.Console->WriteWaitQueue,
398 WriteConsoleThread,
399 ClientThread,
400 ApiMessage,
401 NULL))
402 {
403 /* Fail */
404 Status = STATUS_NO_MEMORY;
405 goto Quit;
406 }
407 }
408
409 /* Wait until we un-pause the console */
410 // Status = STATUS_PENDING;
411 }
412
413 Quit:
414 ConSrvReleaseScreenBuffer(ScreenBuffer, FALSE);
415 return Status;
416 }
417
418
419 /* TEXT OUTPUT APIS ***********************************************************/
420
421 NTSTATUS NTAPI
422 ConDrvReadConsoleOutput(IN PCONSOLE Console,
423 IN PTEXTMODE_SCREEN_BUFFER Buffer,
424 IN BOOLEAN Unicode,
425 OUT PCHAR_INFO CharInfo/*Buffer*/,
426 IN PCOORD BufferSize,
427 IN PCOORD BufferCoord,
428 IN OUT PSMALL_RECT ReadRegion);
429 CSR_API(SrvReadConsoleOutput)
430 {
431 NTSTATUS Status;
432 PCONSOLE_READOUTPUT ReadOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadOutputRequest;
433 PTEXTMODE_SCREEN_BUFFER Buffer;
434
435 DPRINT("SrvReadConsoleOutput\n");
436
437 if (!CsrValidateMessageBuffer(ApiMessage,
438 (PVOID*)&ReadOutputRequest->CharInfo,
439 ReadOutputRequest->BufferSize.X * ReadOutputRequest->BufferSize.Y,
440 sizeof(CHAR_INFO)))
441 {
442 return STATUS_INVALID_PARAMETER;
443 }
444
445 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
446 ReadOutputRequest->OutputHandle,
447 &Buffer, GENERIC_READ, TRUE);
448 if (!NT_SUCCESS(Status)) return Status;
449
450 Status = ConDrvReadConsoleOutput(Buffer->Header.Console,
451 Buffer,
452 ReadOutputRequest->Unicode,
453 ReadOutputRequest->CharInfo,
454 &ReadOutputRequest->BufferSize,
455 &ReadOutputRequest->BufferCoord,
456 &ReadOutputRequest->ReadRegion);
457
458 ConSrvReleaseScreenBuffer(Buffer, TRUE);
459 return Status;
460 }
461
462 NTSTATUS NTAPI
463 ConDrvWriteConsoleOutput(IN PCONSOLE Console,
464 IN PTEXTMODE_SCREEN_BUFFER Buffer,
465 IN BOOLEAN Unicode,
466 IN PCHAR_INFO CharInfo/*Buffer*/,
467 IN PCOORD BufferSize,
468 IN PCOORD BufferCoord,
469 IN OUT PSMALL_RECT WriteRegion);
470 CSR_API(SrvWriteConsoleOutput)
471 {
472 NTSTATUS Status;
473 PCONSOLE_WRITEOUTPUT WriteOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputRequest;
474 PTEXTMODE_SCREEN_BUFFER Buffer;
475
476 DPRINT("SrvWriteConsoleOutput\n");
477
478 if (!CsrValidateMessageBuffer(ApiMessage,
479 (PVOID*)&WriteOutputRequest->CharInfo,
480 WriteOutputRequest->BufferSize.X * WriteOutputRequest->BufferSize.Y,
481 sizeof(CHAR_INFO)))
482 {
483 return STATUS_INVALID_PARAMETER;
484 }
485
486 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
487 WriteOutputRequest->OutputHandle,
488 &Buffer, GENERIC_WRITE, TRUE);
489 if (!NT_SUCCESS(Status)) return Status;
490
491 Status = ConDrvWriteConsoleOutput(Buffer->Header.Console,
492 Buffer,
493 WriteOutputRequest->Unicode,
494 WriteOutputRequest->CharInfo,
495 &WriteOutputRequest->BufferSize,
496 &WriteOutputRequest->BufferCoord,
497 &WriteOutputRequest->WriteRegion);
498
499 ConSrvReleaseScreenBuffer(Buffer, TRUE);
500 return Status;
501 }
502
503 CSR_API(SrvWriteConsole)
504 {
505 NTSTATUS Status;
506 PCONSOLE_WRITECONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest;
507
508 DPRINT("SrvWriteConsole\n");
509
510 if (!CsrValidateMessageBuffer(ApiMessage,
511 (PVOID)&WriteConsoleRequest->Buffer,
512 WriteConsoleRequest->BufferSize,
513 sizeof(BYTE)))
514 {
515 return STATUS_INVALID_PARAMETER;
516 }
517
518 Status = DoWriteConsole(ApiMessage, CsrGetClientThread(), TRUE);
519
520 if (Status == STATUS_PENDING) *ReplyCode = CsrReplyPending;
521
522 return Status;
523 }
524
525 NTSTATUS NTAPI
526 ConDrvReadConsoleOutputString(IN PCONSOLE Console,
527 IN PTEXTMODE_SCREEN_BUFFER Buffer,
528 IN CODE_TYPE CodeType,
529 OUT PVOID StringBuffer,
530 IN ULONG NumCodesToRead,
531 IN PCOORD ReadCoord,
532 OUT PCOORD EndCoord,
533 OUT PULONG CodesRead);
534 CSR_API(SrvReadConsoleOutputString)
535 {
536 NTSTATUS Status;
537 PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadOutputCodeRequest;
538 PTEXTMODE_SCREEN_BUFFER Buffer;
539 ULONG CodeSize;
540
541 DPRINT("SrvReadConsoleOutputString\n");
542
543 switch (ReadOutputCodeRequest->CodeType)
544 {
545 case CODE_ASCII:
546 CodeSize = sizeof(CHAR);
547 break;
548
549 case CODE_UNICODE:
550 CodeSize = sizeof(WCHAR);
551 break;
552
553 case CODE_ATTRIBUTE:
554 CodeSize = sizeof(WORD);
555 break;
556
557 default:
558 return STATUS_INVALID_PARAMETER;
559 }
560
561 if (!CsrValidateMessageBuffer(ApiMessage,
562 (PVOID*)&ReadOutputCodeRequest->pCode.pCode,
563 ReadOutputCodeRequest->NumCodesToRead,
564 CodeSize))
565 {
566 return STATUS_INVALID_PARAMETER;
567 }
568
569 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
570 ReadOutputCodeRequest->OutputHandle,
571 &Buffer, GENERIC_READ, TRUE);
572 if (!NT_SUCCESS(Status)) return Status;
573
574 Status = ConDrvReadConsoleOutputString(Buffer->Header.Console,
575 Buffer,
576 ReadOutputCodeRequest->CodeType,
577 ReadOutputCodeRequest->pCode.pCode,
578 ReadOutputCodeRequest->NumCodesToRead,
579 &ReadOutputCodeRequest->ReadCoord,
580 &ReadOutputCodeRequest->EndCoord,
581 &ReadOutputCodeRequest->CodesRead);
582
583 ConSrvReleaseScreenBuffer(Buffer, TRUE);
584 return Status;
585 }
586
587 NTSTATUS NTAPI
588 ConDrvWriteConsoleOutputString(IN PCONSOLE Console,
589 IN PTEXTMODE_SCREEN_BUFFER Buffer,
590 IN CODE_TYPE CodeType,
591 IN PVOID StringBuffer,
592 IN ULONG NumCodesToWrite,
593 IN PCOORD WriteCoord /*,
594 OUT PCOORD EndCoord,
595 OUT PULONG CodesWritten */);
596 CSR_API(SrvWriteConsoleOutputString)
597 {
598 NTSTATUS Status;
599 PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputCodeRequest;
600 PTEXTMODE_SCREEN_BUFFER Buffer;
601 ULONG CodeSize;
602
603 DPRINT("SrvWriteConsoleOutputString\n");
604
605 switch (WriteOutputCodeRequest->CodeType)
606 {
607 case CODE_ASCII:
608 CodeSize = sizeof(CHAR);
609 break;
610
611 case CODE_UNICODE:
612 CodeSize = sizeof(WCHAR);
613 break;
614
615 case CODE_ATTRIBUTE:
616 CodeSize = sizeof(WORD);
617 break;
618
619 default:
620 return STATUS_INVALID_PARAMETER;
621 }
622
623 if (!CsrValidateMessageBuffer(ApiMessage,
624 (PVOID*)&WriteOutputCodeRequest->pCode.pCode,
625 WriteOutputCodeRequest->Length,
626 CodeSize))
627 {
628 return STATUS_INVALID_PARAMETER;
629 }
630
631 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
632 WriteOutputCodeRequest->OutputHandle,
633 &Buffer, GENERIC_WRITE, TRUE);
634 if (!NT_SUCCESS(Status)) return Status;
635
636 Status = ConDrvWriteConsoleOutputString(Buffer->Header.Console,
637 Buffer,
638 WriteOutputCodeRequest->CodeType,
639 WriteOutputCodeRequest->pCode.pCode,
640 WriteOutputCodeRequest->Length, // NumCodesToWrite,
641 &WriteOutputCodeRequest->Coord /*, // WriteCoord,
642 &WriteOutputCodeRequest->EndCoord,
643 &WriteOutputCodeRequest->NrCharactersWritten */);
644
645 // WriteOutputCodeRequest->NrCharactersWritten = Written;
646
647 ConSrvReleaseScreenBuffer(Buffer, TRUE);
648 return Status;
649 }
650
651 NTSTATUS NTAPI
652 ConDrvFillConsoleOutput(IN PCONSOLE Console,
653 IN PTEXTMODE_SCREEN_BUFFER Buffer,
654 IN CODE_TYPE CodeType,
655 IN PVOID Code,
656 IN ULONG NumCodesToWrite,
657 IN PCOORD WriteCoord /*,
658 OUT PULONG CodesWritten */);
659 CSR_API(SrvFillConsoleOutput)
660 {
661 NTSTATUS Status;
662 PCONSOLE_FILLOUTPUTCODE FillOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.FillOutputRequest;
663 PTEXTMODE_SCREEN_BUFFER Buffer;
664 USHORT CodeType = FillOutputRequest->CodeType;
665
666 DPRINT("SrvFillConsoleOutput\n");
667
668 if ( (CodeType != CODE_ASCII ) &&
669 (CodeType != CODE_UNICODE ) &&
670 (CodeType != CODE_ATTRIBUTE) )
671 {
672 return STATUS_INVALID_PARAMETER;
673 }
674
675 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
676 FillOutputRequest->OutputHandle,
677 &Buffer, GENERIC_WRITE, TRUE);
678 if (!NT_SUCCESS(Status)) return Status;
679
680 Status = ConDrvFillConsoleOutput(Buffer->Header.Console,
681 Buffer,
682 CodeType,
683 &FillOutputRequest->Code,
684 FillOutputRequest->Length, // NumCodesToWrite,
685 &FillOutputRequest->Coord /*, // WriteCoord,
686 &FillOutputRequest->NrCharactersWritten */);
687
688 // FillOutputRequest->NrCharactersWritten = Written;
689
690 ConSrvReleaseScreenBuffer(Buffer, TRUE);
691 return Status;
692 }
693
694 NTSTATUS NTAPI
695 ConDrvGetConsoleScreenBufferInfo(IN PCONSOLE Console,
696 IN PTEXTMODE_SCREEN_BUFFER Buffer,
697 OUT PCONSOLE_SCREEN_BUFFER_INFO ScreenBufferInfo);
698 CSR_API(SrvGetConsoleScreenBufferInfo)
699 {
700 NTSTATUS Status;
701 PCONSOLE_GETSCREENBUFFERINFO ScreenBufferInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ScreenBufferInfoRequest;
702 PTEXTMODE_SCREEN_BUFFER Buffer;
703
704 DPRINT("SrvGetConsoleScreenBufferInfo\n");
705
706 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
707 ScreenBufferInfoRequest->OutputHandle,
708 &Buffer, GENERIC_READ, TRUE);
709 if (!NT_SUCCESS(Status)) return Status;
710
711 Status = ConDrvGetConsoleScreenBufferInfo(Buffer->Header.Console,
712 Buffer,
713 &ScreenBufferInfoRequest->Info);
714
715 ConSrvReleaseScreenBuffer(Buffer, TRUE);
716 return Status;
717 }
718
719 NTSTATUS NTAPI
720 ConDrvSetConsoleTextAttribute(IN PCONSOLE Console,
721 IN PTEXTMODE_SCREEN_BUFFER Buffer,
722 IN WORD Attribute);
723 CSR_API(SrvSetConsoleTextAttribute)
724 {
725 NTSTATUS Status;
726 PCONSOLE_SETTEXTATTRIB SetTextAttribRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetTextAttribRequest;
727 PTEXTMODE_SCREEN_BUFFER Buffer;
728
729 DPRINT("SrvSetConsoleTextAttribute\n");
730
731 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
732 SetTextAttribRequest->OutputHandle,
733 &Buffer, GENERIC_WRITE, TRUE);
734 if (!NT_SUCCESS(Status)) return Status;
735
736 Status = ConDrvSetConsoleTextAttribute(Buffer->Header.Console,
737 Buffer,
738 SetTextAttribRequest->Attrib);
739
740 ConSrvReleaseScreenBuffer(Buffer, TRUE);
741 return Status;
742 }
743
744 NTSTATUS NTAPI
745 ConDrvSetConsoleScreenBufferSize(IN PCONSOLE Console,
746 IN PTEXTMODE_SCREEN_BUFFER Buffer,
747 IN PCOORD Size);
748 CSR_API(SrvSetConsoleScreenBufferSize)
749 {
750 NTSTATUS Status;
751 PCONSOLE_SETSCREENBUFFERSIZE SetScreenBufferSizeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetScreenBufferSizeRequest;
752 PTEXTMODE_SCREEN_BUFFER Buffer;
753
754 DPRINT("SrvSetConsoleScreenBufferSize\n");
755
756 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
757 SetScreenBufferSizeRequest->OutputHandle,
758 &Buffer, GENERIC_WRITE, TRUE);
759 if (!NT_SUCCESS(Status)) return Status;
760
761 Status = ConDrvSetConsoleScreenBufferSize(Buffer->Header.Console,
762 Buffer,
763 &SetScreenBufferSizeRequest->Size);
764
765 ConSrvReleaseScreenBuffer(Buffer, TRUE);
766 return Status;
767 }
768
769 NTSTATUS NTAPI
770 ConDrvScrollConsoleScreenBuffer(IN PCONSOLE Console,
771 IN PTEXTMODE_SCREEN_BUFFER Buffer,
772 IN BOOLEAN Unicode,
773 IN PSMALL_RECT ScrollRectangle,
774 IN BOOLEAN UseClipRectangle,
775 IN PSMALL_RECT ClipRectangle OPTIONAL,
776 IN PCOORD DestinationOrigin,
777 IN CHAR_INFO FillChar);
778 CSR_API(SrvScrollConsoleScreenBuffer)
779 {
780 NTSTATUS Status;
781 PCONSOLE_SCROLLSCREENBUFFER ScrollScreenBufferRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ScrollScreenBufferRequest;
782 PTEXTMODE_SCREEN_BUFFER Buffer;
783
784 DPRINT("SrvScrollConsoleScreenBuffer\n");
785
786 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
787 ScrollScreenBufferRequest->OutputHandle,
788 &Buffer, GENERIC_WRITE, TRUE);
789 if (!NT_SUCCESS(Status)) return Status;
790
791 Status = ConDrvScrollConsoleScreenBuffer(Buffer->Header.Console,
792 Buffer,
793 ScrollScreenBufferRequest->Unicode,
794 &ScrollScreenBufferRequest->ScrollRectangle,
795 ScrollScreenBufferRequest->UseClipRectangle,
796 &ScrollScreenBufferRequest->ClipRectangle,
797 &ScrollScreenBufferRequest->DestinationOrigin,
798 ScrollScreenBufferRequest->Fill);
799
800 ConSrvReleaseScreenBuffer(Buffer, TRUE);
801 return Status;
802 }
803
804 NTSTATUS NTAPI
805 ConDrvSetConsoleWindowInfo(IN PCONSOLE Console,
806 IN PTEXTMODE_SCREEN_BUFFER Buffer,
807 IN BOOLEAN Absolute,
808 IN PSMALL_RECT WindowRect);
809 CSR_API(SrvSetConsoleWindowInfo)
810 {
811 NTSTATUS Status;
812 PCONSOLE_SETWINDOWINFO SetWindowInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetWindowInfoRequest;
813 // PCONSOLE_SCREEN_BUFFER Buffer;
814 PTEXTMODE_SCREEN_BUFFER Buffer;
815
816 DPRINT1("SrvSetConsoleWindowInfo(0x%08x, %d, {L%d, T%d, R%d, B%d}) called\n",
817 SetWindowInfoRequest->OutputHandle, SetWindowInfoRequest->Absolute,
818 SetWindowInfoRequest->WindowRect.Left ,
819 SetWindowInfoRequest->WindowRect.Top ,
820 SetWindowInfoRequest->WindowRect.Right,
821 SetWindowInfoRequest->WindowRect.Bottom);
822
823 // ConSrvGetScreenBuffer
824 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
825 SetWindowInfoRequest->OutputHandle,
826 &Buffer, GENERIC_READ, TRUE);
827 if (!NT_SUCCESS(Status)) return Status;
828
829 Status = ConDrvSetConsoleWindowInfo(Buffer->Header.Console,
830 Buffer,
831 SetWindowInfoRequest->Absolute,
832 &SetWindowInfoRequest->WindowRect);
833
834 ConSrvReleaseScreenBuffer(Buffer, TRUE);
835 return Status;
836 }
837
838 /* EOF */