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