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'};
73 if(KeGetCurrentIrql() != PASSIVE_LEVEL
)
74 return STATUS_INVALID_DEVICE_STATE
;
76 RtlInitUnicodeString(&LinkName
,
79 InitializeObjectAttributes(&ObjectAttributes
,
85 Status
= ZwOpenSymbolicLinkObject(&Handle
,
86 SYMBOLIC_LINK_ALL_ACCESS
,
89 if (!NT_SUCCESS(Status
))
92 SourceName
.Length
= 0;
93 SourceName
.MaximumLength
= _MAX_PATH
* sizeof(WCHAR
);
94 SourceName
.Buffer
= SourceBuffer
;
96 Status
= ZwQuerySymbolicLinkObject(Handle
,
101 Status
= RtlAppendUnicodeToString(&SourceName
, L
"\\vgafonts.cab");
102 InitializeObjectAttributes(&ObjectAttributes
, &SourceName
,
103 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
106 Status
= ZwCreateFile(&Handle
,
108 &ObjectAttributes
, &IoStatusBlock
, NULL
,
109 FILE_ATTRIBUTE_NORMAL
,
112 FILE_SYNCHRONOUS_IO_NONALERT
,
115 ByteOffset
.LowPart
= ByteOffset
.HighPart
= 0;
117 if(NT_SUCCESS(Status
))
119 Status
= ZwReadFile(Handle
, NULL
, NULL
, NULL
, &IoStatusBlock
,
120 &CabFileHeader
, sizeof(CabFileHeader
), &ByteOffset
, NULL
);
122 if(NT_SUCCESS(Status
))
124 if(CabFileHeader
.Signature
== CAB_SIGNATURE
)
126 // We have a valid CAB file!
127 // Read the file table now and decrement the file count on every file. When it's zero, we read the complete table.
128 ByteOffset
.LowPart
= CabFileHeader
.FileTableOffset
;
130 while(CabFileHeader
.FileCount
)
132 Status
= ZwReadFile(Handle
, NULL
, NULL
, NULL
, &IoStatusBlock
,
133 &CabFile
, sizeof(CabFile
), &ByteOffset
, NULL
);
135 if(NT_SUCCESS(Status
))
137 ByteOffset
.LowPart
+= sizeof(CabFile
);
139 // We assume here that the file name is max. 19 characters (+ 1 NULL character) long.
140 // This should be enough for our purpose.
141 Status
= ZwReadFile(Handle
, NULL
, NULL
, NULL
, &IoStatusBlock
,
142 FileName
, sizeof(FileName
), &ByteOffset
, NULL
);
144 if(NT_SUCCESS(Status
))
146 if(!bFoundFile
&& (UINT32
)atoi(FileName
) == CodePage
)
148 // We got the correct file.
149 // Save the offset and loop through the rest of the file table to find the position, where the actual data starts.
150 CabFileOffset
= CabFile
.FileOffset
;
154 ByteOffset
.LowPart
+= strlen(FileName
) + 1;
158 CabFileHeader
.FileCount
--;
161 // 8 = Size of a CFFOLDER structure (see cabman). As we don't need the values of that structure, just increase the offset here.
162 ByteOffset
.LowPart
+= 8;
163 ByteOffset
.LowPart
+= CabFileOffset
;
165 // ByteOffset now contains the offset of the actual data, so we can read the RAW font
166 Status
= ZwReadFile(Handle
, NULL
, NULL
, NULL
, &IoStatusBlock
,
167 FontBitField
, 2048, &ByteOffset
, NULL
);
169 return STATUS_SUCCESS
;
173 DPRINT1("Error: CAB signature is missing!\n");
174 Status
= STATUS_UNSUCCESSFUL
;
178 DPRINT1("Error: Cannot read from file\n");
185 DPRINT1("Error: Cannot open vgafonts.cab\n");
190 /* Font-load specific funcs */
194 /* disable interrupts */
198 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_RESET
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x01);
199 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_ENABLE_WRT_PLANE
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x04);
200 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_MEM_MODE
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x07);
201 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_RESET
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x03);
204 WRITE_PORT_UCHAR (GCT_COMMAND
, GCT_READ_PLANE
); WRITE_PORT_UCHAR (GCT_DATA
, 0x02);
205 WRITE_PORT_UCHAR (GCT_COMMAND
, GCT_RW_MODES
); WRITE_PORT_UCHAR (GCT_DATA
, 0x00);
206 WRITE_PORT_UCHAR (GCT_COMMAND
, GCT_GRAPH_MODE
); WRITE_PORT_UCHAR (GCT_DATA
, 0x00);
208 /* enable interrupts */
215 /* disable interrupts */
219 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_RESET
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x01);
220 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_ENABLE_WRT_PLANE
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x03);
221 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_MEM_MODE
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x03);
222 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_RESET
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x03);
225 WRITE_PORT_UCHAR (GCT_COMMAND
, GCT_READ_PLANE
); WRITE_PORT_UCHAR (GCT_DATA
, 0x00);
226 WRITE_PORT_UCHAR (GCT_COMMAND
, GCT_RW_MODES
); WRITE_PORT_UCHAR (GCT_DATA
, 0x10);
227 WRITE_PORT_UCHAR (GCT_COMMAND
, GCT_GRAPH_MODE
); WRITE_PORT_UCHAR (GCT_DATA
, 0x0e);
229 /* enable interrupts */
234 LoadFont(PUCHAR Bitplane
, PUCHAR FontBitfield
)
238 for (i
=0; i
<256; i
++)
242 *Bitplane
= FontBitfield
[i
*8+j
];