REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the SignedCapsulePkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Jian J Wang <jian.j.wang@intel.com>
		
			
				
	
	
		
			1341 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1341 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  This library parses the INI configuration file.
 | 
						|
 | 
						|
  The INI file format is:
 | 
						|
    ================
 | 
						|
    [SectionName]
 | 
						|
    EntryName=EntryValue
 | 
						|
    ================
 | 
						|
 | 
						|
    Where:
 | 
						|
      1) SectionName is an ASCII string. The valid format is [A-Za-z0-9_]+
 | 
						|
      2) EntryName is an ASCII string. The valid format is [A-Za-z0-9_]+
 | 
						|
      3) EntryValue can be:
 | 
						|
         3.1) an ASCII String. The valid format is [A-Za-z0-9_]+
 | 
						|
         3.2) a GUID. The valid format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, where x is [A-Fa-f0-9]
 | 
						|
         3.3) a decimal value. The valid format is [0-9]+
 | 
						|
         3.4) a hexadecimal value. The valid format is 0x[A-Fa-f0-9]+
 | 
						|
      4) '#' or ';' can be used as comment at anywhere.
 | 
						|
      5) TAB(0x20) or SPACE(0x9) can be used as separator.
 | 
						|
      6) LF(\n, 0xA) or CR(\r, 0xD) can be used as line break.
 | 
						|
 | 
						|
  Caution: This module requires additional review when modified.
 | 
						|
  This driver will have external input - INI data file.
 | 
						|
 | 
						|
  OpenIniFile(), PreProcessDataFile(), ProfileGetSection(), ProfileGetEntry()
 | 
						|
  will receive untrusted input and do basic validation.
 | 
						|
 | 
						|
  Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
 | 
						|
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include <Uefi.h>
 | 
						|
#include <Library/BaseLib.h>
 | 
						|
#include <Library/BaseMemoryLib.h>
 | 
						|
#include <Library/DebugLib.h>
 | 
						|
#include <Library/MemoryAllocationLib.h>
 | 
						|
 | 
						|
#define IS_HYPHEN(a)  ((a) == '-')
 | 
						|
#define IS_NULL(a)    ((a) == '\0')
 | 
						|
 | 
						|
// This is default allocation. Reallocation will happen if it is not enough.
 | 
						|
#define MAX_LINE_LENGTH  512
 | 
						|
 | 
						|
typedef struct _INI_SECTION_ITEM SECTION_ITEM;
 | 
						|
struct _INI_SECTION_ITEM {
 | 
						|
  CHAR8           *PtrSection;
 | 
						|
  UINTN           SecNameLen;
 | 
						|
  CHAR8           *PtrEntry;
 | 
						|
  CHAR8           *PtrValue;
 | 
						|
  SECTION_ITEM    *PtrNext;
 | 
						|
};
 | 
						|
 | 
						|
typedef struct _INI_COMMENT_LINE COMMENT_LINE;
 | 
						|
struct _INI_COMMENT_LINE {
 | 
						|
  CHAR8           *PtrComment;
 | 
						|
  COMMENT_LINE    *PtrNext;
 | 
						|
};
 | 
						|
 | 
						|
typedef struct {
 | 
						|
  SECTION_ITEM    *SectionHead;
 | 
						|
  COMMENT_LINE    *CommentHead;
 | 
						|
} INI_PARSING_LIB_CONTEXT;
 | 
						|
 | 
						|
