Install the vga fonts needed for the Blue driver.
[reactos.git] / reactos / win32ss / user / win32csr / console.c
1 /*
2 * reactos/subsys/csrss/win32csr/conio.c
3 *
4 * Console I/O functions
5 *
6 * ReactOS Operating System
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #define NDEBUG
12 #include "w32csr.h"
13 #include <debug.h>
14
15 /* FUNCTIONS *****************************************************************/
16
17 NTSTATUS FASTCALL
18 ConioConsoleFromProcessData(PCSR_PROCESS ProcessData, PCSRSS_CONSOLE *Console)
19 {
20 PCSRSS_CONSOLE ProcessConsole;
21
22 RtlEnterCriticalSection(&ProcessData->HandleTableLock);
23 ProcessConsole = ProcessData->Console;
24
25 if (!ProcessConsole)
26 {
27 *Console = NULL;
28 RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
29 return STATUS_INVALID_HANDLE;
30 }
31
32 InterlockedIncrement(&ProcessConsole->ReferenceCount);
33 RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
34 EnterCriticalSection(&(ProcessConsole->Lock));
35 *Console = ProcessConsole;
36
37 return STATUS_SUCCESS;
38 }
39
40 VOID FASTCALL
41 ConioConsoleCtrlEventTimeout(DWORD Event, PCSR_PROCESS ProcessData, DWORD Timeout)
42 {
43 HANDLE Thread;
44
45 DPRINT("ConioConsoleCtrlEvent Parent ProcessId = %x\n", ProcessData->ClientId.UniqueProcess);
46
47 if (ProcessData->CtrlDispatcher)
48 {
49
50 Thread = CreateRemoteThread(ProcessData->ProcessHandle, NULL, 0,
51 (LPTHREAD_START_ROUTINE) ProcessData->CtrlDispatcher,
52 UlongToPtr(Event), 0, NULL);
53 if (NULL == Thread)
54 {
55 DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
56 return;
57 }
58 WaitForSingleObject(Thread, Timeout);
59 CloseHandle(Thread);
60 }
61 }
62
63 VOID FASTCALL
64 ConioConsoleCtrlEvent(DWORD Event, PCSR_PROCESS ProcessData)
65 {
66 ConioConsoleCtrlEventTimeout(Event, ProcessData, 0);
67 }
68
69 static NTSTATUS WINAPI
70 CsrInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
71 {
72 NTSTATUS Status;
73 SECURITY_ATTRIBUTES SecurityAttributes;
74 PCSRSS_SCREEN_BUFFER NewBuffer;
75 BOOL GuiMode;
76 WCHAR Title[255];
77 HINSTANCE hInst;
78
79 Console->Title.MaximumLength = Console->Title.Length = 0;
80 Console->Title.Buffer = NULL;
81
82 hInst = GetModuleHandleW(L"win32csr");
83 if (LoadStringW(hInst,IDS_COMMAND_PROMPT,Title,sizeof(Title)/sizeof(Title[0])))
84 {
85 RtlCreateUnicodeString(&Console->Title, Title);
86 }
87 else
88 {
89 RtlCreateUnicodeString(&Console->Title, L"Command Prompt");
90 }
91
92 Console->ReferenceCount = 0;
93 Console->LineBuffer = NULL;
94 Console->Header.Type = CONIO_CONSOLE_MAGIC;
95 Console->Header.Console = Console;
96 Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT;
97 InitializeListHead(&Console->BufferList);
98 Console->ActiveBuffer = NULL;
99 InitializeListHead(&Console->InputEvents);
100 InitializeListHead(&Console->HistoryBuffers);
101 Console->CodePage = GetOEMCP();
102 Console->OutputCodePage = GetOEMCP();
103
104 SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
105 SecurityAttributes.lpSecurityDescriptor = NULL;
106 SecurityAttributes.bInheritHandle = TRUE;
107
108 Console->ActiveEvent = CreateEventW(&SecurityAttributes, TRUE, FALSE, NULL);
109 if (NULL == Console->ActiveEvent)
110 {
111 RtlFreeUnicodeString(&Console->Title);
112 return STATUS_UNSUCCESSFUL;
113 }
114 Console->PrivateData = NULL;
115 InitializeCriticalSection(&Console->Lock);
116
117 GuiMode = DtbgIsDesktopVisible();
118
119 /* allocate console screen buffer */
120 NewBuffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER));
121 if (NULL == NewBuffer)
122 {
123 RtlFreeUnicodeString(&Console->Title);
124 DeleteCriticalSection(&Console->Lock);
125 CloseHandle(Console->ActiveEvent);
126 return STATUS_INSUFFICIENT_RESOURCES;
127 }
128 /* init screen buffer with defaults */
129 NewBuffer->CursorInfo.bVisible = TRUE;
130 NewBuffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE;
131 /* make console active, and insert into console list */
132 Console->ActiveBuffer = (PCSRSS_SCREEN_BUFFER) NewBuffer;
133
134 if (! GuiMode)
135 {
136 Status = TuiInitConsole(Console);
137 if (! NT_SUCCESS(Status))
138 {
139 DPRINT1("Failed to open text-mode console, switching to gui-mode\n");
140 GuiMode = TRUE;
141 }
142 }
143 else /* GuiMode */
144 {
145 Status = GuiInitConsole(Console, ShowCmd);
146 if (! NT_SUCCESS(Status))
147 {
148 HeapFree(Win32CsrApiHeap,0, NewBuffer);
149 RtlFreeUnicodeString(&Console->Title);
150 DeleteCriticalSection(&Console->Lock);
151 CloseHandle(Console->ActiveEvent);
152 DPRINT1("GuiInitConsole: failed\n");
153 return Status;
154 }
155 }
156
157 Status = CsrInitConsoleScreenBuffer(Console, NewBuffer);
158 if (! NT_SUCCESS(Status))
159 {
160 ConioCleanupConsole(Console);
161 RtlFreeUnicodeString(&Console->Title);
162 DeleteCriticalSection(&Console->Lock);
163 CloseHandle(Console->ActiveEvent);
164 HeapFree(Win32CsrApiHeap, 0, NewBuffer);
165 DPRINT1("CsrInitConsoleScreenBuffer: failed\n");
166 return Status;
167 }
168
169 /* copy buffer contents to screen */
170 ConioDrawConsole(Console);
171
172 return STATUS_SUCCESS;
173 }
174
175 CSR_API(CsrAllocConsole)
176 {
177 PCSRSS_CONSOLE Console;
178 NTSTATUS Status = STATUS_SUCCESS;
179 BOOLEAN NewConsole = FALSE;
180
181 DPRINT("CsrAllocConsole\n");
182
183 RtlEnterCriticalSection(&ProcessData->HandleTableLock);
184 if (ProcessData->Console)
185 {
186 DPRINT1("Process already has a console\n");
187 RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
188 return STATUS_INVALID_PARAMETER;
189 }
190
191 /* If we don't need a console, then get out of here */
192 if (!Request->Data.AllocConsoleRequest.ConsoleNeeded)
193 {
194 DPRINT("No console needed\n");
195 RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
196 return STATUS_SUCCESS;
197 }
198
199 /* If we already have one, then don't create a new one... */
200 if (!Request->Data.AllocConsoleRequest.Console ||
201 Request->Data.AllocConsoleRequest.Console != ProcessData->ParentConsole)
202 {
203 /* Allocate a console structure */
204 NewConsole = TRUE;
205 Console = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_CONSOLE));
206 if (NULL == Console)
207 {
208 DPRINT1("Not enough memory for console\n");
209 RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
210 return STATUS_NO_MEMORY;
211 }
212 /* initialize list head */
213 InitializeListHead(&Console->ProcessList);
214 /* insert process data required for GUI initialization */
215 InsertHeadList(&Console->ProcessList, &ProcessData->ConsoleLink);
216 /* Initialize the Console */
217 Status = CsrInitConsole(Console, Request->Data.AllocConsoleRequest.ShowCmd);
218 if (!NT_SUCCESS(Status))
219 {
220 DPRINT1("Console init failed\n");
221 HeapFree(Win32CsrApiHeap, 0, Console);
222 RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
223 return Status;
224 }
225 }
226 else
227 {
228 /* Reuse our current console */
229 Console = Request->Data.AllocConsoleRequest.Console;
230 }
231
232 /* Set the Process Console */
233 ProcessData->Console = Console;
234
235 /* Return it to the caller */
236 Request->Data.AllocConsoleRequest.Console = Console;
237
238 /* Add a reference count because the process is tied to the console */
239 _InterlockedIncrement(&Console->ReferenceCount);
240
241 if (NewConsole || !ProcessData->bInheritHandles)
242 {
243 /* Insert the Objects */
244 Status = Win32CsrInsertObject(ProcessData,
245 &Request->Data.AllocConsoleRequest.InputHandle,
246 &Console->Header,
247 GENERIC_READ | GENERIC_WRITE,
248 TRUE,
249 FILE_SHARE_READ | FILE_SHARE_WRITE);
250 if (! NT_SUCCESS(Status))
251 {
252 DPRINT1("Failed to insert object\n");
253 ConioDeleteConsole((Object_t *) Console);
254 ProcessData->Console = 0;
255 RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
256 return Status;
257 }
258
259 Status = Win32CsrInsertObject(ProcessData,
260 &Request->Data.AllocConsoleRequest.OutputHandle,
261 &Console->ActiveBuffer->Header,
262 GENERIC_READ | GENERIC_WRITE,
263 TRUE,
264 FILE_SHARE_READ | FILE_SHARE_WRITE);
265 if (!NT_SUCCESS(Status))
266 {
267 DPRINT1("Failed to insert object\n");
268 ConioDeleteConsole((Object_t *) Console);
269 Win32CsrReleaseObject(ProcessData,
270 Request->Data.AllocConsoleRequest.InputHandle);
271 ProcessData->Console = 0;
272 RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
273 return Status;
274 }
275 }
276
277 /* Duplicate the Event */
278 if (!DuplicateHandle(GetCurrentProcess(),
279 ProcessData->Console->ActiveEvent,
280 ProcessData->ProcessHandle,
281 &ProcessData->ConsoleEvent,
282 EVENT_ALL_ACCESS,
283 FALSE,
284 0))
285 {
286 DPRINT1("DuplicateHandle() failed: %lu\n", GetLastError());
287 ConioDeleteConsole((Object_t *) Console);
288 if (NewConsole || !ProcessData->bInheritHandles)
289 {
290 Win32CsrReleaseObject(ProcessData,
291 Request->Data.AllocConsoleRequest.OutputHandle);
292 Win32CsrReleaseObject(ProcessData,
293 Request->Data.AllocConsoleRequest.InputHandle);
294 }
295 ProcessData->Console = 0;
296 RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
297 return Status;
298 }
299
300 /* Set the Ctrl Dispatcher */
301 ProcessData->CtrlDispatcher = Request->Data.AllocConsoleRequest.CtrlDispatcher;
302 DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);
303
304 if (!NewConsole)
305 {
306 /* Insert into the list if it has not been added */
307 InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ConsoleLink);
308 }
309
310 RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
311 return STATUS_SUCCESS;
312 }
313
314 CSR_API(CsrFreeConsole)
315 {
316 Win32CsrReleaseConsole(ProcessData);
317 return STATUS_SUCCESS;
318 }
319
320 VOID WINAPI
321 ConioDeleteConsole(Object_t *Object)
322 {
323 PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Object;
324 ConsoleInput *Event;
325
326 DPRINT("ConioDeleteConsole\n");
327
328 /* Drain input event queue */
329 while (Console->InputEvents.Flink != &Console->InputEvents)
330 {
331 Event = (ConsoleInput *) Console->InputEvents.Flink;
332 Console->InputEvents.Flink = Console->InputEvents.Flink->Flink;
333 Console->InputEvents.Flink->Flink->Blink = &Console->InputEvents;
334 HeapFree(Win32CsrApiHeap, 0, Event);
335 }
336
337 ConioCleanupConsole(Console);
338 if (Console->LineBuffer)
339 RtlFreeHeap(Win32CsrApiHeap, 0, Console->LineBuffer);
340 while (!IsListEmpty(&Console->HistoryBuffers))
341 HistoryDeleteBuffer((struct tagHISTORY_BUFFER *)Console->HistoryBuffers.Flink);
342
343 ConioDeleteScreenBuffer(Console->ActiveBuffer);
344 if (!IsListEmpty(&Console->BufferList))
345 {
346 DPRINT1("BUG: screen buffer list not empty\n");
347 }
348
349 CloseHandle(Console->ActiveEvent);
350 if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent);
351 DeleteCriticalSection(&Console->Lock);
352 RtlFreeUnicodeString(&Console->Title);
353 IntDeleteAllAliases(Console->Aliases);
354 HeapFree(Win32CsrApiHeap, 0, Console);
355 }
356
357 VOID WINAPI
358 CsrInitConsoleSupport(VOID)
359 {
360 DPRINT("CSR: CsrInitConsoleSupport()\n");
361
362 /* Should call LoadKeyboardLayout */
363 }
364
365 VOID FASTCALL
366 ConioPause(PCSRSS_CONSOLE Console, UINT Flags)
367 {
368 Console->PauseFlags |= Flags;
369 if (!Console->UnpauseEvent)
370 Console->UnpauseEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
371 }
372
373 VOID FASTCALL
374 ConioUnpause(PCSRSS_CONSOLE Console, UINT Flags)
375 {
376 Console->PauseFlags &= ~Flags;
377 if (Console->PauseFlags == 0 && Console->UnpauseEvent)
378 {
379 SetEvent(Console->UnpauseEvent);
380 CloseHandle(Console->UnpauseEvent);
381 Console->UnpauseEvent = NULL;
382 }
383 }
384
385 CSR_API(CsrSetConsoleMode)
386 {
387 NTSTATUS Status;
388 PCSRSS_CONSOLE Console;
389 PCSRSS_SCREEN_BUFFER Buff;
390
391 DPRINT("CsrSetConsoleMode\n");
392
393 Status = Win32CsrLockObject(ProcessData,
394 Request->Data.SetConsoleModeRequest.ConsoleHandle,
395 (Object_t **) &Console, GENERIC_WRITE, 0);
396 if (! NT_SUCCESS(Status))
397 {
398 return Status;
399 }
400
401 Buff = (PCSRSS_SCREEN_BUFFER)Console;
402 if (CONIO_CONSOLE_MAGIC == Console->Header.Type)
403 {
404 Console->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_INPUT_MODE_VALID;
405 }
406 else if (CONIO_SCREEN_BUFFER_MAGIC == Console->Header.Type)
407 {
408 Buff->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_OUTPUT_MODE_VALID;
409 }
410 else
411 {
412 Status = STATUS_INVALID_HANDLE;
413 }
414
415 Win32CsrUnlockObject((Object_t *)Console);
416
417 return Status;
418 }
419
420 CSR_API(CsrGetConsoleMode)
421 {
422 NTSTATUS Status;
423 PCSRSS_CONSOLE Console;
424 PCSRSS_SCREEN_BUFFER Buff; /* gee, I really wish I could use an anonymous union here */
425
426 DPRINT("CsrGetConsoleMode\n");
427
428 Status = Win32CsrLockObject(ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle,
429 (Object_t **) &Console, GENERIC_READ, 0);
430 if (! NT_SUCCESS(Status))
431 {
432 return Status;
433 }
434 Status = STATUS_SUCCESS;
435 Buff = (PCSRSS_SCREEN_BUFFER) Console;
436 if (CONIO_CONSOLE_MAGIC == Console->Header.Type)
437 {
438 Request->Data.GetConsoleModeRequest.ConsoleMode = Console->Mode;
439 }
440 else if (CONIO_SCREEN_BUFFER_MAGIC == Buff->Header.Type)
441 {
442 Request->Data.GetConsoleModeRequest.ConsoleMode = Buff->Mode;
443 }
444 else
445 {
446 Status = STATUS_INVALID_HANDLE;
447 }
448
449 Win32CsrUnlockObject((Object_t *)Console);
450 return Status;
451 }
452
453 CSR_API(CsrSetTitle)
454 {
455 NTSTATUS Status;
456 PCSRSS_CONSOLE Console;
457 PWCHAR Buffer;
458
459 DPRINT("CsrSetTitle\n");
460
461 if (!Win32CsrValidateBuffer(ProcessData, Request->Data.SetTitleRequest.Title,
462 Request->Data.SetTitleRequest.Length, 1))
463 {
464 return STATUS_ACCESS_VIOLATION;
465 }
466
467 Status = ConioConsoleFromProcessData(ProcessData, &Console);
468 if(NT_SUCCESS(Status))
469 {
470 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Request->Data.SetTitleRequest.Length);
471 if (Buffer)
472 {
473 /* copy title to console */
474 RtlFreeUnicodeString(&Console->Title);
475 Console->Title.Buffer = Buffer;
476 Console->Title.Length = Console->Title.MaximumLength = Request->Data.SetTitleRequest.Length;
477 memcpy(Console->Title.Buffer, Request->Data.SetTitleRequest.Title, Console->Title.Length);
478 if (! ConioChangeTitle(Console))
479 {
480 Status = STATUS_UNSUCCESSFUL;
481 }
482 else
483 {
484 Status = STATUS_SUCCESS;
485 }
486 }
487 else
488 {
489 Status = STATUS_NO_MEMORY;
490 }
491 ConioUnlockConsole(Console);
492 }
493
494 return Status;
495 }
496
497 CSR_API(CsrGetTitle)
498 {
499 NTSTATUS Status;
500 PCSRSS_CONSOLE Console;
501 DWORD Length;
502
503 DPRINT("CsrGetTitle\n");
504
505
506 if (!Win32CsrValidateBuffer(ProcessData, Request->Data.GetTitleRequest.Title,
507 Request->Data.GetTitleRequest.Length, 1))
508 {
509 return STATUS_ACCESS_VIOLATION;
510 }
511
512 Status = ConioConsoleFromProcessData(ProcessData, &Console);
513 if (! NT_SUCCESS(Status))
514 {
515 DPRINT1("Can't get console\n");
516 return Status;
517 }
518
519 /* Copy title of the console to the user title buffer */
520 if (Request->Data.GetTitleRequest.Length >= sizeof(WCHAR))
521 {
522 Length = min(Request->Data.GetTitleRequest.Length - sizeof(WCHAR), Console->Title.Length);
523 memcpy(Request->Data.GetTitleRequest.Title, Console->Title.Buffer, Length);
524 Request->Data.GetTitleRequest.Title[Length / sizeof(WCHAR)] = L'\0';
525 }
526
527 Request->Data.GetTitleRequest.Length = Console->Title.Length;
528
529 ConioUnlockConsole(Console);
530 return STATUS_SUCCESS;
531 }
532
533 /**********************************************************************
534 * HardwareStateProperty
535 *
536 * DESCRIPTION
537 * Set/Get the value of the HardwareState and switch
538 * between direct video buffer ouput and GDI windowed
539 * output.
540 * ARGUMENTS
541 * Client hands us a CSRSS_CONSOLE_HARDWARE_STATE
542 * object. We use the same object to Request.
543 * NOTE
544 * ConsoleHwState has the correct size to be compatible
545 * with NT's, but values are not.
546 */
547 static NTSTATUS FASTCALL
548 SetConsoleHardwareState (PCSRSS_CONSOLE Console, DWORD ConsoleHwState)
549 {
550 DPRINT1("Console Hardware State: %d\n", ConsoleHwState);
551
552 if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED == ConsoleHwState)
553 ||(CONSOLE_HARDWARE_STATE_DIRECT == ConsoleHwState))
554 {
555 if (Console->HardwareState != ConsoleHwState)
556 {
557 /* TODO: implement switching from full screen to windowed mode */
558 /* TODO: or back; now simply store the hardware state */
559 Console->HardwareState = ConsoleHwState;
560 }
561
562 return STATUS_SUCCESS;
563 }
564
565 return STATUS_INVALID_PARAMETER_3; /* Client: (handle, set_get, [mode]) */
566 }
567
568 CSR_API(CsrHardwareStateProperty)
569 {
570 PCSRSS_CONSOLE Console;
571 NTSTATUS Status;
572
573 DPRINT("CsrHardwareStateProperty\n");
574
575 Status = ConioLockConsole(ProcessData,
576 Request->Data.ConsoleHardwareStateRequest.ConsoleHandle,
577 &Console,
578 GENERIC_READ);
579 if (! NT_SUCCESS(Status))
580 {
581 DPRINT1("Failed to get console handle in SetConsoleHardwareState\n");
582 return Status;
583 }
584
585 switch (Request->Data.ConsoleHardwareStateRequest.SetGet)
586 {
587 case CONSOLE_HARDWARE_STATE_GET:
588 Request->Data.ConsoleHardwareStateRequest.State = Console->HardwareState;
589 break;
590
591 case CONSOLE_HARDWARE_STATE_SET:
592 DPRINT("Setting console hardware state.\n");
593 Status = SetConsoleHardwareState(Console, Request->Data.ConsoleHardwareStateRequest.State);
594 break;
595
596 default:
597 Status = STATUS_INVALID_PARAMETER_2; /* Client: (handle, [set_get], mode) */
598 break;
599 }
600
601 ConioUnlockConsole(Console);
602
603 return Status;
604 }
605
606 CSR_API(CsrGetConsoleWindow)
607 {
608 PCSRSS_CONSOLE Console;
609 NTSTATUS Status;
610
611 DPRINT("CsrGetConsoleWindow\n");
612
613 Status = ConioConsoleFromProcessData(ProcessData, &Console);
614 if (! NT_SUCCESS(Status))
615 {
616 return Status;
617 }
618
619 Request->Data.GetConsoleWindowRequest.WindowHandle = Console->hWindow;
620 ConioUnlockConsole(Console);
621
622 return STATUS_SUCCESS;
623 }
624
625 CSR_API(CsrSetConsoleIcon)
626 {
627 PCSRSS_CONSOLE Console;
628 NTSTATUS Status;
629
630 DPRINT("CsrSetConsoleIcon\n");
631
632 Status = ConioConsoleFromProcessData(ProcessData, &Console);
633 if (! NT_SUCCESS(Status))
634 {
635 return Status;
636 }
637
638 Status = (ConioChangeIcon(Console, Request->Data.SetConsoleIconRequest.WindowIcon)
639 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
640 ConioUnlockConsole(Console);
641
642 return Status;
643 }
644
645 CSR_API(CsrGetConsoleCodePage)
646 {
647 PCSRSS_CONSOLE Console;
648 NTSTATUS Status;
649
650 DPRINT("CsrGetConsoleCodePage\n");
651
652 Status = ConioConsoleFromProcessData(ProcessData, &Console);
653 if (! NT_SUCCESS(Status))
654 {
655 return Status;
656 }
657
658 Request->Data.GetConsoleCodePage.CodePage = Console->CodePage;
659 ConioUnlockConsole(Console);
660 return STATUS_SUCCESS;
661 }
662
663 CSR_API(CsrSetConsoleCodePage)
664 {
665 PCSRSS_CONSOLE Console;
666 NTSTATUS Status;
667
668 DPRINT("CsrSetConsoleCodePage\n");
669
670 Status = ConioConsoleFromProcessData(ProcessData, &Console);
671 if (! NT_SUCCESS(Status))
672 {
673 return Status;
674 }
675
676 if (IsValidCodePage(Request->Data.SetConsoleCodePage.CodePage))
677 {
678 Console->CodePage = Request->Data.SetConsoleCodePage.CodePage;
679 ConioUnlockConsole(Console);
680 return STATUS_SUCCESS;
681 }
682
683 ConioUnlockConsole(Console);
684 return STATUS_INVALID_PARAMETER;
685 }
686
687 CSR_API(CsrGetConsoleOutputCodePage)
688 {
689 PCSRSS_CONSOLE Console;
690 NTSTATUS Status;
691
692 DPRINT("CsrGetConsoleOutputCodePage\n");
693
694 Status = ConioConsoleFromProcessData(ProcessData, &Console);
695 if (! NT_SUCCESS(Status))
696 {
697 return Status;
698 }
699
700 Request->Data.GetConsoleOutputCodePage.CodePage = Console->OutputCodePage;
701 ConioUnlockConsole(Console);
702 return STATUS_SUCCESS;
703 }
704
705 CSR_API(CsrSetConsoleOutputCodePage)
706 {
707 PCSRSS_CONSOLE Console;
708 NTSTATUS Status;
709
710 DPRINT("CsrSetConsoleOutputCodePage\n");
711
712 Status = ConioConsoleFromProcessData(ProcessData, &Console);
713 if (! NT_SUCCESS(Status))
714 {
715 return Status;
716 }
717
718 if (IsValidCodePage(Request->Data.SetConsoleOutputCodePage.CodePage))
719 {
720 Console->OutputCodePage = Request->Data.SetConsoleOutputCodePage.CodePage;
721 ConioUnlockConsole(Console);
722 return STATUS_SUCCESS;
723 }
724
725 ConioUnlockConsole(Console);
726 return STATUS_INVALID_PARAMETER;
727 }
728
729 CSR_API(CsrGetProcessList)
730 {
731 PDWORD Buffer;
732 PCSRSS_CONSOLE Console;
733 PCSR_PROCESS current;
734 PLIST_ENTRY current_entry;
735 ULONG nItems = 0;
736 NTSTATUS Status;
737
738 DPRINT("CsrGetProcessList\n");
739
740 Buffer = Request->Data.GetProcessListRequest.ProcessId;
741 if (!Win32CsrValidateBuffer(ProcessData, Buffer, Request->Data.GetProcessListRequest.nMaxIds, sizeof(DWORD)))
742 return STATUS_ACCESS_VIOLATION;
743
744 Status = ConioConsoleFromProcessData(ProcessData, &Console);
745 if (! NT_SUCCESS(Status))
746 {
747 return Status;
748 }
749
750 for (current_entry = Console->ProcessList.Flink;
751 current_entry != &Console->ProcessList;
752 current_entry = current_entry->Flink)
753 {
754 current = CONTAINING_RECORD(current_entry, CSR_PROCESS, ConsoleLink);
755 if (++nItems <= Request->Data.GetProcessListRequest.nMaxIds)
756 {
757 *Buffer++ = HandleToUlong(current->ClientId.UniqueProcess);
758 }
759 }
760
761 ConioUnlockConsole(Console);
762
763 Request->Data.GetProcessListRequest.nProcessIdsTotal = nItems;
764 return STATUS_SUCCESS;
765 }
766
767 CSR_API(CsrGenerateCtrlEvent)
768 {
769 PCSRSS_CONSOLE Console;
770 PCSR_PROCESS current;
771 PLIST_ENTRY current_entry;
772 DWORD Group;
773 NTSTATUS Status;
774
775 Status = ConioConsoleFromProcessData(ProcessData, &Console);
776 if (! NT_SUCCESS(Status))
777 {
778 return Status;
779 }
780
781 Group = Request->Data.GenerateCtrlEvent.ProcessGroup;
782 Status = STATUS_INVALID_PARAMETER;
783 for (current_entry = Console->ProcessList.Flink;
784 current_entry != &Console->ProcessList;
785 current_entry = current_entry->Flink)
786 {
787 current = CONTAINING_RECORD(current_entry, CSR_PROCESS, ConsoleLink);
788 if (Group == 0 || current->ProcessGroupId == Group)
789 {
790 ConioConsoleCtrlEvent(Request->Data.GenerateCtrlEvent.Event, current);
791 Status = STATUS_SUCCESS;
792 }
793 }
794
795 ConioUnlockConsole(Console);
796
797 return Status;
798 }
799
800 CSR_API(CsrGetConsoleSelectionInfo)
801 {
802 NTSTATUS Status;
803 PCSRSS_CONSOLE Console;
804
805 Status = ConioConsoleFromProcessData(ProcessData, &Console);
806 if (NT_SUCCESS(Status))
807 {
808 memset(&Request->Data.GetConsoleSelectionInfo.Info, 0, sizeof(CONSOLE_SELECTION_INFO));
809 if (Console->Selection.dwFlags != 0)
810 Request->Data.GetConsoleSelectionInfo.Info = Console->Selection;
811 ConioUnlockConsole(Console);
812 }
813 return Status;
814 }
815
816 /* EOF */