From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id C97A01A1E53 for ; Tue, 20 Sep 2016 23:46:05 -0700 (PDT) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga105.jf.intel.com with ESMTP; 20 Sep 2016 23:46:05 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.30,372,1470726000"; d="scan'208";a="1059858747" Received: from jyao1-mobl.ccr.corp.intel.com ([10.239.192.109]) by fmsmga002.fm.intel.com with ESMTP; 20 Sep 2016 23:46:03 -0700 From: Jiewen Yao To: edk2-devel@lists.01.org Cc: Feng Tian , Star Zeng , Michael D Kinney , Liming Gao , Chao Zhang Date: Wed, 21 Sep 2016 14:44:49 +0800 Message-Id: <1474440326-9292-9-git-send-email-jiewen.yao@intel.com> X-Mailer: git-send-email 2.7.4.windows.1 In-Reply-To: <1474440326-9292-1-git-send-email-jiewen.yao@intel.com> References: <1474440326-9292-1-git-send-email-jiewen.yao@intel.com> Subject: [PATCH 08/45] MdeModulePkg/IniParsingLib: Add InitParsingLib instance. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 21 Sep 2016 06:46:06 -0000 This library is used to parse the INI configuration file. The INI configuration file is used in EDKII capsule image to describe the capsule information. Cc: Feng Tian Cc: Star Zeng Cc: Michael D Kinney Cc: Liming Gao Cc: Chao Zhang Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao --- MdeModulePkg/Library/IniParsingLib/IniParsingLib.c | 1053 ++++++++++++++++++++ MdeModulePkg/Library/IniParsingLib/IniParsingLib.inf | 42 + MdeModulePkg/Library/IniParsingLib/IniParsingLib.uni | 22 + 3 files changed, 1117 insertions(+) diff --git a/MdeModulePkg/Library/IniParsingLib/IniParsingLib.c b/MdeModulePkg/Library/IniParsingLib/IniParsingLib.c new file mode 100644 index 0000000..e5dd813 --- /dev/null +++ b/MdeModulePkg/Library/IniParsingLib/IniParsingLib.c @@ -0,0 +1,1053 @@ +/** @file + This library parses the INI configuration file. + + Copyright (c) 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions + of the BSD License which accompanies this distribution. The + full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include + +#define IS_HYPHEN(a) ((a) == '-') +#define IS_NULL(a) ((a) == '\0') + +#define MAX_LINE_LENGTH 512 + +typedef struct _SECTION_ITEM SECTION_ITEM; +struct _SECTION_ITEM { + CHAR8 *ptrSection; + UINTN SecNameLen; + CHAR8 *ptrEntry; + CHAR8 *ptrValue; + SECTION_ITEM *ptrNext; +}; + +typedef struct _COMMENT_LINE COMMENT_LINE; +struct _COMMENT_LINE { + CHAR8 *ptrComment; + COMMENT_LINE *ptrNext; +}; + +typedef struct { + SECTION_ITEM *SectionHead; + COMMENT_LINE *CommentHead; +} INI_PARSING_LIB_CONTEXT; + +/** + Copy one line data from buffer data to the line buffer. + + @param Buffer Buffer data. + @param BufferSize Buffer Size. + @param LineBuffer Line buffer to store the found line data. + @param LineSize On input, size of the input line buffer. + On output, size of the actual line buffer. + + @retval EFI_BUFFER_TOO_SMALL The size of input line buffer is not enough. + @retval EFI_SUCCESS Copy line data into the line buffer. + +**/ +EFI_STATUS +ProfileGetLine ( + IN UINT8 *Buffer, + IN UINTN BufferSize, + IN OUT UINT8 *LineBuffer, + IN OUT UINTN *LineSize + ) +{ + UINTN Length; + UINT8 *PtrBuf; + UINTN PtrEnd; + + PtrBuf = Buffer; + PtrEnd = (UINTN)Buffer + BufferSize; + + // + // 0x0D indicates a line break. Otherwise there is no line break + // + while ((UINTN)PtrBuf < PtrEnd) { + if (*PtrBuf == 0x0D) { + break; + } + PtrBuf++; + } + + if ((UINTN)PtrBuf >= (PtrEnd - 1)) { + // + // The buffer ends without any line break + // or it is the last character of the buffer + // + Length = BufferSize; + } else if (*(PtrBuf + 1) == 0x0A) { + // + // Further check if a 0x0A follows. If yes, count 0xA + // + Length = (UINTN) PtrBuf - (UINTN) Buffer + 2; + } else { + Length = (UINTN) PtrBuf - (UINTN) Buffer + 1; + } + + if (Length > (*LineSize)) { + *LineSize = Length; + return EFI_BUFFER_TOO_SMALL; + } + + SetMem (LineBuffer, *LineSize, 0x0); + *LineSize = Length; + CopyMem (LineBuffer, Buffer, Length); + + return EFI_SUCCESS; +} + +/** + Trim Buffer by removing all CR, LF, TAB, and SPACE chars in its head and tail. + + @param Buffer On input, buffer data to be trimed. + On output, the trimmed buffer. + @param BufferSize On input, size of original buffer data. + On output, size of the trimmed buffer. + +**/ +VOID +ProfileTrim ( + IN OUT UINT8 *Buffer, + IN OUT UINTN *BufferSize + ) +{ + UINTN Length; + UINT8 *PtrBuf; + UINT8 *PtrEnd; + + if (*BufferSize == 0) { + return; + } + + // + // Trim the tail first, include CR, LF, TAB, and SPACE. + // + Length = *BufferSize; + PtrBuf = (UINT8 *) ((UINTN) Buffer + Length - 1); + while (PtrBuf >= Buffer) { + if ((*PtrBuf != 0x0D) && (*PtrBuf != 0x0A ) + && (*PtrBuf != 0x20) && (*PtrBuf != 0x09)) { + break; + } + PtrBuf --; + } + + // + // all spaces, a blank line, return directly; + // + if (PtrBuf < Buffer) { + *BufferSize = 0; + return; + } + + Length = (UINTN)PtrBuf - (UINTN)Buffer + 1; + PtrEnd = PtrBuf; + PtrBuf = Buffer; + + // + // Now skip the heading CR, LF, TAB and SPACE + // + while (PtrBuf <= PtrEnd) { + if ((*PtrBuf != 0x0D) && (*PtrBuf != 0x0A ) + && (*PtrBuf != 0x20) && (*PtrBuf != 0x09)) { + break; + } + PtrBuf++; + } + + // + // If no heading CR, LF, TAB or SPACE, directly return + // + if (PtrBuf == Buffer) { + *BufferSize = Length; + return; + } + + *BufferSize = (UINTN)PtrEnd - (UINTN)PtrBuf + 1; + + // + // The first Buffer..PtrBuf characters are CR, LF, TAB or SPACE. + // Now move out all these characters. + // + while (PtrBuf <= PtrEnd) { + *Buffer = *PtrBuf; + Buffer++; + PtrBuf++; + } + + return; +} + +/** + Insert new comment item into comment head. + + @param Buffer Comment buffer to be added. + @param BufferSize Size of comment buffer. + @param CommentHead Comment Item head entry. + + @retval EFI_OUT_OF_RESOURCES No enough memory is allocated. + @retval EFI_SUCCESS New comment item is inserted. + +**/ +EFI_STATUS +ProfileGetComments ( + IN UINT8 *Buffer, + IN UINTN BufferSize, + IN OUT COMMENT_LINE **CommentHead + ) +{ + COMMENT_LINE *CommentItem; + + CommentItem = NULL; + CommentItem = AllocatePool (sizeof (COMMENT_LINE)); + if (CommentItem == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + CommentItem->ptrNext = *CommentHead; + *CommentHead = CommentItem; + + // + // Add a trailing '\0' + // + CommentItem->ptrComment = AllocatePool (BufferSize + 1); + if (CommentItem->ptrComment == NULL) { + FreePool (CommentItem); + return EFI_OUT_OF_RESOURCES; + } + CopyMem (CommentItem->ptrComment, Buffer, BufferSize); + *(CommentItem->ptrComment + BufferSize) = '\0'; + + return EFI_SUCCESS; +} + +/** + Add new section item into Section head. + + @param Buffer Section item data buffer. + @param BufferSize Size of section item. + @param SectionHead Section item head entry. + + @retval EFI_OUT_OF_RESOURCES No enough memory is allocated. + @retval EFI_SUCCESS Section item is NULL or Section item is added. + +**/ +EFI_STATUS +ProfileGetSection ( + IN UINT8 *Buffer, + IN UINTN BufferSize, + IN OUT SECTION_ITEM **SectionHead + ) +{ + EFI_STATUS Status; + SECTION_ITEM *SectionItem; + UINTN Length; + UINT8 *PtrBuf; + + Status = EFI_SUCCESS; + // + // The first character of Buffer is '[', now we want for ']' + // + PtrBuf = (UINT8 *)((UINTN)Buffer + BufferSize - 1); + while (PtrBuf > Buffer) { + if (*PtrBuf == ']') { + break; + } + PtrBuf --; + } + if (PtrBuf <= Buffer) { + // + // Not found. Omit this line + // + return Status; + } + + // + // excluding the heading '[' and tailing ']' + // + Length = PtrBuf - Buffer - 1; + ProfileTrim ( + Buffer + 1, + &Length + ); + + // + // omit this line if the section name is null + // + if (Length == 0) { + return Status; + } + + SectionItem = AllocatePool (sizeof (SECTION_ITEM)); + if (SectionItem == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + SectionItem->ptrSection = NULL; + SectionItem->SecNameLen = Length; + SectionItem->ptrEntry = NULL; + SectionItem->ptrValue = NULL; + SectionItem->ptrNext = *SectionHead; + *SectionHead = SectionItem; + + // + // Add a trailing '\0' + // + SectionItem->ptrSection = AllocatePool (Length + 1); + if (SectionItem->ptrSection == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // excluding the heading '[' + // + CopyMem (SectionItem->ptrSection, Buffer + 1, Length); + *(SectionItem->ptrSection + Length) = '\0'; + + return EFI_SUCCESS; +} + +/** + Add new section entry and entry value into Section head. + + @param Buffer Section entry data buffer. + @param BufferSize Size of section entry. + @param SectionHead Section item head entry. + + @retval EFI_OUT_OF_RESOURCES No enough memory is allocated. + @retval EFI_SUCCESS Section entry is NULL or Section entry is added. + +**/ +EFI_STATUS +ProfileGetEntry ( + IN UINT8 *Buffer, + IN UINTN BufferSize, + IN OUT SECTION_ITEM **SectionHead + ) +{ + EFI_STATUS Status; + SECTION_ITEM *SectionItem; + SECTION_ITEM *PtrSection; + UINTN Length; + UINT8 *PtrBuf; + UINT8 *PtrEnd; + + Status = EFI_SUCCESS; + PtrBuf = Buffer; + PtrEnd = (UINT8 *) ((UINTN)Buffer + BufferSize - 1); + + // + // First search for '=' + // + while (PtrBuf <= PtrEnd) { + if (*PtrBuf == '=') { + break; + } + PtrBuf++; + } + if (PtrBuf > PtrEnd) { + // + // Not found. Omit this line + // + return Status; + } + + // + // excluding the tailing '=' + // + Length = PtrBuf - Buffer; + ProfileTrim ( + Buffer, + &Length + ); + + // + // Omit this line if the entry name is null + // + if (Length == 0) { + return Status; + } + + // + // Omit this line if no section header has been found before + // + if (*SectionHead == NULL) { + return Status; + } + PtrSection = *SectionHead; + + SectionItem = AllocatePool (sizeof (SECTION_ITEM)); + if (SectionItem == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + SectionItem->ptrSection = NULL; + SectionItem->ptrEntry = NULL; + SectionItem->ptrValue = NULL; + SectionItem->SecNameLen = PtrSection->SecNameLen; + SectionItem->ptrNext = *SectionHead; + *SectionHead = SectionItem; + + // + // SectionName, add a trailing '\0' + // + SectionItem->ptrSection = AllocatePool (PtrSection->SecNameLen + 1); + if (SectionItem->ptrSection == NULL) { + return EFI_OUT_OF_RESOURCES; + } + CopyMem (SectionItem->ptrSection, PtrSection->ptrSection, PtrSection->SecNameLen + 1); + + // + // EntryName, add a trailing '\0' + // + SectionItem->ptrEntry = AllocatePool (Length + 1); + if (SectionItem->ptrEntry == NULL) { + return EFI_OUT_OF_RESOURCES; + } + CopyMem (SectionItem->ptrEntry, Buffer, Length); + *(SectionItem->ptrEntry + Length) = '\0'; + + // + // Next search for '#' + // + PtrBuf = PtrBuf + 1; + Buffer = PtrBuf; + while (PtrBuf <= PtrEnd) { + if (*PtrBuf == '#') { + break; + } + PtrBuf++; + } + Length = PtrBuf - Buffer; + ProfileTrim ( + Buffer, + &Length + ); + + if (Length > 0) { + // + // EntryValue, add a trailing '\0' + // + SectionItem->ptrValue = AllocatePool (Length + 1); + if (SectionItem->ptrValue == NULL) { + return EFI_OUT_OF_RESOURCES; + } + CopyMem (SectionItem->ptrValue, Buffer, Length); + *(SectionItem->ptrValue + Length) = '\0'; + } + + return EFI_SUCCESS; +} + +/** + Free all comment entry and section entry. + + @param Section Section entry list. + @param Comment Comment entry list. + +**/ +VOID +FreeAllList ( + IN SECTION_ITEM *Section, + IN COMMENT_LINE *Comment + ) +{ + SECTION_ITEM *PtrSection; + COMMENT_LINE *PtrComment; + + while (Section != NULL) { + PtrSection = Section; + Section = Section->ptrNext; + if (PtrSection->ptrEntry != NULL) { + FreePool (PtrSection->ptrEntry); + } + if (PtrSection->ptrSection != NULL) { + FreePool (PtrSection->ptrSection); + } + if (PtrSection->ptrValue != NULL) { + FreePool (PtrSection->ptrValue); + } + FreePool (PtrSection); + } + + while (Comment != NULL) { + PtrComment = Comment; + Comment = Comment->ptrNext; + if (PtrComment->ptrComment != NULL) { + FreePool (PtrComment->ptrComment); + } + FreePool (PtrComment); + } + + return; +} + +/** + Get section entry value. + + @param Section Section entry list. + @param SectionName Section name. + @param EntryName Section entry name. + @param EntryValue Point to the got entry value. + + @retval EFI_NOT_FOUND Section is not found. + @retval EFI_SUCCESS Section entry value is got. + +**/ +EFI_STATUS +UpdateGetProfileString ( + IN SECTION_ITEM *Section, + IN CHAR8 *SectionName, + IN CHAR8 *EntryName, + OUT CHAR8 **EntryValue + ) +{ + *EntryValue = NULL; + + while (Section != NULL) { + if (AsciiStrCmp ((CONST CHAR8 *) Section->ptrSection, (CONST CHAR8 *) SectionName) == 0) { + if (Section->ptrEntry != NULL) { + if (AsciiStrCmp ((CONST CHAR8 *) Section->ptrEntry, (CONST CHAR8 *) EntryName) == 0) { + break; + } + } + } + Section = Section->ptrNext; + } + + if (Section == NULL) { + return EFI_NOT_FOUND; + } + + *EntryValue = Section->ptrValue; + + return EFI_SUCCESS; +} + +/** + Converts a list of string to a specified buffer. + + @param Buf The output buffer that contains the string. + @param BufferLength The length of the buffer + @param Str The input string that contains the hex number + + @retval EFI_SUCCESS The string was successfully converted to the buffer. + +**/ +EFI_STATUS +AsciiStrToBuf ( + OUT UINT8 *Buf, + IN UINTN BufferLength, + IN CHAR8 *Str + ) +{ + UINTN Index; + UINTN StrLength; + UINT8 Digit; + UINT8 Byte; + + Digit = 0; + + // + // Two hex char make up one byte + // + StrLength = BufferLength * sizeof (CHAR8); + + for(Index = 0; Index < StrLength; Index++, Str++) { + + if ((*Str >= 'a') && (*Str <= 'f')) { + Digit = (UINT8) (*Str - 'a' + 0x0A); + } else if ((*Str >= 'A') && (*Str <= 'F')) { + Digit = (UINT8) (*Str - 'A' + 0x0A); + } else if ((*Str >= '0') && (*Str <= '9')) { + Digit = (UINT8) (*Str - '0'); + } else { + return EFI_INVALID_PARAMETER; + } + + // + // For odd characters, write the upper nibble for each buffer byte, + // and for even characters, the lower nibble. + // + if ((Index & 1) == 0) { + Byte = (UINT8) (Digit << 4); + } else { + Byte = Buf[Index / 2]; + Byte &= 0xF0; + Byte = (UINT8) (Byte | Digit); + } + + Buf[Index / 2] = Byte; + } + + return EFI_SUCCESS; +} + +/** + Converts a string to GUID value. + Guid Format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + + @param Str The registry format GUID string that contains the GUID value. + @param Guid A pointer to the converted GUID value. + + @retval EFI_SUCCESS The GUID string was successfully converted to the GUID value. + @retval EFI_UNSUPPORTED The input string is not in registry format. + @return others Some error occurred when converting part of GUID value. + +**/ +EFI_STATUS +AsciiStrToGuid ( + IN CHAR8 *Str, + OUT EFI_GUID *Guid + ) +{ + // + // Get the first UINT32 data + // + Guid->Data1 = (UINT32) AsciiStrHexToUint64 (Str); + while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) { + Str ++; + } + + if (IS_HYPHEN (*Str)) { + Str++; + } else { + return EFI_UNSUPPORTED; + } + + // + // Get the second UINT16 data + // + Guid->Data2 = (UINT16) AsciiStrHexToUint64 (Str); + while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) { + Str ++; + } + + if (IS_HYPHEN (*Str)) { + Str++; + } else { + return EFI_UNSUPPORTED; + } + + // + // Get the third UINT16 data + // + Guid->Data3 = (UINT16) AsciiStrHexToUint64 (Str); + while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) { + Str ++; + } + + if (IS_HYPHEN (*Str)) { + Str++; + } else { + return EFI_UNSUPPORTED; + } + + // + // Get the following 8 bytes data + // + AsciiStrToBuf (&Guid->Data4[0], 2, Str); + // + // Skip 2 byte hex chars + // + Str += 2 * 2; + + if (IS_HYPHEN (*Str)) { + Str++; + } else { + return EFI_UNSUPPORTED; + } + AsciiStrToBuf (&Guid->Data4[2], 6, Str); + + return EFI_SUCCESS; +} + +/** + Pre process config data buffer into Section entry list and Comment entry list. + + @param DataBuffer Config raw file buffer. + @param BufferSize Size of raw buffer. + @param SectionHead Pointer to the section entry list. + @param CommentHead Pointer to the comment entry list. + + @retval EFI_OUT_OF_RESOURCES No enough memory is allocated. + @retval EFI_SUCCESS Config data buffer is preprocessed. + +**/ +EFI_STATUS +PreProcessDataFile ( + IN UINT8 *DataBuffer, + IN UINTN BufferSize, + IN OUT SECTION_ITEM **SectionHead, + IN OUT COMMENT_LINE **CommentHead + ) +{ + EFI_STATUS Status; + CHAR8 *Source; + CHAR8 *CurrentPtr; + CHAR8 *BufferEnd; + CHAR8 *PtrLine; + UINTN LineLength; + UINTN SourceLength; + UINTN MaxLineLength; + + *SectionHead = NULL; + *CommentHead = NULL; + BufferEnd = (CHAR8 *) ( (UINTN) DataBuffer + BufferSize); + CurrentPtr = (CHAR8 *) DataBuffer; + MaxLineLength = MAX_LINE_LENGTH; + Status = EFI_SUCCESS; + + PtrLine = AllocatePool (MaxLineLength); + if (PtrLine == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + while (CurrentPtr < BufferEnd) { + Source = CurrentPtr; + SourceLength = (UINTN)BufferEnd - (UINTN)CurrentPtr; + LineLength = MaxLineLength; + // + // With the assumption that line length is less than 512 + // characters. Otherwise BUFFER_TOO_SMALL will be returned. + // + Status = ProfileGetLine ( + (UINT8 *) Source, + SourceLength, + (UINT8 *) PtrLine, + &LineLength + ); + if (EFI_ERROR (Status)) { + if (Status == EFI_BUFFER_TOO_SMALL) { + // + // If buffer too small, re-allocate the buffer according + // to the returned LineLength and try again. + // + FreePool (PtrLine); + PtrLine = NULL; + PtrLine = AllocatePool (LineLength); + if (PtrLine == NULL) { + Status = EFI_OUT_OF_RESOURCES; + break; + } + SourceLength = LineLength; + Status = ProfileGetLine ( + (UINT8 *) Source, + SourceLength, + (UINT8 *) PtrLine, + &LineLength + ); + if (EFI_ERROR (Status)) { + break; + } + MaxLineLength = LineLength; + } else { + break; + } + } + CurrentPtr = (CHAR8 *) ( (UINTN) CurrentPtr + LineLength); + + // + // Line got. Trim the line before processing it. + // + ProfileTrim ( + (UINT8 *) PtrLine, + &LineLength + ); + + // + // Blank line + // + if (LineLength == 0) { + continue; + } + + if (PtrLine[0] == '#' || PtrLine[0] == ';') { + Status = ProfileGetComments ( + (UINT8 *) PtrLine, + LineLength, + CommentHead + ); + } else if (PtrLine[0] == '[') { + Status = ProfileGetSection ( + (UINT8 *) PtrLine, + LineLength, + SectionHead + ); + } else { + Status = ProfileGetEntry ( + (UINT8 *) PtrLine, + LineLength, + SectionHead + ); + } + + if (EFI_ERROR (Status)) { + break; + } + } + + // + // Free buffer + // + FreePool (PtrLine); + + return Status; +} + +/** + Open an INI config file and return a context. + + @param DataBuffer Config raw file buffer. + @param BufferSize Size of raw buffer. + + @retval EFI_SUCCESS Config data buffer is opened and context is returned. + @retval EFI_OUT_OF_RESOURCES No enough memory is allocated. +**/ +VOID * +EFIAPI +OpenDataFile ( + IN UINT8 *DataBuffer, + IN UINTN BufferSize + ) +{ + EFI_STATUS Status; + INI_PARSING_LIB_CONTEXT *IniContext; + + IniContext = AllocateZeroPool(sizeof(INI_PARSING_LIB_CONTEXT)); + if (IniContext == NULL) { + return NULL; + } + + // + // First process the data buffer and get all sections and entries + // + Status = PreProcessDataFile ( + DataBuffer, + BufferSize, + &IniContext->SectionHead, + &IniContext->CommentHead + ); + if (EFI_ERROR(Status)) { + FreePool(IniContext); + return NULL; + } + + return IniContext; +} + +/** + Get section entry string value. + + @param Context INI Config file context. + @param SectionName Section name. + @param EntryName Section entry name. + @param EntryValue Point to the got entry string value. + + @retval EFI_SUCCESS Section entry string value is got. + @retval EFI_NOT_FOUND Section is not found. +**/ +EFI_STATUS +EFIAPI +GetStringFromDataFile( + IN VOID *Context, + IN CHAR8 *SectionName, + IN CHAR8 *EntryName, + OUT CHAR8 **EntryValue + ) +{ + INI_PARSING_LIB_CONTEXT *IniContext; + EFI_STATUS Status; + + IniContext = Context; + + *EntryValue = NULL; + Status = UpdateGetProfileString ( + IniContext->SectionHead, + SectionName, + EntryName, + EntryValue + ); + return Status; +} + +/** + Get section entry GUID value. + + @param Context INI Config file context. + @param SectionName Section name. + @param EntryName Section entry name. + @param Guid Point to the got GUID value. + + @retval EFI_SUCCESS Section entry GUID value is got. + @retval EFI_NOT_FOUND Section is not found. +**/ +EFI_STATUS +EFIAPI +GetGuidFromDataFile( + IN VOID *Context, + IN CHAR8 *SectionName, + IN CHAR8 *EntryName, + OUT EFI_GUID *Guid + ) +{ + CHAR8 *Value; + EFI_STATUS Status; + + Status = GetStringFromDataFile( + Context, + SectionName, + EntryName, + &Value + ); + if (EFI_ERROR(Status)) { + return EFI_NOT_FOUND; + } + + Status = AsciiStrToGuid(Value, Guid); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + return EFI_SUCCESS; +} + +/** + Get section entry decimal UINTN value. + + @param Context INI Config file context. + @param SectionName Section name. + @param EntryName Section entry name. + @param Data Point to the got decimal UINTN value. + + @retval EFI_SUCCESS Section entry decimal UINTN value is got. + @retval EFI_NOT_FOUND Section is not found. +**/ +EFI_STATUS +EFIAPI +GetDecimalUintnFromDataFile( + IN VOID *Context, + IN CHAR8 *SectionName, + IN CHAR8 *EntryName, + OUT UINTN *Data + ) +{ + CHAR8 *Value; + EFI_STATUS Status; + + Status = GetStringFromDataFile( + Context, + SectionName, + EntryName, + &Value + ); + if (EFI_ERROR(Status)) { + return EFI_NOT_FOUND; + } + *Data = AsciiStrDecimalToUintn(Value); + return EFI_SUCCESS; +} + +/** + Get section entry heximal UINTN value. + + @param Context INI Config file context. + @param SectionName Section name. + @param EntryName Section entry name. + @param Data Point to the got heximal UINTN value. + + @retval EFI_SUCCESS Section entry heximal UINTN value is got. + @retval EFI_NOT_FOUND Section is not found. +**/ +EFI_STATUS +EFIAPI +GetHexUintnFromDataFile( + IN VOID *Context, + IN CHAR8 *SectionName, + IN CHAR8 *EntryName, + OUT UINTN *Data + ) +{ + CHAR8 *Value; + EFI_STATUS Status; + + Status = GetStringFromDataFile( + Context, + SectionName, + EntryName, + &Value + ); + if (EFI_ERROR(Status)) { + return EFI_NOT_FOUND; + } + *Data = AsciiStrHexToUintn(Value); + return EFI_SUCCESS; +} + +/** + Get section entry heximal UINT64 value. + + @param Context INI Config file context. + @param SectionName Section name. + @param EntryName Section entry name. + @param Data Point to the got heximal UINT64 value. + + @retval EFI_SUCCESS Section entry heximal UINT64 value is got. + @retval EFI_NOT_FOUND Section is not found. +**/ +EFI_STATUS +EFIAPI +GetHexUint64FromDataFile( + IN VOID *Context, + IN CHAR8 *SectionName, + IN CHAR8 *EntryName, + OUT UINT64 *Data + ) +{ + CHAR8 *Value; + EFI_STATUS Status; + + Status = GetStringFromDataFile( + Context, + SectionName, + EntryName, + &Value + ); + if (EFI_ERROR(Status)) { + return EFI_NOT_FOUND; + } + *Data = AsciiStrHexToUint64(Value); + return EFI_SUCCESS; +} + +/** + Close an INI config file and free the context. + + @param Context INI Config file context. +**/ +VOID +EFIAPI +CloseDataFile( + IN VOID *Context + ) +{ + INI_PARSING_LIB_CONTEXT *IniContext; + + IniContext = Context; + FreeAllList(IniContext->SectionHead, IniContext->CommentHead); + + return; +} diff --git a/MdeModulePkg/Library/IniParsingLib/IniParsingLib.inf b/MdeModulePkg/Library/IniParsingLib/IniParsingLib.inf new file mode 100644 index 0000000..4721388 --- /dev/null +++ b/MdeModulePkg/Library/IniParsingLib/IniParsingLib.inf @@ -0,0 +1,42 @@ +## @file +# INI configuration parsing library. +# +# This library parses the INI configuration file. +# +# Copyright (c) 2016, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = IniParsingLib + MODULE_UNI_FILE = IniParsingLib.uni + FILE_GUID = 6E4CD200-43E5-43CE-89E9-D715CF9526C4 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = IniParsingLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + IniParsingLib.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + MemoryAllocationLib diff --git a/MdeModulePkg/Library/IniParsingLib/IniParsingLib.uni b/MdeModulePkg/Library/IniParsingLib/IniParsingLib.uni new file mode 100644 index 0000000..9b198e8 --- /dev/null +++ b/MdeModulePkg/Library/IniParsingLib/IniParsingLib.uni @@ -0,0 +1,22 @@ +// /** @file +// INI configuration parsing library. +// +// This library parses the INI configuration file. +// +// Copyright (c) 2016, Intel Corporation. All rights reserved.
+// +// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the BSD License +// which accompanies this distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php +// +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "INI configuration parsing library." + +#string STR_MODULE_DESCRIPTION #language en-US "This library parses the INI configuration file." + -- 2.7.4.windows.1