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 ***************************************************************/
21 VOID
LoadFont(PUCHAR Bitplane
, PUCHAR FontBitfield
);
23 /* FUNCTIONS ****************************************************************/
26 ScrLoadFontTable(UINT32 CodePage
)
28 PHYSICAL_ADDRESS BaseAddress
;
30 PUCHAR FontBitfield
= NULL
;
31 NTSTATUS Status
= STATUS_SUCCESS
;
33 FontBitfield
= (PUCHAR
) ExAllocatePoolWithTag(NonPagedPool
, 2048, TAG_BLUE
);
36 /* open bit plane for font table access */
39 /* get pointer to video memory */
40 BaseAddress
.QuadPart
= BITPLANE_BASE
;
41 Bitplane
= (PUCHAR
)MmMapIoSpace (BaseAddress
, 0xFFFF, MmNonCached
);
43 Status
= ExtractFont(CodePage
, FontBitfield
);
44 if (NT_SUCCESS(Status
))
45 LoadFont(Bitplane
, FontBitfield
);
47 MmUnmapIoSpace(Bitplane
, 0xFFFF);
48 ExFreePool(FontBitfield
);
55 /* PRIVATE FUNCTIONS *********************************************************/
57 NTSTATUS
ExtractFont(UINT32 CodePage
, PUCHAR FontBitField
)
59 BOOLEAN bFoundFile
= FALSE
;
63 IO_STATUS_BLOCK IoStatusBlock
;
64 OBJECT_ATTRIBUTES ObjectAttributes
;
65 UNICODE_STRING LinkName
;
66 UNICODE_STRING SourceName
;
67 CFHEADER CabFileHeader
;
69 ULONG CabFileOffset
= 0;
70 LARGE_INTEGER ByteOffset
;
71 WCHAR SourceBuffer
[MAX_PATH
] = {L
'\0'};
74 if(KeGetCurrentIrql() != PASSIVE_LEVEL
)
75 return STATUS_INVALID_DEVICE_STATE
;
77 RtlInitUnicodeString(&LinkName
,
80 InitializeObjectAttributes(&ObjectAttributes
,
86 Status
= ZwOpenSymbolicLinkObject(&Handle
,
87 SYMBOLIC_LINK_ALL_ACCESS
,
90 if (!NT_SUCCESS(Status
))
93 SourceName
.Length
= 0;
94 SourceName
.MaximumLength
= MAX_PATH
* sizeof(WCHAR
);
95 SourceName
.Buffer
= SourceBuffer
;
97 Status
= ZwQuerySymbolicLinkObject(Handle
,
102 Status
= RtlAppendUnicodeToString(&SourceName
, L
"\\vgafonts.cab");
103 InitializeObjectAttributes(&ObjectAttributes
, &SourceName
,
104 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
107 Status
= ZwCreateFile(&Handle
,
109 &ObjectAttributes
, &IoStatusBlock
, NULL
,
110 FILE_ATTRIBUTE_NORMAL
,
113 FILE_SYNCHRONOUS_IO_NONALERT
,
116 ByteOffset
.LowPart
= ByteOffset
.HighPart
= 0;
118 if(NT_SUCCESS(Status
))
120 Status
= ZwReadFile(Handle
, NULL
, NULL
, NULL
, &IoStatusBlock
,
121 &CabFileHeader
, sizeof(CabFileHeader
), &ByteOffset
, NULL
);
123 if(NT_SUCCESS(Status
))
125 if(CabFileHeader
.Signature
== CAB_SIGNATURE
)
127 // We have a valid CAB file!
128 // Read the file table now and decrement the file count on every file. When it's zero, we read the complete table.
129 ByteOffset
.LowPart
= CabFileHeader
.FileTableOffset
;
131 while(CabFileHeader
.FileCount
)
133 Status
= ZwReadFile(Handle
, NULL
, NULL
, NULL
, &IoStatusBlock
,
134 &CabFile
, sizeof(CabFile
), &ByteOffset
, NULL
);
136 if(NT_SUCCESS(Status
))
138 ByteOffset
.LowPart
+= sizeof(CabFile
);
140 // We assume here that the file name is max. 19 characters (+ 1 NULL character) long.
141 // This should be enough for our purpose.
142 Status
= ZwReadFile(Handle
, NULL
, NULL
, NULL
, &IoStatusBlock
,
143 FileName
, sizeof(FileName
), &ByteOffset
, NULL
);
145 if(NT_SUCCESS(Status
))
149 Status
= RtlCharToInteger(FileName
, 0, &ReadCP
);
150 if (NT_SUCCESS(Status
) && ReadCP
== CodePage
)
152 // We got the correct file.
153 // Save the offset and loop through the rest of the file table to find the position, where the actual data starts.
154 CabFileOffset
= CabFile
.FileOffset
;
159 ByteOffset
.LowPart
+= strlen(FileName
) + 1;
163 CabFileHeader
.FileCount
--;
166 // 8 = Size of a CFFOLDER structure (see cabman). As we don't need the values of that structure, just increase the offset here.
167 ByteOffset
.LowPart
+= 8;
168 ByteOffset
.LowPart
+= CabFileOffset
;
170 // ByteOffset now contains the offset of the actual data, so we can read the RAW font
171 Status
= ZwReadFile(Handle
, NULL
, NULL
, NULL
, &IoStatusBlock
,
172 FontBitField
, 2048, &ByteOffset
, NULL
);
174 return STATUS_SUCCESS
;
178 DPRINT1("Error: CAB signature is missing!\n");
179 Status
= STATUS_UNSUCCESSFUL
;
183 DPRINT1("Error: Cannot read from file\n");
190 DPRINT1("Error: Cannot open vgafonts.cab\n");
195 /* Font-load specific funcs */
199 /* disable interrupts */
203 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_RESET
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x01);
204 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_ENABLE_WRT_PLANE
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x04);
205 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_MEM_MODE
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x07);
206 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_RESET
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x03);
209 WRITE_PORT_UCHAR (GCT_COMMAND
, GCT_READ_PLANE
); WRITE_PORT_UCHAR (GCT_DATA
, 0x02);
210 WRITE_PORT_UCHAR (GCT_COMMAND
, GCT_RW_MODES
); WRITE_PORT_UCHAR (GCT_DATA
, 0x00);
211 WRITE_PORT_UCHAR (GCT_COMMAND
, GCT_GRAPH_MODE
); WRITE_PORT_UCHAR (GCT_DATA
, 0x00);
213 /* enable interrupts */
220 /* disable interrupts */
224 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_RESET
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x01);
225 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_ENABLE_WRT_PLANE
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x03);
226 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_MEM_MODE
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x03);
227 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_RESET
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x03);
230 WRITE_PORT_UCHAR (GCT_COMMAND
, GCT_READ_PLANE
); WRITE_PORT_UCHAR (GCT_DATA
, 0x00);
231 WRITE_PORT_UCHAR (GCT_COMMAND
, GCT_RW_MODES
); WRITE_PORT_UCHAR (GCT_DATA
, 0x10);
232 WRITE_PORT_UCHAR (GCT_COMMAND
, GCT_GRAPH_MODE
); WRITE_PORT_UCHAR (GCT_DATA
, 0x0e);
234 /* enable interrupts */
239 LoadFont(PUCHAR Bitplane
, PUCHAR FontBitfield
)
243 for (i
=0; i
<256; i
++)
247 *Bitplane
= FontBitfield
[i
*8+j
];