2 * reactos/subsys/csrss/win32csr/conio.c
4 * Console I/O functions
6 * ReactOS Operating System
9 /* INCLUDES ******************************************************************/
15 /* FUNCTIONS *****************************************************************/
18 ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData
, PCSRSS_CONSOLE
*Console
)
20 PCSRSS_CONSOLE ProcessConsole
;
22 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
23 ProcessConsole
= ProcessData
->Console
;
28 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
29 return STATUS_INVALID_HANDLE
;
32 InterlockedIncrement(&ProcessConsole
->ReferenceCount
);
33 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
34 EnterCriticalSection(&(ProcessConsole
->Lock
));
35 *Console
= ProcessConsole
;
37 return STATUS_SUCCESS
;
41 ConioConsoleCtrlEventTimeout(DWORD Event
, PCSRSS_PROCESS_DATA ProcessData
, DWORD Timeout
)
45 DPRINT("ConioConsoleCtrlEvent Parent ProcessId = %x\n", ProcessData
->ProcessId
);
47 if (ProcessData
->CtrlDispatcher
)
50 Thread
= CreateRemoteThread(ProcessData
->Process
, NULL
, 0,
51 (LPTHREAD_START_ROUTINE
) ProcessData
->CtrlDispatcher
,
52 UlongToPtr(Event
), 0, NULL
);
55 DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
58 WaitForSingleObject(Thread
, Timeout
);
64 ConioConsoleCtrlEvent(DWORD Event
, PCSRSS_PROCESS_DATA ProcessData
)
66 ConioConsoleCtrlEventTimeout(Event
, ProcessData
, 0);
69 static NTSTATUS WINAPI
70 CsrInitConsole(PCSRSS_CONSOLE Console
, BOOL Visible
)
73 SECURITY_ATTRIBUTES SecurityAttributes
;
74 PCSRSS_SCREEN_BUFFER NewBuffer
;
77 Console
->Title
.MaximumLength
= Console
->Title
.Length
= 0;
78 Console
->Title
.Buffer
= NULL
;
81 RtlCreateUnicodeString(&Console
->Title
, L
"Command Prompt");
83 Console
->ReferenceCount
= 0;
84 Console
->LineBuffer
= NULL
;
85 Console
->Header
.Type
= CONIO_CONSOLE_MAGIC
;
86 Console
->Header
.Console
= Console
;
87 Console
->Mode
= ENABLE_LINE_INPUT
| ENABLE_ECHO_INPUT
| ENABLE_PROCESSED_INPUT
| ENABLE_MOUSE_INPUT
;
88 InitializeListHead(&Console
->BufferList
);
89 Console
->ActiveBuffer
= NULL
;
90 InitializeListHead(&Console
->InputEvents
);
91 InitializeListHead(&Console
->HistoryBuffers
);
92 Console
->CodePage
= GetOEMCP();
93 Console
->OutputCodePage
= GetOEMCP();
95 SecurityAttributes
.nLength
= sizeof(SECURITY_ATTRIBUTES
);
96 SecurityAttributes
.lpSecurityDescriptor
= NULL
;
97 SecurityAttributes
.bInheritHandle
= TRUE
;
99 Console
->ActiveEvent
= CreateEventW(&SecurityAttributes
, TRUE
, FALSE
, NULL
);
100 if (NULL
== Console
->ActiveEvent
)
102 RtlFreeUnicodeString(&Console
->Title
);
103 return STATUS_UNSUCCESSFUL
;
105 Console
->PrivateData
= NULL
;
106 InitializeCriticalSection(&Console
->Lock
);
108 GuiMode
= DtbgIsDesktopVisible();
110 /* allocate console screen buffer */
111 NewBuffer
= HeapAlloc(Win32CsrApiHeap
, HEAP_ZERO_MEMORY
, sizeof(CSRSS_SCREEN_BUFFER
));
112 if (NULL
== NewBuffer
)
114 RtlFreeUnicodeString(&Console
->Title
);
115 DeleteCriticalSection(&Console
->Lock
);
116 CloseHandle(Console
->ActiveEvent
);
117 return STATUS_INSUFFICIENT_RESOURCES
;
119 /* init screen buffer with defaults */
120 NewBuffer
->CursorInfo
.bVisible
= TRUE
;
121 NewBuffer
->CursorInfo
.dwSize
= CSR_DEFAULT_CURSOR_SIZE
;
122 /* make console active, and insert into console list */
123 Console
->ActiveBuffer
= (PCSRSS_SCREEN_BUFFER
) NewBuffer
;
127 Status
= TuiInitConsole(Console
);
128 if (! NT_SUCCESS(Status
))
130 DPRINT1("Failed to open text-mode console, switching to gui-mode\n");
136 Status
= GuiInitConsole(Console
, Visible
);
137 if (! NT_SUCCESS(Status
))
139 HeapFree(Win32CsrApiHeap
,0, NewBuffer
);
140 RtlFreeUnicodeString(&Console
->Title
);
141 DeleteCriticalSection(&Console
->Lock
);
142 CloseHandle(Console
->ActiveEvent
);
143 DPRINT1("GuiInitConsole: failed\n");
148 Status
= CsrInitConsoleScreenBuffer(Console
, NewBuffer
);
149 if (! NT_SUCCESS(Status
))
151 ConioCleanupConsole(Console
);
152 RtlFreeUnicodeString(&Console
->Title
);
153 DeleteCriticalSection(&Console
->Lock
);
154 CloseHandle(Console
->ActiveEvent
);
155 HeapFree(Win32CsrApiHeap
, 0, NewBuffer
);
156 DPRINT1("CsrInitConsoleScreenBuffer: failed\n");
160 /* copy buffer contents to screen */
161 ConioDrawConsole(Console
);
163 return STATUS_SUCCESS
;
166 CSR_API(CsrAllocConsole
)
168 PCSRSS_CONSOLE Console
;
169 NTSTATUS Status
= STATUS_SUCCESS
;
170 BOOLEAN NewConsole
= FALSE
;
172 DPRINT("CsrAllocConsole\n");
174 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
175 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
177 RtlEnterCriticalSection(&ProcessData
->HandleTableLock
);
178 if (ProcessData
->Console
)
180 DPRINT1("Process already has a console\n");
181 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
182 return STATUS_INVALID_PARAMETER
;
185 /* If we don't need a console, then get out of here */
186 if (!Request
->Data
.AllocConsoleRequest
.ConsoleNeeded
)
188 DPRINT("No console needed\n");
189 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
190 return STATUS_SUCCESS
;
193 /* If we already have one, then don't create a new one... */
194 if (!Request
->Data
.AllocConsoleRequest
.Console
||
195 Request
->Data
.AllocConsoleRequest
.Console
!= ProcessData
->ParentConsole
)
197 /* Allocate a console structure */
199 Console
= HeapAlloc(Win32CsrApiHeap
, HEAP_ZERO_MEMORY
, sizeof(CSRSS_CONSOLE
));
202 DPRINT1("Not enough memory for console\n");
203 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
204 return STATUS_NO_MEMORY
;
206 /* initialize list head */
207 InitializeListHead(&Console
->ProcessList
);
208 /* insert process data required for GUI initialization */
209 InsertHeadList(&Console
->ProcessList
, &ProcessData
->ProcessEntry
);
210 /* Initialize the Console */
211 Status
= CsrInitConsole(Console
, Request
->Data
.AllocConsoleRequest
.Visible
);
212 if (!NT_SUCCESS(Status
))
214 DPRINT1("Console init failed\n");
215 HeapFree(Win32CsrApiHeap
, 0, Console
);
216 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
222 /* Reuse our current console */
223 Console
= Request
->Data
.AllocConsoleRequest
.Console
;
226 /* Set the Process Console */
227 ProcessData
->Console
= Console
;
229 /* Return it to the caller */
230 Request
->Data
.AllocConsoleRequest
.Console
= Console
;
232 /* Add a reference count because the process is tied to the console */
233 _InterlockedIncrement(&Console
->ReferenceCount
);
235 if (NewConsole
|| !ProcessData
->bInheritHandles
)
237 /* Insert the Objects */
238 Status
= Win32CsrInsertObject(ProcessData
,
239 &Request
->Data
.AllocConsoleRequest
.InputHandle
,
241 GENERIC_READ
| GENERIC_WRITE
,
243 FILE_SHARE_READ
| FILE_SHARE_WRITE
);
244 if (! NT_SUCCESS(Status
))
246 DPRINT1("Failed to insert object\n");
247 ConioDeleteConsole((Object_t
*) Console
);
248 ProcessData
->Console
= 0;
249 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
253 Status
= Win32CsrInsertObject(ProcessData
,
254 &Request
->Data
.AllocConsoleRequest
.OutputHandle
,
255 &Console
->ActiveBuffer
->Header
,
256 GENERIC_READ
| GENERIC_WRITE
,
258 FILE_SHARE_READ
| FILE_SHARE_WRITE
);
259 if (!NT_SUCCESS(Status
))
261 DPRINT1("Failed to insert object\n");
262 ConioDeleteConsole((Object_t
*) Console
);
263 Win32CsrReleaseObject(ProcessData
,
264 Request
->Data
.AllocConsoleRequest
.InputHandle
);
265 ProcessData
->Console
= 0;
266 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
271 /* Duplicate the Event */
272 if (!DuplicateHandle(GetCurrentProcess(),
273 ProcessData
->Console
->ActiveEvent
,
274 ProcessData
->Process
,
275 &ProcessData
->ConsoleEvent
,
280 DPRINT1("DuplicateHandle() failed: %d\n", GetLastError
);
281 ConioDeleteConsole((Object_t
*) Console
);
282 if (NewConsole
|| !ProcessData
->bInheritHandles
)
284 Win32CsrReleaseObject(ProcessData
,
285 Request
->Data
.AllocConsoleRequest
.OutputHandle
);
286 Win32CsrReleaseObject(ProcessData
,
287 Request
->Data
.AllocConsoleRequest
.InputHandle
);
289 ProcessData
->Console
= 0;
290 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
294 /* Set the Ctrl Dispatcher */
295 ProcessData
->CtrlDispatcher
= Request
->Data
.AllocConsoleRequest
.CtrlDispatcher
;
296 DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData
->CtrlDispatcher
);
300 /* Insert into the list if it has not been added */
301 InsertHeadList(&ProcessData
->Console
->ProcessList
, &ProcessData
->ProcessEntry
);
304 RtlLeaveCriticalSection(&ProcessData
->HandleTableLock
);
305 return STATUS_SUCCESS
;
308 CSR_API(CsrFreeConsole
)
310 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
311 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
313 return Win32CsrReleaseConsole(ProcessData
);
317 ConioDeleteConsole(Object_t
*Object
)
319 PCSRSS_CONSOLE Console
= (PCSRSS_CONSOLE
) Object
;
322 DPRINT("ConioDeleteConsole\n");
324 /* Drain input event queue */
325 while (Console
->InputEvents
.Flink
!= &Console
->InputEvents
)
327 Event
= (ConsoleInput
*) Console
->InputEvents
.Flink
;
328 Console
->InputEvents
.Flink
= Console
->InputEvents
.Flink
->Flink
;
329 Console
->InputEvents
.Flink
->Flink
->Blink
= &Console
->InputEvents
;
330 HeapFree(Win32CsrApiHeap
, 0, Event
);
333 ConioCleanupConsole(Console
);
334 if (Console
->LineBuffer
)
335 RtlFreeHeap(Win32CsrApiHeap
, 0, Console
->LineBuffer
);
336 while (!IsListEmpty(&Console
->HistoryBuffers
))
337 HistoryDeleteBuffer((struct tagHISTORY_BUFFER
*)Console
->HistoryBuffers
.Flink
);
339 ConioDeleteScreenBuffer(Console
->ActiveBuffer
);
340 if (!IsListEmpty(&Console
->BufferList
))
342 DPRINT1("BUG: screen buffer list not empty\n");
345 CloseHandle(Console
->ActiveEvent
);
346 if (Console
->UnpauseEvent
) CloseHandle(Console
->UnpauseEvent
);
347 DeleteCriticalSection(&Console
->Lock
);
348 RtlFreeUnicodeString(&Console
->Title
);
349 IntDeleteAllAliases(Console
->Aliases
);
350 HeapFree(Win32CsrApiHeap
, 0, Console
);
354 CsrInitConsoleSupport(VOID
)
356 DPRINT("CSR: CsrInitConsoleSupport()\n");
358 /* Should call LoadKeyboardLayout */
362 ConioPause(PCSRSS_CONSOLE Console
, UINT Flags
)
364 Console
->PauseFlags
|= Flags
;
365 if (!Console
->UnpauseEvent
)
366 Console
->UnpauseEvent
= CreateEvent(NULL
, TRUE
, FALSE
, NULL
);
370 ConioUnpause(PCSRSS_CONSOLE Console
, UINT Flags
)
372 Console
->PauseFlags
&= ~Flags
;
373 if (Console
->PauseFlags
== 0 && Console
->UnpauseEvent
)
375 SetEvent(Console
->UnpauseEvent
);
376 CloseHandle(Console
->UnpauseEvent
);
377 Console
->UnpauseEvent
= NULL
;
381 CSR_API(CsrSetConsoleMode
)
384 PCSRSS_CONSOLE Console
;
385 PCSRSS_SCREEN_BUFFER Buff
;
387 DPRINT("CsrSetConsoleMode\n");
389 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
390 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
391 Status
= Win32CsrLockObject(ProcessData
,
392 Request
->Data
.SetConsoleModeRequest
.ConsoleHandle
,
393 (Object_t
**) &Console
, GENERIC_WRITE
, 0);
394 if (! NT_SUCCESS(Status
))
399 Buff
= (PCSRSS_SCREEN_BUFFER
)Console
;
400 if (CONIO_CONSOLE_MAGIC
== Console
->Header
.Type
)
402 Console
->Mode
= Request
->Data
.SetConsoleModeRequest
.Mode
& CONSOLE_INPUT_MODE_VALID
;
404 else if (CONIO_SCREEN_BUFFER_MAGIC
== Console
->Header
.Type
)
406 Buff
->Mode
= Request
->Data
.SetConsoleModeRequest
.Mode
& CONSOLE_OUTPUT_MODE_VALID
;
410 Status
= STATUS_INVALID_HANDLE
;
413 Win32CsrUnlockObject((Object_t
*)Console
);
418 CSR_API(CsrGetConsoleMode
)
421 PCSRSS_CONSOLE Console
;
422 PCSRSS_SCREEN_BUFFER Buff
; /* gee, I really wish I could use an anonymous union here */
424 DPRINT("CsrGetConsoleMode\n");
426 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
427 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
428 Status
= Win32CsrLockObject(ProcessData
, Request
->Data
.GetConsoleModeRequest
.ConsoleHandle
,
429 (Object_t
**) &Console
, GENERIC_READ
, 0);
430 if (! NT_SUCCESS(Status
))
434 Status
= STATUS_SUCCESS
;
435 Buff
= (PCSRSS_SCREEN_BUFFER
) Console
;
436 if (CONIO_CONSOLE_MAGIC
== Console
->Header
.Type
)
438 Request
->Data
.GetConsoleModeRequest
.ConsoleMode
= Console
->Mode
;
440 else if (CONIO_SCREEN_BUFFER_MAGIC
== Buff
->Header
.Type
)
442 Request
->Data
.GetConsoleModeRequest
.ConsoleMode
= Buff
->Mode
;
446 Status
= STATUS_INVALID_HANDLE
;
449 Win32CsrUnlockObject((Object_t
*)Console
);
456 PCSRSS_CONSOLE Console
;
459 DPRINT("CsrSetTitle\n");
461 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
462 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
463 if (!Win32CsrValidateBuffer(ProcessData
, Request
->Data
.SetTitleRequest
.Title
,
464 Request
->Data
.SetTitleRequest
.Length
, 1))
466 return STATUS_ACCESS_VIOLATION
;
469 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
470 if(NT_SUCCESS(Status
))
472 Buffer
= RtlAllocateHeap(RtlGetProcessHeap(), 0, Request
->Data
.SetTitleRequest
.Length
);
475 /* copy title to console */
476 RtlFreeUnicodeString(&Console
->Title
);
477 Console
->Title
.Buffer
= Buffer
;
478 Console
->Title
.Length
= Console
->Title
.MaximumLength
= Request
->Data
.SetTitleRequest
.Length
;
479 memcpy(Console
->Title
.Buffer
, Request
->Data
.SetTitleRequest
.Title
, Console
->Title
.Length
);
480 if (! ConioChangeTitle(Console
))
482 Status
= STATUS_UNSUCCESSFUL
;
486 Status
= STATUS_SUCCESS
;
491 Status
= STATUS_NO_MEMORY
;
493 ConioUnlockConsole(Console
);
502 PCSRSS_CONSOLE Console
;
505 DPRINT("CsrGetTitle\n");
507 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
508 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
510 if (!Win32CsrValidateBuffer(ProcessData
, Request
->Data
.GetTitleRequest
.Title
,
511 Request
->Data
.GetTitleRequest
.Length
, 1))
513 return STATUS_ACCESS_VIOLATION
;
516 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
517 if (! NT_SUCCESS(Status
))
519 DPRINT1("Can't get console\n");
523 /* Copy title of the console to the user title buffer */
524 if (Request
->Data
.GetTitleRequest
.Length
>= sizeof(WCHAR
))
526 Length
= min(Request
->Data
.GetTitleRequest
.Length
- sizeof(WCHAR
), Console
->Title
.Length
);
527 memcpy(Request
->Data
.GetTitleRequest
.Title
, Console
->Title
.Buffer
, Length
);
528 Request
->Data
.GetTitleRequest
.Title
[Length
/ sizeof(WCHAR
)] = L
'\0';
531 Request
->Data
.GetTitleRequest
.Length
= Console
->Title
.Length
;
533 ConioUnlockConsole(Console
);
534 return STATUS_SUCCESS
;
537 /**********************************************************************
538 * HardwareStateProperty
541 * Set/Get the value of the HardwareState and switch
542 * between direct video buffer ouput and GDI windowed
545 * Client hands us a CSRSS_CONSOLE_HARDWARE_STATE
546 * object. We use the same object to Request.
548 * ConsoleHwState has the correct size to be compatible
549 * with NT's, but values are not.
551 static NTSTATUS FASTCALL
552 SetConsoleHardwareState (PCSRSS_CONSOLE Console
, DWORD ConsoleHwState
)
554 DPRINT1("Console Hardware State: %d\n", ConsoleHwState
);
556 if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED
== ConsoleHwState
)
557 ||(CONSOLE_HARDWARE_STATE_DIRECT
== ConsoleHwState
))
559 if (Console
->HardwareState
!= ConsoleHwState
)
561 /* TODO: implement switching from full screen to windowed mode */
562 /* TODO: or back; now simply store the hardware state */
563 Console
->HardwareState
= ConsoleHwState
;
566 return STATUS_SUCCESS
;
569 return STATUS_INVALID_PARAMETER_3
; /* Client: (handle, set_get, [mode]) */
572 CSR_API(CsrHardwareStateProperty
)
574 PCSRSS_CONSOLE Console
;
577 DPRINT("CsrHardwareStateProperty\n");
579 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
580 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
582 Status
= ConioLockConsole(ProcessData
,
583 Request
->Data
.ConsoleHardwareStateRequest
.ConsoleHandle
,
586 if (! NT_SUCCESS(Status
))
588 DPRINT1("Failed to get console handle in SetConsoleHardwareState\n");
592 switch (Request
->Data
.ConsoleHardwareStateRequest
.SetGet
)
594 case CONSOLE_HARDWARE_STATE_GET
:
595 Request
->Data
.ConsoleHardwareStateRequest
.State
= Console
->HardwareState
;
598 case CONSOLE_HARDWARE_STATE_SET
:
599 DPRINT("Setting console hardware state.\n");
600 Status
= SetConsoleHardwareState(Console
, Request
->Data
.ConsoleHardwareStateRequest
.State
);
604 Status
= STATUS_INVALID_PARAMETER_2
; /* Client: (handle, [set_get], mode) */
608 ConioUnlockConsole(Console
);
613 CSR_API(CsrGetConsoleWindow
)
615 PCSRSS_CONSOLE Console
;
618 DPRINT("CsrGetConsoleWindow\n");
620 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
621 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
623 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
624 if (! NT_SUCCESS(Status
))
629 Request
->Data
.GetConsoleWindowRequest
.WindowHandle
= Console
->hWindow
;
630 ConioUnlockConsole(Console
);
632 return STATUS_SUCCESS
;
635 CSR_API(CsrSetConsoleIcon
)
637 PCSRSS_CONSOLE Console
;
640 DPRINT("CsrSetConsoleIcon\n");
642 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
643 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
645 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
646 if (! NT_SUCCESS(Status
))
651 Status
= (ConioChangeIcon(Console
, Request
->Data
.SetConsoleIconRequest
.WindowIcon
)
652 ? STATUS_SUCCESS
: STATUS_UNSUCCESSFUL
);
653 ConioUnlockConsole(Console
);
658 CSR_API(CsrGetConsoleCodePage
)
660 PCSRSS_CONSOLE Console
;
663 DPRINT("CsrGetConsoleCodePage\n");
665 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
666 if (! NT_SUCCESS(Status
))
671 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
672 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
673 Request
->Data
.GetConsoleCodePage
.CodePage
= Console
->CodePage
;
674 ConioUnlockConsole(Console
);
675 return STATUS_SUCCESS
;
678 CSR_API(CsrSetConsoleCodePage
)
680 PCSRSS_CONSOLE Console
;
683 DPRINT("CsrSetConsoleCodePage\n");
685 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
686 if (! NT_SUCCESS(Status
))
691 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
692 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
694 if (IsValidCodePage(Request
->Data
.SetConsoleCodePage
.CodePage
))
696 Console
->CodePage
= Request
->Data
.SetConsoleCodePage
.CodePage
;
697 ConioUnlockConsole(Console
);
698 return STATUS_SUCCESS
;
701 ConioUnlockConsole(Console
);
702 return STATUS_INVALID_PARAMETER
;
705 CSR_API(CsrGetConsoleOutputCodePage
)
707 PCSRSS_CONSOLE Console
;
710 DPRINT("CsrGetConsoleOutputCodePage\n");
712 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
713 if (! NT_SUCCESS(Status
))
718 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
719 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
720 Request
->Data
.GetConsoleOutputCodePage
.CodePage
= Console
->OutputCodePage
;
721 ConioUnlockConsole(Console
);
722 return STATUS_SUCCESS
;
725 CSR_API(CsrSetConsoleOutputCodePage
)
727 PCSRSS_CONSOLE Console
;
730 DPRINT("CsrSetConsoleOutputCodePage\n");
732 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
733 if (! NT_SUCCESS(Status
))
738 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
739 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
741 if (IsValidCodePage(Request
->Data
.SetConsoleOutputCodePage
.CodePage
))
743 Console
->OutputCodePage
= Request
->Data
.SetConsoleOutputCodePage
.CodePage
;
744 ConioUnlockConsole(Console
);
745 return STATUS_SUCCESS
;
748 ConioUnlockConsole(Console
);
749 return STATUS_INVALID_PARAMETER
;
752 CSR_API(CsrGetProcessList
)
755 PCSRSS_CONSOLE Console
;
756 PCSRSS_PROCESS_DATA current
;
757 PLIST_ENTRY current_entry
;
761 DPRINT("CsrGetProcessList\n");
763 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
764 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
766 Buffer
= Request
->Data
.GetProcessListRequest
.ProcessId
;
767 if (!Win32CsrValidateBuffer(ProcessData
, Buffer
, Request
->Data
.GetProcessListRequest
.nMaxIds
, sizeof(DWORD
)))
768 return STATUS_ACCESS_VIOLATION
;
770 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
771 if (! NT_SUCCESS(Status
))
776 for (current_entry
= Console
->ProcessList
.Flink
;
777 current_entry
!= &Console
->ProcessList
;
778 current_entry
= current_entry
->Flink
)
780 current
= CONTAINING_RECORD(current_entry
, CSRSS_PROCESS_DATA
, ProcessEntry
);
781 if (++nItems
<= Request
->Data
.GetProcessListRequest
.nMaxIds
)
783 *Buffer
++ = HandleToUlong(current
->ProcessId
);
787 ConioUnlockConsole(Console
);
789 Request
->Data
.GetProcessListRequest
.nProcessIdsTotal
= nItems
;
790 return STATUS_SUCCESS
;
793 CSR_API(CsrGenerateCtrlEvent
)
795 PCSRSS_CONSOLE Console
;
796 PCSRSS_PROCESS_DATA current
;
797 PLIST_ENTRY current_entry
;
801 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
802 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
804 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
805 if (! NT_SUCCESS(Status
))
810 Group
= Request
->Data
.GenerateCtrlEvent
.ProcessGroup
;
811 Status
= STATUS_INVALID_PARAMETER
;
812 for (current_entry
= Console
->ProcessList
.Flink
;
813 current_entry
!= &Console
->ProcessList
;
814 current_entry
= current_entry
->Flink
)
816 current
= CONTAINING_RECORD(current_entry
, CSRSS_PROCESS_DATA
, ProcessEntry
);
817 if (Group
== 0 || current
->ProcessGroup
== Group
)
819 ConioConsoleCtrlEvent(Request
->Data
.GenerateCtrlEvent
.Event
, current
);
820 Status
= STATUS_SUCCESS
;
824 ConioUnlockConsole(Console
);
829 CSR_API(CsrGetConsoleSelectionInfo
)
832 PCSRSS_CONSOLE Console
;
834 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
835 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
837 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
838 if (NT_SUCCESS(Status
))
840 memset(&Request
->Data
.GetConsoleSelectionInfo
.Info
, 0, sizeof(CONSOLE_SELECTION_INFO
));
841 if (Console
->Selection
.dwFlags
!= 0)
842 Request
->Data
.GetConsoleSelectionInfo
.Info
= Console
->Selection
;
843 ConioUnlockConsole(Console
);