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(UINT32 CodePage) 28 { 29 PHYSICAL_ADDRESS BaseAddress; 30 PUCHAR Bitplane; 31 PUCHAR FontBitfield = NULL; 32 NTSTATUS Status = STATUS_SUCCESS; 33 34 FontBitfield = (PUCHAR) ExAllocatePoolWithTag(NonPagedPool, 2048, TAG_BLUE); 35 if(FontBitfield) 36 { 37 /* open bit plane for font table access */ 38 OpenBitPlane(); 39 40 /* get pointer to video memory */ 41 BaseAddress.QuadPart = BITPLANE_BASE; 42 Bitplane = (PUCHAR)MmMapIoSpace (BaseAddress, 0xFFFF, MmNonCached); 43 44 Status = ExtractFont(CodePage, FontBitfield); 45 if (NT_SUCCESS(Status)) 46 LoadFont(Bitplane, FontBitfield); 47 48 MmUnmapIoSpace(Bitplane, 0xFFFF); 49 ExFreePool(FontBitfield); 50 51 /* close bit plane */ 52 CloseBitPlane(); 53 } 54 } 55 56 /* PRIVATE FUNCTIONS *********************************************************/ 57 58 NTSTATUS ExtractFont(UINT32 CodePage, PUCHAR FontBitField) 59 { 60 BOOLEAN bFoundFile = FALSE; 61 HANDLE Handle; 62 NTSTATUS Status; 63 CHAR FileName[20]; 64 IO_STATUS_BLOCK IoStatusBlock; 65 OBJECT_ATTRIBUTES ObjectAttributes; 66 UNICODE_STRING LinkName; 67 UNICODE_STRING SourceName; 68 CFHEADER CabFileHeader; 69 CFFILE CabFile; 70 ULONG CabFileOffset = 0; 71 LARGE_INTEGER ByteOffset; 72 WCHAR SourceBuffer[MAX_PATH] = {L'\0'}; 73 ULONG ReadCP; 74 75 if(KeGetCurrentIrql() != PASSIVE_LEVEL) 76 return STATUS_INVALID_DEVICE_STATE; 77 78 RtlInitUnicodeString(&LinkName, 79 L"\\SystemRoot"); 80 81 InitializeObjectAttributes(&ObjectAttributes, 82 &LinkName, 83 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 84 NULL, 85 NULL); 86 87 Status = ZwOpenSymbolicLinkObject(&Handle, 88 SYMBOLIC_LINK_ALL_ACCESS, 89 &ObjectAttributes); 90 91 if (!NT_SUCCESS(Status)) 92 return(Status); 93 94 SourceName.Length = 0; 95 SourceName.MaximumLength = MAX_PATH * sizeof(WCHAR); 96 SourceName.Buffer = SourceBuffer; 97 98 Status = ZwQuerySymbolicLinkObject(Handle, 99 &SourceName, 100 NULL); 101 ZwClose(Handle); 102 103 Status = RtlAppendUnicodeToString(&SourceName, L"\\vgafonts.cab"); 104 InitializeObjectAttributes(&ObjectAttributes, &SourceName, 105 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 106 NULL, NULL); 107 108 Status = ZwCreateFile(&Handle, 109 GENERIC_READ, 110 &ObjectAttributes, &IoStatusBlock, NULL, 111 FILE_ATTRIBUTE_NORMAL, 112 0, 113 FILE_OPEN, 114 FILE_SYNCHRONOUS_IO_NONALERT, 115 NULL, 0); 116 117 ByteOffset.LowPart = ByteOffset.HighPart = 0; 118 119 if(NT_SUCCESS(Status)) 120 { 121 Status = ZwReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock, 122 &CabFileHeader, sizeof(CabFileHeader), &ByteOffset, NULL); 123 124 if(NT_SUCCESS(Status)) 125 { 126 if(CabFileHeader.Signature == CAB_SIGNATURE) 127 { 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; 131 132 while(CabFileHeader.FileCount) 133 { 134 Status = ZwReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock, 135 &CabFile, sizeof(CabFile), &ByteOffset, NULL); 136 137 if(NT_SUCCESS(Status)) 138 { 139 ByteOffset.LowPart += sizeof(CabFile); 140 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); 145 146 if(NT_SUCCESS(Status)) 147 { 148 if(!bFoundFile) 149 { 150 Status = RtlCharToInteger(FileName, 0, &ReadCP); 151 if (NT_SUCCESS(Status) && ReadCP == CodePage) 152 { 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; 156 bFoundFile = TRUE; 157 } 158 } 159 160 ByteOffset.LowPart += strlen(FileName) + 1; 161 } 162 } 163 164 CabFileHeader.FileCount--; 165 } 166 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; 170 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); 174 ZwClose(Handle); 175 return STATUS_SUCCESS; 176 } 177 else 178 { 179 DPRINT1("Error: CAB signature is missing!\n"); 180 Status = STATUS_UNSUCCESSFUL; 181 } 182 } 183 else 184 DPRINT1("Error: Cannot read from file\n"); 185 186 ZwClose(Handle); 187 return Status; 188 } 189 else 190 { 191 DPRINT1("Error: Cannot open vgafonts.cab\n"); 192 return Status; 193 } 194 } 195 196 /* Font-load specific funcs */ 197 VOID 198 OpenBitPlane(VOID) 199 { 200 /* disable interrupts */ 201 _disable(); 202 203 /* sequence reg */ 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); 208 209 /* graphic reg */ 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); 213 214 /* enable interrupts */ 215 _enable(); 216 } 217 218 VOID 219 CloseBitPlane(VOID) 220 { 221 /* disable interrupts */ 222 _disable(); 223 224 /* sequence reg */ 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); 229 230 /* graphic reg */ 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); 234 235 /* enable interrupts */ 236 _enable(); 237 } 238 239 VOID 240 LoadFont(PUCHAR Bitplane, PUCHAR FontBitfield) 241 { 242 UINT32 i,j; 243 244 for (i=0; i<256; i++) 245 { 246 for (j=0; j<8; j++) 247 { 248 *Bitplane = FontBitfield[i*8+j]; 249 Bitplane++; 250 } 251 252 // padding 253 for (j=8; j<32; j++) 254 { 255 *Bitplane = 0; 256 Bitplane++; 257 } 258 } 259 } 260