* Sync up to trunk HEAD (r62285). Branch guys deserve the significant speedups too ;)
[reactos.git] / win32ss / user / winsrv / consrv / console.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Console Server DLL
4 * FILE: win32ss/user/winsrv/consrv/console.c
5 * PURPOSE: Console Management Functions
6 * PROGRAMMERS: Gé van Geldorp
7 * Jeffrey Morlan
8 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
9 */
10
11 /* INCLUDES *******************************************************************/
12
13 #include "consrv.h"
14
15 #include <ndk/psfuncs.h>
16
17 #include "procinit.h"
18
19 #ifdef TUITERM_COMPILE
20 #include "frontends/tui/tuiterm.h"
21 #endif
22
23 #define NDEBUG
24 #include <debug.h>
25
26 /* GLOBALS ********************************************************************/
27
28 /***************/
29 #ifdef TUITERM_COMPILE
30 NTSTATUS NTAPI
31 TuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd,
32 IN OUT PCONSOLE_INFO ConsoleInfo,
33 IN OUT PVOID ExtraConsoleInfo,
34 IN ULONG ProcessId);
35 NTSTATUS NTAPI
36 TuiUnloadFrontEnd(IN OUT PFRONTEND FrontEnd);
37 #endif
38
39 NTSTATUS NTAPI
40 GuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd,
41 IN OUT PCONSOLE_INFO ConsoleInfo,
42 IN OUT PVOID ExtraConsoleInfo,
43 IN ULONG ProcessId);
44 NTSTATUS NTAPI
45 GuiUnloadFrontEnd(IN OUT PFRONTEND FrontEnd);
46 /***************/
47
48 typedef
49 NTSTATUS (NTAPI *FRONTEND_LOAD)(IN OUT PFRONTEND FrontEnd,
50 IN OUT PCONSOLE_INFO ConsoleInfo,
51 IN OUT PVOID ExtraConsoleInfo,
52 IN ULONG ProcessId);
53
54 typedef
55 NTSTATUS (NTAPI *FRONTEND_UNLOAD)(IN OUT PFRONTEND FrontEnd);
56
57 /*
58 * If we are not in GUI-mode, start the text-mode terminal emulator.
59 * If we fail, try to start the GUI-mode terminal emulator.
60 *
61 * Try to open the GUI-mode terminal emulator. Two cases are possible:
62 * - We are in GUI-mode, therefore GuiMode == TRUE, the previous test-case
63 * failed and we start GUI-mode terminal emulator.
64 * - We are in text-mode, therefore GuiMode == FALSE, the previous test-case
65 * succeeded BUT we failed at starting text-mode terminal emulator.
66 * Then GuiMode was switched to TRUE in order to try to open the GUI-mode
67 * terminal emulator (Win32k will automatically switch to graphical mode,
68 * therefore no additional code is needed).
69 */
70
71 /*
72 * NOTE: Each entry of the table should be retrieved when loading a front-end
73 * (examples of the CSR servers which register some data for CSRSS).
74 */
75 struct
76 {
77 CHAR FrontEndName[80];
78 FRONTEND_LOAD FrontEndLoad;
79 FRONTEND_UNLOAD FrontEndUnload;
80 } FrontEndLoadingMethods[] =
81 {
82 #ifdef TUITERM_COMPILE
83 {"TUI", TuiLoadFrontEnd, TuiUnloadFrontEnd},
84 #endif
85 {"GUI", GuiLoadFrontEnd, GuiUnloadFrontEnd},
86
87 // {"Not found", 0, NULL}
88 };
89
90
91 /* PRIVATE FUNCTIONS **********************************************************/
92
93 #if 0000
94 VOID FASTCALL
95 ConioPause(PCONSOLE Console, UINT Flags)
96 {
97 Console->PauseFlags |= Flags;
98 if (!Console->UnpauseEvent)
99 Console->UnpauseEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
100 }
101
102 VOID FASTCALL
103 ConioUnpause(PCONSOLE Console, UINT Flags)
104 {
105 Console->PauseFlags &= ~Flags;
106
107 // if ((Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION)) == 0)
108 if (Console->PauseFlags == 0 && Console->UnpauseEvent)
109 {
110 SetEvent(Console->UnpauseEvent);
111 CloseHandle(Console->UnpauseEvent);
112 Console->UnpauseEvent = NULL;
113
114 CsrNotifyWait(&Console->WriteWaitQueue,
115 TRUE,
116 NULL,
117 NULL);
118 if (!IsListEmpty(&Console->WriteWaitQueue))
119 {
120 CsrDereferenceWait(&Console->WriteWaitQueue);
121 }
122 }
123 }
124 #endif
125
126
127 NTSTATUS FASTCALL
128 ConSrvGetConsole(PCONSOLE_PROCESS_DATA ProcessData,
129 PCONSOLE* Console,
130 BOOL LockConsole)
131 {
132 NTSTATUS Status = STATUS_SUCCESS;
133 PCONSOLE ProcessConsole;
134
135 ASSERT(Console);
136 *Console = NULL;
137
138 // RtlEnterCriticalSection(&ProcessData->HandleTableLock);
139
140 Status = ConDrvGetConsole(&ProcessConsole, ProcessData->ConsoleHandle, LockConsole);
141 if (NT_SUCCESS(Status)) *Console = ProcessConsole;
142
143 // RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
144 return Status;
145 }
146
147 VOID FASTCALL
148 ConSrvReleaseConsole(PCONSOLE Console,
149 BOOL WasConsoleLocked)
150 {
151 /* Just call the driver */
152 ConDrvReleaseConsole(Console, WasConsoleLocked);
153 }
154
155
156 NTSTATUS NTAPI
157 ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
158 OUT PCONSOLE* NewConsole,
159 IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
160 IN ULONG ConsoleLeaderProcessId)
161 {
162 NTSTATUS Status;
163 HANDLE ConsoleHandle;
164 PCONSOLE Console;
165 CONSOLE_INFO ConsoleInfo;
166 SIZE_T Length = 0;
167 ULONG i = 0;
168 FRONTEND FrontEnd;
169
170 if (NewConsole == NULL || ConsoleStartInfo == NULL)
171 return STATUS_INVALID_PARAMETER;
172
173 *NewConsole = NULL;
174
175 /*
176 * Load the console settings
177 */
178
179 /* 1. Load the default settings */
180 ConSrvGetDefaultSettings(&ConsoleInfo, ConsoleLeaderProcessId);
181
182 /* 2. Get the title of the console (initialize ConsoleInfo.ConsoleTitle) */
183 Length = min(wcslen(ConsoleStartInfo->ConsoleTitle),
184 sizeof(ConsoleInfo.ConsoleTitle) / sizeof(ConsoleInfo.ConsoleTitle[0]) - 1);
185 wcsncpy(ConsoleInfo.ConsoleTitle, ConsoleStartInfo->ConsoleTitle, Length);
186 ConsoleInfo.ConsoleTitle[Length] = L'\0';
187
188
189 /*
190 * Choose an adequate terminal front-end to load, and load it
191 */
192 Status = STATUS_SUCCESS;
193 for (i = 0; i < sizeof(FrontEndLoadingMethods) / sizeof(FrontEndLoadingMethods[0]); ++i)
194 {
195 DPRINT("CONSRV: Trying to load %s terminal emulator...\n", FrontEndLoadingMethods[i].FrontEndName);
196 Status = FrontEndLoadingMethods[i].FrontEndLoad(&FrontEnd,
197 &ConsoleInfo,
198 ConsoleStartInfo,
199 ConsoleLeaderProcessId);
200 if (NT_SUCCESS(Status))
201 {
202 DPRINT("CONSRV: %s terminal emulator loaded successfully\n", FrontEndLoadingMethods[i].FrontEndName);
203 break;
204 }
205 else
206 {
207 DPRINT1("CONSRV: Loading %s terminal emulator failed, Status = 0x%08lx , continuing...\n", FrontEndLoadingMethods[i].FrontEndName, Status);
208 }
209 }
210
211 if (!NT_SUCCESS(Status))
212 {
213 DPRINT1("CONSRV: Failed to initialize a frontend, Status = 0x%08lx\n", Status);
214 return Status;
215 }
216
217 DPRINT("CONSRV: Frontend initialized\n");
218
219
220 /******************************************************************************/
221 /*
222 * 4. Load the remaining console settings via the registry.
223 */
224 if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
225 {
226 /*
227 * Either we weren't created by an app launched via a shell-link,
228 * or we failed to load shell-link console properties.
229 * Therefore, load the console infos for the application from the registry.
230 */
231 ConSrvReadUserSettings(&ConsoleInfo, ConsoleLeaderProcessId);
232
233 /*
234 * Now, update them with the properties the user might gave to us
235 * via the STARTUPINFO structure before calling CreateProcess
236 * (and which was transmitted via the ConsoleStartInfo structure).
237 * We therefore overwrite the values read in the registry.
238 */
239 if (ConsoleStartInfo->dwStartupFlags & STARTF_USEFILLATTRIBUTE)
240 {
241 ConsoleInfo.ScreenAttrib = (USHORT)ConsoleStartInfo->wFillAttribute;
242 }
243 if (ConsoleStartInfo->dwStartupFlags & STARTF_USECOUNTCHARS)
244 {
245 ConsoleInfo.ScreenBufferSize = ConsoleStartInfo->dwScreenBufferSize;
246 }
247 if (ConsoleStartInfo->dwStartupFlags & STARTF_USESIZE)
248 {
249 ConsoleInfo.ConsoleSize = ConsoleStartInfo->dwWindowSize;
250 }
251 }
252
253 /* Set-up the code page */
254 ConsoleInfo.CodePage = GetOEMCP();
255 /******************************************************************************/
256
257 Status = ConDrvInitConsole(&ConsoleHandle,
258 &Console,
259 &ConsoleInfo,
260 ConsoleLeaderProcessId);
261 if (!NT_SUCCESS(Status))
262 {
263 DPRINT1("Creating a new console failed, Status = 0x%08lx\n", Status);
264 FrontEndLoadingMethods[i].FrontEndUnload(&FrontEnd);
265 return Status;
266 }
267
268 ASSERT(Console);
269 DPRINT("Console initialized\n");
270
271 Status = ConDrvRegisterFrontEnd(Console, &FrontEnd);
272 if (!NT_SUCCESS(Status))
273 {
274 DPRINT1("Failed to register frontend to the given console, Status = 0x%08lx\n", Status);
275 ConDrvDeleteConsole(Console);
276 FrontEndLoadingMethods[i].FrontEndUnload(&FrontEnd);
277 return Status;
278 }
279 DPRINT("FrontEnd registered\n");
280
281 /* Return the newly created console to the caller and a success code too */
282 *NewConsoleHandle = ConsoleHandle;
283 *NewConsole = Console;
284 return STATUS_SUCCESS;
285 }
286
287 VOID NTAPI
288 ConSrvDeleteConsole(PCONSOLE Console)
289 {
290 DPRINT("ConSrvDeleteConsole\n");
291
292 /* Just call the driver. ConSrvDeregisterFrontEnd is called on-demand. */
293 ConDrvDeleteConsole(Console);
294 }
295
296
297 /* PUBLIC SERVER APIS *********************************************************/
298
299 CSR_API(SrvAllocConsole)
300 {
301 NTSTATUS Status = STATUS_SUCCESS;
302 PCONSOLE_ALLOCCONSOLE AllocConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.AllocConsoleRequest;
303 PCSR_PROCESS CsrProcess = CsrGetClientThread()->Process;
304 PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
305
306 if (ProcessData->ConsoleHandle != NULL)
307 {
308 DPRINT1("Process already has a console\n");
309 return STATUS_ACCESS_DENIED;
310 }
311
312 if (!CsrValidateMessageBuffer(ApiMessage,
313 (PVOID*)&AllocConsoleRequest->ConsoleStartInfo,
314 1,
315 sizeof(CONSOLE_START_INFO)))
316 {
317 return STATUS_INVALID_PARAMETER;
318 }
319
320 /* Initialize a new Console owned by the Console Leader Process */
321 Status = ConSrvAllocateConsole(ProcessData,
322 &AllocConsoleRequest->InputHandle,
323 &AllocConsoleRequest->OutputHandle,
324 &AllocConsoleRequest->ErrorHandle,
325 AllocConsoleRequest->ConsoleStartInfo);
326 if (!NT_SUCCESS(Status))
327 {
328 DPRINT1("Console allocation failed\n");
329 return Status;
330 }
331
332 /* Return the console handle and the input wait handle to the caller */
333 AllocConsoleRequest->ConsoleHandle = ProcessData->ConsoleHandle;
334 AllocConsoleRequest->InputWaitHandle = ProcessData->ConsoleEvent;
335
336 /* Set the Property-Dialog and Control-Dispatcher handlers */
337 ProcessData->PropDispatcher = AllocConsoleRequest->PropDispatcher;
338 ProcessData->CtrlDispatcher = AllocConsoleRequest->CtrlDispatcher;
339
340 return STATUS_SUCCESS;
341 }
342
343 CSR_API(SrvAttachConsole)
344 {
345 NTSTATUS Status = STATUS_SUCCESS;
346 PCONSOLE_ATTACHCONSOLE AttachConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.AttachConsoleRequest;
347 PCSR_PROCESS SourceProcess = NULL; // The parent process.
348 PCSR_PROCESS TargetProcess = CsrGetClientThread()->Process; // Ourselves.
349 HANDLE ProcessId = ULongToHandle(AttachConsoleRequest->ProcessId);
350 PCONSOLE_PROCESS_DATA SourceProcessData, TargetProcessData;
351
352 TargetProcessData = ConsoleGetPerProcessData(TargetProcess);
353
354 if (TargetProcessData->ConsoleHandle != NULL)
355 {
356 DPRINT1("Process already has a console\n");
357 return STATUS_ACCESS_DENIED;
358 }
359
360 /* Check whether we try to attach to the parent's console */
361 if (ProcessId == ULongToHandle(ATTACH_PARENT_PROCESS))
362 {
363 PROCESS_BASIC_INFORMATION ProcessInfo;
364 ULONG Length = sizeof(ProcessInfo);
365
366 /* Get the real parent's ID */
367
368 Status = NtQueryInformationProcess(TargetProcess->ProcessHandle,
369 ProcessBasicInformation,
370 &ProcessInfo,
371 Length, &Length);
372 if (!NT_SUCCESS(Status))
373 {
374 DPRINT1("SrvAttachConsole - Cannot retrieve basic process info, Status = %lu\n", Status);
375 return Status;
376 }
377
378 ProcessId = ULongToHandle(ProcessInfo.InheritedFromUniqueProcessId);
379 }
380
381 /* Lock the source process via its PID */
382 Status = CsrLockProcessByClientId(ProcessId, &SourceProcess);
383 if (!NT_SUCCESS(Status)) return Status;
384
385 SourceProcessData = ConsoleGetPerProcessData(SourceProcess);
386
387 if (SourceProcessData->ConsoleHandle == NULL)
388 {
389 Status = STATUS_INVALID_HANDLE;
390 goto Quit;
391 }
392
393 /*
394 * Inherit the console from the parent,
395 * if any, otherwise return an error.
396 */
397 Status = ConSrvInheritConsole(TargetProcessData,
398 SourceProcessData->ConsoleHandle,
399 TRUE,
400 &AttachConsoleRequest->InputHandle,
401 &AttachConsoleRequest->OutputHandle,
402 &AttachConsoleRequest->ErrorHandle);
403 if (!NT_SUCCESS(Status))
404 {
405 DPRINT1("Console inheritance failed\n");
406 goto Quit;
407 }
408
409 /* Return the console handle and the input wait handle to the caller */
410 AttachConsoleRequest->ConsoleHandle = TargetProcessData->ConsoleHandle;
411 AttachConsoleRequest->InputWaitHandle = TargetProcessData->ConsoleEvent;
412
413 /* Set the Property-Dialog and Control-Dispatcher handlers */
414 TargetProcessData->PropDispatcher = AttachConsoleRequest->PropDispatcher;
415 TargetProcessData->CtrlDispatcher = AttachConsoleRequest->CtrlDispatcher;
416
417 Status = STATUS_SUCCESS;
418
419 Quit:
420 /* Unlock the "source" process and exit */
421 CsrUnlockProcess(SourceProcess);
422 return Status;
423 }
424
425 CSR_API(SrvFreeConsole)
426 {
427 ConSrvRemoveConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process));
428 return STATUS_SUCCESS;
429 }
430
431 NTSTATUS NTAPI
432 ConDrvGetConsoleMode(IN PCONSOLE Console,
433 IN PCONSOLE_IO_OBJECT Object,
434 OUT PULONG ConsoleMode);
435 CSR_API(SrvGetConsoleMode)
436 {
437 NTSTATUS Status;
438 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleModeRequest;
439 PCONSOLE_IO_OBJECT Object;
440
441 Status = ConSrvGetObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
442 ConsoleModeRequest->ConsoleHandle,
443 &Object, NULL, GENERIC_READ, TRUE, 0);
444 if (!NT_SUCCESS(Status)) return Status;
445
446 Status = ConDrvGetConsoleMode(Object->Console, Object,
447 &ConsoleModeRequest->ConsoleMode);
448
449 ConSrvReleaseObject(Object, TRUE);
450 return Status;
451 }
452
453 NTSTATUS NTAPI
454 ConDrvSetConsoleMode(IN PCONSOLE Console,
455 IN PCONSOLE_IO_OBJECT Object,
456 IN ULONG ConsoleMode);
457 CSR_API(SrvSetConsoleMode)
458 {
459 NTSTATUS Status;
460 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleModeRequest;
461 PCONSOLE_IO_OBJECT Object;
462
463 Status = ConSrvGetObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
464 ConsoleModeRequest->ConsoleHandle,
465 &Object, NULL, GENERIC_WRITE, TRUE, 0);
466 if (!NT_SUCCESS(Status)) return Status;
467
468 Status = ConDrvSetConsoleMode(Object->Console, Object,
469 ConsoleModeRequest->ConsoleMode);
470
471 ConSrvReleaseObject(Object, TRUE);
472 return Status;
473 }
474
475 NTSTATUS NTAPI
476 ConDrvGetConsoleTitle(IN PCONSOLE Console,
477 IN OUT PWCHAR Title,
478 IN OUT PULONG BufLength);
479 CSR_API(SrvGetConsoleTitle)
480 {
481 NTSTATUS Status;
482 PCONSOLE_GETSETCONSOLETITLE TitleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.TitleRequest;
483 PCONSOLE Console;
484
485 if (!CsrValidateMessageBuffer(ApiMessage,
486 (PVOID)&TitleRequest->Title,
487 TitleRequest->Length,
488 sizeof(BYTE)))
489 {
490 return STATUS_INVALID_PARAMETER;
491 }
492
493 Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
494 if (!NT_SUCCESS(Status))
495 {
496 DPRINT1("Can't get console\n");
497 return Status;
498 }
499
500 Status = ConDrvGetConsoleTitle(Console,
501 TitleRequest->Title,
502 &TitleRequest->Length);
503
504 ConSrvReleaseConsole(Console, TRUE);
505 return Status;
506 }
507
508 NTSTATUS NTAPI
509 ConDrvSetConsoleTitle(IN PCONSOLE Console,
510 IN PWCHAR Title,
511 IN ULONG BufLength);
512 CSR_API(SrvSetConsoleTitle)
513 {
514 NTSTATUS Status;
515 PCONSOLE_GETSETCONSOLETITLE TitleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.TitleRequest;
516 PCONSOLE Console;
517
518 if (!CsrValidateMessageBuffer(ApiMessage,
519 (PVOID)&TitleRequest->Title,
520 TitleRequest->Length,
521 sizeof(BYTE)))
522 {
523 return STATUS_INVALID_PARAMETER;
524 }
525
526 Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
527 if (!NT_SUCCESS(Status))
528 {
529 DPRINT1("Can't get console\n");
530 return Status;
531 }
532
533 Status = ConDrvSetConsoleTitle(Console,
534 TitleRequest->Title,
535 TitleRequest->Length);
536
537 if (NT_SUCCESS(Status)) TermChangeTitle(Console);
538
539 ConSrvReleaseConsole(Console, TRUE);
540 return Status;
541 }
542
543 NTSTATUS NTAPI
544 ConDrvGetConsoleCP(IN PCONSOLE Console,
545 OUT PUINT CodePage,
546 IN BOOLEAN InputCP);
547 CSR_API(SrvGetConsoleCP)
548 {
549 NTSTATUS Status;
550 PCONSOLE_GETSETINPUTOUTPUTCP ConsoleCPRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleCPRequest;
551 PCONSOLE Console;
552
553 DPRINT("SrvGetConsoleCP, getting %s Code Page\n",
554 ConsoleCPRequest->InputCP ? "Input" : "Output");
555
556 Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
557 if (!NT_SUCCESS(Status)) return Status;
558
559 Status = ConDrvGetConsoleCP(Console,
560 &ConsoleCPRequest->CodePage,
561 ConsoleCPRequest->InputCP);
562
563 ConSrvReleaseConsole(Console, TRUE);
564 return Status;
565 }
566
567 NTSTATUS NTAPI
568 ConDrvSetConsoleCP(IN PCONSOLE Console,
569 IN UINT CodePage,
570 IN BOOLEAN InputCP);
571 CSR_API(SrvSetConsoleCP)
572 {
573 NTSTATUS Status = STATUS_INVALID_PARAMETER;
574 PCONSOLE_GETSETINPUTOUTPUTCP ConsoleCPRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleCPRequest;
575 PCONSOLE Console;
576
577 DPRINT("SrvSetConsoleCP, setting %s Code Page\n",
578 ConsoleCPRequest->InputCP ? "Input" : "Output");
579
580 Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
581 if (!NT_SUCCESS(Status)) return Status;
582
583 Status = ConDrvSetConsoleCP(Console,
584 ConsoleCPRequest->CodePage,
585 ConsoleCPRequest->InputCP);
586
587 ConSrvReleaseConsole(Console, TRUE);
588 return Status;
589 }
590
591 NTSTATUS NTAPI
592 ConDrvGetConsoleProcessList(IN PCONSOLE Console,
593 IN OUT PULONG ProcessIdsList,
594 IN ULONG MaxIdListItems,
595 OUT PULONG ProcessIdsTotal);
596 CSR_API(SrvGetConsoleProcessList)
597 {
598 NTSTATUS Status;
599 PCONSOLE_GETPROCESSLIST GetProcessListRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetProcessListRequest;
600 PCONSOLE Console;
601
602 if (!CsrValidateMessageBuffer(ApiMessage,
603 (PVOID)&GetProcessListRequest->pProcessIds,
604 GetProcessListRequest->nMaxIds,
605 sizeof(DWORD)))
606 {
607 return STATUS_INVALID_PARAMETER;
608 }
609
610 Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
611 if (!NT_SUCCESS(Status)) return Status;
612
613 Status = ConDrvGetConsoleProcessList(Console,
614 GetProcessListRequest->pProcessIds,
615 GetProcessListRequest->nMaxIds,
616 &GetProcessListRequest->nProcessIdsTotal);
617
618 ConSrvReleaseConsole(Console, TRUE);
619 return Status;
620 }
621
622 CSR_API(SrvGenerateConsoleCtrlEvent)
623 {
624 NTSTATUS Status;
625 PCONSOLE_GENERATECTRLEVENT GenerateCtrlEventRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GenerateCtrlEventRequest;
626 PCONSOLE Console;
627
628 Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
629 if (!NT_SUCCESS(Status)) return Status;
630
631 Status = ConDrvConsoleProcessCtrlEvent(Console,
632 GenerateCtrlEventRequest->ProcessGroup,
633 GenerateCtrlEventRequest->Event);
634
635 ConSrvReleaseConsole(Console, TRUE);
636 return Status;
637 }
638
639 CSR_API(SrvConsoleNotifyLastClose)
640 {
641 DPRINT1("%s not yet implemented\n", __FUNCTION__);
642 return STATUS_NOT_IMPLEMENTED;
643 }
644
645
646
647 CSR_API(SrvGetConsoleMouseInfo)
648 {
649 DPRINT1("%s not yet implemented\n", __FUNCTION__);
650 return STATUS_NOT_IMPLEMENTED;
651 }
652
653 CSR_API(SrvSetConsoleKeyShortcuts)
654 {
655 DPRINT1("%s not yet implemented\n", __FUNCTION__);
656 return STATUS_NOT_IMPLEMENTED;
657 }
658
659 CSR_API(SrvGetConsoleKeyboardLayoutName)
660 {
661 DPRINT1("%s not yet implemented\n", __FUNCTION__);
662 return STATUS_NOT_IMPLEMENTED;
663 }
664
665 CSR_API(SrvGetConsoleCharType)
666 {
667 DPRINT1("%s not yet implemented\n", __FUNCTION__);
668 return STATUS_NOT_IMPLEMENTED;
669 }
670
671 CSR_API(SrvSetConsoleLocalEUDC)
672 {
673 DPRINT1("%s not yet implemented\n", __FUNCTION__);
674 return STATUS_NOT_IMPLEMENTED;
675 }
676
677 CSR_API(SrvSetConsoleCursorMode)
678 {
679 DPRINT1("%s not yet implemented\n", __FUNCTION__);
680 return STATUS_NOT_IMPLEMENTED;
681 }
682
683 CSR_API(SrvGetConsoleCursorMode)
684 {
685 DPRINT1("%s not yet implemented\n", __FUNCTION__);
686 return STATUS_NOT_IMPLEMENTED;
687 }
688
689 CSR_API(SrvGetConsoleNlsMode)
690 {
691 DPRINT1("%s not yet implemented\n", __FUNCTION__);
692 return STATUS_NOT_IMPLEMENTED;
693 }
694
695 CSR_API(SrvSetConsoleNlsMode)
696 {
697 DPRINT1("%s not yet implemented\n", __FUNCTION__);
698 return STATUS_NOT_IMPLEMENTED;
699 }
700
701 CSR_API(SrvGetConsoleLangId)
702 {
703 DPRINT1("%s not yet implemented\n", __FUNCTION__);
704 return STATUS_NOT_IMPLEMENTED;
705 }
706
707 /* EOF */