/**
 | 
						|
  Return if the digital char is valid.
 | 
						|
 | 
						|
  @param[in] DigitalChar    The digital char to be checked.
 | 
						|
  @param[in] IncludeHex     If it include HEX char.
 | 
						|
 | 
						|
  @retval TRUE   The digital char is valid.
 | 
						|
  @retval FALSE  The digital char is invalid.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
IsValidDigitalChar (
 | 
						|
  IN CHAR8    DigitalChar,
 | 
						|
  IN BOOLEAN  IncludeHex
 | 
						|
  )
 | 
						|
{
 | 
						|
  if ((DigitalChar >= '0') && (DigitalChar <= '9')) {
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (IncludeHex) {
 | 
						|
    if ((DigitalChar >= 'a') && (DigitalChar <= 'f')) {
 | 
						|
      return TRUE;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((DigitalChar >= 'A') && (DigitalChar <= 'F')) {
 | 
						|
      return TRUE;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Return if the name char is valid.
 | 
						|
 | 
						|
  @param[in] NameChar    The name char to be checked.
 | 
						|
 | 
						|
  @retval TRUE   The name char is valid.
 | 
						|
  @retval FALSE  The name char is invalid.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
IsValidNameChar (
 | 
						|
  IN CHAR8  NameChar
 | 
						|
  )
 | 
						|
{
 | 
						|
  if ((NameChar >= 'a') && (NameChar <= 'z')) {
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((NameChar >= 'A') && (NameChar <= 'Z')) {
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((NameChar >= '0') && (NameChar <= '9')) {
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (NameChar == '_') {
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Return if the digital string is valid.
 | 
						|
 | 
						|
  @param[in] Digital        The digital to be checked.
 | 
						|
  @param[in] Length         The length of digital string in bytes.
 | 
						|
  @param[in] IncludeHex     If it include HEX char.
 | 
						|
 | 
						|
  @retval TRUE   The digital string is valid.
 | 
						|
  @retval FALSE  The digital string is invalid.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
IsValidDigital (
 | 
						|
  IN CHAR8    *Digital,
 | 
						|
  IN UINTN    Length,
 | 
						|
  IN BOOLEAN  IncludeHex
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN  Index;
 | 
						|
 | 
						|
  for (Index = 0; Index < Length; Index++) {
 | 
						|
    if (!IsValidDigitalChar (Digital[Index], IncludeHex)) {
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Return if the decimal string is valid.
 | 
						|
 | 
						|
  @param[in] Decimal The decimal string to be checked.
 | 
						|
  @param[in] Length  The length of decimal string in bytes.
 | 
						|
 | 
						|
  @retval TRUE   The decimal string is valid.
 | 
						|
  @retval FALSE  The decimal string is invalid.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
IsValidDecimalString (
 | 
						|
  IN CHAR8  *Decimal,
 | 
						|
  IN UINTN  Length
 | 
						|
  )
 | 
						|
{
 | 
						|
  return IsValidDigital (Decimal, Length, FALSE);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Return if the hexadecimal string is valid.
 | 
						|
 | 
						|
  @param[in] Hex     The hexadecimal string to be checked.
 | 
						|
  @param[in] Length  The length of hexadecimal string in bytes.
 | 
						|
 | 
						|
  @retval TRUE   The hexadecimal string is valid.
 | 
						|
  @retval FALSE  The hexadecimal string is invalid.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
IsValidHexString (
 | 
						|
  IN CHAR8  *Hex,
 | 
						|
  IN UINTN  Length
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (Length <= 2) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (Hex[0] != '0') {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((Hex[1] != 'x') && (Hex[1] != 'X')) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  return IsValidDigital (&Hex[2], Length - 2, TRUE);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Return if the name string is valid.
 | 
						|
 | 
						|
  @param[in] Name    The name to be checked.
 | 
						|
  @param[in] Length  The length of name string in bytes.
 | 
						|
 | 
						|
  @retval TRUE   The name string is valid.
 | 
						|
  @retval FALSE  The name string is invalid.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
IsValidName (
 | 
						|
  IN CHAR8  *Name,
 | 
						|
  IN UINTN  Length
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN  Index;
 | 
						|
 | 
						|
  for (Index = 0; Index < Length; Index++) {
 | 
						|
    if (!IsValidNameChar (Name[Index])) {
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Return if the value string is valid GUID.
 | 
						|
 | 
						|
  @param[in] Value   The value to be checked.
 | 
						|
  @param[in] Length  The length of value string in bytes.
 | 
						|
 | 
						|
  @retval TRUE   The value string is valid GUID.
 | 
						|
  @retval FALSE  The value string is invalid GUID.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
IsValidGuid (
 | 
						|
  IN CHAR8  *Value,
 | 
						|
  IN UINTN  Length
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (Length != sizeof ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") - 1) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!IS_HYPHEN (Value[8])) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!IS_HYPHEN (Value[13])) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!IS_HYPHEN (Value[18])) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!IS_HYPHEN (Value[23])) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!IsValidDigital (&Value[0], 8, TRUE)) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!IsValidDigital (&Value[9], 4, TRUE)) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!IsValidDigital (&Value[14], 4, TRUE)) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!IsValidDigital (&Value[19], 4, TRUE)) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!IsValidDigital (&Value[24], 12, TRUE)) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Return if the value string is valid.
 | 
						|
 | 
						|
  @param[in] Value    The value to be checked.
 | 
						|
  @param[in] Length  The length of value string in bytes.
 | 
						|
 | 
						|
  @retval TRUE   The name string is valid.
 | 
						|
  @retval FALSE  The name string is invalid.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
IsValidValue (
 | 
						|
  IN CHAR8  *Value,
 | 
						|
  IN UINTN  Length
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (IsValidName (Value, Length) || IsValidGuid (Value, Length)) {
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dump an INI config file context.
 | 
						|
 | 
						|
  @param[in] Context         INI Config file context.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
DumpIniSection (
 | 
						|
  IN VOID  *Context
 | 
						|
  )
 | 
						|
{
 | 
						|
  INI_PARSING_LIB_CONTEXT  *IniContext;
 | 
						|
  SECTION_ITEM             *PtrSection;
 | 
						|
  SECTION_ITEM             *Section;
 | 
						|
 | 
						|
  if (Context == NULL) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  IniContext = Context;
 | 
						|
  Section    = IniContext->SectionHead;
 | 
						|
 | 
						|
  while (Section != NULL) {
 | 
						|
    PtrSection = Section;
 | 
						|
    Section    = Section->PtrNext;
 | 
						|
    if (PtrSection->PtrSection != NULL) {
 | 
						|
      DEBUG ((DEBUG_VERBOSE, "Section - %a\n", PtrSection->PtrSection));
 | 
						|
    }
 | 
						|
 | 
						|
    if (PtrSection->PtrEntry != NULL) {
 | 
						|
      DEBUG ((DEBUG_VERBOSE, "  Entry - %a\n", PtrSection->PtrEntry));
 | 
						|
    }
 | 
						|
 | 
						|
    if (PtrSection->PtrValue != NULL) {
 | 
						|
      DEBUG ((DEBUG_VERBOSE, "  Value - %a\n", PtrSection->PtrValue));
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Copy one line data from buffer data to the line buffer.
 | 
						|
 | 
						|
  @param[in]      Buffer          Buffer data.
 | 
						|
  @param[in]      BufferSize      Buffer Size.
 | 
						|
  @param[in, out] LineBuffer      Line buffer to store the found line data.
 | 
						|
  @param[in, out] 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) || (*PtrBuf == 0x0A)) {
 | 
						|
      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[in, out] Buffer          On input,  buffer data to be trimmed.
 | 
						|
                                  On output, the trimmed buffer.
 | 
						|
  @param[in, out] 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[in]      Buffer          Comment buffer to be added.
 | 
						|
  @param[in]      BufferSize      Size of comment buffer.
 | 
						|
  @param[in, out] 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[in]      Buffer          Section item data buffer.
 | 
						|
  @param[in]      BufferSize      Size of section item.
 | 
						|
  @param[in, out] 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
 | 
						|
  )
 | 
						|
{
 | 
						|
  SECTION_ITEM  *SectionItem;
 | 
						|
  UINTN         Length;
 | 
						|
  UINT8         *PtrBuf;
 | 
						|
  UINT8         *PtrEnd;
 | 
						|
 | 
						|
  ASSERT (BufferSize >= 1);
 | 
						|
  //
 | 
						|
  // The first character of Buffer is '[', now we want for ']'
 | 
						|
  //
 | 
						|
  PtrEnd = (UINT8 *)((UINTN)Buffer + BufferSize - 1);
 | 
						|
  PtrBuf = (UINT8 *)((UINTN)Buffer + 1);
 | 
						|
  while (PtrBuf <= PtrEnd) {
 | 
						|
    if (*PtrBuf == ']') {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    PtrBuf++;
 | 
						|
  }
 | 
						|
 | 
						|
  if (PtrBuf > PtrEnd) {
 | 
						|
    //
 | 
						|
    // Not found. Invalid line
 | 
						|
    //
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  if (PtrBuf <= Buffer + 1) {
 | 
						|
    // Empty name
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // excluding the heading '[' and tailing ']'
 | 
						|
  //
 | 
						|
  Length = PtrBuf - Buffer - 1;
 | 
						|
  ProfileTrim (
 | 
						|
    Buffer + 1,
 | 
						|
    &Length
 | 
						|
    );
 | 
						|
 | 
						|
  //
 | 
						|
  // Invalid line if the section name is null
 | 
						|
  //
 | 
						|
  if (Length == 0) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!IsValidName ((CHAR8 *)Buffer + 1, Length)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  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[in]      Buffer          Section entry data buffer.
 | 
						|
  @param[in]      BufferSize      Size of section entry.
 | 
						|
  @param[in, out] SectionHead     Section item head entry.
 | 
						|
 | 
						|
  @retval EFI_OUT_OF_RESOURCES   No enough memory is allocated.
 | 
						|
  @retval EFI_SUCCESS            Section entry is added.
 | 
						|
  @retval EFI_NOT_FOUND          Section entry is not found.
 | 
						|
  @retval EFI_INVALID_PARAMETER  Section entry is invalid.
 | 
						|
 | 
						|
**/
 | 
						|
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. Invalid line
 | 
						|
    //
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  if (PtrBuf <= Buffer) {
 | 
						|
    // Empty name
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // excluding the tailing '='
 | 
						|
  //
 | 
						|
  Length = PtrBuf - Buffer;
 | 
						|
  ProfileTrim (
 | 
						|
    Buffer,
 | 
						|
    &Length
 | 
						|
    );
 | 
						|
 | 
						|
  //
 | 
						|
  // Invalid line if the entry name is null
 | 
						|
  //
 | 
						|
  if (Length == 0) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!IsValidName ((CHAR8 *)Buffer, Length)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // 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) {
 | 
						|
    FreePool (SectionItem->PtrSection);
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  CopyMem (SectionItem->PtrEntry, Buffer, Length);
 | 
						|
  *(SectionItem->PtrEntry + Length) = '\0';
 | 
						|
 | 
						|
  //
 | 
						|
  // Next search for '#' or ';'
 | 
						|
  //
 | 
						|
  PtrBuf = PtrBuf + 1;
 | 
						|
  Buffer = PtrBuf;
 | 
						|
  while (PtrBuf <= PtrEnd) {
 | 
						|
    if ((*PtrBuf == '#') || (*PtrBuf == ';')) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    PtrBuf++;
 | 
						|
  }
 | 
						|
 | 
						|
  if (PtrBuf <= Buffer) {
 | 
						|
    // Empty name
 | 
						|
    FreePool (SectionItem->PtrEntry);
 | 
						|
    FreePool (SectionItem->PtrSection);
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  Length = PtrBuf - Buffer;
 | 
						|
  ProfileTrim (
 | 
						|
    Buffer,
 | 
						|
    &Length
 | 
						|
    );
 | 
						|
 | 
						|
  //
 | 
						|
  // Invalid line if the entry value is null
 | 
						|
  //
 | 
						|
  if (Length == 0) {
 | 
						|
    FreePool (SectionItem->PtrEntry);
 | 
						|
    FreePool (SectionItem->PtrSection);
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!IsValidValue ((CHAR8 *)Buffer, Length)) {
 | 
						|
    FreePool (SectionItem->PtrEntry);
 | 
						|
    FreePool (SectionItem->PtrSection);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // EntryValue, add a trailing '\0'
 | 
						|
  //
 | 
						|
  SectionItem->PtrValue = AllocatePool (Length + 1);
 | 
						|
  if (SectionItem->PtrValue == NULL) {
 | 
						|
    FreePool (SectionItem->PtrEntry);
 | 
						|
    FreePool (SectionItem->PtrSection);
 | 
						|
    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[in] Section         Section entry list.
 | 
						|
  @param[in] 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[in]  Section         Section entry list.
 | 
						|
  @param[in]  SectionName     Section name.
 | 
						|
  @param[in]  EntryName       Section entry name.
 | 
						|
  @param[out] 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;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Pre process config data buffer into Section entry list and Comment entry list.
 | 
						|
 | 
						|
  @param[in]      DataBuffer      Config raw file buffer.
 | 
						|
  @param[in]      BufferSize      Size of raw buffer.
 | 
						|
  @param[in, out] SectionHead     Pointer to the section entry list.
 | 
						|
  @param[in, out] 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.
 | 
						|
  @retval EFI_NOT_FOUND         Config data buffer is invalid, because Section or Entry is not found.
 | 
						|
  @retval EFI_INVALID_PARAMETER Config data buffer is invalid, because Section or Entry is invalid.
 | 
						|
 | 
						|
**/
 | 
						|
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[in] DataBuffer      Config raw file buffer.
 | 
						|
  @param[in] BufferSize      Size of raw buffer.
 | 
						|
 | 
						|
  @return       Config data buffer is opened and context is returned.
 | 
						|
  @retval NULL  No enough memory is allocated.
 | 
						|
  @retval NULL  Config data buffer is invalid.
 | 
						|
**/
 | 
						|
VOID *
 | 
						|
EFIAPI
 | 
						|
OpenIniFile (
 | 
						|
  IN      UINT8  *DataBuffer,
 | 
						|
  IN      UINTN  BufferSize
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS               Status;
 | 
						|
  INI_PARSING_LIB_CONTEXT  *IniContext;
 | 
						|
 | 
						|
  if ((DataBuffer == NULL) || (BufferSize == 0)) {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  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;
 | 
						|
  }
 | 
						|
 | 
						|
  DEBUG_CODE_BEGIN ();
 | 
						|
  DumpIniSection (IniContext);
 | 
						|
  DEBUG_CODE_END ();
 | 
						|
  return IniContext;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Get section entry string value.
 | 
						|
 | 
						|
  @param[in]  Context         INI Config file context.
 | 
						|
  @param[in]  SectionName     Section name.
 | 
						|
  @param[in]  EntryName       Section entry name.
 | 
						|
  @param[out] 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;
 | 
						|
 | 
						|
  if ((Context == NULL) || (SectionName == NULL) || (EntryName == NULL) || (EntryValue == NULL)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  IniContext = Context;
 | 
						|
 | 
						|
  *EntryValue = NULL;
 | 
						|
  Status      = UpdateGetProfileString (
 | 
						|
                  IniContext->SectionHead,
 | 
						|
                  SectionName,
 | 
						|
                  EntryName,
 | 
						|
                  EntryValue
 | 
						|
                  );
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Get section entry GUID value.
 | 
						|
 | 
						|
  @param[in]  Context         INI Config file context.
 | 
						|
  @param[in]  SectionName     Section name.
 | 
						|
  @param[in]  EntryName       Section entry name.
 | 
						|
  @param[out] 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;
 | 
						|
  RETURN_STATUS  RStatus;
 | 
						|
 | 
						|
  if ((Context == NULL) || (SectionName == NULL) || (EntryName == NULL) || (Guid == NULL)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = GetStringFromDataFile (
 | 
						|
             Context,
 | 
						|
             SectionName,
 | 
						|
             EntryName,
 | 
						|
             &Value
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  ASSERT (Value != NULL);
 | 
						|
  RStatus = AsciiStrToGuid (Value, Guid);
 | 
						|
  if (RETURN_ERROR (RStatus) || (Value[GUID_STRING_LENGTH] != '\0')) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Get section entry decimal UINTN value.
 | 
						|
 | 
						|
  @param[in]  Context         INI Config file context.
 | 
						|
  @param[in]  SectionName     Section name.
 | 
						|
  @param[in]  EntryName       Section entry name.
 | 
						|
  @param[out] 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;
 | 
						|
 | 
						|
  if ((Context == NULL) || (SectionName == NULL) || (EntryName == NULL) || (Data == NULL)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = GetStringFromDataFile (
 | 
						|
             Context,
 | 
						|
             SectionName,
 | 
						|
             EntryName,
 | 
						|
             &Value
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  ASSERT (Value != NULL);
 | 
						|
  if (!IsValidDecimalString (Value, AsciiStrLen (Value))) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  *Data = AsciiStrDecimalToUintn (Value);
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Get section entry hexadecimal UINTN value.
 | 
						|
 | 
						|
  @param[in]  Context         INI Config file context.
 | 
						|
  @param[in]  SectionName     Section name.
 | 
						|
  @param[in]  EntryName       Section entry name.
 | 
						|
  @param[out] Data            Point to the got hexadecimal UINTN value.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS    Section entry hexadecimal 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;
 | 
						|
 | 
						|
  if ((Context == NULL) || (SectionName == NULL) || (EntryName == NULL) || (Data == NULL)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = GetStringFromDataFile (
 | 
						|
             Context,
 | 
						|
             SectionName,
 | 
						|
             EntryName,
 | 
						|
             &Value
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  ASSERT (Value != NULL);
 | 
						|
  if (!IsValidHexString (Value, AsciiStrLen (Value))) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  *Data = AsciiStrHexToUintn (Value);
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Get section entry hexadecimal UINT64 value.
 | 
						|
 | 
						|
  @param[in]  Context         INI Config file context.
 | 
						|
  @param[in]  SectionName     Section name.
 | 
						|
  @param[in]  EntryName       Section entry name.
 | 
						|
  @param[out] Data            Point to the got hexadecimal UINT64 value.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS    Section entry hexadecimal 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;
 | 
						|
 | 
						|
  if ((Context == NULL) || (SectionName == NULL) || (EntryName == NULL) || (Data == NULL)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = GetStringFromDataFile (
 | 
						|
             Context,
 | 
						|
             SectionName,
 | 
						|
             EntryName,
 | 
						|
             &Value
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  ASSERT (Value != NULL);
 | 
						|
  if (!IsValidHexString (Value, AsciiStrLen (Value))) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  *Data = AsciiStrHexToUint64 (Value);
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Close an INI config file and free the context.
 | 
						|
 | 
						|
  @param[in] Context         INI Config file context.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
CloseIniFile (
 | 
						|
  IN      VOID  *Context
 | 
						|
  )
 | 
						|
{
 | 
						|
  INI_PARSING_LIB_CONTEXT  *IniContext;
 | 
						|
 | 
						|
  if (Context == NULL) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  IniContext = Context;
 | 
						|
  FreeAllList (IniContext->SectionHead, IniContext->CommentHead);
 | 
						|
 | 
						|
  return;
 | 
						|
}
 |