1 /* 2 * PROJECT: .inf file parser 3 * LICENSE: GPL - See COPYING in the top level directory 4 * PROGRAMMER: Royce Mitchell III 5 * Eric Kohl 6 * Ge van Geldorp <gvg@reactos.org> 7 */ 8 9 /* INCLUDES *****************************************************************/ 10 11 #include "inflib.h" 12 #include "infhost.h" 13 14 #define NDEBUG 15 #include <debug.h> 16 17 /* PUBLIC FUNCTIONS *********************************************************/ 18 19 int 20 InfHostOpenBufferedFile(PHINF InfHandle, 21 void *Buffer, 22 ULONG BufferSize, 23 LANGID LanguageId, 24 ULONG *ErrorLine) 25 { 26 INFSTATUS Status; 27 PINFCACHE Cache; 28 WCHAR *FileBuffer; 29 ULONG FileBufferSize; 30 31 *InfHandle = NULL; 32 *ErrorLine = (ULONG)-1; 33 34 /* Allocate file buffer */ 35 FileBufferSize = BufferSize + 2; 36 FileBuffer = MALLOC(FileBufferSize); 37 if (FileBuffer == NULL) 38 { 39 DPRINT1("MALLOC() failed\n"); 40 return(INF_STATUS_INSUFFICIENT_RESOURCES); 41 } 42 43 MEMCPY(FileBuffer, Buffer, BufferSize); 44 45 /* Append string terminator */ 46 FileBuffer[BufferSize] = 0; 47 FileBuffer[BufferSize + 1] = 0; 48 49 /* Allocate infcache header */ 50 Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE)); 51 if (Cache == NULL) 52 { 53 DPRINT1("MALLOC() failed\n"); 54 FREE(FileBuffer); 55 return(INF_STATUS_INSUFFICIENT_RESOURCES); 56 } 57 58 /* Initialize inicache header */ 59 ZEROMEMORY(Cache, 60 sizeof(INFCACHE)); 61 62 Cache->LanguageId = LanguageId; 63 64 /* Parse the inf buffer */ 65 if (!RtlIsTextUnicode(FileBuffer, (INT)FileBufferSize, NULL)) 66 { 67 // static const BYTE utf8_bom[3] = { 0xef, 0xbb, 0xbf }; 68 WCHAR *new_buff; 69 // UINT codepage = CP_ACP; 70 UINT offset = 0; 71 72 // if (BufferSize > sizeof(utf8_bom) && !memcmp(FileBuffer, utf8_bom, sizeof(utf8_bom) )) 73 // { 74 // codepage = CP_UTF8; 75 // offset = sizeof(utf8_bom); 76 // } 77 78 new_buff = MALLOC(FileBufferSize * sizeof(WCHAR)); 79 if (new_buff != NULL) 80 { 81 ULONG len; 82 Status = RtlMultiByteToUnicodeN(new_buff, 83 FileBufferSize * sizeof(WCHAR), 84 &len, 85 (char *)FileBuffer + offset, 86 FileBufferSize - offset); 87 88 Status = InfpParseBuffer(Cache, 89 new_buff, 90 new_buff + len / sizeof(WCHAR), 91 ErrorLine); 92 FREE(new_buff); 93 } 94 else 95 Status = INF_STATUS_INSUFFICIENT_RESOURCES; 96 } 97 else 98 { 99 WCHAR *new_buff = (WCHAR *)FileBuffer; 100 /* UCS-16 files should start with the Unicode BOM; we should skip it */ 101 if (*new_buff == 0xfeff) 102 { 103 new_buff++; 104 FileBufferSize -= sizeof(WCHAR); 105 } 106 Status = InfpParseBuffer(Cache, 107 new_buff, 108 (WCHAR*)((char*)new_buff + FileBufferSize), 109 ErrorLine); 110 } 111 112 if (!INF_SUCCESS(Status)) 113 { 114 FREE(Cache); 115 Cache = NULL; 116 } 117 118 /* Free file buffer */ 119 FREE(FileBuffer); 120 121 *InfHandle = (HINF)Cache; 122 123 return INF_SUCCESS(Status) ? 0 : -1; 124 } 125 126 127 int 128 InfHostOpenFile(PHINF InfHandle, 129 const CHAR *FileName, 130 LANGID LanguageId, 131 ULONG *ErrorLine) 132 { 133 FILE *File; 134 CHAR *FileBuffer; 135 ULONG FileLength; 136 ULONG FileBufferLength; 137 PINFCACHE Cache; 138 INFSTATUS Status = INF_STATUS_SUCCESS; 139 140 *InfHandle = NULL; 141 *ErrorLine = (ULONG)-1; 142 143 /* Open the inf file */ 144 File = fopen(FileName, "rb"); 145 if (NULL == File) 146 { 147 DPRINT1("fopen() failed (errno %d)\n", errno); 148 return -1; 149 } 150 151 DPRINT("fopen() successful\n"); 152 153 /* Query file size */ 154 if (fseek(File, (size_t)0, SEEK_END)) 155 { 156 DPRINT1("fseek() to EOF failed (errno %d)\n", errno); 157 fclose(File); 158 return -1; 159 } 160 161 FileLength = (ULONG)ftell(File); 162 if ((ULONG) -1 == FileLength) 163 { 164 DPRINT1("ftell() failed (errno %d)\n", errno); 165 fclose(File); 166 return -1; 167 } 168 DPRINT("File size: %u\n", (UINT)FileLength); 169 170 /* Rewind */ 171 if (fseek(File, (size_t)0, SEEK_SET)) 172 { 173 DPRINT1("fseek() to BOF failed (errno %d)\n", errno); 174 fclose(File); 175 return -1; 176 } 177 178 /* Allocate file buffer */ 179 FileBufferLength = FileLength + 2; 180 FileBuffer = MALLOC(FileBufferLength); 181 if (FileBuffer == NULL) 182 { 183 DPRINT1("MALLOC() failed\n"); 184 fclose(File); 185 return -1; 186 } 187 188 /* Read file */ 189 if (FileLength != fread(FileBuffer, (size_t)1, (size_t)FileLength, File)) 190 { 191 DPRINT1("fread() failed (errno %d)\n", errno); 192 FREE(FileBuffer); 193 fclose(File); 194 return -1; 195 } 196 197 fclose(File); 198 199 /* Append string terminator */ 200 FileBuffer[FileLength] = 0; 201 FileBuffer[FileLength + 1] = 0; 202 203 /* Allocate infcache header */ 204 Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE)); 205 if (Cache == NULL) 206 { 207 DPRINT1("MALLOC() failed\n"); 208 FREE(FileBuffer); 209 return -1; 210 } 211 212 /* Initialize inicache header */ 213 ZEROMEMORY(Cache, 214 sizeof(INFCACHE)); 215 216 Cache->LanguageId = LanguageId; 217 218 /* Parse the inf buffer */ 219 if (!RtlIsTextUnicode(FileBuffer, (INT)FileBufferLength, NULL)) 220 { 221 // static const BYTE utf8_bom[3] = { 0xef, 0xbb, 0xbf }; 222 WCHAR *new_buff; 223 // UINT codepage = CP_ACP; 224 UINT offset = 0; 225 226 // if (FileLength > sizeof(utf8_bom) && !memcmp(FileBuffer, utf8_bom, sizeof(utf8_bom) )) 227 // { 228 // codepage = CP_UTF8; 229 // offset = sizeof(utf8_bom); 230 // } 231 232 new_buff = MALLOC(FileBufferLength * sizeof(WCHAR)); 233 if (new_buff != NULL) 234 { 235 ULONG len; 236 Status = RtlMultiByteToUnicodeN(new_buff, 237 FileBufferLength * sizeof(WCHAR), 238 &len, 239 (char *)FileBuffer + offset, 240 FileBufferLength - offset); 241 242 Status = InfpParseBuffer(Cache, 243 new_buff, 244 new_buff + len / sizeof(WCHAR), 245 ErrorLine); 246 247 FREE(new_buff); 248 } 249 else 250 Status = INF_STATUS_INSUFFICIENT_RESOURCES; 251 } 252 else 253 { 254 WCHAR *new_buff = (WCHAR *)FileBuffer; 255 /* UCS-16 files should start with the Unicode BOM; we should skip it */ 256 if (*new_buff == 0xfeff) 257 { 258 new_buff++; 259 FileBufferLength -= sizeof(WCHAR); 260 } 261 Status = InfpParseBuffer(Cache, 262 new_buff, 263 (WCHAR*)((char*)new_buff + FileBufferLength), 264 ErrorLine); 265 } 266 267 if (!INF_SUCCESS(Status)) 268 { 269 FREE(Cache); 270 Cache = NULL; 271 } 272 273 /* Free file buffer */ 274 FREE(FileBuffer); 275 276 *InfHandle = (HINF)Cache; 277 278 return INF_SUCCESS(Status) ? 0 : -1; 279 } 280 281 282 void 283 InfHostCloseFile(HINF InfHandle) 284 { 285 PINFCACHE Cache; 286 287 Cache = (PINFCACHE)InfHandle; 288 289 if (Cache == NULL) 290 { 291 return; 292 } 293 294 while (Cache->FirstSection != NULL) 295 { 296 Cache->FirstSection = InfpFreeSection(Cache->FirstSection); 297 } 298 Cache->LastSection = NULL; 299 300 FREE(Cache); 301 } 302 303 /* EOF */ 304