Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeninfrosgen.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: .inf file parser 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * PROGRAMMER: Royce Mitchell III 00005 * Eric Kohl 00006 * Ge van Geldorp <gvg@reactos.org> 00007 */ 00008 00009 /* INCLUDES *****************************************************************/ 00010 00011 #include "inflib.h" 00012 #include "infros.h" 00013 00014 #define NDEBUG 00015 #include <debug.h> 00016 00017 /* PRIVATE FUNCTIONS ********************************************************/ 00018 00019 static int InfpHeapRefCount; 00020 00021 static VOID 00022 CheckHeap() 00023 { 00024 if (NULL == InfpHeap) 00025 { 00026 InfpHeap = RtlCreateHeap(HEAP_GROWABLE, NULL, 0, 0, NULL, NULL); 00027 } 00028 if (0 <= InfpHeapRefCount) 00029 { 00030 InfpHeapRefCount++; 00031 } 00032 } 00033 00034 00035 /* PUBLIC FUNCTIONS *********************************************************/ 00036 00037 PVOID InfpHeap; 00038 00039 VOID 00040 InfSetHeap(PVOID Heap) 00041 { 00042 if (NULL == InfpHeap) 00043 { 00044 InfpHeap = Heap; 00045 InfpHeapRefCount = -1; 00046 } 00047 } 00048 00049 00050 NTSTATUS 00051 InfOpenBufferedFile(PHINF InfHandle, 00052 PVOID Buffer, 00053 ULONG BufferSize, 00054 LANGID LanguageId, 00055 PULONG ErrorLine) 00056 { 00057 INFSTATUS Status; 00058 PINFCACHE Cache; 00059 PCHAR FileBuffer; 00060 ULONG FileBufferSize; 00061 00062 CheckHeap(); 00063 00064 *InfHandle = NULL; 00065 *ErrorLine = (ULONG)-1; 00066 00067 /* Allocate file buffer */ 00068 FileBufferSize = BufferSize + 2; 00069 FileBuffer = MALLOC(FileBufferSize); 00070 if (FileBuffer == NULL) 00071 { 00072 DPRINT1("MALLOC() failed\n"); 00073 return(INF_STATUS_INSUFFICIENT_RESOURCES); 00074 } 00075 00076 MEMCPY(FileBuffer, Buffer, BufferSize); 00077 00078 /* Append string terminator */ 00079 FileBuffer[BufferSize] = 0; 00080 FileBuffer[BufferSize + 1] = 0; 00081 00082 /* Allocate infcache header */ 00083 Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE)); 00084 if (Cache == NULL) 00085 { 00086 DPRINT("MALLOC() failed\n"); 00087 FREE(FileBuffer); 00088 return(INF_STATUS_INSUFFICIENT_RESOURCES); 00089 } 00090 00091 /* Initialize inicache header */ 00092 ZEROMEMORY(Cache, 00093 sizeof(INFCACHE)); 00094 00095 Cache->LanguageId = LanguageId; 00096 00097 /* Parse the inf buffer */ 00098 if (!RtlIsTextUnicode(FileBuffer, FileBufferSize, NULL)) 00099 { 00100 // static const BYTE utf8_bom[3] = { 0xef, 0xbb, 0xbf }; 00101 WCHAR *new_buff; 00102 // UINT codepage = CP_ACP; 00103 UINT offset = 0; 00104 00105 // if (BufferSize > sizeof(utf8_bom) && !memcmp(FileBuffer, utf8_bom, sizeof(utf8_bom) )) 00106 // { 00107 // codepage = CP_UTF8; 00108 // offset = sizeof(utf8_bom); 00109 // } 00110 00111 new_buff = MALLOC(FileBufferSize * sizeof(WCHAR)); 00112 if (new_buff != NULL) 00113 { 00114 ULONG len; 00115 Status = RtlMultiByteToUnicodeN(new_buff, 00116 FileBufferSize * sizeof(WCHAR), 00117 &len, 00118 (char *)FileBuffer + offset, 00119 FileBufferSize - offset); 00120 00121 Status = InfpParseBuffer(Cache, 00122 new_buff, 00123 new_buff + len / sizeof(WCHAR), 00124 ErrorLine); 00125 FREE(new_buff); 00126 } 00127 else 00128 Status = INF_STATUS_INSUFFICIENT_RESOURCES; 00129 } 00130 else 00131 { 00132 WCHAR *new_buff = (WCHAR *)FileBuffer; 00133 /* UCS-16 files should start with the Unicode BOM; we should skip it */ 00134 if (*new_buff == 0xfeff) 00135 { 00136 new_buff++; 00137 FileBufferSize -= sizeof(WCHAR); 00138 } 00139 Status = InfpParseBuffer(Cache, 00140 new_buff, 00141 (WCHAR*)((char*)new_buff + FileBufferSize), 00142 ErrorLine); 00143 } 00144 00145 if (!INF_SUCCESS(Status)) 00146 { 00147 FREE(Cache); 00148 Cache = NULL; 00149 } 00150 00151 /* Free file buffer */ 00152 FREE(FileBuffer); 00153 00154 *InfHandle = (HINF)Cache; 00155 00156 return(Status); 00157 } 00158 00159 00160 NTSTATUS 00161 InfOpenFile(PHINF InfHandle, 00162 PUNICODE_STRING FileName, 00163 LANGID LanguageId, 00164 PULONG ErrorLine) 00165 { 00166 OBJECT_ATTRIBUTES ObjectAttributes; 00167 FILE_STANDARD_INFORMATION FileInfo; 00168 IO_STATUS_BLOCK IoStatusBlock; 00169 HANDLE FileHandle; 00170 NTSTATUS Status; 00171 PCHAR FileBuffer; 00172 ULONG FileLength; 00173 ULONG FileBufferLength; 00174 LARGE_INTEGER FileOffset; 00175 PINFCACHE Cache; 00176 00177 CheckHeap(); 00178 00179 *InfHandle = NULL; 00180 *ErrorLine = (ULONG)-1; 00181 00182 /* Open the inf file */ 00183 InitializeObjectAttributes(&ObjectAttributes, 00184 FileName, 00185 0, 00186 NULL, 00187 NULL); 00188 00189 Status = NtOpenFile(&FileHandle, 00190 GENERIC_READ | SYNCHRONIZE, 00191 &ObjectAttributes, 00192 &IoStatusBlock, 00193 FILE_SHARE_READ, 00194 FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE); 00195 if (!INF_SUCCESS(Status)) 00196 { 00197 DPRINT("NtOpenFile() failed (Status %lx)\n", Status); 00198 return(Status); 00199 } 00200 00201 DPRINT("NtOpenFile() successful\n"); 00202 00203 /* Query file size */ 00204 Status = NtQueryInformationFile(FileHandle, 00205 &IoStatusBlock, 00206 &FileInfo, 00207 sizeof(FILE_STANDARD_INFORMATION), 00208 FileStandardInformation); 00209 if (!INF_SUCCESS(Status)) 00210 { 00211 DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status); 00212 NtClose(FileHandle); 00213 return(Status); 00214 } 00215 00216 FileLength = FileInfo.EndOfFile.u.LowPart; 00217 00218 DPRINT("File size: %lu\n", FileLength); 00219 00220 /* Allocate file buffer */ 00221 FileBufferLength = FileLength + 2; 00222 FileBuffer = MALLOC(FileBufferLength); 00223 if (FileBuffer == NULL) 00224 { 00225 DPRINT1("MALLOC() failed\n"); 00226 NtClose(FileHandle); 00227 return(INF_STATUS_INSUFFICIENT_RESOURCES); 00228 } 00229 00230 /* Read file */ 00231 FileOffset.QuadPart = 0ULL; 00232 Status = NtReadFile(FileHandle, 00233 NULL, 00234 NULL, 00235 NULL, 00236 &IoStatusBlock, 00237 FileBuffer, 00238 FileLength, 00239 &FileOffset, 00240 NULL); 00241 00242 /* Append string terminator */ 00243 FileBuffer[FileLength] = 0; 00244 FileBuffer[FileLength + 1] = 0; 00245 00246 NtClose(FileHandle); 00247 00248 if (!INF_SUCCESS(Status)) 00249 { 00250 DPRINT("NtReadFile() failed (Status %lx)\n", Status); 00251 FREE(FileBuffer); 00252 return(Status); 00253 } 00254 00255 /* Allocate infcache header */ 00256 Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE)); 00257 if (Cache == NULL) 00258 { 00259 DPRINT("MALLOC() failed\n"); 00260 FREE(FileBuffer); 00261 return(INF_STATUS_INSUFFICIENT_RESOURCES); 00262 } 00263 00264 /* Initialize inicache header */ 00265 ZEROMEMORY(Cache, 00266 sizeof(INFCACHE)); 00267 00268 Cache->LanguageId = LanguageId; 00269 00270 /* Parse the inf buffer */ 00271 if (!RtlIsTextUnicode(FileBuffer, FileBufferLength, NULL)) 00272 { 00273 // static const BYTE utf8_bom[3] = { 0xef, 0xbb, 0xbf }; 00274 WCHAR *new_buff; 00275 // UINT codepage = CP_ACP; 00276 UINT offset = 0; 00277 00278 // if (FileLength > sizeof(utf8_bom) && !memcmp(FileBuffer, utf8_bom, sizeof(utf8_bom) )) 00279 // { 00280 // codepage = CP_UTF8; 00281 // offset = sizeof(utf8_bom); 00282 // } 00283 00284 new_buff = MALLOC(FileBufferLength * sizeof(WCHAR)); 00285 if (new_buff != NULL) 00286 { 00287 ULONG len; 00288 Status = RtlMultiByteToUnicodeN(new_buff, 00289 FileBufferLength * sizeof(WCHAR), 00290 &len, 00291 (char *)FileBuffer + offset, 00292 FileBufferLength - offset); 00293 00294 Status = InfpParseBuffer(Cache, 00295 new_buff, 00296 new_buff + len / sizeof(WCHAR), 00297 ErrorLine); 00298 FREE(new_buff); 00299 } 00300 else 00301 Status = INF_STATUS_INSUFFICIENT_RESOURCES; 00302 } 00303 else 00304 { 00305 WCHAR *new_buff = (WCHAR *)FileBuffer; 00306 /* UCS-16 files should start with the Unicode BOM; we should skip it */ 00307 if (*new_buff == 0xfeff) 00308 { 00309 new_buff++; 00310 FileBufferLength -= sizeof(WCHAR); 00311 } 00312 Status = InfpParseBuffer(Cache, 00313 new_buff, 00314 (WCHAR*)((char*)new_buff + FileBufferLength), 00315 ErrorLine); 00316 } 00317 00318 if (!INF_SUCCESS(Status)) 00319 { 00320 FREE(Cache); 00321 Cache = NULL; 00322 } 00323 00324 /* Free file buffer */ 00325 FREE(FileBuffer); 00326 00327 *InfHandle = (HINF)Cache; 00328 00329 return(Status); 00330 } 00331 00332 00333 VOID 00334 InfCloseFile(HINF InfHandle) 00335 { 00336 PINFCACHE Cache; 00337 00338 Cache = (PINFCACHE)InfHandle; 00339 00340 if (Cache == NULL) 00341 { 00342 return; 00343 } 00344 00345 while (Cache->FirstSection != NULL) 00346 { 00347 Cache->FirstSection = InfpFreeSection(Cache->FirstSection); 00348 } 00349 Cache->LastSection = NULL; 00350 00351 FREE(Cache); 00352 00353 if (0 < InfpHeapRefCount) 00354 { 00355 InfpHeapRefCount--; 00356 if (0 == InfpHeapRefCount) 00357 { 00358 RtlDestroyHeap(InfpHeap); 00359 InfpHeap = NULL; 00360 } 00361 } 00362 } 00363 00364 00365 /* EOF */ Generated on Fri May 25 2012 04:34:45 for ReactOS by
1.7.6.1
|