2 * reactos/subsys/csrss/win32csr/conio.c
4 * Console I/O functions
6 * ReactOS Operating System
9 /* INCLUDES ******************************************************************/
16 /* FIXME: Is there a way to create real aliasses with gcc? [CSH] */
17 #define ALIAS(Name, Target) typeof(Target) Name = Target
19 /* Private user32 routines for CSRSS, not defined in any header file */
20 extern VOID STDCALL
PrivateCsrssRegisterPrimitive(VOID
);
21 extern VOID STDCALL
PrivateCsrssAcquireOrReleaseInputOwnership(BOOL Release
);
23 /* GLOBALS *******************************************************************/
25 #define ConioInitRect(Rect, Top, Left, Bottom, Right) \
26 ((Rect)->top) = Top; \
27 ((Rect)->left) = Left; \
28 ((Rect)->bottom) = Bottom; \
29 ((Rect)->right) = Right
31 #define ConioIsRectEmpty(Rect) \
32 (((Rect)->left > (Rect)->right) || ((Rect)->top > (Rect)->bottom))
34 #define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \
35 WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
37 #define ConsoleAnsiCharToUnicodeChar(Console, sWChar, dChar) \
38 MultiByteToWideChar((Console)->CodePage, 0, (dChar), 1, (sWChar), 1)
41 /* FUNCTIONS *****************************************************************/
43 STATIC NTSTATUS FASTCALL
44 ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData
, PCSRSS_CONSOLE
*Console
)
46 if (NULL
== ProcessData
->Console
)
49 return STATUS_SUCCESS
;
52 EnterCriticalSection(&(ProcessData
->Console
->Header
.Lock
));
53 *Console
= ProcessData
->Console
;
55 return STATUS_SUCCESS
;
59 ConioConsoleCtrlEvent(DWORD Event
, PCSRSS_PROCESS_DATA ProcessData
)
63 DPRINT("ConioConsoleCtrlEvent Parent ProcessId = %x\n", ProcessData
->ProcessId
);
65 if (ProcessData
->CtrlDispatcher
)
68 Thread
= CreateRemoteThread(ProcessData
->Process
, NULL
, 0,
69 (LPTHREAD_START_ROUTINE
) ProcessData
->CtrlDispatcher
,
70 (PVOID
) Event
, 0, NULL
);
73 DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
80 #define GET_CELL_BUFFER(b,o)\
83 #define SET_CELL_BUFFER(b,o,c,a)\
84 (b)->Buffer[(o)++]=(c),\
85 (b)->Buffer[(o)++]=(a)
88 ClearLineBuffer(PCSRSS_SCREEN_BUFFER Buff
)
90 DWORD Offset
= 2 * (Buff
->CurrentY
* Buff
->MaxX
);
93 for (Pos
= 0; Pos
< Buff
->MaxX
; Pos
++)
95 /* Fill the cell: Offset is incremented by the macro */
96 SET_CELL_BUFFER(Buff
, Offset
, ' ', Buff
->DefaultAttrib
);
100 STATIC NTSTATUS FASTCALL
101 CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console
,
102 PCSRSS_SCREEN_BUFFER Buffer
)
104 Buffer
->Header
.Type
= CONIO_SCREEN_BUFFER_MAGIC
;
105 Buffer
->Header
.ReferenceCount
= 0;
106 Buffer
->MaxX
= Console
->Size
.X
;
107 Buffer
->MaxY
= Console
->Size
.Y
;
110 Buffer
->Buffer
= HeapAlloc(Win32CsrApiHeap
, 0, Buffer
->MaxX
* Buffer
->MaxY
* 2);
111 if (NULL
== Buffer
->Buffer
)
113 return STATUS_INSUFFICIENT_RESOURCES
;
115 InitializeCriticalSection(&Buffer
->Header
.Lock
);
116 ConioInitScreenBuffer(Console
, Buffer
);
117 /* initialize buffer to be empty with default attributes */
118 for (Buffer
->CurrentY
= 0 ; Buffer
->CurrentY
< Buffer
->MaxY
; Buffer
->CurrentY
++)
120 ClearLineBuffer(Buffer
);
122 Buffer
->CursorInfo
.bVisible
= TRUE
;
123 Buffer
->CursorInfo
.dwSize
= 5;
124 Buffer
->Mode
= ENABLE_PROCESSED_OUTPUT
| ENABLE_WRAP_AT_EOL_OUTPUT
;
125 Buffer
->CurrentX
= 0;
126 Buffer
->CurrentY
= 0;
128 return STATUS_SUCCESS
;
131 STATIC NTSTATUS STDCALL
132 CsrInitConsole(PCSRSS_CONSOLE Console
)
135 SECURITY_ATTRIBUTES SecurityAttributes
;
136 PCSRSS_SCREEN_BUFFER NewBuffer
;
139 Console
->Title
.MaximumLength
= Console
->Title
.Length
= 0;
140 Console
->Title
.Buffer
= NULL
;
142 RtlCreateUnicodeString(&Console
->Title
, L
"Command Prompt");
144 Console
->Header
.ReferenceCount
= 0;
145 Console
->WaitingChars
= 0;
146 Console
->WaitingLines
= 0;
147 Console
->EchoCount
= 0;
148 Console
->Header
.Type
= CONIO_CONSOLE_MAGIC
;
149 Console
->Mode
= ENABLE_LINE_INPUT
| ENABLE_ECHO_INPUT
| ENABLE_PROCESSED_INPUT
| ENABLE_MOUSE_INPUT
;
150 Console
->EarlyReturn
= FALSE
;
151 Console
->ActiveBuffer
= NULL
;
152 InitializeListHead(&Console
->InputEvents
);
153 InitializeListHead(&Console
->ProcessList
);
155 Console
->CodePage
= GetOEMCP();
156 Console
->OutputCodePage
= GetOEMCP();
158 SecurityAttributes
.nLength
= sizeof(SECURITY_ATTRIBUTES
);
159 SecurityAttributes
.lpSecurityDescriptor
= NULL
;
160 SecurityAttributes
.bInheritHandle
= TRUE
;
162 Console
->ActiveEvent
= CreateEventW(&SecurityAttributes
, TRUE
, FALSE
, NULL
);
163 if (NULL
== Console
->ActiveEvent
)
165 RtlFreeUnicodeString(&Console
->Title
);
166 return STATUS_UNSUCCESSFUL
;
168 Console
->PrivateData
= NULL
;
169 InitializeCriticalSection(&Console
->Header
.Lock
);
170 GuiMode
= DtbgIsDesktopVisible();
173 Status
= TuiInitConsole(Console
);
174 if (! NT_SUCCESS(Status
))
176 DPRINT1("Failed to open text-mode console, switching to gui-mode\n");
182 Status
= GuiInitConsole(Console
);
183 if (! NT_SUCCESS(Status
))
185 RtlFreeUnicodeString(&Console
->Title
);
186 DeleteCriticalSection(&Console
->Header
.Lock
);
187 CloseHandle(Console
->ActiveEvent
);
192 NewBuffer
= HeapAlloc(Win32CsrApiHeap
, 0, sizeof(CSRSS_SCREEN_BUFFER
));
193 if (NULL
== NewBuffer
)
195 ConioCleanupConsole(Console
);
196 RtlFreeUnicodeString(&Console
->Title
);
197 DeleteCriticalSection(&Console
->Header
.Lock
);
198 CloseHandle(Console
->ActiveEvent
);
199 return STATUS_INSUFFICIENT_RESOURCES
;
201 Status
= CsrInitConsoleScreenBuffer(Console
, NewBuffer
);
202 if (! NT_SUCCESS(Status
))
204 ConioCleanupConsole(Console
);
205 RtlFreeUnicodeString(&Console
->Title
);
206 DeleteCriticalSection(&Console
->Header
.Lock
);
207 CloseHandle(Console
->ActiveEvent
);
208 HeapFree(Win32CsrApiHeap
, 0, NewBuffer
);
211 Console
->ActiveBuffer
= NewBuffer
;
212 /* add a reference count because the buffer is tied to the console */
213 InterlockedIncrement(&Console
->ActiveBuffer
->Header
.ReferenceCount
);
214 /* make console active, and insert into console list */
215 /* copy buffer contents to screen */
216 ConioDrawConsole(Console
);
218 return STATUS_SUCCESS
;
222 CSR_API(CsrAllocConsole
)
224 PCSRSS_CONSOLE Console
;
225 NTSTATUS Status
= STATUS_SUCCESS
;
226 BOOLEAN NewConsole
= FALSE
;
228 DPRINT("CsrAllocConsole\n");
230 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
231 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
233 if (ProcessData
== NULL
)
235 DPRINT1("No process data\n");
236 return Request
->Status
= STATUS_INVALID_PARAMETER
;
239 if (ProcessData
->Console
)
241 DPRINT1("Process already has a console\n");
242 Request
->Status
= STATUS_INVALID_PARAMETER
;
243 return STATUS_INVALID_PARAMETER
;
247 Request
->Status
= STATUS_SUCCESS
;
249 /* If we don't need a console, then get out of here */
250 if (!Request
->Data
.AllocConsoleRequest
.ConsoleNeeded
)
252 DPRINT("No console needed\n");
253 return STATUS_SUCCESS
;
256 /* If we already have one, then don't create a new one... */
257 if (!Request
->Data
.AllocConsoleRequest
.Console
||
258 Request
->Data
.AllocConsoleRequest
.Console
!= ProcessData
->ParentConsole
)
260 /* Allocate a console structure */
262 Console
= HeapAlloc(Win32CsrApiHeap
, 0, sizeof(CSRSS_CONSOLE
));
265 DPRINT1("Not enough memory for console\n");
266 Request
->Status
= STATUS_NO_MEMORY
;
267 return STATUS_NO_MEMORY
;
270 /* Initialize the Console */
271 Request
->Status
= CsrInitConsole(Console
);
272 if (!NT_SUCCESS(Request
->Status
))
274 DPRINT1("Console init failed\n");
275 HeapFree(Win32CsrApiHeap
, 0, Console
);
276 return Request
->Status
;
281 /* Reuse our current console */
282 Console
= Request
->Data
.AllocConsoleRequest
.Console
;
285 /* Set the Process Console */
286 ProcessData
->Console
= Console
;
288 /* Return it to the caller */
289 Request
->Data
.AllocConsoleRequest
.Console
= Console
;
291 /* Add a reference count because the process is tied to the console */
292 Console
->Header
.ReferenceCount
++;
294 if (NewConsole
|| !ProcessData
->bInheritHandles
)
296 /* Insert the Objects */
297 Status
= Win32CsrInsertObject(ProcessData
,
298 &Request
->Data
.AllocConsoleRequest
.InputHandle
,
300 if (! NT_SUCCESS(Status
))
302 DPRINT1("Failed to insert object\n");
303 ConioDeleteConsole((Object_t
*) Console
);
304 ProcessData
->Console
= 0;
305 return Request
->Status
= Status
;
308 Status
= Win32CsrInsertObject(ProcessData
,
309 &Request
->Data
.AllocConsoleRequest
.OutputHandle
,
310 &Console
->ActiveBuffer
->Header
);
311 if (!NT_SUCCESS(Status
))
313 DPRINT1("Failed to insert object\n");
314 ConioDeleteConsole((Object_t
*) Console
);
315 Win32CsrReleaseObject(ProcessData
,
316 Request
->Data
.AllocConsoleRequest
.InputHandle
);
317 ProcessData
->Console
= 0;
318 return Request
->Status
= Status
;
322 /* Duplicate the Event */
323 if (!DuplicateHandle(GetCurrentProcess(),
324 ProcessData
->Console
->ActiveEvent
,
325 ProcessData
->Process
,
326 &ProcessData
->ConsoleEvent
,
331 DPRINT1("DuplicateHandle() failed: %d\n", GetLastError
);
332 ConioDeleteConsole((Object_t
*) Console
);
333 if (NewConsole
|| !ProcessData
->bInheritHandles
)
335 Win32CsrReleaseObject(ProcessData
,
336 Request
->Data
.AllocConsoleRequest
.OutputHandle
);
337 Win32CsrReleaseObject(ProcessData
,
338 Request
->Data
.AllocConsoleRequest
.InputHandle
);
340 ProcessData
->Console
= 0;
341 return Request
->Status
= Status
;
344 /* Set the Ctrl Dispatcher */
345 ProcessData
->CtrlDispatcher
= Request
->Data
.AllocConsoleRequest
.CtrlDispatcher
;
346 DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData
->CtrlDispatcher
);
348 /* Insert into the list */
349 InsertHeadList(&ProcessData
->Console
->ProcessList
, &ProcessData
->ProcessEntry
);
350 return STATUS_SUCCESS
;
353 CSR_API(CsrFreeConsole
)
355 PCSRSS_CONSOLE Console
;
357 DPRINT("CsrFreeConsole\n");
359 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
360 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
362 if (ProcessData
== NULL
|| ProcessData
->Console
== NULL
)
364 return Request
->Status
= STATUS_INVALID_PARAMETER
;
367 Console
= ProcessData
->Console
;
368 ProcessData
->Console
= NULL
;
369 if (0 == InterlockedDecrement(&Console
->Header
.ReferenceCount
))
371 ConioDeleteConsole((Object_t
*) Console
);
374 return STATUS_SUCCESS
;
378 ConioNextLine(PCSRSS_SCREEN_BUFFER Buff
, RECT
*UpdateRect
, UINT
*ScrolledLines
)
380 /* slide the viewable screen */
381 if (((Buff
->CurrentY
- Buff
->ShowY
+ Buff
->MaxY
) % Buff
->MaxY
) == (ULONG
)Buff
->MaxY
- 1)
383 if (++Buff
->ShowY
== Buff
->MaxY
)
389 if (++Buff
->CurrentY
== Buff
->MaxY
)
393 ClearLineBuffer(Buff
);
394 UpdateRect
->left
= 0;
395 UpdateRect
->right
= Buff
->MaxX
- 1;
396 if (UpdateRect
->top
== (LONG
)Buff
->CurrentY
)
398 if (++UpdateRect
->top
== Buff
->MaxY
)
403 UpdateRect
->bottom
= Buff
->CurrentY
;
406 STATIC NTSTATUS FASTCALL
407 ConioWriteConsole(PCSRSS_CONSOLE Console
, PCSRSS_SCREEN_BUFFER Buff
,
408 CHAR
*Buffer
, DWORD Length
, BOOL Attrib
)
413 LONG CursorStartX
, CursorStartY
;
416 ConioPhysicalToLogical(Buff
, Buff
->CurrentX
, Buff
->CurrentY
, &CursorStartX
, &CursorStartY
);
417 UpdateRect
.left
= Buff
->MaxX
;
418 UpdateRect
.top
= Buff
->CurrentY
;
419 UpdateRect
.right
= -1;
420 UpdateRect
.bottom
= Buff
->CurrentY
;
423 for (i
= 0; i
< Length
; i
++)
425 if (Buff
->Mode
& ENABLE_PROCESSED_OUTPUT
)
428 if (Buffer
[i
] == '\n')
431 ConioNextLine(Buff
, &UpdateRect
, &ScrolledLines
);
435 else if (Buffer
[i
] == '\b')
437 /* Only handle BS if we're not on the first pos of the first line */
438 if (0 != Buff
->CurrentX
|| Buff
->ShowY
!= Buff
->CurrentY
)
440 if (0 == Buff
->CurrentX
)
442 /* slide virtual position up */
443 Buff
->CurrentX
= Buff
->MaxX
- 1;
444 if (0 == Buff
->CurrentY
)
446 Buff
->CurrentY
= Buff
->MaxY
;
452 if ((0 == UpdateRect
.top
&& UpdateRect
.bottom
< (LONG
)Buff
->CurrentY
)
453 || (0 != UpdateRect
.top
&& (LONG
)Buff
->CurrentY
< UpdateRect
.top
))
455 UpdateRect
.top
= Buff
->CurrentY
;
462 Offset
= 2 * ((Buff
->CurrentY
* Buff
->MaxX
) + Buff
->CurrentX
);
463 SET_CELL_BUFFER(Buff
, Offset
, ' ', Buff
->DefaultAttrib
);
464 UpdateRect
.left
= min(UpdateRect
.left
, (LONG
) Buff
->CurrentX
);
465 UpdateRect
.right
= max(UpdateRect
.right
, (LONG
) Buff
->CurrentX
);
470 else if (Buffer
[i
] == '\r')
473 UpdateRect
.left
= min(UpdateRect
.left
, (LONG
) Buff
->CurrentX
);
474 UpdateRect
.right
= max(UpdateRect
.right
, (LONG
) Buff
->CurrentX
);
478 else if (Buffer
[i
] == '\t')
482 UpdateRect
.left
= min(UpdateRect
.left
, (LONG
)Buff
->CurrentX
);
483 EndX
= (Buff
->CurrentX
+ 8) & ~7;
484 if (EndX
> Buff
->MaxX
)
488 Offset
= 2 * (((Buff
->CurrentY
* Buff
->MaxX
)) + Buff
->CurrentX
);
489 while (Buff
->CurrentX
< EndX
)
491 Buff
->Buffer
[Offset
] = ' ';
495 UpdateRect
.right
= max(UpdateRect
.right
, (LONG
) Buff
->CurrentX
- 1);
496 if (Buff
->CurrentX
== Buff
->MaxX
)
498 if (Buff
->Mode
& ENABLE_WRAP_AT_EOL_OUTPUT
)
501 ConioNextLine(Buff
, &UpdateRect
, &ScrolledLines
);
511 UpdateRect
.left
= min(UpdateRect
.left
, (LONG
)Buff
->CurrentX
);
512 UpdateRect
.right
= max(UpdateRect
.right
, (LONG
) Buff
->CurrentX
);
513 Offset
= 2 * (((Buff
->CurrentY
* Buff
->MaxX
)) + Buff
->CurrentX
);
514 Buff
->Buffer
[Offset
++] = Buffer
[i
];
517 Buff
->Buffer
[Offset
] = Buff
->DefaultAttrib
;
520 if (Buff
->CurrentX
== Buff
->MaxX
)
522 if (Buff
->Mode
& ENABLE_WRAP_AT_EOL_OUTPUT
)
525 ConioNextLine(Buff
, &UpdateRect
, &ScrolledLines
);
529 Buff
->CurrentX
= CursorStartX
;
534 ConioPhysicalToLogical(Buff
, UpdateRect
.left
, UpdateRect
.top
, &(UpdateRect
.left
),
536 ConioPhysicalToLogical(Buff
, UpdateRect
.right
, UpdateRect
.bottom
, &(UpdateRect
.right
),
537 &(UpdateRect
.bottom
));
538 if (! ConioIsRectEmpty(&UpdateRect
) && NULL
!= Console
&& Buff
== Console
->ActiveBuffer
)
540 ConioWriteStream(Console
, &UpdateRect
, CursorStartX
, CursorStartY
, ScrolledLines
,
544 return STATUS_SUCCESS
;
547 CSR_API(CsrReadConsole
)
549 PLIST_ENTRY CurrentEntry
;
552 PWCHAR UnicodeBuffer
;
554 ULONG nNumberOfCharsToRead
, CharSize
;
555 PCSRSS_CONSOLE Console
;
558 DPRINT("CsrReadConsole\n");
560 CharSize
= (Request
->Data
.ReadConsoleRequest
.Unicode
? sizeof(WCHAR
) : sizeof(CHAR
));
562 /* truncate length to CSRSS_MAX_READ_CONSOLE_REQUEST */
563 nNumberOfCharsToRead
= min(Request
->Data
.ReadConsoleRequest
.NrCharactersToRead
, CSRSS_MAX_READ_CONSOLE
/ CharSize
);
564 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
565 Request
->Header
.u1
.s1
.DataLength
= Request
->Header
.u1
.s1
.TotalLength
- sizeof(PORT_MESSAGE
);
567 Buffer
= Request
->Data
.ReadConsoleRequest
.Buffer
;
568 UnicodeBuffer
= (PWCHAR
)Buffer
;
569 Status
= ConioLockConsole(ProcessData
, Request
->Data
.ReadConsoleRequest
.ConsoleHandle
,
571 if (! NT_SUCCESS(Status
))
573 return Request
->Status
= Status
;
575 Request
->Data
.ReadConsoleRequest
.EventHandle
= ProcessData
->ConsoleEvent
;
576 for (i
= 0; i
< nNumberOfCharsToRead
&& Console
->InputEvents
.Flink
!= &Console
->InputEvents
; i
++)
578 /* remove input event from queue */
579 CurrentEntry
= RemoveHeadList(&Console
->InputEvents
);
580 if (IsListEmpty(&Console
->InputEvents
))
583 ResetEvent(Console
->ActiveEvent
);
585 Input
= CONTAINING_RECORD(CurrentEntry
, ConsoleInput
, ListEntry
);
587 /* only pay attention to valid ascii chars, on key down */
588 if (KEY_EVENT
== Input
->InputEvent
.EventType
589 && Input
->InputEvent
.Event
.KeyEvent
.bKeyDown
590 && Input
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
!= '\0')
592 /* backspace handling */
593 if ('\b' == Input
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
)
595 /* echo if it has not already been done, and either we or the client has chars to be deleted */
597 && (0 != i
|| Request
->Data
.ReadConsoleRequest
.nCharsCanBeDeleted
))
599 ConioWriteConsole(Console
, Console
->ActiveBuffer
,
600 &Input
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
, 1, TRUE
);
604 i
-= 2; /* if we already have something to return, just back it up by 2 */
607 { /* otherwise, return STATUS_NOTIFY_CLEANUP to tell client to back up its buffer */
608 Console
->WaitingChars
--;
609 ConioUnlockConsole(Console
);
610 HeapFree(Win32CsrApiHeap
, 0, Input
);
611 Request
->Data
.ReadConsoleRequest
.NrCharactersRead
= 0;
612 Request
->Status
= STATUS_NOTIFY_CLEANUP
;
613 return STATUS_NOTIFY_CLEANUP
;
615 Request
->Data
.ReadConsoleRequest
.nCharsCanBeDeleted
--;
616 Input
->Echoed
= TRUE
; /* mark as echoed so we don't echo it below */
618 /* do not copy backspace to buffer */
621 if(Request
->Data
.ReadConsoleRequest
.Unicode
)
622 UnicodeBuffer
[i
] = Input
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
; /* FIXME */
624 Buffer
[i
] = Input
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
;
626 /* echo to screen if enabled and we did not already echo the char */
627 if (0 != (Console
->Mode
& ENABLE_ECHO_INPUT
)
629 && '\r' != Input
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
)
631 ConioWriteConsole(Console
, Console
->ActiveBuffer
,
632 &Input
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
, 1, TRUE
);
639 Console
->WaitingChars
--;
640 HeapFree(Win32CsrApiHeap
, 0, Input
);
642 Request
->Data
.ReadConsoleRequest
.NrCharactersRead
= i
;
645 Request
->Status
= STATUS_PENDING
; /* we didn't read anything */
647 else if (0 != (Console
->Mode
& ENABLE_LINE_INPUT
))
649 if (0 == Console
->WaitingLines
||
650 (Request
->Data
.ReadConsoleRequest
.Unicode
? (L
'\n' != UnicodeBuffer
[i
- 1]) : ('\n' != Buffer
[i
- 1])))
652 Request
->Status
= STATUS_PENDING
; /* line buffered, didn't get a complete line */
656 Console
->WaitingLines
--;
657 Request
->Status
= STATUS_SUCCESS
; /* line buffered, did get a complete line */
662 Request
->Status
= STATUS_SUCCESS
; /* not line buffered, did read something */
665 if (Request
->Status
== STATUS_PENDING
)
667 Console
->EchoCount
= nNumberOfCharsToRead
- i
;
671 Console
->EchoCount
= 0; /* if the client is no longer waiting on input, do not echo */
673 Request
->Header
.u1
.s1
.TotalLength
+= i
* CharSize
;
675 ConioUnlockConsole(Console
);
676 return Request
->Status
;
680 ConioPhysicalToLogical(PCSRSS_SCREEN_BUFFER Buff
,
686 *LogicalX
= PhysicalX
;
687 if (PhysicalY
< Buff
->ShowY
)
689 *LogicalY
= Buff
->MaxY
- Buff
->ShowY
+ PhysicalY
;
693 *LogicalY
= PhysicalY
- Buff
->ShowY
;
697 inline BOOLEAN
ConioIsEqualRect(
701 return ((Rect1
->left
== Rect2
->left
) && (Rect1
->right
== Rect2
->right
) &&
702 (Rect1
->top
== Rect2
->top
) && (Rect1
->bottom
== Rect2
->bottom
));
705 inline BOOLEAN
ConioGetIntersection(
710 if (ConioIsRectEmpty(Rect1
) ||
711 (ConioIsRectEmpty(Rect2
)) ||
712 (Rect1
->top
> Rect2
->bottom
) ||
713 (Rect1
->left
> Rect2
->right
) ||
714 (Rect1
->bottom
< Rect2
->top
) ||
715 (Rect1
->right
< Rect2
->left
))
717 /* The rectangles do not intersect */
718 ConioInitRect(Intersection
, 0, -1, 0, -1);
722 ConioInitRect(Intersection
,
723 max(Rect1
->top
, Rect2
->top
),
724 max(Rect1
->left
, Rect2
->left
),
725 min(Rect1
->bottom
, Rect2
->bottom
),
726 min(Rect1
->right
, Rect2
->right
));
731 inline BOOLEAN
ConioGetUnion(
736 if (ConioIsRectEmpty(Rect1
))
738 if (ConioIsRectEmpty(Rect2
))
740 ConioInitRect(Union
, 0, -1, 0, -1);
748 else if (ConioIsRectEmpty(Rect2
))
755 min(Rect1
->top
, Rect2
->top
),
756 min(Rect1
->left
, Rect2
->left
),
757 max(Rect1
->bottom
, Rect2
->bottom
),
758 max(Rect1
->right
, Rect2
->right
));
764 inline BOOLEAN
ConioSubtractRect(
771 if (ConioIsRectEmpty(Rect1
))
773 ConioInitRect(Subtraction
, 0, -1, 0, -1);
776 *Subtraction
= *Rect1
;
777 if (ConioGetIntersection(&tmp
, Rect1
, Rect2
))
779 if (ConioIsEqualRect(&tmp
, Subtraction
))
781 ConioInitRect(Subtraction
, 0, -1, 0, -1);
784 if ((tmp
.top
== Subtraction
->top
) && (tmp
.bottom
== Subtraction
->bottom
))
786 if (tmp
.left
== Subtraction
->left
)
788 Subtraction
->left
= tmp
.right
;
790 else if (tmp
.right
== Subtraction
->right
)
792 Subtraction
->right
= tmp
.left
;
795 else if ((tmp
.left
== Subtraction
->left
) && (tmp
.right
== Subtraction
->right
))
797 if (tmp
.top
== Subtraction
->top
)
799 Subtraction
->top
= tmp
.bottom
;
801 else if (tmp
.bottom
== Subtraction
->bottom
)
803 Subtraction
->bottom
= tmp
.top
;
812 ConioCopyRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer
,
822 DstY
= DstRegion
->top
;
823 BytesPerLine
= ConioRectWidth(DstRegion
) * 2;
825 SrcY
= (SrcRegion
->top
+ ScreenBuffer
->ShowY
) % ScreenBuffer
->MaxY
;
826 DstY
= (DstRegion
->top
+ ScreenBuffer
->ShowY
) % ScreenBuffer
->MaxY
;
827 SrcOffset
= (SrcY
* ScreenBuffer
->MaxX
+ SrcRegion
->left
+ ScreenBuffer
->ShowX
) * 2;
828 DstOffset
= (DstY
* ScreenBuffer
->MaxX
+ DstRegion
->left
+ ScreenBuffer
->ShowX
) * 2;
830 for (i
= SrcRegion
->top
; i
<= SrcRegion
->bottom
; i
++)
833 &ScreenBuffer
->Buffer
[DstOffset
],
834 &ScreenBuffer
->Buffer
[SrcOffset
],
837 if (++DstY
== ScreenBuffer
->MaxY
)
840 DstOffset
= (DstRegion
->left
+ ScreenBuffer
->ShowX
) * 2;
844 DstOffset
+= ScreenBuffer
->MaxX
* 2;
847 if (++SrcY
== ScreenBuffer
->MaxY
)
850 SrcOffset
= (SrcRegion
->left
+ ScreenBuffer
->ShowX
) * 2;
854 SrcOffset
+= ScreenBuffer
->MaxX
* 2;
860 ConioFillRegion(PCSRSS_CONSOLE Console
,
861 PCSRSS_SCREEN_BUFFER ScreenBuffer
,
873 ConsoleUnicodeCharToAnsiChar(Console
, &Char
, &CharInfo
->Char
.UnicodeChar
);
875 Char
= CharInfo
->Char
.AsciiChar
;
877 Y
= (Region
->top
+ ScreenBuffer
->ShowY
) % ScreenBuffer
->MaxY
;
878 Offset
= (Y
* ScreenBuffer
->MaxX
+ Region
->left
+ ScreenBuffer
->ShowX
) * 2;
879 Delta
= (ScreenBuffer
->MaxX
- ConioRectWidth(Region
)) * 2;
881 for (i
= Region
->top
; i
<= Region
->bottom
; i
++)
883 for (X
= Region
->left
; X
<= Region
->right
; X
++)
885 SET_CELL_BUFFER(ScreenBuffer
, Offset
, Char
, CharInfo
->Attributes
);
887 if (++Y
== ScreenBuffer
->MaxY
)
890 Offset
= (Region
->left
+ ScreenBuffer
->ShowX
) * 2;
900 ConioInputEventToAnsi(PCSRSS_CONSOLE Console
, PINPUT_RECORD InputEvent
)
902 if (InputEvent
->EventType
== KEY_EVENT
)
904 WCHAR UnicodeChar
= InputEvent
->Event
.KeyEvent
.uChar
.UnicodeChar
;
905 InputEvent
->Event
.KeyEvent
.uChar
.UnicodeChar
= 0;
906 ConsoleUnicodeCharToAnsiChar(Console
,
907 &InputEvent
->Event
.KeyEvent
.uChar
.AsciiChar
,
912 CSR_API(CsrWriteConsole
)
916 PCSRSS_SCREEN_BUFFER Buff
;
917 PCSRSS_CONSOLE Console
;
920 ULONG CharSize
= (Request
->Data
.WriteConsoleRequest
.Unicode
? sizeof(WCHAR
) : sizeof(CHAR
));
922 DPRINT("CsrWriteConsole\n");
924 if (Request
->Header
.u1
.s1
.DataLength
925 < sizeof(CSRSS_WRITE_CONSOLE
) - 1
926 + (Request
->Data
.WriteConsoleRequest
.NrCharactersToWrite
* CharSize
))
928 DPRINT1("Invalid request size\n");
929 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
930 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
931 return Request
->Status
= STATUS_INVALID_PARAMETER
;
933 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
935 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
936 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
938 if (! NT_SUCCESS(Status
))
940 return Request
->Status
= Status
;
943 if(Request
->Data
.WriteConsoleRequest
.Unicode
)
945 Length
= WideCharToMultiByte(Console
->CodePage
, 0,
946 (PWCHAR
)Request
->Data
.WriteConsoleRequest
.Buffer
,
947 Request
->Data
.WriteConsoleRequest
.NrCharactersToWrite
,
948 NULL
, 0, NULL
, NULL
);
949 Buffer
= RtlAllocateHeap(GetProcessHeap(), 0, Length
);
952 WideCharToMultiByte(Console
->CodePage
, 0,
953 (PWCHAR
)Request
->Data
.WriteConsoleRequest
.Buffer
,
954 Request
->Data
.WriteConsoleRequest
.NrCharactersToWrite
,
955 Buffer
, Length
, NULL
, NULL
);
959 Status
= STATUS_NO_MEMORY
;
964 Buffer
= (PCHAR
)Request
->Data
.WriteConsoleRequest
.Buffer
;
969 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.WriteConsoleRequest
.ConsoleHandle
, &Buff
);
970 if (NT_SUCCESS(Status
))
972 Request
->Status
= ConioWriteConsole(Console
, Buff
, Buffer
,
973 Request
->Data
.WriteConsoleRequest
.NrCharactersToWrite
, TRUE
);
974 if (NT_SUCCESS(Status
))
976 Written
= Request
->Data
.WriteConsoleRequest
.NrCharactersToWrite
;
978 ConioUnlockScreenBuffer(Buff
);
980 if (Request
->Data
.WriteConsoleRequest
.Unicode
)
982 RtlFreeHeap(GetProcessHeap(), 0, Buffer
);
987 ConioUnlockConsole(Console
);
990 Request
->Data
.WriteConsoleRequest
.NrCharactersWritten
= Written
;
992 return Request
->Status
= Status
;
996 ConioDeleteScreenBuffer(Object_t
*Object
)
998 PCSRSS_SCREEN_BUFFER Buffer
= (PCSRSS_SCREEN_BUFFER
) Object
;
999 DeleteCriticalSection(&Buffer
->Header
.Lock
);
1000 HeapFree(Win32CsrApiHeap
, 0, Buffer
->Buffer
);
1001 HeapFree(Win32CsrApiHeap
, 0, Buffer
);
1005 ConioDrawConsole(PCSRSS_CONSOLE Console
)
1009 ConioInitRect(&Region
, 0, 0, Console
->Size
.Y
- 1, Console
->Size
.X
- 1);
1011 ConioDrawRegion(Console
, &Region
);
1016 ConioDeleteConsole(Object_t
*Object
)
1018 PCSRSS_CONSOLE Console
= (PCSRSS_CONSOLE
) Object
;
1019 ConsoleInput
*Event
;
1021 DPRINT("ConioDeleteConsole\n");
1023 /* Drain input event queue */
1024 while (Console
->InputEvents
.Flink
!= &Console
->InputEvents
)
1026 Event
= (ConsoleInput
*) Console
->InputEvents
.Flink
;
1027 Console
->InputEvents
.Flink
= Console
->InputEvents
.Flink
->Flink
;
1028 Console
->InputEvents
.Flink
->Flink
->Blink
= &Console
->InputEvents
;
1029 HeapFree(Win32CsrApiHeap
, 0, Event
);
1032 if (0 == InterlockedDecrement(&Console
->ActiveBuffer
->Header
.ReferenceCount
))
1034 ConioDeleteScreenBuffer((Object_t
*) Console
->ActiveBuffer
);
1037 Console
->ActiveBuffer
= NULL
;
1038 ConioCleanupConsole(Console
);
1040 CloseHandle(Console
->ActiveEvent
);
1041 DeleteCriticalSection(&Console
->Header
.Lock
);
1042 RtlFreeUnicodeString(&Console
->Title
);
1043 HeapFree(Win32CsrApiHeap
, 0, Console
);
1047 CsrInitConsoleSupport(VOID
)
1049 DPRINT("CSR: CsrInitConsoleSupport()\n");
1051 /* Should call LoadKeyboardLayout */
1054 STATIC VOID FASTCALL
1055 ConioProcessChar(PCSRSS_CONSOLE Console
,
1056 ConsoleInput
*KeyEventRecord
)
1059 BOOL bClientWake
= FALSE
;
1060 ConsoleInput
*TempInput
;
1062 /* process Ctrl-C and Ctrl-Break */
1063 if (Console
->Mode
& ENABLE_PROCESSED_INPUT
&&
1064 KeyEventRecord
->InputEvent
.Event
.KeyEvent
.bKeyDown
&&
1065 ((KeyEventRecord
->InputEvent
.Event
.KeyEvent
.wVirtualKeyCode
== VK_PAUSE
) ||
1066 (KeyEventRecord
->InputEvent
.Event
.KeyEvent
.wVirtualKeyCode
== 'C')) &&
1067 (KeyEventRecord
->InputEvent
.Event
.KeyEvent
.dwControlKeyState
& (LEFT_CTRL_PRESSED
| RIGHT_CTRL_PRESSED
)))
1069 PCSRSS_PROCESS_DATA current
;
1070 PLIST_ENTRY current_entry
;
1071 DPRINT1("Console_Api Ctrl-C\n");
1072 current_entry
= Console
->ProcessList
.Flink
;
1073 while (current_entry
!= &Console
->ProcessList
)
1075 current
= CONTAINING_RECORD(current_entry
, CSRSS_PROCESS_DATA
, ProcessEntry
);
1076 current_entry
= current_entry
->Flink
;
1077 ConioConsoleCtrlEvent((DWORD
)CTRL_C_EVENT
, current
);
1079 HeapFree(Win32CsrApiHeap
, 0, KeyEventRecord
);
1083 if (0 != (KeyEventRecord
->InputEvent
.Event
.KeyEvent
.dwControlKeyState
1084 & (RIGHT_ALT_PRESSED
| LEFT_ALT_PRESSED
))
1085 && (VK_UP
== KeyEventRecord
->InputEvent
.Event
.KeyEvent
.wVirtualKeyCode
1086 || VK_DOWN
== KeyEventRecord
->InputEvent
.Event
.KeyEvent
.wVirtualKeyCode
))
1088 if (KeyEventRecord
->InputEvent
.Event
.KeyEvent
.bKeyDown
)
1090 /* scroll up or down */
1091 if (NULL
== Console
)
1093 DPRINT1("No Active Console!\n");
1094 HeapFree(Win32CsrApiHeap
, 0, KeyEventRecord
);
1097 if (VK_UP
== KeyEventRecord
->InputEvent
.Event
.KeyEvent
.wVirtualKeyCode
)
1099 /* only scroll up if there is room to scroll up into */
1100 if (Console
->ActiveBuffer
->ShowY
!= ((Console
->ActiveBuffer
->CurrentY
+ 1) %
1101 Console
->ActiveBuffer
->MaxY
))
1103 Console
->ActiveBuffer
->ShowY
= (Console
->ActiveBuffer
->ShowY
+
1104 Console
->ActiveBuffer
->MaxY
- 1) %
1105 Console
->ActiveBuffer
->MaxY
;
1108 else if (Console
->ActiveBuffer
->ShowY
!= Console
->ActiveBuffer
->CurrentY
)
1109 /* only scroll down if there is room to scroll down into */
1111 if (Console
->ActiveBuffer
->ShowY
% Console
->ActiveBuffer
->MaxY
!=
1112 Console
->ActiveBuffer
->CurrentY
)
1114 if (((Console
->ActiveBuffer
->CurrentY
+ 1) % Console
->ActiveBuffer
->MaxY
) !=
1115 (Console
->ActiveBuffer
->ShowY
+ Console
->ActiveBuffer
->MaxY
) %
1116 Console
->ActiveBuffer
->MaxY
)
1118 Console
->ActiveBuffer
->ShowY
= (Console
->ActiveBuffer
->ShowY
+ 1) %
1119 Console
->ActiveBuffer
->MaxY
;
1123 ConioDrawConsole(Console
);
1125 HeapFree(Win32CsrApiHeap
, 0, KeyEventRecord
);
1128 if (NULL
== Console
)
1130 DPRINT1("No Active Console!\n");
1131 HeapFree(Win32CsrApiHeap
, 0, KeyEventRecord
);
1135 if (0 != (Console
->Mode
& (ENABLE_PROCESSED_INPUT
| ENABLE_LINE_INPUT
)))
1137 switch(KeyEventRecord
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
)
1140 /* first add the \r */
1141 KeyEventRecord
->InputEvent
.EventType
= KEY_EVENT
;
1142 updown
= KeyEventRecord
->InputEvent
.Event
.KeyEvent
.bKeyDown
;
1143 KeyEventRecord
->Echoed
= FALSE
;
1144 KeyEventRecord
->InputEvent
.Event
.KeyEvent
.wVirtualKeyCode
= VK_RETURN
;
1145 KeyEventRecord
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
= '\r';
1146 InsertTailList(&Console
->InputEvents
, &KeyEventRecord
->ListEntry
);
1147 Console
->WaitingChars
++;
1148 KeyEventRecord
= HeapAlloc(Win32CsrApiHeap
, 0, sizeof(ConsoleInput
));
1149 if (NULL
== KeyEventRecord
)
1151 DPRINT1("Failed to allocate KeyEventRecord\n");
1154 KeyEventRecord
->InputEvent
.EventType
= KEY_EVENT
;
1155 KeyEventRecord
->InputEvent
.Event
.KeyEvent
.bKeyDown
= updown
;
1156 KeyEventRecord
->InputEvent
.Event
.KeyEvent
.wVirtualKeyCode
= 0;
1157 KeyEventRecord
->InputEvent
.Event
.KeyEvent
.wVirtualScanCode
= 0;
1158 KeyEventRecord
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
= '\n';
1159 KeyEventRecord
->Fake
= TRUE
;
1163 /* add event to the queue */
1164 InsertTailList(&Console
->InputEvents
, &KeyEventRecord
->ListEntry
);
1165 Console
->WaitingChars
++;
1166 /* if line input mode is enabled, only wake the client on enter key down */
1167 if (0 == (Console
->Mode
& ENABLE_LINE_INPUT
)
1168 || Console
->EarlyReturn
1169 || ('\n' == KeyEventRecord
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
1170 && KeyEventRecord
->InputEvent
.Event
.KeyEvent
.bKeyDown
))
1172 if ('\n' == KeyEventRecord
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
)
1174 Console
->WaitingLines
++;
1177 SetEvent(Console
->ActiveEvent
);
1179 KeyEventRecord
->Echoed
= FALSE
;
1180 if (0 != (Console
->Mode
& (ENABLE_PROCESSED_INPUT
| ENABLE_LINE_INPUT
))
1181 && '\b' == KeyEventRecord
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
1182 && KeyEventRecord
->InputEvent
.Event
.KeyEvent
.bKeyDown
)
1184 /* walk the input queue looking for a char to backspace */
1185 for (TempInput
= (ConsoleInput
*) Console
->InputEvents
.Blink
;
1186 TempInput
!= (ConsoleInput
*) &Console
->InputEvents
1187 && (KEY_EVENT
== TempInput
->InputEvent
.EventType
1188 || ! TempInput
->InputEvent
.Event
.KeyEvent
.bKeyDown
1189 || '\b' == TempInput
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
);
1190 TempInput
= (ConsoleInput
*) TempInput
->ListEntry
.Blink
)
1194 /* if we found one, delete it, otherwise, wake the client */
1195 if (TempInput
!= (ConsoleInput
*) &Console
->InputEvents
)
1197 /* delete previous key in queue, maybe echo backspace to screen, and do not place backspace on queue */
1198 RemoveEntryList(&TempInput
->ListEntry
);
1199 if (TempInput
->Echoed
)
1201 ConioWriteConsole(Console
, Console
->ActiveBuffer
,
1202 &KeyEventRecord
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
,
1205 HeapFree(Win32CsrApiHeap
, 0, TempInput
);
1206 RemoveEntryList(&KeyEventRecord
->ListEntry
);
1207 HeapFree(Win32CsrApiHeap
, 0, KeyEventRecord
);
1208 Console
->WaitingChars
-= 2;
1212 SetEvent(Console
->ActiveEvent
);
1217 /* echo chars if we are supposed to and client is waiting for some */
1218 if (0 != (Console
->Mode
& ENABLE_ECHO_INPUT
) && Console
->EchoCount
1219 && KeyEventRecord
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
1220 && KeyEventRecord
->InputEvent
.Event
.KeyEvent
.bKeyDown
1221 && '\r' != KeyEventRecord
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
)
1223 /* mark the char as already echoed */
1224 ConioWriteConsole(Console
, Console
->ActiveBuffer
,
1225 &KeyEventRecord
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
,
1227 Console
->EchoCount
--;
1228 KeyEventRecord
->Echoed
= TRUE
;
1232 /* Console->WaitingChars++; */
1233 if (bClientWake
|| 0 == (Console
->Mode
& ENABLE_LINE_INPUT
))
1235 SetEvent(Console
->ActiveEvent
);
1239 STATIC DWORD FASTCALL
1240 ConioGetShiftState(PBYTE KeyState
)
1244 if (KeyState
[VK_CAPITAL
] & 1)
1245 ssOut
|= CAPSLOCK_ON
;
1247 if (KeyState
[VK_NUMLOCK
] & 1)
1248 ssOut
|= NUMLOCK_ON
;
1250 if (KeyState
[VK_SCROLL
] & 1)
1251 ssOut
|= SCROLLLOCK_ON
;
1253 if (KeyState
[VK_SHIFT
] & 0x80)
1254 ssOut
|= SHIFT_PRESSED
;
1256 if (KeyState
[VK_LCONTROL
] & 0x80)
1257 ssOut
|= LEFT_CTRL_PRESSED
;
1258 if (KeyState
[VK_RCONTROL
] & 0x80)
1259 ssOut
|= RIGHT_CTRL_PRESSED
;
1261 if (KeyState
[VK_LMENU
] & 0x80)
1262 ssOut
|= LEFT_ALT_PRESSED
;
1263 if (KeyState
[VK_RMENU
] & 0x80)
1264 ssOut
|= RIGHT_ALT_PRESSED
;
1270 ConioProcessKey(MSG
*msg
, PCSRSS_CONSOLE Console
, BOOL TextMode
)
1272 static BYTE KeyState
[256] = { 0 };
1273 /* MSDN mentions that you should use the last virtual key code received
1274 * when putting a virtual key identity to a WM_CHAR message since multiple
1275 * or translated keys may be involved. */
1276 static UINT LastVirtualKey
= 0;
1278 ConsoleInput
*ConInRec
;
1282 UINT VirtualKeyCode
;
1283 UINT VirtualScanCode
;
1286 ULONG ResultSize
= 0;
1289 VirtualScanCode
= (msg
->lParam
>> 16) & 0xff;
1290 Down
= msg
->message
== WM_KEYDOWN
|| msg
->message
== WM_CHAR
||
1291 msg
->message
== WM_SYSKEYDOWN
|| msg
->message
== WM_SYSCHAR
;
1293 GetKeyboardState(KeyState
);
1294 ShiftState
= ConioGetShiftState(KeyState
);
1296 if (msg
->message
== WM_CHAR
|| msg
->message
== WM_SYSCHAR
)
1298 VirtualKeyCode
= LastVirtualKey
;
1299 UnicodeChar
= msg
->wParam
;
1306 VirtualKeyCode
= msg
->wParam
;
1307 RetChars
= ToUnicodeEx(VirtualKeyCode
,
1314 UnicodeChar
= (1 == RetChars
? Chars
[0] : 0);
1317 if (0 == ResultSize
)
1322 er
.EventType
= KEY_EVENT
;
1323 er
.Event
.KeyEvent
.bKeyDown
= Down
;
1324 er
.Event
.KeyEvent
.wRepeatCount
= RepeatCount
;
1325 er
.Event
.KeyEvent
.uChar
.UnicodeChar
= UnicodeChar
;
1326 er
.Event
.KeyEvent
.dwControlKeyState
= ShiftState
;
1327 er
.Event
.KeyEvent
.wVirtualKeyCode
= VirtualKeyCode
;
1328 er
.Event
.KeyEvent
.wVirtualScanCode
= VirtualScanCode
;
1332 if (0 != (ShiftState
& (RIGHT_ALT_PRESSED
| LEFT_ALT_PRESSED
))
1333 && VK_TAB
== VirtualKeyCode
)
1337 TuiSwapConsole(ShiftState
& SHIFT_PRESSED
? -1 : 1);
1342 else if (VK_MENU
== VirtualKeyCode
&& ! Down
)
1344 if (TuiSwapConsole(0))
1351 if (NULL
== Console
)
1356 ConInRec
= HeapAlloc(Win32CsrApiHeap
, 0, sizeof(ConsoleInput
));
1358 if (NULL
== ConInRec
)
1363 ConInRec
->InputEvent
= er
;
1364 ConInRec
->Fake
= UnicodeChar
&&
1365 (msg
->message
!= WM_CHAR
&& msg
->message
!= WM_SYSCHAR
&&
1366 msg
->message
!= WM_KEYUP
&& msg
->message
!= WM_SYSKEYUP
);
1367 ConInRec
->NotChar
= (msg
->message
!= WM_CHAR
&& msg
->message
!= WM_SYSCHAR
);
1368 ConInRec
->Echoed
= FALSE
;
1369 if (ConInRec
->NotChar
)
1370 LastVirtualKey
= msg
->wParam
;
1372 DPRINT ("csrss: %s %s %s %s %02x %02x '%c' %04x\n",
1373 Down
? "down" : "up ",
1374 (msg
->message
== WM_CHAR
|| msg
->message
== WM_SYSCHAR
) ?
1376 ConInRec
->Fake
? "fake" : "real",
1377 ConInRec
->NotChar
? "notc" : "char",
1380 (AsciiChar
>= ' ') ? AsciiChar
: '.',
1383 if (! ConInRec
->Fake
|| ! ConInRec
->NotChar
)
1385 /* FIXME - convert to ascii */
1386 ConioProcessChar(Console
, ConInRec
);
1390 HeapFree(Win32CsrApiHeap
, 0, ConInRec
);
1395 Console_Api (PVOID unused
)
1397 /* keep reading events from the keyboard and stuffing them into the current
1398 console's input queue */
1401 /* This call establishes our message queue */
1402 PeekMessageW(&msg
, 0, 0, 0, PM_NOREMOVE
);
1403 /* This call registers our message queue */
1404 PrivateCsrssRegisterPrimitive();
1405 /* This call turns on the input system in win32k */
1406 PrivateCsrssAcquireOrReleaseInputOwnership(FALSE
);
1410 GetMessageW(&msg
, 0, 0, 0);
1411 TranslateMessage(&msg
);
1413 if (msg
.message
== WM_CHAR
|| msg
.message
== WM_SYSCHAR
||
1414 msg
.message
== WM_KEYDOWN
|| msg
.message
== WM_KEYUP
||
1415 msg
.message
== WM_SYSKEYDOWN
|| msg
.message
== WM_SYSKEYUP
)
1417 ConioProcessKey(&msg
, TuiGetFocusConsole(), TRUE
);
1421 PrivateCsrssAcquireOrReleaseInputOwnership(TRUE
);
1425 CSR_API(CsrGetScreenBufferInfo
)
1428 PCSRSS_SCREEN_BUFFER Buff
;
1429 PCONSOLE_SCREEN_BUFFER_INFO pInfo
;
1431 DPRINT("CsrGetScreenBufferInfo\n");
1433 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
1434 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
1436 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.ScreenBufferInfoRequest
.ConsoleHandle
, &Buff
);
1437 if (! NT_SUCCESS(Status
))
1439 return Request
->Status
= Status
;
1441 pInfo
= &Request
->Data
.ScreenBufferInfoRequest
.Info
;
1442 pInfo
->dwSize
.X
= Buff
->MaxX
;
1443 pInfo
->dwSize
.Y
= Buff
->MaxY
;
1444 pInfo
->dwCursorPosition
.X
= Buff
->CurrentX
- Buff
->ShowX
;
1445 pInfo
->dwCursorPosition
.Y
= (Buff
->CurrentY
+ Buff
->MaxY
- Buff
->ShowY
) % Buff
->MaxY
;
1446 pInfo
->wAttributes
= Buff
->DefaultAttrib
;
1447 pInfo
->srWindow
.Left
= 0;
1448 pInfo
->srWindow
.Right
= Buff
->MaxX
- 1;
1449 pInfo
->srWindow
.Top
= 0;
1450 pInfo
->srWindow
.Bottom
= Buff
->MaxY
- 1;
1451 pInfo
->dwMaximumWindowSize
.X
= Buff
->MaxX
;
1452 pInfo
->dwMaximumWindowSize
.Y
= Buff
->MaxY
;
1453 ConioUnlockScreenBuffer(Buff
);
1455 Request
->Status
= STATUS_SUCCESS
;
1457 return Request
->Status
;
1460 CSR_API(CsrSetCursor
)
1463 PCSRSS_CONSOLE Console
;
1464 PCSRSS_SCREEN_BUFFER Buff
;
1465 LONG OldCursorX
, OldCursorY
;
1466 LONG NewCursorX
, NewCursorY
;
1468 DPRINT("CsrSetCursor\n");
1470 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
1471 if (! NT_SUCCESS(Status
))
1473 return Request
->Status
= Status
;
1476 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
1477 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
1479 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.SetCursorRequest
.ConsoleHandle
, &Buff
);
1480 if (! NT_SUCCESS(Status
))
1482 if (NULL
!= Console
)
1484 ConioUnlockConsole(Console
);
1486 return Request
->Status
= Status
;
1489 NewCursorX
= Request
->Data
.SetCursorRequest
.Position
.X
;
1490 NewCursorY
= Request
->Data
.SetCursorRequest
.Position
.Y
;
1491 if (NewCursorX
< 0 || NewCursorX
>= Buff
->MaxX
||
1492 NewCursorY
< 0 || NewCursorY
>= Buff
->MaxY
)
1494 ConioUnlockScreenBuffer(Buff
);
1495 return Request
->Status
= STATUS_INVALID_PARAMETER
;
1497 ConioPhysicalToLogical(Buff
, Buff
->CurrentX
, Buff
->CurrentY
, &OldCursorX
, &OldCursorY
);
1498 Buff
->CurrentX
= NewCursorX
+ Buff
->ShowX
;
1499 Buff
->CurrentY
= (NewCursorY
+ Buff
->ShowY
) % Buff
->MaxY
;
1500 if (NULL
!= Console
&& Buff
== Console
->ActiveBuffer
)
1502 if (! ConioSetScreenInfo(Console
, Buff
, OldCursorX
, OldCursorY
))
1504 ConioUnlockScreenBuffer(Buff
);
1505 return Request
->Status
= STATUS_UNSUCCESSFUL
;
1509 ConioUnlockScreenBuffer(Buff
);
1510 if (NULL
!= Console
)
1512 ConioUnlockConsole(Console
);
1515 return Request
->Status
= STATUS_SUCCESS
;
1518 STATIC FASTCALL VOID
1519 ConioComputeUpdateRect(PCSRSS_SCREEN_BUFFER Buff
, RECT
*UpdateRect
, COORD
*Start
, UINT Length
)
1521 if (Buff
->MaxX
<= Start
->X
+ Length
)
1523 UpdateRect
->left
= 0;
1527 UpdateRect
->left
= Start
->X
;
1529 if (Buff
->MaxX
<= Start
->X
+ Length
)
1531 UpdateRect
->right
= Buff
->MaxX
- 1;
1535 UpdateRect
->right
= Start
->X
+ Length
- 1;
1537 UpdateRect
->top
= Start
->Y
;
1538 UpdateRect
->bottom
= Start
->Y
+ (Start
->X
+ Length
- 1) / Buff
->MaxX
;
1539 if (Buff
->MaxY
<= UpdateRect
->bottom
)
1541 UpdateRect
->bottom
= Buff
->MaxY
- 1;
1545 CSR_API(CsrWriteConsoleOutputChar
)
1548 PCHAR String
, tmpString
= NULL
;
1550 PCSRSS_CONSOLE Console
;
1551 PCSRSS_SCREEN_BUFFER Buff
;
1552 DWORD X
, Y
, Length
, CharSize
, Written
= 0;
1555 DPRINT("CsrWriteConsoleOutputChar\n");
1557 CharSize
= (Request
->Data
.WriteConsoleOutputCharRequest
.Unicode
? sizeof(WCHAR
) : sizeof(CHAR
));
1559 if (Request
->Header
.u1
.s1
.DataLength
1560 < sizeof(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR
) - 1
1561 + (Request
->Data
.WriteConsoleOutputCharRequest
.Length
* CharSize
))
1563 DPRINT1("Invalid request size\n");
1564 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
1565 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
1566 return Request
->Status
= STATUS_INVALID_PARAMETER
;
1569 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
1570 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
1571 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
1572 if (NT_SUCCESS(Status
))
1574 if(Request
->Data
.WriteConsoleOutputCharRequest
.Unicode
)
1576 Length
= WideCharToMultiByte(Console
->CodePage
, 0,
1577 (PWCHAR
)Request
->Data
.WriteConsoleOutputCharRequest
.String
,
1578 Request
->Data
.WriteConsoleOutputCharRequest
.Length
,
1579 NULL
, 0, NULL
, NULL
);
1580 tmpString
= String
= RtlAllocateHeap(GetProcessHeap(), 0, Length
);
1583 WideCharToMultiByte(Console
->CodePage
, 0,
1584 (PWCHAR
)Request
->Data
.WriteConsoleOutputCharRequest
.String
,
1585 Request
->Data
.WriteConsoleOutputCharRequest
.Length
,
1586 String
, Length
, NULL
, NULL
);
1590 Status
= STATUS_NO_MEMORY
;
1595 String
= (PCHAR
)Request
->Data
.WriteConsoleOutputCharRequest
.String
;
1600 Status
= ConioLockScreenBuffer(ProcessData
,
1601 Request
->Data
.WriteConsoleOutputCharRequest
.ConsoleHandle
,
1603 if (NT_SUCCESS(Status
))
1605 X
= Request
->Data
.WriteConsoleOutputCharRequest
.Coord
.X
+ Buff
->ShowX
;
1606 Y
= (Request
->Data
.WriteConsoleOutputCharRequest
.Coord
.Y
+ Buff
->ShowY
) % Buff
->MaxY
;
1607 Length
= Request
->Data
.WriteConsoleOutputCharRequest
.Length
;
1608 Buffer
= &Buff
->Buffer
[2 * (Y
* Buff
->MaxX
+ X
)];
1611 *Buffer
= *String
++;
1614 if (++X
== Buff
->MaxX
)
1616 if (++Y
== Buff
->MaxY
)
1619 Buffer
= Buff
->Buffer
;
1624 if (NULL
!= Console
&& Buff
== Console
->ActiveBuffer
)
1626 ConioComputeUpdateRect(Buff
, &UpdateRect
, &Request
->Data
.WriteConsoleOutputCharRequest
.Coord
,
1627 Request
->Data
.WriteConsoleOutputCharRequest
.Length
);
1628 ConioDrawRegion(Console
, &UpdateRect
);
1631 Request
->Data
.WriteConsoleOutputCharRequest
.EndCoord
.X
= X
- Buff
->ShowX
;
1632 Request
->Data
.WriteConsoleOutputCharRequest
.EndCoord
.Y
= (Y
+ Buff
->MaxY
- Buff
->ShowY
) % Buff
->MaxY
;
1634 ConioUnlockScreenBuffer(Buff
);
1636 if (Request
->Data
.WriteConsoleRequest
.Unicode
)
1638 RtlFreeHeap(GetProcessHeap(), 0, tmpString
);
1641 if (NULL
!= Console
)
1643 ConioUnlockConsole(Console
);
1646 Request
->Data
.WriteConsoleOutputCharRequest
.NrCharactersWritten
= Written
;
1647 return Request
->Status
= Status
;
1650 CSR_API(CsrFillOutputChar
)
1653 PCSRSS_CONSOLE Console
;
1654 PCSRSS_SCREEN_BUFFER Buff
;
1655 DWORD X
, Y
, Length
, Written
= 0;
1660 DPRINT("CsrFillOutputChar\n");
1662 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
1663 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
1665 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
1666 if (! NT_SUCCESS(Status
))
1668 return Request
->Status
= Status
;
1671 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.FillOutputRequest
.ConsoleHandle
, &Buff
);
1672 if (! NT_SUCCESS(Status
))
1674 if (NULL
!= Console
)
1676 ConioUnlockConsole(Console
);
1678 return Request
->Status
= Status
;
1681 X
= Request
->Data
.FillOutputRequest
.Position
.X
+ Buff
->ShowX
;
1682 Y
= (Request
->Data
.FillOutputRequest
.Position
.Y
+ Buff
->ShowY
) % Buff
->MaxY
;
1683 Buffer
= &Buff
->Buffer
[2 * (Y
* Buff
->MaxX
+ X
)];
1684 if(Request
->Data
.FillOutputRequest
.Unicode
)
1685 ConsoleUnicodeCharToAnsiChar(Console
, &Char
, &Request
->Data
.FillOutputRequest
.Char
.UnicodeChar
);
1687 Char
= Request
->Data
.FillOutputRequest
.Char
.AsciiChar
;
1688 Length
= Request
->Data
.FillOutputRequest
.Length
;
1694 if (++X
== Buff
->MaxX
)
1696 if (++Y
== Buff
->MaxY
)
1699 Buffer
= Buff
->Buffer
;
1705 if (NULL
!= Console
&& Buff
== Console
->ActiveBuffer
)
1707 ConioComputeUpdateRect(Buff
, &UpdateRect
, &Request
->Data
.FillOutputRequest
.Position
,
1708 Request
->Data
.FillOutputRequest
.Length
);
1709 ConioDrawRegion(Console
, &UpdateRect
);
1712 ConioUnlockScreenBuffer(Buff
);
1713 if (NULL
!= Console
)
1715 ConioUnlockConsole(Console
);
1718 return Request
->Status
;
1721 CSR_API(CsrReadInputEvent
)
1723 PLIST_ENTRY CurrentEntry
;
1724 PCSRSS_CONSOLE Console
;
1726 BOOLEAN Done
= FALSE
;
1727 ConsoleInput
*Input
;
1729 DPRINT("CsrReadInputEvent\n");
1731 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
1732 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
1733 Request
->Data
.ReadInputRequest
.Event
= ProcessData
->ConsoleEvent
;
1735 Status
= ConioLockConsole(ProcessData
, Request
->Data
.ReadInputRequest
.ConsoleHandle
, &Console
);
1736 if (! NT_SUCCESS(Status
))
1738 return Request
->Status
= Status
;
1741 /* only get input if there is any */
1742 CurrentEntry
= Console
->InputEvents
.Flink
;
1743 while (CurrentEntry
!= &Console
->InputEvents
)
1745 Input
= CONTAINING_RECORD(CurrentEntry
, ConsoleInput
, ListEntry
);
1746 CurrentEntry
= CurrentEntry
->Flink
;
1748 if (Done
&& !Input
->Fake
)
1750 Request
->Data
.ReadInputRequest
.MoreEvents
= TRUE
;
1754 RemoveEntryList(&Input
->ListEntry
);
1756 if (!Done
&& !Input
->Fake
)
1758 Request
->Data
.ReadInputRequest
.Input
= Input
->InputEvent
;
1759 if (Request
->Data
.ReadInputRequest
.Unicode
== FALSE
)
1761 ConioInputEventToAnsi(Console
, &Request
->Data
.ReadInputRequest
.Input
);
1766 if (Input
->InputEvent
.EventType
== KEY_EVENT
)
1768 if (0 != (Console
->Mode
& ENABLE_LINE_INPUT
)
1769 && Input
->InputEvent
.Event
.KeyEvent
.bKeyDown
1770 && '\r' == Input
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
)
1772 Console
->WaitingLines
--;
1774 Console
->WaitingChars
--;
1776 HeapFree(Win32CsrApiHeap
, 0, Input
);
1781 Status
= STATUS_SUCCESS
;
1782 Console
->EarlyReturn
= FALSE
;
1786 Status
= STATUS_PENDING
;
1787 Console
->EarlyReturn
= TRUE
; /* mark for early return */
1790 if (IsListEmpty(&Console
->InputEvents
))
1792 ResetEvent(Console
->ActiveEvent
);
1795 ConioUnlockConsole(Console
);
1797 return Request
->Status
= Status
;
1800 CSR_API(CsrWriteConsoleOutputAttrib
)
1802 PCSRSS_CONSOLE Console
;
1803 PCSRSS_SCREEN_BUFFER Buff
;
1804 PUCHAR Buffer
, Attribute
;
1809 DPRINT("CsrWriteConsoleOutputAttrib\n");
1811 if (Request
->Header
.u1
.s1
.DataLength
1812 < sizeof(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB
) - 1
1813 + Request
->Data
.WriteConsoleOutputAttribRequest
.Length
)
1815 DPRINT1("Invalid request size\n");
1816 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
1817 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
1818 return Request
->Status
= STATUS_INVALID_PARAMETER
;
1821 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
1822 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
1823 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
1824 if (! NT_SUCCESS(Status
))
1826 return Request
->Status
= Status
;
1829 Status
= ConioLockScreenBuffer(ProcessData
,
1830 Request
->Data
.WriteConsoleOutputAttribRequest
.ConsoleHandle
,
1832 if (! NT_SUCCESS(Status
))
1834 if (NULL
!= Console
)
1836 ConioUnlockConsole(Console
);
1838 return Request
->Status
= Status
;
1841 X
= Request
->Data
.WriteConsoleOutputAttribRequest
.Coord
.X
+ Buff
->ShowX
;
1842 Y
= (Request
->Data
.WriteConsoleOutputAttribRequest
.Coord
.Y
+ Buff
->ShowY
) % Buff
->MaxY
;
1843 Length
= Request
->Data
.WriteConsoleOutputAttribRequest
.Length
;
1844 Buffer
= &Buff
->Buffer
[2 * (Y
* Buff
->MaxX
+ X
) + 1];
1845 Attribute
= (PUCHAR
)Request
->Data
.WriteConsoleOutputAttribRequest
.String
;
1848 *Buffer
= *Attribute
++;
1850 if (++X
== Buff
->MaxX
)
1852 if (++Y
== Buff
->MaxY
)
1855 Buffer
= Buff
->Buffer
+ 1;
1861 if (NULL
!= Console
&& Buff
== Console
->ActiveBuffer
)
1863 ConioComputeUpdateRect(Buff
, &UpdateRect
, &Request
->Data
.WriteConsoleOutputAttribRequest
.Coord
,
1864 Request
->Data
.WriteConsoleOutputAttribRequest
.Length
);
1865 ConioDrawRegion(Console
, &UpdateRect
);
1868 if (NULL
!= Console
)
1870 ConioUnlockConsole(Console
);
1873 Request
->Data
.WriteConsoleOutputAttribRequest
.EndCoord
.X
= Buff
->CurrentX
- Buff
->ShowX
;
1874 Request
->Data
.WriteConsoleOutputAttribRequest
.EndCoord
.Y
= (Buff
->CurrentY
+ Buff
->MaxY
- Buff
->ShowY
) % Buff
->MaxY
;
1876 ConioUnlockScreenBuffer(Buff
);
1878 return Request
->Status
= STATUS_SUCCESS
;
1881 CSR_API(CsrFillOutputAttrib
)
1883 PCSRSS_SCREEN_BUFFER Buff
;
1889 PCSRSS_CONSOLE Console
;
1891 DPRINT("CsrFillOutputAttrib\n");
1893 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
1894 if (! NT_SUCCESS(Status
))
1896 return Request
->Status
= Status
;
1899 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
1900 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
1901 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.FillOutputAttribRequest
.ConsoleHandle
, &Buff
);
1902 if (! NT_SUCCESS(Status
))
1904 if (NULL
!= Console
)
1906 ConioUnlockConsole(Console
);
1908 return Request
->Status
= Status
;
1911 X
= Request
->Data
.FillOutputAttribRequest
.Coord
.X
+ Buff
->ShowX
;
1912 Y
= (Request
->Data
.FillOutputAttribRequest
.Coord
.Y
+ Buff
->ShowY
) % Buff
->MaxY
;
1913 Length
= Request
->Data
.FillOutputAttribRequest
.Length
;
1914 Attr
= Request
->Data
.FillOutputAttribRequest
.Attribute
;
1915 Buffer
= &Buff
->Buffer
[(Y
* Buff
->MaxX
* 2) + (X
* 2) + 1];
1920 if (++X
== Buff
->MaxX
)
1922 if (++Y
== Buff
->MaxY
)
1925 Buffer
= Buff
->Buffer
+ 1;
1931 if (NULL
!= Console
&& Buff
== Console
->ActiveBuffer
)
1933 ConioComputeUpdateRect(Buff
, &UpdateRect
, &Request
->Data
.FillOutputAttribRequest
.Coord
,
1934 Request
->Data
.FillOutputAttribRequest
.Length
);
1935 ConioDrawRegion(Console
, &UpdateRect
);
1938 ConioUnlockScreenBuffer(Buff
);
1939 if (NULL
!= Console
)
1941 ConioUnlockConsole(Console
);
1944 return Request
->Status
= STATUS_SUCCESS
;
1948 CSR_API(CsrGetCursorInfo
)
1950 PCSRSS_SCREEN_BUFFER Buff
;
1953 DPRINT("CsrGetCursorInfo\n");
1955 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
1956 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
1958 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.GetCursorInfoRequest
.ConsoleHandle
, &Buff
);
1959 if (! NT_SUCCESS(Status
))
1961 return Request
->Status
= Status
;
1963 Request
->Data
.GetCursorInfoRequest
.Info
= Buff
->CursorInfo
;
1964 ConioUnlockScreenBuffer(Buff
);
1966 return Request
->Status
= STATUS_SUCCESS
;
1969 CSR_API(CsrSetCursorInfo
)
1971 PCSRSS_CONSOLE Console
;
1972 PCSRSS_SCREEN_BUFFER Buff
;
1977 DPRINT("CsrSetCursorInfo\n");
1979 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
1980 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
1982 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
1983 if (! NT_SUCCESS(Status
))
1985 return Request
->Status
= Status
;
1988 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.SetCursorInfoRequest
.ConsoleHandle
, &Buff
);
1989 if (! NT_SUCCESS(Status
))
1991 if (NULL
!= Console
)
1993 ConioUnlockConsole(Console
);
1995 return Request
->Status
= Status
;
1998 Size
= Request
->Data
.SetCursorInfoRequest
.Info
.dwSize
;
1999 Visible
= Request
->Data
.SetCursorInfoRequest
.Info
.bVisible
;
2009 if (Size
!= Buff
->CursorInfo
.dwSize
2010 || (Visible
&& ! Buff
->CursorInfo
.bVisible
) || (! Visible
&& Buff
->CursorInfo
.bVisible
))
2012 Buff
->CursorInfo
.dwSize
= Size
;
2013 Buff
->CursorInfo
.bVisible
= Visible
;
2015 if (NULL
!= Console
&& ! ConioSetCursorInfo(Console
, Buff
))
2017 ConioUnlockScreenBuffer(Buff
);
2018 ConioUnlockConsole(Console
);
2019 return Request
->Status
= STATUS_UNSUCCESSFUL
;
2023 ConioUnlockScreenBuffer(Buff
);
2024 if (NULL
!= Console
)
2026 ConioUnlockConsole(Console
);
2029 return Request
->Status
= STATUS_SUCCESS
;
2032 CSR_API(CsrSetTextAttrib
)
2035 PCSRSS_CONSOLE Console
;
2036 PCSRSS_SCREEN_BUFFER Buff
;
2037 LONG OldCursorX
, OldCursorY
;
2039 DPRINT("CsrSetTextAttrib\n");
2041 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
2042 if (! NT_SUCCESS(Status
))
2044 return Request
->Status
= Status
;
2047 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.SetCursorRequest
.ConsoleHandle
, &Buff
);
2048 if (! NT_SUCCESS(Status
))
2050 if (NULL
!= Console
)
2052 ConioUnlockConsole(Console
);
2054 return Request
->Status
= Status
;
2057 ConioPhysicalToLogical(Buff
, Buff
->CurrentX
, Buff
->CurrentY
, &OldCursorX
, &OldCursorY
);
2059 Buff
->DefaultAttrib
= Request
->Data
.SetAttribRequest
.Attrib
;
2060 if (NULL
!= Console
&& Buff
== Console
->ActiveBuffer
)
2062 if (! ConioSetScreenInfo(Console
, Buff
, OldCursorX
, OldCursorY
))
2064 ConioUnlockScreenBuffer(Buff
);
2065 ConioUnlockConsole(Console
);
2066 return Request
->Status
= STATUS_UNSUCCESSFUL
;
2070 ConioUnlockScreenBuffer(Buff
);
2071 if (NULL
!= Console
)
2073 ConioUnlockConsole(Console
);
2076 return Request
->Status
= STATUS_SUCCESS
;
2079 CSR_API(CsrSetConsoleMode
)
2082 PCSRSS_CONSOLE Console
;
2083 PCSRSS_SCREEN_BUFFER Buff
;
2085 DPRINT("CsrSetConsoleMode\n");
2087 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2088 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2089 Status
= Win32CsrGetObject(ProcessData
,
2090 Request
->Data
.SetConsoleModeRequest
.ConsoleHandle
,
2091 (Object_t
**) &Console
);
2092 if (! NT_SUCCESS(Status
))
2094 return Request
->Status
= Status
;
2097 Buff
= (PCSRSS_SCREEN_BUFFER
)Console
;
2098 if (CONIO_CONSOLE_MAGIC
== Console
->Header
.Type
)
2100 Console
->Mode
= Request
->Data
.SetConsoleModeRequest
.Mode
& CONSOLE_INPUT_MODE_VALID
;
2102 else if (CONIO_SCREEN_BUFFER_MAGIC
== Console
->Header
.Type
)
2104 Buff
->Mode
= Request
->Data
.SetConsoleModeRequest
.Mode
& CONSOLE_OUTPUT_MODE_VALID
;
2108 return Request
->Status
= STATUS_INVALID_HANDLE
;
2111 Request
->Status
= STATUS_SUCCESS
;
2113 return Request
->Status
;
2116 CSR_API(CsrGetConsoleMode
)
2119 PCSRSS_CONSOLE Console
;
2120 PCSRSS_SCREEN_BUFFER Buff
; /* gee, I really wish I could use an anonymous union here */
2122 DPRINT("CsrGetConsoleMode\n");
2124 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2125 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2126 Status
= Win32CsrGetObject(ProcessData
, Request
->Data
.GetConsoleModeRequest
.ConsoleHandle
,
2127 (Object_t
**) &Console
);
2128 if (! NT_SUCCESS(Status
))
2130 return Request
->Status
= Status
;
2132 Request
->Status
= STATUS_SUCCESS
;
2133 Buff
= (PCSRSS_SCREEN_BUFFER
) Console
;
2134 if (CONIO_CONSOLE_MAGIC
== Console
->Header
.Type
)
2136 Request
->Data
.GetConsoleModeRequest
.ConsoleMode
= Console
->Mode
;
2138 else if (CONIO_SCREEN_BUFFER_MAGIC
== Buff
->Header
.Type
)
2140 Request
->Data
.GetConsoleModeRequest
.ConsoleMode
= Buff
->Mode
;
2144 Request
->Status
= STATUS_INVALID_HANDLE
;
2147 return Request
->Status
;
2150 CSR_API(CsrCreateScreenBuffer
)
2152 PCSRSS_CONSOLE Console
;
2153 PCSRSS_SCREEN_BUFFER Buff
;
2156 DPRINT("CsrCreateScreenBuffer\n");
2158 if (ProcessData
== NULL
)
2160 return Request
->Status
= STATUS_INVALID_PARAMETER
;
2163 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
2164 if (! NT_SUCCESS(Status
))
2166 return Request
->Status
= Status
;
2168 if (NULL
== Console
)
2170 return Request
->Status
= STATUS_INVALID_HANDLE
;
2173 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2174 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2176 Buff
= HeapAlloc(Win32CsrApiHeap
, 0, sizeof(CSRSS_SCREEN_BUFFER
));
2179 Request
->Status
= STATUS_INSUFFICIENT_RESOURCES
;
2182 Status
= CsrInitConsoleScreenBuffer(Console
, Buff
);
2183 if(! NT_SUCCESS(Status
))
2185 Request
->Status
= Status
;
2189 Request
->Status
= Win32CsrInsertObject(ProcessData
, &Request
->Data
.CreateScreenBufferRequest
.OutputHandle
, &Buff
->Header
);
2192 ConioUnlockConsole(Console
);
2194 return Request
->Status
;
2197 CSR_API(CsrSetScreenBuffer
)
2200 PCSRSS_CONSOLE Console
;
2201 PCSRSS_SCREEN_BUFFER Buff
;
2203 DPRINT("CsrSetScreenBuffer\n");
2205 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
2206 if (! NT_SUCCESS(Status
))
2208 return Request
->Status
= Status
;
2210 if (NULL
== Console
)
2212 DPRINT1("Trying to set screen buffer for app without console\n");
2213 return Request
->Status
= STATUS_INVALID_HANDLE
;
2216 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2217 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2219 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.SetScreenBufferRequest
.OutputHandle
, &Buff
);
2220 if (! NT_SUCCESS(Status
))
2222 ConioUnlockConsole(Console
);
2223 return Request
->Status
;
2226 if (Buff
== Console
->ActiveBuffer
)
2228 ConioUnlockScreenBuffer(Buff
);
2229 ConioUnlockConsole(Console
);
2230 return STATUS_SUCCESS
;
2233 /* drop reference to old buffer, maybe delete */
2234 if (! InterlockedDecrement(&Console
->ActiveBuffer
->Header
.ReferenceCount
))
2236 ConioDeleteScreenBuffer((Object_t
*) Console
->ActiveBuffer
);
2238 /* tie console to new buffer */
2239 Console
->ActiveBuffer
= Buff
;
2240 /* inc ref count on new buffer */
2241 InterlockedIncrement(&Buff
->Header
.ReferenceCount
);
2242 /* Redraw the console */
2243 ConioDrawConsole(Console
);
2245 ConioUnlockScreenBuffer(Buff
);
2246 ConioUnlockConsole(Console
);
2248 return Request
->Status
= STATUS_SUCCESS
;
2251 CSR_API(CsrSetTitle
)
2254 PCSRSS_CONSOLE Console
;
2256 DPRINT("CsrSetTitle\n");
2258 if (Request
->Header
.u1
.s1
.DataLength
2259 < sizeof(CSRSS_SET_TITLE
) - 1
2260 + Request
->Data
.SetTitleRequest
.Length
)
2262 DPRINT1("Invalid request size\n");
2263 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2264 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2265 return Request
->Status
= STATUS_INVALID_PARAMETER
;
2268 Status
= ConioLockConsole(ProcessData
, Request
->Data
.SetTitleRequest
.Console
, &Console
);
2269 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2270 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2271 if(! NT_SUCCESS(Status
))
2273 Request
->Status
= Status
;
2277 /* copy title to console */
2278 RtlFreeUnicodeString(&Console
->Title
);
2279 RtlCreateUnicodeString(&Console
->Title
, Request
->Data
.SetTitleRequest
.Title
);
2280 if (! ConioChangeTitle(Console
))
2282 Request
->Status
= STATUS_UNSUCCESSFUL
;
2286 Request
->Status
= STATUS_SUCCESS
;
2289 ConioUnlockConsole(Console
);
2291 return Request
->Status
;
2294 CSR_API(CsrGetTitle
)
2297 PCSRSS_CONSOLE Console
;
2299 DPRINT("CsrGetTitle\n");
2301 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2302 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2303 Status
= ConioLockConsole(ProcessData
,
2304 Request
->Data
.GetTitleRequest
.ConsoleHandle
,
2306 if (! NT_SUCCESS(Status
))
2308 DPRINT1("Can't get console\n");
2309 return Request
->Status
= Status
;
2312 /* Copy title of the console to the user title buffer */
2313 RtlZeroMemory(&Request
->Data
.GetTitleRequest
, sizeof(CSRSS_GET_TITLE
));
2314 Request
->Data
.GetTitleRequest
.ConsoleHandle
= Request
->Data
.GetTitleRequest
.ConsoleHandle
;
2315 Request
->Data
.GetTitleRequest
.Length
= Console
->Title
.Length
;
2316 wcscpy (Request
->Data
.GetTitleRequest
.Title
, Console
->Title
.Buffer
);
2317 Request
->Header
.u1
.s1
.TotalLength
+= Console
->Title
.Length
;
2318 Request
->Header
.u1
.s1
.DataLength
+= Console
->Title
.Length
;
2319 Request
->Status
= STATUS_SUCCESS
;
2321 ConioUnlockConsole(Console
);
2323 return Request
->Status
;
2326 CSR_API(CsrWriteConsoleOutput
)
2328 SHORT i
, X
, Y
, SizeX
, SizeY
;
2329 PCSRSS_CONSOLE Console
;
2330 PCSRSS_SCREEN_BUFFER Buff
;
2332 CHAR_INFO
* CurCharInfo
;
2334 CHAR_INFO
* CharInfo
;
2341 DPRINT("CsrWriteConsoleOutput\n");
2343 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
2344 if (! NT_SUCCESS(Status
))
2346 return Request
->Status
= Status
;
2349 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2350 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2351 Status
= ConioLockScreenBuffer(ProcessData
,
2352 Request
->Data
.WriteConsoleOutputRequest
.ConsoleHandle
,
2354 if (! NT_SUCCESS(Status
))
2356 if (NULL
!= Console
)
2358 ConioUnlockConsole(Console
);
2360 return Request
->Status
= Status
;
2363 BufferSize
= Request
->Data
.WriteConsoleOutputRequest
.BufferSize
;
2364 PSize
= BufferSize
.X
* BufferSize
.Y
* sizeof(CHAR_INFO
);
2365 BufferCoord
= Request
->Data
.WriteConsoleOutputRequest
.BufferCoord
;
2366 CharInfo
= Request
->Data
.WriteConsoleOutputRequest
.CharInfo
;
2367 if (((PVOID
)CharInfo
< ProcessData
->CsrSectionViewBase
) ||
2368 (((ULONG_PTR
)CharInfo
+ PSize
) >
2369 ((ULONG_PTR
)ProcessData
->CsrSectionViewBase
+ ProcessData
->CsrSectionViewSize
)))
2371 ConioUnlockScreenBuffer(Buff
);
2372 ConioUnlockConsole(Console
);
2373 return Request
->Status
= STATUS_ACCESS_VIOLATION
;
2375 WriteRegion
.left
= Request
->Data
.WriteConsoleOutputRequest
.WriteRegion
.Left
;
2376 WriteRegion
.top
= Request
->Data
.WriteConsoleOutputRequest
.WriteRegion
.Top
;
2377 WriteRegion
.right
= Request
->Data
.WriteConsoleOutputRequest
.WriteRegion
.Right
;
2378 WriteRegion
.bottom
= Request
->Data
.WriteConsoleOutputRequest
.WriteRegion
.Bottom
;
2380 SizeY
= min(BufferSize
.Y
- BufferCoord
.Y
, ConioRectHeight(&WriteRegion
));
2381 SizeX
= min(BufferSize
.X
- BufferCoord
.X
, ConioRectWidth(&WriteRegion
));
2382 WriteRegion
.bottom
= WriteRegion
.top
+ SizeY
- 1;
2383 WriteRegion
.right
= WriteRegion
.left
+ SizeX
- 1;
2385 /* Make sure WriteRegion is inside the screen buffer */
2386 ConioInitRect(&ScreenBuffer
, 0, 0, Buff
->MaxY
- 1, Buff
->MaxX
- 1);
2387 if (! ConioGetIntersection(&WriteRegion
, &ScreenBuffer
, &WriteRegion
))
2389 ConioUnlockScreenBuffer(Buff
);
2390 ConioUnlockConsole(Console
);
2392 /* It is okay to have a WriteRegion completely outside the screen buffer.
2393 No data is written then. */
2394 return Request
->Status
= STATUS_SUCCESS
;
2397 for (i
= 0, Y
= WriteRegion
.top
; Y
<= WriteRegion
.bottom
; i
++, Y
++)
2399 CurCharInfo
= CharInfo
+ (i
+ BufferCoord
.Y
) * BufferSize
.X
+ BufferCoord
.X
;
2400 Offset
= (((Y
+ Buff
->ShowY
) % Buff
->MaxY
) * Buff
->MaxX
+ WriteRegion
.left
) * 2;
2401 for (X
= WriteRegion
.left
; X
<= WriteRegion
.right
; X
++)
2403 if (Request
->Data
.WriteConsoleOutputRequest
.Unicode
)
2406 ConsoleUnicodeCharToAnsiChar(Console
, &AsciiChar
, &CurCharInfo
->Char
.UnicodeChar
);
2407 SET_CELL_BUFFER(Buff
, Offset
, AsciiChar
, CurCharInfo
->Attributes
);
2411 SET_CELL_BUFFER(Buff
, Offset
, CurCharInfo
->Char
.AsciiChar
, CurCharInfo
->Attributes
);
2417 if (NULL
!= Console
)
2419 ConioDrawRegion(Console
, &WriteRegion
);
2422 ConioUnlockScreenBuffer(Buff
);
2423 ConioUnlockConsole(Console
);
2425 Request
->Data
.WriteConsoleOutputRequest
.WriteRegion
.Right
= WriteRegion
.left
+ SizeX
- 1;
2426 Request
->Data
.WriteConsoleOutputRequest
.WriteRegion
.Bottom
= WriteRegion
.top
+ SizeY
- 1;
2427 Request
->Data
.WriteConsoleOutputRequest
.WriteRegion
.Left
= WriteRegion
.left
;
2428 Request
->Data
.WriteConsoleOutputRequest
.WriteRegion
.Top
= WriteRegion
.top
;
2430 return Request
->Status
= STATUS_SUCCESS
;
2433 CSR_API(CsrFlushInputBuffer
)
2435 PLIST_ENTRY CurrentEntry
;
2436 PCSRSS_CONSOLE Console
;
2437 ConsoleInput
* Input
;
2440 DPRINT("CsrFlushInputBuffer\n");
2442 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2443 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2444 Status
= ConioLockConsole(ProcessData
,
2445 Request
->Data
.FlushInputBufferRequest
.ConsoleInput
,
2447 if(! NT_SUCCESS(Status
))
2449 return Request
->Status
= Status
;
2452 /* Discard all entries in the input event queue */
2453 while (!IsListEmpty(&Console
->InputEvents
))
2455 CurrentEntry
= RemoveHeadList(&Console
->InputEvents
);
2456 Input
= CONTAINING_RECORD(CurrentEntry
, ConsoleInput
, ListEntry
);
2457 /* Destroy the event */
2458 HeapFree(Win32CsrApiHeap
, 0, Input
);
2460 ResetEvent(Console
->ActiveEvent
);
2461 Console
->WaitingChars
=0;
2463 ConioUnlockConsole(Console
);
2465 return Request
->Status
= STATUS_SUCCESS
;
2468 CSR_API(CsrScrollConsoleScreenBuffer
)
2470 PCSRSS_CONSOLE Console
;
2471 PCSRSS_SCREEN_BUFFER Buff
;
2476 RECT ScrollRectangle
;
2481 DPRINT("CsrScrollConsoleScreenBuffer\n");
2483 ALIAS(ConsoleHandle
,Request
->Data
.ScrollConsoleScreenBufferRequest
.ConsoleHandle
);
2484 ALIAS(UseClipRectangle
,Request
->Data
.ScrollConsoleScreenBufferRequest
.UseClipRectangle
);
2485 ALIAS(DestinationOrigin
,Request
->Data
.ScrollConsoleScreenBufferRequest
.DestinationOrigin
);
2486 ALIAS(Fill
,Request
->Data
.ScrollConsoleScreenBufferRequest
.Fill
);
2488 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
2489 if (! NT_SUCCESS(Status
))
2491 return Request
->Status
= Status
;
2494 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2495 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2496 Status
= ConioLockScreenBuffer(ProcessData
, ConsoleHandle
, &Buff
);
2497 if (! NT_SUCCESS(Status
))
2499 if (NULL
!= Console
)
2501 ConioUnlockConsole(Console
);
2503 return Request
->Status
= Status
;
2506 ScrollRectangle
.left
= Request
->Data
.ScrollConsoleScreenBufferRequest
.ScrollRectangle
.Left
;
2507 ScrollRectangle
.top
= Request
->Data
.ScrollConsoleScreenBufferRequest
.ScrollRectangle
.Top
;
2508 ScrollRectangle
.right
= Request
->Data
.ScrollConsoleScreenBufferRequest
.ScrollRectangle
.Right
;
2509 ScrollRectangle
.bottom
= Request
->Data
.ScrollConsoleScreenBufferRequest
.ScrollRectangle
.Bottom
;
2510 ClipRectangle
.left
= Request
->Data
.ScrollConsoleScreenBufferRequest
.ClipRectangle
.Left
;
2511 ClipRectangle
.top
= Request
->Data
.ScrollConsoleScreenBufferRequest
.ClipRectangle
.Top
;
2512 ClipRectangle
.right
= Request
->Data
.ScrollConsoleScreenBufferRequest
.ClipRectangle
.Right
;
2513 ClipRectangle
.bottom
= Request
->Data
.ScrollConsoleScreenBufferRequest
.ClipRectangle
.Bottom
;
2515 /* Make sure source rectangle is inside the screen buffer */
2516 ConioInitRect(&ScreenBuffer
, 0, 0, Buff
->MaxY
- 1, Buff
->MaxX
- 1);
2517 if (! ConioGetIntersection(&SrcRegion
, &ScreenBuffer
, &ScrollRectangle
))
2519 ConioUnlockScreenBuffer(Buff
);
2520 return Request
->Status
= STATUS_INVALID_PARAMETER
;
2523 if (UseClipRectangle
&& ! ConioGetIntersection(&SrcRegion
, &SrcRegion
, &ClipRectangle
))
2525 ConioUnlockScreenBuffer(Buff
);
2526 return Request
->Status
= STATUS_SUCCESS
;
2530 ConioInitRect(&DstRegion
,
2531 DestinationOrigin
.Y
,
2532 DestinationOrigin
.X
,
2533 DestinationOrigin
.Y
+ ConioRectHeight(&ScrollRectangle
) - 1,
2534 DestinationOrigin
.X
+ ConioRectWidth(&ScrollRectangle
) - 1);
2536 /* Make sure destination rectangle is inside the screen buffer */
2537 if (! ConioGetIntersection(&DstRegion
, &DstRegion
, &ScreenBuffer
))
2539 ConioUnlockScreenBuffer(Buff
);
2540 return Request
->Status
= STATUS_INVALID_PARAMETER
;
2543 ConioCopyRegion(Buff
, &SrcRegion
, &DstRegion
);
2545 /* Get the region that should be filled with the specified character and attributes */
2549 ConioGetUnion(&FillRegion
, &SrcRegion
, &DstRegion
);
2551 if (ConioSubtractRect(&FillRegion
, &FillRegion
, &DstRegion
))
2553 /* FIXME: The subtracted rectangle is off by one line */
2554 FillRegion
.top
+= 1;
2556 ConioFillRegion(Console
, Buff
, &FillRegion
, &Fill
, Request
->Data
.ScrollConsoleScreenBufferRequest
.Unicode
);
2560 if (NULL
!= Console
&& Buff
== Console
->ActiveBuffer
)
2562 /* Draw destination region */
2563 ConioDrawRegion(Console
, &DstRegion
);
2567 /* Draw filled region */
2568 ConioDrawRegion(Console
, &FillRegion
);
2572 ConioUnlockScreenBuffer(Buff
);
2573 if (NULL
!= Console
)
2575 ConioUnlockConsole(Console
);
2578 return Request
->Status
= STATUS_SUCCESS
;
2581 CSR_API(CsrReadConsoleOutputChar
)
2584 PCSRSS_CONSOLE Console
;
2585 PCSRSS_SCREEN_BUFFER Buff
;
2592 DPRINT("CsrReadConsoleOutputChar\n");
2594 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2595 Request
->Header
.u1
.s1
.DataLength
= Request
->Header
.u1
.s1
.TotalLength
- sizeof(PORT_MESSAGE
);
2596 ReadBuffer
= Request
->Data
.ReadConsoleOutputCharRequest
.String
;
2598 CharSize
= (Request
->Data
.ReadConsoleOutputCharRequest
.Unicode
? sizeof(WCHAR
) : sizeof(CHAR
));
2600 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
2601 if (! NT_SUCCESS(Status
))
2603 return Request
->Status
= Status
;
2606 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.ReadConsoleOutputCharRequest
.ConsoleHandle
, &Buff
);
2607 if (! NT_SUCCESS(Status
))
2609 return Request
->Status
= Status
;
2612 Xpos
= Request
->Data
.ReadConsoleOutputCharRequest
.ReadCoord
.X
+ Buff
->ShowX
;
2613 Ypos
= (Request
->Data
.ReadConsoleOutputCharRequest
.ReadCoord
.Y
+ Buff
->ShowY
) % Buff
->MaxY
;
2615 for (i
= 0; i
< Request
->Data
.ReadConsoleOutputCharRequest
.NumCharsToRead
; ++i
)
2617 Char
= Buff
->Buffer
[(Xpos
* 2) + (Ypos
* 2 * Buff
->MaxX
)];
2619 if(Request
->Data
.ReadConsoleOutputCharRequest
.Unicode
)
2621 ConsoleAnsiCharToUnicodeChar(Console
, (WCHAR
*)ReadBuffer
, &Char
);
2622 ReadBuffer
+= sizeof(WCHAR
);
2625 *(ReadBuffer
++) = Char
;
2629 if (Xpos
== Buff
->MaxX
)
2634 if (Ypos
== Buff
->MaxY
)
2642 Request
->Status
= STATUS_SUCCESS
;
2643 Request
->Data
.ReadConsoleOutputCharRequest
.EndCoord
.X
= Xpos
- Buff
->ShowX
;
2644 Request
->Data
.ReadConsoleOutputCharRequest
.EndCoord
.Y
= (Ypos
- Buff
->ShowY
+ Buff
->MaxY
) % Buff
->MaxY
;
2645 Request
->Header
.u1
.s1
.TotalLength
+= Request
->Data
.ReadConsoleOutputCharRequest
.NumCharsToRead
;
2646 Request
->Header
.u1
.s1
.DataLength
+= Request
->Data
.ReadConsoleOutputCharRequest
.NumCharsToRead
;
2648 ConioUnlockScreenBuffer(Buff
);
2649 if (NULL
!= Console
)
2651 ConioUnlockConsole(Console
);
2654 Request
->Data
.ReadConsoleOutputCharRequest
.CharsRead
= (DWORD
)((ULONG_PTR
)ReadBuffer
- (ULONG_PTR
)Request
->Data
.ReadConsoleOutputCharRequest
.String
) / CharSize
;
2656 return Request
->Status
;
2660 CSR_API(CsrReadConsoleOutputAttrib
)
2663 PCSRSS_SCREEN_BUFFER Buff
;
2668 DPRINT("CsrReadConsoleOutputAttrib\n");
2670 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2671 Request
->Header
.u1
.s1
.DataLength
= Request
->Header
.u1
.s1
.TotalLength
- sizeof(PORT_MESSAGE
);
2672 ReadBuffer
= Request
->Data
.ReadConsoleOutputAttribRequest
.String
;
2674 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.ReadConsoleOutputAttribRequest
.ConsoleHandle
, &Buff
);
2675 if (! NT_SUCCESS(Status
))
2677 return Request
->Status
= Status
;
2680 Xpos
= Request
->Data
.ReadConsoleOutputAttribRequest
.ReadCoord
.X
+ Buff
->ShowX
;
2681 Ypos
= (Request
->Data
.ReadConsoleOutputAttribRequest
.ReadCoord
.Y
+ Buff
->ShowY
) % Buff
->MaxY
;
2683 for (i
= 0; i
< Request
->Data
.ReadConsoleOutputAttribRequest
.NumAttrsToRead
; ++i
)
2685 *ReadBuffer
= Buff
->Buffer
[(Xpos
* 2) + (Ypos
* 2 * Buff
->MaxX
) + 1];
2690 if (Xpos
== Buff
->MaxX
)
2695 if (Ypos
== Buff
->MaxY
)
2704 Request
->Status
= STATUS_SUCCESS
;
2705 Request
->Data
.ReadConsoleOutputAttribRequest
.EndCoord
.X
= Xpos
- Buff
->ShowX
;
2706 Request
->Data
.ReadConsoleOutputAttribRequest
.EndCoord
.Y
= (Ypos
- Buff
->ShowY
+ Buff
->MaxY
) % Buff
->MaxY
;
2707 Request
->Header
.u1
.s1
.TotalLength
+= Request
->Data
.ReadConsoleOutputAttribRequest
.NumAttrsToRead
;
2708 Request
->Header
.u1
.s1
.DataLength
+= Request
->Data
.ReadConsoleOutputAttribRequest
.NumAttrsToRead
;
2710 ConioUnlockScreenBuffer(Buff
);
2712 return Request
->Status
;
2716 CSR_API(CsrGetNumberOfConsoleInputEvents
)
2719 PCSRSS_CONSOLE Console
;
2720 PLIST_ENTRY CurrentItem
;
2722 ConsoleInput
*Input
;
2724 DPRINT("CsrGetNumberOfConsoleInputEvents\n");
2726 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2727 Request
->Header
.u1
.s1
.DataLength
= Request
->Header
.u1
.s1
.TotalLength
- sizeof(PORT_MESSAGE
);
2729 Status
= ConioLockConsole(ProcessData
, Request
->Data
.GetNumInputEventsRequest
.ConsoleHandle
, &Console
);
2730 if (! NT_SUCCESS(Status
))
2732 return Request
->Status
= Status
;
2735 CurrentItem
= Console
->InputEvents
.Flink
;
2738 /* If there are any events ... */
2739 while (CurrentItem
!= &Console
->InputEvents
)
2741 Input
= CONTAINING_RECORD(CurrentItem
, ConsoleInput
, ListEntry
);
2742 CurrentItem
= CurrentItem
->Flink
;
2749 ConioUnlockConsole(Console
);
2751 Request
->Status
= STATUS_SUCCESS
;
2752 Request
->Data
.GetNumInputEventsRequest
.NumInputEvents
= NumEvents
;
2754 return Request
->Status
;
2758 CSR_API(CsrPeekConsoleInput
)
2761 PCSRSS_CONSOLE Console
;
2764 PLIST_ENTRY CurrentItem
;
2765 PINPUT_RECORD InputRecord
;
2769 DPRINT("CsrPeekConsoleInput\n");
2771 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2772 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2774 Status
= ConioLockConsole(ProcessData
, Request
->Data
.GetNumInputEventsRequest
.ConsoleHandle
, &Console
);
2775 if(! NT_SUCCESS(Status
))
2777 return Request
->Status
= Status
;
2780 InputRecord
= Request
->Data
.PeekConsoleInputRequest
.InputRecord
;
2781 Length
= Request
->Data
.PeekConsoleInputRequest
.Length
;
2782 Size
= Length
* sizeof(INPUT_RECORD
);
2784 if (((PVOID
)InputRecord
< ProcessData
->CsrSectionViewBase
)
2785 || (((ULONG_PTR
)InputRecord
+ Size
) > ((ULONG_PTR
)ProcessData
->CsrSectionViewBase
+ ProcessData
->CsrSectionViewSize
)))
2787 ConioUnlockConsole(Console
);
2788 Request
->Status
= STATUS_ACCESS_VIOLATION
;
2789 return Request
->Status
;
2794 if (! IsListEmpty(&Console
->InputEvents
))
2796 CurrentItem
= Console
->InputEvents
.Flink
;
2798 while (CurrentItem
!= &Console
->InputEvents
&& NumItems
< Length
)
2800 Item
= CONTAINING_RECORD(CurrentItem
, ConsoleInput
, ListEntry
);
2804 CurrentItem
= CurrentItem
->Flink
;
2809 *InputRecord
= Item
->InputEvent
;
2811 if (Request
->Data
.ReadInputRequest
.Unicode
== FALSE
)
2813 ConioInputEventToAnsi(Console
, InputRecord
);
2817 CurrentItem
= CurrentItem
->Flink
;
2821 ConioUnlockConsole(Console
);
2823 Request
->Status
= STATUS_SUCCESS
;
2824 Request
->Data
.PeekConsoleInputRequest
.Length
= NumItems
;
2826 return Request
->Status
;
2830 CSR_API(CsrReadConsoleOutput
)
2832 PCHAR_INFO CharInfo
;
2833 PCHAR_INFO CurCharInfo
;
2834 PCSRSS_SCREEN_BUFFER Buff
;
2847 DPRINT("CsrReadConsoleOutput\n");
2849 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2850 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2852 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.ReadConsoleOutputRequest
.ConsoleHandle
, &Buff
);
2853 if (! NT_SUCCESS(Status
))
2855 return Request
->Status
= Status
;
2858 CharInfo
= Request
->Data
.ReadConsoleOutputRequest
.CharInfo
;
2859 ReadRegion
.left
= Request
->Data
.ReadConsoleOutputRequest
.ReadRegion
.Left
;
2860 ReadRegion
.top
= Request
->Data
.ReadConsoleOutputRequest
.ReadRegion
.Top
;
2861 ReadRegion
.right
= Request
->Data
.ReadConsoleOutputRequest
.ReadRegion
.Right
;
2862 ReadRegion
.bottom
= Request
->Data
.ReadConsoleOutputRequest
.ReadRegion
.Bottom
;
2863 BufferSize
= Request
->Data
.ReadConsoleOutputRequest
.BufferSize
;
2864 BufferCoord
= Request
->Data
.ReadConsoleOutputRequest
.BufferCoord
;
2865 Length
= BufferSize
.X
* BufferSize
.Y
;
2866 Size
= Length
* sizeof(CHAR_INFO
);
2868 /* FIXME: Is this correct? */
2869 CodePage
= ProcessData
->Console
->OutputCodePage
;
2871 if (((PVOID
)CharInfo
< ProcessData
->CsrSectionViewBase
)
2872 || (((ULONG_PTR
)CharInfo
+ Size
) > ((ULONG_PTR
)ProcessData
->CsrSectionViewBase
+ ProcessData
->CsrSectionViewSize
)))
2874 ConioUnlockScreenBuffer(Buff
);
2875 Request
->Status
= STATUS_ACCESS_VIOLATION
;
2876 return Request
->Status
;
2879 SizeY
= min(BufferSize
.Y
- BufferCoord
.Y
, ConioRectHeight(&ReadRegion
));
2880 SizeX
= min(BufferSize
.X
- BufferCoord
.X
, ConioRectWidth(&ReadRegion
));
2881 ReadRegion
.bottom
= ReadRegion
.top
+ SizeY
;
2882 ReadRegion
.right
= ReadRegion
.left
+ SizeX
;
2884 ConioInitRect(&ScreenRect
, 0, 0, Buff
->MaxY
, Buff
->MaxX
);
2885 if (! ConioGetIntersection(&ReadRegion
, &ScreenRect
, &ReadRegion
))
2887 ConioUnlockScreenBuffer(Buff
);
2888 Request
->Status
= STATUS_SUCCESS
;
2889 return Request
->Status
;
2892 for (i
= 0, Y
= ReadRegion
.top
; Y
< ReadRegion
.bottom
; ++i
, ++Y
)
2894 CurCharInfo
= CharInfo
+ (i
* BufferSize
.X
);
2896 Offset
= (((Y
+ Buff
->ShowY
) % Buff
->MaxY
) * Buff
->MaxX
+ ReadRegion
.left
) * 2;
2897 for (X
= ReadRegion
.left
; X
< ReadRegion
.right
; ++X
)
2899 if (Request
->Data
.ReadConsoleOutputRequest
.Unicode
)
2901 MultiByteToWideChar(CodePage
, 0,
2902 (PCHAR
)&GET_CELL_BUFFER(Buff
, Offset
), 1,
2903 &CurCharInfo
->Char
.UnicodeChar
, 1);
2907 CurCharInfo
->Char
.AsciiChar
= GET_CELL_BUFFER(Buff
, Offset
);
2909 CurCharInfo
->Attributes
= GET_CELL_BUFFER(Buff
, Offset
);
2914 ConioUnlockScreenBuffer(Buff
);
2916 Request
->Status
= STATUS_SUCCESS
;
2917 Request
->Data
.ReadConsoleOutputRequest
.ReadRegion
.Right
= ReadRegion
.left
+ SizeX
- 1;
2918 Request
->Data
.ReadConsoleOutputRequest
.ReadRegion
.Bottom
= ReadRegion
.top
+ SizeY
- 1;
2919 Request
->Data
.ReadConsoleOutputRequest
.ReadRegion
.Left
= ReadRegion
.left
;
2920 Request
->Data
.ReadConsoleOutputRequest
.ReadRegion
.Top
= ReadRegion
.top
;
2922 return Request
->Status
;
2926 CSR_API(CsrWriteConsoleInput
)
2928 PINPUT_RECORD InputRecord
;
2929 PCSRSS_CONSOLE Console
;
2934 ConsoleInput
* Record
;
2936 DPRINT("CsrWriteConsoleInput\n");
2938 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2939 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2941 Status
= ConioLockConsole(ProcessData
, Request
->Data
.WriteConsoleInputRequest
.ConsoleHandle
, &Console
);
2942 if (! NT_SUCCESS(Status
))
2944 return Request
->Status
= Status
;
2947 InputRecord
= Request
->Data
.WriteConsoleInputRequest
.InputRecord
;
2948 Length
= Request
->Data
.WriteConsoleInputRequest
.Length
;
2949 Size
= Length
* sizeof(INPUT_RECORD
);
2951 if (((PVOID
)InputRecord
< ProcessData
->CsrSectionViewBase
)
2952 || (((ULONG_PTR
)InputRecord
+ Size
) > ((ULONG_PTR
)ProcessData
->CsrSectionViewBase
+ ProcessData
->CsrSectionViewSize
)))
2954 ConioUnlockConsole(Console
);
2955 Request
->Status
= STATUS_ACCESS_VIOLATION
;
2956 return Request
->Status
;
2959 for (i
= 0; i
< Length
; i
++)
2961 Record
= HeapAlloc(Win32CsrApiHeap
, 0, sizeof(ConsoleInput
));
2964 ConioUnlockConsole(Console
);
2965 Request
->Status
= STATUS_INSUFFICIENT_RESOURCES
;
2966 return Request
->Status
;
2969 Record
->Echoed
= FALSE
;
2970 Record
->Fake
= FALSE
;
2971 Record
->InputEvent
= *InputRecord
++;
2972 if (KEY_EVENT
== Record
->InputEvent
.EventType
)
2974 /* FIXME - convert from unicode to ascii!! */
2975 ConioProcessChar(Console
, Record
);
2979 ConioUnlockConsole(Console
);
2981 Request
->Status
= STATUS_SUCCESS
;
2982 Request
->Data
.WriteConsoleInputRequest
.Length
= i
;
2984 return Request
->Status
;
2987 /**********************************************************************
2988 * HardwareStateProperty
2991 * Set/Get the value of the HardwareState and switch
2992 * between direct video buffer ouput and GDI windowed
2995 * Client hands us a CSRSS_CONSOLE_HARDWARE_STATE
2996 * object. We use the same object to Request.
2998 * ConsoleHwState has the correct size to be compatible
2999 * with NT's, but values are not.
3001 STATIC NTSTATUS FASTCALL
3002 SetConsoleHardwareState (PCSRSS_CONSOLE Console
, DWORD ConsoleHwState
)
3004 DPRINT1("Console Hardware State: %d\n", ConsoleHwState
);
3006 if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED
== ConsoleHwState
)
3007 ||(CONSOLE_HARDWARE_STATE_DIRECT
== ConsoleHwState
))
3009 if (Console
->HardwareState
!= ConsoleHwState
)
3011 /* TODO: implement switching from full screen to windowed mode */
3012 /* TODO: or back; now simply store the hardware state */
3013 Console
->HardwareState
= ConsoleHwState
;
3016 return STATUS_SUCCESS
;
3019 return STATUS_INVALID_PARAMETER_3
; /* Client: (handle, set_get, [mode]) */
3022 CSR_API(CsrHardwareStateProperty
)
3024 PCSRSS_CONSOLE Console
;
3027 DPRINT("CsrHardwareStateProperty\n");
3029 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
3030 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
3032 Status
= ConioLockConsole(ProcessData
,
3033 Request
->Data
.ConsoleHardwareStateRequest
.ConsoleHandle
,
3035 if (! NT_SUCCESS(Status
))
3037 DPRINT1("Failed to get console handle in SetConsoleHardwareState\n");
3038 return Request
->Status
= Status
;
3041 switch (Request
->Data
.ConsoleHardwareStateRequest
.SetGet
)
3043 case CONSOLE_HARDWARE_STATE_GET
:
3044 Request
->Data
.ConsoleHardwareStateRequest
.State
= Console
->HardwareState
;
3047 case CONSOLE_HARDWARE_STATE_SET
:
3048 DPRINT("Setting console hardware state.\n");
3049 Request
->Status
= SetConsoleHardwareState(Console
, Request
->Data
.ConsoleHardwareStateRequest
.State
);
3053 Request
->Status
= STATUS_INVALID_PARAMETER_2
; /* Client: (handle, [set_get], mode) */
3057 ConioUnlockConsole(Console
);
3059 return Request
->Status
;
3062 CSR_API(CsrGetConsoleWindow
)
3064 PCSRSS_CONSOLE Console
;
3067 DPRINT("CsrGetConsoleWindow\n");
3069 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
3070 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
3072 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
3073 if (! NT_SUCCESS(Status
))
3075 return Request
->Status
= Status
;
3078 Request
->Data
.GetConsoleWindowRequest
.WindowHandle
= Console
->hWindow
;
3079 ConioUnlockConsole(Console
);
3081 return Request
->Status
= STATUS_SUCCESS
;
3084 CSR_API(CsrSetConsoleIcon
)
3086 PCSRSS_CONSOLE Console
;
3089 DPRINT("CsrSetConsoleIcon\n");
3091 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
3092 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
3094 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
3095 if (! NT_SUCCESS(Status
))
3097 return Request
->Status
= Status
;
3100 Console
->hWindowIcon
= Request
->Data
.SetConsoleIconRequest
.WindowIcon
;
3101 Request
->Status
= (ConioChangeIcon(Console
) ? STATUS_SUCCESS
: STATUS_UNSUCCESSFUL
);
3102 ConioUnlockConsole(Console
);
3104 return Request
->Status
;
3107 CSR_API(CsrGetConsoleCodePage
)
3109 PCSRSS_CONSOLE Console
;
3112 DPRINT("CsrGetConsoleCodePage\n");
3114 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
3115 if (! NT_SUCCESS(Status
))
3117 return Request
->Status
= Status
;
3120 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
3121 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
3122 Request
->Data
.GetConsoleCodePage
.CodePage
= Console
->CodePage
;
3123 ConioUnlockConsole(Console
);
3124 return Request
->Status
= STATUS_SUCCESS
;
3127 CSR_API(CsrSetConsoleCodePage
)
3129 PCSRSS_CONSOLE Console
;
3132 DPRINT("CsrSetConsoleCodePage\n");
3134 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
3135 if (! NT_SUCCESS(Status
))
3137 return Request
->Status
= Status
;
3140 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
3141 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
3142 if (IsValidCodePage(Request
->Data
.SetConsoleCodePage
.CodePage
))
3144 Console
->CodePage
= Request
->Data
.SetConsoleCodePage
.CodePage
;
3145 ConioUnlockConsole(Console
);
3146 return Request
->Status
= STATUS_SUCCESS
;
3148 ConioUnlockConsole(Console
);
3149 return Request
->Status
= STATUS_UNSUCCESSFUL
;
3152 CSR_API(CsrGetConsoleOutputCodePage
)
3154 PCSRSS_CONSOLE Console
;
3157 DPRINT("CsrGetConsoleOutputCodePage\n");
3159 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
3160 if (! NT_SUCCESS(Status
))
3162 return Request
->Status
= Status
;
3165 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
3166 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
3167 Request
->Data
.GetConsoleOutputCodePage
.CodePage
= Console
->OutputCodePage
;
3168 ConioUnlockConsole(Console
);
3169 return Request
->Status
= STATUS_SUCCESS
;
3172 CSR_API(CsrSetConsoleOutputCodePage
)
3174 PCSRSS_CONSOLE Console
;
3177 DPRINT("CsrSetConsoleOutputCodePage\n");
3179 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
3180 if (! NT_SUCCESS(Status
))
3182 return Request
->Status
= Status
;
3185 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
3186 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
3187 if (IsValidCodePage(Request
->Data
.SetConsoleOutputCodePage
.CodePage
))
3189 Console
->OutputCodePage
= Request
->Data
.SetConsoleOutputCodePage
.CodePage
;
3190 ConioUnlockConsole(Console
);
3191 return Request
->Status
= STATUS_SUCCESS
;
3193 ConioUnlockConsole(Console
);
3194 return Request
->Status
= STATUS_UNSUCCESSFUL
;
3197 CSR_API(CsrGetProcessList
)
3200 PCSRSS_CONSOLE Console
;
3201 PCSRSS_PROCESS_DATA current
;
3202 PLIST_ENTRY current_entry
;
3203 ULONG nItems
, nCopied
;
3206 DPRINT("CsrGetProcessList\n");
3208 Buffer
= Request
->Data
.GetProcessListRequest
.ProcessId
;
3209 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
3210 Request
->Header
.u1
.s1
.DataLength
= Request
->Header
.u1
.s1
.TotalLength
- sizeof(PORT_MESSAGE
);
3212 nItems
= nCopied
= 0;
3213 Request
->Data
.GetProcessListRequest
.nProcessIdsCopied
= 0;
3214 Request
->Data
.GetProcessListRequest
.nProcessIdsTotal
= 0;
3216 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
3217 if (! NT_SUCCESS(Status
))
3219 return Request
->Status
= Status
;
3222 DPRINT1("Console_Api Ctrl-C\n");
3224 for(current_entry
= Console
->ProcessList
.Flink
;
3225 current_entry
!= &Console
->ProcessList
;
3226 current_entry
= current_entry
->Flink
)
3228 current
= CONTAINING_RECORD(current_entry
, CSRSS_PROCESS_DATA
, ProcessEntry
);
3229 if(nItems
++ < Request
->Data
.GetProcessListRequest
.nMaxIds
)
3231 *(Buffer
++) = current
->ProcessId
;
3236 ConioUnlockConsole(Console
);
3238 Request
->Data
.GetProcessListRequest
.nProcessIdsCopied
= nCopied
;
3239 Request
->Data
.GetProcessListRequest
.nProcessIdsTotal
= nItems
;
3241 return Request
->Status
= STATUS_SUCCESS
;