Sync with trunk r63343.
[reactos.git] / 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: subsys/system/usetup/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 Buffer = (CHAR*)RtlAllocateHeap(ProcessHeap,
291 0,
292 nLength + sizeof(COORD));
293 pCoord = (COORD *)Buffer;
294 pText = (PCHAR)(pCoord + 1);
295
296 *pCoord = dwWriteCoord;
297
298 /* FIXME: use real unicode->oem conversion */
299 for (i = 0; i < nLength; i++)
300 pText[i] = (CHAR)lpCharacter[i];
301
302 Status = NtDeviceIoControlFile(hConsoleOutput,
303 NULL,
304 NULL,
305 NULL,
306 &IoStatusBlock,
307 IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
308 NULL,
309 0,
310 Buffer,
311 nLength + sizeof(COORD));
312
313 RtlFreeHeap(ProcessHeap, 0, Buffer);
314 if (!NT_SUCCESS(Status))
315 return FALSE;
316
317 *lpNumberOfCharsWritten = IoStatusBlock.Information;
318 return TRUE;
319 }
320
321
322 BOOL
323 WINAPI
324 FillConsoleOutputAttribute(
325 IN HANDLE hConsoleOutput,
326 IN WORD wAttribute,
327 IN DWORD nLength,
328 IN COORD dwWriteCoord,
329 OUT LPDWORD lpNumberOfAttrsWritten)
330 {
331 IO_STATUS_BLOCK IoStatusBlock;
332 OUTPUT_ATTRIBUTE Buffer;
333 NTSTATUS Status;
334
335 Buffer.wAttribute = wAttribute;
336 Buffer.nLength = nLength;
337 Buffer.dwCoord = dwWriteCoord;
338
339 Status = NtDeviceIoControlFile(hConsoleOutput,
340 NULL,
341 NULL,
342 NULL,
343 &IoStatusBlock,
344 IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE,
345 &Buffer,
346 sizeof(OUTPUT_ATTRIBUTE),
347 &Buffer,
348 sizeof(OUTPUT_ATTRIBUTE));
349 if (!NT_SUCCESS(Status))
350 return FALSE;
351
352 *lpNumberOfAttrsWritten = Buffer.dwTransfered;
353 return TRUE;
354 }
355
356
357 BOOL
358 WINAPI
359 FillConsoleOutputCharacterA(
360 IN HANDLE hConsoleOutput,
361 IN CHAR cCharacter,
362 IN DWORD nLength,
363 IN COORD dwWriteCoord,
364 OUT LPDWORD lpNumberOfCharsWritten)
365 {
366 IO_STATUS_BLOCK IoStatusBlock;
367 OUTPUT_CHARACTER Buffer;
368 NTSTATUS Status;
369
370 Buffer.cCharacter = cCharacter;
371 Buffer.nLength = nLength;
372 Buffer.dwCoord = dwWriteCoord;
373
374 Status = NtDeviceIoControlFile(hConsoleOutput,
375 NULL,
376 NULL,
377 NULL,
378 &IoStatusBlock,
379 IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER,
380 &Buffer,
381 sizeof(OUTPUT_CHARACTER),
382 &Buffer,
383 sizeof(OUTPUT_CHARACTER));
384 if (!NT_SUCCESS(Status))
385 return FALSE;
386
387 *lpNumberOfCharsWritten = Buffer.dwTransfered;
388 return TRUE;
389 }
390
391
392 BOOL
393 WINAPI
394 GetConsoleScreenBufferInfo(
395 IN HANDLE hConsoleOutput,
396 OUT PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
397 {
398 IO_STATUS_BLOCK IoStatusBlock;
399 NTSTATUS Status;
400
401 Status = NtDeviceIoControlFile(hConsoleOutput,
402 NULL,
403 NULL,
404 NULL,
405 &IoStatusBlock,
406 IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO,
407 NULL,
408 0,
409 lpConsoleScreenBufferInfo,
410 sizeof(CONSOLE_SCREEN_BUFFER_INFO));
411 return NT_SUCCESS(Status);
412 }
413
414
415 BOOL
416 WINAPI
417 SetConsoleCursorInfo(
418 IN HANDLE hConsoleOutput,
419 IN const CONSOLE_CURSOR_INFO *lpConsoleCursorInfo)
420 {
421 IO_STATUS_BLOCK IoStatusBlock;
422 NTSTATUS Status;
423
424 Status = NtDeviceIoControlFile(hConsoleOutput,
425 NULL,
426 NULL,
427 NULL,
428 &IoStatusBlock,
429 IOCTL_CONSOLE_SET_CURSOR_INFO,
430 (PCONSOLE_CURSOR_INFO)lpConsoleCursorInfo,
431 sizeof(CONSOLE_CURSOR_INFO),
432 NULL,
433 0);
434 return NT_SUCCESS(Status);
435 }
436
437
438 BOOL
439 WINAPI
440 SetConsoleCursorPosition(
441 IN HANDLE hConsoleOutput,
442 IN COORD dwCursorPosition)
443 {
444 CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
445 IO_STATUS_BLOCK IoStatusBlock;
446 NTSTATUS Status;
447
448 Status = GetConsoleScreenBufferInfo(hConsoleOutput, &ConsoleScreenBufferInfo);
449 if (!NT_SUCCESS(Status))
450 return FALSE;
451
452 ConsoleScreenBufferInfo.dwCursorPosition.X = dwCursorPosition.X;
453 ConsoleScreenBufferInfo.dwCursorPosition.Y = dwCursorPosition.Y;
454
455 Status = NtDeviceIoControlFile(hConsoleOutput,
456 NULL,
457 NULL,
458 NULL,
459 &IoStatusBlock,
460 IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO,
461 &ConsoleScreenBufferInfo,
462 sizeof(CONSOLE_SCREEN_BUFFER_INFO),
463 NULL,
464 0);
465 return NT_SUCCESS(Status);
466 }
467
468
469 BOOL
470 WINAPI
471 SetConsoleTextAttribute(
472 IN HANDLE hConsoleOutput,
473 IN WORD wAttributes)
474 {
475 IO_STATUS_BLOCK IoStatusBlock;
476 NTSTATUS Status;
477
478 Status = NtDeviceIoControlFile(hConsoleOutput,
479 NULL,
480 NULL,
481 NULL,
482 &IoStatusBlock,
483 IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE,
484 &wAttributes,
485 sizeof(USHORT),
486 NULL,
487 0);
488 return NT_SUCCESS(Status);
489 }
490
491
492 BOOL
493 WINAPI
494 SetConsoleOutputCP(
495 IN UINT wCodepage)
496 {
497 HANDLE hConsoleOutput;
498 IO_STATUS_BLOCK IoStatusBlock;
499 NTSTATUS Status;
500
501 hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
502
503 Status = NtDeviceIoControlFile(hConsoleOutput,
504 NULL,
505 NULL,
506 NULL,
507 &IoStatusBlock,
508 IOCTL_CONSOLE_LOADFONT,
509 &wCodepage,
510 sizeof(ULONG),
511 NULL,
512 0);
513 return NT_SUCCESS(Status);
514 }
515
516
517 /* EOF */