ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

infrosgen.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.