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
8 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
11 /* INCLUDES *******************************************************************/
14 #include "include/conio.h"
15 #include "include/term.h"
20 #include "conoutput.h"
21 #include "lineinput.h"
22 #include "include/settings.h"
24 #include "frontends/gui/guiterm.h"
25 #ifdef TUITERM_COMPILE
26 #include "frontends/tui/tuiterm.h"
29 #include "include/console.h"
37 /* GLOBALS ********************************************************************/
40 #ifdef TUITERM_COMPILE
42 TuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd
,
43 IN OUT PCONSOLE_INFO ConsoleInfo
,
44 IN OUT PVOID ExtraConsoleInfo
,
47 TuiUnloadFrontEnd(IN OUT PFRONTEND FrontEnd
);
51 GuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd
,
52 IN OUT PCONSOLE_INFO ConsoleInfo
,
53 IN OUT PVOID ExtraConsoleInfo
,
56 GuiUnloadFrontEnd(IN OUT PFRONTEND FrontEnd
);
60 NTSTATUS (NTAPI
*FRONTEND_LOAD
)(IN OUT PFRONTEND FrontEnd
,
61 IN OUT PCONSOLE_INFO ConsoleInfo
,
62 IN OUT PVOID ExtraConsoleInfo
,
66 NTSTATUS (NTAPI
*FRONTEND_UNLOAD
)(IN OUT PFRONTEND FrontEnd
);
69 * If we are not in GUI-mode, start the text-mode terminal emulator.
70 * If we fail, try to start the GUI-mode terminal emulator.
72 * Try to open the GUI-mode terminal emulator. Two cases are possible:
73 * - We are in GUI-mode, therefore GuiMode == TRUE, the previous test-case
74 * failed and we start GUI-mode terminal emulator.
75 * - We are in text-mode, therefore GuiMode == FALSE, the previous test-case
76 * succeeded BUT we failed at starting text-mode terminal emulator.
77 * Then GuiMode was switched to TRUE in order to try to open the GUI-mode
78 * terminal emulator (Win32k will automatically switch to graphical mode,
79 * therefore no additional code is needed).
83 * NOTE: Each entry of the table should be retrieved when loading a front-end
84 * (examples of the CSR servers which register some data for CSRSS).
88 CHAR FrontEndName
[80];
89 FRONTEND_LOAD FrontEndLoad
;
90 FRONTEND_UNLOAD FrontEndUnload
;
91 } FrontEndLoadingMethods
[] =
93 #ifdef TUITERM_COMPILE
94 {"TUI", TuiLoadFrontEnd
, TuiUnloadFrontEnd
},
96 {"GUI", GuiLoadFrontEnd
, GuiUnloadFrontEnd
},
98 // {"Not found", 0, NULL}
102 /* PRIVATE FUNCTIONS **********************************************************/
106 ConioPause(PCONSOLE Console
, UINT Flags
)
108 Console
->PauseFlags
|= Flags
;
109 if (!Console
->UnpauseEvent
)
110 Console
->UnpauseEvent
= CreateEvent(NULL
, TRUE
, FALSE
, NULL
);
114 ConioUnpause(PCONSOLE Console
, UINT Flags
)
116 Console
->PauseFlags
&= ~Flags
;
118 // if ((Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION)) == 0)
119 if (Console
->PauseFlags
== 0 && Console
->UnpauseEvent
)
121 SetEvent(Console
->UnpauseEvent
);
122 CloseHandle(Console
->UnpauseEvent
);
123 Console
->UnpauseEvent
= NULL
;
125 CsrNotifyWait(&Console
->WriteWaitQueue
,
129 if (!IsListEmpty(&Console
->WriteWaitQueue
))
131 CsrDereferenceWait(&Console
->WriteWaitQueue
);
139 ConSrvGetConsole(PCONSOLE_PROCESS_DATA ProcessData
,
143 NTSTATUS Status
= STATUS_SUCCESS
;
144 PCONSOLE ProcessConsole
;
149 // RtlEnterCriticalSection(&ProcessData->HandleTableLock);
151 Status
= ConDrvGetConsole(&ProcessConsole
, ProcessData
->ConsoleHandle
, LockConsole
);
152 if (NT_SUCCESS(Status
)) *Console
= ProcessConsole
;
154 // RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
159 ConSrvReleaseConsole(PCONSOLE Console
,
160 BOOL WasConsoleLocked
)
162 /* Just call the driver */
163 ConDrvReleaseConsole(Console
, WasConsoleLocked
);
168 ConSrvInitConsole(OUT PHANDLE NewConsoleHandle
,
169 OUT PCONSOLE
* NewConsole
,
170 IN OUT PCONSOLE_START_INFO ConsoleStartInfo
,
171 IN ULONG ConsoleLeaderProcessId
)
174 HANDLE ConsoleHandle
;
176 CONSOLE_INFO ConsoleInfo
;
181 if (NewConsole
== NULL
|| ConsoleStartInfo
== NULL
)
182 return STATUS_INVALID_PARAMETER
;
187 * Load the console settings
190 /* 1. Load the default settings */
191 ConSrvGetDefaultSettings(&ConsoleInfo
, ConsoleLeaderProcessId
);
193 /* 2. Get the title of the console (initialize ConsoleInfo.ConsoleTitle) */
194 Length
= min(wcslen(ConsoleStartInfo
->ConsoleTitle
),
195 sizeof(ConsoleInfo
.ConsoleTitle
) / sizeof(ConsoleInfo
.ConsoleTitle
[0]) - 1);
196 wcsncpy(ConsoleInfo
.ConsoleTitle
, ConsoleStartInfo
->ConsoleTitle
, Length
);
197 ConsoleInfo
.ConsoleTitle
[Length
] = L
'\0';
201 * Choose an adequate terminal front-end to load, and load it
203 Status
= STATUS_SUCCESS
;
204 for (i
= 0; i
< sizeof(FrontEndLoadingMethods
) / sizeof(FrontEndLoadingMethods
[0]); ++i
)
206 DPRINT("CONSRV: Trying to load %s terminal emulator...\n", FrontEndLoadingMethods
[i
].FrontEndName
);
207 Status
= FrontEndLoadingMethods
[i
].FrontEndLoad(&FrontEnd
,
210 ConsoleLeaderProcessId
);
211 if (NT_SUCCESS(Status
))
213 DPRINT("CONSRV: %s terminal emulator loaded successfully\n", FrontEndLoadingMethods
[i
].FrontEndName
);
218 DPRINT1("CONSRV: Loading %s terminal emulator failed, Status = 0x%08lx , continuing...\n", FrontEndLoadingMethods
[i
].FrontEndName
, Status
);
222 if (!NT_SUCCESS(Status
))
224 DPRINT1("CONSRV: Failed to initialize a frontend, Status = 0x%08lx\n", Status
);
228 DPRINT("CONSRV: Frontend initialized\n");
231 /******************************************************************************/
233 * 4. Load the remaining console settings via the registry.
235 if ((ConsoleStartInfo
->dwStartupFlags
& STARTF_TITLEISLINKNAME
) == 0)
238 * Either we weren't created by an app launched via a shell-link,
239 * or we failed to load shell-link console properties.
240 * Therefore, load the console infos for the application from the registry.
242 ConSrvReadUserSettings(&ConsoleInfo
, ConsoleLeaderProcessId
);
245 * Now, update them with the properties the user might gave to us
246 * via the STARTUPINFO structure before calling CreateProcess
247 * (and which was transmitted via the ConsoleStartInfo structure).
248 * We therefore overwrite the values read in the registry.
250 if (ConsoleStartInfo
->dwStartupFlags
& STARTF_USEFILLATTRIBUTE
)
252 ConsoleInfo
.ScreenAttrib
= (USHORT
)ConsoleStartInfo
->wFillAttribute
;
254 if (ConsoleStartInfo
->dwStartupFlags
& STARTF_USECOUNTCHARS
)
256 ConsoleInfo
.ScreenBufferSize
= ConsoleStartInfo
->dwScreenBufferSize
;
258 if (ConsoleStartInfo
->dwStartupFlags
& STARTF_USESIZE
)
260 ConsoleInfo
.ConsoleSize
= ConsoleStartInfo
->dwWindowSize
;
264 /* Set-up the code page */
265 ConsoleInfo
.CodePage
= GetOEMCP();
266 /******************************************************************************/
268 Status
= ConDrvInitConsole(&ConsoleHandle
,
271 ConsoleLeaderProcessId
);
272 if (!NT_SUCCESS(Status
))
274 DPRINT1("Creating a new console failed, Status = 0x%08lx\n", Status
);
275 FrontEndLoadingMethods
[i
].FrontEndUnload(&FrontEnd
);
280 DPRINT("Console initialized\n");
282 Status
= ConDrvRegisterFrontEnd(Console
, &FrontEnd
);
283 if (!NT_SUCCESS(Status
))
285 DPRINT1("Failed to register frontend to the given console, Status = 0x%08lx\n", Status
);
286 ConDrvDeleteConsole(Console
);
287 FrontEndLoadingMethods
[i
].FrontEndUnload(&FrontEnd
);
290 DPRINT("FrontEnd registered\n");
292 /* Return the newly created console to the caller and a success code too */
293 *NewConsoleHandle
= ConsoleHandle
;
294 *NewConsole
= Console
;
295 return STATUS_SUCCESS
;
299 ConSrvDeleteConsole(PCONSOLE Console
)
301 DPRINT("ConSrvDeleteConsole\n");
303 /* Just call the driver. ConSrvDeregisterFrontEnd is called on-demand. */
304 ConDrvDeleteConsole(Console
);
308 /* PUBLIC SERVER APIS *********************************************************/
310 CSR_API(SrvAllocConsole
)
312 NTSTATUS Status
= STATUS_SUCCESS
;
313 PCONSOLE_ALLOCCONSOLE AllocConsoleRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.AllocConsoleRequest
;
314 PCSR_PROCESS CsrProcess
= CsrGetClientThread()->Process
;
315 PCONSOLE_PROCESS_DATA ProcessData
= ConsoleGetPerProcessData(CsrProcess
);
317 if (ProcessData
->ConsoleHandle
!= NULL
)
319 DPRINT1("Process already has a console\n");
320 return STATUS_ACCESS_DENIED
;
323 if (!CsrValidateMessageBuffer(ApiMessage
,
324 (PVOID
*)&AllocConsoleRequest
->ConsoleStartInfo
,
326 sizeof(CONSOLE_START_INFO
)))
328 return STATUS_INVALID_PARAMETER
;
331 /* Initialize a new Console owned by the Console Leader Process */
332 Status
= ConSrvAllocateConsole(ProcessData
,
333 &AllocConsoleRequest
->InputHandle
,
334 &AllocConsoleRequest
->OutputHandle
,
335 &AllocConsoleRequest
->ErrorHandle
,
336 AllocConsoleRequest
->ConsoleStartInfo
);
337 if (!NT_SUCCESS(Status
))
339 DPRINT1("Console allocation failed\n");
343 /* Return the console handle and the input wait handle to the caller */
344 AllocConsoleRequest
->ConsoleHandle
= ProcessData
->ConsoleHandle
;
345 AllocConsoleRequest
->InputWaitHandle
= ProcessData
->ConsoleEvent
;
347 /* Set the Property-Dialog and Control-Dispatcher handlers */
348 ProcessData
->PropDispatcher
= AllocConsoleRequest
->PropDispatcher
;
349 ProcessData
->CtrlDispatcher
= AllocConsoleRequest
->CtrlDispatcher
;
351 return STATUS_SUCCESS
;
354 CSR_API(SrvAttachConsole
)
356 NTSTATUS Status
= STATUS_SUCCESS
;
357 PCONSOLE_ATTACHCONSOLE AttachConsoleRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.AttachConsoleRequest
;
358 PCSR_PROCESS SourceProcess
= NULL
; // The parent process.
359 PCSR_PROCESS TargetProcess
= CsrGetClientThread()->Process
; // Ourselves.
360 HANDLE ProcessId
= ULongToHandle(AttachConsoleRequest
->ProcessId
);
361 PCONSOLE_PROCESS_DATA SourceProcessData
, TargetProcessData
;
363 TargetProcessData
= ConsoleGetPerProcessData(TargetProcess
);
365 if (TargetProcessData
->ConsoleHandle
!= NULL
)
367 DPRINT1("Process already has a console\n");
368 return STATUS_ACCESS_DENIED
;
371 /* Check whether we try to attach to the parent's console */
372 if (ProcessId
== ULongToHandle(ATTACH_PARENT_PROCESS
))
374 PROCESS_BASIC_INFORMATION ProcessInfo
;
375 ULONG Length
= sizeof(ProcessInfo
);
377 /* Get the real parent's ID */
379 Status
= NtQueryInformationProcess(TargetProcess
->ProcessHandle
,
380 ProcessBasicInformation
,
383 if (!NT_SUCCESS(Status
))
385 DPRINT1("SrvAttachConsole - Cannot retrieve basic process info, Status = %lu\n", Status
);
389 ProcessId
= ULongToHandle(ProcessInfo
.InheritedFromUniqueProcessId
);
392 /* Lock the source process via its PID */
393 Status
= CsrLockProcessByClientId(ProcessId
, &SourceProcess
);
394 if (!NT_SUCCESS(Status
)) return Status
;
396 SourceProcessData
= ConsoleGetPerProcessData(SourceProcess
);
398 if (SourceProcessData
->ConsoleHandle
== NULL
)
400 Status
= STATUS_INVALID_HANDLE
;
405 * Inherit the console from the parent,
406 * if any, otherwise return an error.
408 Status
= ConSrvInheritConsole(TargetProcessData
,
409 SourceProcessData
->ConsoleHandle
,
411 &AttachConsoleRequest
->InputHandle
,
412 &AttachConsoleRequest
->OutputHandle
,
413 &AttachConsoleRequest
->ErrorHandle
);
414 if (!NT_SUCCESS(Status
))
416 DPRINT1("Console inheritance failed\n");
420 /* Return the console handle and the input wait handle to the caller */
421 AttachConsoleRequest
->ConsoleHandle
= TargetProcessData
->ConsoleHandle
;
422 AttachConsoleRequest
->InputWaitHandle
= TargetProcessData
->ConsoleEvent
;
424 /* Set the Property-Dialog and Control-Dispatcher handlers */
425 TargetProcessData
->PropDispatcher
= AttachConsoleRequest
->PropDispatcher
;
426 TargetProcessData
->CtrlDispatcher
= AttachConsoleRequest
->CtrlDispatcher
;
428 Status
= STATUS_SUCCESS
;
431 /* Unlock the "source" process and exit */
432 CsrUnlockProcess(SourceProcess
);
436 CSR_API(SrvFreeConsole
)
438 ConSrvRemoveConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process
));
439 return STATUS_SUCCESS
;
443 ConDrvGetConsoleMode(IN PCONSOLE Console
,
444 IN PCONSOLE_IO_OBJECT Object
,
445 OUT PULONG ConsoleMode
);
446 CSR_API(SrvGetConsoleMode
)
449 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleModeRequest
;
450 PCONSOLE_IO_OBJECT Object
;
452 Status
= ConSrvGetObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process
),
453 ConsoleModeRequest
->ConsoleHandle
,
454 &Object
, NULL
, GENERIC_READ
, TRUE
, 0);
455 if (!NT_SUCCESS(Status
)) return Status
;
457 Status
= ConDrvGetConsoleMode(Object
->Console
, Object
,
458 &ConsoleModeRequest
->ConsoleMode
);
460 ConSrvReleaseObject(Object
, TRUE
);
465 ConDrvSetConsoleMode(IN PCONSOLE Console
,
466 IN PCONSOLE_IO_OBJECT Object
,
467 IN ULONG ConsoleMode
);
468 CSR_API(SrvSetConsoleMode
)
471 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleModeRequest
;
472 PCONSOLE_IO_OBJECT Object
;
474 Status
= ConSrvGetObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process
),
475 ConsoleModeRequest
->ConsoleHandle
,
476 &Object
, NULL
, GENERIC_WRITE
, TRUE
, 0);
477 if (!NT_SUCCESS(Status
)) return Status
;
479 Status
= ConDrvSetConsoleMode(Object
->Console
, Object
,
480 ConsoleModeRequest
->ConsoleMode
);
482 ConSrvReleaseObject(Object
, TRUE
);
487 ConDrvGetConsoleTitle(IN PCONSOLE Console
,
489 IN OUT PULONG BufLength
);
490 CSR_API(SrvGetConsoleTitle
)
493 PCONSOLE_GETSETCONSOLETITLE TitleRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.TitleRequest
;
496 if (!CsrValidateMessageBuffer(ApiMessage
,
497 (PVOID
)&TitleRequest
->Title
,
498 TitleRequest
->Length
,
501 return STATUS_INVALID_PARAMETER
;
504 Status
= ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
, TRUE
);
505 if (!NT_SUCCESS(Status
))
507 DPRINT1("Can't get console\n");
511 Status
= ConDrvGetConsoleTitle(Console
,
513 &TitleRequest
->Length
);
515 ConSrvReleaseConsole(Console
, TRUE
);
520 ConDrvSetConsoleTitle(IN PCONSOLE Console
,
523 CSR_API(SrvSetConsoleTitle
)
526 PCONSOLE_GETSETCONSOLETITLE TitleRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.TitleRequest
;
529 if (!CsrValidateMessageBuffer(ApiMessage
,
530 (PVOID
)&TitleRequest
->Title
,
531 TitleRequest
->Length
,
534 return STATUS_INVALID_PARAMETER
;
537 Status
= ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
, TRUE
);
538 if (!NT_SUCCESS(Status
))
540 DPRINT1("Can't get console\n");
544 Status
= ConDrvSetConsoleTitle(Console
,
546 TitleRequest
->Length
);
548 if (NT_SUCCESS(Status
)) TermChangeTitle(Console
);
550 ConSrvReleaseConsole(Console
, TRUE
);
555 ConDrvGetConsoleCP(IN PCONSOLE Console
,
558 CSR_API(SrvGetConsoleCP
)
561 PCONSOLE_GETSETINPUTOUTPUTCP ConsoleCPRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleCPRequest
;
564 DPRINT("SrvGetConsoleCP, getting %s Code Page\n",
565 ConsoleCPRequest
->InputCP
? "Input" : "Output");
567 Status
= ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
, TRUE
);
568 if (!NT_SUCCESS(Status
)) return Status
;
570 Status
= ConDrvGetConsoleCP(Console
,
571 &ConsoleCPRequest
->CodePage
,
572 ConsoleCPRequest
->InputCP
);
574 ConSrvReleaseConsole(Console
, TRUE
);
579 ConDrvSetConsoleCP(IN PCONSOLE Console
,
582 CSR_API(SrvSetConsoleCP
)
584 NTSTATUS Status
= STATUS_INVALID_PARAMETER
;
585 PCONSOLE_GETSETINPUTOUTPUTCP ConsoleCPRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleCPRequest
;
588 DPRINT("SrvSetConsoleCP, setting %s Code Page\n",
589 ConsoleCPRequest
->InputCP
? "Input" : "Output");
591 Status
= ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
, TRUE
);
592 if (!NT_SUCCESS(Status
)) return Status
;
594 Status
= ConDrvSetConsoleCP(Console
,
595 ConsoleCPRequest
->CodePage
,
596 ConsoleCPRequest
->InputCP
);
598 ConSrvReleaseConsole(Console
, TRUE
);
603 ConDrvGetConsoleProcessList(IN PCONSOLE Console
,
604 IN OUT PULONG ProcessIdsList
,
605 IN ULONG MaxIdListItems
,
606 OUT PULONG ProcessIdsTotal
);
607 CSR_API(SrvGetConsoleProcessList
)
610 PCONSOLE_GETPROCESSLIST GetProcessListRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetProcessListRequest
;
613 if (!CsrValidateMessageBuffer(ApiMessage
,
614 (PVOID
)&GetProcessListRequest
->pProcessIds
,
615 GetProcessListRequest
->nMaxIds
,
618 return STATUS_INVALID_PARAMETER
;
621 Status
= ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
, TRUE
);
622 if (!NT_SUCCESS(Status
)) return Status
;
624 Status
= ConDrvGetConsoleProcessList(Console
,
625 GetProcessListRequest
->pProcessIds
,
626 GetProcessListRequest
->nMaxIds
,
627 &GetProcessListRequest
->nProcessIdsTotal
);
629 ConSrvReleaseConsole(Console
, TRUE
);
633 CSR_API(SrvGenerateConsoleCtrlEvent
)
636 PCONSOLE_GENERATECTRLEVENT GenerateCtrlEventRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GenerateCtrlEventRequest
;
639 Status
= ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
, TRUE
);
640 if (!NT_SUCCESS(Status
)) return Status
;
642 Status
= ConDrvConsoleProcessCtrlEvent(Console
,
643 GenerateCtrlEventRequest
->ProcessGroup
,
644 GenerateCtrlEventRequest
->Event
);
646 ConSrvReleaseConsole(Console
, TRUE
);
650 CSR_API(SrvConsoleNotifyLastClose
)
652 DPRINT1("%s not yet implemented\n", __FUNCTION__
);
653 return STATUS_NOT_IMPLEMENTED
;
658 CSR_API(SrvGetConsoleMouseInfo
)
660 DPRINT1("%s not yet implemented\n", __FUNCTION__
);
661 return STATUS_NOT_IMPLEMENTED
;
664 CSR_API(SrvSetConsoleKeyShortcuts
)
666 DPRINT1("%s not yet implemented\n", __FUNCTION__
);
667 return STATUS_NOT_IMPLEMENTED
;
670 CSR_API(SrvGetConsoleKeyboardLayoutName
)
672 DPRINT1("%s not yet implemented\n", __FUNCTION__
);
673 return STATUS_NOT_IMPLEMENTED
;
676 CSR_API(SrvGetConsoleCharType
)
678 DPRINT1("%s not yet implemented\n", __FUNCTION__
);
679 return STATUS_NOT_IMPLEMENTED
;
682 CSR_API(SrvSetConsoleLocalEUDC
)
684 DPRINT1("%s not yet implemented\n", __FUNCTION__
);
685 return STATUS_NOT_IMPLEMENTED
;
688 CSR_API(SrvSetConsoleCursorMode
)
690 DPRINT1("%s not yet implemented\n", __FUNCTION__
);
691 return STATUS_NOT_IMPLEMENTED
;
694 CSR_API(SrvGetConsoleCursorMode
)
696 DPRINT1("%s not yet implemented\n", __FUNCTION__
);
697 return STATUS_NOT_IMPLEMENTED
;
700 CSR_API(SrvGetConsoleNlsMode
)
702 DPRINT1("%s not yet implemented\n", __FUNCTION__
);
703 return STATUS_NOT_IMPLEMENTED
;
706 CSR_API(SrvSetConsoleNlsMode
)
708 DPRINT1("%s not yet implemented\n", __FUNCTION__
);
709 return STATUS_NOT_IMPLEMENTED
;
712 CSR_API(SrvGetConsoleLangId
)
714 DPRINT1("%s not yet implemented\n", __FUNCTION__
);
715 return STATUS_NOT_IMPLEMENTED
;