ReactOS 0.4.15-dev-7906-g1b85a5f
console.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Console Driver DLL
4 * FILE: win32ss/user/winsrv/consrv/condrv/console.c
5 * PURPOSE: Console Management Functions
6 * PROGRAMMERS: Gé van Geldorp
7 * Jeffrey Morlan
8 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
9 * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
10 */
11
12/* INCLUDES *******************************************************************/
13
14#include <consrv.h>
15#include <coninput.h>
16#include "../../concfg/font.h"
17
18#define NDEBUG
19#include <debug.h>
20
21/* CONSOLE VALIDATION FUNCTIONS ***********************************************/
22
25 IN CONSOLE_STATE ExpectedState)
26{
27 // if (!Console) return FALSE;
28
29 /* The console must be locked */
30 // ASSERT(Console_locked);
31
32 return (Console->State == ExpectedState);
33}
34
37 IN CONSOLE_STATE ExpectedState,
38 IN BOOLEAN LockConsole)
39{
40 if (!Console) return FALSE;
41
42 /*
43 * Lock the console to forbid possible console's state changes
44 * (which must be done when the console is already locked).
45 * If we don't want to lock it, it's because the lock is already
46 * held. So there must be no problems.
47 */
48 if (LockConsole) EnterCriticalSection(&Console->Lock);
49
50 // ASSERT(Console_locked);
51
52 /* Check whether the console's state is what we expect */
53 if (!ConDrvValidateConsoleState(Console, ExpectedState))
54 {
55 if (LockConsole) LeaveCriticalSection(&Console->Lock);
56 return FALSE;
57 }
58
59 return TRUE;
60}
61
62
63/* CONSOLE INITIALIZATION FUNCTIONS *******************************************/
64
65/* For resetting the terminal - defined in dummyterm.c */
67
72{
74 // CONSOLE_INFO CapturedConsoleInfo;
76 PCONSOLE_SCREEN_BUFFER NewBuffer;
77
78 if (Console == NULL || ConsoleInfo == NULL)
80
81 /* Reset the console structure */
82 RtlZeroMemory(Console, sizeof(*Console));
83
84 /*
85 * Set and fix the screen buffer size if needed.
86 * The rule is: ScreenBufferSize >= ConsoleSize
87 */
88 if (ConsoleInfo->ScreenBufferSize.X == 0) ConsoleInfo->ScreenBufferSize.X = 1;
89 if (ConsoleInfo->ScreenBufferSize.Y == 0) ConsoleInfo->ScreenBufferSize.Y = 1;
90 if (ConsoleInfo->ScreenBufferSize.X < ConsoleInfo->ConsoleSize.X)
91 ConsoleInfo->ScreenBufferSize.X = ConsoleInfo->ConsoleSize.X;
92 if (ConsoleInfo->ScreenBufferSize.Y < ConsoleInfo->ConsoleSize.Y)
93 ConsoleInfo->ScreenBufferSize.Y = ConsoleInfo->ConsoleSize.Y;
94
95 /*
96 * Initialize the console
97 */
99 Console->ReferenceCount = 0;
101
102 /* Initialize the terminal interface */
104
105 Console->ConsoleSize = ConsoleInfo->ConsoleSize;
106 Console->FixedSize = FALSE; // Value by default; is reseted by the terminals if needed.
107
108 /* Initialize the input buffer */
109 Status = ConDrvInitInputBuffer(Console, 0 /* ConsoleInfo->InputBufferSize */);
110 if (!NT_SUCCESS(Status))
111 {
112 DPRINT1("ConDrvInitInputBuffer: failed, Status = 0x%08lx\n", Status);
114 return Status;
115 }
116
117 /* Set-up the code page */
118 if (IsValidCodePage(ConsoleInfo->CodePage))
119 {
121 Console->InputCodePage = ConsoleInfo->CodePage;
122 }
123
124 /* Initialize a new text-mode screen buffer with default settings */
125 ScreenBufferInfo.ScreenBufferSize = ConsoleInfo->ScreenBufferSize;
126 ScreenBufferInfo.ViewSize = ConsoleInfo->ConsoleSize;
127 ScreenBufferInfo.ScreenAttrib = ConsoleInfo->ScreenAttrib;
128 ScreenBufferInfo.PopupAttrib = ConsoleInfo->PopupAttrib;
129 ScreenBufferInfo.CursorSize = ConsoleInfo->CursorSize;
130 ScreenBufferInfo.IsCursorVisible = TRUE;
131
132 InitializeListHead(&Console->BufferList);
133 Status = ConDrvCreateScreenBuffer(&NewBuffer,
134 Console,
135 NULL,
138 if (!NT_SUCCESS(Status))
139 {
140 DPRINT1("ConDrvCreateScreenBuffer: failed, Status = 0x%08lx\n", Status);
143 return Status;
144 }
145 /* Make the new screen buffer active */
146 Console->ActiveBuffer = NewBuffer;
147 Console->ConsolePaused = FALSE;
148
149 DPRINT("Console initialized\n");
150
151 /* The initialization is finished */
152 DPRINT("Change state\n");
153 Console->State = CONSOLE_RUNNING;
154
155 /* The caller now has a newly initialized console */
156 return STATUS_SUCCESS;
157}
158
161 IN PTERMINAL Terminal)
162{
164
165 if (Console == NULL || Terminal == NULL)
167
168 /* FIXME: Lock the console before ?? */
169
170 /*
171 * Attach the terminal to the console. Use now the TermIFace of the console,
172 * and not the user-defined temporary Terminal pointer.
173 */
174 Console->TermIFace = *Terminal;
175 Console->TermIFace.Console = Console;
176
177 /* Initialize the terminal AFTER having attached it to the console */
178 DPRINT("Finish initialization of terminal\n");
179 Status = Console->TermIFace.Vtbl->InitTerminal(&Console->TermIFace, Console);
180 if (!NT_SUCCESS(Status))
181 {
182 DPRINT1("Terminal initialization failed, Status = 0x%08lx\n", Status);
183
184 /* We failed, detach the terminal from the console */
185 Terminal->Console = NULL; // For the caller
187 return Status;
188 }
189
190 /* Copy buffer contents to screen */
191 // Terminal.Draw();
192
193 DPRINT("Terminal initialization done\n");
194 return STATUS_SUCCESS;
195}
196
199{
201
202 /* FIXME: Lock the console before ?? */
203
204 /* Deinitialize the terminal BEFORE detaching it from the console */
205 Console->TermIFace.Vtbl->DeinitTerminal(&Console->TermIFace/*, Console*/);
206
207 /*
208 * Detach the terminal from the console:
209 * reinitialize the terminal interface.
210 */
212
213 DPRINT("Terminal unregistered\n");
214 return STATUS_SUCCESS;
215}
216
219{
220 DPRINT("ConDrvDeleteConsole(0x%p)\n", Console);
221
222 /*
223 * Forbid validation of any console by other threads
224 * during the deletion of this console.
225 */
226 // ConDrvLockConsoleListExclusive();
227
228 /*
229 * If the console is already being destroyed, i.e. not running
230 * or finishing to be initialized, just return.
231 */
234 {
235 return;
236 }
237
238 /*
239 * We are about to be destroyed. Signal it to other people
240 * so that they can terminate what they are doing, and that
241 * they cannot longer validate the console.
242 */
244
245 /*
246 * Allow other threads to finish their job: basically, unlock
247 * all other calls to EnterCriticalSection(&Console->Lock); by
248 * ConDrvValidateConsoleUnsafe() functions so that they just see
249 * that we are not in CONSOLE_RUNNING state anymore, or unlock
250 * other concurrent calls to ConDrvDeleteConsole() so that they
251 * can see that we are in fact already deleting the console.
252 */
254
255 /* Deregister the terminal */
256 DPRINT("Deregister terminal\n");
258 DPRINT("Terminal deregistered\n");
259
260 /***
261 * Check that the console is in terminating state before continuing
262 * (the cleanup code must not change the state of the console...
263 * ...unless to cancel console deletion ?).
264 ***/
265
267 {
268 return;
269 }
270
271 /* We are now in destruction */
273
274 /* We really delete the console. Reset the count to be sure. */
275 Console->ReferenceCount = 0;
276
277 /* Delete the last screen buffer */
278 ConDrvDeleteScreenBuffer(Console->ActiveBuffer);
279 Console->ActiveBuffer = NULL;
280 if (!IsListEmpty(&Console->BufferList))
281 {
282 /***ConDrvUnlockConsoleList();***/
283 ASSERTMSG("BUGBUGBUG!! screen buffer list not empty\n", FALSE);
284 }
285
286 /* Deinitialize the input buffer */
288
289 Console->ConsolePaused = FALSE;
290
291 DPRINT("ConDrvDeleteConsole - Unlocking\n");
293 DPRINT("ConDrvDeleteConsole - Destroying lock\n");
295 DPRINT("ConDrvDeleteConsole - Lock destroyed\n");
296
297 DPRINT("ConDrvDeleteConsole - Console destroyed\n");
298}
299
300
301/* PUBLIC DRIVER APIS *********************************************************/
302
305{
306 /* In case we are already paused, just exit... */
307 if (Console->ConsolePaused) return;
308
309 /* ... otherwise set the flag */
310 Console->ConsolePaused = TRUE;
311}
312
315{
316 /* In case we are already unpaused, just exit... */
317 if (!Console->ConsolePaused) return;
318
319 /* ... otherwise reset the flag */
320 Console->ConsolePaused = FALSE;
321}
322
326 OUT PULONG ConsoleMode)
327{
329
330 if (Console == NULL || Object == NULL || ConsoleMode == NULL)
332
333 /* Validity check */
334 ASSERT(Console == Object->Console);
335
336 /*** FIXME: */ *ConsoleMode = 0; /***/
337
338 if (INPUT_BUFFER == Object->Type)
339 {
341 *ConsoleMode = InputBuffer->Mode;
342 }
343 else if (TEXTMODE_BUFFER == Object->Type || GRAPHICS_BUFFER == Object->Type)
344 {
346 *ConsoleMode = Buffer->Mode;
347 }
348 else
349 {
351 }
352
353 return Status;
354}
355
359 IN ULONG ConsoleMode)
360{
361#define CONSOLE_VALID_INPUT_MODES ( ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | \
362 ENABLE_ECHO_INPUT | ENABLE_WINDOW_INPUT | \
363 ENABLE_MOUSE_INPUT )
364#define CONSOLE_VALID_OUTPUT_MODES ( ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT )
365
367
368 if (Console == NULL || Object == NULL)
370
371 /* Validity check */
372 ASSERT(Console == Object->Console);
373
374 if (INPUT_BUFFER == Object->Type)
375 {
377
378 /* Only the presence of valid mode flags is allowed */
379 if (ConsoleMode & ~CONSOLE_VALID_INPUT_MODES)
380 {
382 }
383 else
384 {
385 InputBuffer->Mode = (ConsoleMode & CONSOLE_VALID_INPUT_MODES);
386 }
387 }
388 else if (TEXTMODE_BUFFER == Object->Type || GRAPHICS_BUFFER == Object->Type)
389 {
391
392 /* Only the presence of valid mode flags is allowed */
393 if (ConsoleMode & ~CONSOLE_VALID_OUTPUT_MODES)
394 {
396 }
397 else
398 {
399 Buffer->Mode = (ConsoleMode & CONSOLE_VALID_OUTPUT_MODES);
400 }
401 }
402 else
403 {
405 }
406
407 return Status;
408}
409
412 OUT PUINT CodePage,
413 IN BOOLEAN OutputCP)
414{
415 if (Console == NULL || CodePage == NULL)
417
418 *CodePage = (OutputCP ? Console->OutputCodePage : Console->InputCodePage);
419
420 return STATUS_SUCCESS;
421}
422
425 IN UINT CodePage,
426 IN BOOLEAN OutputCP)
427{
428 if (Console == NULL || !IsValidCodePage(CodePage))
430
431 if (OutputCP)
432 {
433 /* Request the terminal to change its code page support */
434 if (!TermSetCodePage(Console, CodePage))
435 return STATUS_UNSUCCESSFUL;
436
437 /* All is fine, actually set the output code page */
438 CON_SET_OUTPUT_CP(Console, CodePage);
439 return STATUS_SUCCESS;
440 }
441 else
442 {
443 Console->InputCodePage = CodePage;
444 return STATUS_SUCCESS;
445 }
446}
447
448/* EOF */
unsigned char BOOLEAN
CConsole Console
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
Definition: bufpool.h:45
VOID NTAPI ConDrvDeinitInputBuffer(IN PCONSOLE Console)
Definition: coninput.c:221
NTSTATUS NTAPI ConDrvInitInputBuffer(IN PCONSOLE Console, IN ULONG InputBufferSize)
Definition: coninput.c:192
VOID NTAPI ConDrvDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer)
Definition: conoutput.c:130
NTSTATUS ConDrvCreateScreenBuffer(OUT PCONSOLE_SCREEN_BUFFER *Buffer, IN PCONSOLE Console, IN HANDLE ProcessHandle OPTIONAL, IN ULONG BufferType, IN PVOID ScreenBufferInfo)
Definition: conoutput.c:85
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOL WINAPI IsValidCodePage(UINT CodePage)
Definition: nls.c:1604
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
Status
Definition: gdiplustypes.h:25
#define ASSERT(a)
Definition: mode.c:44
unsigned int * PUINT
Definition: ndis.h:50
unsigned int UINT
Definition: ndis.h:50
CONSOLE_SCREEN_BUFFER_INFO ScreenBufferInfo
Definition: notevil.c:38
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
#define TEXTMODE_BUFFER
Definition: pccons.c:21
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
static CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo
Definition: video.c:47
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
#define TermSetCodePage(Console, CodePage)
Definition: term.h:38
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
BOOLEAN NTAPI ConDrvValidateConsoleState(IN PCONSOLE Console, IN CONSOLE_STATE ExpectedState)
Definition: console.c:24
VOID NTAPI ConDrvUnpause(PCONSOLE Console)
Definition: console.c:314
BOOLEAN NTAPI ConDrvValidateConsoleUnsafe(IN PCONSOLE Console, IN CONSOLE_STATE ExpectedState, IN BOOLEAN LockConsole)
Definition: console.c:36
VOID NTAPI ConDrvDeleteConsole(IN PCONSOLE Console)
Definition: console.c:218
NTSTATUS NTAPI ConDrvGetConsoleCP(IN PCONSOLE Console, OUT PUINT CodePage, IN BOOLEAN OutputCP)
Definition: console.c:411
#define CONSOLE_VALID_INPUT_MODES
NTSTATUS NTAPI ConDrvSetConsoleMode(IN PCONSOLE Console, IN PCONSOLE_IO_OBJECT Object, IN ULONG ConsoleMode)
Definition: console.c:357
#define CONSOLE_VALID_OUTPUT_MODES
NTSTATUS NTAPI ConDrvAttachTerminal(IN PCONSOLE Console, IN PTERMINAL Terminal)
Definition: console.c:160
VOID ResetTerminal(IN PCONSOLE Console)
Definition: dummyterm.c:164
NTSTATUS NTAPI ConDrvSetConsoleCP(IN PCONSOLE Console, IN UINT CodePage, IN BOOLEAN OutputCP)
Definition: console.c:424
NTSTATUS NTAPI ConDrvDetachTerminal(IN PCONSOLE Console)
Definition: console.c:198
NTSTATUS NTAPI ConDrvGetConsoleMode(IN PCONSOLE Console, IN PCONSOLE_IO_OBJECT Object, OUT PULONG ConsoleMode)
Definition: console.c:324
NTSTATUS NTAPI ConDrvInitConsole(IN OUT PCONSOLE Console, IN PCONSOLE_INFO ConsoleInfo)
Definition: console.c:69
VOID NTAPI ConDrvPause(PCONSOLE Console)
Definition: console.c:304
struct _CONSOLE_INPUT_BUFFER * PCONSOLE_INPUT_BUFFER
@ INPUT_BUFFER
Definition: conio.h:28
@ GRAPHICS_BUFFER
Definition: conio.h:26
#define CON_SET_OUTPUT_CP(Console, CodePage)
Definition: conio.h:323
struct _CONSOLE_SCREEN_BUFFER * PCONSOLE_SCREEN_BUFFER
@ CONSOLE_IN_DESTRUCTION
Definition: conio.h:285
@ CONSOLE_TERMINATING
Definition: conio.h:284
@ CONSOLE_RUNNING
Definition: conio.h:283
@ CONSOLE_INITIALIZING
Definition: conio.h:282
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define CONSOLE_TEXTMODE_BUFFER
Definition: wincon.h:62