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
->InputEvents
);
119 InitializeListHead(&Console
->HistoryBuffers
);
120 Console
->CodePage
= GetOEMCP();
121 Console
->OutputCodePage
= GetOEMCP();
123 SecurityAttributes
.nLength
= sizeof(SECURITY_ATTRIBUTES
);
124 SecurityAttributes
.lpSecurityDescriptor
= NULL
;
125 SecurityAttributes
.bInheritHandle
= TRUE
;
127 Console
->ActiveEvent
= CreateEventW(&SecurityAttributes
, TRUE
, FALSE
, NULL
);
128 if (NULL
== Console
->ActiveEvent
)
130 RtlFreeUnicodeString(&Console
->Title
);
131 return STATUS_UNSUCCESSFUL
;
133 Console
->PrivateData
= NULL
;
134 InitializeCriticalSection(&Console
->Lock
);
136 GuiMode
= DtbgIsDesktopVisible();
138 /* allocate console screen buffer */
139 NewBuffer
= HeapAlloc(ConSrvHeap
, HEAP_ZERO_MEMORY
, sizeof(CSRSS_SCREEN_BUFFER
));
140 if (NULL
== NewBuffer
)
142 RtlFreeUnicodeString(&Console
->Title
);
143 DeleteCriticalSection(&Console
->Lock
);
144 CloseHandle(Console
->ActiveEvent
);
145 return STATUS_INSUFFICIENT_RESOURCES
;
147 /* init screen buffer with defaults */
148 NewBuffer
->CursorInfo
.bVisible
= TRUE
;
149 NewBuffer
->CursorInfo
.dwSize
= CSR_DEFAULT_CURSOR_SIZE
;
150 /* make console active, and insert into console list */
151 Console
->ActiveBuffer
= (PCSRSS_SCREEN_BUFFER
) NewBuffer
;
154 * If we are not in GUI-mode, start the text-mode console. If we fail,
155 * try to start the GUI-mode console (win32k will automatically switch
156 * to graphical mode, therefore no additional code is needed).
160 DPRINT1("CONSRV: Opening text-mode console\n");
161 Status
= TuiInitConsole(Console
);
162 if (!NT_SUCCESS(Status
))
164 DPRINT1("Failed to open text-mode console, switching to gui-mode, Status = 0x%08lx\n", Status
);
170 * Try to open the GUI-mode console. Two cases are possible:
171 * - We are in GUI-mode, therefore GuiMode == TRUE, the previous test-case
172 * failed and we start GUI-mode console.
173 * - We are in text-mode, therefore GuiMode == FALSE, the previous test-case
174 * succeeded BUT we failed at starting text-mode console. Then GuiMode
175 * was switched to TRUE in order to try to open the console in GUI-mode.
179 DPRINT1("CONSRV: Opening GUI-mode console\n");
180 Status
= GuiInitConsole(Console
, ShowCmd
);
181 if (!NT_SUCCESS(Status
))
183 HeapFree(ConSrvHeap
,0, NewBuffer
);
184 RtlFreeUnicodeString(&Console
->Title
);
185 DeleteCriticalSection(&Console
->Lock
);
186 CloseHandle(Console
->ActiveEvent
);
187 DPRINT1("GuiInitConsole: failed, Status = 0x%08lx\n", Status
);
192 Status
= CsrInitConsoleScreenBuffer(Console
, NewBuffer
);
193 if (!NT_SUCCESS(Status
))
195 ConioCleanupConsole(Console
);
196 RtlFreeUnicodeString(&Console
->Title
);
197 DeleteCriticalSection(&Console
->Lock
);
198 CloseHandle(Console
->ActiveEvent
);
199 HeapFree(ConSrvHeap
, 0, NewBuffer
);
200 DPRINT1("CsrInitConsoleScreenBuffer: failed\n");
204 /* copy buffer contents to screen */
205 ConioDrawConsole(Console
);
207 return STATUS_SUCCESS
;
210 CSR_API(SrvOpenConsole
)
212 NTSTATUS Status
= STATUS_SUCCESS
;
213 PCSRSS_OPEN_CONSOLE OpenConsoleRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.OpenConsoleRequest
;
214 PCONSOLE_PROCESS_DATA ProcessData
= ConsoleGetPerProcessData(CsrGetClientThread()->Process
);
216 DPRINT("SrvOpenConsole\n");
218 OpenConsoleRequest
->Handle
= INVALID_HANDLE_VALUE
;
220 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
222 DPRINT1("SrvOpenConsole - Checkpoint 1\n");
223 DPRINT1("ProcessData = 0x%p ; ProcessData->Console = 0x%p\n", ProcessData
, ProcessData
->Console
);
225 if (ProcessData
->Console
)
227 DWORD DesiredAccess
= OpenConsoleRequest
->Access
;
228 DWORD ShareMode
= OpenConsoleRequest
->ShareMode
;
230 PCSRSS_CONSOLE Console
= ProcessData
->Console
;
233 DPRINT1("SrvOpenConsole - Checkpoint 2\n");
234 EnterCriticalSection(&Console
->Lock
);
235 DPRINT1("SrvOpenConsole - Checkpoint 3\n");
237 if (OpenConsoleRequest
->HandleType
== HANDLE_OUTPUT
)
238 Object
= &Console
->ActiveBuffer
->Header
;
240 Object
= &Console
->Header
;
242 if (((DesiredAccess
& GENERIC_READ
) && Object
->ExclusiveRead
!= 0) ||
243 ((DesiredAccess
& GENERIC_WRITE
) && Object
->ExclusiveWrite
!= 0) ||
244 (!(ShareMode
& FILE_SHARE_READ
) && Object
->AccessRead
!= 0) ||
245 (!(ShareMode
& FILE_SHARE_WRITE
) && Object
->AccessWrite
!= 0))
247 DPRINT1("Sharing violation\n");
248 Status
= STATUS_SHARING_VIOLATION
;
252 Status
= Win32CsrInsertObject(ProcessData
,
253 &OpenConsoleRequest
->Handle
,
256 OpenConsoleRequest
->Inheritable
,
260 LeaveCriticalSection(&Console
->Lock
);
263 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
268 CSR_API(SrvAllocConsole
)
270 NTSTATUS Status
= STATUS_SUCCESS
;
271 PCSRSS_ALLOC_CONSOLE AllocConsoleRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.AllocConsoleRequest
;
272 PCONSOLE_PROCESS_DATA ProcessData
= ConsoleGetPerProcessData(CsrGetClientThread()->Process
);
273 PCSRSS_CONSOLE Console
;
274 BOOLEAN NewConsole
= FALSE
;
276 DPRINT("SrvAllocConsole\n");
278 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
280 if (ProcessData
->Console
)
282 DPRINT1("Process already has a console\n");
283 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
284 return STATUS_INVALID_PARAMETER
;
287 DPRINT1("SrvAllocConsole - Checkpoint 1\n");
289 /* If we don't need a console, then get out of here */
290 if (!AllocConsoleRequest
->ConsoleNeeded
)
292 DPRINT("No console needed\n");
293 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
294 return STATUS_SUCCESS
;
297 /* If we already have one, then don't create a new one... */
298 if (!AllocConsoleRequest
->Console
||
299 AllocConsoleRequest
->Console
!= ProcessData
->ParentConsole
)
301 /* Allocate a console structure */
303 Console
= HeapAlloc(ConSrvHeap
, HEAP_ZERO_MEMORY
, sizeof(CSRSS_CONSOLE
));
306 DPRINT1("Not enough memory for console\n");
307 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
308 return STATUS_NO_MEMORY
;
311 /* Initialize list head */
312 InitializeListHead(&Console
->ProcessList
);
314 /* Insert process data required for GUI initialization */
315 InsertHeadList(&Console
->ProcessList
, &ProcessData
->ConsoleLink
);
317 /* Initialize the Console */
318 Status
= CsrInitConsole(Console
, AllocConsoleRequest
->ShowCmd
);
319 if (!NT_SUCCESS(Status
))
321 DPRINT1("Console init failed\n");
322 HeapFree(ConSrvHeap
, 0, Console
);
323 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
329 /* Reuse our current console */
330 Console
= AllocConsoleRequest
->Console
;
333 /* Set the Process Console */
334 ProcessData
->Console
= Console
;
336 /* Return it to the caller */
337 AllocConsoleRequest
->Console
= Console
;
339 /* Add a reference count because the process is tied to the console */
340 _InterlockedIncrement(&Console
->ReferenceCount
);
342 if (NewConsole
|| !ProcessData
->bInheritHandles
)
344 /* Insert the Objects */
345 Status
= Win32CsrInsertObject(ProcessData
,
346 &AllocConsoleRequest
->InputHandle
,
348 GENERIC_READ
| GENERIC_WRITE
,
350 FILE_SHARE_READ
| FILE_SHARE_WRITE
);
351 if (! NT_SUCCESS(Status
))
353 DPRINT1("Failed to insert object\n");
354 ConioDeleteConsole((Object_t
*) Console
);
355 ProcessData
->Console
= NULL
;
356 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
360 Status
= Win32CsrInsertObject(ProcessData
,
361 &AllocConsoleRequest
->OutputHandle
,
362 &Console
->ActiveBuffer
->Header
,
363 GENERIC_READ
| GENERIC_WRITE
,
365 FILE_SHARE_READ
| FILE_SHARE_WRITE
);
366 if (!NT_SUCCESS(Status
))
368 DPRINT1("Failed to insert object\n");
369 ConioDeleteConsole((Object_t
*) Console
);
370 Win32CsrReleaseObject(ProcessData
,
371 AllocConsoleRequest
->InputHandle
);
372 ProcessData
->Console
= NULL
;
373 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
378 /* Duplicate the Event */
379 Status
= NtDuplicateObject(NtCurrentProcess(),
380 ProcessData
->Console
->ActiveEvent
,
381 ProcessData
->Process
->ProcessHandle
,
382 &ProcessData
->ConsoleEvent
,
383 EVENT_ALL_ACCESS
, 0, 0);
384 if (!NT_SUCCESS(Status
))
386 DPRINT1("NtDuplicateObject() failed: %lu\n", Status
);
387 ConioDeleteConsole((Object_t
*) Console
);
388 if (NewConsole
|| !ProcessData
->bInheritHandles
)
390 Win32CsrReleaseObject(ProcessData
,
391 AllocConsoleRequest
->OutputHandle
);
392 Win32CsrReleaseObject(ProcessData
,
393 AllocConsoleRequest
->InputHandle
);
395 ProcessData
->Console
= NULL
;
396 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
400 /* Set the Ctrl Dispatcher */
401 ProcessData
->CtrlDispatcher
= AllocConsoleRequest
->CtrlDispatcher
;
402 DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData
->CtrlDispatcher
);
406 /* Insert into the list if it has not been added */
407 InsertHeadList(&ProcessData
->Console
->ProcessList
, &ProcessData
->ConsoleLink
);
410 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
411 return STATUS_SUCCESS
;
414 CSR_API(SrvFreeConsole
)
416 Win32CsrReleaseConsole(CsrGetClientThread()->Process
);
417 return STATUS_SUCCESS
;
421 ConioDeleteConsole(Object_t
*Object
)
423 PCSRSS_CONSOLE Console
= (PCSRSS_CONSOLE
) Object
;
426 DPRINT("ConioDeleteConsole\n");
428 /* TODO: Dereference all the waits in Console->ReadWaitQueue */
430 /* Drain input event queue */
431 while (Console
->InputEvents
.Flink
!= &Console
->InputEvents
)
433 Event
= (ConsoleInput
*) Console
->InputEvents
.Flink
;
434 Console
->InputEvents
.Flink
= Console
->InputEvents
.Flink
->Flink
;
435 Console
->InputEvents
.Flink
->Flink
->Blink
= &Console
->InputEvents
;
436 HeapFree(ConSrvHeap
, 0, Event
);
439 ConioCleanupConsole(Console
);
440 if (Console
->LineBuffer
)
441 RtlFreeHeap(ConSrvHeap
, 0, Console
->LineBuffer
);
442 while (!IsListEmpty(&Console
->HistoryBuffers
))
443 HistoryDeleteBuffer((struct tagHISTORY_BUFFER
*)Console
->HistoryBuffers
.Flink
);
445 ConioDeleteScreenBuffer(Console
->ActiveBuffer
);
446 if (!IsListEmpty(&Console
->BufferList
))
448 DPRINT1("BUG: screen buffer list not empty\n");
451 CloseHandle(Console
->ActiveEvent
);
452 if (Console
->UnpauseEvent
) CloseHandle(Console
->UnpauseEvent
);
453 DeleteCriticalSection(&Console
->Lock
);
454 RtlFreeUnicodeString(&Console
->Title
);
455 IntDeleteAllAliases(Console
->Aliases
);
456 HeapFree(ConSrvHeap
, 0, Console
);
460 CsrInitConsoleSupport(VOID
)
462 DPRINT("CSR: CsrInitConsoleSupport()\n");
464 /* Should call LoadKeyboardLayout */
468 ConioPause(PCSRSS_CONSOLE Console
, UINT Flags
)
470 Console
->PauseFlags
|= Flags
;
471 if (!Console
->UnpauseEvent
)
472 Console
->UnpauseEvent
= CreateEvent(NULL
, TRUE
, FALSE
, NULL
);
476 ConioUnpause(PCSRSS_CONSOLE Console
, UINT Flags
)
478 Console
->PauseFlags
&= ~Flags
;
479 if (Console
->PauseFlags
== 0 && Console
->UnpauseEvent
)
481 SetEvent(Console
->UnpauseEvent
);
482 CloseHandle(Console
->UnpauseEvent
);
483 Console
->UnpauseEvent
= NULL
;
487 CSR_API(SrvSetConsoleMode
)
490 PCSRSS_CONSOLE_MODE ConsoleModeRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleModeRequest
;
491 PCSRSS_CONSOLE Console
;
492 PCSRSS_SCREEN_BUFFER Buff
;
494 DPRINT("SrvSetConsoleMode\n");
496 Status
= Win32CsrLockObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process
),
497 ConsoleModeRequest
->ConsoleHandle
,
498 (Object_t
**) &Console
, GENERIC_WRITE
, 0);
499 if (!NT_SUCCESS(Status
)) return Status
;
501 Buff
= (PCSRSS_SCREEN_BUFFER
)Console
;
503 if (CONIO_CONSOLE_MAGIC
== Console
->Header
.Type
)
505 Console
->Mode
= ConsoleModeRequest
->ConsoleMode
& CONSOLE_INPUT_MODE_VALID
;
507 else if (CONIO_SCREEN_BUFFER_MAGIC
== Console
->Header
.Type
)
509 Buff
->Mode
= ConsoleModeRequest
->ConsoleMode
& CONSOLE_OUTPUT_MODE_VALID
;
513 Status
= STATUS_INVALID_HANDLE
;
516 Win32CsrUnlockObject((Object_t
*)Console
);
521 CSR_API(SrvGetConsoleMode
)
524 PCSRSS_CONSOLE_MODE ConsoleModeRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleModeRequest
;
525 PCSRSS_CONSOLE Console
;
526 PCSRSS_SCREEN_BUFFER Buff
;
528 DPRINT("SrvGetConsoleMode\n");
530 Status
= Win32CsrLockObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process
),
531 ConsoleModeRequest
->ConsoleHandle
,
532 (Object_t
**) &Console
, GENERIC_READ
, 0);
533 if (!NT_SUCCESS(Status
)) return Status
;
535 Status
= STATUS_SUCCESS
;
536 Buff
= (PCSRSS_SCREEN_BUFFER
) Console
;
538 if (CONIO_CONSOLE_MAGIC
== Console
->Header
.Type
)
540 ConsoleModeRequest
->ConsoleMode
= Console
->Mode
;
542 else if (CONIO_SCREEN_BUFFER_MAGIC
== Buff
->Header
.Type
)
544 ConsoleModeRequest
->ConsoleMode
= Buff
->Mode
;
548 Status
= STATUS_INVALID_HANDLE
;
551 Win32CsrUnlockObject((Object_t
*)Console
);
555 CSR_API(SrvSetConsoleTitle
)
558 PCSRSS_CONSOLE_TITLE TitleRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.TitleRequest
;
559 // PCSR_PROCESS Process = CsrGetClientThread()->Process;
560 PCSRSS_CONSOLE Console
;
563 DPRINT("SrvSetConsoleTitle\n");
565 if (!CsrValidateMessageBuffer(ApiMessage
,
566 (PVOID
)&TitleRequest
->Title
,
567 TitleRequest
->Length
,
570 return STATUS_INVALID_PARAMETER
;
573 if (!Win32CsrValidateBuffer(Process, TitleRequest->Title,
574 TitleRequest->Length, 1))
576 return STATUS_ACCESS_VIOLATION;
580 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
581 if(NT_SUCCESS(Status
))
583 Buffer
= RtlAllocateHeap(RtlGetProcessHeap(), 0, TitleRequest
->Length
);
586 /* Copy title to console */
587 RtlFreeUnicodeString(&Console
->Title
);
588 Console
->Title
.Buffer
= Buffer
;
589 Console
->Title
.Length
= Console
->Title
.MaximumLength
= TitleRequest
->Length
;
590 memcpy(Console
->Title
.Buffer
, TitleRequest
->Title
, Console
->Title
.Length
);
592 if (!ConioChangeTitle(Console
))
594 Status
= STATUS_UNSUCCESSFUL
;
598 Status
= STATUS_SUCCESS
;
603 Status
= STATUS_NO_MEMORY
;
606 ConioUnlockConsole(Console
);
612 CSR_API(SrvGetConsoleTitle
)
615 PCSRSS_CONSOLE_TITLE TitleRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.TitleRequest
;
616 // PCSR_PROCESS Process = CsrGetClientThread()->Process;
617 PCSRSS_CONSOLE Console
;
620 DPRINT("SrvGetConsoleTitle\n");
622 if (!CsrValidateMessageBuffer(ApiMessage
,
623 (PVOID
)&TitleRequest
->Title
,
624 TitleRequest
->Length
,
627 return STATUS_INVALID_PARAMETER
;
630 if (!Win32CsrValidateBuffer(Process, TitleRequest->Title,
631 TitleRequest->Length, 1))
633 return STATUS_ACCESS_VIOLATION;
637 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
638 if (!NT_SUCCESS(Status
))
640 DPRINT1("Can't get console\n");
644 /* Copy title of the console to the user title buffer */
645 if (TitleRequest
->Length
>= sizeof(WCHAR
))
647 Length
= min(TitleRequest
->Length
- sizeof(WCHAR
), Console
->Title
.Length
);
648 memcpy(TitleRequest
->Title
, Console
->Title
.Buffer
, Length
);
649 TitleRequest
->Title
[Length
/ sizeof(WCHAR
)] = L
'\0';
652 TitleRequest
->Length
= Console
->Title
.Length
;
654 ConioUnlockConsole(Console
);
655 return STATUS_SUCCESS
;
658 /**********************************************************************
659 * HardwareStateProperty
662 * Set/Get the value of the HardwareState and switch
663 * between direct video buffer ouput and GDI windowed
666 * Client hands us a CSRSS_CONSOLE_HARDWARE_STATE
667 * object. We use the same object to Request.
669 * ConsoleHwState has the correct size to be compatible
670 * with NT's, but values are not.
672 static NTSTATUS FASTCALL
673 SetConsoleHardwareState(PCSRSS_CONSOLE Console
, DWORD ConsoleHwState
)
675 DPRINT1("Console Hardware State: %d\n", ConsoleHwState
);
677 if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED
== ConsoleHwState
)
678 ||(CONSOLE_HARDWARE_STATE_DIRECT
== ConsoleHwState
))
680 if (Console
->HardwareState
!= ConsoleHwState
)
682 /* TODO: implement switching from full screen to windowed mode */
683 /* TODO: or back; now simply store the hardware state */
684 Console
->HardwareState
= ConsoleHwState
;
687 return STATUS_SUCCESS
;
690 return STATUS_INVALID_PARAMETER_3
; /* Client: (handle, set_get, [mode]) */
693 CSR_API(SrvGetConsoleHardwareState
)
696 PCSRSS_CONSOLE_HW_STATE ConsoleHardwareStateRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleHardwareStateRequest
;
697 PCSRSS_CONSOLE Console
;
699 DPRINT("SrvGetConsoleHardwareState\n");
701 Status
= ConioLockConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process
),
702 ConsoleHardwareStateRequest
->ConsoleHandle
,
705 if (!NT_SUCCESS(Status
))
707 DPRINT1("Failed to get console handle in SrvGetConsoleHardwareState\n");
711 ConsoleHardwareStateRequest
->State
= Console
->HardwareState
;
713 ConioUnlockConsole(Console
);
718 CSR_API(SrvSetConsoleHardwareState
)
721 PCSRSS_CONSOLE_HW_STATE ConsoleHardwareStateRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleHardwareStateRequest
;
722 PCSRSS_CONSOLE Console
;
724 DPRINT("SrvSetConsoleHardwareState\n");
726 Status
= ConioLockConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process
),
727 ConsoleHardwareStateRequest
->ConsoleHandle
,
730 if (!NT_SUCCESS(Status
))
732 DPRINT1("Failed to get console handle in SrvSetConsoleHardwareState\n");
736 DPRINT("Setting console hardware state.\n");
737 Status
= SetConsoleHardwareState(Console
, ConsoleHardwareStateRequest
->State
);
739 ConioUnlockConsole(Console
);
744 CSR_API(SrvGetConsoleWindow
)
747 PCSRSS_GET_CONSOLE_WINDOW GetConsoleWindowRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetConsoleWindowRequest
;
748 PCSRSS_CONSOLE Console
;
750 DPRINT("SrvGetConsoleWindow\n");
752 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
753 if (!NT_SUCCESS(Status
)) return Status
;
755 GetConsoleWindowRequest
->WindowHandle
= Console
->hWindow
;
756 ConioUnlockConsole(Console
);
758 return STATUS_SUCCESS
;
761 CSR_API(SrvSetConsoleIcon
)
764 PCSRSS_SET_CONSOLE_ICON SetConsoleIconRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.SetConsoleIconRequest
;
765 PCSRSS_CONSOLE Console
;
767 DPRINT("SrvSetConsoleIcon\n");
769 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
770 if (!NT_SUCCESS(Status
)) return Status
;
772 Status
= (ConioChangeIcon(Console
, SetConsoleIconRequest
->WindowIcon
)
774 : STATUS_UNSUCCESSFUL
);
776 ConioUnlockConsole(Console
);
781 CSR_API(SrvGetConsoleCP
)
784 PCSRSS_CONSOLE_CP ConsoleCPRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleCPRequest
;
785 PCSRSS_CONSOLE Console
;
787 DPRINT("SrvGetConsoleCP, getting %s Code Page\n",
788 ConsoleCPRequest
->InputCP
? "Input" : "Output");
790 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
791 if (!NT_SUCCESS(Status
)) return Status
;
793 ConsoleCPRequest
->CodePage
= (ConsoleCPRequest
->InputCP
? Console
->CodePage
794 : Console
->OutputCodePage
);
795 ConioUnlockConsole(Console
);
796 return STATUS_SUCCESS
;
799 CSR_API(SrvSetConsoleCP
)
802 PCSRSS_CONSOLE_CP ConsoleCPRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleCPRequest
;
803 PCSRSS_CONSOLE Console
;
805 DPRINT("SrvSetConsoleCP, setting %s Code Page\n",
806 ConsoleCPRequest
->InputCP
? "Input" : "Output");
808 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
809 if (!NT_SUCCESS(Status
)) return Status
;
811 if (IsValidCodePage(ConsoleCPRequest
->CodePage
))
813 if (ConsoleCPRequest
->InputCP
)
814 Console
->CodePage
= ConsoleCPRequest
->CodePage
;
816 Console
->OutputCodePage
= ConsoleCPRequest
->CodePage
;
818 ConioUnlockConsole(Console
);
819 return STATUS_SUCCESS
;
822 ConioUnlockConsole(Console
);
823 return STATUS_INVALID_PARAMETER
;
826 CSR_API(SrvGetConsoleProcessList
)
829 PCSRSS_GET_PROCESS_LIST GetProcessListRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetProcessListRequest
;
831 // PCSR_PROCESS Process = CsrGetClientThread()->Process;
832 PCSRSS_CONSOLE Console
;
833 PCONSOLE_PROCESS_DATA current
;
834 PLIST_ENTRY current_entry
;
837 DPRINT("SrvGetConsoleProcessList\n");
839 if (!CsrValidateMessageBuffer(ApiMessage
,
840 (PVOID
)&GetProcessListRequest
->pProcessIds
,
841 GetProcessListRequest
->nMaxIds
,
844 return STATUS_INVALID_PARAMETER
;
847 Buffer
= GetProcessListRequest
->pProcessIds
;
850 if (!Win32CsrValidateBuffer(ProcessData, Buffer, GetProcessListRequest->nMaxIds, sizeof(DWORD)))
851 return STATUS_ACCESS_VIOLATION;
854 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
855 if (!NT_SUCCESS(Status
)) return Status
;
857 for (current_entry
= Console
->ProcessList
.Flink
;
858 current_entry
!= &Console
->ProcessList
;
859 current_entry
= current_entry
->Flink
)
861 current
= CONTAINING_RECORD(current_entry
, CONSOLE_PROCESS_DATA
, ConsoleLink
);
862 if (++nItems
<= GetProcessListRequest
->nMaxIds
)
864 *Buffer
++ = HandleToUlong(current
->Process
->ClientId
.UniqueProcess
);
868 ConioUnlockConsole(Console
);
870 GetProcessListRequest
->nProcessIdsTotal
= nItems
;
871 return STATUS_SUCCESS
;
874 CSR_API(SrvGenerateConsoleCtrlEvent
)
877 PCSRSS_GENERATE_CTRL_EVENT GenerateCtrlEvent
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GenerateCtrlEvent
;
878 PCSRSS_CONSOLE Console
;
879 PCONSOLE_PROCESS_DATA current
;
880 PLIST_ENTRY current_entry
;
883 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
884 if (!NT_SUCCESS(Status
)) return Status
;
886 Group
= GenerateCtrlEvent
->ProcessGroup
;
887 Status
= STATUS_INVALID_PARAMETER
;
888 for (current_entry
= Console
->ProcessList
.Flink
;
889 current_entry
!= &Console
->ProcessList
;
890 current_entry
= current_entry
->Flink
)
892 current
= CONTAINING_RECORD(current_entry
, CONSOLE_PROCESS_DATA
, ConsoleLink
);
893 if (Group
== 0 || current
->Process
->ProcessGroupId
== Group
)
895 ConioConsoleCtrlEvent(GenerateCtrlEvent
->Event
, current
);
896 Status
= STATUS_SUCCESS
;
900 ConioUnlockConsole(Console
);
905 CSR_API(SrvGetConsoleSelectionInfo
)
908 PCSRSS_GET_CONSOLE_SELECTION_INFO GetConsoleSelectionInfo
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetConsoleSelectionInfo
;
909 PCSRSS_CONSOLE Console
;
911 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
912 if (NT_SUCCESS(Status
))
914 memset(&GetConsoleSelectionInfo
->Info
, 0, sizeof(CONSOLE_SELECTION_INFO
));
915 if (Console
->Selection
.dwFlags
!= 0)
916 GetConsoleSelectionInfo
->Info
= Console
->Selection
;
917 ConioUnlockConsole(Console
);