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