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