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
->ReadWaitQueue
);
118 InitializeListHead(&Console
->WriteWaitQueue
);
119 InitializeListHead(&Console
->InputEvents
);
120 InitializeListHead(&Console
->HistoryBuffers
);
121 Console
->CodePage
= GetOEMCP();
122 Console
->OutputCodePage
= GetOEMCP();
124 SecurityAttributes
.nLength
= sizeof(SECURITY_ATTRIBUTES
);
125 SecurityAttributes
.lpSecurityDescriptor
= NULL
;
126 SecurityAttributes
.bInheritHandle
= TRUE
;
128 Console
->ActiveEvent
= CreateEventW(&SecurityAttributes
, TRUE
, FALSE
, NULL
);
129 if (NULL
== Console
->ActiveEvent
)
131 RtlFreeUnicodeString(&Console
->Title
);
132 return STATUS_UNSUCCESSFUL
;
134 Console
->PrivateData
= NULL
;
135 InitializeCriticalSection(&Console
->Lock
);
137 GuiMode
= DtbgIsDesktopVisible();
139 /* allocate console screen buffer */
140 NewBuffer
= HeapAlloc(ConSrvHeap
, HEAP_ZERO_MEMORY
, sizeof(CSRSS_SCREEN_BUFFER
));
141 if (NULL
== NewBuffer
)
143 RtlFreeUnicodeString(&Console
->Title
);
144 DeleteCriticalSection(&Console
->Lock
);
145 CloseHandle(Console
->ActiveEvent
);
146 return STATUS_INSUFFICIENT_RESOURCES
;
148 /* init screen buffer with defaults */
149 NewBuffer
->CursorInfo
.bVisible
= TRUE
;
150 NewBuffer
->CursorInfo
.dwSize
= CSR_DEFAULT_CURSOR_SIZE
;
151 /* make console active, and insert into console list */
152 Console
->ActiveBuffer
= (PCSRSS_SCREEN_BUFFER
) NewBuffer
;
155 * If we are not in GUI-mode, start the text-mode console. If we fail,
156 * try to start the GUI-mode console (win32k will automatically switch
157 * to graphical mode, therefore no additional code is needed).
161 DPRINT1("CONSRV: Opening text-mode console\n");
162 Status
= TuiInitConsole(Console
);
163 if (!NT_SUCCESS(Status
))
165 DPRINT1("Failed to open text-mode console, switching to gui-mode, Status = 0x%08lx\n", Status
);
171 * Try to open the GUI-mode console. Two cases are possible:
172 * - We are in GUI-mode, therefore GuiMode == TRUE, the previous test-case
173 * failed and we start GUI-mode console.
174 * - We are in text-mode, therefore GuiMode == FALSE, the previous test-case
175 * succeeded BUT we failed at starting text-mode console. Then GuiMode
176 * was switched to TRUE in order to try to open the console in GUI-mode.
180 DPRINT1("CONSRV: Opening GUI-mode console\n");
181 Status
= GuiInitConsole(Console
, ShowCmd
);
182 if (!NT_SUCCESS(Status
))
184 HeapFree(ConSrvHeap
,0, NewBuffer
);
185 RtlFreeUnicodeString(&Console
->Title
);
186 DeleteCriticalSection(&Console
->Lock
);
187 CloseHandle(Console
->ActiveEvent
);
188 DPRINT1("GuiInitConsole: failed, Status = 0x%08lx\n", Status
);
193 Status
= CsrInitConsoleScreenBuffer(Console
, NewBuffer
);
194 if (!NT_SUCCESS(Status
))
196 ConioCleanupConsole(Console
);
197 RtlFreeUnicodeString(&Console
->Title
);
198 DeleteCriticalSection(&Console
->Lock
);
199 CloseHandle(Console
->ActiveEvent
);
200 HeapFree(ConSrvHeap
, 0, NewBuffer
);
201 DPRINT1("CsrInitConsoleScreenBuffer: failed\n");
205 /* copy buffer contents to screen */
206 ConioDrawConsole(Console
);
208 return STATUS_SUCCESS
;
211 CSR_API(SrvOpenConsole
)
213 NTSTATUS Status
= STATUS_SUCCESS
;
214 PCSRSS_OPEN_CONSOLE OpenConsoleRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.OpenConsoleRequest
;
215 PCONSOLE_PROCESS_DATA ProcessData
= ConsoleGetPerProcessData(CsrGetClientThread()->Process
);
217 DPRINT("SrvOpenConsole\n");
219 OpenConsoleRequest
->Handle
= INVALID_HANDLE_VALUE
;
221 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
223 DPRINT1("SrvOpenConsole - Checkpoint 1\n");
224 DPRINT1("ProcessData = 0x%p ; ProcessData->Console = 0x%p\n", ProcessData
, ProcessData
->Console
);
226 if (ProcessData
->Console
)
228 DWORD DesiredAccess
= OpenConsoleRequest
->Access
;
229 DWORD ShareMode
= OpenConsoleRequest
->ShareMode
;
231 PCSRSS_CONSOLE Console
= ProcessData
->Console
;
234 DPRINT1("SrvOpenConsole - Checkpoint 2\n");
235 EnterCriticalSection(&Console
->Lock
);
236 DPRINT1("SrvOpenConsole - Checkpoint 3\n");
238 if (OpenConsoleRequest
->HandleType
== HANDLE_OUTPUT
)
239 Object
= &Console
->ActiveBuffer
->Header
;
241 Object
= &Console
->Header
;
243 if (((DesiredAccess
& GENERIC_READ
) && Object
->ExclusiveRead
!= 0) ||
244 ((DesiredAccess
& GENERIC_WRITE
) && Object
->ExclusiveWrite
!= 0) ||
245 (!(ShareMode
& FILE_SHARE_READ
) && Object
->AccessRead
!= 0) ||
246 (!(ShareMode
& FILE_SHARE_WRITE
) && Object
->AccessWrite
!= 0))
248 DPRINT1("Sharing violation\n");
249 Status
= STATUS_SHARING_VIOLATION
;
253 Status
= Win32CsrInsertObject(ProcessData
,
254 &OpenConsoleRequest
->Handle
,
257 OpenConsoleRequest
->Inheritable
,
261 LeaveCriticalSection(&Console
->Lock
);
264 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
269 CSR_API(SrvAllocConsole
)
271 NTSTATUS Status
= STATUS_SUCCESS
;
272 PCSRSS_ALLOC_CONSOLE AllocConsoleRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.AllocConsoleRequest
;
273 PCONSOLE_PROCESS_DATA ProcessData
= ConsoleGetPerProcessData(CsrGetClientThread()->Process
);
274 PCSRSS_CONSOLE Console
;
275 BOOLEAN NewConsole
= FALSE
;
277 DPRINT("SrvAllocConsole\n");
279 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
281 if (ProcessData
->Console
)
283 DPRINT1("Process already has a console\n");
284 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
285 return STATUS_INVALID_PARAMETER
;
288 DPRINT1("SrvAllocConsole - Checkpoint 1\n");
290 /* If we don't need a console, then get out of here */
291 if (!AllocConsoleRequest
->ConsoleNeeded
)
293 DPRINT("No console needed\n");
294 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
295 return STATUS_SUCCESS
;
298 /* If we already have one, then don't create a new one... */
299 if (!AllocConsoleRequest
->Console
||
300 AllocConsoleRequest
->Console
!= ProcessData
->ParentConsole
)
302 /* Allocate a console structure */
304 Console
= HeapAlloc(ConSrvHeap
, HEAP_ZERO_MEMORY
, sizeof(CSRSS_CONSOLE
));
307 DPRINT1("Not enough memory for console\n");
308 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
309 return STATUS_NO_MEMORY
;
312 /* Initialize list head */
313 InitializeListHead(&Console
->ProcessList
);
315 /* Insert process data required for GUI initialization */
316 InsertHeadList(&Console
->ProcessList
, &ProcessData
->ConsoleLink
);
318 /* Initialize the Console */
319 Status
= CsrInitConsole(Console
, AllocConsoleRequest
->ShowCmd
);
320 if (!NT_SUCCESS(Status
))
322 DPRINT1("Console init failed\n");
323 HeapFree(ConSrvHeap
, 0, Console
);
324 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
330 /* Reuse our current console */
331 Console
= AllocConsoleRequest
->Console
;
334 /* Set the Process Console */
335 ProcessData
->Console
= Console
;
337 /* Return it to the caller */
338 AllocConsoleRequest
->Console
= Console
;
340 /* Add a reference count because the process is tied to the console */
341 _InterlockedIncrement(&Console
->ReferenceCount
);
343 if (NewConsole
|| !ProcessData
->bInheritHandles
)
345 /* Insert the Objects */
346 Status
= Win32CsrInsertObject(ProcessData
,
347 &AllocConsoleRequest
->InputHandle
,
349 GENERIC_READ
| GENERIC_WRITE
,
351 FILE_SHARE_READ
| FILE_SHARE_WRITE
);
352 if (! NT_SUCCESS(Status
))
354 DPRINT1("Failed to insert object\n");
355 ConioDeleteConsole((Object_t
*) Console
);
356 ProcessData
->Console
= NULL
;
357 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
361 Status
= Win32CsrInsertObject(ProcessData
,
362 &AllocConsoleRequest
->OutputHandle
,
363 &Console
->ActiveBuffer
->Header
,
364 GENERIC_READ
| GENERIC_WRITE
,
366 FILE_SHARE_READ
| FILE_SHARE_WRITE
);
367 if (!NT_SUCCESS(Status
))
369 DPRINT1("Failed to insert object\n");
370 ConioDeleteConsole((Object_t
*) Console
);
371 Win32CsrReleaseObject(ProcessData
,
372 AllocConsoleRequest
->InputHandle
);
373 ProcessData
->Console
= NULL
;
374 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
379 /* Duplicate the Event */
380 Status
= NtDuplicateObject(NtCurrentProcess(),
381 ProcessData
->Console
->ActiveEvent
,
382 ProcessData
->Process
->ProcessHandle
,
383 &ProcessData
->ConsoleEvent
,
384 EVENT_ALL_ACCESS
, 0, 0);
385 if (!NT_SUCCESS(Status
))
387 DPRINT1("NtDuplicateObject() failed: %lu\n", Status
);
388 ConioDeleteConsole((Object_t
*) Console
);
389 if (NewConsole
|| !ProcessData
->bInheritHandles
)
391 Win32CsrReleaseObject(ProcessData
,
392 AllocConsoleRequest
->OutputHandle
);
393 Win32CsrReleaseObject(ProcessData
,
394 AllocConsoleRequest
->InputHandle
);
396 ProcessData
->Console
= NULL
;
397 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
401 /* Set the Ctrl Dispatcher */
402 ProcessData
->CtrlDispatcher
= AllocConsoleRequest
->CtrlDispatcher
;
403 DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData
->CtrlDispatcher
);
407 /* Insert into the list if it has not been added */
408 InsertHeadList(&ProcessData
->Console
->ProcessList
, &ProcessData
->ConsoleLink
);
411 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
412 return STATUS_SUCCESS
;
415 CSR_API(SrvFreeConsole
)
417 Win32CsrReleaseConsole(CsrGetClientThread()->Process
);
418 return STATUS_SUCCESS
;
422 ConioDeleteConsole(Object_t
*Object
)
424 PCSRSS_CONSOLE Console
= (PCSRSS_CONSOLE
) Object
;
427 DPRINT("ConioDeleteConsole\n");
429 /* TODO: Dereference all the waits in Console->ReadWaitQueue */
430 /* TODO: Dereference all the waits in Console->WriteWaitQueue */
432 /* Drain input event queue */
433 while (Console
->InputEvents
.Flink
!= &Console
->InputEvents
)
435 Event
= (ConsoleInput
*) Console
->InputEvents
.Flink
;
436 Console
->InputEvents
.Flink
= Console
->InputEvents
.Flink
->Flink
;
437 Console
->InputEvents
.Flink
->Flink
->Blink
= &Console
->InputEvents
;
438 HeapFree(ConSrvHeap
, 0, Event
);
441 ConioCleanupConsole(Console
);
442 if (Console
->LineBuffer
)
443 RtlFreeHeap(ConSrvHeap
, 0, Console
->LineBuffer
);
444 while (!IsListEmpty(&Console
->HistoryBuffers
))
445 HistoryDeleteBuffer((struct tagHISTORY_BUFFER
*)Console
->HistoryBuffers
.Flink
);
447 ConioDeleteScreenBuffer(Console
->ActiveBuffer
);
448 if (!IsListEmpty(&Console
->BufferList
))
450 DPRINT1("BUG: screen buffer list not empty\n");
453 CloseHandle(Console
->ActiveEvent
);
454 if (Console
->UnpauseEvent
) CloseHandle(Console
->UnpauseEvent
);
455 DeleteCriticalSection(&Console
->Lock
);
456 RtlFreeUnicodeString(&Console
->Title
);
457 IntDeleteAllAliases(Console
->Aliases
);
458 HeapFree(ConSrvHeap
, 0, Console
);
462 CsrInitConsoleSupport(VOID
)
464 DPRINT("CSR: CsrInitConsoleSupport()\n");
466 /* Should call LoadKeyboardLayout */
470 ConioPause(PCSRSS_CONSOLE Console
, UINT Flags
)
472 Console
->PauseFlags
|= Flags
;
473 if (!Console
->UnpauseEvent
)
474 Console
->UnpauseEvent
= CreateEvent(NULL
, TRUE
, FALSE
, NULL
);
478 ConioUnpause(PCSRSS_CONSOLE Console
, UINT Flags
)
480 Console
->PauseFlags
&= ~Flags
;
482 // if ((Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION)) == 0)
483 if (Console
->PauseFlags
== 0 && Console
->UnpauseEvent
)
485 SetEvent(Console
->UnpauseEvent
);
486 CloseHandle(Console
->UnpauseEvent
);
487 Console
->UnpauseEvent
= NULL
;
489 CsrNotifyWait(&Console
->WriteWaitQueue
,
496 CSR_API(SrvSetConsoleMode
)
499 PCSRSS_CONSOLE_MODE ConsoleModeRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleModeRequest
;
500 PCSRSS_CONSOLE Console
;
501 PCSRSS_SCREEN_BUFFER Buff
;
503 DPRINT("SrvSetConsoleMode\n");
505 Status
= Win32CsrLockObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process
),
506 ConsoleModeRequest
->ConsoleHandle
,
507 (Object_t
**) &Console
, GENERIC_WRITE
, 0);
508 if (!NT_SUCCESS(Status
)) return Status
;
510 Buff
= (PCSRSS_SCREEN_BUFFER
)Console
;
512 if (CONIO_CONSOLE_MAGIC
== Console
->Header
.Type
)
514 Console
->Mode
= ConsoleModeRequest
->ConsoleMode
& CONSOLE_INPUT_MODE_VALID
;
516 else if (CONIO_SCREEN_BUFFER_MAGIC
== Console
->Header
.Type
)
518 Buff
->Mode
= ConsoleModeRequest
->ConsoleMode
& CONSOLE_OUTPUT_MODE_VALID
;
522 Status
= STATUS_INVALID_HANDLE
;
525 Win32CsrUnlockObject((Object_t
*)Console
);
530 CSR_API(SrvGetConsoleMode
)
533 PCSRSS_CONSOLE_MODE ConsoleModeRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleModeRequest
;
534 PCSRSS_CONSOLE Console
;
535 PCSRSS_SCREEN_BUFFER Buff
;
537 DPRINT("SrvGetConsoleMode\n");
539 Status
= Win32CsrLockObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process
),
540 ConsoleModeRequest
->ConsoleHandle
,
541 (Object_t
**) &Console
, GENERIC_READ
, 0);
542 if (!NT_SUCCESS(Status
)) return Status
;
544 Status
= STATUS_SUCCESS
;
545 Buff
= (PCSRSS_SCREEN_BUFFER
) Console
;
547 if (CONIO_CONSOLE_MAGIC
== Console
->Header
.Type
)
549 ConsoleModeRequest
->ConsoleMode
= Console
->Mode
;
551 else if (CONIO_SCREEN_BUFFER_MAGIC
== Buff
->Header
.Type
)
553 ConsoleModeRequest
->ConsoleMode
= Buff
->Mode
;
557 Status
= STATUS_INVALID_HANDLE
;
560 Win32CsrUnlockObject((Object_t
*)Console
);
564 CSR_API(SrvSetConsoleTitle
)
567 PCSRSS_CONSOLE_TITLE TitleRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.TitleRequest
;
568 // PCSR_PROCESS Process = CsrGetClientThread()->Process;
569 PCSRSS_CONSOLE Console
;
572 DPRINT("SrvSetConsoleTitle\n");
574 if (!CsrValidateMessageBuffer(ApiMessage
,
575 (PVOID
)&TitleRequest
->Title
,
576 TitleRequest
->Length
,
579 return STATUS_INVALID_PARAMETER
;
582 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
583 if(NT_SUCCESS(Status
))
585 Buffer
= RtlAllocateHeap(RtlGetProcessHeap(), 0, TitleRequest
->Length
);
588 /* Copy title to console */
589 RtlFreeUnicodeString(&Console
->Title
);
590 Console
->Title
.Buffer
= Buffer
;
591 Console
->Title
.Length
= Console
->Title
.MaximumLength
= TitleRequest
->Length
;
592 memcpy(Console
->Title
.Buffer
, TitleRequest
->Title
, Console
->Title
.Length
);
594 if (!ConioChangeTitle(Console
))
596 Status
= STATUS_UNSUCCESSFUL
;
600 Status
= STATUS_SUCCESS
;
605 Status
= STATUS_NO_MEMORY
;
608 ConioUnlockConsole(Console
);
614 CSR_API(SrvGetConsoleTitle
)
617 PCSRSS_CONSOLE_TITLE TitleRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.TitleRequest
;
618 // PCSR_PROCESS Process = CsrGetClientThread()->Process;
619 PCSRSS_CONSOLE Console
;
622 DPRINT("SrvGetConsoleTitle\n");
624 if (!CsrValidateMessageBuffer(ApiMessage
,
625 (PVOID
)&TitleRequest
->Title
,
626 TitleRequest
->Length
,
629 return STATUS_INVALID_PARAMETER
;
632 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
633 if (!NT_SUCCESS(Status
))
635 DPRINT1("Can't get console\n");
639 /* Copy title of the console to the user title buffer */
640 if (TitleRequest
->Length
>= sizeof(WCHAR
))
642 Length
= min(TitleRequest
->Length
- sizeof(WCHAR
), Console
->Title
.Length
);
643 memcpy(TitleRequest
->Title
, Console
->Title
.Buffer
, Length
);
644 TitleRequest
->Title
[Length
/ sizeof(WCHAR
)] = L
'\0';
647 TitleRequest
->Length
= Console
->Title
.Length
;
649 ConioUnlockConsole(Console
);
650 return STATUS_SUCCESS
;
653 /**********************************************************************
654 * HardwareStateProperty
657 * Set/Get the value of the HardwareState and switch
658 * between direct video buffer ouput and GDI windowed
661 * Client hands us a CSRSS_CONSOLE_HARDWARE_STATE
662 * object. We use the same object to Request.
664 * ConsoleHwState has the correct size to be compatible
665 * with NT's, but values are not.
667 static NTSTATUS FASTCALL
668 SetConsoleHardwareState(PCSRSS_CONSOLE Console
, DWORD ConsoleHwState
)
670 DPRINT1("Console Hardware State: %d\n", ConsoleHwState
);
672 if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED
== ConsoleHwState
)
673 ||(CONSOLE_HARDWARE_STATE_DIRECT
== ConsoleHwState
))
675 if (Console
->HardwareState
!= ConsoleHwState
)
677 /* TODO: implement switching from full screen to windowed mode */
678 /* TODO: or back; now simply store the hardware state */
679 Console
->HardwareState
= ConsoleHwState
;
682 return STATUS_SUCCESS
;
685 return STATUS_INVALID_PARAMETER_3
; /* Client: (handle, set_get, [mode]) */
688 CSR_API(SrvGetConsoleHardwareState
)
691 PCSRSS_CONSOLE_HW_STATE ConsoleHardwareStateRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleHardwareStateRequest
;
692 PCSRSS_CONSOLE Console
;
694 DPRINT("SrvGetConsoleHardwareState\n");
696 Status
= ConioLockConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process
),
697 ConsoleHardwareStateRequest
->ConsoleHandle
,
700 if (!NT_SUCCESS(Status
))
702 DPRINT1("Failed to get console handle in SrvGetConsoleHardwareState\n");
706 ConsoleHardwareStateRequest
->State
= Console
->HardwareState
;
708 ConioUnlockConsole(Console
);
713 CSR_API(SrvSetConsoleHardwareState
)
716 PCSRSS_CONSOLE_HW_STATE ConsoleHardwareStateRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleHardwareStateRequest
;
717 PCSRSS_CONSOLE Console
;
719 DPRINT("SrvSetConsoleHardwareState\n");
721 Status
= ConioLockConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process
),
722 ConsoleHardwareStateRequest
->ConsoleHandle
,
725 if (!NT_SUCCESS(Status
))
727 DPRINT1("Failed to get console handle in SrvSetConsoleHardwareState\n");
731 DPRINT("Setting console hardware state.\n");
732 Status
= SetConsoleHardwareState(Console
, ConsoleHardwareStateRequest
->State
);
734 ConioUnlockConsole(Console
);
739 CSR_API(SrvGetConsoleWindow
)
742 PCSRSS_GET_CONSOLE_WINDOW GetConsoleWindowRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetConsoleWindowRequest
;
743 PCSRSS_CONSOLE Console
;
745 DPRINT("SrvGetConsoleWindow\n");
747 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
748 if (!NT_SUCCESS(Status
)) return Status
;
750 GetConsoleWindowRequest
->WindowHandle
= Console
->hWindow
;
751 ConioUnlockConsole(Console
);
753 return STATUS_SUCCESS
;
756 CSR_API(SrvSetConsoleIcon
)
759 PCSRSS_SET_CONSOLE_ICON SetConsoleIconRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.SetConsoleIconRequest
;
760 PCSRSS_CONSOLE Console
;
762 DPRINT("SrvSetConsoleIcon\n");
764 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
765 if (!NT_SUCCESS(Status
)) return Status
;
767 Status
= (ConioChangeIcon(Console
, SetConsoleIconRequest
->WindowIcon
)
769 : STATUS_UNSUCCESSFUL
);
771 ConioUnlockConsole(Console
);
776 CSR_API(SrvGetConsoleCP
)
779 PCSRSS_CONSOLE_CP ConsoleCPRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleCPRequest
;
780 PCSRSS_CONSOLE Console
;
782 DPRINT("SrvGetConsoleCP, getting %s Code Page\n",
783 ConsoleCPRequest
->InputCP
? "Input" : "Output");
785 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
786 if (!NT_SUCCESS(Status
)) return Status
;
788 ConsoleCPRequest
->CodePage
= (ConsoleCPRequest
->InputCP
? Console
->CodePage
789 : Console
->OutputCodePage
);
790 ConioUnlockConsole(Console
);
791 return STATUS_SUCCESS
;
794 CSR_API(SrvSetConsoleCP
)
797 PCSRSS_CONSOLE_CP ConsoleCPRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleCPRequest
;
798 PCSRSS_CONSOLE Console
;
800 DPRINT("SrvSetConsoleCP, setting %s Code Page\n",
801 ConsoleCPRequest
->InputCP
? "Input" : "Output");
803 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
804 if (!NT_SUCCESS(Status
)) return Status
;
806 if (IsValidCodePage(ConsoleCPRequest
->CodePage
))
808 if (ConsoleCPRequest
->InputCP
)
809 Console
->CodePage
= ConsoleCPRequest
->CodePage
;
811 Console
->OutputCodePage
= ConsoleCPRequest
->CodePage
;
813 ConioUnlockConsole(Console
);
814 return STATUS_SUCCESS
;
817 ConioUnlockConsole(Console
);
818 return STATUS_INVALID_PARAMETER
;
821 CSR_API(SrvGetConsoleProcessList
)
824 PCSRSS_GET_PROCESS_LIST GetProcessListRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetProcessListRequest
;
826 // PCSR_PROCESS Process = CsrGetClientThread()->Process;
827 PCSRSS_CONSOLE Console
;
828 PCONSOLE_PROCESS_DATA current
;
829 PLIST_ENTRY current_entry
;
832 DPRINT("SrvGetConsoleProcessList\n");
834 if (!CsrValidateMessageBuffer(ApiMessage
,
835 (PVOID
)&GetProcessListRequest
->pProcessIds
,
836 GetProcessListRequest
->nMaxIds
,
839 return STATUS_INVALID_PARAMETER
;
842 Buffer
= GetProcessListRequest
->pProcessIds
;
844 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
845 if (!NT_SUCCESS(Status
)) return Status
;
847 for (current_entry
= Console
->ProcessList
.Flink
;
848 current_entry
!= &Console
->ProcessList
;
849 current_entry
= current_entry
->Flink
)
851 current
= CONTAINING_RECORD(current_entry
, CONSOLE_PROCESS_DATA
, ConsoleLink
);
852 if (++nItems
<= GetProcessListRequest
->nMaxIds
)
854 *Buffer
++ = HandleToUlong(current
->Process
->ClientId
.UniqueProcess
);
858 ConioUnlockConsole(Console
);
860 GetProcessListRequest
->nProcessIdsTotal
= nItems
;
861 return STATUS_SUCCESS
;
864 CSR_API(SrvGenerateConsoleCtrlEvent
)
867 PCSRSS_GENERATE_CTRL_EVENT GenerateCtrlEvent
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GenerateCtrlEvent
;
868 PCSRSS_CONSOLE Console
;
869 PCONSOLE_PROCESS_DATA current
;
870 PLIST_ENTRY current_entry
;
873 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
874 if (!NT_SUCCESS(Status
)) return Status
;
876 Group
= GenerateCtrlEvent
->ProcessGroup
;
877 Status
= STATUS_INVALID_PARAMETER
;
878 for (current_entry
= Console
->ProcessList
.Flink
;
879 current_entry
!= &Console
->ProcessList
;
880 current_entry
= current_entry
->Flink
)
882 current
= CONTAINING_RECORD(current_entry
, CONSOLE_PROCESS_DATA
, ConsoleLink
);
883 if (Group
== 0 || current
->Process
->ProcessGroupId
== Group
)
885 ConioConsoleCtrlEvent(GenerateCtrlEvent
->Event
, current
);
886 Status
= STATUS_SUCCESS
;
890 ConioUnlockConsole(Console
);
895 CSR_API(SrvGetConsoleSelectionInfo
)
898 PCSRSS_GET_CONSOLE_SELECTION_INFO GetConsoleSelectionInfo
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetConsoleSelectionInfo
;
899 PCSRSS_CONSOLE Console
;
901 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
902 if (NT_SUCCESS(Status
))
904 memset(&GetConsoleSelectionInfo
->Info
, 0, sizeof(CONSOLE_SELECTION_INFO
));
905 if (Console
->Selection
.dwFlags
!= 0)
906 GetConsoleSelectionInfo
->Info
= Console
->Selection
;
907 ConioUnlockConsole(Console
);