mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
[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 toaaa416d3
and2391e31c
.
This commit is contained in:
parent
ac2494994b
commit
9f201d462d
6 changed files with 271 additions and 313 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 **************************************************************/
|
||||
|
||||
|
|
|
@ -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 (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 */
|
||||
|
|
Loading…
Reference in a new issue