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