2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Console Server DLL
4 * FILE: win32ss/user/consrv/console.c
5 * PURPOSE: Console I/O functions
9 /* INCLUDES ******************************************************************/
12 #include "guiconsole.h"
13 #include "tuiconsole.h"
18 /* FUNCTIONS *****************************************************************/
21 DtbgIsDesktopVisible(VOID
)
23 HWND VisibleDesktopWindow
= GetDesktopWindow(); // DESKTOPWNDPROC
25 if (VisibleDesktopWindow
!= NULL
&&
26 !IsWindowVisible(VisibleDesktopWindow
))
28 VisibleDesktopWindow
= NULL
;
31 return VisibleDesktopWindow
!= NULL
;
35 ConioConsoleFromProcessData(PCONSOLE_PROCESS_DATA ProcessData
,
36 PCSRSS_CONSOLE
*Console
)
38 PCSRSS_CONSOLE ProcessConsole
;
40 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
41 ProcessConsole
= ProcessData
->Console
;
46 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
47 return STATUS_INVALID_HANDLE
;
50 InterlockedIncrement(&ProcessConsole
->ReferenceCount
);
51 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
52 EnterCriticalSection(&(ProcessConsole
->Lock
));
53 *Console
= ProcessConsole
;
55 return STATUS_SUCCESS
;
59 ConioConsoleCtrlEventTimeout(DWORD Event
,
60 PCONSOLE_PROCESS_DATA ProcessData
,
65 DPRINT("ConioConsoleCtrlEvent Parent ProcessId = %x\n", ProcessData
->Process
->ClientId
.UniqueProcess
);
67 if (ProcessData
->CtrlDispatcher
)
69 Thread
= CreateRemoteThread(ProcessData
->Process
->ProcessHandle
, NULL
, 0,
70 ProcessData
->CtrlDispatcher
,
71 UlongToPtr(Event
), 0, NULL
);
74 DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
78 WaitForSingleObject(Thread
, Timeout
);
84 ConioConsoleCtrlEvent(DWORD Event
, PCONSOLE_PROCESS_DATA ProcessData
)
86 ConioConsoleCtrlEventTimeout(Event
, ProcessData
, 0);
89 static NTSTATUS WINAPI
90 CsrInitConsole(PCSRSS_CONSOLE Console
, int ShowCmd
)
93 SECURITY_ATTRIBUTES SecurityAttributes
;
94 PCSRSS_SCREEN_BUFFER NewBuffer
;
98 Console
->Title
.MaximumLength
= Console
->Title
.Length
= 0;
99 Console
->Title
.Buffer
= NULL
;
101 if (LoadStringW(ConSrvDllInstance
, IDS_COMMAND_PROMPT
, Title
, sizeof(Title
) / sizeof(Title
[0])))
103 RtlCreateUnicodeString(&Console
->Title
, Title
);
107 RtlCreateUnicodeString(&Console
->Title
, L
"Command Prompt");
110 Console
->ReferenceCount
= 0;
111 Console
->LineBuffer
= NULL
;
112 Console
->Header
.Type
= CONIO_CONSOLE_MAGIC
;
113 Console
->Header
.Console
= Console
;
114 Console
->Mode
= ENABLE_LINE_INPUT
| ENABLE_ECHO_INPUT
| ENABLE_PROCESSED_INPUT
| ENABLE_MOUSE_INPUT
;
115 InitializeListHead(&Console
->BufferList
);
116 Console
->ActiveBuffer
= NULL
;
117 InitializeListHead(&Console
->InputEvents
);
118 InitializeListHead(&Console
->HistoryBuffers
);
119 Console
->CodePage
= GetOEMCP();
120 Console
->OutputCodePage
= GetOEMCP();
122 SecurityAttributes
.nLength
= sizeof(SECURITY_ATTRIBUTES
);
123 SecurityAttributes
.lpSecurityDescriptor
= NULL
;
124 SecurityAttributes
.bInheritHandle
= TRUE
;
126 Console
->ActiveEvent
= CreateEventW(&SecurityAttributes
, TRUE
, FALSE
, NULL
);
127 if (NULL
== Console
->ActiveEvent
)
129 RtlFreeUnicodeString(&Console
->Title
);
130 return STATUS_UNSUCCESSFUL
;
132 Console
->PrivateData
= NULL
;
133 InitializeCriticalSection(&Console
->Lock
);
135 GuiMode
= DtbgIsDesktopVisible();
137 /* allocate console screen buffer */
138 NewBuffer
= HeapAlloc(ConSrvHeap
, HEAP_ZERO_MEMORY
, sizeof(CSRSS_SCREEN_BUFFER
));
139 if (NULL
== NewBuffer
)
141 RtlFreeUnicodeString(&Console
->Title
);
142 DeleteCriticalSection(&Console
->Lock
);
143 CloseHandle(Console
->ActiveEvent
);
144 return STATUS_INSUFFICIENT_RESOURCES
;
146 /* init screen buffer with defaults */
147 NewBuffer
->CursorInfo
.bVisible
= TRUE
;
148 NewBuffer
->CursorInfo
.dwSize
= CSR_DEFAULT_CURSOR_SIZE
;
149 /* make console active, and insert into console list */
150 Console
->ActiveBuffer
= (PCSRSS_SCREEN_BUFFER
) NewBuffer
;
154 Status
= TuiInitConsole(Console
);
155 if (!NT_SUCCESS(Status
))
157 DPRINT1("Failed to open text-mode console, switching to gui-mode\n");
163 Status
= GuiInitConsole(Console
, ShowCmd
);
164 if (!NT_SUCCESS(Status
))
166 HeapFree(ConSrvHeap
,0, NewBuffer
);
167 RtlFreeUnicodeString(&Console
->Title
);
168 DeleteCriticalSection(&Console
->Lock
);
169 CloseHandle(Console
->ActiveEvent
);
170 DPRINT1("GuiInitConsole: failed\n");
175 Status
= CsrInitConsoleScreenBuffer(Console
, NewBuffer
);
176 if (! NT_SUCCESS(Status
))
178 ConioCleanupConsole(Console
);
179 RtlFreeUnicodeString(&Console
->Title
);
180 DeleteCriticalSection(&Console
->Lock
);
181 CloseHandle(Console
->ActiveEvent
);
182 HeapFree(ConSrvHeap
, 0, NewBuffer
);
183 DPRINT1("CsrInitConsoleScreenBuffer: failed\n");
187 /* copy buffer contents to screen */
188 ConioDrawConsole(Console
);
190 return STATUS_SUCCESS
;
193 CSR_API(SrvOpenConsole
)
195 NTSTATUS Status
= STATUS_SUCCESS
;
196 PCSRSS_OPEN_CONSOLE OpenConsoleRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.OpenConsoleRequest
;
197 PCONSOLE_PROCESS_DATA ProcessData
= ConsoleGetPerProcessData(CsrGetClientThread()->Process
);
199 DPRINT("SrvOpenConsole\n");
201 OpenConsoleRequest
->Handle
= INVALID_HANDLE_VALUE
;
203 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
205 DPRINT1("SrvOpenConsole - Checkpoint 1\n");
206 DPRINT1("ProcessData = 0x%p ; ProcessData->Console = 0x%p\n", ProcessData
, ProcessData
->Console
);
208 if (ProcessData
->Console
)
210 DWORD DesiredAccess
= OpenConsoleRequest
->Access
;
211 DWORD ShareMode
= OpenConsoleRequest
->ShareMode
;
213 PCSRSS_CONSOLE Console
= ProcessData
->Console
;
216 DPRINT1("SrvOpenConsole - Checkpoint 2\n");
217 EnterCriticalSection(&Console
->Lock
);
218 DPRINT1("SrvOpenConsole - Checkpoint 3\n");
220 if (OpenConsoleRequest
->HandleType
== HANDLE_OUTPUT
)
221 Object
= &Console
->ActiveBuffer
->Header
;
223 Object
= &Console
->Header
;
225 if (((DesiredAccess
& GENERIC_READ
) && Object
->ExclusiveRead
!= 0) ||
226 ((DesiredAccess
& GENERIC_WRITE
) && Object
->ExclusiveWrite
!= 0) ||
227 (!(ShareMode
& FILE_SHARE_READ
) && Object
->AccessRead
!= 0) ||
228 (!(ShareMode
& FILE_SHARE_WRITE
) && Object
->AccessWrite
!= 0))
230 DPRINT1("Sharing violation\n");
231 Status
= STATUS_SHARING_VIOLATION
;
235 Status
= Win32CsrInsertObject(ProcessData
,
236 &OpenConsoleRequest
->Handle
,
239 OpenConsoleRequest
->Inheritable
,
243 LeaveCriticalSection(&Console
->Lock
);
246 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
251 CSR_API(SrvAllocConsole
)
253 PCSRSS_ALLOC_CONSOLE AllocConsoleRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.AllocConsoleRequest
;
254 PCSR_PROCESS ProcessData
= CsrGetClientThread()->Process
;
255 PCSRSS_CONSOLE Console
;
256 NTSTATUS Status
= STATUS_SUCCESS
;
257 BOOLEAN NewConsole
= FALSE
;
259 DPRINT("SrvAllocConsole\n");
261 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
262 if (ProcessData
->Console
)
264 DPRINT1("Process already has a console\n");
265 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
266 return STATUS_INVALID_PARAMETER
;
269 /* If we don't need a console, then get out of here */
270 if (!AllocConsoleRequest
->ConsoleNeeded
)
272 DPRINT("No console needed\n");
273 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
274 return STATUS_SUCCESS
;
277 /* If we already have one, then don't create a new one... */
278 if (!AllocConsoleRequest
->Console
||
279 AllocConsoleRequest
->Console
!= ProcessData
->ParentConsole
)
281 /* Allocate a console structure */
283 Console
= HeapAlloc(ConSrvHeap
, HEAP_ZERO_MEMORY
, sizeof(CSRSS_CONSOLE
));
286 DPRINT1("Not enough memory for console\n");
287 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
288 return STATUS_NO_MEMORY
;
290 /* initialize list head */
291 InitializeListHead(&Console
->ProcessList
);
292 /* insert process data required for GUI initialization */
293 InsertHeadList(&Console
->ProcessList
, &ProcessData
->ConsoleLink
);
294 /* Initialize the Console */
295 Status
= CsrInitConsole(Console
, AllocConsoleRequest
->ShowCmd
);
296 if (!NT_SUCCESS(Status
))
298 DPRINT1("Console init failed\n");
299 HeapFree(ConSrvHeap
, 0, Console
);
300 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
306 /* Reuse our current console */
307 Console
= AllocConsoleRequest
->Console
;
310 /* Set the Process Console */
311 ProcessData
->Console
= Console
;
313 /* Return it to the caller */
314 AllocConsoleRequest
->Console
= Console
;
316 /* Add a reference count because the process is tied to the console */
317 _InterlockedIncrement(&Console
->ReferenceCount
);
319 if (NewConsole
|| !ProcessData
->bInheritHandles
)
321 /* Insert the Objects */
322 Status
= Win32CsrInsertObject(ProcessData
,
323 &AllocConsoleRequest
->InputHandle
,
325 GENERIC_READ
| GENERIC_WRITE
,
327 FILE_SHARE_READ
| FILE_SHARE_WRITE
);
328 if (! NT_SUCCESS(Status
))
330 DPRINT1("Failed to insert object\n");
331 ConioDeleteConsole((Object_t
*) Console
);
332 ProcessData
->Console
= 0;
333 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
337 Status
= Win32CsrInsertObject(ProcessData
,
338 &AllocConsoleRequest
->OutputHandle
,
339 &Console
->ActiveBuffer
->Header
,
340 GENERIC_READ
| GENERIC_WRITE
,
342 FILE_SHARE_READ
| FILE_SHARE_WRITE
);
343 if (!NT_SUCCESS(Status
))
345 DPRINT1("Failed to insert object\n");
346 ConioDeleteConsole((Object_t
*) Console
);
347 Win32CsrReleaseObject(ProcessData
,
348 AllocConsoleRequest
->InputHandle
);
349 ProcessData
->Console
= 0;
350 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
355 /* Duplicate the Event */
356 if (!DuplicateHandle(GetCurrentProcess(),
357 ProcessData
->Console
->ActiveEvent
,
358 ProcessData
->ProcessHandle
,
359 &ProcessData
->ConsoleEvent
,
364 DPRINT1("DuplicateHandle() failed: %lu\n", GetLastError());
365 ConioDeleteConsole((Object_t
*) Console
);
366 if (NewConsole
|| !ProcessData
->bInheritHandles
)
368 Win32CsrReleaseObject(ProcessData
,
369 AllocConsoleRequest
->OutputHandle
);
370 Win32CsrReleaseObject(ProcessData
,
371 AllocConsoleRequest
->InputHandle
);
373 ProcessData
->Console
= 0;
374 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
378 /* Set the Ctrl Dispatcher */
379 ProcessData
->CtrlDispatcher
= AllocConsoleRequest
->CtrlDispatcher
;
380 DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData
->CtrlDispatcher
);
384 /* Insert into the list if it has not been added */
385 InsertHeadList(&ProcessData
->Console
->ProcessList
, &ProcessData
->ConsoleLink
);
388 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
389 return STATUS_SUCCESS
;
392 CSR_API(SrvFreeConsole
)
394 Win32CsrReleaseConsole(CsrGetClientThread()->Process
);
395 return STATUS_SUCCESS
;
399 ConioDeleteConsole(Object_t
*Object
)
401 PCSRSS_CONSOLE Console
= (PCSRSS_CONSOLE
) Object
;
404 DPRINT("ConioDeleteConsole\n");
406 /* Drain input event queue */
407 while (Console
->InputEvents
.Flink
!= &Console
->InputEvents
)
409 Event
= (ConsoleInput
*) Console
->InputEvents
.Flink
;
410 Console
->InputEvents
.Flink
= Console
->InputEvents
.Flink
->Flink
;
411 Console
->InputEvents
.Flink
->Flink
->Blink
= &Console
->InputEvents
;
412 HeapFree(ConSrvHeap
, 0, Event
);
415 ConioCleanupConsole(Console
);
416 if (Console
->LineBuffer
)
417 RtlFreeHeap(ConSrvHeap
, 0, Console
->LineBuffer
);
418 while (!IsListEmpty(&Console
->HistoryBuffers
))
419 HistoryDeleteBuffer((struct tagHISTORY_BUFFER
*)Console
->HistoryBuffers
.Flink
);
421 ConioDeleteScreenBuffer(Console
->ActiveBuffer
);
422 if (!IsListEmpty(&Console
->BufferList
))
424 DPRINT1("BUG: screen buffer list not empty\n");
427 CloseHandle(Console
->ActiveEvent
);
428 if (Console
->UnpauseEvent
) CloseHandle(Console
->UnpauseEvent
);
429 DeleteCriticalSection(&Console
->Lock
);
430 RtlFreeUnicodeString(&Console
->Title
);
431 IntDeleteAllAliases(Console
->Aliases
);
432 HeapFree(ConSrvHeap
, 0, Console
);
436 CsrInitConsoleSupport(VOID
)
438 DPRINT("CSR: CsrInitConsoleSupport()\n");
440 /* Should call LoadKeyboardLayout */
444 ConioPause(PCSRSS_CONSOLE Console
, UINT Flags
)
446 Console
->PauseFlags
|= Flags
;
447 if (!Console
->UnpauseEvent
)
448 Console
->UnpauseEvent
= CreateEvent(NULL
, TRUE
, FALSE
, NULL
);
452 ConioUnpause(PCSRSS_CONSOLE Console
, UINT Flags
)
454 Console
->PauseFlags
&= ~Flags
;
455 if (Console
->PauseFlags
== 0 && Console
->UnpauseEvent
)
457 SetEvent(Console
->UnpauseEvent
);
458 CloseHandle(Console
->UnpauseEvent
);
459 Console
->UnpauseEvent
= NULL
;
463 CSR_API(SrvSetConsoleMode
)
466 PCSRSS_SET_CONSOLE_MODE SetConsoleModeRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.SetConsoleModeRequest
;
467 PCSRSS_CONSOLE Console
;
468 PCSRSS_SCREEN_BUFFER Buff
;
470 DPRINT("SrvSetConsoleMode\n");
472 Status
= Win32CsrLockObject(CsrGetClientThread()->Process
,
473 SetConsoleModeRequest
->ConsoleHandle
,
474 (Object_t
**) &Console
, GENERIC_WRITE
, 0);
475 if (! NT_SUCCESS(Status
))
480 Buff
= (PCSRSS_SCREEN_BUFFER
)Console
;
481 if (CONIO_CONSOLE_MAGIC
== Console
->Header
.Type
)
483 Console
->Mode
= SetConsoleModeRequest
->Mode
& CONSOLE_INPUT_MODE_VALID
;
485 else if (CONIO_SCREEN_BUFFER_MAGIC
== Console
->Header
.Type
)
487 Buff
->Mode
= SetConsoleModeRequest
->Mode
& CONSOLE_OUTPUT_MODE_VALID
;
491 Status
= STATUS_INVALID_HANDLE
;
494 Win32CsrUnlockObject((Object_t
*)Console
);
499 CSR_API(SrvGetConsoleMode
)
502 PCSRSS_GET_CONSOLE_MODE GetConsoleModeRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetConsoleModeRequest
;
503 PCSRSS_CONSOLE Console
;
504 PCSRSS_SCREEN_BUFFER Buff
;
506 DPRINT("SrvGetConsoleMode\n");
508 Status
= Win32CsrLockObject(CsrGetClientThread()->Process
, GetConsoleModeRequest
->ConsoleHandle
,
509 (Object_t
**) &Console
, GENERIC_READ
, 0);
510 if (! NT_SUCCESS(Status
))
514 Status
= STATUS_SUCCESS
;
515 Buff
= (PCSRSS_SCREEN_BUFFER
) Console
;
516 if (CONIO_CONSOLE_MAGIC
== Console
->Header
.Type
)
518 GetConsoleModeRequest
->ConsoleMode
= Console
->Mode
;
520 else if (CONIO_SCREEN_BUFFER_MAGIC
== Buff
->Header
.Type
)
522 GetConsoleModeRequest
->ConsoleMode
= Buff
->Mode
;
526 Status
= STATUS_INVALID_HANDLE
;
529 Win32CsrUnlockObject((Object_t
*)Console
);
533 CSR_API(SrvSetConsoleTitle
)
536 PCSRSS_SET_TITLE SetTitleRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.SetTitleRequest
;
537 PCSR_PROCESS ProcessData
= CsrGetClientThread()->Process
;
538 PCSRSS_CONSOLE Console
;
541 DPRINT("SrvSetConsoleTitle\n");
543 if (!Win32CsrValidateBuffer(ProcessData
, SetTitleRequest
->Title
,
544 SetTitleRequest
->Length
, 1))
546 return STATUS_ACCESS_VIOLATION
;
549 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
550 if(NT_SUCCESS(Status
))
552 Buffer
= RtlAllocateHeap(RtlGetProcessHeap(), 0, SetTitleRequest
->Length
);
555 /* copy title to console */
556 RtlFreeUnicodeString(&Console
->Title
);
557 Console
->Title
.Buffer
= Buffer
;
558 Console
->Title
.Length
= Console
->Title
.MaximumLength
= SetTitleRequest
->Length
;
559 memcpy(Console
->Title
.Buffer
, SetTitleRequest
->Title
, Console
->Title
.Length
);
560 if (! ConioChangeTitle(Console
))
562 Status
= STATUS_UNSUCCESSFUL
;
566 Status
= STATUS_SUCCESS
;
571 Status
= STATUS_NO_MEMORY
;
573 ConioUnlockConsole(Console
);
579 CSR_API(SrvGetConsoleTitle
)
582 PCSRSS_GET_TITLE GetTitleRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetTitleRequest
;
583 PCSR_PROCESS ProcessData
= CsrGetClientThread()->Process
;
584 PCSRSS_CONSOLE Console
;
587 DPRINT("SrvGetConsoleTitle\n");
589 if (!Win32CsrValidateBuffer(ProcessData
, GetTitleRequest
->Title
,
590 GetTitleRequest
->Length
, 1))
592 return STATUS_ACCESS_VIOLATION
;
595 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
596 if (! NT_SUCCESS(Status
))
598 DPRINT1("Can't get console\n");
602 /* Copy title of the console to the user title buffer */
603 if (GetTitleRequest
->Length
>= sizeof(WCHAR
))
605 Length
= min(GetTitleRequest
->Length
- sizeof(WCHAR
), Console
->Title
.Length
);
606 memcpy(GetTitleRequest
->Title
, Console
->Title
.Buffer
, Length
);
607 GetTitleRequest
->Title
[Length
/ sizeof(WCHAR
)] = L
'\0';
610 GetTitleRequest
->Length
= Console
->Title
.Length
;
612 ConioUnlockConsole(Console
);
613 return STATUS_SUCCESS
;
616 /**********************************************************************
617 * HardwareStateProperty
620 * Set/Get the value of the HardwareState and switch
621 * between direct video buffer ouput and GDI windowed
624 * Client hands us a CSRSS_CONSOLE_HARDWARE_STATE
625 * object. We use the same object to Request.
627 * ConsoleHwState has the correct size to be compatible
628 * with NT's, but values are not.
630 static NTSTATUS FASTCALL
631 SetConsoleHardwareState(PCSRSS_CONSOLE Console
, DWORD ConsoleHwState
)
633 DPRINT1("Console Hardware State: %d\n", ConsoleHwState
);
635 if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED
== ConsoleHwState
)
636 ||(CONSOLE_HARDWARE_STATE_DIRECT
== ConsoleHwState
))
638 if (Console
->HardwareState
!= ConsoleHwState
)
640 /* TODO: implement switching from full screen to windowed mode */
641 /* TODO: or back; now simply store the hardware state */
642 Console
->HardwareState
= ConsoleHwState
;
645 return STATUS_SUCCESS
;
648 return STATUS_INVALID_PARAMETER_3
; /* Client: (handle, set_get, [mode]) */
651 CSR_API(SrvGetConsoleHardwareState
)
653 PCSRSS_SETGET_CONSOLE_HW_STATE ConsoleHardwareStateRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleHardwareStateRequest
;
654 PCSRSS_CONSOLE Console
;
657 DPRINT("SrvGetConsoleHardwareState\n");
659 Status
= ConioLockConsole(CsrGetClientThread()->Process
,
660 ConsoleHardwareStateRequest
->ConsoleHandle
,
663 if (! NT_SUCCESS(Status
))
665 DPRINT1("Failed to get console handle in SetConsoleHardwareState\n");
669 switch (ConsoleHardwareStateRequest
->SetGet
)
671 case CONSOLE_HARDWARE_STATE_GET
:
672 ConsoleHardwareStateRequest
->State
= Console
->HardwareState
;
675 case CONSOLE_HARDWARE_STATE_SET
:
676 DPRINT("Setting console hardware state.\n");
677 Status
= SetConsoleHardwareState(Console
, ConsoleHardwareStateRequest
->State
);
681 Status
= STATUS_INVALID_PARAMETER_2
; /* Client: (handle, [set_get], mode) */
685 ConioUnlockConsole(Console
);
690 CSR_API(SrvSetConsoleHardwareState
)
692 PCSRSS_SETGET_CONSOLE_HW_STATE ConsoleHardwareStateRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleHardwareStateRequest
;
693 PCSRSS_CONSOLE Console
;
696 DPRINT("SrvSetConsoleHardwareState\n");
698 Status
= ConioLockConsole(CsrGetClientThread()->Process
,
699 ConsoleHardwareStateRequest
->ConsoleHandle
,
702 if (! NT_SUCCESS(Status
))
704 DPRINT1("Failed to get console handle in SetConsoleHardwareState\n");
708 switch (ConsoleHardwareStateRequest
->SetGet
)
710 case CONSOLE_HARDWARE_STATE_GET
:
711 ConsoleHardwareStateRequest
->State
= Console
->HardwareState
;
714 case CONSOLE_HARDWARE_STATE_SET
:
715 DPRINT("Setting console hardware state.\n");
716 Status
= SetConsoleHardwareState(Console
, ConsoleHardwareStateRequest
->State
);
720 Status
= STATUS_INVALID_PARAMETER_2
; /* Client: (handle, [set_get], mode) */
724 ConioUnlockConsole(Console
);
729 CSR_API(SrvGetConsoleWindow
)
731 PCSRSS_GET_CONSOLE_WINDOW GetConsoleWindowRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetConsoleWindowRequest
;
732 PCSRSS_CONSOLE Console
;
735 DPRINT("SrvGetConsoleWindow\n");
737 Status
= ConioConsoleFromProcessData(CsrGetClientThread()->Process
, &Console
);
738 if (! NT_SUCCESS(Status
))
743 GetConsoleWindowRequest
->WindowHandle
= Console
->hWindow
;
744 ConioUnlockConsole(Console
);
746 return STATUS_SUCCESS
;
749 CSR_API(SrvSetConsoleIcon
)
751 PCSRSS_SET_CONSOLE_ICON SetConsoleIconRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.SetConsoleIconRequest
;
752 PCSRSS_CONSOLE Console
;
755 DPRINT("SrvSetConsoleIcon\n");
757 Status
= ConioConsoleFromProcessData(CsrGetClientThread()->Process
, &Console
);
758 if (! NT_SUCCESS(Status
))
763 Status
= (ConioChangeIcon(Console
, SetConsoleIconRequest
->WindowIcon
)
764 ? STATUS_SUCCESS
: STATUS_UNSUCCESSFUL
);
765 ConioUnlockConsole(Console
);
770 CSR_API(SrvGetConsoleCP
)
772 PCSRSS_GET_CONSOLE_CP GetConsoleCodePage
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetConsoleCodePage
;
773 PCSRSS_CONSOLE Console
;
776 DPRINT("SrvGetConsoleCP\n");
778 Status
= ConioConsoleFromProcessData(CsrGetClientThread()->Process
, &Console
);
779 if (! NT_SUCCESS(Status
))
784 GetConsoleCodePage
->CodePage
= Console
->CodePage
;
785 ConioUnlockConsole(Console
);
786 return STATUS_SUCCESS
;
789 CSR_API(CsrGetConsoleOutputCodePage
) // TODO: Merge this function with the other one.
791 PCSRSS_GET_CONSOLE_OUTPUT_CP GetConsoleOutputCodePage
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetConsoleOutputCodePage
;
792 PCSRSS_CONSOLE Console
;
795 DPRINT("CsrGetConsoleOutputCodePage\n");
797 Status
= ConioConsoleFromProcessData(CsrGetClientThread()->Process
, &Console
);
798 if (! NT_SUCCESS(Status
))
803 GetConsoleOutputCodePage
->CodePage
= Console
->OutputCodePage
;
804 ConioUnlockConsole(Console
);
805 return STATUS_SUCCESS
;
808 CSR_API(SrvSetConsoleCP
)
810 PCSRSS_SET_CONSOLE_CP SetConsoleCodePage
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.SetConsoleCodePage
;
811 PCSRSS_CONSOLE Console
;
814 DPRINT("SrvSetConsoleCP\n");
816 Status
= ConioConsoleFromProcessData(CsrGetClientThread()->Process
, &Console
);
817 if (! NT_SUCCESS(Status
))
822 if (IsValidCodePage(SetConsoleCodePage
->CodePage
))
824 Console
->CodePage
= SetConsoleCodePage
->CodePage
;
825 ConioUnlockConsole(Console
);
826 return STATUS_SUCCESS
;
829 ConioUnlockConsole(Console
);
830 return STATUS_INVALID_PARAMETER
;
833 CSR_API(CsrSetConsoleOutputCodePage
) // TODO: Merge this function with the other one.
835 PCSRSS_SET_CONSOLE_OUTPUT_CP SetConsoleOutputCodePage
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.SetConsoleOutputCodePage
;
836 PCSRSS_CONSOLE Console
;
839 DPRINT("CsrSetConsoleOutputCodePage\n");
841 Status
= ConioConsoleFromProcessData(CsrGetClientThread()->Process
, &Console
);
842 if (! NT_SUCCESS(Status
))
847 if (IsValidCodePage(SetConsoleOutputCodePage
->CodePage
))
849 Console
->OutputCodePage
= SetConsoleOutputCodePage
->CodePage
;
850 ConioUnlockConsole(Console
);
851 return STATUS_SUCCESS
;
854 ConioUnlockConsole(Console
);
855 return STATUS_INVALID_PARAMETER
;
858 CSR_API(SrvGetConsoleProcessList
)
860 PCSRSS_GET_PROCESS_LIST GetProcessListRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetProcessListRequest
;
862 PCSR_PROCESS ProcessData
= CsrGetClientThread()->Process
;
863 PCSRSS_CONSOLE Console
;
864 PCSR_PROCESS current
;
865 PLIST_ENTRY current_entry
;
869 DPRINT("SrvGetConsoleProcessList\n");
871 Buffer
= GetProcessListRequest
->ProcessId
;
872 if (!Win32CsrValidateBuffer(ProcessData
, Buffer
, GetProcessListRequest
->nMaxIds
, sizeof(DWORD
)))
873 return STATUS_ACCESS_VIOLATION
;
875 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
876 if (! NT_SUCCESS(Status
))
881 for (current_entry
= Console
->ProcessList
.Flink
;
882 current_entry
!= &Console
->ProcessList
;
883 current_entry
= current_entry
->Flink
)
885 current
= CONTAINING_RECORD(current_entry
, CSR_PROCESS
, ConsoleLink
);
886 if (++nItems
<= GetProcessListRequest
->nMaxIds
)
888 *Buffer
++ = HandleToUlong(current
->ClientId
.UniqueProcess
);
892 ConioUnlockConsole(Console
);
894 GetProcessListRequest
->nProcessIdsTotal
= nItems
;
895 return STATUS_SUCCESS
;
898 CSR_API(SrvGenerateConsoleCtrlEvent
)
900 PCSRSS_GENERATE_CTRL_EVENT GenerateCtrlEvent
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GenerateCtrlEvent
;
901 PCSRSS_CONSOLE Console
;
902 PCSR_PROCESS current
;
903 PLIST_ENTRY current_entry
;
907 Status
= ConioConsoleFromProcessData(CsrGetClientThread()->Process
, &Console
);
908 if (! NT_SUCCESS(Status
))
913 Group
= GenerateCtrlEvent
->ProcessGroup
;
914 Status
= STATUS_INVALID_PARAMETER
;
915 for (current_entry
= Console
->ProcessList
.Flink
;
916 current_entry
!= &Console
->ProcessList
;
917 current_entry
= current_entry
->Flink
)
919 current
= CONTAINING_RECORD(current_entry
, CSR_PROCESS
, ConsoleLink
);
920 if (Group
== 0 || current
->ProcessGroupId
== Group
)
922 ConioConsoleCtrlEvent(GenerateCtrlEvent
->Event
, current
);
923 Status
= STATUS_SUCCESS
;
927 ConioUnlockConsole(Console
);
932 CSR_API(SrvGetConsoleSelectionInfo
)
935 PCSRSS_GET_CONSOLE_SELECTION_INFO GetConsoleSelectionInfo
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetConsoleSelectionInfo
;
936 PCSRSS_CONSOLE Console
;
938 Status
= ConioConsoleFromProcessData(CsrGetClientThread()->Process
, &Console
);
939 if (NT_SUCCESS(Status
))
941 memset(&GetConsoleSelectionInfo
->Info
, 0, sizeof(CONSOLE_SELECTION_INFO
));
942 if (Console
->Selection
.dwFlags
!= 0)
943 GetConsoleSelectionInfo
->Info
= Console
->Selection
;
944 ConioUnlockConsole(Console
);