xref: /reactos/base/setup/usetup/console.c (revision aad80191)
1 /*
2  *  ReactOS kernel
3  *  Copyright (C) 2002 ReactOS Team
4  *
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.
9  *
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.
14  *
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.
18  */
19 /*
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
24  * PROGRAMMER:
25  */
26 
27 /* INCLUDES ******************************************************************/
28 
29 #include <usetup.h>
30 /* Blue Driver Header */
31 #include <blue/ntddblue.h>
32 #include "keytrans.h"
33 
34 #define NDEBUG
35 #include <debug.h>
36 
37 /* FUNCTIONS *****************************************************************/
38 
39 BOOL
40 WINAPI
41 AllocConsole(VOID)
42 {
43     UNICODE_STRING ScreenName = RTL_CONSTANT_STRING(L"\\??\\BlueScreen");
44     UNICODE_STRING KeyboardName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
45     OBJECT_ATTRIBUTES ObjectAttributes;
46     IO_STATUS_BLOCK IoStatusBlock;
47     NTSTATUS Status;
48 
49     /* Open the screen */
50     InitializeObjectAttributes(&ObjectAttributes,
51                                &ScreenName,
52                                0,
53                                NULL,
54                                NULL);
55     Status = NtOpenFile(&StdOutput,
56                         FILE_ALL_ACCESS,
57                         &ObjectAttributes,
58                         &IoStatusBlock,
59                         FILE_OPEN,
60                         FILE_SYNCHRONOUS_IO_ALERT);
61     if (!NT_SUCCESS(Status))
62         return FALSE;
63 
64     /* Open the keyboard */
65     InitializeObjectAttributes(&ObjectAttributes,
66                                &KeyboardName,
67                                0,
68                                NULL,
69                                NULL);
70     Status = NtOpenFile(&StdInput,
71                         FILE_ALL_ACCESS,
72                         &ObjectAttributes,
73                         &IoStatusBlock,
74                         FILE_OPEN,
75                         0);
76     if (!NT_SUCCESS(Status))
77         return FALSE;
78 
79     return TRUE;
80 }
81 
82 
83 BOOL
84 WINAPI
85 AttachConsole(
86     IN DWORD dwProcessId)
87 {
88     return FALSE;
89 }
90 
91 
92 BOOL
93 WINAPI
94 FreeConsole(VOID)
95 {
96     if (StdInput != INVALID_HANDLE_VALUE)
97         NtClose(StdInput);
98 
99     if (StdOutput != INVALID_HANDLE_VALUE)
100         NtClose(StdOutput);
101 
102     return TRUE;
103 }
104 
105 
106 BOOL
107 WINAPI
108 WriteConsole(
109     IN HANDLE hConsoleOutput,
110     IN const VOID *lpBuffer,
111     IN DWORD nNumberOfCharsToWrite,
112     OUT LPDWORD lpNumberOfCharsWritten,
113     IN LPVOID lpReserved)
114 {
115     IO_STATUS_BLOCK IoStatusBlock;
116     NTSTATUS Status;
117 
118     Status = NtWriteFile(hConsoleOutput,
119                          NULL,
120                          NULL,
121                          NULL,
122                          &IoStatusBlock,
123                          (PVOID)lpBuffer,
124                          nNumberOfCharsToWrite,
125                          NULL,
126                          NULL);
127     if (!NT_SUCCESS(Status))
128         return FALSE;
129 
130     *lpNumberOfCharsWritten = IoStatusBlock.Information;
131     return TRUE;
132 }
133 
134 
135 HANDLE
136 WINAPI
137 GetStdHandle(
138     IN DWORD nStdHandle)
139 {
140     switch (nStdHandle)
141     {
142         case STD_INPUT_HANDLE:
143             return StdInput;
144         case STD_OUTPUT_HANDLE:
145             return StdOutput;
146         default:
147             return INVALID_HANDLE_VALUE;
148     }
149 }
150 
151 
152 BOOL
153 WINAPI
154 FlushConsoleInputBuffer(
155     IN HANDLE hConsoleInput)
156 {
157     LARGE_INTEGER Offset, Timeout;
158     IO_STATUS_BLOCK IoStatusBlock;
159     KEYBOARD_INPUT_DATA InputData;
160     NTSTATUS Status;
161 
162     do
163     {
164         Offset.QuadPart = 0;
165         Status = NtReadFile(hConsoleInput,
166                             NULL,
167                             NULL,
168                             NULL,
169                             &IoStatusBlock,
170                             &InputData,
171                             sizeof(KEYBOARD_INPUT_DATA),
172                             &Offset,
173                             NULL);
174         if (Status == STATUS_PENDING)
175         {
176             Timeout.QuadPart = -100;
177             Status = NtWaitForSingleObject(hConsoleInput, FALSE, &Timeout);
178             if (Status == STATUS_TIMEOUT)
179             {
180                 NtCancelIoFile(hConsoleInput, &IoStatusBlock);
181                 return TRUE;
182             }
183         }
184     } while (NT_SUCCESS(Status));
185     return FALSE;
186 }
187 
188 
189 BOOL
190 WINAPI
191 ReadConsoleInput(
192     IN HANDLE hConsoleInput,
193     OUT PINPUT_RECORD lpBuffer,
194     IN DWORD nLength,
195     OUT LPDWORD lpNumberOfEventsRead)
196 {
197     LARGE_INTEGER Offset;
198     IO_STATUS_BLOCK IoStatusBlock;
199     KEYBOARD_INPUT_DATA InputData;
200     NTSTATUS Status;
201 
202     Offset.QuadPart = 0;
203     Status = NtReadFile(hConsoleInput,
204                         NULL,
205                         NULL,
206                         NULL,
207                         &IoStatusBlock,
208                         &InputData,
209                         sizeof(KEYBOARD_INPUT_DATA),
210                         &Offset,
211                         NULL);
212     if (Status == STATUS_PENDING)
213     {
214         Status = NtWaitForSingleObject(hConsoleInput, FALSE, NULL);
215         Status = IoStatusBlock.Status;
216     }
217     if (!NT_SUCCESS(Status))
218         return FALSE;
219 
220     lpBuffer->EventType = KEY_EVENT;
221     Status = IntTranslateKey(hConsoleInput, &InputData, &lpBuffer->Event.KeyEvent);
222     if (!NT_SUCCESS(Status))
223         return FALSE;
224 
225     *lpNumberOfEventsRead = 1;
226     return TRUE;
227 }
228 
229 
230 BOOL
231 WINAPI
232 WriteConsoleOutputCharacterA(
233     HANDLE hConsoleOutput,
234     IN LPCSTR lpCharacter,
235     IN DWORD nLength,
236     IN COORD dwWriteCoord,
237     OUT LPDWORD lpNumberOfCharsWritten)
238 {
239     IO_STATUS_BLOCK IoStatusBlock;
240     PCHAR Buffer;
241     COORD *pCoord;
242     PCHAR pText;
243     NTSTATUS Status;
244 
245     Buffer = (CHAR*)RtlAllocateHeap(ProcessHeap,
246                                     0,
247                                     nLength + sizeof(COORD));
248     pCoord = (COORD *)Buffer;
249     pText = (PCHAR)(pCoord + 1);
250 
251     *pCoord = dwWriteCoord;
252     memcpy(pText, lpCharacter, nLength);
253 
254     Status = NtDeviceIoControlFile(hConsoleOutput,
255                                    NULL,
256                                    NULL,
257                                    NULL,
258                                    &IoStatusBlock,
259                                    IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
260                                    NULL,
261                                    0,
262                                    Buffer,
263                                    nLength + sizeof(COORD));
264 
265     RtlFreeHeap(ProcessHeap, 0, Buffer);
266     if (!NT_SUCCESS(Status))
267         return FALSE;
268 
269     *lpNumberOfCharsWritten = IoStatusBlock.Information;
270     return TRUE;
271 }
272 
273 
274 BOOL
275 WINAPI
276 WriteConsoleOutputCharacterW(
277     HANDLE hConsoleOutput,
278     IN LPCWSTR lpCharacter,
279     IN DWORD nLength,
280     IN COORD dwWriteCoord,
281     OUT LPDWORD lpNumberOfCharsWritten)
282 {
283     IO_STATUS_BLOCK IoStatusBlock;
284     PCHAR Buffer;
285     COORD *pCoord;
286     PCHAR pText;
287     NTSTATUS Status;
288 //    ULONG i;
289 
290     UNICODE_STRING UnicodeString;
291     OEM_STRING OemString;
292     ULONG OemLength;
293 
294     UnicodeString.Length = nLength * sizeof(WCHAR);
295     UnicodeString.MaximumLength = nLength * sizeof(WCHAR);
296     UnicodeString.Buffer = (LPWSTR)lpCharacter;
297 
298     OemLength = RtlUnicodeStringToOemSize(&UnicodeString);
299 
300 
301     Buffer = (CHAR*)RtlAllocateHeap(ProcessHeap,
302                                     0,
303                                     OemLength + sizeof(COORD));
304 //                                    nLength + sizeof(COORD));
305     if (Buffer== NULL)
306         return FALSE;
307 
308     pCoord = (COORD *)Buffer;
309     pText = (PCHAR)(pCoord + 1);
310 
311     *pCoord = dwWriteCoord;
312 
313     OemString.Length = 0;
314     OemString.MaximumLength = OemLength;
315     OemString.Buffer = pText;
316 
317     Status = RtlUnicodeStringToOemString(&OemString,
318                                          &UnicodeString,
319                                          FALSE);
320     if (!NT_SUCCESS(Status))
321         goto done;
322 
323     /* FIXME: use real unicode->oem conversion */
324 //    for (i = 0; i < nLength; i++)
325 //        pText[i] = (CHAR)lpCharacter[i];
326 
327     Status = NtDeviceIoControlFile(hConsoleOutput,
328                                    NULL,
329                                    NULL,
330                                    NULL,
331                                    &IoStatusBlock,
332                                    IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
333                                    NULL,
334                                    0,
335                                    Buffer,
336                                    nLength + sizeof(COORD));
337 
338 done:
339     RtlFreeHeap(ProcessHeap, 0, Buffer);
340     if (!NT_SUCCESS(Status))
341         return FALSE;
342 
343     *lpNumberOfCharsWritten = IoStatusBlock.Information;
344     return TRUE;
345 }
346 
347 
348 BOOL
349 WINAPI
350 FillConsoleOutputAttribute(
351     IN HANDLE hConsoleOutput,
352     IN WORD wAttribute,
353     IN DWORD nLength,
354     IN COORD dwWriteCoord,
355     OUT LPDWORD lpNumberOfAttrsWritten)
356 {
357     IO_STATUS_BLOCK IoStatusBlock;
358     OUTPUT_ATTRIBUTE Buffer;
359     NTSTATUS Status;
360 
361     Buffer.wAttribute = wAttribute;
362     Buffer.nLength    = nLength;
363     Buffer.dwCoord    = dwWriteCoord;
364 
365     Status = NtDeviceIoControlFile(hConsoleOutput,
366                                    NULL,
367                                    NULL,
368                                    NULL,
369                                    &IoStatusBlock,
370                                    IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE,
371                                    &Buffer,
372                                    sizeof(OUTPUT_ATTRIBUTE),
373                                    &Buffer,
374                                    sizeof(OUTPUT_ATTRIBUTE));
375     if (!NT_SUCCESS(Status))
376         return FALSE;
377 
378     *lpNumberOfAttrsWritten = Buffer.dwTransfered;
379     return TRUE;
380 }
381 
382 
383 BOOL
384 WINAPI
385 FillConsoleOutputCharacterA(
386     IN HANDLE hConsoleOutput,
387     IN CHAR cCharacter,
388     IN DWORD nLength,
389     IN COORD dwWriteCoord,
390     OUT LPDWORD lpNumberOfCharsWritten)
391 {
392     IO_STATUS_BLOCK IoStatusBlock;
393     OUTPUT_CHARACTER Buffer;
394     NTSTATUS Status;
395 
396     Buffer.cCharacter = cCharacter;
397     Buffer.nLength = nLength;
398     Buffer.dwCoord = dwWriteCoord;
399 
400     Status = NtDeviceIoControlFile(hConsoleOutput,
401                                    NULL,
402                                    NULL,
403                                    NULL,
404                                    &IoStatusBlock,
405                                    IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER,
406                                    &Buffer,
407                                    sizeof(OUTPUT_CHARACTER),
408                                    &Buffer,
409                                    sizeof(OUTPUT_CHARACTER));
410     if (!NT_SUCCESS(Status))
411         return FALSE;
412 
413     *lpNumberOfCharsWritten = Buffer.dwTransfered;
414     return TRUE;
415 }
416 
417 
418 BOOL
419 WINAPI
420 GetConsoleScreenBufferInfo(
421     IN HANDLE hConsoleOutput,
422     OUT PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
423 {
424     IO_STATUS_BLOCK IoStatusBlock;
425     NTSTATUS Status;
426 
427     Status = NtDeviceIoControlFile(hConsoleOutput,
428                                    NULL,
429                                    NULL,
430                                    NULL,
431                                    &IoStatusBlock,
432                                    IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO,
433                                    NULL,
434                                    0,
435                                    lpConsoleScreenBufferInfo,
436                                    sizeof(CONSOLE_SCREEN_BUFFER_INFO));
437     return NT_SUCCESS(Status);
438 }
439 
440 
441 BOOL
442 WINAPI
443 SetConsoleCursorInfo(
444     IN HANDLE hConsoleOutput,
445     IN const CONSOLE_CURSOR_INFO *lpConsoleCursorInfo)
446 {
447     IO_STATUS_BLOCK IoStatusBlock;
448     NTSTATUS Status;
449 
450     Status = NtDeviceIoControlFile(hConsoleOutput,
451                                    NULL,
452                                    NULL,
453                                    NULL,
454                                    &IoStatusBlock,
455                                    IOCTL_CONSOLE_SET_CURSOR_INFO,
456                                    (PCONSOLE_CURSOR_INFO)lpConsoleCursorInfo,
457                                    sizeof(CONSOLE_CURSOR_INFO),
458                                    NULL,
459                                    0);
460     return NT_SUCCESS(Status);
461 }
462 
463 
464 BOOL
465 WINAPI
466 SetConsoleCursorPosition(
467     IN HANDLE hConsoleOutput,
468     IN COORD dwCursorPosition)
469 {
470     CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
471     IO_STATUS_BLOCK IoStatusBlock;
472     NTSTATUS Status;
473 
474     Status = GetConsoleScreenBufferInfo(hConsoleOutput, &ConsoleScreenBufferInfo);
475     if (!NT_SUCCESS(Status))
476         return FALSE;
477 
478     ConsoleScreenBufferInfo.dwCursorPosition.X = dwCursorPosition.X;
479     ConsoleScreenBufferInfo.dwCursorPosition.Y = dwCursorPosition.Y;
480 
481     Status = NtDeviceIoControlFile(hConsoleOutput,
482                                    NULL,
483                                    NULL,
484                                    NULL,
485                                    &IoStatusBlock,
486                                    IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO,
487                                    &ConsoleScreenBufferInfo,
488                                    sizeof(CONSOLE_SCREEN_BUFFER_INFO),
489                                    NULL,
490                                    0);
491     return NT_SUCCESS(Status);
492 }
493 
494 
495 BOOL
496 WINAPI
497 SetConsoleTextAttribute(
498     IN HANDLE hConsoleOutput,
499     IN WORD wAttributes)
500 {
501     IO_STATUS_BLOCK IoStatusBlock;
502     NTSTATUS Status;
503 
504     Status = NtDeviceIoControlFile(hConsoleOutput,
505                                    NULL,
506                                    NULL,
507                                    NULL,
508                                    &IoStatusBlock,
509                                    IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE,
510                                    &wAttributes,
511                                    sizeof(USHORT),
512                                    NULL,
513                                    0);
514     return NT_SUCCESS(Status);
515 }
516 
517 
518 BOOL
519 WINAPI
520 SetConsoleOutputCP(
521     IN UINT wCodepage)
522 {
523     HANDLE hConsoleOutput;
524     IO_STATUS_BLOCK IoStatusBlock;
525     NTSTATUS Status;
526 
527     hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
528 
529     Status = NtDeviceIoControlFile(hConsoleOutput,
530                                    NULL,
531                                    NULL,
532                                    NULL,
533                                    &IoStatusBlock,
534                                    IOCTL_CONSOLE_LOADFONT,
535                                    &wCodepage,
536                                    sizeof(ULONG),
537                                    NULL,
538                                    0);
539     return NT_SUCCESS(Status);
540 }
541 
542 
543 /* EOF */
544