https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9f201d462d3204814829609d0f0d159142170ffb

commit 9f201d462d3204814829609d0f0d159142170ffb
Author:     Hermès Bélusca-Maïto <[email protected]>
AuthorDate: Sun Jul 4 01:46:52 2021 +0200
Commit:     Hermès Bélusca-Maïto <[email protected]>
CommitDate: Sat Jan 15 17:41:36 2022 +0100

    [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.
---
 base/setup/usetup/console.c                        |  13 +-
 drivers/setup/blue/blue.c                          |  43 +---
 drivers/setup/blue/blue.h                          |  33 +--
 drivers/setup/blue/font.c                          | 236 +------------------
 sdk/include/reactos/drivers/blue/ntddblue.h        |   1 -
 win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c | 258 ++++++++++++++++++++-
 6 files changed, 271 insertions(+), 313 deletions(-)

diff --git a/base/setup/usetup/console.c b/base/setup/usetup/console.c
index ab3587eb52e..5cbcf839be1 100644
--- a/base/setup/usetup/console.c
+++ b/base/setup/usetup/console.c
@@ -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,
@@ -753,7 +754,7 @@ SetConsoleOutputCP(
     RtlFreeHeap(ProcessHeap, 0, ConsoleCabinetContext.Data);
 
     if (!NT_SUCCESS(Status))
-          return FALSE;
+        return FALSE;
 
     LastLoadedCodepage = wCodepage;
     return TRUE;
diff --git a/drivers/setup/blue/blue.c b/drivers/setup/blue/blue.c
index 2ca5c70389c..81011fe10cc 100644
--- a/drivers/setup/blue/blue.c
+++ b/drivers/setup/blue/blue.c
@@ -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);
-
-            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;
-        }
+            //
+            // FIXME: For the moment we support only a fixed 256-char 8-bit 
font.
+            //
 
-        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);
 
diff --git a/drivers/setup/blue/blue.h b/drivers/setup/blue/blue.h
index 3a3af7a4511..6baadfb83f0 100644
--- a/drivers/setup/blue/blue.h
+++ b/drivers/setup/blue/blue.h
@@ -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_ */
diff --git a/drivers/setup/blue/font.c b/drivers/setup/blue/font.c
index 57342c86235..5e09a58a707 100644
--- a/drivers/setup/blue/font.c
+++ b/drivers/setup/blue/font.c
@@ -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)
diff --git a/sdk/include/reactos/drivers/blue/ntddblue.h 
b/sdk/include/reactos/drivers/blue/ntddblue.h
index 1c6d22e5008..0d41d0f158d 100644
--- a/sdk/include/reactos/drivers/blue/ntddblue.h
+++ b/sdk/include/reactos/drivers/blue/ntddblue.h
@@ -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 **************************************************************/
 
diff --git a/win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c 
b/win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c
index 3bc48c85940..a3f60e3895d 100644
--- a/win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c
+++ b/win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c
@@ -4,7 +4,7 @@
  * FILE:            win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c
  * PURPOSE:         TUI Terminal Front-End - Virtual Consoles...
  * PROGRAMMERS:     David Welch
- *                  G� van Geldorp
+ *                  Gé van Geldorp
  *                  Jeffrey Morlan
  *                  Hermes Belusca-Maito ([email protected])
  */
@@ -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 */

Reply via email to