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