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 ////////////////////////////
350 InsertHeadList(&ProcessData
->Console
->ProcessList
, &ProcessData
->ProcessEntry
);
351 ///////////////////////////
352 return STATUS_SUCCESS
;
355 CSR_API(CsrFreeConsole
)
357 PCSRSS_CONSOLE Console
;
359 DPRINT("CsrFreeConsole\n");
361 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
362 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
364 if (ProcessData
== NULL
|| ProcessData
->Console
== NULL
)
366 return Request
->Status
= STATUS_INVALID_PARAMETER
;
369 Console
= ProcessData
->Console
;
370 ProcessData
->Console
= NULL
;
371 if (0 == InterlockedDecrement(&Console
->Header
.ReferenceCount
))
373 ConioDeleteConsole((Object_t
*) Console
);
376 return STATUS_SUCCESS
;
380 ConioNextLine(PCSRSS_SCREEN_BUFFER Buff
, RECT
*UpdateRect
, UINT
*ScrolledLines
)
382 /* slide the viewable screen */
383 if (((Buff
->CurrentY
- Buff
->ShowY
+ Buff
->MaxY
) % Buff
->MaxY
) == (ULONG
)Buff
->MaxY
- 1)
385 if (++Buff
->ShowY
== Buff
->MaxY
)
391 if (++Buff
->CurrentY
== Buff
->MaxY
)
395 ClearLineBuffer(Buff
);
396 UpdateRect
->left
= 0;
397 UpdateRect
->right
= Buff
->MaxX
- 1;
398 if (UpdateRect
->top
== (LONG
)Buff
->CurrentY
)
400 if (++UpdateRect
->top
== Buff
->MaxY
)
405 UpdateRect
->bottom
= Buff
->CurrentY
;
408 STATIC NTSTATUS FASTCALL
409 ConioWriteConsole(PCSRSS_CONSOLE Console
, PCSRSS_SCREEN_BUFFER Buff
,
410 CHAR
*Buffer
, DWORD Length
, BOOL Attrib
)
415 LONG CursorStartX
, CursorStartY
;
418 ConioPhysicalToLogical(Buff
, Buff
->CurrentX
, Buff
->CurrentY
, &CursorStartX
, &CursorStartY
);
419 UpdateRect
.left
= Buff
->MaxX
;
420 UpdateRect
.top
= Buff
->CurrentY
;
421 UpdateRect
.right
= -1;
422 UpdateRect
.bottom
= Buff
->CurrentY
;
425 for (i
= 0; i
< Length
; i
++)
427 if (Buff
->Mode
& ENABLE_PROCESSED_OUTPUT
)
430 if (Buffer
[i
] == '\n')
433 ConioNextLine(Buff
, &UpdateRect
, &ScrolledLines
);
437 else if (Buffer
[i
] == '\b')
439 /* Only handle BS if we're not on the first pos of the first line */
440 if (0 != Buff
->CurrentX
|| Buff
->ShowY
!= Buff
->CurrentY
)
442 if (0 == Buff
->CurrentX
)
444 /* slide virtual position up */
445 Buff
->CurrentX
= Buff
->MaxX
- 1;
446 if (0 == Buff
->CurrentY
)
448 Buff
->CurrentY
= Buff
->MaxY
;
454 if ((0 == UpdateRect
.top
&& UpdateRect
.bottom
< (LONG
)Buff
->CurrentY
)
455 || (0 != UpdateRect
.top
&& (LONG
)Buff
->CurrentY
< UpdateRect
.top
))
457 UpdateRect
.top
= Buff
->CurrentY
;
464 Offset
= 2 * ((Buff
->CurrentY
* Buff
->MaxX
) + Buff
->CurrentX
);
465 SET_CELL_BUFFER(Buff
, Offset
, ' ', Buff
->DefaultAttrib
);
466 UpdateRect
.left
= min(UpdateRect
.left
, (LONG
) Buff
->CurrentX
);
467 UpdateRect
.right
= max(UpdateRect
.right
, (LONG
) Buff
->CurrentX
);
472 else if (Buffer
[i
] == '\r')
475 UpdateRect
.left
= min(UpdateRect
.left
, (LONG
) Buff
->CurrentX
);
476 UpdateRect
.right
= max(UpdateRect
.right
, (LONG
) Buff
->CurrentX
);
480 else if (Buffer
[i
] == '\t')
484 UpdateRect
.left
= min(UpdateRect
.left
, (LONG
)Buff
->CurrentX
);
485 EndX
= (Buff
->CurrentX
+ 8) & ~7;
486 if (EndX
> Buff
->MaxX
)
490 Offset
= 2 * (((Buff
->CurrentY
* Buff
->MaxX
)) + Buff
->CurrentX
);
491 while (Buff
->CurrentX
< EndX
)
493 Buff
->Buffer
[Offset
] = ' ';
497 UpdateRect
.right
= max(UpdateRect
.right
, (LONG
) Buff
->CurrentX
- 1);
498 if (Buff
->CurrentX
== Buff
->MaxX
)
500 if (Buff
->Mode
& ENABLE_WRAP_AT_EOL_OUTPUT
)
503 ConioNextLine(Buff
, &UpdateRect
, &ScrolledLines
);
513 UpdateRect
.left
= min(UpdateRect
.left
, (LONG
)Buff
->CurrentX
);
514 UpdateRect
.right
= max(UpdateRect
.right
, (LONG
) Buff
->CurrentX
);
515 Offset
= 2 * (((Buff
->CurrentY
* Buff
->MaxX
)) + Buff
->CurrentX
);
516 Buff
->Buffer
[Offset
++] = Buffer
[i
];
519 Buff
->Buffer
[Offset
] = Buff
->DefaultAttrib
;
522 if (Buff
->CurrentX
== Buff
->MaxX
)
524 if (Buff
->Mode
& ENABLE_WRAP_AT_EOL_OUTPUT
)
527 ConioNextLine(Buff
, &UpdateRect
, &ScrolledLines
);
531 Buff
->CurrentX
= CursorStartX
;
536 ConioPhysicalToLogical(Buff
, UpdateRect
.left
, UpdateRect
.top
, &(UpdateRect
.left
),
538 ConioPhysicalToLogical(Buff
, UpdateRect
.right
, UpdateRect
.bottom
, &(UpdateRect
.right
),
539 &(UpdateRect
.bottom
));
540 if (! ConioIsRectEmpty(&UpdateRect
) && NULL
!= Console
&& Buff
== Console
->ActiveBuffer
)
542 ConioWriteStream(Console
, &UpdateRect
, CursorStartX
, CursorStartY
, ScrolledLines
,
546 return STATUS_SUCCESS
;
549 CSR_API(CsrReadConsole
)
551 PLIST_ENTRY CurrentEntry
;
554 PWCHAR UnicodeBuffer
;
556 ULONG nNumberOfCharsToRead
, CharSize
;
557 PCSRSS_CONSOLE Console
;
560 DPRINT("CsrReadConsole\n");
562 CharSize
= (Request
->Data
.ReadConsoleRequest
.Unicode
? sizeof(WCHAR
) : sizeof(CHAR
));
564 /* truncate length to CSRSS_MAX_READ_CONSOLE_REQUEST */
565 nNumberOfCharsToRead
= min(Request
->Data
.ReadConsoleRequest
.NrCharactersToRead
, CSRSS_MAX_READ_CONSOLE
/ CharSize
);
566 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
567 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
569 Buffer
= Request
->Data
.ReadConsoleRequest
.Buffer
;
570 UnicodeBuffer
= (PWCHAR
)Buffer
;
571 Status
= ConioLockConsole(ProcessData
, Request
->Data
.ReadConsoleRequest
.ConsoleHandle
,
573 if (! NT_SUCCESS(Status
))
575 return Request
->Status
= Status
;
577 Request
->Data
.ReadConsoleRequest
.EventHandle
= ProcessData
->ConsoleEvent
;
578 for (i
= 0; i
< nNumberOfCharsToRead
&& Console
->InputEvents
.Flink
!= &Console
->InputEvents
; i
++)
580 /* remove input event from queue */
581 CurrentEntry
= RemoveHeadList(&Console
->InputEvents
);
582 if (IsListEmpty(&Console
->InputEvents
))
585 ResetEvent(Console
->ActiveEvent
);
587 Input
= CONTAINING_RECORD(CurrentEntry
, ConsoleInput
, ListEntry
);
589 /* only pay attention to valid ascii chars, on key down */
590 if (KEY_EVENT
== Input
->InputEvent
.EventType
591 && Input
->InputEvent
.Event
.KeyEvent
.bKeyDown
592 && Input
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
!= '\0')
594 /* backspace handling */
595 if ('\b' == Input
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
)
597 /* echo if it has not already been done, and either we or the client has chars to be deleted */
599 && (0 != i
|| Request
->Data
.ReadConsoleRequest
.nCharsCanBeDeleted
))
601 ConioWriteConsole(Console
, Console
->ActiveBuffer
,
602 &Input
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
, 1, TRUE
);
606 i
-= 2; /* if we already have something to return, just back it up by 2 */
609 { /* otherwise, return STATUS_NOTIFY_CLEANUP to tell client to back up its buffer */
610 Console
->WaitingChars
--;
611 ConioUnlockConsole(Console
);
612 HeapFree(Win32CsrApiHeap
, 0, Input
);
613 Request
->Data
.ReadConsoleRequest
.NrCharactersRead
= 0;
614 Request
->Status
= STATUS_NOTIFY_CLEANUP
;
615 return STATUS_NOTIFY_CLEANUP
;
617 Request
->Data
.ReadConsoleRequest
.nCharsCanBeDeleted
--;
618 Input
->Echoed
= TRUE
; /* mark as echoed so we don't echo it below */
620 /* do not copy backspace to buffer */
623 if(Request
->Data
.ReadConsoleRequest
.Unicode
)
624 UnicodeBuffer
[i
] = Input
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
; /* FIXME */
626 Buffer
[i
] = Input
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
;
628 /* echo to screen if enabled and we did not already echo the char */
629 if (0 != (Console
->Mode
& ENABLE_ECHO_INPUT
)
631 && '\r' != Input
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
)
633 ConioWriteConsole(Console
, Console
->ActiveBuffer
,
634 &Input
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
, 1, TRUE
);
641 Console
->WaitingChars
--;
642 HeapFree(Win32CsrApiHeap
, 0, Input
);
644 Request
->Data
.ReadConsoleRequest
.NrCharactersRead
= i
;
647 Request
->Status
= STATUS_PENDING
; /* we didn't read anything */
649 else if (0 != (Console
->Mode
& ENABLE_LINE_INPUT
))
651 if (0 == Console
->WaitingLines
||
652 (Request
->Data
.ReadConsoleRequest
.Unicode
? (L
'\n' != UnicodeBuffer
[i
- 1]) : ('\n' != Buffer
[i
- 1])))
654 Request
->Status
= STATUS_PENDING
; /* line buffered, didn't get a complete line */
658 Console
->WaitingLines
--;
659 Request
->Status
= STATUS_SUCCESS
; /* line buffered, did get a complete line */
664 Request
->Status
= STATUS_SUCCESS
; /* not line buffered, did read something */
667 if (Request
->Status
== STATUS_PENDING
)
669 Console
->EchoCount
= nNumberOfCharsToRead
- i
;
673 Console
->EchoCount
= 0; /* if the client is no longer waiting on input, do not echo */
676 ConioUnlockConsole(Console
);
678 if (CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE
) + i
* CharSize
> sizeof(CSR_API_MESSAGE
))
680 Request
->Header
.u1
.s1
.TotalLength
= CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE
) + i
* CharSize
;
681 Request
->Header
.u1
.s1
.DataLength
= Request
->Header
.u1
.s1
.TotalLength
- sizeof(PORT_MESSAGE
);
684 return Request
->Status
;
688 ConioPhysicalToLogical(PCSRSS_SCREEN_BUFFER Buff
,
694 *LogicalX
= PhysicalX
;
695 if (PhysicalY
< Buff
->ShowY
)
697 *LogicalY
= Buff
->MaxY
- Buff
->ShowY
+ PhysicalY
;
701 *LogicalY
= PhysicalY
- Buff
->ShowY
;
705 inline BOOLEAN
ConioIsEqualRect(
709 return ((Rect1
->left
== Rect2
->left
) && (Rect1
->right
== Rect2
->right
) &&
710 (Rect1
->top
== Rect2
->top
) && (Rect1
->bottom
== Rect2
->bottom
));
713 inline BOOLEAN
ConioGetIntersection(
718 if (ConioIsRectEmpty(Rect1
) ||
719 (ConioIsRectEmpty(Rect2
)) ||
720 (Rect1
->top
> Rect2
->bottom
) ||
721 (Rect1
->left
> Rect2
->right
) ||
722 (Rect1
->bottom
< Rect2
->top
) ||
723 (Rect1
->right
< Rect2
->left
))
725 /* The rectangles do not intersect */
726 ConioInitRect(Intersection
, 0, -1, 0, -1);
730 ConioInitRect(Intersection
,
731 max(Rect1
->top
, Rect2
->top
),
732 max(Rect1
->left
, Rect2
->left
),
733 min(Rect1
->bottom
, Rect2
->bottom
),
734 min(Rect1
->right
, Rect2
->right
));
739 inline BOOLEAN
ConioGetUnion(
744 if (ConioIsRectEmpty(Rect1
))
746 if (ConioIsRectEmpty(Rect2
))
748 ConioInitRect(Union
, 0, -1, 0, -1);
756 else if (ConioIsRectEmpty(Rect2
))
763 min(Rect1
->top
, Rect2
->top
),
764 min(Rect1
->left
, Rect2
->left
),
765 max(Rect1
->bottom
, Rect2
->bottom
),
766 max(Rect1
->right
, Rect2
->right
));
772 inline BOOLEAN
ConioSubtractRect(
779 if (ConioIsRectEmpty(Rect1
))
781 ConioInitRect(Subtraction
, 0, -1, 0, -1);
784 *Subtraction
= *Rect1
;
785 if (ConioGetIntersection(&tmp
, Rect1
, Rect2
))
787 if (ConioIsEqualRect(&tmp
, Subtraction
))
789 ConioInitRect(Subtraction
, 0, -1, 0, -1);
792 if ((tmp
.top
== Subtraction
->top
) && (tmp
.bottom
== Subtraction
->bottom
))
794 if (tmp
.left
== Subtraction
->left
)
796 Subtraction
->left
= tmp
.right
;
798 else if (tmp
.right
== Subtraction
->right
)
800 Subtraction
->right
= tmp
.left
;
803 else if ((tmp
.left
== Subtraction
->left
) && (tmp
.right
== Subtraction
->right
))
805 if (tmp
.top
== Subtraction
->top
)
807 Subtraction
->top
= tmp
.bottom
;
809 else if (tmp
.bottom
== Subtraction
->bottom
)
811 Subtraction
->bottom
= tmp
.top
;
820 ConioCopyRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer
,
830 DstY
= DstRegion
->top
;
831 BytesPerLine
= ConioRectWidth(DstRegion
) * 2;
833 SrcY
= (SrcRegion
->top
+ ScreenBuffer
->ShowY
) % ScreenBuffer
->MaxY
;
834 DstY
= (DstRegion
->top
+ ScreenBuffer
->ShowY
) % ScreenBuffer
->MaxY
;
835 SrcOffset
= (SrcY
* ScreenBuffer
->MaxX
+ SrcRegion
->left
+ ScreenBuffer
->ShowX
) * 2;
836 DstOffset
= (DstY
* ScreenBuffer
->MaxX
+ DstRegion
->left
+ ScreenBuffer
->ShowX
) * 2;
838 for (i
= SrcRegion
->top
; i
<= SrcRegion
->bottom
; i
++)
841 &ScreenBuffer
->Buffer
[DstOffset
],
842 &ScreenBuffer
->Buffer
[SrcOffset
],
845 if (++DstY
== ScreenBuffer
->MaxY
)
848 DstOffset
= (DstRegion
->left
+ ScreenBuffer
->ShowX
) * 2;
852 DstOffset
+= ScreenBuffer
->MaxX
* 2;
855 if (++SrcY
== ScreenBuffer
->MaxY
)
858 SrcOffset
= (SrcRegion
->left
+ ScreenBuffer
->ShowX
) * 2;
862 SrcOffset
+= ScreenBuffer
->MaxX
* 2;
868 ConioFillRegion(PCSRSS_CONSOLE Console
,
869 PCSRSS_SCREEN_BUFFER ScreenBuffer
,
881 ConsoleUnicodeCharToAnsiChar(Console
, &Char
, &CharInfo
->Char
.UnicodeChar
);
883 Char
= CharInfo
->Char
.AsciiChar
;
885 Y
= (Region
->top
+ ScreenBuffer
->ShowY
) % ScreenBuffer
->MaxY
;
886 Offset
= (Y
* ScreenBuffer
->MaxX
+ Region
->left
+ ScreenBuffer
->ShowX
) * 2;
887 Delta
= (ScreenBuffer
->MaxX
- ConioRectWidth(Region
)) * 2;
889 for (i
= Region
->top
; i
<= Region
->bottom
; i
++)
891 for (X
= Region
->left
; X
<= Region
->right
; X
++)
893 SET_CELL_BUFFER(ScreenBuffer
, Offset
, Char
, CharInfo
->Attributes
);
895 if (++Y
== ScreenBuffer
->MaxY
)
898 Offset
= (Region
->left
+ ScreenBuffer
->ShowX
) * 2;
908 ConioInputEventToAnsi(PCSRSS_CONSOLE Console
, PINPUT_RECORD InputEvent
)
910 if (InputEvent
->EventType
== KEY_EVENT
)
912 WCHAR UnicodeChar
= InputEvent
->Event
.KeyEvent
.uChar
.UnicodeChar
;
913 InputEvent
->Event
.KeyEvent
.uChar
.UnicodeChar
= 0;
914 ConsoleUnicodeCharToAnsiChar(Console
,
915 &InputEvent
->Event
.KeyEvent
.uChar
.AsciiChar
,
920 CSR_API(CsrWriteConsole
)
924 PCSRSS_SCREEN_BUFFER Buff
;
925 PCSRSS_CONSOLE Console
;
928 ULONG CharSize
= (Request
->Data
.WriteConsoleRequest
.Unicode
? sizeof(WCHAR
) : sizeof(CHAR
));
930 DPRINT("CsrWriteConsole\n");
932 if (Request
->Header
.u1
.s1
.TotalLength
933 < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE
)
934 + (Request
->Data
.WriteConsoleRequest
.NrCharactersToWrite
* CharSize
))
936 DPRINT1("Invalid request size\n");
937 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
938 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
939 return Request
->Status
= STATUS_INVALID_PARAMETER
;
941 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
943 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
944 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
946 if (! NT_SUCCESS(Status
))
948 return Request
->Status
= Status
;
951 if(Request
->Data
.WriteConsoleRequest
.Unicode
)
953 Length
= WideCharToMultiByte(Console
->CodePage
, 0,
954 (PWCHAR
)Request
->Data
.WriteConsoleRequest
.Buffer
,
955 Request
->Data
.WriteConsoleRequest
.NrCharactersToWrite
,
956 NULL
, 0, NULL
, NULL
);
957 Buffer
= RtlAllocateHeap(GetProcessHeap(), 0, Length
);
960 WideCharToMultiByte(Console
->CodePage
, 0,
961 (PWCHAR
)Request
->Data
.WriteConsoleRequest
.Buffer
,
962 Request
->Data
.WriteConsoleRequest
.NrCharactersToWrite
,
963 Buffer
, Length
, NULL
, NULL
);
967 Status
= STATUS_NO_MEMORY
;
972 Buffer
= (PCHAR
)Request
->Data
.WriteConsoleRequest
.Buffer
;
977 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.WriteConsoleRequest
.ConsoleHandle
, &Buff
);
978 if (NT_SUCCESS(Status
))
980 Request
->Status
= ConioWriteConsole(Console
, Buff
, Buffer
,
981 Request
->Data
.WriteConsoleRequest
.NrCharactersToWrite
, TRUE
);
982 if (NT_SUCCESS(Status
))
984 Written
= Request
->Data
.WriteConsoleRequest
.NrCharactersToWrite
;
986 ConioUnlockScreenBuffer(Buff
);
988 if (Request
->Data
.WriteConsoleRequest
.Unicode
)
990 RtlFreeHeap(GetProcessHeap(), 0, Buffer
);
995 ConioUnlockConsole(Console
);
998 Request
->Data
.WriteConsoleRequest
.NrCharactersWritten
= Written
;
1000 return Request
->Status
= Status
;
1004 ConioDeleteScreenBuffer(Object_t
*Object
)
1006 PCSRSS_SCREEN_BUFFER Buffer
= (PCSRSS_SCREEN_BUFFER
) Object
;
1007 DeleteCriticalSection(&Buffer
->Header
.Lock
);
1008 HeapFree(Win32CsrApiHeap
, 0, Buffer
->Buffer
);
1009 HeapFree(Win32CsrApiHeap
, 0, Buffer
);
1013 ConioDrawConsole(PCSRSS_CONSOLE Console
)
1017 ConioInitRect(&Region
, 0, 0, Console
->Size
.Y
- 1, Console
->Size
.X
- 1);
1019 ConioDrawRegion(Console
, &Region
);
1024 ConioDeleteConsole(Object_t
*Object
)
1026 PCSRSS_CONSOLE Console
= (PCSRSS_CONSOLE
) Object
;
1027 ConsoleInput
*Event
;
1029 DPRINT("ConioDeleteConsole\n");
1031 /* Drain input event queue */
1032 while (Console
->InputEvents
.Flink
!= &Console
->InputEvents
)
1034 Event
= (ConsoleInput
*) Console
->InputEvents
.Flink
;
1035 Console
->InputEvents
.Flink
= Console
->InputEvents
.Flink
->Flink
;
1036 Console
->InputEvents
.Flink
->Flink
->Blink
= &Console
->InputEvents
;
1037 HeapFree(Win32CsrApiHeap
, 0, Event
);
1040 if (0 == InterlockedDecrement(&Console
->ActiveBuffer
->Header
.ReferenceCount
))
1042 ConioDeleteScreenBuffer((Object_t
*) Console
->ActiveBuffer
);
1045 Console
->ActiveBuffer
= NULL
;
1046 ConioCleanupConsole(Console
);
1048 CloseHandle(Console
->ActiveEvent
);
1049 DeleteCriticalSection(&Console
->Header
.Lock
);
1050 RtlFreeUnicodeString(&Console
->Title
);
1051 HeapFree(Win32CsrApiHeap
, 0, Console
);
1055 CsrInitConsoleSupport(VOID
)
1057 DPRINT("CSR: CsrInitConsoleSupport()\n");
1059 /* Should call LoadKeyboardLayout */
1062 STATIC VOID FASTCALL
1063 ConioProcessChar(PCSRSS_CONSOLE Console
,
1064 ConsoleInput
*KeyEventRecord
)
1067 BOOL bClientWake
= FALSE
;
1068 ConsoleInput
*TempInput
;
1070 /* process Ctrl-C and Ctrl-Break */
1071 if (Console
->Mode
& ENABLE_PROCESSED_INPUT
&&
1072 KeyEventRecord
->InputEvent
.Event
.KeyEvent
.bKeyDown
&&
1073 ((KeyEventRecord
->InputEvent
.Event
.KeyEvent
.wVirtualKeyCode
== VK_PAUSE
) ||
1074 (KeyEventRecord
->InputEvent
.Event
.KeyEvent
.wVirtualKeyCode
== 'C')) &&
1075 (KeyEventRecord
->InputEvent
.Event
.KeyEvent
.dwControlKeyState
& (LEFT_CTRL_PRESSED
| RIGHT_CTRL_PRESSED
)))
1077 PCSRSS_PROCESS_DATA current
;
1078 PLIST_ENTRY current_entry
;
1079 DPRINT1("Console_Api Ctrl-C\n");
1080 current_entry
= Console
->ProcessList
.Flink
;
1081 while (current_entry
!= &Console
->ProcessList
)
1083 current
= CONTAINING_RECORD(current_entry
, CSRSS_PROCESS_DATA
, ProcessEntry
);
1084 current_entry
= current_entry
->Flink
;
1085 ConioConsoleCtrlEvent((DWORD
)CTRL_C_EVENT
, current
);
1087 HeapFree(Win32CsrApiHeap
, 0, KeyEventRecord
);
1091 if (0 != (KeyEventRecord
->InputEvent
.Event
.KeyEvent
.dwControlKeyState
1092 & (RIGHT_ALT_PRESSED
| LEFT_ALT_PRESSED
))
1093 && (VK_UP
== KeyEventRecord
->InputEvent
.Event
.KeyEvent
.wVirtualKeyCode
1094 || VK_DOWN
== KeyEventRecord
->InputEvent
.Event
.KeyEvent
.wVirtualKeyCode
))
1096 if (KeyEventRecord
->InputEvent
.Event
.KeyEvent
.bKeyDown
)
1098 /* scroll up or down */
1099 if (NULL
== Console
)
1101 DPRINT1("No Active Console!\n");
1102 HeapFree(Win32CsrApiHeap
, 0, KeyEventRecord
);
1105 if (VK_UP
== KeyEventRecord
->InputEvent
.Event
.KeyEvent
.wVirtualKeyCode
)
1107 /* only scroll up if there is room to scroll up into */
1108 if (Console
->ActiveBuffer
->ShowY
!= ((Console
->ActiveBuffer
->CurrentY
+ 1) %
1109 Console
->ActiveBuffer
->MaxY
))
1111 Console
->ActiveBuffer
->ShowY
= (Console
->ActiveBuffer
->ShowY
+
1112 Console
->ActiveBuffer
->MaxY
- 1) %
1113 Console
->ActiveBuffer
->MaxY
;
1116 else if (Console
->ActiveBuffer
->ShowY
!= Console
->ActiveBuffer
->CurrentY
)
1117 /* only scroll down if there is room to scroll down into */
1119 if (Console
->ActiveBuffer
->ShowY
% Console
->ActiveBuffer
->MaxY
!=
1120 Console
->ActiveBuffer
->CurrentY
)
1122 if (((Console
->ActiveBuffer
->CurrentY
+ 1) % Console
->ActiveBuffer
->MaxY
) !=
1123 (Console
->ActiveBuffer
->ShowY
+ Console
->ActiveBuffer
->MaxY
) %
1124 Console
->ActiveBuffer
->MaxY
)
1126 Console
->ActiveBuffer
->ShowY
= (Console
->ActiveBuffer
->ShowY
+ 1) %
1127 Console
->ActiveBuffer
->MaxY
;
1131 ConioDrawConsole(Console
);
1133 HeapFree(Win32CsrApiHeap
, 0, KeyEventRecord
);
1136 if (NULL
== Console
)
1138 DPRINT1("No Active Console!\n");
1139 HeapFree(Win32CsrApiHeap
, 0, KeyEventRecord
);
1143 if (0 != (Console
->Mode
& (ENABLE_PROCESSED_INPUT
| ENABLE_LINE_INPUT
)))
1145 switch(KeyEventRecord
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
)
1148 /* first add the \r */
1149 KeyEventRecord
->InputEvent
.EventType
= KEY_EVENT
;
1150 updown
= KeyEventRecord
->InputEvent
.Event
.KeyEvent
.bKeyDown
;
1151 KeyEventRecord
->Echoed
= FALSE
;
1152 KeyEventRecord
->InputEvent
.Event
.KeyEvent
.wVirtualKeyCode
= VK_RETURN
;
1153 KeyEventRecord
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
= '\r';
1154 InsertTailList(&Console
->InputEvents
, &KeyEventRecord
->ListEntry
);
1155 Console
->WaitingChars
++;
1156 KeyEventRecord
= HeapAlloc(Win32CsrApiHeap
, 0, sizeof(ConsoleInput
));
1157 if (NULL
== KeyEventRecord
)
1159 DPRINT1("Failed to allocate KeyEventRecord\n");
1162 KeyEventRecord
->InputEvent
.EventType
= KEY_EVENT
;
1163 KeyEventRecord
->InputEvent
.Event
.KeyEvent
.bKeyDown
= updown
;
1164 KeyEventRecord
->InputEvent
.Event
.KeyEvent
.wVirtualKeyCode
= 0;
1165 KeyEventRecord
->InputEvent
.Event
.KeyEvent
.wVirtualScanCode
= 0;
1166 KeyEventRecord
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
= '\n';
1167 KeyEventRecord
->Fake
= TRUE
;
1171 /* add event to the queue */
1172 InsertTailList(&Console
->InputEvents
, &KeyEventRecord
->ListEntry
);
1173 Console
->WaitingChars
++;
1174 /* if line input mode is enabled, only wake the client on enter key down */
1175 if (0 == (Console
->Mode
& ENABLE_LINE_INPUT
)
1176 || Console
->EarlyReturn
1177 || ('\n' == KeyEventRecord
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
1178 && KeyEventRecord
->InputEvent
.Event
.KeyEvent
.bKeyDown
))
1180 if ('\n' == KeyEventRecord
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
)
1182 Console
->WaitingLines
++;
1185 SetEvent(Console
->ActiveEvent
);
1187 KeyEventRecord
->Echoed
= FALSE
;
1188 if (0 != (Console
->Mode
& (ENABLE_PROCESSED_INPUT
| ENABLE_LINE_INPUT
))
1189 && '\b' == KeyEventRecord
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
1190 && KeyEventRecord
->InputEvent
.Event
.KeyEvent
.bKeyDown
)
1192 /* walk the input queue looking for a char to backspace */
1193 for (TempInput
= (ConsoleInput
*) Console
->InputEvents
.Blink
;
1194 TempInput
!= (ConsoleInput
*) &Console
->InputEvents
1195 && (KEY_EVENT
== TempInput
->InputEvent
.EventType
1196 || ! TempInput
->InputEvent
.Event
.KeyEvent
.bKeyDown
1197 || '\b' == TempInput
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
);
1198 TempInput
= (ConsoleInput
*) TempInput
->ListEntry
.Blink
)
1202 /* if we found one, delete it, otherwise, wake the client */
1203 if (TempInput
!= (ConsoleInput
*) &Console
->InputEvents
)
1205 /* delete previous key in queue, maybe echo backspace to screen, and do not place backspace on queue */
1206 RemoveEntryList(&TempInput
->ListEntry
);
1207 if (TempInput
->Echoed
)
1209 ConioWriteConsole(Console
, Console
->ActiveBuffer
,
1210 &KeyEventRecord
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
,
1213 HeapFree(Win32CsrApiHeap
, 0, TempInput
);
1214 RemoveEntryList(&KeyEventRecord
->ListEntry
);
1215 HeapFree(Win32CsrApiHeap
, 0, KeyEventRecord
);
1216 Console
->WaitingChars
-= 2;
1220 SetEvent(Console
->ActiveEvent
);
1225 /* echo chars if we are supposed to and client is waiting for some */
1226 if (0 != (Console
->Mode
& ENABLE_ECHO_INPUT
) && Console
->EchoCount
1227 && KeyEventRecord
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
1228 && KeyEventRecord
->InputEvent
.Event
.KeyEvent
.bKeyDown
1229 && '\r' != KeyEventRecord
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
)
1231 /* mark the char as already echoed */
1232 ConioWriteConsole(Console
, Console
->ActiveBuffer
,
1233 &KeyEventRecord
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
,
1235 Console
->EchoCount
--;
1236 KeyEventRecord
->Echoed
= TRUE
;
1240 /* Console->WaitingChars++; */
1241 if (bClientWake
|| 0 == (Console
->Mode
& ENABLE_LINE_INPUT
))
1243 SetEvent(Console
->ActiveEvent
);
1247 STATIC DWORD FASTCALL
1248 ConioGetShiftState(PBYTE KeyState
)
1252 if (KeyState
[VK_CAPITAL
] & 1)
1253 ssOut
|= CAPSLOCK_ON
;
1255 if (KeyState
[VK_NUMLOCK
] & 1)
1256 ssOut
|= NUMLOCK_ON
;
1258 if (KeyState
[VK_SCROLL
] & 1)
1259 ssOut
|= SCROLLLOCK_ON
;
1261 if (KeyState
[VK_SHIFT
] & 0x80)
1262 ssOut
|= SHIFT_PRESSED
;
1264 if (KeyState
[VK_LCONTROL
] & 0x80)
1265 ssOut
|= LEFT_CTRL_PRESSED
;
1266 if (KeyState
[VK_RCONTROL
] & 0x80)
1267 ssOut
|= RIGHT_CTRL_PRESSED
;
1269 if (KeyState
[VK_LMENU
] & 0x80)
1270 ssOut
|= LEFT_ALT_PRESSED
;
1271 if (KeyState
[VK_RMENU
] & 0x80)
1272 ssOut
|= RIGHT_ALT_PRESSED
;
1278 ConioProcessKey(MSG
*msg
, PCSRSS_CONSOLE Console
, BOOL TextMode
)
1280 static BYTE KeyState
[256] = { 0 };
1281 /* MSDN mentions that you should use the last virtual key code received
1282 * when putting a virtual key identity to a WM_CHAR message since multiple
1283 * or translated keys may be involved. */
1284 static UINT LastVirtualKey
= 0;
1286 ConsoleInput
*ConInRec
;
1290 UINT VirtualKeyCode
;
1291 UINT VirtualScanCode
;
1294 ULONG ResultSize
= 0;
1297 VirtualScanCode
= (msg
->lParam
>> 16) & 0xff;
1298 Down
= msg
->message
== WM_KEYDOWN
|| msg
->message
== WM_CHAR
||
1299 msg
->message
== WM_SYSKEYDOWN
|| msg
->message
== WM_SYSCHAR
;
1301 GetKeyboardState(KeyState
);
1302 ShiftState
= ConioGetShiftState(KeyState
);
1304 if (msg
->message
== WM_CHAR
|| msg
->message
== WM_SYSCHAR
)
1306 VirtualKeyCode
= LastVirtualKey
;
1307 UnicodeChar
= msg
->wParam
;
1314 VirtualKeyCode
= msg
->wParam
;
1315 RetChars
= ToUnicodeEx(VirtualKeyCode
,
1322 UnicodeChar
= (1 == RetChars
? Chars
[0] : 0);
1325 if (0 == ResultSize
)
1330 er
.EventType
= KEY_EVENT
;
1331 er
.Event
.KeyEvent
.bKeyDown
= Down
;
1332 er
.Event
.KeyEvent
.wRepeatCount
= RepeatCount
;
1333 er
.Event
.KeyEvent
.uChar
.UnicodeChar
= UnicodeChar
;
1334 er
.Event
.KeyEvent
.dwControlKeyState
= ShiftState
;
1335 er
.Event
.KeyEvent
.wVirtualKeyCode
= VirtualKeyCode
;
1336 er
.Event
.KeyEvent
.wVirtualScanCode
= VirtualScanCode
;
1340 if (0 != (ShiftState
& (RIGHT_ALT_PRESSED
| LEFT_ALT_PRESSED
))
1341 && VK_TAB
== VirtualKeyCode
)
1345 TuiSwapConsole(ShiftState
& SHIFT_PRESSED
? -1 : 1);
1350 else if (VK_MENU
== VirtualKeyCode
&& ! Down
)
1352 if (TuiSwapConsole(0))
1359 if (NULL
== Console
)
1364 ConInRec
= HeapAlloc(Win32CsrApiHeap
, 0, sizeof(ConsoleInput
));
1366 if (NULL
== ConInRec
)
1371 ConInRec
->InputEvent
= er
;
1372 ConInRec
->Fake
= UnicodeChar
&&
1373 (msg
->message
!= WM_CHAR
&& msg
->message
!= WM_SYSCHAR
&&
1374 msg
->message
!= WM_KEYUP
&& msg
->message
!= WM_SYSKEYUP
);
1375 ConInRec
->NotChar
= (msg
->message
!= WM_CHAR
&& msg
->message
!= WM_SYSCHAR
);
1376 ConInRec
->Echoed
= FALSE
;
1377 if (ConInRec
->NotChar
)
1378 LastVirtualKey
= msg
->wParam
;
1380 DPRINT ("csrss: %s %s %s %s %02x %02x '%c' %04x\n",
1381 Down
? "down" : "up ",
1382 (msg
->message
== WM_CHAR
|| msg
->message
== WM_SYSCHAR
) ?
1384 ConInRec
->Fake
? "fake" : "real",
1385 ConInRec
->NotChar
? "notc" : "char",
1388 (AsciiChar
>= ' ') ? AsciiChar
: '.',
1391 if (! ConInRec
->Fake
|| ! ConInRec
->NotChar
)
1393 /* FIXME - convert to ascii */
1394 ConioProcessChar(Console
, ConInRec
);
1398 HeapFree(Win32CsrApiHeap
, 0, ConInRec
);
1403 Console_Api (PVOID unused
)
1405 /* keep reading events from the keyboard and stuffing them into the current
1406 console's input queue */
1409 /* This call establishes our message queue */
1410 PeekMessageW(&msg
, 0, 0, 0, PM_NOREMOVE
);
1411 /* This call registers our message queue */
1412 PrivateCsrssRegisterPrimitive();
1413 /* This call turns on the input system in win32k */
1414 PrivateCsrssAcquireOrReleaseInputOwnership(FALSE
);
1418 GetMessageW(&msg
, 0, 0, 0);
1419 TranslateMessage(&msg
);
1421 if (msg
.message
== WM_CHAR
|| msg
.message
== WM_SYSCHAR
||
1422 msg
.message
== WM_KEYDOWN
|| msg
.message
== WM_KEYUP
||
1423 msg
.message
== WM_SYSKEYDOWN
|| msg
.message
== WM_SYSKEYUP
)
1425 ConioProcessKey(&msg
, TuiGetFocusConsole(), TRUE
);
1429 PrivateCsrssAcquireOrReleaseInputOwnership(TRUE
);
1433 CSR_API(CsrGetScreenBufferInfo
)
1436 PCSRSS_SCREEN_BUFFER Buff
;
1437 PCONSOLE_SCREEN_BUFFER_INFO pInfo
;
1439 DPRINT("CsrGetScreenBufferInfo\n");
1441 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
1442 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
1444 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.ScreenBufferInfoRequest
.ConsoleHandle
, &Buff
);
1445 if (! NT_SUCCESS(Status
))
1447 return Request
->Status
= Status
;
1449 pInfo
= &Request
->Data
.ScreenBufferInfoRequest
.Info
;
1450 pInfo
->dwSize
.X
= Buff
->MaxX
;
1451 pInfo
->dwSize
.Y
= Buff
->MaxY
;
1452 pInfo
->dwCursorPosition
.X
= Buff
->CurrentX
- Buff
->ShowX
;
1453 pInfo
->dwCursorPosition
.Y
= (Buff
->CurrentY
+ Buff
->MaxY
- Buff
->ShowY
) % Buff
->MaxY
;
1454 pInfo
->wAttributes
= Buff
->DefaultAttrib
;
1455 pInfo
->srWindow
.Left
= 0;
1456 pInfo
->srWindow
.Right
= Buff
->MaxX
- 1;
1457 pInfo
->srWindow
.Top
= 0;
1458 pInfo
->srWindow
.Bottom
= Buff
->MaxY
- 1;
1459 pInfo
->dwMaximumWindowSize
.X
= Buff
->MaxX
;
1460 pInfo
->dwMaximumWindowSize
.Y
= Buff
->MaxY
;
1461 ConioUnlockScreenBuffer(Buff
);
1463 Request
->Status
= STATUS_SUCCESS
;
1465 return Request
->Status
;
1468 CSR_API(CsrSetCursor
)
1471 PCSRSS_CONSOLE Console
;
1472 PCSRSS_SCREEN_BUFFER Buff
;
1473 LONG OldCursorX
, OldCursorY
;
1474 LONG NewCursorX
, NewCursorY
;
1476 DPRINT("CsrSetCursor\n");
1478 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
1479 if (! NT_SUCCESS(Status
))
1481 return Request
->Status
= Status
;
1484 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
1485 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
1487 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.SetCursorRequest
.ConsoleHandle
, &Buff
);
1488 if (! NT_SUCCESS(Status
))
1490 if (NULL
!= Console
)
1492 ConioUnlockConsole(Console
);
1494 return Request
->Status
= Status
;
1497 NewCursorX
= Request
->Data
.SetCursorRequest
.Position
.X
;
1498 NewCursorY
= Request
->Data
.SetCursorRequest
.Position
.Y
;
1499 if (NewCursorX
< 0 || NewCursorX
>= Buff
->MaxX
||
1500 NewCursorY
< 0 || NewCursorY
>= Buff
->MaxY
)
1502 ConioUnlockScreenBuffer(Buff
);
1503 if (NULL
!= Console
)
1505 ConioUnlockConsole(Console
);
1507 return Request
->Status
= STATUS_INVALID_PARAMETER
;
1509 ConioPhysicalToLogical(Buff
, Buff
->CurrentX
, Buff
->CurrentY
, &OldCursorX
, &OldCursorY
);
1510 Buff
->CurrentX
= NewCursorX
+ Buff
->ShowX
;
1511 Buff
->CurrentY
= (NewCursorY
+ Buff
->ShowY
) % Buff
->MaxY
;
1512 if (NULL
!= Console
&& Buff
== Console
->ActiveBuffer
)
1514 if (! ConioSetScreenInfo(Console
, Buff
, OldCursorX
, OldCursorY
))
1516 ConioUnlockScreenBuffer(Buff
);
1517 if (NULL
!= Console
)
1519 ConioUnlockConsole(Console
);
1521 return Request
->Status
= STATUS_UNSUCCESSFUL
;
1525 ConioUnlockScreenBuffer(Buff
);
1526 if (NULL
!= Console
)
1528 ConioUnlockConsole(Console
);
1531 return Request
->Status
= STATUS_SUCCESS
;
1534 STATIC FASTCALL VOID
1535 ConioComputeUpdateRect(PCSRSS_SCREEN_BUFFER Buff
, RECT
*UpdateRect
, COORD
*Start
, UINT Length
)
1537 if (Buff
->MaxX
<= Start
->X
+ Length
)
1539 UpdateRect
->left
= 0;
1543 UpdateRect
->left
= Start
->X
;
1545 if (Buff
->MaxX
<= Start
->X
+ Length
)
1547 UpdateRect
->right
= Buff
->MaxX
- 1;
1551 UpdateRect
->right
= Start
->X
+ Length
- 1;
1553 UpdateRect
->top
= Start
->Y
;
1554 UpdateRect
->bottom
= Start
->Y
+ (Start
->X
+ Length
- 1) / Buff
->MaxX
;
1555 if (Buff
->MaxY
<= UpdateRect
->bottom
)
1557 UpdateRect
->bottom
= Buff
->MaxY
- 1;
1561 CSR_API(CsrWriteConsoleOutputChar
)
1564 PCHAR String
, tmpString
= NULL
;
1566 PCSRSS_CONSOLE Console
;
1567 PCSRSS_SCREEN_BUFFER Buff
;
1568 DWORD X
, Y
, Length
, CharSize
, Written
= 0;
1571 DPRINT("CsrWriteConsoleOutputChar\n");
1573 CharSize
= (Request
->Data
.WriteConsoleOutputCharRequest
.Unicode
? sizeof(WCHAR
) : sizeof(CHAR
));
1575 if (Request
->Header
.u1
.s1
.TotalLength
1576 < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR
)
1577 + (Request
->Data
.WriteConsoleOutputCharRequest
.Length
* CharSize
))
1579 DPRINT1("Invalid request size\n");
1580 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
1581 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
1582 return Request
->Status
= STATUS_INVALID_PARAMETER
;
1585 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
1586 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
1587 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
1588 if (NT_SUCCESS(Status
))
1590 if(Request
->Data
.WriteConsoleOutputCharRequest
.Unicode
)
1592 Length
= WideCharToMultiByte(Console
->CodePage
, 0,
1593 (PWCHAR
)Request
->Data
.WriteConsoleOutputCharRequest
.String
,
1594 Request
->Data
.WriteConsoleOutputCharRequest
.Length
,
1595 NULL
, 0, NULL
, NULL
);
1596 tmpString
= String
= RtlAllocateHeap(GetProcessHeap(), 0, Length
);
1599 WideCharToMultiByte(Console
->CodePage
, 0,
1600 (PWCHAR
)Request
->Data
.WriteConsoleOutputCharRequest
.String
,
1601 Request
->Data
.WriteConsoleOutputCharRequest
.Length
,
1602 String
, Length
, NULL
, NULL
);
1606 Status
= STATUS_NO_MEMORY
;
1611 String
= (PCHAR
)Request
->Data
.WriteConsoleOutputCharRequest
.String
;
1616 Status
= ConioLockScreenBuffer(ProcessData
,
1617 Request
->Data
.WriteConsoleOutputCharRequest
.ConsoleHandle
,
1619 if (NT_SUCCESS(Status
))
1621 X
= Request
->Data
.WriteConsoleOutputCharRequest
.Coord
.X
+ Buff
->ShowX
;
1622 Y
= (Request
->Data
.WriteConsoleOutputCharRequest
.Coord
.Y
+ Buff
->ShowY
) % Buff
->MaxY
;
1623 Length
= Request
->Data
.WriteConsoleOutputCharRequest
.Length
;
1624 Buffer
= &Buff
->Buffer
[2 * (Y
* Buff
->MaxX
+ X
)];
1627 *Buffer
= *String
++;
1630 if (++X
== Buff
->MaxX
)
1632 if (++Y
== Buff
->MaxY
)
1635 Buffer
= Buff
->Buffer
;
1640 if (NULL
!= Console
&& Buff
== Console
->ActiveBuffer
)
1642 ConioComputeUpdateRect(Buff
, &UpdateRect
, &Request
->Data
.WriteConsoleOutputCharRequest
.Coord
,
1643 Request
->Data
.WriteConsoleOutputCharRequest
.Length
);
1644 ConioDrawRegion(Console
, &UpdateRect
);
1647 Request
->Data
.WriteConsoleOutputCharRequest
.EndCoord
.X
= X
- Buff
->ShowX
;
1648 Request
->Data
.WriteConsoleOutputCharRequest
.EndCoord
.Y
= (Y
+ Buff
->MaxY
- Buff
->ShowY
) % Buff
->MaxY
;
1650 ConioUnlockScreenBuffer(Buff
);
1652 if (Request
->Data
.WriteConsoleRequest
.Unicode
)
1654 RtlFreeHeap(GetProcessHeap(), 0, tmpString
);
1657 if (NULL
!= Console
)
1659 ConioUnlockConsole(Console
);
1662 Request
->Data
.WriteConsoleOutputCharRequest
.NrCharactersWritten
= Written
;
1663 return Request
->Status
= Status
;
1666 CSR_API(CsrFillOutputChar
)
1669 PCSRSS_CONSOLE Console
;
1670 PCSRSS_SCREEN_BUFFER Buff
;
1671 DWORD X
, Y
, Length
, Written
= 0;
1676 DPRINT("CsrFillOutputChar\n");
1678 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
1679 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
1681 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
1682 if (! NT_SUCCESS(Status
))
1684 return Request
->Status
= Status
;
1687 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.FillOutputRequest
.ConsoleHandle
, &Buff
);
1688 if (! NT_SUCCESS(Status
))
1690 if (NULL
!= Console
)
1692 ConioUnlockConsole(Console
);
1694 return Request
->Status
= Status
;
1697 X
= Request
->Data
.FillOutputRequest
.Position
.X
+ Buff
->ShowX
;
1698 Y
= (Request
->Data
.FillOutputRequest
.Position
.Y
+ Buff
->ShowY
) % Buff
->MaxY
;
1699 Buffer
= &Buff
->Buffer
[2 * (Y
* Buff
->MaxX
+ X
)];
1700 if(Request
->Data
.FillOutputRequest
.Unicode
)
1701 ConsoleUnicodeCharToAnsiChar(Console
, &Char
, &Request
->Data
.FillOutputRequest
.Char
.UnicodeChar
);
1703 Char
= Request
->Data
.FillOutputRequest
.Char
.AsciiChar
;
1704 Length
= Request
->Data
.FillOutputRequest
.Length
;
1710 if (++X
== Buff
->MaxX
)
1712 if (++Y
== Buff
->MaxY
)
1715 Buffer
= Buff
->Buffer
;
1721 if (NULL
!= Console
&& Buff
== Console
->ActiveBuffer
)
1723 ConioComputeUpdateRect(Buff
, &UpdateRect
, &Request
->Data
.FillOutputRequest
.Position
,
1724 Request
->Data
.FillOutputRequest
.Length
);
1725 ConioDrawRegion(Console
, &UpdateRect
);
1728 ConioUnlockScreenBuffer(Buff
);
1729 if (NULL
!= Console
)
1731 ConioUnlockConsole(Console
);
1733 Length
= Request
->Data
.FillOutputRequest
.Length
;
1734 Request
->Data
.FillOutputRequest
.NrCharactersWritten
= Length
;
1735 return Request
->Status
;
1738 CSR_API(CsrReadInputEvent
)
1740 PLIST_ENTRY CurrentEntry
;
1741 PCSRSS_CONSOLE Console
;
1743 BOOLEAN Done
= FALSE
;
1744 ConsoleInput
*Input
;
1746 DPRINT("CsrReadInputEvent\n");
1748 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
1749 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
1750 Request
->Data
.ReadInputRequest
.Event
= ProcessData
->ConsoleEvent
;
1752 Status
= ConioLockConsole(ProcessData
, Request
->Data
.ReadInputRequest
.ConsoleHandle
, &Console
);
1753 if (! NT_SUCCESS(Status
))
1755 return Request
->Status
= Status
;
1758 /* only get input if there is any */
1759 CurrentEntry
= Console
->InputEvents
.Flink
;
1760 while (CurrentEntry
!= &Console
->InputEvents
)
1762 Input
= CONTAINING_RECORD(CurrentEntry
, ConsoleInput
, ListEntry
);
1763 CurrentEntry
= CurrentEntry
->Flink
;
1765 if (Done
&& !Input
->Fake
)
1767 Request
->Data
.ReadInputRequest
.MoreEvents
= TRUE
;
1771 RemoveEntryList(&Input
->ListEntry
);
1773 if (!Done
&& !Input
->Fake
)
1775 Request
->Data
.ReadInputRequest
.Input
= Input
->InputEvent
;
1776 if (Request
->Data
.ReadInputRequest
.Unicode
== FALSE
)
1778 ConioInputEventToAnsi(Console
, &Request
->Data
.ReadInputRequest
.Input
);
1783 if (Input
->InputEvent
.EventType
== KEY_EVENT
)
1785 if (0 != (Console
->Mode
& ENABLE_LINE_INPUT
)
1786 && Input
->InputEvent
.Event
.KeyEvent
.bKeyDown
1787 && '\r' == Input
->InputEvent
.Event
.KeyEvent
.uChar
.AsciiChar
)
1789 Console
->WaitingLines
--;
1791 Console
->WaitingChars
--;
1793 HeapFree(Win32CsrApiHeap
, 0, Input
);
1798 Status
= STATUS_SUCCESS
;
1799 Console
->EarlyReturn
= FALSE
;
1803 Status
= STATUS_PENDING
;
1804 Console
->EarlyReturn
= TRUE
; /* mark for early return */
1807 if (IsListEmpty(&Console
->InputEvents
))
1809 ResetEvent(Console
->ActiveEvent
);
1812 ConioUnlockConsole(Console
);
1814 return Request
->Status
= Status
;
1817 CSR_API(CsrWriteConsoleOutputAttrib
)
1819 PCSRSS_CONSOLE Console
;
1820 PCSRSS_SCREEN_BUFFER Buff
;
1827 DPRINT("CsrWriteConsoleOutputAttrib\n");
1829 if (Request
->Header
.u1
.s1
.TotalLength
1830 < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB
)
1831 + Request
->Data
.WriteConsoleOutputAttribRequest
.Length
* sizeof(WORD
))
1833 DPRINT1("Invalid request size\n");
1834 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
1835 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
1836 return Request
->Status
= STATUS_INVALID_PARAMETER
;
1839 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
1840 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
1841 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
1842 if (! NT_SUCCESS(Status
))
1844 return Request
->Status
= Status
;
1847 Status
= ConioLockScreenBuffer(ProcessData
,
1848 Request
->Data
.WriteConsoleOutputAttribRequest
.ConsoleHandle
,
1850 if (! NT_SUCCESS(Status
))
1852 if (NULL
!= Console
)
1854 ConioUnlockConsole(Console
);
1856 return Request
->Status
= Status
;
1859 X
= Request
->Data
.WriteConsoleOutputAttribRequest
.Coord
.X
+ Buff
->ShowX
;
1860 Y
= (Request
->Data
.WriteConsoleOutputAttribRequest
.Coord
.Y
+ Buff
->ShowY
) % Buff
->MaxY
;
1861 Length
= Request
->Data
.WriteConsoleOutputAttribRequest
.Length
;
1862 Buffer
= &Buff
->Buffer
[2 * (Y
* Buff
->MaxX
+ X
) + 1];
1863 Attribute
= Request
->Data
.WriteConsoleOutputAttribRequest
.Attribute
;
1866 *Buffer
= (UCHAR
)(*Attribute
++);
1868 if (++X
== Buff
->MaxX
)
1870 if (++Y
== Buff
->MaxY
)
1873 Buffer
= Buff
->Buffer
+ 1;
1879 if (NULL
!= Console
&& Buff
== Console
->ActiveBuffer
)
1881 ConioComputeUpdateRect(Buff
, &UpdateRect
, &Request
->Data
.WriteConsoleOutputAttribRequest
.Coord
,
1882 Request
->Data
.WriteConsoleOutputAttribRequest
.Length
);
1883 ConioDrawRegion(Console
, &UpdateRect
);
1886 if (NULL
!= Console
)
1888 ConioUnlockConsole(Console
);
1891 Request
->Data
.WriteConsoleOutputAttribRequest
.EndCoord
.X
= Buff
->CurrentX
- Buff
->ShowX
;
1892 Request
->Data
.WriteConsoleOutputAttribRequest
.EndCoord
.Y
= (Buff
->CurrentY
+ Buff
->MaxY
- Buff
->ShowY
) % Buff
->MaxY
;
1894 ConioUnlockScreenBuffer(Buff
);
1896 return Request
->Status
= STATUS_SUCCESS
;
1899 CSR_API(CsrFillOutputAttrib
)
1901 PCSRSS_SCREEN_BUFFER Buff
;
1907 PCSRSS_CONSOLE Console
;
1909 DPRINT("CsrFillOutputAttrib\n");
1911 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
1912 if (! NT_SUCCESS(Status
))
1914 return Request
->Status
= Status
;
1917 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
1918 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
1919 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.FillOutputAttribRequest
.ConsoleHandle
, &Buff
);
1920 if (! NT_SUCCESS(Status
))
1922 if (NULL
!= Console
)
1924 ConioUnlockConsole(Console
);
1926 return Request
->Status
= Status
;
1929 X
= Request
->Data
.FillOutputAttribRequest
.Coord
.X
+ Buff
->ShowX
;
1930 Y
= (Request
->Data
.FillOutputAttribRequest
.Coord
.Y
+ Buff
->ShowY
) % Buff
->MaxY
;
1931 Length
= Request
->Data
.FillOutputAttribRequest
.Length
;
1932 Attr
= Request
->Data
.FillOutputAttribRequest
.Attribute
;
1933 Buffer
= &Buff
->Buffer
[(Y
* Buff
->MaxX
* 2) + (X
* 2) + 1];
1938 if (++X
== Buff
->MaxX
)
1940 if (++Y
== Buff
->MaxY
)
1943 Buffer
= Buff
->Buffer
+ 1;
1949 if (NULL
!= Console
&& Buff
== Console
->ActiveBuffer
)
1951 ConioComputeUpdateRect(Buff
, &UpdateRect
, &Request
->Data
.FillOutputAttribRequest
.Coord
,
1952 Request
->Data
.FillOutputAttribRequest
.Length
);
1953 ConioDrawRegion(Console
, &UpdateRect
);
1956 ConioUnlockScreenBuffer(Buff
);
1957 if (NULL
!= Console
)
1959 ConioUnlockConsole(Console
);
1962 return Request
->Status
= STATUS_SUCCESS
;
1966 CSR_API(CsrGetCursorInfo
)
1968 PCSRSS_SCREEN_BUFFER Buff
;
1971 DPRINT("CsrGetCursorInfo\n");
1973 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
1974 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
1976 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.GetCursorInfoRequest
.ConsoleHandle
, &Buff
);
1977 if (! NT_SUCCESS(Status
))
1979 return Request
->Status
= Status
;
1981 Request
->Data
.GetCursorInfoRequest
.Info
= Buff
->CursorInfo
;
1982 ConioUnlockScreenBuffer(Buff
);
1984 return Request
->Status
= STATUS_SUCCESS
;
1987 CSR_API(CsrSetCursorInfo
)
1989 PCSRSS_CONSOLE Console
;
1990 PCSRSS_SCREEN_BUFFER Buff
;
1995 DPRINT("CsrSetCursorInfo\n");
1997 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
1998 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2000 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
2001 if (! NT_SUCCESS(Status
))
2003 return Request
->Status
= Status
;
2006 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.SetCursorInfoRequest
.ConsoleHandle
, &Buff
);
2007 if (! NT_SUCCESS(Status
))
2009 if (NULL
!= Console
)
2011 ConioUnlockConsole(Console
);
2013 return Request
->Status
= Status
;
2016 Size
= Request
->Data
.SetCursorInfoRequest
.Info
.dwSize
;
2017 Visible
= Request
->Data
.SetCursorInfoRequest
.Info
.bVisible
;
2027 if (Size
!= Buff
->CursorInfo
.dwSize
2028 || (Visible
&& ! Buff
->CursorInfo
.bVisible
) || (! Visible
&& Buff
->CursorInfo
.bVisible
))
2030 Buff
->CursorInfo
.dwSize
= Size
;
2031 Buff
->CursorInfo
.bVisible
= Visible
;
2033 if (NULL
!= Console
&& ! ConioSetCursorInfo(Console
, Buff
))
2035 ConioUnlockScreenBuffer(Buff
);
2036 ConioUnlockConsole(Console
);
2037 return Request
->Status
= STATUS_UNSUCCESSFUL
;
2041 ConioUnlockScreenBuffer(Buff
);
2042 if (NULL
!= Console
)
2044 ConioUnlockConsole(Console
);
2047 return Request
->Status
= STATUS_SUCCESS
;
2050 CSR_API(CsrSetTextAttrib
)
2053 PCSRSS_CONSOLE Console
;
2054 PCSRSS_SCREEN_BUFFER Buff
;
2055 LONG OldCursorX
, OldCursorY
;
2057 DPRINT("CsrSetTextAttrib\n");
2059 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
2060 if (! NT_SUCCESS(Status
))
2062 return Request
->Status
= Status
;
2065 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.SetCursorRequest
.ConsoleHandle
, &Buff
);
2066 if (! NT_SUCCESS(Status
))
2068 if (NULL
!= Console
)
2070 ConioUnlockConsole(Console
);
2072 return Request
->Status
= Status
;
2075 ConioPhysicalToLogical(Buff
, Buff
->CurrentX
, Buff
->CurrentY
, &OldCursorX
, &OldCursorY
);
2077 Buff
->DefaultAttrib
= Request
->Data
.SetAttribRequest
.Attrib
;
2078 if (NULL
!= Console
&& Buff
== Console
->ActiveBuffer
)
2080 if (! ConioSetScreenInfo(Console
, Buff
, OldCursorX
, OldCursorY
))
2082 ConioUnlockScreenBuffer(Buff
);
2083 ConioUnlockConsole(Console
);
2084 return Request
->Status
= STATUS_UNSUCCESSFUL
;
2088 ConioUnlockScreenBuffer(Buff
);
2089 if (NULL
!= Console
)
2091 ConioUnlockConsole(Console
);
2094 return Request
->Status
= STATUS_SUCCESS
;
2097 CSR_API(CsrSetConsoleMode
)
2100 PCSRSS_CONSOLE Console
;
2101 PCSRSS_SCREEN_BUFFER Buff
;
2103 DPRINT("CsrSetConsoleMode\n");
2105 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2106 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2107 Status
= Win32CsrGetObject(ProcessData
,
2108 Request
->Data
.SetConsoleModeRequest
.ConsoleHandle
,
2109 (Object_t
**) &Console
);
2110 if (! NT_SUCCESS(Status
))
2112 return Request
->Status
= Status
;
2115 Buff
= (PCSRSS_SCREEN_BUFFER
)Console
;
2116 if (CONIO_CONSOLE_MAGIC
== Console
->Header
.Type
)
2118 Console
->Mode
= Request
->Data
.SetConsoleModeRequest
.Mode
& CONSOLE_INPUT_MODE_VALID
;
2120 else if (CONIO_SCREEN_BUFFER_MAGIC
== Console
->Header
.Type
)
2122 Buff
->Mode
= Request
->Data
.SetConsoleModeRequest
.Mode
& CONSOLE_OUTPUT_MODE_VALID
;
2126 return Request
->Status
= STATUS_INVALID_HANDLE
;
2129 Request
->Status
= STATUS_SUCCESS
;
2131 return Request
->Status
;
2134 CSR_API(CsrGetConsoleMode
)
2137 PCSRSS_CONSOLE Console
;
2138 PCSRSS_SCREEN_BUFFER Buff
; /* gee, I really wish I could use an anonymous union here */
2140 DPRINT("CsrGetConsoleMode\n");
2142 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2143 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2144 Status
= Win32CsrGetObject(ProcessData
, Request
->Data
.GetConsoleModeRequest
.ConsoleHandle
,
2145 (Object_t
**) &Console
);
2146 if (! NT_SUCCESS(Status
))
2148 return Request
->Status
= Status
;
2150 Request
->Status
= STATUS_SUCCESS
;
2151 Buff
= (PCSRSS_SCREEN_BUFFER
) Console
;
2152 if (CONIO_CONSOLE_MAGIC
== Console
->Header
.Type
)
2154 Request
->Data
.GetConsoleModeRequest
.ConsoleMode
= Console
->Mode
;
2156 else if (CONIO_SCREEN_BUFFER_MAGIC
== Buff
->Header
.Type
)
2158 Request
->Data
.GetConsoleModeRequest
.ConsoleMode
= Buff
->Mode
;
2162 Request
->Status
= STATUS_INVALID_HANDLE
;
2165 return Request
->Status
;
2168 CSR_API(CsrCreateScreenBuffer
)
2170 PCSRSS_CONSOLE Console
;
2171 PCSRSS_SCREEN_BUFFER Buff
;
2174 DPRINT("CsrCreateScreenBuffer\n");
2176 if (ProcessData
== NULL
)
2178 return Request
->Status
= STATUS_INVALID_PARAMETER
;
2181 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
2182 if (! NT_SUCCESS(Status
))
2184 return Request
->Status
= Status
;
2186 if (NULL
== Console
)
2188 return Request
->Status
= STATUS_INVALID_HANDLE
;
2191 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2192 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2194 Buff
= HeapAlloc(Win32CsrApiHeap
, 0, sizeof(CSRSS_SCREEN_BUFFER
));
2197 Request
->Status
= STATUS_INSUFFICIENT_RESOURCES
;
2200 Status
= CsrInitConsoleScreenBuffer(Console
, Buff
);
2201 if(! NT_SUCCESS(Status
))
2203 Request
->Status
= Status
;
2207 Request
->Status
= Win32CsrInsertObject(ProcessData
, &Request
->Data
.CreateScreenBufferRequest
.OutputHandle
, &Buff
->Header
);
2210 ConioUnlockConsole(Console
);
2212 return Request
->Status
;
2215 CSR_API(CsrSetScreenBuffer
)
2218 PCSRSS_CONSOLE Console
;
2219 PCSRSS_SCREEN_BUFFER Buff
;
2221 DPRINT("CsrSetScreenBuffer\n");
2223 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
2224 if (! NT_SUCCESS(Status
))
2226 return Request
->Status
= Status
;
2228 if (NULL
== Console
)
2230 DPRINT1("Trying to set screen buffer for app without console\n");
2231 return Request
->Status
= STATUS_INVALID_HANDLE
;
2234 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2235 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2237 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.SetScreenBufferRequest
.OutputHandle
, &Buff
);
2238 if (! NT_SUCCESS(Status
))
2240 ConioUnlockConsole(Console
);
2241 return Request
->Status
;
2244 if (Buff
== Console
->ActiveBuffer
)
2246 ConioUnlockScreenBuffer(Buff
);
2247 ConioUnlockConsole(Console
);
2248 return STATUS_SUCCESS
;
2251 /* drop reference to old buffer, maybe delete */
2252 if (! InterlockedDecrement(&Console
->ActiveBuffer
->Header
.ReferenceCount
))
2254 ConioDeleteScreenBuffer((Object_t
*) Console
->ActiveBuffer
);
2256 /* tie console to new buffer */
2257 Console
->ActiveBuffer
= Buff
;
2258 /* inc ref count on new buffer */
2259 InterlockedIncrement(&Buff
->Header
.ReferenceCount
);
2260 /* Redraw the console */
2261 ConioDrawConsole(Console
);
2263 ConioUnlockScreenBuffer(Buff
);
2264 ConioUnlockConsole(Console
);
2266 return Request
->Status
= STATUS_SUCCESS
;
2269 CSR_API(CsrSetTitle
)
2272 PCSRSS_CONSOLE Console
;
2275 DPRINT("CsrSetTitle\n");
2277 if (Request
->Header
.u1
.s1
.TotalLength
2278 < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE
)
2279 + Request
->Data
.SetTitleRequest
.Length
)
2281 DPRINT1("Invalid request size\n");
2282 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2283 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2284 return Request
->Status
= STATUS_INVALID_PARAMETER
;
2287 Status
= ConioLockConsole(ProcessData
, Request
->Data
.SetTitleRequest
.Console
, &Console
);
2288 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2289 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2290 if(! NT_SUCCESS(Status
))
2292 Request
->Status
= Status
;
2296 Buffer
= RtlAllocateHeap(RtlGetProcessHeap(), 0, Request
->Data
.SetTitleRequest
.Length
);
2299 /* copy title to console */
2300 RtlFreeUnicodeString(&Console
->Title
);
2301 Console
->Title
.Buffer
= Buffer
;
2302 Console
->Title
.Length
= Console
->Title
.MaximumLength
= Request
->Data
.SetTitleRequest
.Length
;
2303 memcpy(Console
->Title
.Buffer
, Request
->Data
.SetTitleRequest
.Title
, Console
->Title
.Length
);
2304 if (! ConioChangeTitle(Console
))
2306 Request
->Status
= STATUS_UNSUCCESSFUL
;
2310 Request
->Status
= STATUS_SUCCESS
;
2315 Request
->Status
= STATUS_NO_MEMORY
;
2318 ConioUnlockConsole(Console
);
2320 return Request
->Status
;
2323 CSR_API(CsrGetTitle
)
2326 PCSRSS_CONSOLE Console
;
2329 DPRINT("CsrGetTitle\n");
2331 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2332 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2333 Status
= ConioLockConsole(ProcessData
,
2334 Request
->Data
.GetTitleRequest
.ConsoleHandle
,
2336 if (! NT_SUCCESS(Status
))
2338 DPRINT1("Can't get console\n");
2339 return Request
->Status
= Status
;
2342 /* Copy title of the console to the user title buffer */
2343 RtlZeroMemory(&Request
->Data
.GetTitleRequest
, sizeof(CSRSS_GET_TITLE
));
2344 Request
->Data
.GetTitleRequest
.ConsoleHandle
= Request
->Data
.GetTitleRequest
.ConsoleHandle
;
2345 Request
->Data
.GetTitleRequest
.Length
= Console
->Title
.Length
;
2346 memcpy (Request
->Data
.GetTitleRequest
.Title
, Console
->Title
.Buffer
,
2347 Console
->Title
.Length
);
2348 Length
= CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE
) + Console
->Title
.Length
;
2350 ConioUnlockConsole(Console
);
2352 if (Length
> sizeof(CSR_API_MESSAGE
))
2354 Request
->Header
.u1
.s1
.TotalLength
= Length
;
2355 Request
->Header
.u1
.s1
.DataLength
= Length
- sizeof(PORT_MESSAGE
);
2357 Request
->Status
= STATUS_SUCCESS
;
2359 return Request
->Status
;
2362 CSR_API(CsrWriteConsoleOutput
)
2364 SHORT i
, X
, Y
, SizeX
, SizeY
;
2365 PCSRSS_CONSOLE Console
;
2366 PCSRSS_SCREEN_BUFFER Buff
;
2368 CHAR_INFO
* CurCharInfo
;
2370 CHAR_INFO
* CharInfo
;
2377 DPRINT("CsrWriteConsoleOutput\n");
2379 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
2380 if (! NT_SUCCESS(Status
))
2382 return Request
->Status
= Status
;
2385 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2386 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2387 Status
= ConioLockScreenBuffer(ProcessData
,
2388 Request
->Data
.WriteConsoleOutputRequest
.ConsoleHandle
,
2390 if (! NT_SUCCESS(Status
))
2392 if (NULL
!= Console
)
2394 ConioUnlockConsole(Console
);
2396 return Request
->Status
= Status
;
2399 BufferSize
= Request
->Data
.WriteConsoleOutputRequest
.BufferSize
;
2400 PSize
= BufferSize
.X
* BufferSize
.Y
* sizeof(CHAR_INFO
);
2401 BufferCoord
= Request
->Data
.WriteConsoleOutputRequest
.BufferCoord
;
2402 CharInfo
= Request
->Data
.WriteConsoleOutputRequest
.CharInfo
;
2403 if (((PVOID
)CharInfo
< ProcessData
->CsrSectionViewBase
) ||
2404 (((ULONG_PTR
)CharInfo
+ PSize
) >
2405 ((ULONG_PTR
)ProcessData
->CsrSectionViewBase
+ ProcessData
->CsrSectionViewSize
)))
2407 ConioUnlockScreenBuffer(Buff
);
2408 ConioUnlockConsole(Console
);
2409 return Request
->Status
= STATUS_ACCESS_VIOLATION
;
2411 WriteRegion
.left
= Request
->Data
.WriteConsoleOutputRequest
.WriteRegion
.Left
;
2412 WriteRegion
.top
= Request
->Data
.WriteConsoleOutputRequest
.WriteRegion
.Top
;
2413 WriteRegion
.right
= Request
->Data
.WriteConsoleOutputRequest
.WriteRegion
.Right
;
2414 WriteRegion
.bottom
= Request
->Data
.WriteConsoleOutputRequest
.WriteRegion
.Bottom
;
2416 SizeY
= min(BufferSize
.Y
- BufferCoord
.Y
, ConioRectHeight(&WriteRegion
));
2417 SizeX
= min(BufferSize
.X
- BufferCoord
.X
, ConioRectWidth(&WriteRegion
));
2418 WriteRegion
.bottom
= WriteRegion
.top
+ SizeY
- 1;
2419 WriteRegion
.right
= WriteRegion
.left
+ SizeX
- 1;
2421 /* Make sure WriteRegion is inside the screen buffer */
2422 ConioInitRect(&ScreenBuffer
, 0, 0, Buff
->MaxY
- 1, Buff
->MaxX
- 1);
2423 if (! ConioGetIntersection(&WriteRegion
, &ScreenBuffer
, &WriteRegion
))
2425 ConioUnlockScreenBuffer(Buff
);
2426 ConioUnlockConsole(Console
);
2428 /* It is okay to have a WriteRegion completely outside the screen buffer.
2429 No data is written then. */
2430 return Request
->Status
= STATUS_SUCCESS
;
2433 for (i
= 0, Y
= WriteRegion
.top
; Y
<= WriteRegion
.bottom
; i
++, Y
++)
2435 CurCharInfo
= CharInfo
+ (i
+ BufferCoord
.Y
) * BufferSize
.X
+ BufferCoord
.X
;
2436 Offset
= (((Y
+ Buff
->ShowY
) % Buff
->MaxY
) * Buff
->MaxX
+ WriteRegion
.left
) * 2;
2437 for (X
= WriteRegion
.left
; X
<= WriteRegion
.right
; X
++)
2439 if (Request
->Data
.WriteConsoleOutputRequest
.Unicode
)
2442 ConsoleUnicodeCharToAnsiChar(Console
, &AsciiChar
, &CurCharInfo
->Char
.UnicodeChar
);
2443 SET_CELL_BUFFER(Buff
, Offset
, AsciiChar
, CurCharInfo
->Attributes
);
2447 SET_CELL_BUFFER(Buff
, Offset
, CurCharInfo
->Char
.AsciiChar
, CurCharInfo
->Attributes
);
2453 if (NULL
!= Console
)
2455 ConioDrawRegion(Console
, &WriteRegion
);
2458 ConioUnlockScreenBuffer(Buff
);
2459 ConioUnlockConsole(Console
);
2461 Request
->Data
.WriteConsoleOutputRequest
.WriteRegion
.Right
= WriteRegion
.left
+ SizeX
- 1;
2462 Request
->Data
.WriteConsoleOutputRequest
.WriteRegion
.Bottom
= WriteRegion
.top
+ SizeY
- 1;
2463 Request
->Data
.WriteConsoleOutputRequest
.WriteRegion
.Left
= WriteRegion
.left
;
2464 Request
->Data
.WriteConsoleOutputRequest
.WriteRegion
.Top
= WriteRegion
.top
;
2466 return Request
->Status
= STATUS_SUCCESS
;
2469 CSR_API(CsrFlushInputBuffer
)
2471 PLIST_ENTRY CurrentEntry
;
2472 PCSRSS_CONSOLE Console
;
2473 ConsoleInput
* Input
;
2476 DPRINT("CsrFlushInputBuffer\n");
2478 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2479 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2480 Status
= ConioLockConsole(ProcessData
,
2481 Request
->Data
.FlushInputBufferRequest
.ConsoleInput
,
2483 if(! NT_SUCCESS(Status
))
2485 return Request
->Status
= Status
;
2488 /* Discard all entries in the input event queue */
2489 while (!IsListEmpty(&Console
->InputEvents
))
2491 CurrentEntry
= RemoveHeadList(&Console
->InputEvents
);
2492 Input
= CONTAINING_RECORD(CurrentEntry
, ConsoleInput
, ListEntry
);
2493 /* Destroy the event */
2494 HeapFree(Win32CsrApiHeap
, 0, Input
);
2496 ResetEvent(Console
->ActiveEvent
);
2497 Console
->WaitingChars
=0;
2499 ConioUnlockConsole(Console
);
2501 return Request
->Status
= STATUS_SUCCESS
;
2504 CSR_API(CsrScrollConsoleScreenBuffer
)
2506 PCSRSS_CONSOLE Console
;
2507 PCSRSS_SCREEN_BUFFER Buff
;
2512 RECT ScrollRectangle
;
2517 DPRINT("CsrScrollConsoleScreenBuffer\n");
2519 ALIAS(ConsoleHandle
,Request
->Data
.ScrollConsoleScreenBufferRequest
.ConsoleHandle
);
2520 ALIAS(UseClipRectangle
,Request
->Data
.ScrollConsoleScreenBufferRequest
.UseClipRectangle
);
2521 ALIAS(DestinationOrigin
,Request
->Data
.ScrollConsoleScreenBufferRequest
.DestinationOrigin
);
2522 ALIAS(Fill
,Request
->Data
.ScrollConsoleScreenBufferRequest
.Fill
);
2524 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
2525 if (! NT_SUCCESS(Status
))
2527 return Request
->Status
= Status
;
2530 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2531 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2532 Status
= ConioLockScreenBuffer(ProcessData
, ConsoleHandle
, &Buff
);
2533 if (! NT_SUCCESS(Status
))
2535 if (NULL
!= Console
)
2537 ConioUnlockConsole(Console
);
2539 return Request
->Status
= Status
;
2542 ScrollRectangle
.left
= Request
->Data
.ScrollConsoleScreenBufferRequest
.ScrollRectangle
.Left
;
2543 ScrollRectangle
.top
= Request
->Data
.ScrollConsoleScreenBufferRequest
.ScrollRectangle
.Top
;
2544 ScrollRectangle
.right
= Request
->Data
.ScrollConsoleScreenBufferRequest
.ScrollRectangle
.Right
;
2545 ScrollRectangle
.bottom
= Request
->Data
.ScrollConsoleScreenBufferRequest
.ScrollRectangle
.Bottom
;
2546 ClipRectangle
.left
= Request
->Data
.ScrollConsoleScreenBufferRequest
.ClipRectangle
.Left
;
2547 ClipRectangle
.top
= Request
->Data
.ScrollConsoleScreenBufferRequest
.ClipRectangle
.Top
;
2548 ClipRectangle
.right
= Request
->Data
.ScrollConsoleScreenBufferRequest
.ClipRectangle
.Right
;
2549 ClipRectangle
.bottom
= Request
->Data
.ScrollConsoleScreenBufferRequest
.ClipRectangle
.Bottom
;
2551 /* Make sure source rectangle is inside the screen buffer */
2552 ConioInitRect(&ScreenBuffer
, 0, 0, Buff
->MaxY
- 1, Buff
->MaxX
- 1);
2553 if (! ConioGetIntersection(&SrcRegion
, &ScreenBuffer
, &ScrollRectangle
))
2555 ConioUnlockScreenBuffer(Buff
);
2556 return Request
->Status
= STATUS_INVALID_PARAMETER
;
2559 if (UseClipRectangle
&& ! ConioGetIntersection(&SrcRegion
, &SrcRegion
, &ClipRectangle
))
2561 ConioUnlockScreenBuffer(Buff
);
2562 return Request
->Status
= STATUS_SUCCESS
;
2566 ConioInitRect(&DstRegion
,
2567 DestinationOrigin
.Y
,
2568 DestinationOrigin
.X
,
2569 DestinationOrigin
.Y
+ ConioRectHeight(&ScrollRectangle
) - 1,
2570 DestinationOrigin
.X
+ ConioRectWidth(&ScrollRectangle
) - 1);
2572 /* Make sure destination rectangle is inside the screen buffer */
2573 if (! ConioGetIntersection(&DstRegion
, &DstRegion
, &ScreenBuffer
))
2575 ConioUnlockScreenBuffer(Buff
);
2576 return Request
->Status
= STATUS_INVALID_PARAMETER
;
2579 ConioCopyRegion(Buff
, &SrcRegion
, &DstRegion
);
2581 /* Get the region that should be filled with the specified character and attributes */
2585 ConioGetUnion(&FillRegion
, &SrcRegion
, &DstRegion
);
2587 if (ConioSubtractRect(&FillRegion
, &FillRegion
, &DstRegion
))
2589 /* FIXME: The subtracted rectangle is off by one line */
2590 FillRegion
.top
+= 1;
2592 ConioFillRegion(Console
, Buff
, &FillRegion
, &Fill
, Request
->Data
.ScrollConsoleScreenBufferRequest
.Unicode
);
2596 if (NULL
!= Console
&& Buff
== Console
->ActiveBuffer
)
2598 /* Draw destination region */
2599 ConioDrawRegion(Console
, &DstRegion
);
2603 /* Draw filled region */
2604 ConioDrawRegion(Console
, &FillRegion
);
2608 ConioUnlockScreenBuffer(Buff
);
2609 if (NULL
!= Console
)
2611 ConioUnlockConsole(Console
);
2614 return Request
->Status
= STATUS_SUCCESS
;
2617 CSR_API(CsrReadConsoleOutputChar
)
2620 PCSRSS_CONSOLE Console
;
2621 PCSRSS_SCREEN_BUFFER Buff
;
2628 DPRINT("CsrReadConsoleOutputChar\n");
2630 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2631 Request
->Header
.u1
.s1
.DataLength
= Request
->Header
.u1
.s1
.TotalLength
- sizeof(PORT_MESSAGE
);
2632 ReadBuffer
= Request
->Data
.ReadConsoleOutputCharRequest
.String
;
2634 CharSize
= (Request
->Data
.ReadConsoleOutputCharRequest
.Unicode
? sizeof(WCHAR
) : sizeof(CHAR
));
2636 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
2637 if (! NT_SUCCESS(Status
))
2639 return Request
->Status
= Status
;
2642 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.ReadConsoleOutputCharRequest
.ConsoleHandle
, &Buff
);
2643 if (! NT_SUCCESS(Status
))
2645 return Request
->Status
= Status
;
2648 Xpos
= Request
->Data
.ReadConsoleOutputCharRequest
.ReadCoord
.X
+ Buff
->ShowX
;
2649 Ypos
= (Request
->Data
.ReadConsoleOutputCharRequest
.ReadCoord
.Y
+ Buff
->ShowY
) % Buff
->MaxY
;
2651 for (i
= 0; i
< Request
->Data
.ReadConsoleOutputCharRequest
.NumCharsToRead
; ++i
)
2653 Char
= Buff
->Buffer
[(Xpos
* 2) + (Ypos
* 2 * Buff
->MaxX
)];
2655 if(Request
->Data
.ReadConsoleOutputCharRequest
.Unicode
)
2657 ConsoleAnsiCharToUnicodeChar(Console
, (WCHAR
*)ReadBuffer
, &Char
);
2658 ReadBuffer
+= sizeof(WCHAR
);
2661 *(ReadBuffer
++) = Char
;
2665 if (Xpos
== Buff
->MaxX
)
2670 if (Ypos
== Buff
->MaxY
)
2678 Request
->Status
= STATUS_SUCCESS
;
2679 Request
->Data
.ReadConsoleOutputCharRequest
.EndCoord
.X
= Xpos
- Buff
->ShowX
;
2680 Request
->Data
.ReadConsoleOutputCharRequest
.EndCoord
.Y
= (Ypos
- Buff
->ShowY
+ Buff
->MaxY
) % Buff
->MaxY
;
2682 ConioUnlockScreenBuffer(Buff
);
2683 if (NULL
!= Console
)
2685 ConioUnlockConsole(Console
);
2688 Request
->Data
.ReadConsoleOutputCharRequest
.CharsRead
= (DWORD
)((ULONG_PTR
)ReadBuffer
- (ULONG_PTR
)Request
->Data
.ReadConsoleOutputCharRequest
.String
) / CharSize
;
2689 if (Request
->Data
.ReadConsoleOutputCharRequest
.CharsRead
* CharSize
+ CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR
) > sizeof(CSR_API_MESSAGE
))
2691 Request
->Header
.u1
.s1
.TotalLength
= Request
->Data
.ReadConsoleOutputCharRequest
.CharsRead
* CharSize
+ CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR
);
2692 Request
->Header
.u1
.s1
.DataLength
= Request
->Header
.u1
.s1
.TotalLength
- sizeof(PORT_MESSAGE
);
2695 return Request
->Status
;
2699 CSR_API(CsrReadConsoleOutputAttrib
)
2702 PCSRSS_SCREEN_BUFFER Buff
;
2706 DWORD CurrentLength
;
2708 DPRINT("CsrReadConsoleOutputAttrib\n");
2710 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2711 Request
->Header
.u1
.s1
.DataLength
= Request
->Header
.u1
.s1
.TotalLength
- sizeof(PORT_MESSAGE
);
2712 ReadBuffer
= Request
->Data
.ReadConsoleOutputAttribRequest
.Attribute
;
2714 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.ReadConsoleOutputAttribRequest
.ConsoleHandle
, &Buff
);
2715 if (! NT_SUCCESS(Status
))
2717 return Request
->Status
= Status
;
2720 Xpos
= Request
->Data
.ReadConsoleOutputAttribRequest
.ReadCoord
.X
+ Buff
->ShowX
;
2721 Ypos
= (Request
->Data
.ReadConsoleOutputAttribRequest
.ReadCoord
.Y
+ Buff
->ShowY
) % Buff
->MaxY
;
2723 for (i
= 0; i
< Request
->Data
.ReadConsoleOutputAttribRequest
.NumAttrsToRead
; ++i
)
2725 *ReadBuffer
= Buff
->Buffer
[(Xpos
* 2) + (Ypos
* 2 * Buff
->MaxX
) + 1];
2730 if (Xpos
== Buff
->MaxX
)
2735 if (Ypos
== Buff
->MaxY
)
2744 Request
->Status
= STATUS_SUCCESS
;
2745 Request
->Data
.ReadConsoleOutputAttribRequest
.EndCoord
.X
= Xpos
- Buff
->ShowX
;
2746 Request
->Data
.ReadConsoleOutputAttribRequest
.EndCoord
.Y
= (Ypos
- Buff
->ShowY
+ Buff
->MaxY
) % Buff
->MaxY
;
2748 ConioUnlockScreenBuffer(Buff
);
2750 CurrentLength
= CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB
)
2751 + Request
->Data
.ReadConsoleOutputAttribRequest
.NumAttrsToRead
* sizeof(WORD
);
2752 if (CurrentLength
> sizeof(CSR_API_MESSAGE
))
2754 Request
->Header
.u1
.s1
.TotalLength
= CurrentLength
;
2755 Request
->Header
.u1
.s1
.DataLength
= CurrentLength
- sizeof(PORT_MESSAGE
);
2758 return Request
->Status
;
2762 CSR_API(CsrGetNumberOfConsoleInputEvents
)
2765 PCSRSS_CONSOLE Console
;
2766 PLIST_ENTRY CurrentItem
;
2768 ConsoleInput
*Input
;
2770 DPRINT("CsrGetNumberOfConsoleInputEvents\n");
2772 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2773 Request
->Header
.u1
.s1
.DataLength
= Request
->Header
.u1
.s1
.TotalLength
- sizeof(PORT_MESSAGE
);
2775 Status
= ConioLockConsole(ProcessData
, Request
->Data
.GetNumInputEventsRequest
.ConsoleHandle
, &Console
);
2776 if (! NT_SUCCESS(Status
))
2778 return Request
->Status
= Status
;
2781 CurrentItem
= Console
->InputEvents
.Flink
;
2784 /* If there are any events ... */
2785 while (CurrentItem
!= &Console
->InputEvents
)
2787 Input
= CONTAINING_RECORD(CurrentItem
, ConsoleInput
, ListEntry
);
2788 CurrentItem
= CurrentItem
->Flink
;
2795 ConioUnlockConsole(Console
);
2797 Request
->Status
= STATUS_SUCCESS
;
2798 Request
->Data
.GetNumInputEventsRequest
.NumInputEvents
= NumEvents
;
2800 return Request
->Status
;
2804 CSR_API(CsrPeekConsoleInput
)
2807 PCSRSS_CONSOLE Console
;
2810 PLIST_ENTRY CurrentItem
;
2811 PINPUT_RECORD InputRecord
;
2815 DPRINT("CsrPeekConsoleInput\n");
2817 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2818 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2820 Status
= ConioLockConsole(ProcessData
, Request
->Data
.GetNumInputEventsRequest
.ConsoleHandle
, &Console
);
2821 if(! NT_SUCCESS(Status
))
2823 return Request
->Status
= Status
;
2826 InputRecord
= Request
->Data
.PeekConsoleInputRequest
.InputRecord
;
2827 Length
= Request
->Data
.PeekConsoleInputRequest
.Length
;
2828 Size
= Length
* sizeof(INPUT_RECORD
);
2830 if (((PVOID
)InputRecord
< ProcessData
->CsrSectionViewBase
)
2831 || (((ULONG_PTR
)InputRecord
+ Size
) > ((ULONG_PTR
)ProcessData
->CsrSectionViewBase
+ ProcessData
->CsrSectionViewSize
)))
2833 ConioUnlockConsole(Console
);
2834 Request
->Status
= STATUS_ACCESS_VIOLATION
;
2835 return Request
->Status
;
2840 if (! IsListEmpty(&Console
->InputEvents
))
2842 CurrentItem
= Console
->InputEvents
.Flink
;
2844 while (CurrentItem
!= &Console
->InputEvents
&& NumItems
< Length
)
2846 Item
= CONTAINING_RECORD(CurrentItem
, ConsoleInput
, ListEntry
);
2850 CurrentItem
= CurrentItem
->Flink
;
2855 *InputRecord
= Item
->InputEvent
;
2857 if (Request
->Data
.ReadInputRequest
.Unicode
== FALSE
)
2859 ConioInputEventToAnsi(Console
, InputRecord
);
2863 CurrentItem
= CurrentItem
->Flink
;
2867 ConioUnlockConsole(Console
);
2869 Request
->Status
= STATUS_SUCCESS
;
2870 Request
->Data
.PeekConsoleInputRequest
.Length
= NumItems
;
2872 return Request
->Status
;
2876 CSR_API(CsrReadConsoleOutput
)
2878 PCHAR_INFO CharInfo
;
2879 PCHAR_INFO CurCharInfo
;
2880 PCSRSS_SCREEN_BUFFER Buff
;
2893 DPRINT("CsrReadConsoleOutput\n");
2895 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2896 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2898 Status
= ConioLockScreenBuffer(ProcessData
, Request
->Data
.ReadConsoleOutputRequest
.ConsoleHandle
, &Buff
);
2899 if (! NT_SUCCESS(Status
))
2901 return Request
->Status
= Status
;
2904 CharInfo
= Request
->Data
.ReadConsoleOutputRequest
.CharInfo
;
2905 ReadRegion
.left
= Request
->Data
.ReadConsoleOutputRequest
.ReadRegion
.Left
;
2906 ReadRegion
.top
= Request
->Data
.ReadConsoleOutputRequest
.ReadRegion
.Top
;
2907 ReadRegion
.right
= Request
->Data
.ReadConsoleOutputRequest
.ReadRegion
.Right
;
2908 ReadRegion
.bottom
= Request
->Data
.ReadConsoleOutputRequest
.ReadRegion
.Bottom
;
2909 BufferSize
= Request
->Data
.ReadConsoleOutputRequest
.BufferSize
;
2910 BufferCoord
= Request
->Data
.ReadConsoleOutputRequest
.BufferCoord
;
2911 Length
= BufferSize
.X
* BufferSize
.Y
;
2912 Size
= Length
* sizeof(CHAR_INFO
);
2914 /* FIXME: Is this correct? */
2915 CodePage
= ProcessData
->Console
->OutputCodePage
;
2917 if (((PVOID
)CharInfo
< ProcessData
->CsrSectionViewBase
)
2918 || (((ULONG_PTR
)CharInfo
+ Size
) > ((ULONG_PTR
)ProcessData
->CsrSectionViewBase
+ ProcessData
->CsrSectionViewSize
)))
2920 ConioUnlockScreenBuffer(Buff
);
2921 Request
->Status
= STATUS_ACCESS_VIOLATION
;
2922 return Request
->Status
;
2925 SizeY
= min(BufferSize
.Y
- BufferCoord
.Y
, ConioRectHeight(&ReadRegion
));
2926 SizeX
= min(BufferSize
.X
- BufferCoord
.X
, ConioRectWidth(&ReadRegion
));
2927 ReadRegion
.bottom
= ReadRegion
.top
+ SizeY
;
2928 ReadRegion
.right
= ReadRegion
.left
+ SizeX
;
2930 ConioInitRect(&ScreenRect
, 0, 0, Buff
->MaxY
, Buff
->MaxX
);
2931 if (! ConioGetIntersection(&ReadRegion
, &ScreenRect
, &ReadRegion
))
2933 ConioUnlockScreenBuffer(Buff
);
2934 Request
->Status
= STATUS_SUCCESS
;
2935 return Request
->Status
;
2938 for (i
= 0, Y
= ReadRegion
.top
; Y
< ReadRegion
.bottom
; ++i
, ++Y
)
2940 CurCharInfo
= CharInfo
+ (i
* BufferSize
.X
);
2942 Offset
= (((Y
+ Buff
->ShowY
) % Buff
->MaxY
) * Buff
->MaxX
+ ReadRegion
.left
) * 2;
2943 for (X
= ReadRegion
.left
; X
< ReadRegion
.right
; ++X
)
2945 if (Request
->Data
.ReadConsoleOutputRequest
.Unicode
)
2947 MultiByteToWideChar(CodePage
, 0,
2948 (PCHAR
)&GET_CELL_BUFFER(Buff
, Offset
), 1,
2949 &CurCharInfo
->Char
.UnicodeChar
, 1);
2953 CurCharInfo
->Char
.AsciiChar
= GET_CELL_BUFFER(Buff
, Offset
);
2955 CurCharInfo
->Attributes
= GET_CELL_BUFFER(Buff
, Offset
);
2960 ConioUnlockScreenBuffer(Buff
);
2962 Request
->Status
= STATUS_SUCCESS
;
2963 Request
->Data
.ReadConsoleOutputRequest
.ReadRegion
.Right
= ReadRegion
.left
+ SizeX
- 1;
2964 Request
->Data
.ReadConsoleOutputRequest
.ReadRegion
.Bottom
= ReadRegion
.top
+ SizeY
- 1;
2965 Request
->Data
.ReadConsoleOutputRequest
.ReadRegion
.Left
= ReadRegion
.left
;
2966 Request
->Data
.ReadConsoleOutputRequest
.ReadRegion
.Top
= ReadRegion
.top
;
2968 return Request
->Status
;
2972 CSR_API(CsrWriteConsoleInput
)
2974 PINPUT_RECORD InputRecord
;
2975 PCSRSS_CONSOLE Console
;
2980 ConsoleInput
* Record
;
2982 DPRINT("CsrWriteConsoleInput\n");
2984 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
2985 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
2987 Status
= ConioLockConsole(ProcessData
, Request
->Data
.WriteConsoleInputRequest
.ConsoleHandle
, &Console
);
2988 if (! NT_SUCCESS(Status
))
2990 return Request
->Status
= Status
;
2993 InputRecord
= Request
->Data
.WriteConsoleInputRequest
.InputRecord
;
2994 Length
= Request
->Data
.WriteConsoleInputRequest
.Length
;
2995 Size
= Length
* sizeof(INPUT_RECORD
);
2997 if (((PVOID
)InputRecord
< ProcessData
->CsrSectionViewBase
)
2998 || (((ULONG_PTR
)InputRecord
+ Size
) > ((ULONG_PTR
)ProcessData
->CsrSectionViewBase
+ ProcessData
->CsrSectionViewSize
)))
3000 ConioUnlockConsole(Console
);
3001 Request
->Status
= STATUS_ACCESS_VIOLATION
;
3002 return Request
->Status
;
3005 for (i
= 0; i
< Length
; i
++)
3007 Record
= HeapAlloc(Win32CsrApiHeap
, 0, sizeof(ConsoleInput
));
3010 ConioUnlockConsole(Console
);
3011 Request
->Status
= STATUS_INSUFFICIENT_RESOURCES
;
3012 return Request
->Status
;
3015 Record
->Echoed
= FALSE
;
3016 Record
->Fake
= FALSE
;
3017 Record
->InputEvent
= *InputRecord
++;
3018 if (KEY_EVENT
== Record
->InputEvent
.EventType
)
3020 /* FIXME - convert from unicode to ascii!! */
3021 ConioProcessChar(Console
, Record
);
3025 ConioUnlockConsole(Console
);
3027 Request
->Status
= STATUS_SUCCESS
;
3028 Request
->Data
.WriteConsoleInputRequest
.Length
= i
;
3030 return Request
->Status
;
3033 /**********************************************************************
3034 * HardwareStateProperty
3037 * Set/Get the value of the HardwareState and switch
3038 * between direct video buffer ouput and GDI windowed
3041 * Client hands us a CSRSS_CONSOLE_HARDWARE_STATE
3042 * object. We use the same object to Request.
3044 * ConsoleHwState has the correct size to be compatible
3045 * with NT's, but values are not.
3047 STATIC NTSTATUS FASTCALL
3048 SetConsoleHardwareState (PCSRSS_CONSOLE Console
, DWORD ConsoleHwState
)
3050 DPRINT1("Console Hardware State: %d\n", ConsoleHwState
);
3052 if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED
== ConsoleHwState
)
3053 ||(CONSOLE_HARDWARE_STATE_DIRECT
== ConsoleHwState
))
3055 if (Console
->HardwareState
!= ConsoleHwState
)
3057 /* TODO: implement switching from full screen to windowed mode */
3058 /* TODO: or back; now simply store the hardware state */
3059 Console
->HardwareState
= ConsoleHwState
;
3062 return STATUS_SUCCESS
;
3065 return STATUS_INVALID_PARAMETER_3
; /* Client: (handle, set_get, [mode]) */
3068 CSR_API(CsrHardwareStateProperty
)
3070 PCSRSS_CONSOLE Console
;
3073 DPRINT("CsrHardwareStateProperty\n");
3075 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
3076 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
3078 Status
= ConioLockConsole(ProcessData
,
3079 Request
->Data
.ConsoleHardwareStateRequest
.ConsoleHandle
,
3081 if (! NT_SUCCESS(Status
))
3083 DPRINT1("Failed to get console handle in SetConsoleHardwareState\n");
3084 return Request
->Status
= Status
;
3087 switch (Request
->Data
.ConsoleHardwareStateRequest
.SetGet
)
3089 case CONSOLE_HARDWARE_STATE_GET
:
3090 Request
->Data
.ConsoleHardwareStateRequest
.State
= Console
->HardwareState
;
3093 case CONSOLE_HARDWARE_STATE_SET
:
3094 DPRINT("Setting console hardware state.\n");
3095 Request
->Status
= SetConsoleHardwareState(Console
, Request
->Data
.ConsoleHardwareStateRequest
.State
);
3099 Request
->Status
= STATUS_INVALID_PARAMETER_2
; /* Client: (handle, [set_get], mode) */
3103 ConioUnlockConsole(Console
);
3105 return Request
->Status
;
3108 CSR_API(CsrGetConsoleWindow
)
3110 PCSRSS_CONSOLE Console
;
3113 DPRINT("CsrGetConsoleWindow\n");
3115 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
3116 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
3118 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
3119 if (! NT_SUCCESS(Status
))
3121 return Request
->Status
= Status
;
3124 Request
->Data
.GetConsoleWindowRequest
.WindowHandle
= Console
->hWindow
;
3125 ConioUnlockConsole(Console
);
3127 return Request
->Status
= STATUS_SUCCESS
;
3130 CSR_API(CsrSetConsoleIcon
)
3132 PCSRSS_CONSOLE Console
;
3135 DPRINT("CsrSetConsoleIcon\n");
3137 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
3138 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
3140 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
3141 if (! NT_SUCCESS(Status
))
3143 return Request
->Status
= Status
;
3146 Console
->hWindowIcon
= Request
->Data
.SetConsoleIconRequest
.WindowIcon
;
3147 Request
->Status
= (ConioChangeIcon(Console
) ? STATUS_SUCCESS
: STATUS_UNSUCCESSFUL
);
3148 ConioUnlockConsole(Console
);
3150 return Request
->Status
;
3153 CSR_API(CsrGetConsoleCodePage
)
3155 PCSRSS_CONSOLE Console
;
3158 DPRINT("CsrGetConsoleCodePage\n");
3160 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
3161 if (! NT_SUCCESS(Status
))
3163 return Request
->Status
= Status
;
3166 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
3167 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
3168 Request
->Data
.GetConsoleCodePage
.CodePage
= Console
->CodePage
;
3169 ConioUnlockConsole(Console
);
3170 return Request
->Status
= STATUS_SUCCESS
;
3173 CSR_API(CsrSetConsoleCodePage
)
3175 PCSRSS_CONSOLE Console
;
3178 DPRINT("CsrSetConsoleCodePage\n");
3180 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
3181 if (! NT_SUCCESS(Status
))
3183 return Request
->Status
= Status
;
3186 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
3187 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
3188 if (IsValidCodePage(Request
->Data
.SetConsoleCodePage
.CodePage
))
3190 Console
->CodePage
= Request
->Data
.SetConsoleCodePage
.CodePage
;
3191 ConioUnlockConsole(Console
);
3192 return Request
->Status
= STATUS_SUCCESS
;
3194 ConioUnlockConsole(Console
);
3195 return Request
->Status
= STATUS_UNSUCCESSFUL
;
3198 CSR_API(CsrGetConsoleOutputCodePage
)
3200 PCSRSS_CONSOLE Console
;
3203 DPRINT("CsrGetConsoleOutputCodePage\n");
3205 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
3206 if (! NT_SUCCESS(Status
))
3208 return Request
->Status
= Status
;
3211 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
3212 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
3213 Request
->Data
.GetConsoleOutputCodePage
.CodePage
= Console
->OutputCodePage
;
3214 ConioUnlockConsole(Console
);
3215 return Request
->Status
= STATUS_SUCCESS
;
3218 CSR_API(CsrSetConsoleOutputCodePage
)
3220 PCSRSS_CONSOLE Console
;
3223 DPRINT("CsrSetConsoleOutputCodePage\n");
3225 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
3226 if (! NT_SUCCESS(Status
))
3228 return Request
->Status
= Status
;
3231 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
3232 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
3233 if (IsValidCodePage(Request
->Data
.SetConsoleOutputCodePage
.CodePage
))
3235 Console
->OutputCodePage
= Request
->Data
.SetConsoleOutputCodePage
.CodePage
;
3236 ConioUnlockConsole(Console
);
3237 return Request
->Status
= STATUS_SUCCESS
;
3239 ConioUnlockConsole(Console
);
3240 return Request
->Status
= STATUS_UNSUCCESSFUL
;
3243 CSR_API(CsrGetProcessList
)
3246 PCSRSS_CONSOLE Console
;
3247 PCSRSS_PROCESS_DATA current
;
3248 PLIST_ENTRY current_entry
;
3249 ULONG nItems
, nCopied
, Length
;
3252 DPRINT("CsrGetProcessList\n");
3254 Buffer
= Request
->Data
.GetProcessListRequest
.ProcessId
;
3255 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
3256 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
3258 nItems
= nCopied
= 0;
3259 Request
->Data
.GetProcessListRequest
.nProcessIdsCopied
= 0;
3260 Request
->Data
.GetProcessListRequest
.nProcessIdsTotal
= 0;
3262 Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
3263 if (! NT_SUCCESS(Status
))
3265 return Request
->Status
= Status
;
3268 DPRINT1("Console_Api Ctrl-C\n");
3270 for(current_entry
= Console
->ProcessList
.Flink
;
3271 current_entry
!= &Console
->ProcessList
;
3272 current_entry
= current_entry
->Flink
)
3274 current
= CONTAINING_RECORD(current_entry
, CSRSS_PROCESS_DATA
, ProcessEntry
);
3275 if(nItems
++ < Request
->Data
.GetProcessListRequest
.nMaxIds
)
3277 *(Buffer
++) = current
->ProcessId
;
3282 ConioUnlockConsole(Console
);
3284 Request
->Data
.GetProcessListRequest
.nProcessIdsCopied
= nCopied
;
3285 Request
->Data
.GetProcessListRequest
.nProcessIdsTotal
= nItems
;
3287 Length
= CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST
) + nCopied
* sizeof(HANDLE
);
3288 if (Length
> sizeof(CSR_API_MESSAGE
))
3290 Request
->Header
.u1
.s1
.TotalLength
= Length
;
3291 Request
->Header
.u1
.s1
.DataLength
= Length
- sizeof(PORT_MESSAGE
);
3293 return Request
->Status
= STATUS_SUCCESS
;