2 * PROJECT: ReactOS Setup Driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/setup/blue/font.c
5 * PURPOSE: Loading specific fonts into VGA
6 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
7 * Colin Finck (mail@colinfinck.de)
8 * Christoph von Wittich (christoph_vw@reactos.org)
11 /* INCLUDES ***************************************************************/
22 VOID
LoadFont(PUCHAR Bitplane
, PUCHAR FontBitfield
);
24 /* FUNCTIONS ****************************************************************/
30 PHYSICAL_ADDRESS BaseAddress
;
32 PUCHAR FontBitfield
= NULL
;
33 NTSTATUS Status
= STATUS_SUCCESS
;
35 FontBitfield
= (PUCHAR
)ExAllocatePoolWithTag(NonPagedPool
, 2048, TAG_BLUE
);
36 if (FontBitfield
== NULL
)
38 DPRINT1("ExAllocatePoolWithTag failed\n");
42 /* open bit plane for font table access */
45 /* get pointer to video memory */
46 BaseAddress
.QuadPart
= BITPLANE_BASE
;
47 Bitplane
= (PUCHAR
)MmMapIoSpace(BaseAddress
, 0xFFFF, MmNonCached
);
49 Status
= ExtractFont(CodePage
, FontBitfield
);
50 if (NT_SUCCESS(Status
))
52 LoadFont(Bitplane
, FontBitfield
);
56 DPRINT1("ExtractFont failed with Status 0x%lx\n", Status
);
59 MmUnmapIoSpace(Bitplane
, 0xFFFF);
60 ExFreePool(FontBitfield
);
66 /* PRIVATE FUNCTIONS *********************************************************/
73 BOOLEAN bFoundFile
= FALSE
;
77 IO_STATUS_BLOCK IoStatusBlock
;
78 OBJECT_ATTRIBUTES ObjectAttributes
;
79 UNICODE_STRING LinkName
;
80 UNICODE_STRING SourceName
;
81 CFHEADER CabFileHeader
;
83 ULONG CabFileOffset
= 0;
84 LARGE_INTEGER ByteOffset
;
85 WCHAR SourceBuffer
[MAX_PATH
] = { L
'\0' };
88 if (KeGetCurrentIrql() != PASSIVE_LEVEL
)
89 return STATUS_INVALID_DEVICE_STATE
;
91 RtlInitUnicodeString(&LinkName
,
94 InitializeObjectAttributes(&ObjectAttributes
,
96 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
100 Status
= ZwOpenSymbolicLinkObject(&Handle
,
101 SYMBOLIC_LINK_ALL_ACCESS
,
104 if (!NT_SUCCESS(Status
))
106 DPRINT1("ZwOpenSymbolicLinkObject failed with Status 0x%lx\n", Status
);
110 SourceName
.Length
= 0;
111 SourceName
.MaximumLength
= MAX_PATH
* sizeof(WCHAR
);
112 SourceName
.Buffer
= SourceBuffer
;
114 Status
= ZwQuerySymbolicLinkObject(Handle
,
119 if (!NT_SUCCESS(Status
))
121 DPRINT1("ZwQuerySymbolicLinkObject failed with Status 0x%lx\n", Status
);
125 Status
= RtlAppendUnicodeToString(&SourceName
, L
"\\vgafonts.cab");
126 if (!NT_SUCCESS(Status
))
128 DPRINT1("RtlAppendUnicodeToString failed with Status 0x%lx\n", Status
);
132 InitializeObjectAttributes(&ObjectAttributes
,
134 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
138 Status
= ZwCreateFile(&Handle
,
143 FILE_ATTRIBUTE_NORMAL
,
146 FILE_SYNCHRONOUS_IO_NONALERT
,
149 if (!NT_SUCCESS(Status
))
151 DPRINT1("Error: Cannot open vgafonts.cab (0x%lx)\n", Status
);
155 ByteOffset
.QuadPart
= 0;
156 Status
= ZwReadFile(Handle
,
162 sizeof(CabFileHeader
),
166 if (!NT_SUCCESS(Status
))
168 DPRINT1("Error: Cannot read from file (0x%lx)\n", Status
);
172 if (CabFileHeader
.Signature
!= CAB_SIGNATURE
)
174 DPRINT1("Invalid CAB signature: 0x%lx!\n", CabFileHeader
.Signature
);
175 Status
= STATUS_UNSUCCESSFUL
;
179 // We have a valid CAB file!
180 // Read the file table now and decrement the file count on every file. When it's zero, we read the complete table.
181 ByteOffset
.QuadPart
= CabFileHeader
.FileTableOffset
;
183 while (CabFileHeader
.FileCount
)
185 Status
= ZwReadFile(Handle
,
195 if (NT_SUCCESS(Status
))
197 ByteOffset
.QuadPart
+= sizeof(CabFile
);
199 // We assume here that the file name is max. 19 characters (+ 1 NULL character) long.
200 // This should be enough for our purpose.
201 Status
= ZwReadFile(Handle
,
211 if (NT_SUCCESS(Status
))
215 Status
= RtlCharToInteger(FileName
, 0, &ReadCP
);
216 if (NT_SUCCESS(Status
) && ReadCP
== CodePage
)
218 // We got the correct file.
219 // Save the offset and loop through the rest of the file table to find the position, where the actual data starts.
220 CabFileOffset
= CabFile
.FileOffset
;
225 ByteOffset
.QuadPart
+= strlen(FileName
) + 1;
229 CabFileHeader
.FileCount
--;
232 // 8 = Size of a CFFOLDER structure (see cabman). As we don't need the values of that structure, just increase the offset here.
233 ByteOffset
.QuadPart
+= 8;
234 ByteOffset
.QuadPart
+= CabFileOffset
;
236 // ByteOffset now contains the offset of the actual data, so we can read the RAW font
237 Status
= ZwReadFile(Handle
,
246 if (!NT_SUCCESS(Status
))
248 DPRINT1("ZwReadFile failed with Status 0x%lx\n", Status
);
257 /* Font-load specific funcs */
261 /* disable interrupts */
265 WRITE_PORT_UCHAR(SEQ_COMMAND
, SEQ_RESET
); WRITE_PORT_UCHAR(SEQ_DATA
, 0x01);
266 WRITE_PORT_UCHAR(SEQ_COMMAND
, SEQ_ENABLE_WRT_PLANE
); WRITE_PORT_UCHAR(SEQ_DATA
, 0x04);
267 WRITE_PORT_UCHAR(SEQ_COMMAND
, SEQ_MEM_MODE
); WRITE_PORT_UCHAR(SEQ_DATA
, 0x07);
268 WRITE_PORT_UCHAR(SEQ_COMMAND
, SEQ_RESET
); WRITE_PORT_UCHAR(SEQ_DATA
, 0x03);
271 WRITE_PORT_UCHAR(GCT_COMMAND
, GCT_READ_PLANE
); WRITE_PORT_UCHAR(GCT_DATA
, 0x02);
272 WRITE_PORT_UCHAR(GCT_COMMAND
, GCT_RW_MODES
); WRITE_PORT_UCHAR(GCT_DATA
, 0x00);
273 WRITE_PORT_UCHAR(GCT_COMMAND
, GCT_GRAPH_MODE
); WRITE_PORT_UCHAR(GCT_DATA
, 0x00);
275 /* enable interrupts */
282 /* disable interrupts */
286 WRITE_PORT_UCHAR(SEQ_COMMAND
, SEQ_RESET
); WRITE_PORT_UCHAR(SEQ_DATA
, 0x01);
287 WRITE_PORT_UCHAR(SEQ_COMMAND
, SEQ_ENABLE_WRT_PLANE
); WRITE_PORT_UCHAR(SEQ_DATA
, 0x03);
288 WRITE_PORT_UCHAR(SEQ_COMMAND
, SEQ_MEM_MODE
); WRITE_PORT_UCHAR(SEQ_DATA
, 0x03);
289 WRITE_PORT_UCHAR(SEQ_COMMAND
, SEQ_RESET
); WRITE_PORT_UCHAR(SEQ_DATA
, 0x03);
292 WRITE_PORT_UCHAR(GCT_COMMAND
, GCT_READ_PLANE
); WRITE_PORT_UCHAR(GCT_DATA
, 0x00);
293 WRITE_PORT_UCHAR(GCT_COMMAND
, GCT_RW_MODES
); WRITE_PORT_UCHAR(GCT_DATA
, 0x10);
294 WRITE_PORT_UCHAR(GCT_COMMAND
, GCT_GRAPH_MODE
); WRITE_PORT_UCHAR(GCT_DATA
, 0x0e);
296 /* enable interrupts */
307 for (i
= 0; i
< 256; i
++)
309 for (j
= 0; j
< 8; j
++)
311 *Bitplane
= FontBitfield
[i
* 8 + j
];
316 for (j
= 8; j
< 32; j
++)