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

infget.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 
00013 #define NDEBUG
00014 #include <debug.h>
00015 
00016 static unsigned int
00017 InfpSubstituteString(PINFCACHE Inf,
00018                      const WCHAR *text,
00019                      WCHAR *buffer,
00020                      unsigned int size);
00021 
00022 /* retrieve the string substitution for a given string, or NULL if not found */
00023 /* if found, len is set to the substitution length */
00024 static PCWSTR
00025 InfpGetSubstitutionString(PINFCACHE Inf,
00026                           PCWSTR str,
00027                           unsigned int *len,
00028                           BOOL no_trailing_slash)
00029 {
00030     static const WCHAR percent = '%';
00031 
00032     INFSTATUS Status = INF_STATUS_NOT_FOUND;
00033     PINFCONTEXT Context = NULL;
00034     PWCHAR Data = NULL;
00035     WCHAR ValueName[MAX_INF_STRING_LENGTH +1];
00036     WCHAR StringLangId[13];
00037 
00038     if (!*len)  /* empty string (%%) is replaced by single percent */
00039     {
00040         *len = 1;
00041         return &percent;
00042     }
00043 
00044     memcpy(ValueName, str, *len * sizeof(WCHAR));
00045     ValueName[*len] = 0;
00046 
00047     DPRINT("Value name: %S\n", ValueName);
00048 
00049     if (Inf->LanguageId != 0)
00050     {
00051         swprintf(StringLangId,
00052                  L"Strings.%04hx",
00053                  Inf->LanguageId);
00054 
00055         Status = InfpFindFirstLine(Inf,
00056                                    StringLangId,
00057                                    ValueName,
00058                                    &Context);
00059         if (Status != INF_STATUS_SUCCESS)
00060         {
00061             swprintf(StringLangId,
00062                      L"Strings.%04hx",
00063                      MAKELANGID(PRIMARYLANGID(Inf->LanguageId), SUBLANG_NEUTRAL));
00064 
00065             Status = InfpFindFirstLine(Inf,
00066                                        StringLangId,
00067                                        ValueName,
00068                                        &Context);
00069             if (Status != INF_STATUS_SUCCESS)
00070             {
00071                 Status = InfpFindFirstLine(Inf,
00072                                            L"Strings",
00073                                            ValueName,
00074                                            &Context);
00075             }
00076         }
00077     }
00078     else
00079     {
00080         Status = InfpFindFirstLine(Inf,
00081                                    L"Strings",
00082                                    ValueName,
00083                                    &Context);
00084     }
00085 
00086     if (Status != INF_STATUS_SUCCESS || Context == NULL)
00087         return NULL;
00088 
00089     Status = InfpGetData(Context,
00090                          NULL,
00091                          &Data);
00092 
00093     InfpFreeContext(Context);
00094 
00095     if (Status == STATUS_SUCCESS)
00096     {
00097         *len = strlenW(Data);
00098         DPRINT("Substitute: %S  Length: %ul\n", Data, *len);
00099         return Data;
00100     }
00101 
00102     return NULL;
00103 }
00104 
00105 
00106 /* do string substitutions on the specified text */
00107 /* the buffer is assumed to be large enough */
00108 /* returns necessary length not including terminating null */
00109 static unsigned int
00110 InfpSubstituteString(PINFCACHE Inf,
00111                      PCWSTR text,
00112                      PWSTR buffer,
00113                      unsigned int size)
00114 {
00115     const WCHAR *start, *subst, *p;
00116     unsigned int len, total = 0;
00117     int inside = 0;
00118 
00119     if (!buffer) size = MAX_INF_STRING_LENGTH + 1;
00120     for (p = start = text; *p; p++)
00121     {
00122         if (*p != '%') continue;
00123         inside = !inside;
00124         if (inside)  /* start of a %xx% string */
00125         {
00126             len = (unsigned int)(p - start);
00127             if (len > size - 1) len = size - 1;
00128             if (buffer) memcpy( buffer + total, start, len * sizeof(WCHAR) );
00129             total += len;
00130             size -= len;
00131             start = p;
00132         }
00133         else /* end of the %xx% string, find substitution */
00134         {
00135             len = (unsigned int)(p - start - 1);
00136             subst = InfpGetSubstitutionString( Inf, start + 1, &len, p[1] == '\\' );
00137             if (!subst)
00138             {
00139                 subst = start;
00140                 len = (unsigned int)(p - start + 1);
00141             }
00142             if (len > size - 1) len = size - 1;
00143             if (buffer) memcpy( buffer + total, subst, len * sizeof(WCHAR) );
00144             total += len;
00145             size -= len;
00146             start = p + 1;
00147         }
00148     }
00149 
00150     if (start != p) /* unfinished string, copy it */
00151     {
00152         len = (unsigned int)(p - start);
00153         if (len > size - 1) len = size - 1;
00154         if (buffer) memcpy( buffer + total, start, len * sizeof(WCHAR) );
00155         total += len;
00156     }
00157     if (buffer && size) buffer[total] = 0;
00158     return total;
00159 }
00160 
00161 
00162 INFSTATUS
00163 InfpFindFirstLine(PINFCACHE Cache,
00164                   PCWSTR Section,
00165                   PCWSTR Key,
00166                   PINFCONTEXT *Context)
00167 {
00168   PINFCACHESECTION CacheSection;
00169   PINFCACHELINE CacheLine;
00170 
00171   if (Cache == NULL || Section == NULL || Context == NULL)
00172     {
00173       DPRINT1("Invalid parameter\n");
00174       return INF_STATUS_INVALID_PARAMETER;
00175     }
00176 
00177   CacheSection = InfpFindSection(Cache, Section);
00178   if (NULL == CacheSection)
00179     {
00180       DPRINT("Section not found\n");
00181       return INF_STATUS_NOT_FOUND;
00182     }
00183 
00184   if (Key != NULL)
00185     {
00186       CacheLine = InfpFindKeyLine(CacheSection, Key);
00187     }
00188   else
00189     {
00190       CacheLine = CacheSection->FirstLine;
00191     }
00192 
00193   if (NULL == CacheLine)
00194     {
00195       DPRINT("Key not found\n");
00196       return INF_STATUS_NOT_FOUND;
00197     }
00198 
00199   *Context = MALLOC(sizeof(INFCONTEXT));
00200   if (NULL == *Context)
00201     {
00202       DPRINT1("MALLOC() failed\n");
00203       return INF_STATUS_NO_MEMORY;
00204     }
00205   (*Context)->Inf = (PVOID)Cache;
00206   (*Context)->Section = (PVOID)CacheSection;
00207   (*Context)->Line = (PVOID)CacheLine;
00208 
00209   return INF_STATUS_SUCCESS;
00210 }
00211 
00212 
00213 INFSTATUS
00214 InfpFindNextLine(PINFCONTEXT ContextIn,
00215                  PINFCONTEXT ContextOut)
00216 {
00217   PINFCACHELINE CacheLine;
00218 
00219   if (ContextIn == NULL || ContextOut == NULL)
00220     return INF_STATUS_INVALID_PARAMETER;
00221 
00222   if (ContextIn->Line == NULL)
00223     return INF_STATUS_INVALID_PARAMETER;
00224 
00225   CacheLine = (PINFCACHELINE)ContextIn->Line;
00226   if (CacheLine->Next == NULL)
00227     return INF_STATUS_NOT_FOUND;
00228 
00229   if (ContextIn != ContextOut)
00230     {
00231       ContextOut->Inf = ContextIn->Inf;
00232       ContextOut->Section = ContextIn->Section;
00233     }
00234   ContextOut->Line = (PVOID)(CacheLine->Next);
00235 
00236   return INF_STATUS_SUCCESS;
00237 }
00238 
00239 
00240 INFSTATUS
00241 InfpFindFirstMatchLine(PINFCONTEXT ContextIn,
00242                        PCWSTR Key,
00243                        PINFCONTEXT ContextOut)
00244 {
00245   PINFCACHELINE CacheLine;
00246 
00247   if (ContextIn == NULL || ContextOut == NULL || Key == NULL || *Key == 0)
00248     return INF_STATUS_INVALID_PARAMETER;
00249 
00250   if (ContextIn->Inf == NULL || ContextIn->Section == NULL)
00251     return INF_STATUS_INVALID_PARAMETER;
00252 
00253   CacheLine = ((PINFCACHESECTION)(ContextIn->Section))->FirstLine;
00254   while (CacheLine != NULL)
00255     {
00256       if (CacheLine->Key != NULL && strcmpiW (CacheLine->Key, Key) == 0)
00257         {
00258 
00259           if (ContextIn != ContextOut)
00260             {
00261               ContextOut->Inf = ContextIn->Inf;
00262               ContextOut->Section = ContextIn->Section;
00263             }
00264           ContextOut->Line = (PVOID)CacheLine;
00265 
00266           return INF_STATUS_SUCCESS;
00267         }
00268 
00269       CacheLine = CacheLine->Next;
00270     }
00271 
00272   return INF_STATUS_NOT_FOUND;
00273 }
00274 
00275 
00276 INFSTATUS
00277 InfpFindNextMatchLine(PINFCONTEXT ContextIn,
00278                       PCWSTR Key,
00279                       PINFCONTEXT ContextOut)
00280 {
00281   PINFCACHELINE CacheLine;
00282 
00283   if (ContextIn == NULL || ContextOut == NULL || Key == NULL || *Key == 0)
00284     return INF_STATUS_INVALID_PARAMETER;
00285 
00286   if (ContextIn->Inf == NULL || ContextIn->Section == NULL || ContextIn->Line == NULL)
00287     return INF_STATUS_INVALID_PARAMETER;
00288 
00289   CacheLine = (PINFCACHELINE)ContextIn->Line;
00290   while (CacheLine != NULL)
00291     {
00292       if (CacheLine->Key != NULL && strcmpiW (CacheLine->Key, Key) == 0)
00293         {
00294 
00295           if (ContextIn != ContextOut)
00296             {
00297               ContextOut->Inf = ContextIn->Inf;
00298               ContextOut->Section = ContextIn->Section;
00299             }
00300           ContextOut->Line = (PVOID)CacheLine;
00301 
00302           return INF_STATUS_SUCCESS;
00303         }
00304 
00305       CacheLine = CacheLine->Next;
00306     }
00307 
00308   return INF_STATUS_NOT_FOUND;
00309 }
00310 
00311 
00312 LONG
00313 InfpGetLineCount(HINF InfHandle,
00314                  PCWSTR Section)
00315 {
00316   PINFCACHE Cache;
00317   PINFCACHESECTION CacheSection;
00318 
00319   if (InfHandle == NULL || Section == NULL)
00320     {
00321       DPRINT("Invalid parameter\n");
00322       return -1;
00323     }
00324 
00325   Cache = (PINFCACHE)InfHandle;
00326 
00327   /* Iterate through list of sections */
00328   CacheSection = Cache->FirstSection;
00329   while (CacheSection != NULL)
00330     {
00331       /* Are the section names the same? */
00332       if (strcmpiW(CacheSection->Name, Section) == 0)
00333         {
00334           return CacheSection->LineCount;
00335         }
00336 
00337       /* Get the next section */
00338       CacheSection = CacheSection->Next;
00339     }
00340 
00341   DPRINT("Section not found\n");
00342 
00343   return -1;
00344 }
00345 
00346 
00347 /* InfpGetLineText */
00348 
00349 
00350 LONG
00351 InfpGetFieldCount(PINFCONTEXT Context)
00352 {
00353   if (Context == NULL || Context->Line == NULL)
00354     return 0;
00355 
00356   return ((PINFCACHELINE)Context->Line)->FieldCount;
00357 }
00358 
00359 
00360 INFSTATUS
00361 InfpGetBinaryField(PINFCONTEXT Context,
00362                    ULONG FieldIndex,
00363                    PUCHAR ReturnBuffer,
00364                    ULONG ReturnBufferSize,
00365                    PULONG RequiredSize)
00366 {
00367   PINFCACHELINE CacheLine;
00368   PINFCACHEFIELD CacheField;
00369   ULONG Index;
00370   ULONG Size;
00371   PUCHAR Ptr;
00372 
00373   if (Context == NULL || Context->Line == NULL || FieldIndex == 0)
00374     {
00375       DPRINT("Invalid parameter\n");
00376       return INF_STATUS_INVALID_PARAMETER;
00377     }
00378 
00379   if (RequiredSize != NULL)
00380     *RequiredSize = 0;
00381 
00382   CacheLine = (PINFCACHELINE)Context->Line;
00383 
00384   if (FieldIndex > (ULONG)CacheLine->FieldCount)
00385     return INF_STATUS_NOT_FOUND;
00386 
00387   CacheField = CacheLine->FirstField;
00388   for (Index = 1; Index < FieldIndex; Index++)
00389     CacheField = CacheField->Next;
00390 
00391   Size = (ULONG)CacheLine->FieldCount - FieldIndex + 1;
00392 
00393   if (RequiredSize != NULL)
00394     *RequiredSize = Size;
00395 
00396   if (ReturnBuffer != NULL)
00397     {
00398       if (ReturnBufferSize < Size)
00399         return INF_STATUS_BUFFER_OVERFLOW;
00400 
00401       /* Copy binary data */
00402       Ptr = ReturnBuffer;
00403       while (CacheField != NULL)
00404         {
00405           *Ptr = (UCHAR)strtoulW(CacheField->Data, NULL, 16);
00406 
00407           Ptr++;
00408           CacheField = CacheField->Next;
00409         }
00410     }
00411 
00412   return INF_STATUS_SUCCESS;
00413 }
00414 
00415 
00416 INFSTATUS
00417 InfpGetIntField(PINFCONTEXT Context,
00418                 ULONG FieldIndex,
00419                 INT *IntegerValue)
00420 {
00421   PINFCACHELINE CacheLine;
00422   PINFCACHEFIELD CacheField;
00423   ULONG Index;
00424   PWCHAR Ptr;
00425 
00426   if (Context == NULL || Context->Line == NULL || IntegerValue == NULL)
00427     {
00428       DPRINT("Invalid parameter\n");
00429       return INF_STATUS_INVALID_PARAMETER;
00430     }
00431 
00432   CacheLine = (PINFCACHELINE)Context->Line;
00433 
00434   if (FieldIndex > (ULONG)CacheLine->FieldCount)
00435     {
00436       DPRINT("Invalid parameter\n");
00437       return INF_STATUS_INVALID_PARAMETER;
00438     }
00439 
00440   if (FieldIndex == 0)
00441     {
00442       Ptr = CacheLine->Key;
00443     }
00444   else
00445     {
00446       CacheField = CacheLine->FirstField;
00447       for (Index = 1; Index < FieldIndex; Index++)
00448         CacheField = CacheField->Next;
00449 
00450       Ptr = CacheField->Data;
00451     }
00452 
00453   *IntegerValue = (LONG)strtolW(Ptr, NULL, 0);
00454 
00455   return INF_STATUS_SUCCESS;
00456 }
00457 
00458 
00459 INFSTATUS
00460 InfpGetMultiSzField(PINFCONTEXT Context,
00461                     ULONG FieldIndex,
00462                     PWSTR ReturnBuffer,
00463                     ULONG ReturnBufferSize,
00464                     PULONG RequiredSize)
00465 {
00466   PINFCACHELINE CacheLine;
00467   PINFCACHEFIELD CacheField;
00468   PINFCACHEFIELD FieldPtr;
00469   ULONG Index;
00470   ULONG Size;
00471   PWCHAR Ptr;
00472 
00473   if (Context == NULL || Context->Line == NULL || FieldIndex == 0)
00474     {
00475       DPRINT("Invalid parameter\n");
00476       return INF_STATUS_INVALID_PARAMETER;
00477     }
00478 
00479   if (RequiredSize != NULL)
00480     *RequiredSize = 0;
00481 
00482   CacheLine = (PINFCACHELINE)Context->Line;
00483 
00484   if (FieldIndex > (ULONG)CacheLine->FieldCount)
00485     return INF_STATUS_INVALID_PARAMETER;
00486 
00487   CacheField = CacheLine->FirstField;
00488   for (Index = 1; Index < FieldIndex; Index++)
00489     CacheField = CacheField->Next;
00490 
00491   /* Calculate the required buffer size */
00492   FieldPtr = CacheField;
00493   Size = 0;
00494   while (FieldPtr != NULL)
00495     {
00496       Size += ((ULONG)strlenW(FieldPtr->Data) + 1);
00497       FieldPtr = FieldPtr->Next;
00498     }
00499   Size++;
00500 
00501   if (RequiredSize != NULL)
00502     *RequiredSize = Size;
00503 
00504   if (ReturnBuffer != NULL)
00505     {
00506       if (ReturnBufferSize < Size)
00507         return INF_STATUS_BUFFER_OVERFLOW;
00508 
00509       /* Copy multi-sz string */
00510       Ptr = ReturnBuffer;
00511       FieldPtr = CacheField;
00512       while (FieldPtr != NULL)
00513         {
00514           Size = (ULONG)strlenW(FieldPtr->Data) + 1;
00515 
00516           strcpyW(Ptr, FieldPtr->Data);
00517 
00518           Ptr = Ptr + Size;
00519           FieldPtr = FieldPtr->Next;
00520         }
00521       *Ptr = 0;
00522     }
00523 
00524   return INF_STATUS_SUCCESS;
00525 }
00526 
00527 
00528 INFSTATUS
00529 InfpGetStringField(PINFCONTEXT Context,
00530                    ULONG FieldIndex,
00531                    PWSTR ReturnBuffer,
00532                    ULONG ReturnBufferSize,
00533                    PULONG RequiredSize)
00534 {
00535   PINFCACHELINE CacheLine;
00536   PINFCACHEFIELD CacheField;
00537   ULONG Index;
00538   PWCHAR Ptr;
00539   ULONG Size;
00540 
00541   if (Context == NULL || Context->Line == NULL || FieldIndex == 0)
00542     {
00543       DPRINT("Invalid parameter\n");
00544       return INF_STATUS_INVALID_PARAMETER;
00545     }
00546 
00547   if (RequiredSize != NULL)
00548     *RequiredSize = 0;
00549 
00550   CacheLine = (PINFCACHELINE)Context->Line;
00551 
00552   if (FieldIndex > (ULONG)CacheLine->FieldCount)
00553     return INF_STATUS_INVALID_PARAMETER;
00554 
00555   if (FieldIndex == 0)
00556     {
00557       Ptr = CacheLine->Key;
00558     }
00559   else
00560     {
00561       CacheField = CacheLine->FirstField;
00562       for (Index = 1; Index < FieldIndex; Index++)
00563         CacheField = CacheField->Next;
00564 
00565       Ptr = CacheField->Data;
00566     }
00567 
00568 //  Size = (ULONG)strlenW(Ptr) + 1;
00569   Size = InfpSubstituteString(Context->Inf,
00570                               Ptr,
00571                               NULL,
00572                               0);
00573 
00574   if (RequiredSize != NULL)
00575     *RequiredSize = Size + 1;
00576 
00577   if (ReturnBuffer != NULL)
00578     {
00579       if (ReturnBufferSize <= Size)
00580         return INF_STATUS_BUFFER_OVERFLOW;
00581 
00582 //      strcpyW(ReturnBuffer, Ptr);
00583       InfpSubstituteString(Context->Inf,
00584                            Ptr,
00585                            ReturnBuffer,
00586                            ReturnBufferSize);
00587     }
00588 
00589   return INF_STATUS_SUCCESS;
00590 }
00591 
00592 
00593 INFSTATUS
00594 InfpGetData(PINFCONTEXT Context,
00595             PWCHAR *Key,
00596             PWCHAR *Data)
00597 {
00598   PINFCACHELINE CacheKey;
00599 
00600   if (Context == NULL || Context->Line == NULL || Data == NULL)
00601     {
00602       DPRINT("Invalid parameter\n");
00603       return INF_STATUS_INVALID_PARAMETER;
00604     }
00605 
00606   CacheKey = (PINFCACHELINE)Context->Line;
00607   if (Key != NULL)
00608     *Key = CacheKey->Key;
00609 
00610   if (Data != NULL)
00611     {
00612       if (CacheKey->FirstField == NULL)
00613         {
00614           *Data = NULL;
00615         }
00616       else
00617         {
00618           *Data = CacheKey->FirstField->Data;
00619         }
00620     }
00621 
00622   return INF_STATUS_SUCCESS;
00623 }
00624 
00625 
00626 INFSTATUS
00627 InfpGetDataField(PINFCONTEXT Context,
00628                  ULONG FieldIndex,
00629                  PWCHAR *Data)
00630 {
00631   PINFCACHELINE CacheLine;
00632   PINFCACHEFIELD CacheField;
00633   ULONG Index;
00634 
00635   if (Context == NULL || Context->Line == NULL || Data == NULL)
00636     {
00637       DPRINT("Invalid parameter\n");
00638       return INF_STATUS_INVALID_PARAMETER;
00639     }
00640 
00641   CacheLine = (PINFCACHELINE)Context->Line;
00642 
00643   if (FieldIndex > (ULONG)CacheLine->FieldCount)
00644     return INF_STATUS_INVALID_PARAMETER;
00645 
00646   if (FieldIndex == 0)
00647     {
00648       *Data = CacheLine->Key;
00649     }
00650   else
00651     {
00652       CacheField = CacheLine->FirstField;
00653       for (Index = 1; Index < FieldIndex; Index++)
00654         CacheField = CacheField->Next;
00655 
00656       *Data = CacheField->Data;
00657     }
00658 
00659   return INF_STATUS_SUCCESS;
00660 }
00661 
00662 VOID
00663 InfpFreeContext(PINFCONTEXT Context)
00664 {
00665   FREE(Context);
00666 }
00667 
00668 /* EOF */

Generated on Sun May 27 2012 04:36:14 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.