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 ****************************************************************/
27 ScrLoadFontTable(UINT32 CodePage
)
29 PHYSICAL_ADDRESS BaseAddress
;
31 PUCHAR FontBitfield
= NULL
;
32 NTSTATUS Status
= STATUS_SUCCESS
;
34 FontBitfield
= (PUCHAR
) ExAllocatePoolWithTag(NonPagedPool
, 2048, TAG_BLUE
);
37 /* open bit plane for font table access */
40 /* get pointer to video memory */
41 BaseAddress
.QuadPart
= BITPLANE_BASE
;
42 Bitplane
= (PUCHAR
)MmMapIoSpace (BaseAddress
, 0xFFFF, MmNonCached
);
44 Status
= ExtractFont(CodePage
, FontBitfield
);
45 if (NT_SUCCESS(Status
))
46 LoadFont(Bitplane
, FontBitfield
);
48 MmUnmapIoSpace(Bitplane
, 0xFFFF);
49 ExFreePool(FontBitfield
);
56 /* PRIVATE FUNCTIONS *********************************************************/
58 NTSTATUS
ExtractFont(UINT32 CodePage
, PUCHAR FontBitField
)
60 BOOLEAN bFoundFile
= FALSE
;
64 IO_STATUS_BLOCK IoStatusBlock
;
65 OBJECT_ATTRIBUTES ObjectAttributes
;
66 UNICODE_STRING LinkName
;
67 UNICODE_STRING SourceName
;
68 CFHEADER CabFileHeader
;
70 ULONG CabFileOffset
= 0;
71 LARGE_INTEGER ByteOffset
;
72 WCHAR SourceBuffer
[MAX_PATH
] = {L
'\0'};
75 if(KeGetCurrentIrql() != PASSIVE_LEVEL
)
76 return STATUS_INVALID_DEVICE_STATE
;
78 RtlInitUnicodeString(&LinkName
,
81 InitializeObjectAttributes(&ObjectAttributes
,
87 Status
= ZwOpenSymbolicLinkObject(&Handle
,
88 SYMBOLIC_LINK_ALL_ACCESS
,
91 if (!NT_SUCCESS(Status
))
94 SourceName
.Length
= 0;
95 SourceName
.MaximumLength
= MAX_PATH
* sizeof(WCHAR
);
96 SourceName
.Buffer
= SourceBuffer
;
98 Status
= ZwQuerySymbolicLinkObject(Handle
,
103 Status
= RtlAppendUnicodeToString(&SourceName
, L
"\\vgafonts.cab");
104 InitializeObjectAttributes(&ObjectAttributes
, &SourceName
,
105 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
108 Status
= ZwCreateFile(&Handle
,
110 &ObjectAttributes
, &IoStatusBlock
, NULL
,
111 FILE_ATTRIBUTE_NORMAL
,
114 FILE_SYNCHRONOUS_IO_NONALERT
,
117 ByteOffset
.LowPart
= ByteOffset
.HighPart
= 0;
119 if(NT_SUCCESS(Status
))
121 Status
= ZwReadFile(Handle
, NULL
, NULL
, NULL
, &IoStatusBlock
,
122 &CabFileHeader
, sizeof(CabFileHeader
), &ByteOffset
, NULL
);
124 if(NT_SUCCESS(Status
))
126 if(CabFileHeader
.Signature
== CAB_SIGNATURE
)
128 // We have a valid CAB file!
129 // Read the file table now and decrement the file count on every file. When it's zero, we read the complete table.
130 ByteOffset
.LowPart
= CabFileHeader
.FileTableOffset
;
132 while(CabFileHeader
.FileCount
)
134 Status
= ZwReadFile(Handle
, NULL
, NULL
, NULL
, &IoStatusBlock
,
135 &CabFile
, sizeof(CabFile
), &ByteOffset
, NULL
);
137 if(NT_SUCCESS(Status
))
139 ByteOffset
.LowPart
+= sizeof(CabFile
);
141 // We assume here that the file name is max. 19 characters (+ 1 NULL character) long.
142 // This should be enough for our purpose.
143 Status
= ZwReadFile(Handle
, NULL
, NULL
, NULL
, &IoStatusBlock
,
144 FileName
, sizeof(FileName
), &ByteOffset
, NULL
);
146 if(NT_SUCCESS(Status
))
150 Status
= RtlCharToInteger(FileName
, 0, &ReadCP
);
151 if (NT_SUCCESS(Status
) && ReadCP
== CodePage
)
153 // We got the correct file.
154 // Save the offset and loop through the rest of the file table to find the position, where the actual data starts.
155 CabFileOffset
= CabFile
.FileOffset
;
160 ByteOffset
.LowPart
+= strlen(FileName
) + 1;
164 CabFileHeader
.FileCount
--;
167 // 8 = Size of a CFFOLDER structure (see cabman). As we don't need the values of that structure, just increase the offset here.
168 ByteOffset
.LowPart
+= 8;
169 ByteOffset
.LowPart
+= CabFileOffset
;
171 // ByteOffset now contains the offset of the actual data, so we can read the RAW font
172 Status
= ZwReadFile(Handle
, NULL
, NULL
, NULL
, &IoStatusBlock
,
173 FontBitField
, 2048, &ByteOffset
, NULL
);
175 return STATUS_SUCCESS
;
179 DPRINT1("Error: CAB signature is missing!\n");
180 Status
= STATUS_UNSUCCESSFUL
;
184 DPRINT1("Error: Cannot read from file\n");
191 DPRINT1("Error: Cannot open vgafonts.cab\n");
196 /* Font-load specific funcs */
200 /* disable interrupts */
204 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_RESET
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x01);
205 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_ENABLE_WRT_PLANE
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x04);
206 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_MEM_MODE
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x07);
207 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_RESET
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x03);
210 WRITE_PORT_UCHAR (GCT_COMMAND
, GCT_READ_PLANE
); WRITE_PORT_UCHAR (GCT_DATA
, 0x02);
211 WRITE_PORT_UCHAR (GCT_COMMAND
, GCT_RW_MODES
); WRITE_PORT_UCHAR (GCT_DATA
, 0x00);
212 WRITE_PORT_UCHAR (GCT_COMMAND
, GCT_GRAPH_MODE
); WRITE_PORT_UCHAR (GCT_DATA
, 0x00);
214 /* enable interrupts */
221 /* disable interrupts */
225 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_RESET
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x01);
226 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_ENABLE_WRT_PLANE
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x03);
227 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_MEM_MODE
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x03);
228 WRITE_PORT_UCHAR (SEQ_COMMAND
, SEQ_RESET
); WRITE_PORT_UCHAR (SEQ_DATA
, 0x03);
231 WRITE_PORT_UCHAR (GCT_COMMAND
, GCT_READ_PLANE
); WRITE_PORT_UCHAR (GCT_DATA
, 0x00);
232 WRITE_PORT_UCHAR (GCT_COMMAND
, GCT_RW_MODES
); WRITE_PORT_UCHAR (GCT_DATA
, 0x10);
233 WRITE_PORT_UCHAR (GCT_COMMAND
, GCT_GRAPH_MODE
); WRITE_PORT_UCHAR (GCT_DATA
, 0x0e);
235 /* enable interrupts */
240 LoadFont(PUCHAR Bitplane
, PUCHAR FontBitfield
)
244 for (i
=0; i
<256; i
++)
248 *Bitplane
= FontBitfield
[i
*8+j
];