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