[BLUE][CONSRV][USETUP] Completely remove support for CAB font extraction from driver, and move it to CONSRV, much like what was done for USETUP.

Addendum to aaa416d3 and 2391e31c.
This commit is contained in:
Hermès Bélusca-Maïto 2021-07-04 01:46:52 +02:00
parent ac2494994b
commit 9f201d462d
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
6 changed files with 271 additions and 313 deletions

View file

@ -692,8 +692,8 @@ WINAPI
SetConsoleOutputCP(
IN UINT wCodepage)
{
WCHAR FontName[100];
WCHAR FontFile[] = L"\\SystemRoot\\vgafonts.cab";
static PCWSTR FontFile = L"\\SystemRoot\\vgafonts.cab";
WCHAR FontName[20];
CONSOLE_CABINET_CONTEXT ConsoleCabinetContext;
PCABINET_CONTEXT CabinetContext = &ConsoleCabinetContext.CabinetContext;
CAB_SEARCH Search;
@ -719,7 +719,8 @@ SetConsoleOutputCP(
return FALSE;
}
swprintf(FontName, L"%u-8x8.bin", wCodepage);
RtlStringCbPrintfW(FontName, sizeof(FontName),
L"%u-8x8.bin", wCodepage);
CabStatus = CabinetFindFirst(CabinetContext, FontName, &Search);
if (CabStatus != CAB_STATUS_SUCCESS)
{
@ -732,7 +733,7 @@ SetConsoleOutputCP(
CabinetClose(CabinetContext);
if (CabStatus != CAB_STATUS_SUCCESS)
{
DPRINT("CabinetLoadFile('%S', '%S') returned 0x%08x\n", FontFile, FontName, CabStatus);
DPRINT("CabinetExtractFile('%S', '%S') returned 0x%08x\n", FontFile, FontName, CabStatus);
if (ConsoleCabinetContext.Data)
RtlFreeHeap(ProcessHeap, 0, ConsoleCabinetContext.Data);
return FALSE;
@ -744,7 +745,7 @@ SetConsoleOutputCP(
NULL,
NULL,
&IoStatusBlock,
IOCTL_CONSOLE_SETFONT,
IOCTL_CONSOLE_LOADFONT,
ConsoleCabinetContext.Data,
ConsoleCabinetContext.Size,
NULL,

View file

@ -38,8 +38,7 @@ typedef struct _DEVICE_EXTENSION
USHORT Rows; /* Number of rows */
USHORT Columns; /* Number of columns */
USHORT CursorX, CursorY; /* Cursor position */
PUCHAR FontBitfield; /* Specifies the font. If NULL, use CodePage */
ULONG CodePage; /* Specifies the font associated to this code page */
PUCHAR FontBitfield; /* Specifies the font */
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
typedef struct _VGA_REGISTERS
@ -484,15 +483,9 @@ ScrAcquireOwnership(
// DeviceExtension->CursorX = min(max(DeviceExtension->CursorX, 0), DeviceExtension->Columns - 1);
DeviceExtension->CursorY = min(max(DeviceExtension->CursorY, 0), DeviceExtension->Rows - 1);
/* Set the font */
if (DeviceExtension->FontBitfield)
{
ScrSetFont(DeviceExtension->FontBitfield);
}
else
{
/* Upload a default font for the current codepage */
ScrLoadFontTable(DeviceExtension->CodePage);
}
DPRINT("%d Columns %d Rows %d Scanlines\n",
DeviceExtension->Columns,
@ -529,7 +522,6 @@ ScrResetScreen(
DeviceExtension->CharAttribute = BACKGROUND_BLUE | FOREGROUND_LIGHTGRAY;
DeviceExtension->Mode = ENABLE_PROCESSED_OUTPUT |
ENABLE_WRAP_AT_EOL_OUTPUT;
DeviceExtension->CodePage = 437; /* Use default codepage */
}
if (Enable)
@ -1503,32 +1495,10 @@ ScrIoControl(
case IOCTL_CONSOLE_LOADFONT:
{
/* Validate input buffer */
if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
{
Status = STATUS_INVALID_PARAMETER;
break;
}
ASSERT(Irp->AssociatedIrp.SystemBuffer);
//
// FIXME: For the moment we support only a fixed 256-char 8-bit font.
//
if (DeviceExtension->FontBitfield)
{
ExFreePoolWithTag(DeviceExtension->FontBitfield, TAG_BLUE);
DeviceExtension->FontBitfield = NULL;
}
DeviceExtension->CodePage = *(PULONG)Irp->AssociatedIrp.SystemBuffer;
/* Upload a font for the codepage if needed */
if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
ScrLoadFontTable(DeviceExtension->CodePage);
Irp->IoStatus.Information = 0;
Status = STATUS_SUCCESS;
break;
}
case IOCTL_CONSOLE_SETFONT:
{
/* Validate input buffer */
if (stk->Parameters.DeviceIoControl.InputBufferLength < 256 * 8)
{
@ -1537,7 +1507,6 @@ ScrIoControl(
}
ASSERT(Irp->AssociatedIrp.SystemBuffer);
DeviceExtension->CodePage = 0;
if (DeviceExtension->FontBitfield)
ExFreePoolWithTag(DeviceExtension->FontBitfield, TAG_BLUE);
DeviceExtension->FontBitfield = ExAllocatePoolWithTag(NonPagedPool, 256 * 8, TAG_BLUE);
@ -1548,7 +1517,7 @@ ScrIoControl(
}
RtlCopyMemory(DeviceExtension->FontBitfield, Irp->AssociatedIrp.SystemBuffer, 256 * 8);
/* Upload the font if needed */
/* Set the font if needed */
if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
ScrSetFont(DeviceExtension->FontBitfield);

View file

@ -67,35 +67,9 @@ typedef struct tagCONSOLE_CURSOR_INFO
#define BACKGROUND_RED 0x0040
#define BACKGROUND_INTENSITY 0x0080
typedef struct _CFHEADER
{
ULONG Signature; // File signature 'MSCF' (CAB_SIGNATURE)
ULONG Reserved1; // Reserved field
ULONG CabinetSize; // Cabinet file size
ULONG Reserved2; // Reserved field
ULONG FileTableOffset; // Offset of first CFFILE
ULONG Reserved3; // Reserved field
USHORT Version; // Cabinet version (CAB_VERSION)
USHORT FolderCount; // Number of folders
USHORT FileCount; // Number of files
USHORT Flags; // Cabinet flags (CAB_FLAG_*)
USHORT SetID; // Cabinet set id
USHORT CabinetNumber; // Zero-based cabinet number
} CFHEADER, *PCFHEADER;
typedef struct _CFFILE
{
ULONG FileSize; // Uncompressed file size in bytes
ULONG FileOffset; // Uncompressed offset of file in the folder
USHORT FileControlID; // File control ID (CAB_FILE_*)
USHORT FileDate; // File date stamp, as used by DOS
USHORT FileTime; // File time stamp, as used by DOS
USHORT Attributes; // File attributes (CAB_ATTRIB_*)
/* After this is the NULL terminated filename */
} CFFILE, *PCFFILE;
#define CAB_SIGNATURE 0x4643534D // "MSCF"
/*
* VGA registers
*/
#define VIDMEM_BASE 0xb8000
#define BITPLANE_BASE 0xa0000
@ -144,7 +118,6 @@ typedef struct _CFFILE
#define PELINDEX (PUCHAR)0x3c8
#define PELDATA (PUCHAR)0x3c9
VOID ScrLoadFontTable(_In_ ULONG CodePage);
VOID ScrSetFont(_In_ PUCHAR FontBitfield);
#endif /* _BLUE_PCH_ */

View file

@ -10,58 +10,17 @@
/* INCLUDES ***************************************************************/
#include "blue.h"
#include <ndk/rtlfuncs.h>
#define NDEBUG
#include <debug.h>
//
// FIXME: For the moment we support only a fixed 256-char 8-bit font.
//
NTSTATUS ExtractFont(_In_ ULONG CodePage, _In_ PUCHAR FontBitField);
VOID OpenBitPlane(VOID);
VOID CloseBitPlane(VOID);
VOID LoadFont(_In_ PUCHAR Bitplane, _In_ PUCHAR FontBitfield);
/* FUNCTIONS ****************************************************************/
VOID
ScrLoadFontTable(
_In_ ULONG CodePage)
{
PHYSICAL_ADDRESS BaseAddress;
PUCHAR Bitplane;
PUCHAR FontBitfield = NULL;
NTSTATUS Status = STATUS_SUCCESS;
FontBitfield = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, 2048, TAG_BLUE);
if (FontBitfield == NULL)
{
DPRINT1("ExAllocatePoolWithTag failed\n");
return;
}
/* open bit plane for font table access */
OpenBitPlane();
/* get pointer to video memory */
BaseAddress.QuadPart = BITPLANE_BASE;
Bitplane = (PUCHAR)MmMapIoSpace(BaseAddress, 0xFFFF, MmNonCached);
Status = ExtractFont(CodePage, FontBitfield);
if (NT_SUCCESS(Status))
{
LoadFont(Bitplane, FontBitfield);
}
else
{
DPRINT1("ExtractFont failed with Status 0x%lx\n", Status);
}
MmUnmapIoSpace(Bitplane, 0xFFFF);
ExFreePoolWithTag(FontBitfield, TAG_BLUE);
/* close bit plane */
CloseBitPlane();
}
VOID
ScrSetFont(
_In_ PUCHAR FontBitfield)
@ -86,195 +45,6 @@ ScrSetFont(
/* PRIVATE FUNCTIONS *********************************************************/
NTSTATUS
ExtractFont(
_In_ ULONG CodePage,
_In_ PUCHAR FontBitField)
{
BOOLEAN bFoundFile = FALSE;
HANDLE Handle;
NTSTATUS Status;
CHAR FileName[20];
IO_STATUS_BLOCK IoStatusBlock;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING LinkName;
UNICODE_STRING SourceName;
CFHEADER CabFileHeader;
CFFILE CabFile;
ULONG CabFileOffset = 0;
LARGE_INTEGER ByteOffset;
WCHAR SourceBuffer[MAX_PATH] = { L'\0' };
ULONG ReadCP;
if (KeGetCurrentIrql() != PASSIVE_LEVEL)
return STATUS_INVALID_DEVICE_STATE;
RtlInitUnicodeString(&LinkName,
L"\\SystemRoot");
InitializeObjectAttributes(&ObjectAttributes,
&LinkName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL);
Status = ZwOpenSymbolicLinkObject(&Handle,
SYMBOLIC_LINK_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT1("ZwOpenSymbolicLinkObject failed with Status 0x%lx\n", Status);
return Status;
}
SourceName.Length = 0;
SourceName.MaximumLength = MAX_PATH * sizeof(WCHAR);
SourceName.Buffer = SourceBuffer;
Status = ZwQuerySymbolicLinkObject(Handle,
&SourceName,
NULL);
ZwClose(Handle);
if (!NT_SUCCESS(Status))
{
DPRINT1("ZwQuerySymbolicLinkObject failed with Status 0x%lx\n", Status);
return Status;
}
Status = RtlAppendUnicodeToString(&SourceName, L"\\vgafonts.cab");
if (!NT_SUCCESS(Status))
{
DPRINT1("RtlAppendUnicodeToString failed with Status 0x%lx\n", Status);
return Status;
}
InitializeObjectAttributes(&ObjectAttributes,
&SourceName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL);
Status = ZwCreateFile(&Handle,
GENERIC_READ,
&ObjectAttributes,
&IoStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
0,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
if (!NT_SUCCESS(Status))
{
DPRINT1("Error: Cannot open vgafonts.cab (0x%lx)\n", Status);
return Status;
}
ByteOffset.QuadPart = 0;
Status = ZwReadFile(Handle,
NULL,
NULL,
NULL,
&IoStatusBlock,
&CabFileHeader,
sizeof(CabFileHeader),
&ByteOffset,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("Error: Cannot read from file (0x%lx)\n", Status);
goto Exit;
}
if (CabFileHeader.Signature != CAB_SIGNATURE)
{
DPRINT1("Invalid CAB signature: 0x%lx!\n", CabFileHeader.Signature);
Status = STATUS_UNSUCCESSFUL;
goto Exit;
}
// We have a valid CAB file!
// Read the file table now and decrement the file count on every file. When it's zero, we read the complete table.
ByteOffset.QuadPart = CabFileHeader.FileTableOffset;
while (CabFileHeader.FileCount)
{
Status = ZwReadFile(Handle,
NULL,
NULL,
NULL,
&IoStatusBlock,
&CabFile,
sizeof(CabFile),
&ByteOffset,
NULL);
if (NT_SUCCESS(Status))
{
ByteOffset.QuadPart += sizeof(CabFile);
// We assume here that the file name is max. 19 characters (+ 1 NULL character) long.
// This should be enough for our purpose.
Status = ZwReadFile(Handle,
NULL,
NULL,
NULL,
&IoStatusBlock,
FileName,
sizeof(FileName),
&ByteOffset,
NULL);
if (NT_SUCCESS(Status))
{
if (!bFoundFile)
{
Status = RtlCharToInteger(FileName, 0, &ReadCP);
if (NT_SUCCESS(Status) && ReadCP == CodePage)
{
// We got the correct file.
// Save the offset and loop through the rest of the file table to find the position, where the actual data starts.
CabFileOffset = CabFile.FileOffset;
bFoundFile = TRUE;
}
}
ByteOffset.QuadPart += strlen(FileName) + 1;
}
}
CabFileHeader.FileCount--;
}
// 8 = Size of a CFFOLDER structure (see cabman). As we don't need the values of that structure, just increase the offset here.
ByteOffset.QuadPart += 8;
ByteOffset.QuadPart += CabFileOffset;
// ByteOffset now contains the offset of the actual data, so we can read the RAW font
Status = ZwReadFile(Handle,
NULL,
NULL,
NULL,
&IoStatusBlock,
FontBitField,
2048,
&ByteOffset,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("ZwReadFile failed with Status 0x%lx\n", Status);
}
Exit:
ZwClose(Handle);
return Status;
}
/* Font-load specific funcs */
VOID
OpenBitPlane(VOID)

View file

@ -22,7 +22,6 @@
#define IOCTL_CONSOLE_DRAW CTL_CODE(FILE_DEVICE_SCREEN, 0x830, METHOD_IN_DIRECT, FILE_WRITE_ACCESS)
#define IOCTL_CONSOLE_LOADFONT CTL_CODE(FILE_DEVICE_SCREEN, 0x840, METHOD_IN_DIRECT, FILE_WRITE_ACCESS)
#define IOCTL_CONSOLE_SETFONT CTL_CODE(FILE_DEVICE_SCREEN, 0x841, METHOD_IN_DIRECT, FILE_WRITE_ACCESS)
/* TYPEDEFS **************************************************************/

View file

@ -4,7 +4,7 @@
* FILE: win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c
* PURPOSE: TUI Terminal Front-End - Virtual Consoles...
* PROGRAMMERS: David Welch
* van Geldorp
* van Geldorp
* Jeffrey Morlan
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
*/
@ -26,7 +26,41 @@
#include <debug.h>
/* GLOBALS ********************************************************************/
/* CAB FILE STRUCTURES ******************************************************/
typedef struct _CFHEADER
{
ULONG Signature; // File signature 'MSCF' (CAB_SIGNATURE)
ULONG Reserved1; // Reserved field
ULONG CabinetSize; // Cabinet file size
ULONG Reserved2; // Reserved field
ULONG FileTableOffset; // Offset of first CFFILE
ULONG Reserved3; // Reserved field
USHORT Version; // Cabinet version (CAB_VERSION)
USHORT FolderCount; // Number of folders
USHORT FileCount; // Number of files
USHORT Flags; // Cabinet flags (CAB_FLAG_*)
USHORT SetID; // Cabinet set id
USHORT CabinetNumber; // Zero-based cabinet number
} CFHEADER, *PCFHEADER;
typedef struct _CFFILE
{
ULONG FileSize; // Uncompressed file size in bytes
ULONG FileOffset; // Uncompressed offset of file in the folder
USHORT FileControlID; // File control ID (CAB_FILE_*)
USHORT FileDate; // File date stamp, as used by DOS
USHORT FileTime; // File time stamp, as used by DOS
USHORT Attributes; // File attributes (CAB_ATTRIB_*)
/* After this is the NULL terminated filename */
// CHAR FileName[ANYSIZE_ARRAY];
} CFFILE, *PCFFILE;
#define CAB_SIGNATURE 0x4643534D // "MSCF"
#define CAB_VERSION 0x0103
/* GLOBALS ******************************************************************/
#define ConsoleOutputUnicodeToAnsiChar(Console, dChar, sWChar) \
do { \
@ -374,8 +408,222 @@ TuiConsoleThread(PVOID Param)
return 0;
}
static BOOLEAN
TuiSetConsoleOutputCP(
IN HANDLE hNtConddHandle,
IN UINT CodePage)
{
static UINT LastLoadedCodepage = 0;
UNICODE_STRING FontFile = RTL_CONSTANT_STRING(L"\\SystemRoot\\vgafonts.cab");
CHAR FontName[20];
NTSTATUS Status;
HANDLE FileHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
// ULONG ReadCP;
PUCHAR FontBitField = NULL;
/* CAB-specific data */
HANDLE FileSectionHandle;
PUCHAR FileBuffer = NULL;
SIZE_T FileSize = 0;
PCFHEADER CabFileHeader;
union
{
PCFFILE CabFile;
PVOID Buffer;
} Data;
PCFFILE FoundFile = NULL;
PSTR FileName;
USHORT Index;
if (CodePage == LastLoadedCodepage)
return TRUE;
/*
* Open the *uncompressed* fonts archive file.
*/
InitializeObjectAttributes(&ObjectAttributes,
&FontFile,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenFile(&FileHandle,
GENERIC_READ | SYNCHRONIZE,
&ObjectAttributes,
&IoStatusBlock,
FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS(Status))
{
DPRINT1("Error: Cannot open '%wZ' (0x%lx)\n", &FontFile, Status);
return FALSE;
}
/*
* Load it.
*/
Status = NtCreateSection(&FileSectionHandle,
SECTION_ALL_ACCESS,
0, 0,
PAGE_READONLY,
SEC_COMMIT,
FileHandle);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtCreateSection failed (0x%lx)\n", Status);
goto Exit;
}
Status = NtMapViewOfSection(FileSectionHandle,
NtCurrentProcess(),
(PVOID*)&FileBuffer,
0, 0, NULL,
&FileSize,
ViewUnmap,
0,
PAGE_READONLY);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtMapViewOfSection failed (0x%lx)\n", Status);
goto Exit;
}
/* Wrap in SEH to protect against ill-formed file */
_SEH2_TRY
{
DPRINT("Cabinet file '%wZ' opened and mapped to 0x%p\n",
&FontFile, FileBuffer);
CabFileHeader = (PCFHEADER)FileBuffer;
/* Validate the CAB file */
if (FileSize <= sizeof(CFHEADER) ||
CabFileHeader->Signature != CAB_SIGNATURE ||
CabFileHeader->Version != CAB_VERSION ||
CabFileHeader->FolderCount == 0 ||
CabFileHeader->FileCount == 0 ||
CabFileHeader->FileTableOffset < sizeof(CFHEADER))
{
DPRINT1("Cabinet file '%wZ' has an invalid header\n", &FontFile);
Status = STATUS_UNSUCCESSFUL;
_SEH2_YIELD(goto Exit);
}
/*
* Find the font file within the archive.
*/
RtlStringCbPrintfA(FontName, sizeof(FontName),
"%u-8x8.bin", CodePage);
/* Read the file table, find the file of interest and the end of the table */
Data.CabFile = (PCFFILE)(FileBuffer + CabFileHeader->FileTableOffset);
for (Index = 0; Index < CabFileHeader->FileCount; ++Index)
{
FileName = (PSTR)(Data.CabFile + 1);
if (!FoundFile)
{
// Status = RtlCharToInteger(FileName, 0, &ReadCP);
// if (NT_SUCCESS(Status) && (ReadCP == CodePage))
if (_stricmp(FontName, FileName) == 0)
{
/* We've got the correct file. Save the offset and
* loop through the rest of the file table to find
* the position, where the actual data starts. */
FoundFile = Data.CabFile;
}
}
/* Move to the next file (go past the filename NULL terminator) */
Data.CabFile = (PCFFILE)(strchr(FileName, 0) + 1);
}
if (!FoundFile)
{
DPRINT("File '%S' not found in cabinet '%wZ'\n",
FontName, &FontFile);
Status = STATUS_OBJECT_NAME_NOT_FOUND;
_SEH2_YIELD(goto Exit);
}
/*
* Extract the font file.
*/
/* Verify the font file size; we only support a fixed 256-char 8-bit font */
if (FoundFile->FileSize != 256 * 8)
{
DPRINT1("File of size %lu is not of the expected size %lu\n",
FoundFile->FileSize, 256 * 8);
Status = STATUS_INVALID_BUFFER_SIZE;
_SEH2_YIELD(goto Exit);
}
FontBitField = RtlAllocateHeap(RtlGetProcessHeap(), 0, FoundFile->FileSize);
if (!FontBitField)
{
DPRINT1("ExAllocatePoolWithTag(%lu) failed\n", FoundFile->FileSize);
Status = STATUS_NO_MEMORY;
_SEH2_YIELD(goto Exit);
}
/* 8 = Size of a CFFOLDER structure (see cabman). As we don't need
* the values of that structure, just increase the offset here. */
Data.Buffer = (PVOID)((ULONG_PTR)Data.Buffer + 8); // sizeof(CFFOLDER);
Data.Buffer = (PVOID)((ULONG_PTR)Data.Buffer + FoundFile->FileOffset);
/* Data.Buffer now points to the actual data of the RAW font */
RtlCopyMemory(FontBitField, Data.Buffer, FoundFile->FileSize);
Status = STATUS_SUCCESS;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
DPRINT1("TuiSetConsoleOutputCP - Caught an exception, Status = 0x%08lx\n", Status);
}
_SEH2_END;
/*
* Load the font.
*/
if (NT_SUCCESS(Status))
{
ASSERT(FoundFile);
ASSERT(FontBitField);
Status = NtDeviceIoControlFile(hNtConddHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_CONSOLE_LOADFONT,
FontBitField,
FoundFile->FileSize,
NULL,
0);
}
if (FontBitField)
RtlFreeHeap(RtlGetProcessHeap(), 0, FontBitField);
Exit:
if (FileBuffer)
NtUnmapViewOfSection(NtCurrentProcess(), FileBuffer);
if (FileSectionHandle)
NtClose(FileSectionHandle);
NtClose(FileHandle);
if (NT_SUCCESS(Status))
LastLoadedCodepage = CodePage;
return NT_SUCCESS(Status);
}
static BOOL
TuiInit(DWORD OemCP)
TuiInit(IN UINT OemCP)
{
BOOL Success;
CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
@ -417,9 +665,7 @@ TuiInit(DWORD OemCP)
return FALSE;
}
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_LOADFONT,
&OemCP, sizeof(OemCP), NULL, 0,
&BytesReturned, NULL))
if (!TuiSetConsoleOutputCP(ConsoleDeviceHandle, OemCP))
{
DPRINT1("Failed to load the font for codepage %d\n", OemCP);
/* Let's suppose the font is good enough to continue */