5aec605f168e2f08e898ba9822d5aece2611ebe0
[reactos.git] / reactos / base / setup / usetup / native / utils / console.c
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/native/utils/console.c
23 * PURPOSE: Console support functions
24 * PROGRAMMER: Eric Kohl
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 0);
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 0);
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(&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 */