EDK2 doxygen online documents - Firmware Encoding Index 1
EDK2 doxygen online documents - Firmware Encoding Index

IntelFrameworkModulePkg/Universal/FirmwareVolume/UpdateDriverDxe/ParseUpdateProfile.c

Go to the documentation of this file.
00001 
00019 #include "UpdateDriver.h"
00020 
00034 EFI_STATUS
00035 ProfileGetLine (
00036   IN      UINT8                         *Buffer,
00037   IN      UINTN                         BufferSize,
00038   IN OUT  UINT8                         *LineBuffer,
00039   IN OUT  UINTN                         *LineSize
00040   )
00041 {
00042   UINTN                                 Length;
00043   UINT8                                 *PtrBuf;
00044   UINTN                                 PtrEnd;
00045 
00046   PtrBuf      = Buffer;
00047   PtrEnd      = (UINTN)Buffer + BufferSize;
00048 
00049   //
00050   // 0x0D indicates a line break. Otherwise there is no line break
00051   //
00052   while ((UINTN)PtrBuf < PtrEnd) {
00053     if (*PtrBuf == 0x0D) {
00054       break;
00055     }
00056     PtrBuf++;
00057   }
00058 
00059   if ((UINTN)PtrBuf >= (PtrEnd - 1)) {
00060     //
00061     // The buffer ends without any line break
00062     // or it is the last character of the buffer
00063     //
00064     Length    = BufferSize;
00065   } else if (*(PtrBuf + 1) == 0x0A) {
00066     //
00067     // Further check if a 0x0A follows. If yes, count 0xA
00068     //
00069     Length    = (UINTN) PtrBuf - (UINTN) Buffer + 2;
00070   } else {
00071     Length    = (UINTN) PtrBuf - (UINTN) Buffer + 1;
00072   }
00073 
00074   if (Length > (*LineSize)) {
00075     *LineSize = Length;
00076     return EFI_BUFFER_TOO_SMALL;
00077   }
00078 
00079   SetMem (LineBuffer, *LineSize, 0x0);
00080   *LineSize   = Length;
00081   CopyMem (LineBuffer, Buffer, Length);
00082 
00083   return EFI_SUCCESS;
00084 }
00085 
00095 VOID
00096 ProfileTrim (
00097   IN OUT  UINT8                         *Buffer,
00098   IN OUT  UINTN                         *BufferSize
00099   )
00100 {
00101   UINTN                                 Length;
00102   UINT8                                 *PtrBuf;
00103   UINT8                                 *PtrEnd;
00104 
00105   if (*BufferSize == 0) {
00106     return;
00107   }
00108 
00109   //
00110   // Trim the tail first, include CR, LF, TAB, and SPACE.
00111   //
00112   Length          = *BufferSize;
00113   PtrBuf          = (UINT8 *) ((UINTN) Buffer + Length - 1);
00114   while (PtrBuf >= Buffer) {
00115     if ((*PtrBuf != 0x0D) && (*PtrBuf != 0x0A )
00116       && (*PtrBuf != 0x20) && (*PtrBuf != 0x09)) {
00117       break;
00118     }
00119     PtrBuf --;
00120   }
00121 
00122   //
00123   // all spaces, a blank line, return directly;
00124   //
00125   if (PtrBuf < Buffer) {
00126     *BufferSize   = 0;
00127     return;
00128   }
00129 
00130   Length          = (UINTN)PtrBuf - (UINTN)Buffer + 1;
00131   PtrEnd          = PtrBuf;
00132   PtrBuf          = Buffer;
00133 
00134   //
00135   // Now skip the heading CR, LF, TAB and SPACE
00136   //
00137   while (PtrBuf <= PtrEnd) {
00138     if ((*PtrBuf != 0x0D) && (*PtrBuf != 0x0A )
00139       && (*PtrBuf != 0x20) && (*PtrBuf != 0x09)) {
00140       break;
00141     }
00142     PtrBuf++;
00143   }
00144 
00145   //
00146   // If no heading CR, LF, TAB or SPACE, directly return
00147   //
00148   if (PtrBuf == Buffer) {
00149     *BufferSize   = Length;
00150     return;
00151   }
00152 
00153   *BufferSize     = (UINTN)PtrEnd - (UINTN)PtrBuf + 1;
00154 
00155   //
00156   // The first Buffer..PtrBuf characters are CR, LF, TAB or SPACE.
00157   // Now move out all these characters.
00158   //
00159   while (PtrBuf <= PtrEnd) {
00160     *Buffer       = *PtrBuf;
00161     Buffer++;
00162     PtrBuf++;
00163   }
00164 
00165   return;
00166 }
00167 
00179 EFI_STATUS
00180 ProfileGetComments (
00181   IN      UINT8                         *Buffer,
00182   IN      UINTN                         BufferSize,
00183   IN OUT  COMMENT_LINE                  **CommentHead
00184   )
00185 {
00186   COMMENT_LINE                          *CommentItem;
00187 
00188   CommentItem = NULL;
00189   CommentItem = AllocatePool (sizeof (COMMENT_LINE));
00190   if (CommentItem == NULL) {
00191     return EFI_OUT_OF_RESOURCES;
00192   }
00193 
00194   CommentItem->ptrNext  = *CommentHead;
00195   *CommentHead          = CommentItem;
00196 
00197   //
00198   // Add a trailing '\0'
00199   //
00200   CommentItem->ptrComment = AllocatePool (BufferSize + 1);
00201   if (CommentItem->ptrComment == NULL) {
00202     FreePool (CommentItem);
00203     return EFI_OUT_OF_RESOURCES;
00204   }
00205   CopyMem (CommentItem->ptrComment, Buffer, BufferSize);
00206   *(CommentItem->ptrComment + BufferSize) = '\0';
00207 
00208   return EFI_SUCCESS;
00209 }
00210 
00222 EFI_STATUS
00223 ProfileGetSection (
00224   IN      UINT8                         *Buffer,
00225   IN      UINTN                         BufferSize,
00226   IN OUT  SECTION_ITEM                  **SectionHead
00227   )
00228 {
00229   EFI_STATUS                            Status;
00230   SECTION_ITEM                          *SectionItem;
00231   UINTN                                 Length;
00232   UINT8                                 *PtrBuf;
00233 
00234   Status      = EFI_SUCCESS;
00235   //
00236   // The first character of Buffer is '[', now we want for ']'
00237   //
00238   PtrBuf      = (UINT8 *)((UINTN)Buffer + BufferSize - 1);
00239   while (PtrBuf > Buffer) {
00240     if (*PtrBuf == ']') {
00241       break;
00242     }
00243     PtrBuf --;
00244   }
00245   if (PtrBuf <= Buffer) {
00246     //
00247     // Not found. Omit this line
00248     //
00249     return Status;
00250   }
00251 
00252   //
00253   // excluding the heading '[' and tailing ']'
00254   //
00255   Length      = PtrBuf - Buffer - 1;
00256   ProfileTrim (
00257     Buffer + 1,
00258     &Length
00259   );
00260 
00261   //
00262   // omit this line if the section name is null
00263   //
00264   if (Length == 0) {
00265     return Status;
00266   }
00267 
00268   SectionItem = AllocatePool (sizeof (SECTION_ITEM));
00269   if (SectionItem == NULL) {
00270     return EFI_OUT_OF_RESOURCES;
00271   }
00272 
00273   SectionItem->ptrSection = NULL;
00274   SectionItem->SecNameLen = Length;
00275   SectionItem->ptrEntry   = NULL;
00276   SectionItem->ptrValue   = NULL;
00277   SectionItem->ptrNext    = *SectionHead;
00278   *SectionHead            = SectionItem;
00279 
00280   //
00281   // Add a trailing '\0'
00282   //
00283   SectionItem->ptrSection = AllocatePool (Length + 1);
00284   if (SectionItem->ptrSection == NULL) {
00285     return EFI_OUT_OF_RESOURCES;
00286   }
00287 
00288   //
00289   // excluding the heading '['
00290   //
00291   CopyMem (SectionItem->ptrSection, Buffer + 1, Length);
00292   *(SectionItem->ptrSection + Length) = '\0';
00293 
00294   return EFI_SUCCESS;
00295 }
00296 
00308 EFI_STATUS
00309 ProfileGetEntry (
00310   IN      UINT8                         *Buffer,
00311   IN      UINTN                         BufferSize,
00312   IN OUT  SECTION_ITEM                  **SectionHead
00313   )
00314 {
00315   EFI_STATUS                            Status;
00316   SECTION_ITEM                          *SectionItem;
00317   SECTION_ITEM                          *PtrSection;
00318   UINTN                                 Length;
00319   UINT8                                 *PtrBuf;
00320   UINT8                                 *PtrEnd;
00321 
00322   Status      = EFI_SUCCESS;
00323   PtrBuf      = Buffer;
00324   PtrEnd      = (UINT8 *) ((UINTN)Buffer + BufferSize - 1);
00325 
00326   //
00327   // First search for '='
00328   //
00329   while (PtrBuf <= PtrEnd) {
00330     if (*PtrBuf == '=') {
00331       break;
00332     }
00333     PtrBuf++;
00334   }
00335   if (PtrBuf > PtrEnd) {
00336     //
00337     // Not found. Omit this line
00338     //
00339     return Status;
00340   }
00341 
00342   //
00343   // excluding the tailing '='
00344   //
00345   Length      = PtrBuf - Buffer;
00346   ProfileTrim (
00347     Buffer,
00348     &Length
00349   );
00350 
00351   //
00352   // Omit this line if the entry name is null
00353   //
00354   if (Length == 0) {
00355     return Status;
00356   }
00357 
00358   //
00359   // Omit this line if no section header has been found before
00360   //
00361   if (*SectionHead == NULL) {
00362     return Status;
00363   }
00364   PtrSection  = *SectionHead;
00365 
00366   SectionItem = AllocatePool (sizeof (SECTION_ITEM));
00367   if (SectionItem == NULL) {
00368     return EFI_OUT_OF_RESOURCES;
00369   }
00370 
00371   SectionItem->ptrSection = NULL;
00372   SectionItem->ptrEntry   = NULL;
00373   SectionItem->ptrValue   = NULL;
00374   SectionItem->SecNameLen = PtrSection->SecNameLen;
00375   SectionItem->ptrNext    = *SectionHead;
00376   *SectionHead            = SectionItem;
00377 
00378   //
00379   // SectionName, add a trailing '\0'
00380   //
00381   SectionItem->ptrSection = AllocatePool (PtrSection->SecNameLen + 1);
00382   if (SectionItem->ptrSection == NULL) {
00383     return EFI_OUT_OF_RESOURCES;
00384   }
00385   CopyMem (SectionItem->ptrSection, PtrSection->ptrSection, PtrSection->SecNameLen + 1);
00386 
00387   //
00388   // EntryName, add a trailing '\0'
00389   //
00390   SectionItem->ptrEntry = AllocatePool (Length + 1);
00391   if (SectionItem->ptrEntry == NULL) {
00392     return EFI_OUT_OF_RESOURCES;
00393   }
00394   CopyMem (SectionItem->ptrEntry, Buffer, Length);
00395   *(SectionItem->ptrEntry + Length) = '\0';
00396 
00397   //
00398   // Next search for '#'
00399   //
00400   PtrBuf      = PtrBuf + 1;
00401   Buffer      = PtrBuf;
00402   while (PtrBuf <= PtrEnd) {
00403     if (*PtrBuf == '#') {
00404       break;
00405     }
00406     PtrBuf++;
00407   }
00408   Length      = PtrBuf - Buffer;
00409   ProfileTrim (
00410     Buffer,
00411     &Length
00412   );
00413 
00414   if (Length > 0) {
00415     //
00416     // EntryValue, add a trailing '\0'
00417     //
00418     SectionItem->ptrValue = AllocatePool (Length + 1);
00419     if (SectionItem->ptrValue == NULL) {
00420       return EFI_OUT_OF_RESOURCES;
00421     }
00422     CopyMem (SectionItem->ptrValue, Buffer, Length);
00423     *(SectionItem->ptrValue + Length) = '\0';
00424   }
00425 
00426   return EFI_SUCCESS;
00427 }
00428 
00436 VOID
00437 FreeAllList (
00438   IN      SECTION_ITEM                  *Section,
00439   IN      COMMENT_LINE                  *Comment
00440   )
00441 {
00442   SECTION_ITEM                          *PtrSection;
00443   COMMENT_LINE                          *PtrComment;
00444 
00445   while (Section != NULL) {
00446     PtrSection    = Section;
00447     Section       = Section->ptrNext;
00448     if (PtrSection->ptrEntry != NULL) {
00449       FreePool (PtrSection->ptrEntry);
00450     }
00451     if (PtrSection->ptrSection != NULL) {
00452       FreePool (PtrSection->ptrSection);
00453     }
00454     if (PtrSection->ptrValue != NULL) {
00455       FreePool (PtrSection->ptrValue);
00456     }
00457     FreePool (PtrSection);
00458   }
00459 
00460   while (Comment != NULL) {
00461     PtrComment    = Comment;
00462     Comment       = Comment->ptrNext;
00463     if (PtrComment->ptrComment != NULL) {
00464       FreePool (PtrComment->ptrComment);
00465     }
00466     FreePool (PtrComment);
00467   }
00468 
00469   return;
00470 }
00471 
00484 EFI_STATUS
00485 UpdateGetProfileString (
00486   IN      SECTION_ITEM                  *Section,
00487   IN      UINT8                         *SectionName,
00488   IN      UINT8                         *EntryName,
00489   OUT     UINT8                         **EntryValue
00490   )
00491 {
00492   *EntryValue   = NULL;
00493 
00494   while (Section != NULL) {
00495     if (AsciiStrCmp ((CONST CHAR8 *) Section->ptrSection, (CONST CHAR8 *) SectionName) == 0) {
00496       if (Section->ptrEntry != NULL) {
00497         if (AsciiStrCmp ((CONST CHAR8 *) Section->ptrEntry, (CONST CHAR8 *) EntryName) == 0) {
00498           break;
00499         }
00500       }
00501     }
00502     Section     = Section->ptrNext;
00503   }
00504 
00505   if (Section == NULL) {
00506     return EFI_NOT_FOUND;
00507   }
00508 
00509   *EntryValue   = (UINT8 *) Section->ptrValue;
00510 
00511   return EFI_SUCCESS;
00512 }
00513 
00522 UINTN
00523 UpdateAtoi (
00524   IN      UINT8                         *Str
00525   )
00526 {
00527   UINTN Number;
00528 
00529   Number = 0;
00530 
00531   //
00532   // Skip preceeding while spaces
00533   //
00534   while (*Str != '\0') {
00535     if (*Str != 0x20) {
00536       break;
00537     }
00538     Str++;
00539   }
00540 
00541   if (*Str == '\0') {
00542     return Number;
00543   }
00544 
00545   //
00546   // Find whether the string is prefixed by 0x.
00547   // That is, it should be xtoi or atoi.
00548   //
00549   if (*Str == '0') {
00550     if ((*(Str+1) == 'x' ) || ( *(Str+1) == 'X')) {
00551       return AsciiStrHexToUintn ((CONST CHAR8 *) Str);
00552     }
00553   }
00554 
00555   while (*Str != '\0') {
00556     if ((*Str >= '0') && (*Str <= '9')) {
00557       Number  = Number * 10 + *Str - '0';
00558     } else {
00559       break;
00560     }
00561     Str++;
00562   }
00563 
00564   return Number;
00565 }
00566 
00577 UINTN
00578 UpdateValueToString (
00579   IN  OUT UINT8                         *Buffer,
00580   IN      INT64                         Value
00581   )
00582 {
00583   UINT8                                 TempBuffer[30];
00584   UINT8                                 *TempStr;
00585   UINT8                                 *BufferPtr;
00586   UINTN                                 Count;
00587   UINT32                                Remainder;
00588 
00589   TempStr           = TempBuffer;
00590   BufferPtr         = Buffer;
00591   Count             = 0;
00592 
00593   if (Value < 0) {
00594     *BufferPtr      = '-';
00595     BufferPtr++;
00596     Value           = -Value;
00597     Count++;
00598   }
00599 
00600   do {
00601     Value = (INT64) DivU64x32Remainder  ((UINT64)Value, 10, &Remainder);
00602     //
00603     // The first item of TempStr is not occupied. It's kind of flag
00604     //
00605     TempStr++;
00606     Count++;
00607     *TempStr        = (UINT8) ((UINT8)Remainder + '0');
00608   } while (Value != 0);
00609 
00610   //
00611   // Reverse temp string into Buffer.
00612   //
00613   while (TempStr != TempBuffer) {
00614     *BufferPtr      = *TempStr;
00615     BufferPtr++;
00616     TempStr --;
00617   }
00618 
00619   *BufferPtr = 0;
00620 
00621   return Count;
00622 }
00623 
00632 VOID
00633 UpdateStrCatNumber (
00634   IN OUT  UINT8                         *Str,
00635   IN      UINTN                         Number
00636   )
00637 {
00638   UINTN                                 Count;
00639 
00640   while (*Str != '\0') {
00641     Str++;
00642   }
00643 
00644   Count = UpdateValueToString (Str, (INT64)Number);
00645 
00646   *(Str + Count) = '\0';
00647 
00648   return;
00649 }
00650 
00662 EFI_STATUS
00663 UpdateStringToGuid (
00664   IN      UINT8                         *Str,
00665   IN OUT  EFI_GUID                      *Guid
00666   )
00667 {
00668   UINT8                                 *PtrBuffer;
00669   UINT8                                 *PtrPosition;
00670   UINT8                                 *Buffer;
00671   UINTN                                 Data;
00672   UINTN                                 StrLen;
00673   UINTN                                 Index;
00674   UINT8                                 Digits[3];
00675 
00676   StrLen          = AsciiStrLen  ((CONST CHAR8 *) Str);
00677   Buffer          = AllocatePool (StrLen + 1);
00678   if (Buffer == NULL) {
00679     return EFI_OUT_OF_RESOURCES;
00680   }
00681   AsciiStrCpy ((CHAR8 *)Buffer, (CHAR8 *)Str);
00682 
00683   //
00684   // Data1
00685   //
00686   PtrBuffer       = Buffer;
00687   PtrPosition     = PtrBuffer;
00688   while (*PtrBuffer != '\0') {
00689     if (*PtrBuffer == '-') {
00690       break;
00691     }
00692     PtrBuffer++;
00693   }
00694   if (*PtrBuffer == '\0') {
00695     FreePool (Buffer);
00696     return EFI_NOT_FOUND;
00697   }
00698 
00699   *PtrBuffer      = '\0';
00700   Data            = AsciiStrHexToUintn ((CONST CHAR8 *) PtrPosition);
00701   Guid->Data1     = (UINT32)Data;
00702 
00703   //
00704   // Data2
00705   //
00706   PtrBuffer++;
00707   PtrPosition     = PtrBuffer;
00708   while (*PtrBuffer != '\0') {
00709     if (*PtrBuffer == '-') {
00710       break;
00711     }
00712     PtrBuffer++;
00713   }
00714   if (*PtrBuffer == '\0') {
00715     FreePool (Buffer);
00716     return EFI_NOT_FOUND;
00717   }
00718   *PtrBuffer      = '\0';
00719   Data            = AsciiStrHexToUintn ((CONST CHAR8 *) PtrPosition);
00720   Guid->Data2     = (UINT16)Data;
00721 
00722   //
00723   // Data3
00724   //
00725   PtrBuffer++;
00726   PtrPosition     = PtrBuffer;
00727   while (*PtrBuffer != '\0') {
00728     if (*PtrBuffer == '-') {
00729       break;
00730     }
00731     PtrBuffer++;
00732   }
00733   if (*PtrBuffer == '\0') {
00734     FreePool (Buffer);
00735     return EFI_NOT_FOUND;
00736   }
00737   *PtrBuffer      = '\0';
00738   Data            = AsciiStrHexToUintn ((CONST CHAR8 *) PtrPosition);
00739   Guid->Data3     = (UINT16)Data;
00740 
00741   //
00742   // Data4[0..1]
00743   //
00744   for ( Index = 0 ; Index < 2 ; Index++) {
00745     PtrBuffer++;
00746     if ((*PtrBuffer == '\0') || ( *(PtrBuffer + 1) == '\0')) {
00747       FreePool (Buffer);
00748       return EFI_NOT_FOUND;
00749     }
00750     Digits[0]     = *PtrBuffer;
00751     PtrBuffer++;
00752     Digits[1]     = *PtrBuffer;
00753     Digits[2]     = '\0';
00754     Data          = AsciiStrHexToUintn ((CONST CHAR8 *) Digits);
00755     Guid->Data4[Index] = (UINT8)Data;
00756   }
00757 
00758   //
00759   // skip the '-'
00760   //
00761   PtrBuffer++;
00762   if ((*PtrBuffer != '-' ) || ( *PtrBuffer == '\0')) {
00763     return EFI_NOT_FOUND;
00764   }
00765 
00766   //
00767   // Data4[2..7]
00768   //
00769   for ( ; Index < 8; Index++) {
00770     PtrBuffer++;
00771     if ((*PtrBuffer == '\0') || ( *(PtrBuffer + 1) == '\0')) {
00772       FreePool (Buffer);
00773       return EFI_NOT_FOUND;
00774     }
00775     Digits[0]     = *PtrBuffer;
00776     PtrBuffer++;
00777     Digits[1]     = *PtrBuffer;
00778     Digits[2]     = '\0';
00779     Data          = AsciiStrHexToUintn ((CONST CHAR8 *) Digits);
00780     Guid->Data4[Index] = (UINT8)Data;
00781   }
00782 
00783   FreePool (Buffer);
00784 
00785   return EFI_SUCCESS;
00786 }
00787 
00800 EFI_STATUS
00801 PreProcessDataFile (
00802   IN      UINT8                         *DataBuffer,
00803   IN      UINTN                         BufferSize,
00804   IN OUT  SECTION_ITEM                  **SectionHead,
00805   IN OUT  COMMENT_LINE                  **CommentHead
00806   )
00807 {
00808   EFI_STATUS                            Status;
00809   CHAR8                                 *Source;
00810   CHAR8                                 *CurrentPtr;
00811   CHAR8                                 *BufferEnd;
00812   CHAR8                                 *PtrLine;
00813   UINTN                                 LineLength;
00814   UINTN                                 SourceLength;
00815   UINTN                                 MaxLineLength;
00816 
00817   *SectionHead          = NULL;
00818   *CommentHead          = NULL;
00819   BufferEnd             = (CHAR8 *) ( (UINTN) DataBuffer + BufferSize);
00820   CurrentPtr            = (CHAR8 *) DataBuffer;
00821   MaxLineLength         = MAX_LINE_LENGTH;
00822   Status                = EFI_SUCCESS;
00823 
00824   PtrLine = AllocatePool (MaxLineLength);
00825   if (PtrLine == NULL) {
00826     return EFI_OUT_OF_RESOURCES;
00827   }
00828 
00829   while (CurrentPtr < BufferEnd) {
00830     Source              = CurrentPtr;
00831     SourceLength        = (UINTN)BufferEnd - (UINTN)CurrentPtr;
00832     LineLength          = MaxLineLength;
00833     //
00834     // With the assumption that line length is less than 512
00835     // characters. Otherwise BUFFER_TOO_SMALL will be returned.
00836     //
00837     Status              = ProfileGetLine (
00838                             (UINT8 *) Source,
00839                             SourceLength,
00840                             (UINT8 *) PtrLine,
00841                             &LineLength
00842                             );
00843     if (EFI_ERROR (Status)) {
00844       if (Status == EFI_BUFFER_TOO_SMALL) {
00845         //
00846         // If buffer too small, re-allocate the buffer according
00847         // to the returned LineLength and try again.
00848         //
00849         FreePool (PtrLine);
00850         PtrLine         = NULL;
00851         PtrLine = AllocatePool (LineLength);
00852         if (PtrLine == NULL) {
00853           Status        = EFI_OUT_OF_RESOURCES;
00854           break;
00855         }
00856         SourceLength    = LineLength;
00857         Status          = ProfileGetLine (
00858                             (UINT8 *) Source,
00859                             SourceLength,
00860                             (UINT8 *) PtrLine,
00861                             &LineLength
00862                             );
00863         if (EFI_ERROR (Status)) {
00864           break;
00865         }
00866         MaxLineLength   = LineLength;
00867       } else {
00868         break;
00869       }
00870     }
00871     CurrentPtr          = (CHAR8 *) ( (UINTN) CurrentPtr + LineLength);
00872 
00873     //
00874     // Line got. Trim the line before processing it.
00875     //
00876     ProfileTrim (
00877       (UINT8 *) PtrLine,
00878       &LineLength
00879    );
00880 
00881     //
00882     // Blank line
00883     //
00884     if (LineLength == 0) {
00885       continue;
00886     }
00887 
00888     if (PtrLine[0] == '#') {
00889       Status            = ProfileGetComments (
00890                             (UINT8 *) PtrLine,
00891                             LineLength,
00892                             CommentHead
00893                             );
00894     } else if (PtrLine[0] == '[') {
00895       Status            = ProfileGetSection (
00896                             (UINT8 *) PtrLine,
00897                             LineLength,
00898                             SectionHead
00899                             );
00900     } else {
00901       Status            = ProfileGetEntry (
00902                             (UINT8 *) PtrLine,
00903                             LineLength,
00904                             SectionHead
00905                             );
00906     }
00907 
00908     if (EFI_ERROR (Status)) {
00909       break;
00910     }
00911   }
00912 
00913   //
00914   // Free buffer
00915   //
00916   FreePool (PtrLine);
00917 
00918   return Status;
00919 }
00920 
00934 EFI_STATUS
00935 ParseUpdateDataFile (
00936   IN      UINT8                         *DataBuffer,
00937   IN      UINTN                         BufferSize,
00938   IN OUT  UINTN                         *NumOfUpdates,
00939   IN OUT  UPDATE_CONFIG_DATA            **UpdateArray
00940   )
00941 {
00942   EFI_STATUS                            Status;
00943   CHAR8                                 *Value;
00944   CHAR8                                 *SectionName;
00945   CHAR8                                 Entry[MAX_LINE_LENGTH];
00946   SECTION_ITEM                          *SectionHead;
00947   COMMENT_LINE                          *CommentHead;
00948   UINTN                                 Num;
00949   UINTN                                 Index;
00950   EFI_GUID                              FileGuid;
00951 
00952   SectionHead           = NULL;
00953   CommentHead           = NULL;
00954 
00955   //
00956   // First process the data buffer and get all sections and entries
00957   //
00958   Status                = PreProcessDataFile (
00959                             DataBuffer,
00960                             BufferSize,
00961                             &SectionHead,
00962                             &CommentHead
00963                             );
00964   if (EFI_ERROR (Status)) {
00965     FreeAllList (SectionHead, CommentHead);
00966     return Status;
00967   }
00968 
00969   //
00970   // Now get NumOfUpdate
00971   //
00972   Value                 = NULL;
00973   Status                = UpdateGetProfileString (
00974                             SectionHead,
00975                             (UINT8 *) "Head",
00976                             (UINT8 *) "NumOfUpdate",
00977                             (UINT8 **) &Value
00978                             );
00979   if (Value == NULL) {
00980     FreeAllList (SectionHead, CommentHead);
00981     return EFI_NOT_FOUND;
00982   }
00983   Num                   = UpdateAtoi((UINT8 *) Value);
00984   if (Num <= 0) {
00985     FreeAllList (SectionHead, CommentHead);
00986     return EFI_NOT_FOUND;
00987   }
00988 
00989   *NumOfUpdates         = Num;
00990   *UpdateArray = AllocatePool ((sizeof (UPDATE_CONFIG_DATA) * Num));
00991   if (*UpdateArray == NULL) {
00992     FreeAllList (SectionHead, CommentHead);
00993     return EFI_OUT_OF_RESOURCES;
00994   }
00995 
00996   for ( Index = 0 ; Index < *NumOfUpdates ; Index++) {
00997     //
00998     // Get the section name of each update
00999     //
01000     AsciiStrCpy (Entry, "Update");
01001     UpdateStrCatNumber ((UINT8 *) Entry, Index);
01002     Value               = NULL;
01003     Status              = UpdateGetProfileString (
01004                             SectionHead,
01005                             (UINT8 *) "Head",
01006                             (UINT8 *) Entry,
01007                             (UINT8 **) &Value
01008                             );
01009     if (Value == NULL) {
01010       FreeAllList (SectionHead, CommentHead);
01011       return EFI_NOT_FOUND;
01012     }
01013 
01014     //
01015     // The section name of this update has been found.
01016     // Now looks for all the config data of this update
01017     //
01018     SectionName         = Value;
01019 
01020     //
01021     // UpdateType
01022     //
01023     Value               = NULL;
01024     Status              = UpdateGetProfileString (
01025                             SectionHead,
01026                             (UINT8 *) SectionName,
01027                             (UINT8 *) "UpdateType",
01028                             (UINT8 **) &Value
01029                             );
01030     if (Value == NULL) {
01031       FreeAllList (SectionHead, CommentHead);
01032       return EFI_NOT_FOUND;
01033     }
01034 
01035     Num                 = UpdateAtoi((UINT8 *) Value);
01036     if (( Num >= (UINTN) UpdateOperationMaximum)) {
01037       FreeAllList (SectionHead, CommentHead);
01038       return Status;
01039     }
01040     (*UpdateArray)[Index].Index       = Index;
01041     (*UpdateArray)[Index].UpdateType  = (UPDATE_OPERATION_TYPE) Num;
01042 
01043     //
01044     // FvBaseAddress
01045     //
01046     Value               = NULL;
01047     Status              = UpdateGetProfileString (
01048                             SectionHead,
01049                             (UINT8 *) SectionName,
01050                             (UINT8 *) "FvBaseAddress",
01051                             (UINT8 **) &Value
01052                             );
01053     if (Value == NULL) {
01054       FreeAllList (SectionHead, CommentHead);
01055       return EFI_NOT_FOUND;
01056     }
01057 
01058     Num                 = AsciiStrHexToUintn ((CONST CHAR8 *) Value);
01059     (*UpdateArray)[Index].BaseAddress = (EFI_PHYSICAL_ADDRESS) Num;
01060 
01061     //
01062     // FileBuid
01063     //
01064     Value               = NULL;
01065     Status              = UpdateGetProfileString (
01066                             SectionHead,
01067                             (UINT8 *) SectionName,
01068                             (UINT8 *) "FileGuid",
01069                             (UINT8 **) &Value
01070                             );
01071     if (Value == NULL) {
01072       FreeAllList (SectionHead, CommentHead);
01073       return EFI_NOT_FOUND;
01074     }
01075 
01076     Status              = UpdateStringToGuid ((UINT8 *) Value, &FileGuid);
01077     if (EFI_ERROR (Status)) {
01078       FreeAllList (SectionHead, CommentHead);
01079       return Status;
01080     }
01081     CopyMem (&((*UpdateArray)[Index].FileGuid), &FileGuid, sizeof(EFI_GUID));
01082 
01083     //
01084     // FaultTolerant
01085     // Default value is FALSE
01086     //
01087     Value               = NULL;
01088     (*UpdateArray)[Index].FaultTolerant = FALSE;
01089     Status              = UpdateGetProfileString (
01090                             SectionHead,
01091                             (UINT8 *) SectionName,
01092                             (UINT8 *) "FaultTolerant",
01093                             (UINT8 **) &Value
01094                            );
01095     if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
01096       FreeAllList (SectionHead, CommentHead);
01097       return Status;
01098     } else if (Value != NULL) {
01099       if (AsciiStriCmp ((CONST CHAR8 *) Value, (CONST CHAR8 *) "TRUE") == 0) {
01100         (*UpdateArray)[Index].FaultTolerant = TRUE;
01101       } else if (AsciiStriCmp ((CONST CHAR8 *) Value, (CONST CHAR8 *) "FALSE") == 0) {
01102         (*UpdateArray)[Index].FaultTolerant = FALSE;
01103       }
01104     }
01105 
01106     if ((*UpdateArray)[Index].UpdateType == UpdateFvRange) {
01107       //
01108       // Length
01109       //
01110       Value             = NULL;
01111       Status            = UpdateGetProfileString (
01112                             SectionHead,
01113                             (UINT8 *) SectionName,
01114                             (UINT8 *) "Length",
01115                             (UINT8 **) &Value
01116                             );
01117       if (Value == NULL) {
01118         FreeAllList (SectionHead, CommentHead);
01119         return EFI_NOT_FOUND;
01120       }
01121 
01122       Num               = AsciiStrHexToUintn ((CONST CHAR8 *) Value);
01123       (*UpdateArray)[Index].Length = (UINTN) Num;
01124     }
01125   }
01126 
01127   //
01128   // Now all configuration data got. Free those temporary buffers
01129   //
01130   FreeAllList (SectionHead, CommentHead);
01131 
01132   return EFI_SUCCESS;
01133 }
01134 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Defines