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
;
153 * If we are not in GUI-mode, start the text-mode console. If we fail,
154 * try to start the GUI-mode console (win32k will automatically switch
155 * to graphical mode, therefore no additional code is needed).
159 DPRINT1("WIN32CSR: Opening text-mode console\n");
160 Status
= TuiInitConsole(Console
);
161 if (!NT_SUCCESS(Status
))
163 DPRINT1("Failed to open text-mode console, switching to gui-mode, Status = 0x%08lx\n", Status
);
169 * Try to open the GUI-mode console. Two cases are possible:
170 * - We are in GUI-mode, therefore GuiMode == TRUE, the previous test-case
171 * failed and we start GUI-mode console.
172 * - We are in text-mode, therefore GuiMode == FALSE, the previous test-case
173 * succeeded BUT we failed at starting text-mode console. Then GuiMode
174 * was switched to TRUE in order to try to open the console in GUI-mode.
178 DPRINT1("WIN32CSR: Opening GUI-mode console\n");
179 Status
= GuiInitConsole(Console
, ShowCmd
);
180 if (!NT_SUCCESS(Status
))
182 HeapFree(ConSrvHeap
,0, NewBuffer
);
183 RtlFreeUnicodeString(&Console
->Title
);
184 DeleteCriticalSection(&Console
->Lock
);
185 CloseHandle(Console
->ActiveEvent
);
186 DPRINT1("GuiInitConsole: failed, Status = 0x%08lx\n", Status
);
191 Status
= CsrInitConsoleScreenBuffer(Console
, NewBuffer
);
192 if (!NT_SUCCESS(Status
))
194 ConioCleanupConsole(Console
);
195 RtlFreeUnicodeString(&Console
->Title
);
196 DeleteCriticalSection(&Console
->Lock
);
197 CloseHandle(Console
->ActiveEvent
);
198 HeapFree(ConSrvHeap
, 0, NewBuffer
);
199 DPRINT1("CsrInitConsoleScreenBuffer: failed\n");
203 /* copy buffer contents to screen */
204 ConioDrawConsole(Console
);
206 return STATUS_SUCCESS
;
209 CSR_API(SrvOpenConsole
)
211 NTSTATUS Status
= STATUS_SUCCESS
;
212 PCSRSS_OPEN_CONSOLE OpenConsoleRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.OpenConsoleRequest
;
213 PCONSOLE_PROCESS_DATA ProcessData
= ConsoleGetPerProcessData(CsrGetClientThread()->Process
);
215 DPRINT("SrvOpenConsole\n");
217 OpenConsoleRequest
->Handle
= INVALID_HANDLE_VALUE
;
219 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
221 DPRINT1("SrvOpenConsole - Checkpoint 1\n");
222 DPRINT1("ProcessData = 0x%p ; ProcessData->Console = 0x%p\n", ProcessData
, ProcessData
->Console
);
224 if (ProcessData
->Console
)
226 DWORD DesiredAccess
= OpenConsoleRequest
->Access
;
227 DWORD ShareMode
= OpenConsoleRequest
->ShareMode
;
229 PCSRSS_CONSOLE Console
= ProcessData
->Console
;
232 DPRINT1("SrvOpenConsole - Checkpoint 2\n");
233 EnterCriticalSection(&Console
->Lock
);
234 DPRINT1("SrvOpenConsole - Checkpoint 3\n");
236 if (OpenConsoleRequest
->HandleType
== HANDLE_OUTPUT
)
237 Object
= &Console
->ActiveBuffer
->Header
;
239 Object
= &Console
->Header
;
241 if (((DesiredAccess
& GENERIC_READ
) && Object
->ExclusiveRead
!= 0) ||
242 ((DesiredAccess
& GENERIC_WRITE
) && Object
->ExclusiveWrite
!= 0) ||
243 (!(ShareMode
& FILE_SHARE_READ
) && Object
->AccessRead
!= 0) ||
244 (!(ShareMode
& FILE_SHARE_WRITE
) && Object
->AccessWrite
!= 0))
246 DPRINT1("Sharing violation\n");
247 Status
= STATUS_SHARING_VIOLATION
;
251 Status
= Win32CsrInsertObject(ProcessData
,
252 &OpenConsoleRequest
->Handle
,
255 OpenConsoleRequest
->Inheritable
,
259 LeaveCriticalSection(&Console
->Lock
);
262 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
267 CSR_API(SrvAllocConsole
)
269 NTSTATUS Status
= STATUS_SUCCESS
;
270 PCSRSS_ALLOC_CONSOLE AllocConsoleRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.AllocConsoleRequest
;
271 PCONSOLE_PROCESS_DATA ProcessData
= ConsoleGetPerProcessData(CsrGetClientThread()->Process
);
272 PCSRSS_CONSOLE Console
;
273 BOOLEAN NewConsole
= FALSE
;
275 DPRINT("SrvAllocConsole\n");
277 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
279 if (ProcessData
->Console
)
281 DPRINT1("Process already has a console\n");
282 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
283 return STATUS_INVALID_PARAMETER
;
286 DPRINT1("SrvAllocConsole - Checkpoint 1\n");
288 /* If we don't need a console, then get out of here */
289 if (!AllocConsoleRequest
->ConsoleNeeded
)
291 DPRINT("No console needed\n");
292 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
293 return STATUS_SUCCESS
;
296 /* If we already have one, then don't create a new one... */
297 if (!AllocConsoleRequest
->Console
||
298 AllocConsoleRequest
->Console
!= ProcessData
->ParentConsole
)
300 /* Allocate a console structure */
302 Console
= HeapAlloc(ConSrvHeap
, HEAP_ZERO_MEMORY
, sizeof(CSRSS_CONSOLE
));
305 DPRINT1("Not enough memory for console\n");
306 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
307 return STATUS_NO_MEMORY
;
310 /* Initialize list head */
311 InitializeListHead(&Console
->ProcessList
);
313 /* Insert process data required for GUI initialization */
314 InsertHeadList(&Console
->ProcessList
, &ProcessData
->ConsoleLink
);
316 /* Initialize the Console */
317 Status
= CsrInitConsole(Console
, AllocConsoleRequest
->ShowCmd
);
318 if (!NT_SUCCESS(Status
))
320 DPRINT1("Console init failed\n");
321 HeapFree(ConSrvHeap
, 0, Console
);
322 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
328 /* Reuse our current console */
329 Console
= AllocConsoleRequest
->Console
;
332 /* Set the Process Console */
333 ProcessData
->Console
= Console
;
335 /* Return it to the caller */
336 AllocConsoleRequest
->Console
= Console
;
338 /* Add a reference count because the process is tied to the console */
339 _InterlockedIncrement(&Console
->ReferenceCount
);
341 if (NewConsole
|| !ProcessData
->bInheritHandles
)
343 /* Insert the Objects */
344 Status
= Win32CsrInsertObject(ProcessData
,
345 &AllocConsoleRequest
->InputHandle
,
347 GENERIC_READ
| GENERIC_WRITE
,
349 FILE_SHARE_READ
| FILE_SHARE_WRITE
);
350 if (! NT_SUCCESS(Status
))
352 DPRINT1("Failed to insert object\n");
353 ConioDeleteConsole((Object_t
*) Console
);
354 ProcessData
->Console
= NULL
;
355 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
359 Status
= Win32CsrInsertObject(ProcessData
,
360 &AllocConsoleRequest
->OutputHandle
,
361 &Console
->ActiveBuffer
->Header
,
362 GENERIC_READ
| GENERIC_WRITE
,
364 FILE_SHARE_READ
| FILE_SHARE_WRITE
);
365 if (!NT_SUCCESS(Status
))
367 DPRINT1("Failed to insert object\n");
368 ConioDeleteConsole((Object_t
*) Console
);
369 Win32CsrReleaseObject(ProcessData
,
370 AllocConsoleRequest
->InputHandle
);
371 ProcessData
->Console
= NULL
;
372 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
377 /* Duplicate the Event */
378 Status
= NtDuplicateObject(NtCurrentProcess(),
379 ProcessData
->Console
->ActiveEvent
,
380 ProcessData
->Process
->ProcessHandle
,
381 &ProcessData
->ConsoleEvent
,
382 EVENT_ALL_ACCESS
, 0, 0);
383 if (!NT_SUCCESS(Status
))
385 DPRINT1("NtDuplicateObject() failed: %lu\n", Status
);
386 ConioDeleteConsole((Object_t
*) Console
);
387 if (NewConsole
|| !ProcessData
->bInheritHandles
)
389 Win32CsrReleaseObject(ProcessData
,
390 AllocConsoleRequest
->OutputHandle
);
391 Win32CsrReleaseObject(ProcessData
,
392 AllocConsoleRequest
->InputHandle
);
394 ProcessData
->Console
= NULL
;
395 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
399 /* Set the Ctrl Dispatcher */
400 ProcessData
->CtrlDispatcher
= AllocConsoleRequest
->CtrlDispatcher
;
401 DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData
->CtrlDispatcher
);
405 /* Insert into the list if it has not been added */
406 InsertHeadList(&ProcessData
->Console
->ProcessList
, &ProcessData
->ConsoleLink
);
409 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
410 return STATUS_SUCCESS
;
413 CSR_API(SrvFreeConsole
)
415 Win32CsrReleaseConsole(CsrGetClientThread()->Process
);
416 return STATUS_SUCCESS
;
420 ConioDeleteConsole(Object_t
*Object
)
422 PCSRSS_CONSOLE Console
= (PCSRSS_CONSOLE
) Object
;
425 DPRINT("ConioDeleteConsole\n");
427 /* Drain input event queue */
428 while (Console
->InputEvents
.Flink
!= &Console
->InputEvents
)
430 Event
= (ConsoleInput
*) Console
->InputEvents
.Flink
;
431 Console
->InputEvents
.Flink
= Console
->InputEvents
.Flink
->Flink
;
432 Console
->InputEvents
.Flink
->Flink
->Blink
= &Console
->InputEvents
;
433 HeapFree(ConSrvHeap
, 0, Event
);
436 ConioCleanupConsole(Console
);
437 if (Console
->LineBuffer
)
438 RtlFreeHeap(ConSrvHeap
, 0, Console
->LineBuffer
);
439 while (!IsListEmpty(&Console
->HistoryBuffers
))
440 HistoryDeleteBuffer((struct tagHISTORY_BUFFER
*)Console
->HistoryBuffers
.Flink
);
442 ConioDeleteScreenBuffer(Console
->ActiveBuffer
);
443 if (!IsListEmpty(&Console
->BufferList
))
445 DPRINT1("BUG: screen buffer list not empty\n");
448 CloseHandle(Console
->ActiveEvent
);
449 if (Console
->UnpauseEvent
) CloseHandle(Console
->UnpauseEvent
);
450 DeleteCriticalSection(&Console
->Lock
);
451 RtlFreeUnicodeString(&Console
->Title
);
452 IntDeleteAllAliases(Console
->Aliases
);
453 HeapFree(ConSrvHeap
, 0, Console
);
457 CsrInitConsoleSupport(VOID
)
459 DPRINT("CSR: CsrInitConsoleSupport()\n");
461 /* Should call LoadKeyboardLayout */
465 ConioPause(PCSRSS_CONSOLE Console
, UINT Flags
)
467 Console
->PauseFlags
|= Flags
;
468 if (!Console
->UnpauseEvent
)
469 Console
->UnpauseEvent
= CreateEvent(NULL
, TRUE
, FALSE
, NULL
);
473 ConioUnpause(PCSRSS_CONSOLE Console
, UINT Flags
)
475 Console
->PauseFlags
&= ~Flags
;
476 if (Console
->PauseFlags
== 0 && Console
->UnpauseEvent
)
478 SetEvent(Console
->UnpauseEvent
);
479 CloseHandle(Console
->UnpauseEvent
);
480 Console
->UnpauseEvent
= NULL
;
484 CSR_API(SrvSetConsoleMode
)
487 PCSRSS_CONSOLE_MODE ConsoleModeRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleModeRequest
;
488 PCSRSS_CONSOLE Console
;
489 PCSRSS_SCREEN_BUFFER Buff
;
491 DPRINT("SrvSetConsoleMode\n");
493 Status
= Win32CsrLockObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process
),
494 ConsoleModeRequest
->ConsoleHandle
,
495 (Object_t
**) &Console
, GENERIC_WRITE
, 0);
496 if (!NT_SUCCESS(Status
)) return Status
;
498 Buff
= (PCSRSS_SCREEN_BUFFER
)Console
;
500 if (CONIO_CONSOLE_MAGIC
== Console
->Header
.Type
)
502 Console
->Mode
= ConsoleModeRequest
->ConsoleMode
& CONSOLE_INPUT_MODE_VALID
;
504 else if (CONIO_SCREEN_BUFFER_MAGIC
== Console
->Header
.Type
)
506 Buff
->Mode
= ConsoleModeRequest
->ConsoleMode
& CONSOLE_OUTPUT_MODE_VALID
;
510 Status
= STATUS_INVALID_HANDLE
;
513 Win32CsrUnlockObject((Object_t
*)Console
);
518 CSR_API(SrvGetConsoleMode
)
521 PCSRSS_CONSOLE_MODE ConsoleModeRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleModeRequest
;
522 PCSRSS_CONSOLE Console
;
523 PCSRSS_SCREEN_BUFFER Buff
;
525 DPRINT("SrvGetConsoleMode\n");
527 Status
= Win32CsrLockObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process
),
528 ConsoleModeRequest
->ConsoleHandle
,
529 (Object_t
**) &Console
, GENERIC_READ
, 0);
530 if (!NT_SUCCESS(Status
)) return Status
;
532 Status
= STATUS_SUCCESS
;
533 Buff
= (PCSRSS_SCREEN_BUFFER
) Console
;
535 if (CONIO_CONSOLE_MAGIC
== Console
->Header
.Type
)
537 ConsoleModeRequest
->ConsoleMode
= Console
->Mode
;
539 else if (CONIO_SCREEN_BUFFER_MAGIC
== Buff
->Header
.Type
)
541 ConsoleModeRequest
->ConsoleMode
= Buff
->Mode
;
545 Status
= STATUS_INVALID_HANDLE
;
548 Win32CsrUnlockObject((Object_t
*)Console
);
552 CSR_API(SrvSetConsoleTitle
)
555 PCSRSS_CONSOLE_TITLE TitleRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.TitleRequest
;
556 // PCSR_PROCESS Process = CsrGetClientThread()->Process;
557 PCSRSS_CONSOLE Console
;
560 DPRINT("SrvSetConsoleTitle\n");
562 if (!CsrValidateMessageBuffer(ApiMessage
,
563 (PVOID
)&TitleRequest
->Title
,
564 TitleRequest
->Length
,
567 return STATUS_INVALID_PARAMETER
;
570 if (!Win32CsrValidateBuffer(Process, TitleRequest->Title,
571 TitleRequest->Length, 1))
573 return STATUS_ACCESS_VIOLATION;
577 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
578 if(NT_SUCCESS(Status
))
580 Buffer
= RtlAllocateHeap(RtlGetProcessHeap(), 0, TitleRequest
->Length
);
583 /* Copy title to console */
584 RtlFreeUnicodeString(&Console
->Title
);
585 Console
->Title
.Buffer
= Buffer
;
586 Console
->Title
.Length
= Console
->Title
.MaximumLength
= TitleRequest
->Length
;
587 memcpy(Console
->Title
.Buffer
, TitleRequest
->Title
, Console
->Title
.Length
);
589 if (!ConioChangeTitle(Console
))
591 Status
= STATUS_UNSUCCESSFUL
;
595 Status
= STATUS_SUCCESS
;
600 Status
= STATUS_NO_MEMORY
;
603 ConioUnlockConsole(Console
);
609 CSR_API(SrvGetConsoleTitle
)
612 PCSRSS_CONSOLE_TITLE TitleRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.TitleRequest
;
613 // PCSR_PROCESS Process = CsrGetClientThread()->Process;
614 PCSRSS_CONSOLE Console
;
617 DPRINT("SrvGetConsoleTitle\n");
619 if (!CsrValidateMessageBuffer(ApiMessage
,
620 (PVOID
)&TitleRequest
->Title
,
621 TitleRequest
->Length
,
624 return STATUS_INVALID_PARAMETER
;
627 if (!Win32CsrValidateBuffer(Process, TitleRequest->Title,
628 TitleRequest->Length, 1))
630 return STATUS_ACCESS_VIOLATION;
634 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
635 if (!NT_SUCCESS(Status
))
637 DPRINT1("Can't get console\n");
641 /* Copy title of the console to the user title buffer */
642 if (TitleRequest
->Length
>= sizeof(WCHAR
))
644 Length
= min(TitleRequest
->Length
- sizeof(WCHAR
), Console
->Title
.Length
);
645 memcpy(TitleRequest
->Title
, Console
->Title
.Buffer
, Length
);
646 TitleRequest
->Title
[Length
/ sizeof(WCHAR
)] = L
'\0';
649 TitleRequest
->Length
= Console
->Title
.Length
;
651 ConioUnlockConsole(Console
);
652 return STATUS_SUCCESS
;
655 /**********************************************************************
656 * HardwareStateProperty
659 * Set/Get the value of the HardwareState and switch
660 * between direct video buffer ouput and GDI windowed
663 * Client hands us a CSRSS_CONSOLE_HARDWARE_STATE
664 * object. We use the same object to Request.
666 * ConsoleHwState has the correct size to be compatible
667 * with NT's, but values are not.
669 static NTSTATUS FASTCALL
670 SetConsoleHardwareState(PCSRSS_CONSOLE Console
, DWORD ConsoleHwState
)
672 DPRINT1("Console Hardware State: %d\n", ConsoleHwState
);
674 if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED
== ConsoleHwState
)
675 ||(CONSOLE_HARDWARE_STATE_DIRECT
== ConsoleHwState
))
677 if (Console
->HardwareState
!= ConsoleHwState
)
679 /* TODO: implement switching from full screen to windowed mode */
680 /* TODO: or back; now simply store the hardware state */
681 Console
->HardwareState
= ConsoleHwState
;
684 return STATUS_SUCCESS
;
687 return STATUS_INVALID_PARAMETER_3
; /* Client: (handle, set_get, [mode]) */
690 CSR_API(SrvGetConsoleHardwareState
)
693 PCSRSS_CONSOLE_HW_STATE ConsoleHardwareStateRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleHardwareStateRequest
;
694 PCSRSS_CONSOLE Console
;
696 DPRINT("SrvGetConsoleHardwareState\n");
698 Status
= ConioLockConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process
),
699 ConsoleHardwareStateRequest
->ConsoleHandle
,
702 if (!NT_SUCCESS(Status
))
704 DPRINT1("Failed to get console handle in SrvGetConsoleHardwareState\n");
708 ConsoleHardwareStateRequest
->State
= Console
->HardwareState
;
710 ConioUnlockConsole(Console
);
715 CSR_API(SrvSetConsoleHardwareState
)
718 PCSRSS_CONSOLE_HW_STATE ConsoleHardwareStateRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleHardwareStateRequest
;
719 PCSRSS_CONSOLE Console
;
721 DPRINT("SrvSetConsoleHardwareState\n");
723 Status
= ConioLockConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process
),
724 ConsoleHardwareStateRequest
->ConsoleHandle
,
727 if (!NT_SUCCESS(Status
))
729 DPRINT1("Failed to get console handle in SrvSetConsoleHardwareState\n");
733 DPRINT("Setting console hardware state.\n");
734 Status
= SetConsoleHardwareState(Console
, ConsoleHardwareStateRequest
->State
);
736 ConioUnlockConsole(Console
);
741 CSR_API(SrvGetConsoleWindow
)
744 PCSRSS_GET_CONSOLE_WINDOW GetConsoleWindowRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetConsoleWindowRequest
;
745 PCSRSS_CONSOLE Console
;
747 DPRINT("SrvGetConsoleWindow\n");
749 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
750 if (!NT_SUCCESS(Status
)) return Status
;
752 GetConsoleWindowRequest
->WindowHandle
= Console
->hWindow
;
753 ConioUnlockConsole(Console
);
755 return STATUS_SUCCESS
;
758 CSR_API(SrvSetConsoleIcon
)
761 PCSRSS_SET_CONSOLE_ICON SetConsoleIconRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.SetConsoleIconRequest
;
762 PCSRSS_CONSOLE Console
;
764 DPRINT("SrvSetConsoleIcon\n");
766 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
767 if (!NT_SUCCESS(Status
)) return Status
;
769 Status
= (ConioChangeIcon(Console
, SetConsoleIconRequest
->WindowIcon
)
771 : STATUS_UNSUCCESSFUL
);
773 ConioUnlockConsole(Console
);
778 CSR_API(SrvGetConsoleCP
)
781 PCSRSS_CONSOLE_CP ConsoleCPRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleCPRequest
;
782 PCSRSS_CONSOLE Console
;
784 DPRINT("SrvGetConsoleCP, getting %s Code Page\n",
785 ConsoleCPRequest
->InputCP
? "Input" : "Output");
787 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
788 if (!NT_SUCCESS(Status
)) return Status
;
790 ConsoleCPRequest
->CodePage
= (ConsoleCPRequest
->InputCP
? Console
->CodePage
791 : Console
->OutputCodePage
);
792 ConioUnlockConsole(Console
);
793 return STATUS_SUCCESS
;
796 CSR_API(SrvSetConsoleCP
)
799 PCSRSS_CONSOLE_CP ConsoleCPRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleCPRequest
;
800 PCSRSS_CONSOLE Console
;
802 DPRINT("SrvSetConsoleCP, setting %s Code Page\n",
803 ConsoleCPRequest
->InputCP
? "Input" : "Output");
805 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
806 if (!NT_SUCCESS(Status
)) return Status
;
808 if (IsValidCodePage(ConsoleCPRequest
->CodePage
))
810 if (ConsoleCPRequest
->InputCP
)
811 Console
->CodePage
= ConsoleCPRequest
->CodePage
;
813 Console
->OutputCodePage
= ConsoleCPRequest
->CodePage
;
815 ConioUnlockConsole(Console
);
816 return STATUS_SUCCESS
;
819 ConioUnlockConsole(Console
);
820 return STATUS_INVALID_PARAMETER
;
823 CSR_API(SrvGetConsoleProcessList
)
826 PCSRSS_GET_PROCESS_LIST GetProcessListRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetProcessListRequest
;
828 // PCSR_PROCESS Process = CsrGetClientThread()->Process;
829 PCSRSS_CONSOLE Console
;
830 PCONSOLE_PROCESS_DATA current
;
831 PLIST_ENTRY current_entry
;
834 DPRINT("SrvGetConsoleProcessList\n");
836 if (!CsrValidateMessageBuffer(ApiMessage
,
837 (PVOID
)&GetProcessListRequest
->pProcessIds
,
838 GetProcessListRequest
->nMaxIds
,
841 return STATUS_INVALID_PARAMETER
;
844 Buffer
= GetProcessListRequest
->pProcessIds
;
847 if (!Win32CsrValidateBuffer(ProcessData, Buffer, GetProcessListRequest->nMaxIds, sizeof(DWORD)))
848 return STATUS_ACCESS_VIOLATION;
851 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
852 if (!NT_SUCCESS(Status
)) return Status
;
854 for (current_entry
= Console
->ProcessList
.Flink
;
855 current_entry
!= &Console
->ProcessList
;
856 current_entry
= current_entry
->Flink
)
858 current
= CONTAINING_RECORD(current_entry
, CONSOLE_PROCESS_DATA
, ConsoleLink
);
859 if (++nItems
<= GetProcessListRequest
->nMaxIds
)
861 *Buffer
++ = HandleToUlong(current
->Process
->ClientId
.UniqueProcess
);
865 ConioUnlockConsole(Console
);
867 GetProcessListRequest
->nProcessIdsTotal
= nItems
;
868 return STATUS_SUCCESS
;
871 CSR_API(SrvGenerateConsoleCtrlEvent
)
874 PCSRSS_GENERATE_CTRL_EVENT GenerateCtrlEvent
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GenerateCtrlEvent
;
875 PCSRSS_CONSOLE Console
;
876 PCONSOLE_PROCESS_DATA current
;
877 PLIST_ENTRY current_entry
;
880 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
881 if (!NT_SUCCESS(Status
)) return Status
;
883 Group
= GenerateCtrlEvent
->ProcessGroup
;
884 Status
= STATUS_INVALID_PARAMETER
;
885 for (current_entry
= Console
->ProcessList
.Flink
;
886 current_entry
!= &Console
->ProcessList
;
887 current_entry
= current_entry
->Flink
)
889 current
= CONTAINING_RECORD(current_entry
, CONSOLE_PROCESS_DATA
, ConsoleLink
);
890 if (Group
== 0 || current
->Process
->ProcessGroupId
== Group
)
892 ConioConsoleCtrlEvent(GenerateCtrlEvent
->Event
, current
);
893 Status
= STATUS_SUCCESS
;
897 ConioUnlockConsole(Console
);
902 CSR_API(SrvGetConsoleSelectionInfo
)
905 PCSRSS_GET_CONSOLE_SELECTION_INFO GetConsoleSelectionInfo
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetConsoleSelectionInfo
;
906 PCSRSS_CONSOLE Console
;
908 Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
909 if (NT_SUCCESS(Status
))
911 memset(&GetConsoleSelectionInfo
->Info
, 0, sizeof(CONSOLE_SELECTION_INFO
));
912 if (Console
->Selection
.dwFlags
!= 0)
913 GetConsoleSelectionInfo
->Info
= Console
->Selection
;
914 ConioUnlockConsole(Console
);