[BLUE] Use ByteOffset.QuadPrt instead of ByteOffset.LowPart
[reactos.git] / drivers / setup / blue / font.c
1 /*
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)
9 */
10
11 /* INCLUDES ***************************************************************/
12
13 #include "blue.h"
14
15 #include <ntddk.h>
16
17 #define NDEBUG
18 #include <debug.h>
19
20 VOID OpenBitPlane();
21 VOID CloseBitPlane();
22 VOID LoadFont(PUCHAR Bitplane, PUCHAR FontBitfield);
23
24 /* FUNCTIONS ****************************************************************/
25
26 VOID
27 ScrLoadFontTable(
28 UINT32 CodePage)
29 {
30 PHYSICAL_ADDRESS BaseAddress;
31 PUCHAR Bitplane;
32 PUCHAR FontBitfield = NULL;
33 NTSTATUS Status = STATUS_SUCCESS;
34
35 FontBitfield = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, 2048, TAG_BLUE);
36 if (FontBitfield == NULL)
37 {
38 DPRINT1("ExAllocatePoolWithTag failed\n");
39 return;
40 }
41
42 /* open bit plane for font table access */
43 OpenBitPlane();
44
45 /* get pointer to video memory */
46 BaseAddress.QuadPart = BITPLANE_BASE;
47 Bitplane = (PUCHAR)MmMapIoSpace(BaseAddress, 0xFFFF, MmNonCached);
48
49 Status = ExtractFont(CodePage, FontBitfield);
50 if (NT_SUCCESS(Status))
51 {
52 LoadFont(Bitplane, FontBitfield);
53 }
54 else
55 {
56 DPRINT1("ExtractFont failed with Status 0x%lx\n", Status);
57 }
58
59 MmUnmapIoSpace(Bitplane, 0xFFFF);
60 ExFreePool(FontBitfield);
61
62 /* close bit plane */
63 CloseBitPlane();
64 }
65
66 /* PRIVATE FUNCTIONS *********************************************************/
67
68 NTSTATUS
69 ExtractFont(
70 UINT32 CodePage,
71 PUCHAR FontBitField)
72 {
73 BOOLEAN bFoundFile = FALSE;
74 HANDLE Handle;
75 NTSTATUS Status;
76 CHAR FileName[20];
77 IO_STATUS_BLOCK IoStatusBlock;
78 OBJECT_ATTRIBUTES ObjectAttributes;
79 UNICODE_STRING LinkName;
80 UNICODE_STRING SourceName;
81 CFHEADER CabFileHeader;
82 CFFILE CabFile;
83 ULONG CabFileOffset = 0;
84 LARGE_INTEGER ByteOffset;
85 WCHAR SourceBuffer[MAX_PATH] = { L'\0' };
86 ULONG ReadCP;
87
88 if (KeGetCurrentIrql() != PASSIVE_LEVEL)
89 return STATUS_INVALID_DEVICE_STATE;
90
91 RtlInitUnicodeString(&LinkName,
92 L"\\SystemRoot");
93
94 InitializeObjectAttributes(&ObjectAttributes,
95 &LinkName,
96 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
97 NULL,
98 NULL);
99
100 Status = ZwOpenSymbolicLinkObject(&Handle,
101 SYMBOLIC_LINK_ALL_ACCESS,
102 &ObjectAttributes);
103
104 if (!NT_SUCCESS(Status))
105 {
106 DPRINT1("ZwOpenSymbolicLinkObject failed with Status 0x%lx\n", Status);
107 return Status;
108 }
109
110 SourceName.Length = 0;
111 SourceName.MaximumLength = MAX_PATH * sizeof(WCHAR);
112 SourceName.Buffer = SourceBuffer;
113
114 Status = ZwQuerySymbolicLinkObject(Handle,
115 &SourceName,
116 NULL);
117 ZwClose(Handle);
118
119 if (!NT_SUCCESS(Status))
120 {
121 DPRINT1("ZwQuerySymbolicLinkObject failed with Status 0x%lx\n", Status);
122 return Status;
123 }
124
125 Status = RtlAppendUnicodeToString(&SourceName, L"\\vgafonts.cab");
126 if (!NT_SUCCESS(Status))
127 {
128 DPRINT1("RtlAppendUnicodeToString failed with Status 0x%lx\n", Status);
129 return Status;
130 }
131
132 InitializeObjectAttributes(&ObjectAttributes,
133 &SourceName,
134 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
135 NULL,
136 NULL);
137
138 Status = ZwCreateFile(&Handle,
139 GENERIC_READ,
140 &ObjectAttributes,
141 &IoStatusBlock,
142 NULL,
143 FILE_ATTRIBUTE_NORMAL,
144 0,
145 FILE_OPEN,
146 FILE_SYNCHRONOUS_IO_NONALERT,
147 NULL,
148 0);
149 if (!NT_SUCCESS(Status))
150 {
151 DPRINT1("Error: Cannot open vgafonts.cab (0x%lx)\n", Status);
152 return Status;
153 }
154
155 ByteOffset.QuadPart = 0;
156 Status = ZwReadFile(Handle,
157 NULL,
158 NULL,
159 NULL,
160 &IoStatusBlock,
161 &CabFileHeader,
162 sizeof(CabFileHeader),
163 &ByteOffset,
164 NULL);
165
166 if (!NT_SUCCESS(Status))
167 {
168 DPRINT1("Error: Cannot read from file (0x%lx)\n", Status);
169 goto Exit;
170 }
171
172 if (CabFileHeader.Signature != CAB_SIGNATURE)
173 {
174 DPRINT1("Invalid CAB signature: 0x%lx!\n", CabFileHeader.Signature);
175 Status = STATUS_UNSUCCESSFUL;
176 goto Exit;
177 }
178
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;
182
183 while (CabFileHeader.FileCount)
184 {
185 Status = ZwReadFile(Handle,
186 NULL,
187 NULL,
188 NULL,
189 &IoStatusBlock,
190 &CabFile,
191 sizeof(CabFile),
192 &ByteOffset,
193 NULL);
194
195 if (NT_SUCCESS(Status))
196 {
197 ByteOffset.QuadPart += sizeof(CabFile);
198
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,
202 NULL,
203 NULL,
204 NULL,
205 &IoStatusBlock,
206 FileName,
207 sizeof(FileName),
208 &ByteOffset,
209 NULL);
210
211 if (NT_SUCCESS(Status))
212 {
213 if (!bFoundFile)
214 {
215 Status = RtlCharToInteger(FileName, 0, &ReadCP);
216 if (NT_SUCCESS(Status) && ReadCP == CodePage)
217 {
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;
221 bFoundFile = TRUE;
222 }
223 }
224
225 ByteOffset.QuadPart += strlen(FileName) + 1;
226 }
227 }
228
229 CabFileHeader.FileCount--;
230 }
231
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;
235
236 // ByteOffset now contains the offset of the actual data, so we can read the RAW font
237 Status = ZwReadFile(Handle,
238 NULL,
239 NULL,
240 NULL,
241 &IoStatusBlock,
242 FontBitField,
243 2048,
244 &ByteOffset,
245 NULL);
246 if (!NT_SUCCESS(Status))
247 {
248 DPRINT1("ZwReadFile failed with Status 0x%lx\n", Status);
249 }
250
251 Exit:
252
253 ZwClose(Handle);
254 return Status;
255 }
256
257 /* Font-load specific funcs */
258 VOID
259 OpenBitPlane(VOID)
260 {
261 /* disable interrupts */
262 _disable();
263
264 /* sequence reg */
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);
269
270 /* graphic reg */
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);
274
275 /* enable interrupts */
276 _enable();
277 }
278
279 VOID
280 CloseBitPlane(VOID)
281 {
282 /* disable interrupts */
283 _disable();
284
285 /* sequence reg */
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);
290
291 /* graphic reg */
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);
295
296 /* enable interrupts */
297 _enable();
298 }
299
300 VOID
301 LoadFont(
302 PUCHAR Bitplane,
303 PUCHAR FontBitfield)
304 {
305 UINT32 i, j;
306
307 for (i = 0; i < 256; i++)
308 {
309 for (j = 0; j < 8; j++)
310 {
311 *Bitplane = FontBitfield[i * 8 + j];
312 Bitplane++;
313 }
314
315 // padding
316 for (j = 8; j < 32; j++)
317 {
318 *Bitplane = 0;
319 Bitplane++;
320 }
321 }
322 }