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