+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);
+}
+