mirror of
https://github.com/reactos/reactos.git
synced 2024-11-09 08:08:38 +00:00
527f2f9057
* Create a branch for some evul shell experiments. svn path=/branches/shell-experiments/; revision=61927
512 lines
9.6 KiB
C
512 lines
9.6 KiB
C
/*
|
|
* ReactOS kernel
|
|
* Copyright (C) 2002 ReactOS Team
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS text-mode setup
|
|
* FILE: subsys/system/usetup/console.c
|
|
* PURPOSE: Console support functions
|
|
* PROGRAMMER: Eric Kohl
|
|
*/
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
#include <usetup.h>
|
|
/* Blue Driver Header */
|
|
#include <blue/ntddblue.h>
|
|
#include "keytrans.h"
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
BOOL WINAPI
|
|
AllocConsole(VOID)
|
|
{
|
|
UNICODE_STRING ScreenName = RTL_CONSTANT_STRING(L"\\??\\BlueScreen");
|
|
UNICODE_STRING KeyboardName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
NTSTATUS Status;
|
|
|
|
/* Open the screen */
|
|
InitializeObjectAttributes(
|
|
&ObjectAttributes,
|
|
&ScreenName,
|
|
0,
|
|
NULL,
|
|
NULL);
|
|
Status = NtOpenFile(
|
|
&StdOutput,
|
|
FILE_ALL_ACCESS,
|
|
&ObjectAttributes,
|
|
&IoStatusBlock,
|
|
FILE_OPEN,
|
|
FILE_SYNCHRONOUS_IO_ALERT);
|
|
if (!NT_SUCCESS(Status))
|
|
return FALSE;
|
|
|
|
/* Open the keyboard */
|
|
InitializeObjectAttributes(
|
|
&ObjectAttributes,
|
|
&KeyboardName,
|
|
0,
|
|
NULL,
|
|
NULL);
|
|
Status = NtOpenFile(
|
|
&StdInput,
|
|
FILE_ALL_ACCESS,
|
|
&ObjectAttributes,
|
|
&IoStatusBlock,
|
|
FILE_OPEN,
|
|
0);
|
|
if (!NT_SUCCESS(Status))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI
|
|
AttachConsole(
|
|
IN DWORD dwProcessId)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL WINAPI
|
|
FreeConsole(VOID)
|
|
{
|
|
if (StdInput != INVALID_HANDLE_VALUE)
|
|
NtClose(StdInput);
|
|
|
|
if (StdOutput != INVALID_HANDLE_VALUE)
|
|
NtClose(StdOutput);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI
|
|
WriteConsole(
|
|
IN HANDLE hConsoleOutput,
|
|
IN const VOID* lpBuffer,
|
|
IN DWORD nNumberOfCharsToWrite,
|
|
OUT LPDWORD lpNumberOfCharsWritten,
|
|
IN LPVOID lpReserved)
|
|
{
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
NTSTATUS Status;
|
|
|
|
Status = NtWriteFile(
|
|
hConsoleOutput,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&IoStatusBlock,
|
|
(PVOID)lpBuffer,
|
|
nNumberOfCharsToWrite,
|
|
NULL,
|
|
NULL);
|
|
if (!NT_SUCCESS(Status))
|
|
return FALSE;
|
|
|
|
*lpNumberOfCharsWritten = IoStatusBlock.Information;
|
|
return TRUE;
|
|
}
|
|
|
|
HANDLE WINAPI
|
|
GetStdHandle(
|
|
IN DWORD nStdHandle)
|
|
{
|
|
switch (nStdHandle)
|
|
{
|
|
case STD_INPUT_HANDLE:
|
|
return StdInput;
|
|
case STD_OUTPUT_HANDLE:
|
|
return StdOutput;
|
|
default:
|
|
return INVALID_HANDLE_VALUE;
|
|
}
|
|
}
|
|
|
|
BOOL WINAPI
|
|
FlushConsoleInputBuffer(
|
|
IN HANDLE hConsoleInput)
|
|
{
|
|
LARGE_INTEGER Offset, Timeout;
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
KEYBOARD_INPUT_DATA InputData;
|
|
NTSTATUS Status;
|
|
|
|
do
|
|
{
|
|
Offset.QuadPart = 0;
|
|
Status = NtReadFile(
|
|
hConsoleInput,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&IoStatusBlock,
|
|
&InputData,
|
|
sizeof(KEYBOARD_INPUT_DATA),
|
|
&Offset,
|
|
0);
|
|
if (Status == STATUS_PENDING)
|
|
{
|
|
Timeout.QuadPart = -100;
|
|
Status = NtWaitForSingleObject(hConsoleInput, FALSE, &Timeout);
|
|
if (Status == STATUS_TIMEOUT)
|
|
{
|
|
NtCancelIoFile(hConsoleInput, &IoStatusBlock);
|
|
return TRUE;
|
|
}
|
|
}
|
|
} while (NT_SUCCESS(Status));
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL WINAPI
|
|
ReadConsoleInput(
|
|
IN HANDLE hConsoleInput,
|
|
OUT PINPUT_RECORD lpBuffer,
|
|
IN DWORD nLength,
|
|
OUT LPDWORD lpNumberOfEventsRead)
|
|
{
|
|
LARGE_INTEGER Offset;
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
KEYBOARD_INPUT_DATA InputData;
|
|
NTSTATUS Status;
|
|
|
|
Offset.QuadPart = 0;
|
|
Status = NtReadFile(
|
|
hConsoleInput,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&IoStatusBlock,
|
|
&InputData,
|
|
sizeof(KEYBOARD_INPUT_DATA),
|
|
&Offset,
|
|
0);
|
|
if (Status == STATUS_PENDING)
|
|
{
|
|
Status = NtWaitForSingleObject(hConsoleInput, FALSE, NULL);
|
|
Status = IoStatusBlock.Status;
|
|
}
|
|
if (!NT_SUCCESS(Status))
|
|
return FALSE;
|
|
|
|
lpBuffer->EventType = KEY_EVENT;
|
|
Status = IntTranslateKey(&InputData, &lpBuffer->Event.KeyEvent);
|
|
if (!NT_SUCCESS(Status))
|
|
return FALSE;
|
|
|
|
*lpNumberOfEventsRead = 1;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI
|
|
WriteConsoleOutputCharacterA(
|
|
HANDLE hConsoleOutput,
|
|
IN LPCSTR lpCharacter,
|
|
IN DWORD nLength,
|
|
IN COORD dwWriteCoord,
|
|
OUT LPDWORD lpNumberOfCharsWritten)
|
|
{
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
PCHAR Buffer;
|
|
COORD *pCoord;
|
|
PCHAR pText;
|
|
NTSTATUS Status;
|
|
|
|
Buffer = (CHAR*) RtlAllocateHeap(
|
|
ProcessHeap,
|
|
0,
|
|
nLength + sizeof(COORD));
|
|
pCoord = (COORD *)Buffer;
|
|
pText = (PCHAR)(pCoord + 1);
|
|
|
|
*pCoord = dwWriteCoord;
|
|
memcpy(pText, lpCharacter, nLength);
|
|
|
|
Status = NtDeviceIoControlFile(
|
|
hConsoleOutput,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&IoStatusBlock,
|
|
IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
|
|
NULL,
|
|
0,
|
|
Buffer,
|
|
nLength + sizeof(COORD));
|
|
|
|
RtlFreeHeap(
|
|
ProcessHeap,
|
|
0,
|
|
Buffer);
|
|
if (!NT_SUCCESS(Status))
|
|
return FALSE;
|
|
|
|
*lpNumberOfCharsWritten = IoStatusBlock.Information;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI
|
|
WriteConsoleOutputCharacterW(
|
|
HANDLE hConsoleOutput,
|
|
IN LPCWSTR lpCharacter,
|
|
IN DWORD nLength,
|
|
IN COORD dwWriteCoord,
|
|
OUT LPDWORD lpNumberOfCharsWritten)
|
|
{
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
PCHAR Buffer;
|
|
COORD *pCoord;
|
|
PCHAR pText;
|
|
NTSTATUS Status;
|
|
ULONG i;
|
|
|
|
Buffer = (CHAR*) RtlAllocateHeap(
|
|
ProcessHeap,
|
|
0,
|
|
nLength + sizeof(COORD));
|
|
pCoord = (COORD *)Buffer;
|
|
pText = (PCHAR)(pCoord + 1);
|
|
|
|
*pCoord = dwWriteCoord;
|
|
|
|
/* FIXME: use real unicode->oem conversion */
|
|
for (i = 0; i < nLength; i++)
|
|
pText[i] = (CHAR)lpCharacter[i];
|
|
|
|
Status = NtDeviceIoControlFile(
|
|
hConsoleOutput,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&IoStatusBlock,
|
|
IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
|
|
NULL,
|
|
0,
|
|
Buffer,
|
|
nLength + sizeof(COORD));
|
|
|
|
RtlFreeHeap(
|
|
ProcessHeap,
|
|
0,
|
|
Buffer);
|
|
if (!NT_SUCCESS(Status))
|
|
return FALSE;
|
|
|
|
*lpNumberOfCharsWritten = IoStatusBlock.Information;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI
|
|
FillConsoleOutputAttribute(
|
|
IN HANDLE hConsoleOutput,
|
|
IN WORD wAttribute,
|
|
IN DWORD nLength,
|
|
IN COORD dwWriteCoord,
|
|
OUT LPDWORD lpNumberOfAttrsWritten)
|
|
{
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
OUTPUT_ATTRIBUTE Buffer;
|
|
NTSTATUS Status;
|
|
|
|
Buffer.wAttribute = wAttribute;
|
|
Buffer.nLength = nLength;
|
|
Buffer.dwCoord = dwWriteCoord;
|
|
|
|
Status = NtDeviceIoControlFile(
|
|
hConsoleOutput,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&IoStatusBlock,
|
|
IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE,
|
|
&Buffer,
|
|
sizeof(OUTPUT_ATTRIBUTE),
|
|
&Buffer,
|
|
sizeof(OUTPUT_ATTRIBUTE));
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
return FALSE;
|
|
|
|
*lpNumberOfAttrsWritten = Buffer.dwTransfered;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI
|
|
FillConsoleOutputCharacterA(
|
|
IN HANDLE hConsoleOutput,
|
|
IN CHAR cCharacter,
|
|
IN DWORD nLength,
|
|
IN COORD dwWriteCoord,
|
|
OUT LPDWORD lpNumberOfCharsWritten)
|
|
{
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
OUTPUT_CHARACTER Buffer;
|
|
NTSTATUS Status;
|
|
|
|
Buffer.cCharacter = cCharacter;
|
|
Buffer.nLength = nLength;
|
|
Buffer.dwCoord = dwWriteCoord;
|
|
|
|
Status = NtDeviceIoControlFile(
|
|
hConsoleOutput,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&IoStatusBlock,
|
|
IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER,
|
|
&Buffer,
|
|
sizeof(OUTPUT_CHARACTER),
|
|
&Buffer,
|
|
sizeof(OUTPUT_CHARACTER));
|
|
if (!NT_SUCCESS(Status))
|
|
return FALSE;
|
|
|
|
*lpNumberOfCharsWritten = Buffer.dwTransfered;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI
|
|
GetConsoleScreenBufferInfo(
|
|
IN HANDLE hConsoleOutput,
|
|
OUT PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
|
|
{
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
NTSTATUS Status;
|
|
|
|
Status = NtDeviceIoControlFile(
|
|
hConsoleOutput,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&IoStatusBlock,
|
|
IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO,
|
|
NULL,
|
|
0,
|
|
lpConsoleScreenBufferInfo,
|
|
sizeof(CONSOLE_SCREEN_BUFFER_INFO));
|
|
return NT_SUCCESS(Status);
|
|
}
|
|
|
|
BOOL WINAPI
|
|
SetConsoleCursorInfo(
|
|
IN HANDLE hConsoleOutput,
|
|
IN const CONSOLE_CURSOR_INFO* lpConsoleCursorInfo)
|
|
{
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
NTSTATUS Status;
|
|
|
|
Status = NtDeviceIoControlFile(
|
|
hConsoleOutput,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&IoStatusBlock,
|
|
IOCTL_CONSOLE_SET_CURSOR_INFO,
|
|
(PCONSOLE_CURSOR_INFO)lpConsoleCursorInfo,
|
|
sizeof(CONSOLE_CURSOR_INFO),
|
|
NULL,
|
|
0);
|
|
return NT_SUCCESS(Status);
|
|
}
|
|
|
|
BOOL WINAPI
|
|
SetConsoleCursorPosition(
|
|
IN HANDLE hConsoleOutput,
|
|
IN COORD dwCursorPosition)
|
|
{
|
|
CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
NTSTATUS Status;
|
|
|
|
Status = GetConsoleScreenBufferInfo(hConsoleOutput, &ConsoleScreenBufferInfo);
|
|
if (!NT_SUCCESS(Status))
|
|
return FALSE;
|
|
|
|
ConsoleScreenBufferInfo.dwCursorPosition.X = dwCursorPosition.X;
|
|
ConsoleScreenBufferInfo.dwCursorPosition.Y = dwCursorPosition.Y;
|
|
|
|
Status = NtDeviceIoControlFile(
|
|
hConsoleOutput,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&IoStatusBlock,
|
|
IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO,
|
|
&ConsoleScreenBufferInfo,
|
|
sizeof(CONSOLE_SCREEN_BUFFER_INFO),
|
|
NULL,
|
|
0);
|
|
|
|
return NT_SUCCESS(Status);
|
|
}
|
|
|
|
BOOL WINAPI
|
|
SetConsoleTextAttribute(
|
|
IN HANDLE hConsoleOutput,
|
|
IN WORD wAttributes)
|
|
{
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
NTSTATUS Status;
|
|
|
|
Status = NtDeviceIoControlFile(
|
|
hConsoleOutput,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&IoStatusBlock,
|
|
IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE,
|
|
&wAttributes,
|
|
sizeof(USHORT),
|
|
NULL,
|
|
0);
|
|
return NT_SUCCESS(Status);
|
|
}
|
|
|
|
BOOL WINAPI
|
|
SetConsoleOutputCP(
|
|
IN UINT wCodepage)
|
|
{
|
|
HANDLE hConsoleOutput;
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
NTSTATUS Status;
|
|
|
|
hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
|
|
Status = NtDeviceIoControlFile(
|
|
hConsoleOutput,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&IoStatusBlock,
|
|
IOCTL_CONSOLE_LOADFONT,
|
|
&wCodepage,
|
|
sizeof(ULONG),
|
|
NULL,
|
|
0);
|
|
return NT_SUCCESS(Status);
|
|
}
|
|
|
|
|
|
/* EOF */
|