mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +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(
|
SetConsoleOutputCP(
|
||||||
IN UINT wCodepage)
|
IN UINT wCodepage)
|
||||||
{
|
{
|
||||||
WCHAR FontName[100];
|
static PCWSTR FontFile = L"\\SystemRoot\\vgafonts.cab";
|
||||||
WCHAR FontFile[] = L"\\SystemRoot\\vgafonts.cab";
|
WCHAR FontName[20];
|
||||||
CONSOLE_CABINET_CONTEXT ConsoleCabinetContext;
|
CONSOLE_CABINET_CONTEXT ConsoleCabinetContext;
|
||||||
PCABINET_CONTEXT CabinetContext = &ConsoleCabinetContext.CabinetContext;
|
PCABINET_CONTEXT CabinetContext = &ConsoleCabinetContext.CabinetContext;
|
||||||
CAB_SEARCH Search;
|
CAB_SEARCH Search;
|
||||||
|
@ -719,7 +719,8 @@ SetConsoleOutputCP(
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
swprintf(FontName, L"%u-8x8.bin", wCodepage);
|
RtlStringCbPrintfW(FontName, sizeof(FontName),
|
||||||
|
L"%u-8x8.bin", wCodepage);
|
||||||
CabStatus = CabinetFindFirst(CabinetContext, FontName, &Search);
|
CabStatus = CabinetFindFirst(CabinetContext, FontName, &Search);
|
||||||
if (CabStatus != CAB_STATUS_SUCCESS)
|
if (CabStatus != CAB_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -732,7 +733,7 @@ SetConsoleOutputCP(
|
||||||
CabinetClose(CabinetContext);
|
CabinetClose(CabinetContext);
|
||||||
if (CabStatus != CAB_STATUS_SUCCESS)
|
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)
|
if (ConsoleCabinetContext.Data)
|
||||||
RtlFreeHeap(ProcessHeap, 0, ConsoleCabinetContext.Data);
|
RtlFreeHeap(ProcessHeap, 0, ConsoleCabinetContext.Data);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -744,7 +745,7 @@ SetConsoleOutputCP(
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
&IoStatusBlock,
|
&IoStatusBlock,
|
||||||
IOCTL_CONSOLE_SETFONT,
|
IOCTL_CONSOLE_LOADFONT,
|
||||||
ConsoleCabinetContext.Data,
|
ConsoleCabinetContext.Data,
|
||||||
ConsoleCabinetContext.Size,
|
ConsoleCabinetContext.Size,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -753,7 +754,7 @@ SetConsoleOutputCP(
|
||||||
RtlFreeHeap(ProcessHeap, 0, ConsoleCabinetContext.Data);
|
RtlFreeHeap(ProcessHeap, 0, ConsoleCabinetContext.Data);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
LastLoadedCodepage = wCodepage;
|
LastLoadedCodepage = wCodepage;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -38,8 +38,7 @@ typedef struct _DEVICE_EXTENSION
|
||||||
USHORT Rows; /* Number of rows */
|
USHORT Rows; /* Number of rows */
|
||||||
USHORT Columns; /* Number of columns */
|
USHORT Columns; /* Number of columns */
|
||||||
USHORT CursorX, CursorY; /* Cursor position */
|
USHORT CursorX, CursorY; /* Cursor position */
|
||||||
PUCHAR FontBitfield; /* Specifies the font. If NULL, use CodePage */
|
PUCHAR FontBitfield; /* Specifies the font */
|
||||||
ULONG CodePage; /* Specifies the font associated to this code page */
|
|
||||||
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||||||
|
|
||||||
typedef struct _VGA_REGISTERS
|
typedef struct _VGA_REGISTERS
|
||||||
|
@ -484,15 +483,9 @@ ScrAcquireOwnership(
|
||||||
// DeviceExtension->CursorX = min(max(DeviceExtension->CursorX, 0), DeviceExtension->Columns - 1);
|
// DeviceExtension->CursorX = min(max(DeviceExtension->CursorX, 0), DeviceExtension->Columns - 1);
|
||||||
DeviceExtension->CursorY = min(max(DeviceExtension->CursorY, 0), DeviceExtension->Rows - 1);
|
DeviceExtension->CursorY = min(max(DeviceExtension->CursorY, 0), DeviceExtension->Rows - 1);
|
||||||
|
|
||||||
|
/* Set the font */
|
||||||
if (DeviceExtension->FontBitfield)
|
if (DeviceExtension->FontBitfield)
|
||||||
{
|
|
||||||
ScrSetFont(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",
|
DPRINT("%d Columns %d Rows %d Scanlines\n",
|
||||||
DeviceExtension->Columns,
|
DeviceExtension->Columns,
|
||||||
|
@ -529,7 +522,6 @@ ScrResetScreen(
|
||||||
DeviceExtension->CharAttribute = BACKGROUND_BLUE | FOREGROUND_LIGHTGRAY;
|
DeviceExtension->CharAttribute = BACKGROUND_BLUE | FOREGROUND_LIGHTGRAY;
|
||||||
DeviceExtension->Mode = ENABLE_PROCESSED_OUTPUT |
|
DeviceExtension->Mode = ENABLE_PROCESSED_OUTPUT |
|
||||||
ENABLE_WRAP_AT_EOL_OUTPUT;
|
ENABLE_WRAP_AT_EOL_OUTPUT;
|
||||||
DeviceExtension->CodePage = 437; /* Use default codepage */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Enable)
|
if (Enable)
|
||||||
|
@ -1503,32 +1495,10 @@ ScrIoControl(
|
||||||
|
|
||||||
case IOCTL_CONSOLE_LOADFONT:
|
case IOCTL_CONSOLE_LOADFONT:
|
||||||
{
|
{
|
||||||
/* Validate input buffer */
|
//
|
||||||
if (stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
|
// FIXME: For the moment we support only a fixed 256-char 8-bit font.
|
||||||
{
|
//
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
case IOCTL_CONSOLE_SETFONT:
|
|
||||||
{
|
|
||||||
/* Validate input buffer */
|
/* Validate input buffer */
|
||||||
if (stk->Parameters.DeviceIoControl.InputBufferLength < 256 * 8)
|
if (stk->Parameters.DeviceIoControl.InputBufferLength < 256 * 8)
|
||||||
{
|
{
|
||||||
|
@ -1537,7 +1507,6 @@ ScrIoControl(
|
||||||
}
|
}
|
||||||
ASSERT(Irp->AssociatedIrp.SystemBuffer);
|
ASSERT(Irp->AssociatedIrp.SystemBuffer);
|
||||||
|
|
||||||
DeviceExtension->CodePage = 0;
|
|
||||||
if (DeviceExtension->FontBitfield)
|
if (DeviceExtension->FontBitfield)
|
||||||
ExFreePoolWithTag(DeviceExtension->FontBitfield, TAG_BLUE);
|
ExFreePoolWithTag(DeviceExtension->FontBitfield, TAG_BLUE);
|
||||||
DeviceExtension->FontBitfield = ExAllocatePoolWithTag(NonPagedPool, 256 * 8, TAG_BLUE);
|
DeviceExtension->FontBitfield = ExAllocatePoolWithTag(NonPagedPool, 256 * 8, TAG_BLUE);
|
||||||
|
@ -1548,7 +1517,7 @@ ScrIoControl(
|
||||||
}
|
}
|
||||||
RtlCopyMemory(DeviceExtension->FontBitfield, Irp->AssociatedIrp.SystemBuffer, 256 * 8);
|
RtlCopyMemory(DeviceExtension->FontBitfield, Irp->AssociatedIrp.SystemBuffer, 256 * 8);
|
||||||
|
|
||||||
/* Upload the font if needed */
|
/* Set the font if needed */
|
||||||
if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
|
if (DeviceExtension->Enabled && DeviceExtension->VideoMemory)
|
||||||
ScrSetFont(DeviceExtension->FontBitfield);
|
ScrSetFont(DeviceExtension->FontBitfield);
|
||||||
|
|
||||||
|
|
|
@ -67,35 +67,9 @@ typedef struct tagCONSOLE_CURSOR_INFO
|
||||||
#define BACKGROUND_RED 0x0040
|
#define BACKGROUND_RED 0x0040
|
||||||
#define BACKGROUND_INTENSITY 0x0080
|
#define BACKGROUND_INTENSITY 0x0080
|
||||||
|
|
||||||
typedef struct _CFHEADER
|
/*
|
||||||
{
|
* VGA registers
|
||||||
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"
|
|
||||||
|
|
||||||
#define VIDMEM_BASE 0xb8000
|
#define VIDMEM_BASE 0xb8000
|
||||||
#define BITPLANE_BASE 0xa0000
|
#define BITPLANE_BASE 0xa0000
|
||||||
|
|
||||||
|
@ -144,7 +118,6 @@ typedef struct _CFFILE
|
||||||
#define PELINDEX (PUCHAR)0x3c8
|
#define PELINDEX (PUCHAR)0x3c8
|
||||||
#define PELDATA (PUCHAR)0x3c9
|
#define PELDATA (PUCHAR)0x3c9
|
||||||
|
|
||||||
VOID ScrLoadFontTable(_In_ ULONG CodePage);
|
|
||||||
VOID ScrSetFont(_In_ PUCHAR FontBitfield);
|
VOID ScrSetFont(_In_ PUCHAR FontBitfield);
|
||||||
|
|
||||||
#endif /* _BLUE_PCH_ */
|
#endif /* _BLUE_PCH_ */
|
||||||
|
|
|
@ -10,58 +10,17 @@
|
||||||
/* INCLUDES ***************************************************************/
|
/* INCLUDES ***************************************************************/
|
||||||
|
|
||||||
#include "blue.h"
|
#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 OpenBitPlane(VOID);
|
||||||
VOID CloseBitPlane(VOID);
|
VOID CloseBitPlane(VOID);
|
||||||
VOID LoadFont(_In_ PUCHAR Bitplane, _In_ PUCHAR FontBitfield);
|
VOID LoadFont(_In_ PUCHAR Bitplane, _In_ PUCHAR FontBitfield);
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* 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
|
VOID
|
||||||
ScrSetFont(
|
ScrSetFont(
|
||||||
_In_ PUCHAR FontBitfield)
|
_In_ PUCHAR FontBitfield)
|
||||||
|
@ -86,195 +45,6 @@ ScrSetFont(
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS *********************************************************/
|
/* 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 */
|
/* Font-load specific funcs */
|
||||||
VOID
|
VOID
|
||||||
OpenBitPlane(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_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_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 **************************************************************/
|
/* TYPEDEFS **************************************************************/
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* FILE: win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c
|
* FILE: win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c
|
||||||
* PURPOSE: TUI Terminal Front-End - Virtual Consoles...
|
* PURPOSE: TUI Terminal Front-End - Virtual Consoles...
|
||||||
* PROGRAMMERS: David Welch
|
* PROGRAMMERS: David Welch
|
||||||
* Gé van Geldorp
|
* Gé van Geldorp
|
||||||
* Jeffrey Morlan
|
* Jeffrey Morlan
|
||||||
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||||
*/
|
*/
|
||||||
|
@ -26,7 +26,41 @@
|
||||||
#include <debug.h>
|
#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) \
|
#define ConsoleOutputUnicodeToAnsiChar(Console, dChar, sWChar) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -374,8 +408,222 @@ TuiConsoleThread(PVOID Param)
|
||||||
return 0;
|
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
|
static BOOL
|
||||||
TuiInit(DWORD OemCP)
|
TuiInit(IN UINT OemCP)
|
||||||
{
|
{
|
||||||
BOOL Success;
|
BOOL Success;
|
||||||
CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
|
CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
|
||||||
|
@ -417,9 +665,7 @@ TuiInit(DWORD OemCP)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_LOADFONT,
|
if (!TuiSetConsoleOutputCP(ConsoleDeviceHandle, OemCP))
|
||||||
&OemCP, sizeof(OemCP), NULL, 0,
|
|
||||||
&BytesReturned, NULL))
|
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to load the font for codepage %d\n", OemCP);
|
DPRINT1("Failed to load the font for codepage %d\n", OemCP);
|
||||||
/* Let's suppose the font is good enough to continue */
|
/* Let's suppose the font is good enough to continue */
|
||||||
|
|
Loading…
Reference in a new issue