2 * reactos/win32ss/user/consrv/conio.c
4 * Console I/O functions
6 * ReactOS Operating System
9 /* INCLUDES ******************************************************************/
15 /* FUNCTIONS *****************************************************************/
18 ConioConsoleFromProcessData(PCSR_PROCESS ProcessData
, PCSRSS_CONSOLE
*Console
)
20 PCSRSS_CONSOLE ProcessConsole
;
22 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
23 ProcessConsole
= ProcessData
->Console
;
28 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
29 return STATUS_INVALID_HANDLE
;
32 InterlockedIncrement(&ProcessConsole
->ReferenceCount
);
33 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
34 EnterCriticalSection(&(ProcessConsole
->Lock
));
35 *Console
= ProcessConsole
;
37 return STATUS_SUCCESS
;
41 ConioConsoleCtrlEventTimeout(DWORD Event
, PCSR_PROCESS ProcessData
, DWORD Timeout
)
45 DPRINT("ConioConsoleCtrlEvent Parent ProcessId = %x\n", ProcessData
->ClientId
.UniqueProcess
);
47 if (ProcessData
->CtrlDispatcher
)
50 Thread
= CreateRemoteThread(ProcessData
->ProcessHandle
, NULL
, 0,
51 (LPTHREAD_START_ROUTINE
) ProcessData
->CtrlDispatcher
,
52 UlongToPtr(Event
), 0, NULL
);
55 DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
58 WaitForSingleObject(Thread
, Timeout
);
64 ConioConsoleCtrlEvent(DWORD Event
, PCSR_PROCESS ProcessData
)
66 ConioConsoleCtrlEventTimeout(Event
, ProcessData
, 0);
69 static NTSTATUS WINAPI
70 CsrInitConsole(PCSRSS_CONSOLE Console
, int ShowCmd
)
73 SECURITY_ATTRIBUTES SecurityAttributes
;
74 PCSRSS_SCREEN_BUFFER NewBuffer
;
79 Console
->Title
.MaximumLength
= Console
->Title
.Length
= 0;
80 Console
->Title
.Buffer
= NULL
;
82 hInst
= GetModuleHandleW(L
"win32csr");
83 if (LoadStringW(hInst
,IDS_COMMAND_PROMPT
,Title
,sizeof(Title
)/sizeof(Title
[0])))
85 RtlCreateUnicodeString(&Console
->Title
, Title
);
89 RtlCreateUnicodeString(&Console
->Title
, L
"Command Prompt");
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();
104 SecurityAttributes
.nLength
= sizeof(SECURITY_ATTRIBUTES
);
105 SecurityAttributes
.lpSecurityDescriptor
= NULL
;
106 SecurityAttributes
.bInheritHandle
= TRUE
;
108 Console
->ActiveEvent
= CreateEventW(&SecurityAttributes
, TRUE
, FALSE
, NULL
);
109 if (NULL
== Console
->ActiveEvent
)
111 RtlFreeUnicodeString(&Console
->Title
);
112 return STATUS_UNSUCCESSFUL
;
114 Console
->PrivateData
= NULL
;
115 InitializeCriticalSection(&Console
->Lock
);
117 GuiMode
= DtbgIsDesktopVisible();
119 /* allocate console screen buffer */
120 NewBuffer
= HeapAlloc(ConSrvHeap
, HEAP_ZERO_MEMORY
, sizeof(CSRSS_SCREEN_BUFFER
));
121 if (NULL
== NewBuffer
)
123 RtlFreeUnicodeString(&Console
->Title
);
124 DeleteCriticalSection(&Console
->Lock
);
125 CloseHandle(Console
->ActiveEvent
);
126 return STATUS_INSUFFICIENT_RESOURCES
;
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
;
136 Status
= TuiInitConsole(Console
);
137 if (! NT_SUCCESS(Status
))
139 DPRINT1("Failed to open text-mode console, switching to gui-mode\n");
145 Status
= GuiInitConsole(Console
, ShowCmd
);
146 if (! NT_SUCCESS(Status
))
148 HeapFree(ConSrvHeap
,0, NewBuffer
);
149 RtlFreeUnicodeString(&Console
->Title
);
150 DeleteCriticalSection(&Console
->Lock
);
151 CloseHandle(Console
->ActiveEvent
);
152 DPRINT1("GuiInitConsole: failed\n");
157 Status
= CsrInitConsoleScreenBuffer(Console
, NewBuffer
);
158 if (! NT_SUCCESS(Status
))
160 ConioCleanupConsole(Console
);
161 RtlFreeUnicodeString(&Console
->Title
);
162 DeleteCriticalSection(&Console
->Lock
);
163 CloseHandle(Console
->ActiveEvent
);
164 HeapFree(ConSrvHeap
, 0, NewBuffer
);
165 DPRINT1("CsrInitConsoleScreenBuffer: failed\n");
169 /* copy buffer contents to screen */
170 ConioDrawConsole(Console
);
172 return STATUS_SUCCESS
;
175 CSR_API(SrvAllocConsole
)
177 PCSR_PROCESS ProcessData
= CsrGetClientThread()->Process
;
178 PCSRSS_CONSOLE Console
;
179 NTSTATUS Status
= STATUS_SUCCESS
;
180 BOOLEAN NewConsole
= FALSE
;
182 DPRINT("SrvAllocConsole\n");
184 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
185 if (ProcessData
->Console
)
187 DPRINT1("Process already has a console\n");
188 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
189 return STATUS_INVALID_PARAMETER
;
192 /* If we don't need a console, then get out of here */
193 if (!ApiMessage
->Data
.AllocConsoleRequest
.ConsoleNeeded
)
195 DPRINT("No console needed\n");
196 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
197 return STATUS_SUCCESS
;
200 /* If we already have one, then don't create a new one... */
201 if (!ApiMessage
->Data
.AllocConsoleRequest
.Console
||
202 ApiMessage
->Data
.AllocConsoleRequest
.Console
!= ProcessData
->ParentConsole
)
204 /* Allocate a console structure */
206 Console
= HeapAlloc(ConSrvHeap
, HEAP_ZERO_MEMORY
, sizeof(CSRSS_CONSOLE
));
209 DPRINT1("Not enough memory for console\n");
210 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
211 return STATUS_NO_MEMORY
;
213 /* initialize list head */
214 InitializeListHead(&Console
->ProcessList
);
215 /* insert process data required for GUI initialization */
216 InsertHeadList(&Console
->ProcessList
, &ProcessData
->ConsoleLink
);
217 /* Initialize the Console */
218 Status
= CsrInitConsole(Console
, ApiMessage
->Data
.AllocConsoleRequest
.ShowCmd
);
219 if (!NT_SUCCESS(Status
))
221 DPRINT1("Console init failed\n");
222 HeapFree(ConSrvHeap
, 0, Console
);
223 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
229 /* Reuse our current console */
230 Console
= ApiMessage
->Data
.AllocConsoleRequest
.Console
;
233 /* Set the Process Console */
234 ProcessData
->Console
= Console
;
236 /* Return it to the caller */
237 ApiMessage
->Data
.AllocConsoleRequest
.Console
= Console
;
239 /* Add a reference count because the process is tied to the console */
240 _InterlockedIncrement(&Console
->ReferenceCount
);
242 if (NewConsole
|| !ProcessData
->bInheritHandles
)
244 /* Insert the Objects */
245 Status
= Win32CsrInsertObject(ProcessData
,
246 &ApiMessage
->Data
.AllocConsoleRequest
.InputHandle
,
248 GENERIC_READ
| GENERIC_WRITE
,
250 FILE_SHARE_READ
| FILE_SHARE_WRITE
);
251 if (! NT_SUCCESS(Status
))
253 DPRINT1("Failed to insert object\n");
254 ConioDeleteConsole((Object_t
*) Console
);
255 ProcessData
->Console
= 0;
256 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
260 Status
= Win32CsrInsertObject(ProcessData
,
261 &ApiMessage
->Data
.AllocConsoleRequest
.OutputHandle
,
262 &Console
->ActiveBuffer
->Header
,
263 GENERIC_READ
| GENERIC_WRITE
,
265 FILE_SHARE_READ
| FILE_SHARE_WRITE
);
266 if (!NT_SUCCESS(Status
))
268 DPRINT1("Failed to insert object\n");
269 ConioDeleteConsole((Object_t
*) Console
);
270 Win32CsrReleaseObject(ProcessData
,
271 ApiMessage
->Data
.AllocConsoleRequest
.InputHandle
);
272 ProcessData
->Console
= 0;
273 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
278 /* Duplicate the Event */
279 if (!DuplicateHandle(GetCurrentProcess(),
280 ProcessData
->Console
->ActiveEvent
,
281 ProcessData
->ProcessHandle
,
282 &ProcessData
->ConsoleEvent
,
287 DPRINT1("DuplicateHandle() failed: %lu\n", GetLastError());
288 ConioDeleteConsole((Object_t
*) Console
);
289 if (NewConsole
|| !ProcessData
->bInheritHandles
)
291 Win32CsrReleaseObject(ProcessData
,
292 ApiMessage
->Data
.AllocConsoleRequest
.OutputHandle
);
293 Win32CsrReleaseObject(ProcessData
,
294 ApiMessage
->Data
.AllocConsoleRequest
.InputHandle
);
296 ProcessData
->Console
= 0;
297 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
301 /* Set the Ctrl Dispatcher */
302 ProcessData
->CtrlDispatcher
= ApiMessage
->Data
.AllocConsoleRequest
.CtrlDispatcher
;
303 DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData
->CtrlDispatcher
);
307 /* Insert into the list if it has not been added */
308 InsertHeadList(&ProcessData
->Console
->ProcessList
, &ProcessData
->ConsoleLink
);
311 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
312 return STATUS_SUCCESS
;
315 CSR_API(SrvFreeConsole
)
317 Win32CsrReleaseConsole(CsrGetClientThread()->Process
);
318 return STATUS_SUCCESS
;
322 ConioDeleteConsole(Object_t
*Object
)
324 PCSRSS_CONSOLE Console
= (PCSRSS_CONSOLE
) Object
;
327 DPRINT("ConioDeleteConsole\n");
329 /* Drain input event queue */
330 while (Console
->InputEvents
.Flink
!= &Console
->InputEvents
)
332 Event
= (ConsoleInput
*) Console
->InputEvents
.Flink
;
333 Console
->InputEvents
.Flink
= Console
->InputEvents
.Flink
->Flink
;
334 Console
->InputEvents
.Flink
->Flink
->Blink
= &Console
->InputEvents
;
335 HeapFree(ConSrvHeap
, 0, Event
);
338 ConioCleanupConsole(Console
);
339 if (Console
->LineBuffer
)
340 RtlFreeHeap(ConSrvHeap
, 0, Console
->LineBuffer
);
341 while (!IsListEmpty(&Console
->HistoryBuffers
))
342 HistoryDeleteBuffer((struct tagHISTORY_BUFFER
*)Console
->HistoryBuffers
.Flink
);
344 ConioDeleteScreenBuffer(Console
->ActiveBuffer
);
345 if (!IsListEmpty(&Console
->BufferList
))
347 DPRINT1("BUG: screen buffer list not empty\n");
350 CloseHandle(Console
->ActiveEvent
);
351 if (Console
->UnpauseEvent
) CloseHandle(Console
->UnpauseEvent
);
352 DeleteCriticalSection(&Console
->Lock
);
353 RtlFreeUnicodeString(&Console
->Title
);
354 IntDeleteAllAliases(Console
->Aliases
);
355 HeapFree(ConSrvHeap
, 0, Console
);
359 CsrInitConsoleSupport(VOID
)
361 DPRINT("CSR: CsrInitConsoleSupport()\n");
363 /* Should call LoadKeyboardLayout */
367 ConioPause(PCSRSS_CONSOLE Console
, UINT Flags
)
369 Console
->PauseFlags
|= Flags
;
370 if (!Console
->UnpauseEvent
)
371 Console
->UnpauseEvent
= CreateEvent(NULL
, TRUE
, FALSE
, NULL
);
375 ConioUnpause(PCSRSS_CONSOLE Console
, UINT Flags
)
377 Console
->PauseFlags
&= ~Flags
;
378 if (Console
->PauseFlags
== 0 && Console
->UnpauseEvent
)
380 SetEvent(Console
->UnpauseEvent
);
381 CloseHandle(Console
->UnpauseEvent
);
382 Console
->UnpauseEvent
= NULL
;
386 CSR_API(SrvSetConsoleMode
)
389 PCSRSS_CONSOLE Console
;
390 PCSRSS_SCREEN_BUFFER Buff
;
392 DPRINT("SrvSetConsoleMode\n");
394 Status
= Win32CsrLockObject(CsrGetClientThread()->Process
,
395 ApiMessage
->Data
.SetConsoleModeRequest
.ConsoleHandle
,
396 (Object_t
**) &Console
, GENERIC_WRITE
, 0);
397 if (! NT_SUCCESS(Status
))
402 Buff
= (PCSRSS_SCREEN_BUFFER
)Console
;
403 if (CONIO_CONSOLE_MAGIC
== Console
->Header
.Type
)
405 Console
->Mode
= ApiMessage
->Data
.SetConsoleModeRequest
.Mode
& CONSOLE_INPUT_MODE_VALID
;
407 else if (CONIO_SCREEN_BUFFER_MAGIC
== Console
->Header
.Type
)
409 Buff
->Mode
= ApiMessage
->Data
.SetConsoleModeRequest
.Mode
& CONSOLE_OUTPUT_MODE_VALID
;
413 Status
= STATUS_INVALID_HANDLE
;
416 Win32CsrUnlockObject((Object_t
*)Console
);
421 CSR_API(SrvGetConsoleMode
)
424 PCSRSS_CONSOLE Console
;
425 PCSRSS_SCREEN_BUFFER Buff
; /* gee, I really wish I could use an anonymous union here */
427 DPRINT("SrvGetConsoleMode\n");
429 Status
= Win32CsrLockObject(CsrGetClientThread()->Process
, ApiMessage
->Data
.GetConsoleModeRequest
.ConsoleHandle
,
430 (Object_t
**) &Console
, GENERIC_READ
, 0);
431 if (! NT_SUCCESS(Status
))
435 Status
= STATUS_SUCCESS
;
436 Buff
= (PCSRSS_SCREEN_BUFFER
) Console
;
437 if (CONIO_CONSOLE_MAGIC
== Console
->Header
.Type
)
439 ApiMessage
->Data
.GetConsoleModeRequest
.ConsoleMode
= Console
->Mode
;
441 else if (CONIO_SCREEN_BUFFER_MAGIC
== Buff
->Header
.Type
)
443 ApiMessage
->Data
.GetConsoleModeRequest
.ConsoleMode
= Buff
->Mode
;
447 Status
= STATUS_INVALID_HANDLE
;
450 Win32CsrUnlockObject((Object_t
*)Console
);
454 CSR_API(SrvSetConsoleTitle
)
457 PCSR_PROCESS ProcessData
= CsrGetClientThread()->Process
;
458 PCSRSS_CONSOLE Console
;
461 DPRINT("SrvSetConsoleTitle\n");
463 if (!Win32CsrValidateBuffer(ProcessData
, ApiMessage
->Data
.SetTitleRequest
.Title
,
464 ApiMessage
->Data
.SetTitleRequest
.Length
, 1))
466 return STATUS_ACCESS_VIOLATION
;
469 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
470 if(NT_SUCCESS(Status
))
472 Buffer
= RtlAllocateHeap(RtlGetProcessHeap(), 0, ApiMessage
->Data
.SetTitleRequest
.Length
);
475 /* copy title to console */
476 RtlFreeUnicodeString(&Console
->Title
);
477 Console
->Title
.Buffer
= Buffer
;
478 Console
->Title
.Length
= Console
->Title
.MaximumLength
= ApiMessage
->Data
.SetTitleRequest
.Length
;
479 memcpy(Console
->Title
.Buffer
, ApiMessage
->Data
.SetTitleRequest
.Title
, Console
->Title
.Length
);
480 if (! ConioChangeTitle(Console
))
482 Status
= STATUS_UNSUCCESSFUL
;
486 Status
= STATUS_SUCCESS
;
491 Status
= STATUS_NO_MEMORY
;
493 ConioUnlockConsole(Console
);
499 CSR_API(SrvGetConsoleTitle
)
502 PCSR_PROCESS ProcessData
= CsrGetClientThread()->Process
;
503 PCSRSS_CONSOLE Console
;
506 DPRINT("SrvGetConsoleTitle\n");
509 if (!Win32CsrValidateBuffer(ProcessData
, ApiMessage
->Data
.GetTitleRequest
.Title
,
510 ApiMessage
->Data
.GetTitleRequest
.Length
, 1))
512 return STATUS_ACCESS_VIOLATION
;
515 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
516 if (! NT_SUCCESS(Status
))
518 DPRINT1("Can't get console\n");
522 /* Copy title of the console to the user title buffer */
523 if (ApiMessage
->Data
.GetTitleRequest
.Length
>= sizeof(WCHAR
))
525 Length
= min(ApiMessage
->Data
.GetTitleRequest
.Length
- sizeof(WCHAR
), Console
->Title
.Length
);
526 memcpy(ApiMessage
->Data
.GetTitleRequest
.Title
, Console
->Title
.Buffer
, Length
);
527 ApiMessage
->Data
.GetTitleRequest
.Title
[Length
/ sizeof(WCHAR
)] = L
'\0';
530 ApiMessage
->Data
.GetTitleRequest
.Length
= Console
->Title
.Length
;
532 ConioUnlockConsole(Console
);
533 return STATUS_SUCCESS
;
536 /**********************************************************************
537 * HardwareStateProperty
540 * Set/Get the value of the HardwareState and switch
541 * between direct video buffer ouput and GDI windowed
544 * Client hands us a CSRSS_CONSOLE_HARDWARE_STATE
545 * object. We use the same object to Request.
547 * ConsoleHwState has the correct size to be compatible
548 * with NT's, but values are not.
550 static NTSTATUS FASTCALL
551 SetConsoleHardwareState(PCSRSS_CONSOLE Console
, DWORD ConsoleHwState
)
553 DPRINT1("Console Hardware State: %d\n", ConsoleHwState
);
555 if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED
== ConsoleHwState
)
556 ||(CONSOLE_HARDWARE_STATE_DIRECT
== ConsoleHwState
))
558 if (Console
->HardwareState
!= ConsoleHwState
)
560 /* TODO: implement switching from full screen to windowed mode */
561 /* TODO: or back; now simply store the hardware state */
562 Console
->HardwareState
= ConsoleHwState
;
565 return STATUS_SUCCESS
;
568 return STATUS_INVALID_PARAMETER_3
; /* Client: (handle, set_get, [mode]) */
571 CSR_API(SrvGetConsoleHardwareState
)
573 PCSRSS_CONSOLE Console
;
576 DPRINT("SrvGetConsoleHardwareState\n");
578 Status
= ConioLockConsole(CsrGetClientThread()->Process
,
579 ApiMessage
->Data
.ConsoleHardwareStateRequest
.ConsoleHandle
,
582 if (! NT_SUCCESS(Status
))
584 DPRINT1("Failed to get console handle in SetConsoleHardwareState\n");
588 switch (ApiMessage
->Data
.ConsoleHardwareStateRequest
.SetGet
)
590 case CONSOLE_HARDWARE_STATE_GET
:
591 ApiMessage
->Data
.ConsoleHardwareStateRequest
.State
= Console
->HardwareState
;
594 case CONSOLE_HARDWARE_STATE_SET
:
595 DPRINT("Setting console hardware state.\n");
596 Status
= SetConsoleHardwareState(Console
, ApiMessage
->Data
.ConsoleHardwareStateRequest
.State
);
600 Status
= STATUS_INVALID_PARAMETER_2
; /* Client: (handle, [set_get], mode) */
604 ConioUnlockConsole(Console
);
609 CSR_API(SrvSetConsoleHardwareState
)
611 PCSRSS_CONSOLE Console
;
614 DPRINT("SrvSetConsoleHardwareState\n");
616 Status
= ConioLockConsole(CsrGetClientThread()->Process
,
617 ApiMessage
->Data
.ConsoleHardwareStateRequest
.ConsoleHandle
,
620 if (! NT_SUCCESS(Status
))
622 DPRINT1("Failed to get console handle in SetConsoleHardwareState\n");
626 switch (ApiMessage
->Data
.ConsoleHardwareStateRequest
.SetGet
)
628 case CONSOLE_HARDWARE_STATE_GET
:
629 ApiMessage
->Data
.ConsoleHardwareStateRequest
.State
= Console
->HardwareState
;
632 case CONSOLE_HARDWARE_STATE_SET
:
633 DPRINT("Setting console hardware state.\n");
634 Status
= SetConsoleHardwareState(Console
, ApiMessage
->Data
.ConsoleHardwareStateRequest
.State
);
638 Status
= STATUS_INVALID_PARAMETER_2
; /* Client: (handle, [set_get], mode) */
642 ConioUnlockConsole(Console
);
647 CSR_API(SrvGetConsoleWindow
)
649 PCSRSS_CONSOLE Console
;
652 DPRINT("SrvGetConsoleWindow\n");
654 Status
= ConioConsoleFromProcessData(CsrGetClientThread()->Process
, &Console
);
655 if (! NT_SUCCESS(Status
))
660 ApiMessage
->Data
.GetConsoleWindowRequest
.WindowHandle
= Console
->hWindow
;
661 ConioUnlockConsole(Console
);
663 return STATUS_SUCCESS
;
666 CSR_API(SrvSetConsoleIcon
)
668 PCSRSS_CONSOLE Console
;
671 DPRINT("SrvSetConsoleIcon\n");
673 Status
= ConioConsoleFromProcessData(CsrGetClientThread()->Process
, &Console
);
674 if (! NT_SUCCESS(Status
))
679 Status
= (ConioChangeIcon(Console
, ApiMessage
->Data
.SetConsoleIconRequest
.WindowIcon
)
680 ? STATUS_SUCCESS
: STATUS_UNSUCCESSFUL
);
681 ConioUnlockConsole(Console
);
686 CSR_API(SrvGetConsoleCP
)
688 PCSRSS_CONSOLE Console
;
691 DPRINT("SrvGetConsoleCP\n");
693 Status
= ConioConsoleFromProcessData(CsrGetClientThread()->Process
, &Console
);
694 if (! NT_SUCCESS(Status
))
699 ApiMessage
->Data
.GetConsoleCodePage
.CodePage
= Console
->CodePage
;
700 ConioUnlockConsole(Console
);
701 return STATUS_SUCCESS
;
704 CSR_API(CsrGetConsoleOutputCodePage
) // TODO: Merge this function with the other one.
706 PCSRSS_CONSOLE Console
;
709 DPRINT("CsrGetConsoleOutputCodePage\n");
711 Status
= ConioConsoleFromProcessData(CsrGetClientThread()->Process
, &Console
);
712 if (! NT_SUCCESS(Status
))
717 ApiMessage
->Data
.GetConsoleOutputCodePage
.CodePage
= Console
->OutputCodePage
;
718 ConioUnlockConsole(Console
);
719 return STATUS_SUCCESS
;
722 CSR_API(SrvSetConsoleCP
)
724 PCSRSS_CONSOLE Console
;
727 DPRINT("SrvSetConsoleCP\n");
729 Status
= ConioConsoleFromProcessData(CsrGetClientThread()->Process
, &Console
);
730 if (! NT_SUCCESS(Status
))
735 if (IsValidCodePage(ApiMessage
->Data
.SetConsoleCodePage
.CodePage
))
737 Console
->CodePage
= ApiMessage
->Data
.SetConsoleCodePage
.CodePage
;
738 ConioUnlockConsole(Console
);
739 return STATUS_SUCCESS
;
742 ConioUnlockConsole(Console
);
743 return STATUS_INVALID_PARAMETER
;
746 CSR_API(CsrSetConsoleOutputCodePage
) // TODO: Merge this function with the other one.
748 PCSRSS_CONSOLE Console
;
751 DPRINT("CsrSetConsoleOutputCodePage\n");
753 Status
= ConioConsoleFromProcessData(CsrGetClientThread()->Process
, &Console
);
754 if (! NT_SUCCESS(Status
))
759 if (IsValidCodePage(ApiMessage
->Data
.SetConsoleOutputCodePage
.CodePage
))
761 Console
->OutputCodePage
= ApiMessage
->Data
.SetConsoleOutputCodePage
.CodePage
;
762 ConioUnlockConsole(Console
);
763 return STATUS_SUCCESS
;
766 ConioUnlockConsole(Console
);
767 return STATUS_INVALID_PARAMETER
;
770 CSR_API(SrvGetConsoleProcessList
)
773 PCSR_PROCESS ProcessData
= CsrGetClientThread()->Process
;
774 PCSRSS_CONSOLE Console
;
775 PCSR_PROCESS current
;
776 PLIST_ENTRY current_entry
;
780 DPRINT("SrvGetConsoleProcessList\n");
782 Buffer
= ApiMessage
->Data
.GetProcessListRequest
.ProcessId
;
783 if (!Win32CsrValidateBuffer(ProcessData
, Buffer
, ApiMessage
->Data
.GetProcessListRequest
.nMaxIds
, sizeof(DWORD
)))
784 return STATUS_ACCESS_VIOLATION
;
786 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
787 if (! NT_SUCCESS(Status
))
792 for (current_entry
= Console
->ProcessList
.Flink
;
793 current_entry
!= &Console
->ProcessList
;
794 current_entry
= current_entry
->Flink
)
796 current
= CONTAINING_RECORD(current_entry
, CSR_PROCESS
, ConsoleLink
);
797 if (++nItems
<= ApiMessage
->Data
.GetProcessListRequest
.nMaxIds
)
799 *Buffer
++ = HandleToUlong(current
->ClientId
.UniqueProcess
);
803 ConioUnlockConsole(Console
);
805 ApiMessage
->Data
.GetProcessListRequest
.nProcessIdsTotal
= nItems
;
806 return STATUS_SUCCESS
;
809 CSR_API(SrvGenerateConsoleCtrlEvent
)
811 PCSRSS_CONSOLE Console
;
812 PCSR_PROCESS current
;
813 PLIST_ENTRY current_entry
;
817 Status
= ConioConsoleFromProcessData(CsrGetClientThread()->Process
, &Console
);
818 if (! NT_SUCCESS(Status
))
823 Group
= ApiMessage
->Data
.GenerateCtrlEvent
.ProcessGroup
;
824 Status
= STATUS_INVALID_PARAMETER
;
825 for (current_entry
= Console
->ProcessList
.Flink
;
826 current_entry
!= &Console
->ProcessList
;
827 current_entry
= current_entry
->Flink
)
829 current
= CONTAINING_RECORD(current_entry
, CSR_PROCESS
, ConsoleLink
);
830 if (Group
== 0 || current
->ProcessGroupId
== Group
)
832 ConioConsoleCtrlEvent(ApiMessage
->Data
.GenerateCtrlEvent
.Event
, current
);
833 Status
= STATUS_SUCCESS
;
837 ConioUnlockConsole(Console
);
842 CSR_API(SrvGetConsoleSelectionInfo
)
845 PCSRSS_CONSOLE Console
;
847 Status
= ConioConsoleFromProcessData(CsrGetClientThread()->Process
, &Console
);
848 if (NT_SUCCESS(Status
))
850 memset(&ApiMessage
->Data
.GetConsoleSelectionInfo
.Info
, 0, sizeof(CONSOLE_SELECTION_INFO
));
851 if (Console
->Selection
.dwFlags
!= 0)
852 ApiMessage
->Data
.GetConsoleSelectionInfo
.Info
= Console
->Selection
;
853 ConioUnlockConsole(Console
);