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