3 * Copyright (C) 2002 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS text-mode setup
22 * FILE: base/setup/usetup/console.c
23 * PURPOSE: Console support functions
27 /* INCLUDES ******************************************************************/
30 /* Blue Driver Header */
31 #include <blue/ntddblue.h>
37 /* DATA **********************************************************************/
39 static BOOLEAN InputQueueEmpty
;
40 static BOOLEAN WaitForInput
;
41 static KEYBOARD_INPUT_DATA InputDataQueue
; // Only one element!
42 static IO_STATUS_BLOCK InputIosb
;
44 /* FUNCTIONS *****************************************************************/
50 UNICODE_STRING ScreenName
= RTL_CONSTANT_STRING(L
"\\??\\BlueScreen");
51 UNICODE_STRING KeyboardName
= RTL_CONSTANT_STRING(L
"\\Device\\KeyboardClass0");
52 OBJECT_ATTRIBUTES ObjectAttributes
;
53 IO_STATUS_BLOCK IoStatusBlock
;
57 InitializeObjectAttributes(&ObjectAttributes
,
62 Status
= NtOpenFile(&StdOutput
,
67 FILE_SYNCHRONOUS_IO_ALERT
);
68 if (!NT_SUCCESS(Status
))
71 /* Open the keyboard */
72 InitializeObjectAttributes(&ObjectAttributes
,
77 Status
= NtOpenFile(&StdInput
,
83 if (!NT_SUCCESS(Status
))
86 /* Reset the queue state */
87 InputQueueEmpty
= TRUE
;
107 /* Reset the queue state */
108 InputQueueEmpty
= TRUE
;
109 WaitForInput
= FALSE
;
111 if (StdInput
!= INVALID_HANDLE_VALUE
)
114 if (StdOutput
!= INVALID_HANDLE_VALUE
)
124 IN HANDLE hConsoleOutput
,
125 IN
const VOID
*lpBuffer
,
126 IN DWORD nNumberOfCharsToWrite
,
127 OUT LPDWORD lpNumberOfCharsWritten
,
128 IN LPVOID lpReserved
)
130 IO_STATUS_BLOCK IoStatusBlock
;
133 Status
= NtWriteFile(hConsoleOutput
,
139 nNumberOfCharsToWrite
,
142 if (!NT_SUCCESS(Status
))
145 *lpNumberOfCharsWritten
= IoStatusBlock
.Information
;
157 case STD_INPUT_HANDLE
:
159 case STD_OUTPUT_HANDLE
:
162 return INVALID_HANDLE_VALUE
;
169 FlushConsoleInputBuffer(
170 IN HANDLE hConsoleInput
)
173 LARGE_INTEGER Offset
, Timeout
;
174 IO_STATUS_BLOCK IoStatusBlock
;
175 KEYBOARD_INPUT_DATA InputData
;
177 /* Cancel any pending read */
179 NtCancelIoFile(hConsoleInput
, &IoStatusBlock
);
181 /* Reset the queue state */
182 InputQueueEmpty
= TRUE
;
183 WaitForInput
= FALSE
;
185 /* Flush the keyboard buffer */
189 Status
= NtReadFile(hConsoleInput
,
198 if (Status
== STATUS_PENDING
)
200 Timeout
.QuadPart
= -100;
201 Status
= NtWaitForSingleObject(hConsoleInput
, FALSE
, &Timeout
);
202 if (Status
== STATUS_TIMEOUT
)
204 NtCancelIoFile(hConsoleInput
, &IoStatusBlock
);
208 } while (NT_SUCCESS(Status
));
216 IN HANDLE hConsoleInput
,
217 OUT PINPUT_RECORD lpBuffer
,
219 OUT LPDWORD lpNumberOfEventsRead
)
222 LARGE_INTEGER Offset
, Timeout
;
223 KEYBOARD_INPUT_DATA InputData
;
227 /* Read the keyboard for an event, without waiting */
231 Status
= NtReadFile(hConsoleInput
,
237 sizeof(InputDataQueue
),
240 if (!NT_SUCCESS(Status
))
242 if (Status
== STATUS_PENDING
)
244 /* No input yet, we will have to wait next time */
245 *lpNumberOfEventsRead
= 0;
253 * We already tried to read from the keyboard and are
254 * waiting for data, check whether something showed up.
256 Timeout
.QuadPart
= -100; // Wait just a little bit.
257 Status
= NtWaitForSingleObject(hConsoleInput
, FALSE
, &Timeout
);
258 if (Status
== STATUS_TIMEOUT
)
260 /* Nothing yet, continue waiting next time */
261 *lpNumberOfEventsRead
= 0;
265 WaitForInput
= FALSE
;
266 if (!NT_SUCCESS(Status
))
270 /* We got something in the queue */
271 InputQueueEmpty
= FALSE
;
272 WaitForInput
= FALSE
;
275 /* Fetch from the queue but keep it inside */
276 InputData
= InputDataQueue
;
278 lpBuffer
->EventType
= KEY_EVENT
;
279 Status
= IntTranslateKey(hConsoleInput
, &InputData
, &lpBuffer
->Event
.KeyEvent
);
280 if (!NT_SUCCESS(Status
))
283 *lpNumberOfEventsRead
= 1;
291 IN HANDLE hConsoleInput
,
292 OUT PINPUT_RECORD lpBuffer
,
294 OUT LPDWORD lpNumberOfEventsRead
)
297 LARGE_INTEGER Offset
;
298 KEYBOARD_INPUT_DATA InputData
;
302 /* Read the keyboard and wait for an event, skipping the queue */
306 Status
= NtReadFile(hConsoleInput
,
312 sizeof(InputDataQueue
),
315 if (Status
== STATUS_PENDING
)
317 /* Block and wait for input */
319 Status
= NtWaitForSingleObject(hConsoleInput
, FALSE
, NULL
);
320 WaitForInput
= FALSE
;
321 Status
= InputIosb
.Status
;
323 if (!NT_SUCCESS(Status
))
329 * We already tried to read from the keyboard and are
330 * waiting for data, block and wait for input.
332 Status
= NtWaitForSingleObject(hConsoleInput
, FALSE
, NULL
);
333 WaitForInput
= FALSE
;
334 Status
= InputIosb
.Status
;
335 if (!NT_SUCCESS(Status
))
340 /* Fetch from the queue and empty it */
341 InputData
= InputDataQueue
;
342 InputQueueEmpty
= TRUE
;
344 lpBuffer
->EventType
= KEY_EVENT
;
345 Status
= IntTranslateKey(hConsoleInput
, &InputData
, &lpBuffer
->Event
.KeyEvent
);
346 if (!NT_SUCCESS(Status
))
349 *lpNumberOfEventsRead
= 1;
356 WriteConsoleOutputCharacterA(
357 HANDLE hConsoleOutput
,
358 IN LPCSTR lpCharacter
,
360 IN COORD dwWriteCoord
,
361 OUT LPDWORD lpNumberOfCharsWritten
)
363 IO_STATUS_BLOCK IoStatusBlock
;
369 Buffer
= (CHAR
*)RtlAllocateHeap(ProcessHeap
,
371 nLength
+ sizeof(COORD
));
372 pCoord
= (COORD
*)Buffer
;
373 pText
= (PCHAR
)(pCoord
+ 1);
375 *pCoord
= dwWriteCoord
;
376 memcpy(pText
, lpCharacter
, nLength
);
378 Status
= NtDeviceIoControlFile(hConsoleOutput
,
383 IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER
,
387 nLength
+ sizeof(COORD
));
389 RtlFreeHeap(ProcessHeap
, 0, Buffer
);
390 if (!NT_SUCCESS(Status
))
393 *lpNumberOfCharsWritten
= IoStatusBlock
.Information
;
400 WriteConsoleOutputCharacterW(
401 HANDLE hConsoleOutput
,
402 IN LPCWSTR lpCharacter
,
404 IN COORD dwWriteCoord
,
405 OUT LPDWORD lpNumberOfCharsWritten
)
407 IO_STATUS_BLOCK IoStatusBlock
;
414 UNICODE_STRING UnicodeString
;
415 OEM_STRING OemString
;
418 UnicodeString
.Length
= nLength
* sizeof(WCHAR
);
419 UnicodeString
.MaximumLength
= nLength
* sizeof(WCHAR
);
420 UnicodeString
.Buffer
= (LPWSTR
)lpCharacter
;
422 OemLength
= RtlUnicodeStringToOemSize(&UnicodeString
);
425 Buffer
= (CHAR
*)RtlAllocateHeap(ProcessHeap
,
427 OemLength
+ sizeof(COORD
));
428 // nLength + sizeof(COORD));
432 pCoord
= (COORD
*)Buffer
;
433 pText
= (PCHAR
)(pCoord
+ 1);
435 *pCoord
= dwWriteCoord
;
437 OemString
.Length
= 0;
438 OemString
.MaximumLength
= OemLength
;
439 OemString
.Buffer
= pText
;
441 Status
= RtlUnicodeStringToOemString(&OemString
,
444 if (!NT_SUCCESS(Status
))
447 /* FIXME: use real unicode->oem conversion */
448 // for (i = 0; i < nLength; i++)
449 // pText[i] = (CHAR)lpCharacter[i];
451 Status
= NtDeviceIoControlFile(hConsoleOutput
,
456 IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER
,
460 nLength
+ sizeof(COORD
));
463 RtlFreeHeap(ProcessHeap
, 0, Buffer
);
464 if (!NT_SUCCESS(Status
))
467 *lpNumberOfCharsWritten
= IoStatusBlock
.Information
;
474 FillConsoleOutputAttribute(
475 IN HANDLE hConsoleOutput
,
478 IN COORD dwWriteCoord
,
479 OUT LPDWORD lpNumberOfAttrsWritten
)
481 IO_STATUS_BLOCK IoStatusBlock
;
482 OUTPUT_ATTRIBUTE Buffer
;
485 Buffer
.wAttribute
= wAttribute
;
486 Buffer
.nLength
= nLength
;
487 Buffer
.dwCoord
= dwWriteCoord
;
489 Status
= NtDeviceIoControlFile(hConsoleOutput
,
494 IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE
,
496 sizeof(OUTPUT_ATTRIBUTE
),
498 sizeof(OUTPUT_ATTRIBUTE
));
499 if (!NT_SUCCESS(Status
))
502 *lpNumberOfAttrsWritten
= Buffer
.dwTransfered
;
509 FillConsoleOutputCharacterA(
510 IN HANDLE hConsoleOutput
,
513 IN COORD dwWriteCoord
,
514 OUT LPDWORD lpNumberOfCharsWritten
)
516 IO_STATUS_BLOCK IoStatusBlock
;
517 OUTPUT_CHARACTER Buffer
;
520 Buffer
.cCharacter
= cCharacter
;
521 Buffer
.nLength
= nLength
;
522 Buffer
.dwCoord
= dwWriteCoord
;
524 Status
= NtDeviceIoControlFile(hConsoleOutput
,
529 IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER
,
531 sizeof(OUTPUT_CHARACTER
),
533 sizeof(OUTPUT_CHARACTER
));
534 if (!NT_SUCCESS(Status
))
537 *lpNumberOfCharsWritten
= Buffer
.dwTransfered
;
544 GetConsoleScreenBufferInfo(
545 IN HANDLE hConsoleOutput
,
546 OUT PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo
)
548 IO_STATUS_BLOCK IoStatusBlock
;
551 Status
= NtDeviceIoControlFile(hConsoleOutput
,
556 IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO
,
559 lpConsoleScreenBufferInfo
,
560 sizeof(CONSOLE_SCREEN_BUFFER_INFO
));
561 return NT_SUCCESS(Status
);
567 SetConsoleCursorInfo(
568 IN HANDLE hConsoleOutput
,
569 IN
const CONSOLE_CURSOR_INFO
*lpConsoleCursorInfo
)
571 IO_STATUS_BLOCK IoStatusBlock
;
574 Status
= NtDeviceIoControlFile(hConsoleOutput
,
579 IOCTL_CONSOLE_SET_CURSOR_INFO
,
580 (PCONSOLE_CURSOR_INFO
)lpConsoleCursorInfo
,
581 sizeof(CONSOLE_CURSOR_INFO
),
584 return NT_SUCCESS(Status
);
590 SetConsoleCursorPosition(
591 IN HANDLE hConsoleOutput
,
592 IN COORD dwCursorPosition
)
594 CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo
;
595 IO_STATUS_BLOCK IoStatusBlock
;
598 Status
= GetConsoleScreenBufferInfo(hConsoleOutput
, &ConsoleScreenBufferInfo
);
599 if (!NT_SUCCESS(Status
))
602 ConsoleScreenBufferInfo
.dwCursorPosition
.X
= dwCursorPosition
.X
;
603 ConsoleScreenBufferInfo
.dwCursorPosition
.Y
= dwCursorPosition
.Y
;
605 Status
= NtDeviceIoControlFile(hConsoleOutput
,
610 IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO
,
611 &ConsoleScreenBufferInfo
,
612 sizeof(CONSOLE_SCREEN_BUFFER_INFO
),
615 return NT_SUCCESS(Status
);
621 SetConsoleTextAttribute(
622 IN HANDLE hConsoleOutput
,
625 IO_STATUS_BLOCK IoStatusBlock
;
628 Status
= NtDeviceIoControlFile(hConsoleOutput
,
633 IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE
,
638 return NT_SUCCESS(Status
);
647 HANDLE hConsoleOutput
;
648 IO_STATUS_BLOCK IoStatusBlock
;
651 hConsoleOutput
= GetStdHandle(STD_OUTPUT_HANDLE
);
653 Status
= NtDeviceIoControlFile(hConsoleOutput
,
658 IOCTL_CONSOLE_LOADFONT
,
663 return NT_SUCCESS(Status
);