git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9257 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			2880 lines
		
	
	
		
			70 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			2880 lines
		
	
	
		
			70 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/** @file
 | 
						|
  
 | 
						|
  Vfr common library functions.
 | 
						|
 | 
						|
Copyright (c) 2004 - 2008, 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 "stdio.h"
 | 
						|
#include "stdlib.h"
 | 
						|
#include "VfrUtilityLib.h"
 | 
						|
#include "VfrFormPkg.h"
 | 
						|
 | 
						|
VOID
 | 
						|
CVfrBinaryOutput::WriteLine (
 | 
						|
  IN FILE   *pFile,
 | 
						|
  IN UINT32 LineBytes,
 | 
						|
  IN CHAR8  *LineHeader,
 | 
						|
  IN CHAR8  *BlkBuf,
 | 
						|
  IN UINT32 BlkSize
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32    Index;
 | 
						|
 | 
						|
  if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  for (Index = 0; Index < BlkSize; Index++) {
 | 
						|
    if ((Index % LineBytes) == 0) {
 | 
						|
      fprintf (pFile, "\n%s", LineHeader);
 | 
						|
    }
 | 
						|
    fprintf (pFile, "0x%02X,  ", (UINT8)BlkBuf[Index]);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CVfrBinaryOutput::WriteEnd (
 | 
						|
  IN FILE   *pFile,
 | 
						|
  IN UINT32 LineBytes,
 | 
						|
  IN CHAR8  *LineHeader,
 | 
						|
  IN CHAR8  *BlkBuf,
 | 
						|
  IN UINT32 BlkSize
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32    Index;
 | 
						|
 | 
						|
  if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  for (Index = 0; Index < BlkSize - 1; Index++) {
 | 
						|
    if ((Index % LineBytes) == 0) {
 | 
						|
      fprintf (pFile, "\n%s", LineHeader);
 | 
						|
    }
 | 
						|
    fprintf (pFile, "0x%02X,  ", (UINT8)BlkBuf[Index]);
 | 
						|
  }
 | 
						|
 | 
						|
  if ((Index % LineBytes) == 0) {
 | 
						|
    fprintf (pFile, "\n%s", LineHeader);
 | 
						|
  }
 | 
						|
  fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);
 | 
						|
}
 | 
						|
 | 
						|
SConfigInfo::SConfigInfo (
 | 
						|
  IN UINT8              Type, 
 | 
						|
  IN UINT16             Offset, 
 | 
						|
  IN UINT32             Width, 
 | 
						|
  IN EFI_IFR_TYPE_VALUE Value
 | 
						|
  )
 | 
						|
{
 | 
						|
  mNext   = NULL;
 | 
						|
  mOffset = Offset;
 | 
						|
  mWidth  = (UINT16)Width;
 | 
						|
  mValue  = new UINT8[mWidth];
 | 
						|
  if (mValue == NULL) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  switch (Type) {
 | 
						|
  case EFI_IFR_TYPE_NUM_SIZE_8 :
 | 
						|
    memcpy (mValue, &Value.u8, mWidth);
 | 
						|
    break;
 | 
						|
  case EFI_IFR_TYPE_NUM_SIZE_16 :
 | 
						|
    memcpy (mValue, &Value.u16, mWidth);
 | 
						|
    break;
 | 
						|
  case EFI_IFR_TYPE_NUM_SIZE_32 :
 | 
						|
    memcpy (mValue, &Value.u32, mWidth);
 | 
						|
    break;
 | 
						|
  case EFI_IFR_TYPE_NUM_SIZE_64 :
 | 
						|
    memcpy (mValue, &Value.u64, mWidth);
 | 
						|
    break;
 | 
						|
  case EFI_IFR_TYPE_BOOLEAN :
 | 
						|
    memcpy (mValue, &Value.b, mWidth);
 | 
						|
    break;
 | 
						|
  case EFI_IFR_TYPE_TIME :
 | 
						|
    memcpy (mValue, &Value.time, mWidth);
 | 
						|
    break;
 | 
						|
  case EFI_IFR_TYPE_DATE :
 | 
						|
    memcpy (mValue, &Value.date, mWidth);
 | 
						|
    break;
 | 
						|
  case EFI_IFR_TYPE_STRING :
 | 
						|
    memcpy (mValue, &Value.string, mWidth);
 | 
						|
    break;
 | 
						|
  case EFI_IFR_TYPE_OTHER :
 | 
						|
    return;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
SConfigInfo::~SConfigInfo (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  BUFFER_SAFE_FREE (mValue);
 | 
						|
}
 | 
						|
 | 
						|
SConfigItem::SConfigItem (
 | 
						|
  IN CHAR8               *Name,
 | 
						|
  IN CHAR8               *Id
 | 
						|
  )
 | 
						|
{
 | 
						|
  mName          = NULL;
 | 
						|
  mId            = 0;
 | 
						|
  mInfoStrList = NULL;
 | 
						|
  mNext        = NULL;
 | 
						|
 | 
						|
  if (Name != NULL) {
 | 
						|
    if ((mName = new CHAR8[strlen (Name) + 1]) != NULL) {
 | 
						|
      strcpy (mName, Name);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (Id != NULL) {
 | 
						|
    if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) {
 | 
						|
      strcpy (mId, Id);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
SConfigItem::SConfigItem (
 | 
						|
  IN CHAR8               *Name,
 | 
						|
  IN CHAR8               *Id,
 | 
						|
  IN UINT8               Type,
 | 
						|
  IN UINT16              Offset,
 | 
						|
  IN UINT16              Width,
 | 
						|
  IN EFI_IFR_TYPE_VALUE  Value
 | 
						|
  )
 | 
						|
{
 | 
						|
  mName        = NULL;
 | 
						|
  mId          = NULL;
 | 
						|
  mInfoStrList = NULL;
 | 
						|
  mNext        = NULL;
 | 
						|
 | 
						|
  if (Name != NULL) {
 | 
						|
    if ((mName = new CHAR8[strlen (Name) + 1]) != NULL) {
 | 
						|
      strcpy (mName, Name);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (Id != NULL) {
 | 
						|
    if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) {
 | 
						|
      strcpy (mId, Id);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  mInfoStrList = new SConfigInfo(Type, Offset, Width, Value);
 | 
						|
}
 | 
						|
 | 
						|
SConfigItem::~SConfigItem (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  SConfigInfo  *Info;
 | 
						|
 | 
						|
  BUFFER_SAFE_FREE (mName);
 | 
						|
  BUFFER_SAFE_FREE (mId);
 | 
						|
  while (mInfoStrList != NULL) {
 | 
						|
    Info = mInfoStrList;
 | 
						|
    mInfoStrList = mInfoStrList->mNext;
 | 
						|
 | 
						|
    BUFFER_SAFE_FREE (Info);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
UINT8
 | 
						|
CVfrBufferConfig::Register (
 | 
						|
  IN CHAR8               *Name,
 | 
						|
  IN CHAR8               *Id
 | 
						|
  )
 | 
						|
{
 | 
						|
  SConfigItem *pNew;
 | 
						|
 | 
						|
  if (Select (Name) == 0) {
 | 
						|
    return 1;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((pNew = new SConfigItem (Name, Id)) == NULL) {
 | 
						|
    return 2;
 | 
						|
  }
 | 
						|
  if (mItemListHead == NULL) {
 | 
						|
    mItemListHead = pNew;
 | 
						|
    mItemListTail = pNew;
 | 
						|
  } else {
 | 
						|
    mItemListTail->mNext = pNew;
 | 
						|
    mItemListTail = pNew;
 | 
						|
  }
 | 
						|
  mItemListPos    = pNew;
 | 
						|
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CVfrBufferConfig::Open (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  mItemListPos = mItemListHead;
 | 
						|
}
 | 
						|
 | 
						|
BOOLEAN
 | 
						|
CVfrBufferConfig::Eof(
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  return (mItemListPos == NULL) ? TRUE : FALSE;
 | 
						|
}
 | 
						|
 | 
						|
UINT8
 | 
						|
CVfrBufferConfig::Select (
 | 
						|
  IN CHAR8 *Name,
 | 
						|
  IN CHAR8 *Id
 | 
						|
  )
 | 
						|
{
 | 
						|
  SConfigItem *p;
 | 
						|
 | 
						|
  if (Name == NULL) {
 | 
						|
    mItemListPos = mItemListHead;
 | 
						|
    return 0;
 | 
						|
  } else {
 | 
						|
    for (p = mItemListHead; p != NULL; p = p->mNext) {
 | 
						|
      if (strcmp (p->mName, Name) != 0) {
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
 | 
						|
      if (Id != NULL) {
 | 
						|
        if (p->mId == NULL || strcmp (p->mId, Id) != 0) {
 | 
						|
          continue;
 | 
						|
        }
 | 
						|
      } else if (p->mId != NULL) {
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
 | 
						|
      mItemListPos = p;
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return 1;
 | 
						|
}
 | 
						|
 | 
						|
UINT8
 | 
						|
CVfrBufferConfig::Write (
 | 
						|
  IN CONST CHAR8         Mode,
 | 
						|
  IN CHAR8               *Name,
 | 
						|
  IN CHAR8               *Id,
 | 
						|
  IN UINT8               Type,
 | 
						|
  IN UINT16              Offset,
 | 
						|
  IN UINT32              Width,
 | 
						|
  IN EFI_IFR_TYPE_VALUE  Value
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT8         Ret;
 | 
						|
  SConfigItem   *pItem;
 | 
						|
  SConfigInfo   *pInfo;
 | 
						|
 | 
						|
  if ((Ret = Select (Name)) != 0) {
 | 
						|
    return Ret;
 | 
						|
  }
 | 
						|
 | 
						|
  switch (Mode) {
 | 
						|
  case 'a' : // add
 | 
						|
    if (Select (Name, Id) != 0) {
 | 
						|
      if ((pItem = new SConfigItem (Name, Id, Type, Offset, Width, Value)) == NULL) {
 | 
						|
        return 2;
 | 
						|
      }
 | 
						|
      if (mItemListHead == NULL) {
 | 
						|
        mItemListHead = pItem;
 | 
						|
        mItemListTail = pItem;
 | 
						|
      } else {
 | 
						|
        mItemListTail->mNext = pItem;
 | 
						|
        mItemListTail = pItem;
 | 
						|
      }
 | 
						|
      mItemListPos = pItem;
 | 
						|
    } else {
 | 
						|
      // tranverse the list to find out if there's already the value for the same offset
 | 
						|
      for (pInfo = mItemListPos->mInfoStrList; pInfo != NULL; pInfo = pInfo->mNext) {
 | 
						|
        if (pInfo->mOffset == Offset) {
 | 
						|
          // check if the value and width are the same; return error if not
 | 
						|
          if ((Id != NULL) && (pInfo->mWidth != Width || memcmp(pInfo->mValue, &Value, Width) != 0)) {
 | 
						|
            return VFR_RETURN_DEFAULT_VALUE_REDEFINED;
 | 
						|
          }
 | 
						|
          return 0;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      if((pInfo = new SConfigInfo (Type, Offset, Width, Value)) == NULL) {
 | 
						|
        return 2;
 | 
						|
      }
 | 
						|
      pInfo->mNext = mItemListPos->mInfoStrList;
 | 
						|
      mItemListPos->mInfoStrList = pInfo;
 | 
						|
    }
 | 
						|
    break;
 | 
						|
 | 
						|
  case 'd' : // delete
 | 
						|
    if (mItemListHead == mItemListPos) {
 | 
						|
      mItemListHead = mItemListPos->mNext;
 | 
						|
      delete mItemListPos;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    for (pItem = mItemListHead; pItem->mNext != mItemListPos; pItem = pItem->mNext)
 | 
						|
      ;
 | 
						|
 | 
						|
    pItem->mNext = mItemListPos->mNext;
 | 
						|
    if (mItemListTail == mItemListPos) {
 | 
						|
      mItemListTail = pItem;
 | 
						|
    }
 | 
						|
    delete mItemListPos;
 | 
						|
    mItemListPos = pItem->mNext;
 | 
						|
    break;
 | 
						|
 | 
						|
  case 'i' : // set info
 | 
						|
    if (mItemListPos->mId != NULL) {
 | 
						|
      delete mItemListPos->mId;
 | 
						|
    }
 | 
						|
    mItemListPos->mId = NULL;
 | 
						|
    if (Id != NULL) {
 | 
						|
      if ((mItemListPos->mId = new CHAR8[strlen (Id) + 1]) == NULL) {
 | 
						|
        return 2;
 | 
						|
      }
 | 
						|
      strcpy (mItemListPos->mId, Id);
 | 
						|
    }
 | 
						|
    break;
 | 
						|
 | 
						|
  default :
 | 
						|
    return 1;
 | 
						|
  }
 | 
						|
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
VOID
 | 
						|
CVfrBufferConfig::Close (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  mItemListPos = NULL;
 | 
						|
}
 | 
						|
 | 
						|
#define BYTES_PRE_LINE 0x10
 | 
						|
 | 
						|
VOID
 | 
						|
CVfrBufferConfig::OutputCFile (
 | 
						|
  IN FILE  *pFile,
 | 
						|
  IN CHAR8 *BaseName
 | 
						|
  )
 | 
						|
{
 | 
						|
  CVfrBinaryOutput Output;
 | 
						|
  SConfigItem      *Item;
 | 
						|
  SConfigInfo      *Info;
 | 
						|
  UINT32           TotalLen;
 | 
						|
 | 
						|
  if (pFile == NULL) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  for (Item = mItemListHead; Item != NULL; Item = Item->mNext) {
 | 
						|
    if (Item->mId != NULL || Item->mInfoStrList == NULL) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
    fprintf (pFile, "\nunsigned char %s%sBlockName[] = {", BaseName, Item->mName);
 | 
						|
 | 
						|
    TotalLen = sizeof (UINT32);
 | 
						|
    for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
 | 
						|
      TotalLen += sizeof (UINT16) * 2;
 | 
						|
    }
 | 
						|
    Output.WriteLine (pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)&TotalLen, sizeof (UINT32));
 | 
						|
 | 
						|
    for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
 | 
						|
      fprintf (pFile, "\n");
 | 
						|
      Output.WriteLine (pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)&Info->mOffset, sizeof (UINT16));
 | 
						|
      Output.WriteLine (pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)&Info->mWidth, sizeof (UINT16));
 | 
						|
    }
 | 
						|
    fprintf (pFile, "\n};\n");
 | 
						|
  }
 | 
						|
 | 
						|
  for (Item = mItemListHead; Item != NULL; Item = Item->mNext) {
 | 
						|
    if (Item->mId != NULL && Item->mInfoStrList != NULL) {
 | 
						|
      fprintf (pFile, "\nunsigned char %s%sDefault%s[] = {", BaseName, Item->mName, Item->mId);
 | 
						|
 | 
						|
      TotalLen = sizeof (UINT32);
 | 
						|
      for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
 | 
						|
        TotalLen += Info->mWidth + sizeof (UINT16) * 2;
 | 
						|
      }
 | 
						|
      Output.WriteLine (pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)&TotalLen, sizeof (UINT32));
 | 
						|
 | 
						|
      for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
 | 
						|
        fprintf (pFile, "\n");
 | 
						|
        Output.WriteLine (pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)&Info->mOffset, sizeof (UINT16));
 | 
						|
        Output.WriteLine (pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)&Info->mWidth, sizeof (UINT16));
 | 
						|
        if (Info->mNext == NULL) {
 | 
						|
          Output.WriteEnd (pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)Info->mValue, Info->mWidth);
 | 
						|
        } else {
 | 
						|
          Output.WriteLine (pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)Info->mValue, Info->mWidth);
 | 
						|
        }
 | 
						|
      }
 | 
						|
      fprintf (pFile, "\n};\n");
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
CVfrBufferConfig::CVfrBufferConfig (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  mItemListHead = NULL;
 | 
						|
  mItemListTail = NULL;
 | 
						|
  mItemListPos  = NULL;
 | 
						|
}
 | 
						|
 | 
						|
CVfrBufferConfig::~CVfrBufferConfig (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  SConfigItem *p;
 | 
						|
 | 
						|
  while (mItemListHead != NULL) {
 | 
						|
    p = mItemListHead;
 | 
						|
    mItemListHead = mItemListHead->mNext;
 | 
						|
    delete p;
 | 
						|
  }
 | 
						|
 | 
						|
  mItemListHead = NULL;
 | 
						|
  mItemListTail = NULL;
 | 
						|
  mItemListPos  = NULL;
 | 
						|
}
 | 
						|
 | 
						|
CVfrBufferConfig gCVfrBufferConfig;
 | 
						|
 | 
						|
static struct {
 | 
						|
  CHAR8  *mTypeName;
 | 
						|
  UINT8  mType;
 | 
						|
  UINT32 mSize;
 | 
						|
  UINT32 mAlign;
 | 
						|
} gInternalTypesTable [] = {
 | 
						|
  {"UINT64",        EFI_IFR_TYPE_NUM_SIZE_64, sizeof (UINT64),       sizeof (UINT64)},
 | 
						|
  {"UINT32",        EFI_IFR_TYPE_NUM_SIZE_32, sizeof (UINT32),       sizeof (UINT32)},
 | 
						|
  {"UINT16",        EFI_IFR_TYPE_NUM_SIZE_16, sizeof (UINT16),       sizeof (UINT16)},
 | 
						|
  {"UINT8",         EFI_IFR_TYPE_NUM_SIZE_8,  sizeof (UINT8),        sizeof (UINT8)},
 | 
						|
  {"BOOLEAN",       EFI_IFR_TYPE_BOOLEAN,     sizeof (BOOLEAN),      sizeof (BOOLEAN)},
 | 
						|
  {"EFI_HII_DATE",  EFI_IFR_TYPE_DATE,        sizeof (EFI_HII_DATE), sizeof (UINT16)},
 | 
						|
  {"EFI_STRING_ID", EFI_IFR_TYPE_STRING,      sizeof (EFI_STRING_ID),sizeof (EFI_STRING_ID)},
 | 
						|
  {"EFI_HII_TIME",  EFI_IFR_TYPE_TIME,        sizeof (EFI_HII_TIME), sizeof (UINT8)},
 | 
						|
  {NULL,            EFI_IFR_TYPE_OTHER,       0,                     0}
 | 
						|
};
 | 
						|
 | 
						|
STATIC
 | 
						|
BOOLEAN
 | 
						|
_IS_INTERNAL_TYPE (
 | 
						|
  IN CHAR8 *TypeName
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32  Index;
 | 
						|
 | 
						|
  if (TypeName == NULL) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {
 | 
						|
    if (strcmp (TypeName, gInternalTypesTable[Index].mTypeName) == 0) {
 | 
						|
      return TRUE;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
CHAR8 *
 | 
						|
TrimHex (
 | 
						|
  IN  CHAR8   *Str,
 | 
						|
  OUT bool    *IsHex
 | 
						|
  )
 | 
						|
{
 | 
						|
  *IsHex = FALSE;
 | 
						|
 | 
						|
  while (*Str && *Str == ' ') {
 | 
						|
    Str++;
 | 
						|
  }
 | 
						|
  while (*Str && *Str == '0') {
 | 
						|
    Str++;
 | 
						|
  }
 | 
						|
  if (*Str && (*Str == 'x' || *Str == 'X')) {
 | 
						|
    Str++;
 | 
						|
    *IsHex = TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  return Str;
 | 
						|
}
 | 
						|
 | 
						|
UINT32
 | 
						|
_STR2U32 (
 | 
						|
  IN CHAR8 *Str
 | 
						|
  )
 | 
						|
{
 | 
						|
  bool    IsHex;
 | 
						|
  UINT32  Value;
 | 
						|
  CHAR8    c;
 | 
						|
 | 
						|
  Str = TrimHex (Str, &IsHex);
 | 
						|
  for (Value = 0; (c = *Str) != '\0'; Str++) {
 | 
						|
    //
 | 
						|
    // BUG: does not handle overflow here
 | 
						|
    //
 | 
						|
	(IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);
 | 
						|
 | 
						|
    if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) {
 | 
						|
      Value += (c - 'a' + 10);
 | 
						|
    }
 | 
						|
    if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) {
 | 
						|
      Value += (c - 'A' + 10);
 | 
						|
    }
 | 
						|
    if (c >= '0' && c <= '9') {
 | 
						|
      Value += (c - '0');
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return Value;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CVfrVarDataTypeDB::RegisterNewType (
 | 
						|
  IN SVfrDataType  *New
 | 
						|
  )
 | 
						|
{
 | 
						|
  New->mNext               = mDataTypeList;
 | 
						|
  mDataTypeList            = New;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrVarDataTypeDB::ExtractStructTypeName (
 | 
						|
  IN  CHAR8 *&VarStr,
 | 
						|
  OUT CHAR8 *TName
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (TName == NULL) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  while((*VarStr != '\0') && (*VarStr != '.')) {
 | 
						|
    *TName = *VarStr;
 | 
						|
    VarStr++;
 | 
						|
    TName++;
 | 
						|
  }
 | 
						|
  *TName = '\0';
 | 
						|
  if (*VarStr == '.') {
 | 
						|
    VarStr++;
 | 
						|
  }
 | 
						|
 | 
						|
  return VFR_RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrVarDataTypeDB::ExtractFieldNameAndArrary (
 | 
						|
  IN  CHAR8   *&VarStr,
 | 
						|
  IN  CHAR8   *FName,
 | 
						|
  OUT UINT32 &ArrayIdx
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32 Idx;
 | 
						|
  CHAR8   ArrayStr[MAX_NAME_LEN + 1];
 | 
						|
 | 
						|
  ArrayIdx = INVALID_ARRAY_INDEX;
 | 
						|
 | 
						|
  if (FName == NULL) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  while((*VarStr != '\0') &&
 | 
						|
        (*VarStr != '.') &&
 | 
						|
        (*VarStr != '[') &&
 | 
						|
        (*VarStr != ']')) {
 | 
						|
    *FName = *VarStr;
 | 
						|
    VarStr++;
 | 
						|
    FName++;
 | 
						|
  }
 | 
						|
  *FName = '\0';
 | 
						|
 | 
						|
  switch (*VarStr) {
 | 
						|
  case '.' :
 | 
						|
    VarStr++;
 | 
						|
  case '\0':
 | 
						|
    return VFR_RETURN_SUCCESS;
 | 
						|
  case '[' :
 | 
						|
    VarStr++;
 | 
						|
    for (Idx = 0; (Idx < MAX_NAME_LEN) && (*VarStr != '\0') && (*VarStr != ']'); VarStr++, Idx++) {
 | 
						|
      ArrayStr[Idx] = *VarStr;
 | 
						|
    }
 | 
						|
    ArrayStr[Idx] = '\0';
 | 
						|
 | 
						|
    if ((*VarStr != ']') && (ArrayStr[0] == '\0')) {
 | 
						|
      return VFR_RETURN_DATA_STRING_ERROR;
 | 
						|
    }
 | 
						|
    ArrayIdx = _STR2U32 (ArrayStr);
 | 
						|
    if (*VarStr == ']') {
 | 
						|
      VarStr++;
 | 
						|
    }
 | 
						|
    return VFR_RETURN_SUCCESS;
 | 
						|
  case ']':
 | 
						|
    return VFR_RETURN_DATA_STRING_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  return VFR_RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrVarDataTypeDB::GetTypeField (
 | 
						|
  IN  CHAR8          *FName,
 | 
						|
  IN  SVfrDataType  *Type,
 | 
						|
  OUT SVfrDataField *&Field
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrDataField  *pField = NULL;
 | 
						|
 | 
						|
  if ((FName == NULL) && (Type == NULL)) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  for (pField = Type->mMembers; pField != NULL; pField = pField->mNext) {
 | 
						|
    if (strcmp (pField->mFieldName, FName) == 0) {
 | 
						|
      Field = pField;
 | 
						|
      return VFR_RETURN_SUCCESS;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return VFR_RETURN_UNDEFINED;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrVarDataTypeDB::GetFieldOffset (
 | 
						|
  IN  SVfrDataField *Field,
 | 
						|
  IN  UINT32        ArrayIdx,
 | 
						|
  OUT UINT32        &Offset
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (Field == NULL) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
  
 | 
						|
  //
 | 
						|
  // Framework Vfr file Array Index is from 1.
 | 
						|
  // But Uefi Vfr file Array Index is from 0.
 | 
						|
  //
 | 
						|
  if (VfrCompatibleMode && ArrayIdx != INVALID_ARRAY_INDEX) {
 | 
						|
    if (ArrayIdx == 0) {
 | 
						|
      return VFR_RETURN_ERROR_ARRARY_NUM;
 | 
						|
    }
 | 
						|
    ArrayIdx = ArrayIdx - 1;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((ArrayIdx != INVALID_ARRAY_INDEX) && ((Field->mArrayNum == 0) || (Field->mArrayNum <= ArrayIdx))) {
 | 
						|
    return VFR_RETURN_ERROR_ARRARY_NUM;
 | 
						|
  }
 | 
						|
  
 | 
						|
  //
 | 
						|
  // Be compatible with the current usage
 | 
						|
  // If ArraryIdx is not specified, the first one is used.
 | 
						|
  //
 | 
						|
  // if ArrayNum is larger than zero, ArraryIdx must be specified.
 | 
						|
  //
 | 
						|
  // if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum > 0)) {
 | 
						|
  //   return VFR_RETURN_ERROR_ARRARY_NUM;
 | 
						|
  // }
 | 
						|
  //
 | 
						|
 | 
						|
  Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx);
 | 
						|
  return VFR_RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
UINT8
 | 
						|
CVfrVarDataTypeDB::GetFieldWidth (
 | 
						|
  IN SVfrDataField *Field
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (Field == NULL) {
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  return Field->mFieldType->mType;
 | 
						|
}
 | 
						|
 | 
						|
UINT32
 | 
						|
CVfrVarDataTypeDB::GetFieldSize (
 | 
						|
  IN SVfrDataField *Field,
 | 
						|
  IN UINT32       ArrayIdx
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (Field == NULL) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum != 0)) {
 | 
						|
    return Field->mFieldType->mTotalSize * Field->mArrayNum;
 | 
						|
  } else {
 | 
						|
    return Field->mFieldType->mTotalSize;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CVfrVarDataTypeDB::InternalTypesListInit (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrDataType *New   = NULL;
 | 
						|
  UINT32       Index;
 | 
						|
 | 
						|
  for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {
 | 
						|
    New                 = new SVfrDataType;
 | 
						|
    if (New != NULL) {
 | 
						|
      strcpy (New->mTypeName, gInternalTypesTable[Index].mTypeName);
 | 
						|
      New->mType        = gInternalTypesTable[Index].mType;
 | 
						|
      New->mAlign       = gInternalTypesTable[Index].mAlign;
 | 
						|
      New->mTotalSize   = gInternalTypesTable[Index].mSize;
 | 
						|
      if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_DATE") == 0) {
 | 
						|
        SVfrDataField *pYearField  = new SVfrDataField;
 | 
						|
        SVfrDataField *pMonthField = new SVfrDataField;
 | 
						|
        SVfrDataField *pDayField   = new SVfrDataField;
 | 
						|
 | 
						|
        strcpy (pYearField->mFieldName, "Year");
 | 
						|
        GetDataType ("UINT8", &pYearField->mFieldType);
 | 
						|
        pYearField->mOffset      = 0;
 | 
						|
        pYearField->mNext        = pMonthField;
 | 
						|
        pYearField->mArrayNum    = 0;
 | 
						|
 | 
						|
        strcpy (pMonthField->mFieldName, "Month");
 | 
						|
        GetDataType ("UINT8", &pMonthField->mFieldType);
 | 
						|
        pMonthField->mOffset     = 1;
 | 
						|
        pMonthField->mNext       = pDayField;
 | 
						|
        pMonthField->mArrayNum   = 0;
 | 
						|
 | 
						|
        strcpy (pDayField->mFieldName, "Day");
 | 
						|
        GetDataType ("UINT8", &pDayField->mFieldType);
 | 
						|
        pDayField->mOffset       = 2;
 | 
						|
        pDayField->mNext         = NULL;
 | 
						|
        pDayField->mArrayNum     = 0;
 | 
						|
 | 
						|
        New->mMembers            = pYearField;
 | 
						|
      } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_TIME") == 0) {
 | 
						|
        SVfrDataField *pHoursField   = new SVfrDataField;
 | 
						|
        SVfrDataField *pMinutesField = new SVfrDataField;
 | 
						|
        SVfrDataField *pSecondsField = new SVfrDataField;
 | 
						|
 | 
						|
        strcpy (pHoursField->mFieldName, "Hours");
 | 
						|
        GetDataType ("UINT8", &pHoursField->mFieldType);
 | 
						|
        pHoursField->mOffset     = 0;
 | 
						|
        pHoursField->mNext       = pMinutesField;
 | 
						|
        pHoursField->mArrayNum   = 0;
 | 
						|
 | 
						|
        strcpy (pMinutesField->mFieldName, "Minutes");
 | 
						|
        GetDataType ("UINT8", &pMinutesField->mFieldType);
 | 
						|
        pMinutesField->mOffset   = 1;
 | 
						|
        pMinutesField->mNext     = pSecondsField;
 | 
						|
        pMinutesField->mArrayNum = 0;
 | 
						|
 | 
						|
        strcpy (pSecondsField->mFieldName, "Seconds");
 | 
						|
        GetDataType ("UINT8", &pSecondsField->mFieldType);
 | 
						|
        pSecondsField->mOffset   = 2;
 | 
						|
        pSecondsField->mNext     = NULL;
 | 
						|
        pSecondsField->mArrayNum = 0;
 | 
						|
 | 
						|
        New->mMembers            = pHoursField;
 | 
						|
      } else {
 | 
						|
        New->mMembers            = NULL;
 | 
						|
      }
 | 
						|
      New->mNext                 = NULL;
 | 
						|
      RegisterNewType (New);
 | 
						|
      New                        = NULL;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
CVfrVarDataTypeDB::CVfrVarDataTypeDB (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  mDataTypeList  = NULL;
 | 
						|
  mNewDataType   = NULL;
 | 
						|
  mCurrDataField = NULL;
 | 
						|
  mPackAlign     = DEFAULT_PACK_ALIGN;
 | 
						|
  mPackStack     = NULL;
 | 
						|
  mFirstNewDataTypeName = NULL;
 | 
						|
 | 
						|
  InternalTypesListInit ();
 | 
						|
}
 | 
						|
 | 
						|
CVfrVarDataTypeDB::~CVfrVarDataTypeDB (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrDataType      *pType;
 | 
						|
  SVfrDataField     *pField;
 | 
						|
  SVfrPackStackNode *pPack;
 | 
						|
 | 
						|
  if (mNewDataType != NULL) {
 | 
						|
    delete mNewDataType;
 | 
						|
  }
 | 
						|
 | 
						|
  while (mDataTypeList != NULL) {
 | 
						|
    pType = mDataTypeList;
 | 
						|
    mDataTypeList = mDataTypeList->mNext;
 | 
						|
    while(pType->mMembers != NULL) {
 | 
						|
      pField = pType->mMembers;
 | 
						|
      pType->mMembers = pType->mMembers->mNext;
 | 
						|
      delete pField;
 | 
						|
    }
 | 
						|
	delete pType;
 | 
						|
  }
 | 
						|
 | 
						|
  while (mPackStack != NULL) {
 | 
						|
    pPack = mPackStack;
 | 
						|
    mPackStack = mPackStack->mNext;
 | 
						|
    delete pPack;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrVarDataTypeDB::Pack (
 | 
						|
  IN UINT32         LineNum,
 | 
						|
  IN UINT8          Action,
 | 
						|
  IN CHAR8           *Identifier,
 | 
						|
  IN UINT32         Number
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32            PackAlign;
 | 
						|
  CHAR8             Msg[MAX_STRING_LEN] = {0, };
 | 
						|
 | 
						|
  if (Action & VFR_PACK_SHOW) {
 | 
						|
    sprintf (Msg, "value of pragma pack(show) == %d", mPackAlign);
 | 
						|
    gCVfrErrorHandle.PrintMsg (LineNum, "", "Warning", Msg);
 | 
						|
  }
 | 
						|
 | 
						|
  if (Action & VFR_PACK_PUSH) {
 | 
						|
    SVfrPackStackNode *pNew = NULL;
 | 
						|
 | 
						|
    if ((pNew = new SVfrPackStackNode (Identifier, mPackAlign)) == NULL) {
 | 
						|
      return VFR_RETURN_FATAL_ERROR;
 | 
						|
    }
 | 
						|
    pNew->mNext = mPackStack;
 | 
						|
    mPackStack  = pNew;
 | 
						|
  }
 | 
						|
 | 
						|
  if (Action & VFR_PACK_POP) {
 | 
						|
    SVfrPackStackNode *pNode = NULL;
 | 
						|
 | 
						|
    if (mPackStack == NULL) {
 | 
						|
      gCVfrErrorHandle.PrintMsg (LineNum, "", "Error", "#pragma pack(pop...) : more pops than pushes");
 | 
						|
    }
 | 
						|
 | 
						|
    for (pNode = mPackStack; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
      if (pNode->Match (Identifier) == TRUE) {
 | 
						|
        mPackAlign = pNode->mNumber;
 | 
						|
        mPackStack = pNode->mNext;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (Action & VFR_PACK_ASSIGN) {
 | 
						|
    PackAlign = (Number > 1) ? Number + Number % 2 : Number;
 | 
						|
    if ((PackAlign == 0) || (PackAlign > 16)) {
 | 
						|
      gCVfrErrorHandle.PrintMsg (LineNum, "", "Error", "expected pragma parameter to be '1', '2', '4', '8', or '16'");
 | 
						|
    } else {
 | 
						|
      mPackAlign = PackAlign;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return VFR_RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CVfrVarDataTypeDB::DeclareDataTypeBegin (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrDataType *pNewType = NULL;
 | 
						|
 | 
						|
  pNewType               = new SVfrDataType;
 | 
						|
  pNewType->mTypeName[0] = '\0';
 | 
						|
  pNewType->mType        = EFI_IFR_TYPE_OTHER;
 | 
						|
  pNewType->mAlign       = DEFAULT_ALIGN;
 | 
						|
  pNewType->mTotalSize   = 0;
 | 
						|
  pNewType->mMembers     = NULL;
 | 
						|
  pNewType->mNext        = NULL;
 | 
						|
 | 
						|
  mNewDataType           = pNewType;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrVarDataTypeDB::SetNewTypeName (
 | 
						|
  IN CHAR8   *TypeName
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrDataType *pType;
 | 
						|
 | 
						|
  if (mNewDataType == NULL) {
 | 
						|
    return VFR_RETURN_ERROR_SKIPED;
 | 
						|
  }
 | 
						|
  if (TypeName == NULL) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
  if (strlen(TypeName) >= MAX_NAME_LEN) {
 | 
						|
    return VFR_RETURN_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
 | 
						|
    if (strcmp(pType->mTypeName, TypeName) == 0) {
 | 
						|
      return VFR_RETURN_REDEFINED;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  strcpy(mNewDataType->mTypeName, TypeName);
 | 
						|
  return VFR_RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrVarDataTypeDB::DataTypeAddField (
 | 
						|
  IN CHAR8   *FieldName,
 | 
						|
  IN CHAR8   *TypeName,
 | 
						|
  IN UINT32 ArrayNum
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrDataField       *pNewField  = NULL;
 | 
						|
  SVfrDataType        *pFieldType = NULL;
 | 
						|
  SVfrDataField       *pTmp;
 | 
						|
  UINT32              Align;
 | 
						|
 | 
						|
  CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);
 | 
						|
 | 
						|
  if (strlen (FieldName) >= MAX_NAME_LEN) {
 | 
						|
   return VFR_RETURN_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {
 | 
						|
    if (strcmp (pTmp->mFieldName, FieldName) == 0) {
 | 
						|
      return VFR_RETURN_REDEFINED;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  Align = MIN (mPackAlign, pFieldType->mAlign);
 | 
						|
 | 
						|
  if ((pNewField = new SVfrDataField) == NULL) {
 | 
						|
    return VFR_RETURN_OUT_FOR_RESOURCES;
 | 
						|
  }
 | 
						|
  strcpy (pNewField->mFieldName, FieldName);
 | 
						|
  pNewField->mFieldType    = pFieldType;
 | 
						|
  pNewField->mArrayNum     = ArrayNum;
 | 
						|
  if ((mNewDataType->mTotalSize % Align) == 0) {
 | 
						|
    pNewField->mOffset     = mNewDataType->mTotalSize;
 | 
						|
  } else {
 | 
						|
    pNewField->mOffset     = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);
 | 
						|
  }
 | 
						|
  if (mNewDataType->mMembers == NULL) {
 | 
						|
    mNewDataType->mMembers = pNewField;
 | 
						|
    pNewField->mNext       = NULL;
 | 
						|
  } else {
 | 
						|
    for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext)
 | 
						|
      ;
 | 
						|
    pTmp->mNext            = pNewField;
 | 
						|
    pNewField->mNext       = NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  mNewDataType->mAlign     = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));
 | 
						|
  mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum);
 | 
						|
 | 
						|
  return VFR_RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CVfrVarDataTypeDB::DeclareDataTypeEnd (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (mNewDataType->mTypeName[0] == '\0') {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((mNewDataType->mTotalSize % mNewDataType->mAlign) !=0) {
 | 
						|
    mNewDataType->mTotalSize += ALIGN_STUFF (mNewDataType->mTotalSize, mNewDataType->mAlign);
 | 
						|
  }
 | 
						|
 | 
						|
  RegisterNewType (mNewDataType);
 | 
						|
  if (mFirstNewDataTypeName == NULL) {
 | 
						|
    mFirstNewDataTypeName = mNewDataType->mTypeName;
 | 
						|
  }
 | 
						|
 | 
						|
  mNewDataType             = NULL;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrVarDataTypeDB::GetDataType (
 | 
						|
  IN  CHAR8         *TypeName,
 | 
						|
  OUT SVfrDataType **DataType
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrDataType *pDataType = NULL;
 | 
						|
 | 
						|
  if (TypeName == NULL) {
 | 
						|
    return VFR_RETURN_ERROR_SKIPED;
 | 
						|
  }
 | 
						|
 | 
						|
  if (DataType == NULL) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  *DataType = NULL;
 | 
						|
 | 
						|
  for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
 | 
						|
    if (strcmp (TypeName, pDataType->mTypeName) == 0) {
 | 
						|
      *DataType = pDataType;
 | 
						|
      return VFR_RETURN_SUCCESS;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return VFR_RETURN_UNDEFINED;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrVarDataTypeDB::GetDataTypeSize (
 | 
						|
  IN  UINT8   DataType,
 | 
						|
  OUT UINT32 *Size
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrDataType *pDataType = NULL;
 | 
						|
 | 
						|
  if (Size == NULL) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  *Size    = 0;
 | 
						|
  DataType = DataType & 0x0F;
 | 
						|
 | 
						|
  //
 | 
						|
  // For user defined data type, the size can't be got by this function.
 | 
						|
  //
 | 
						|
  if (DataType == EFI_IFR_TYPE_OTHER) {
 | 
						|
    return VFR_RETURN_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
 | 
						|
    if (DataType == pDataType->mType) {
 | 
						|
      *Size = pDataType->mTotalSize;
 | 
						|
      return VFR_RETURN_SUCCESS;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return VFR_RETURN_UNDEFINED;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrVarDataTypeDB::GetDataTypeSize (
 | 
						|
  IN  CHAR8   *TypeName,
 | 
						|
  OUT UINT32 *Size
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrDataType *pDataType = NULL;
 | 
						|
 | 
						|
  if (Size == NULL) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  *Size = 0;
 | 
						|
 | 
						|
  for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
 | 
						|
    if (strcmp (TypeName, pDataType->mTypeName) == 0) {
 | 
						|
      *Size = pDataType->mTotalSize;
 | 
						|
      return VFR_RETURN_SUCCESS;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return VFR_RETURN_UNDEFINED;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrVarDataTypeDB::GetDataFieldInfo (
 | 
						|
  IN  CHAR8     *VarStr,
 | 
						|
  OUT UINT16   &Offset,
 | 
						|
  OUT UINT8    &Type,
 | 
						|
  OUT UINT32   &Size
 | 
						|
  )
 | 
						|
{
 | 
						|
  CHAR8               TName[MAX_NAME_LEN], FName[MAX_NAME_LEN];
 | 
						|
  UINT32              ArrayIdx, Tmp;
 | 
						|
  SVfrDataType        *pType  = NULL;
 | 
						|
  SVfrDataField       *pField = NULL;
 | 
						|
 | 
						|
  Offset = 0;
 | 
						|
  Type   = EFI_IFR_TYPE_OTHER;
 | 
						|
  Size   = 0;
 | 
						|
 | 
						|
  CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);
 | 
						|
  CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);
 | 
						|
 | 
						|
  //
 | 
						|
  // if it is not struct data type
 | 
						|
  //
 | 
						|
  Type  = pType->mType;
 | 
						|
  Size  = pType->mTotalSize;
 | 
						|
 | 
						|
  while (*VarStr != '\0') {
 | 
						|
  	CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);
 | 
						|
    CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);
 | 
						|
    pType  = pField->mFieldType;
 | 
						|
    CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp), VFR_RETURN_SUCCESS);
 | 
						|
    Offset += Tmp;
 | 
						|
    Type   = GetFieldWidth (pField);
 | 
						|
    Size   = GetFieldSize (pField, ArrayIdx);
 | 
						|
  }
 | 
						|
  return VFR_RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrVarDataTypeDB::GetUserDefinedTypeNameList  (
 | 
						|
  OUT CHAR8      ***NameList,
 | 
						|
  OUT UINT32    *ListSize
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32       Index;
 | 
						|
  SVfrDataType *pType;
 | 
						|
 | 
						|
  if ((NameList == NULL) || (ListSize == NULL)) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  *NameList = NULL;
 | 
						|
  *ListSize = 0;
 | 
						|
 | 
						|
  for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
 | 
						|
    if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {
 | 
						|
      (*ListSize)++;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (*ListSize == 0) {
 | 
						|
    return VFR_RETURN_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((*NameList = new CHAR8*[*ListSize]) == NULL) {
 | 
						|
    *ListSize = 0;
 | 
						|
    return VFR_RETURN_OUT_FOR_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  for (Index = 0, pType = mDataTypeList; pType != NULL; pType = pType->mNext, Index++) {
 | 
						|
    if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {
 | 
						|
      (*NameList)[Index] = pType->mTypeName;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return VFR_RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
BOOLEAN
 | 
						|
CVfrVarDataTypeDB::IsTypeNameDefined (
 | 
						|
  IN CHAR8 *TypeName
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrDataType *pType;
 | 
						|
 | 
						|
  if (TypeName == NULL) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
 | 
						|
    if (strcmp (pType->mTypeName, TypeName) == 0) {
 | 
						|
      return TRUE;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CVfrVarDataTypeDB::Dump (
 | 
						|
  IN FILE         *File
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrDataType  *pTNode;
 | 
						|
  SVfrDataField *pFNode;
 | 
						|
 | 
						|
  fprintf (File, "\n\n***************************************************************\n");
 | 
						|
  fprintf (File, "\t\tmPackAlign = %x\n", mPackAlign);
 | 
						|
  for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {
 | 
						|
    fprintf (File, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);
 | 
						|
    fprintf (File, "\t\tstruct %s {\n", pTNode->mTypeName);
 | 
						|
    for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {
 | 
						|
      if (pFNode->mArrayNum > 0) {
 | 
						|
        fprintf (File, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode->mOffset, pFNode->mOffset, 
 | 
						|
                  pFNode->mFieldName, pFNode->mArrayNum, pFNode->mFieldType->mTypeName);
 | 
						|
      } else {
 | 
						|
        fprintf (File, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode->mOffset, pFNode->mOffset, 
 | 
						|
                  pFNode->mFieldName, pFNode->mFieldType->mTypeName);
 | 
						|
      }
 | 
						|
    }
 | 
						|
    fprintf (File, "\t\t};\n");
 | 
						|
  fprintf (File, "---------------------------------------------------------------\n");
 | 
						|
  }
 | 
						|
  fprintf (File, "***************************************************************\n");
 | 
						|
}
 | 
						|
 | 
						|
#ifdef CVFR_VARDATATYPEDB_DEBUG
 | 
						|
VOID
 | 
						|
CVfrVarDataTypeDB::ParserDB (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrDataType  *pTNode;
 | 
						|
  SVfrDataField *pFNode;
 | 
						|
 | 
						|
  printf ("***************************************************************\n");
 | 
						|
  printf ("\t\tmPackAlign = %x\n", mPackAlign);
 | 
						|
  for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {
 | 
						|
    printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);
 | 
						|
    printf ("\t\tstruct %s {\n", pTNode->mTypeName);
 | 
						|
    for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {
 | 
						|
      printf ("\t\t\t%s\t%s\n", pFNode->mFieldType->mTypeName, pFNode->mFieldName);
 | 
						|
    }
 | 
						|
    printf ("\t\t};\n");
 | 
						|
	printf ("---------------------------------------------------------------\n");
 | 
						|
  }
 | 
						|
  printf ("***************************************************************\n");
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
SVfrVarStorageNode::SVfrVarStorageNode (
 | 
						|
  IN EFI_GUID              *Guid,
 | 
						|
  IN CHAR8                 *StoreName,
 | 
						|
  IN EFI_VARSTORE_ID       VarStoreId,
 | 
						|
  IN EFI_STRING_ID         VarName,
 | 
						|
  IN UINT32                VarSize,
 | 
						|
  IN BOOLEAN               Flag
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (Guid != NULL) {
 | 
						|
    mGuid = *Guid;
 | 
						|
  } else {
 | 
						|
    memset (&Guid, 0, sizeof (EFI_GUID));
 | 
						|
  }
 | 
						|
  if (StoreName != NULL) {
 | 
						|
    mVarStoreName = new CHAR8[strlen(StoreName) + 1];
 | 
						|
    strcpy (mVarStoreName, StoreName);
 | 
						|
  } else {
 | 
						|
    mVarStoreName = NULL;
 | 
						|
  }
 | 
						|
  mNext                            = NULL;
 | 
						|
  mVarStoreId                      = VarStoreId;
 | 
						|
  mVarStoreType                    = EFI_VFR_VARSTORE_EFI;
 | 
						|
  mStorageInfo.mEfiVar.mEfiVarName = VarName;
 | 
						|
  mStorageInfo.mEfiVar.mEfiVarSize = VarSize;
 | 
						|
  mAssignedFlag                    = Flag;
 | 
						|
}
 | 
						|
 | 
						|
SVfrVarStorageNode::SVfrVarStorageNode (
 | 
						|
  IN EFI_GUID              *Guid,
 | 
						|
  IN CHAR8                 *StoreName,
 | 
						|
  IN EFI_VARSTORE_ID       VarStoreId,
 | 
						|
  IN SVfrDataType          *DataType,
 | 
						|
  IN BOOLEAN               Flag
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (Guid != NULL) {
 | 
						|
    mGuid = *Guid;
 | 
						|
  } else {
 | 
						|
    memset (&Guid, 0, sizeof (EFI_GUID));
 | 
						|
  }
 | 
						|
  if (StoreName != NULL) {
 | 
						|
    mVarStoreName = new CHAR8[strlen(StoreName) + 1];
 | 
						|
    strcpy (mVarStoreName, StoreName);
 | 
						|
  } else {
 | 
						|
    mVarStoreName = NULL;
 | 
						|
  }
 | 
						|
  mNext                    = NULL;
 | 
						|
  mVarStoreId              = VarStoreId;
 | 
						|
  mVarStoreType            = EFI_VFR_VARSTORE_BUFFER;
 | 
						|
  mStorageInfo.mDataType   = DataType;
 | 
						|
  mAssignedFlag            = Flag;
 | 
						|
}
 | 
						|
 | 
						|
SVfrVarStorageNode::SVfrVarStorageNode (
 | 
						|
  IN CHAR8                 *StoreName,
 | 
						|
  IN EFI_VARSTORE_ID       VarStoreId
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (StoreName != NULL) {
 | 
						|
    mVarStoreName = new CHAR8[strlen(StoreName) + 1];
 | 
						|
    strcpy (mVarStoreName, StoreName);
 | 
						|
  } else {
 | 
						|
    mVarStoreName = NULL;
 | 
						|
  }
 | 
						|
  mNext                              = NULL;
 | 
						|
  mVarStoreId                        = VarStoreId;
 | 
						|
  mVarStoreType                      = EFI_VFR_VARSTORE_NAME;
 | 
						|
  mStorageInfo.mNameSpace.mNameTable = new EFI_VARSTORE_ID[DEFAULT_NAME_TABLE_ITEMS];
 | 
						|
  mStorageInfo.mNameSpace.mTableSize = 0;
 | 
						|
}
 | 
						|
 | 
						|
SVfrVarStorageNode::~SVfrVarStorageNode (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (mVarStoreName != NULL) {
 | 
						|
    delete mVarStoreName;
 | 
						|
  }
 | 
						|
 | 
						|
  if (mVarStoreType == EFI_VFR_VARSTORE_NAME) {
 | 
						|
    delete mStorageInfo.mNameSpace.mNameTable;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
CVfrDataStorage::CVfrDataStorage (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32 Index;
 | 
						|
 | 
						|
  for (Index = 0; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {
 | 
						|
    mFreeVarStoreIdBitMap[Index] = 0;
 | 
						|
  }
 | 
						|
 | 
						|
  // Question ID 0 is reserved.
 | 
						|
  mFreeVarStoreIdBitMap[0] = 0x80000000;
 | 
						|
 | 
						|
  mBufferVarStoreList      = NULL;
 | 
						|
  mEfiVarStoreList         = NULL;
 | 
						|
  mNameVarStoreList        = NULL;
 | 
						|
  mCurrVarStorageNode      = NULL;
 | 
						|
  mNewVarStorageNode       = NULL;
 | 
						|
}
 | 
						|
 | 
						|
CVfrDataStorage::~CVfrDataStorage (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrVarStorageNode *pNode;
 | 
						|
 | 
						|
  while (mBufferVarStoreList != NULL) {
 | 
						|
    pNode = mBufferVarStoreList;
 | 
						|
    mBufferVarStoreList = mBufferVarStoreList->mNext;
 | 
						|
    delete pNode;
 | 
						|
  }
 | 
						|
  while (mEfiVarStoreList != NULL) {
 | 
						|
    pNode = mEfiVarStoreList;
 | 
						|
    mEfiVarStoreList = mEfiVarStoreList->mNext;
 | 
						|
    delete pNode;
 | 
						|
  }
 | 
						|
  while (mNameVarStoreList != NULL) {
 | 
						|
    pNode = mNameVarStoreList;
 | 
						|
    mNameVarStoreList = mNameVarStoreList->mNext;
 | 
						|
    delete pNode;
 | 
						|
  }
 | 
						|
  if (mNewVarStorageNode != NULL) {
 | 
						|
    delete mNewVarStorageNode;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
EFI_VARSTORE_ID
 | 
						|
CVfrDataStorage::GetFreeVarStoreId (
 | 
						|
  EFI_VFR_VARSTORE_TYPE VarType
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32  Index, Mask, Offset;
 | 
						|
  
 | 
						|
  //
 | 
						|
  // Assign the different ID range for the different type VarStore to support Framework Vfr
 | 
						|
  //
 | 
						|
  if ((!VfrCompatibleMode) || (VarType == EFI_VFR_VARSTORE_BUFFER)) {
 | 
						|
    Index = 0;
 | 
						|
  } else if (VarType == EFI_VFR_VARSTORE_EFI) {
 | 
						|
    Index = 1;
 | 
						|
  } else if (VarType == EFI_VFR_VARSTORE_NAME) {
 | 
						|
    Index = 2;
 | 
						|
  }
 | 
						|
 | 
						|
  for (; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {
 | 
						|
    if (mFreeVarStoreIdBitMap[Index] != 0xFFFFFFFF) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
 | 
						|
    if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) {
 | 
						|
      mFreeVarStoreIdBitMap[Index] |= Mask;
 | 
						|
      return (EFI_VARSTORE_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_VARSTORE_ID_INVALID;
 | 
						|
}
 | 
						|
 | 
						|
BOOLEAN
 | 
						|
CVfrDataStorage::ChekVarStoreIdFree (
 | 
						|
  IN EFI_VARSTORE_ID VarStoreId
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32 Index  = (VarStoreId / EFI_BITS_PER_UINT32);
 | 
						|
  UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
 | 
						|
 | 
						|
  return (mFreeVarStoreIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CVfrDataStorage::MarkVarStoreIdUsed (
 | 
						|
  IN EFI_VARSTORE_ID VarStoreId
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32 Index  = (VarStoreId / EFI_BITS_PER_UINT32);
 | 
						|
  UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
 | 
						|
 | 
						|
  mFreeVarStoreIdBitMap[Index] |= (0x80000000 >> Offset);
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CVfrDataStorage::MarkVarStoreIdUnused (
 | 
						|
  IN EFI_VARSTORE_ID VarStoreId
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32 Index  = (VarStoreId / EFI_BITS_PER_UINT32);
 | 
						|
  UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
 | 
						|
 | 
						|
  mFreeVarStoreIdBitMap[Index] &= ~(0x80000000 >> Offset);
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrDataStorage::DeclareNameVarStoreBegin (
 | 
						|
  IN CHAR8    *StoreName
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrVarStorageNode *pNode = NULL;
 | 
						|
  EFI_VARSTORE_ID    VarStoreId;
 | 
						|
 | 
						|
  if (StoreName == NULL) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
 | 
						|
      return VFR_RETURN_REDEFINED;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);
 | 
						|
  if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {
 | 
						|
    return VFR_RETURN_UNDEFINED;
 | 
						|
  }
 | 
						|
 | 
						|
  mNewVarStorageNode = pNode;
 | 
						|
 | 
						|
  return VFR_RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrDataStorage::NameTableAddItem (
 | 
						|
  IN EFI_STRING_ID  Item
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_VARSTORE_ID *NewTable, *OldTable;
 | 
						|
  UINT32          TableSize;
 | 
						|
 | 
						|
  OldTable  = mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable;
 | 
						|
  TableSize = mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize;
 | 
						|
 | 
						|
  if ((TableSize != 0) && ((TableSize % DEFAULT_NAME_TABLE_ITEMS) == 0)) {
 | 
						|
    if ((NewTable = new EFI_VARSTORE_ID[TableSize + DEFAULT_NAME_TABLE_ITEMS]) == NULL) {
 | 
						|
      return VFR_RETURN_OUT_FOR_RESOURCES;
 | 
						|
    }
 | 
						|
    memcpy (NewTable, OldTable, TableSize);
 | 
						|
    mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable = NewTable;
 | 
						|
  }
 | 
						|
 | 
						|
  mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable[TableSize++] = Item;
 | 
						|
  mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize = TableSize;
 | 
						|
 | 
						|
  return VFR_RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrDataStorage::DeclareNameVarStoreEnd (
 | 
						|
  IN EFI_GUID *Guid
 | 
						|
  )
 | 
						|
{
 | 
						|
  mNewVarStorageNode->mGuid = *Guid;
 | 
						|
  mNewVarStorageNode->mNext = mNameVarStoreList;
 | 
						|
  mNameVarStoreList         = mNewVarStorageNode;
 | 
						|
 | 
						|
  mNewVarStorageNode        = NULL;
 | 
						|
 | 
						|
  return VFR_RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE 
 | 
						|
CVfrDataStorage::DeclareEfiVarStore (
 | 
						|
  IN CHAR8          *StoreName, 
 | 
						|
  IN EFI_GUID       *Guid, 
 | 
						|
  IN EFI_STRING_ID  NameStrId,
 | 
						|
  IN UINT32         VarSize,
 | 
						|
  IN BOOLEAN        Flag
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrVarStorageNode *pNode;
 | 
						|
  EFI_VARSTORE_ID    VarStoreId;
 | 
						|
 | 
						|
  if ((StoreName == NULL) || (Guid == NULL)) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  if (VarSize > sizeof (UINT64)) {
 | 
						|
    return VFR_RETURN_EFIVARSTORE_SIZE_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
 | 
						|
      return VFR_RETURN_REDEFINED;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI);
 | 
						|
  if ((pNode = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, NameStrId, VarSize, Flag)) == NULL) {
 | 
						|
    return VFR_RETURN_OUT_FOR_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  pNode->mNext       = mEfiVarStoreList;
 | 
						|
  mEfiVarStoreList   = pNode;
 | 
						|
 | 
						|
  return VFR_RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE 
 | 
						|
CVfrDataStorage::DeclareBufferVarStore (
 | 
						|
  IN CHAR8             *StoreName, 
 | 
						|
  IN EFI_GUID          *Guid, 
 | 
						|
  IN CVfrVarDataTypeDB *DataTypeDB,
 | 
						|
  IN CHAR8             *TypeName,
 | 
						|
  IN EFI_VARSTORE_ID   VarStoreId,
 | 
						|
  IN BOOLEAN           Flag
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrVarStorageNode   *pNew = NULL;
 | 
						|
  SVfrDataType         *pDataType = NULL;
 | 
						|
 | 
						|
  if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS);
 | 
						|
 | 
						|
  if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
 | 
						|
    VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER);
 | 
						|
  } else {
 | 
						|
    if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
 | 
						|
      return VFR_RETURN_VARSTOREID_REDEFINED;
 | 
						|
    }
 | 
						|
    MarkVarStoreIdUsed (VarStoreId);
 | 
						|
  }
 | 
						|
 | 
						|
  if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, Flag)) == NULL) {
 | 
						|
    return VFR_RETURN_OUT_FOR_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  pNew->mNext         = mBufferVarStoreList;
 | 
						|
  mBufferVarStoreList = pNew;
 | 
						|
 | 
						|
  if (gCVfrBufferConfig.Register(StoreName) != 0) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  return VFR_RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE 
 | 
						|
CVfrDataStorage::GetVarStoreId (
 | 
						|
  IN  CHAR8           *StoreName,
 | 
						|
  OUT EFI_VARSTORE_ID *VarStoreId
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrVarStorageNode    *pNode;
 | 
						|
 | 
						|
  for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
 | 
						|
      mCurrVarStorageNode = pNode;
 | 
						|
      *VarStoreId = pNode->mVarStoreId;
 | 
						|
      return VFR_RETURN_SUCCESS;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
 | 
						|
      mCurrVarStorageNode = pNode;
 | 
						|
      *VarStoreId = pNode->mVarStoreId;
 | 
						|
      return VFR_RETURN_SUCCESS;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
 | 
						|
      mCurrVarStorageNode = pNode;
 | 
						|
      *VarStoreId = pNode->mVarStoreId;
 | 
						|
      return VFR_RETURN_SUCCESS;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  mCurrVarStorageNode = NULL;
 | 
						|
  *VarStoreId        = EFI_VARSTORE_ID_INVALID;
 | 
						|
  return VFR_RETURN_UNDEFINED;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrDataStorage::GetBufferVarStoreDataTypeName (
 | 
						|
  IN  CHAR8                  *StoreName,
 | 
						|
  OUT CHAR8                  **DataTypeName
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrVarStorageNode    *pNode;
 | 
						|
 | 
						|
  if ((StoreName == NULL) || (DataTypeName == NULL)) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (pNode == NULL) {
 | 
						|
    return VFR_RETURN_UNDEFINED;
 | 
						|
  }
 | 
						|
 | 
						|
  if (pNode->mStorageInfo.mDataType == NULL) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;
 | 
						|
  return VFR_RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrDataStorage::GetVarStoreType (
 | 
						|
  IN  CHAR8                  *StoreName,
 | 
						|
  OUT EFI_VFR_VARSTORE_TYPE  &VarStoreType
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrVarStorageNode    *pNode;
 | 
						|
 | 
						|
  if (StoreName == NULL) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
 | 
						|
      VarStoreType = pNode->mVarStoreType;
 | 
						|
      return VFR_RETURN_SUCCESS;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
 | 
						|
      VarStoreType = pNode->mVarStoreType;
 | 
						|
      return VFR_RETURN_SUCCESS;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
 | 
						|
      VarStoreType = pNode->mVarStoreType;
 | 
						|
      return VFR_RETURN_SUCCESS;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  VarStoreType = EFI_VFR_VARSTORE_INVALID;
 | 
						|
  return VFR_RETURN_UNDEFINED;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_VARSTORE_TYPE
 | 
						|
CVfrDataStorage::GetVarStoreType (
 | 
						|
  IN  EFI_VARSTORE_ID        VarStoreId
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrVarStorageNode    *pNode;
 | 
						|
  EFI_VFR_VARSTORE_TYPE VarStoreType;
 | 
						|
 | 
						|
  VarStoreType = EFI_VFR_VARSTORE_INVALID;
 | 
						|
 | 
						|
  if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
 | 
						|
    return VarStoreType;
 | 
						|
  }
 | 
						|
 | 
						|
  for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (pNode->mVarStoreId == VarStoreId) {
 | 
						|
      VarStoreType = pNode->mVarStoreType;
 | 
						|
      return VarStoreType;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (pNode->mVarStoreId == VarStoreId) {
 | 
						|
      VarStoreType = pNode->mVarStoreType;
 | 
						|
      return VarStoreType;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (pNode->mVarStoreId == VarStoreId) {
 | 
						|
      VarStoreType = pNode->mVarStoreType;
 | 
						|
      return VarStoreType;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return VarStoreType;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrDataStorage::GetVarStoreName (
 | 
						|
  IN  EFI_VARSTORE_ID VarStoreId, 
 | 
						|
  OUT CHAR8           **VarStoreName
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrVarStorageNode    *pNode;
 | 
						|
 | 
						|
  if (VarStoreName == NULL) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (pNode->mVarStoreId == VarStoreId) {
 | 
						|
      *VarStoreName = pNode->mVarStoreName;
 | 
						|
      return VFR_RETURN_SUCCESS;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (pNode->mVarStoreId == VarStoreId) {
 | 
						|
      *VarStoreName = pNode->mVarStoreName;
 | 
						|
      return VFR_RETURN_SUCCESS;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (pNode->mVarStoreId == VarStoreId) {
 | 
						|
      *VarStoreName = pNode->mVarStoreName;
 | 
						|
      return VFR_RETURN_SUCCESS;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  *VarStoreName = NULL;
 | 
						|
  return VFR_RETURN_UNDEFINED;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrDataStorage::GetEfiVarStoreInfo (
 | 
						|
  IN OUT EFI_VARSTORE_INFO  *Info
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (Info == NULL) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  if (mCurrVarStorageNode == NULL) {
 | 
						|
    return VFR_RETURN_GET_EFIVARSTORE_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName;
 | 
						|
  Info->mVarTotalSize  = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize;
 | 
						|
  switch (Info->mVarTotalSize) {
 | 
						|
  case 1:
 | 
						|
    Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8;
 | 
						|
    break;
 | 
						|
  case 2:
 | 
						|
    Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16;
 | 
						|
    break;
 | 
						|
  case 4:
 | 
						|
    Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32;
 | 
						|
    break;
 | 
						|
  case 8:
 | 
						|
    Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64;
 | 
						|
    break;
 | 
						|
  default :
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  return VFR_RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrDataStorage::GetNameVarStoreInfo (
 | 
						|
  OUT EFI_VARSTORE_INFO  *Info,
 | 
						|
  IN  UINT32             Index
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (Info == NULL) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  if (mCurrVarStorageNode == NULL) {
 | 
						|
    return VFR_RETURN_GET_NVVARSTORE_ERROR;
 | 
						|
  }
 | 
						|
  
 | 
						|
  //
 | 
						|
  // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.
 | 
						|
  //
 | 
						|
  if (VfrCompatibleMode) {
 | 
						|
    if (Index == 0) {
 | 
						|
      return VFR_RETURN_ERROR_ARRARY_NUM;
 | 
						|
    }
 | 
						|
    Index --;
 | 
						|
  }
 | 
						|
 | 
						|
  Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index];
 | 
						|
 | 
						|
  return VFR_RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrDataStorage::BufferVarStoreRequestElementAdd (
 | 
						|
  IN CHAR8             *StoreName,
 | 
						|
  IN EFI_VARSTORE_INFO &Info
 | 
						|
  )
 | 
						|
{
 | 
						|
  CHAR8                 NewReqElt[128] = {'\0',};
 | 
						|
  CHAR8                 *OldReqElt = NULL;
 | 
						|
  SVfrVarStorageNode    *pNode = NULL;
 | 
						|
  EFI_IFR_TYPE_VALUE    Value = gZeroEfiIfrTypeValue;
 | 
						|
 | 
						|
  for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (strcmp (pNode->mVarStoreName, StoreName) == NULL) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (pNode == NULL) {
 | 
						|
    return VFR_RETURN_UNDEFINED;
 | 
						|
  }
 | 
						|
 | 
						|
  gCVfrBufferConfig.Open ();
 | 
						|
  Value.u8 = 0;
 | 
						|
  if (gCVfrBufferConfig.Write ('a', StoreName, NULL, EFI_IFR_TYPE_NUM_SIZE_8, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value) != 0) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
  gCVfrBufferConfig.Close ();
 | 
						|
 | 
						|
  return VFR_RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
SVfrDefaultStoreNode::SVfrDefaultStoreNode (
 | 
						|
  IN EFI_IFR_DEFAULTSTORE *ObjBinAddr,
 | 
						|
  IN CHAR8                *RefName, 
 | 
						|
  IN EFI_STRING_ID        DefaultStoreNameId, 
 | 
						|
  IN UINT16               DefaultId
 | 
						|
  )
 | 
						|
{
 | 
						|
  mObjBinAddr = ObjBinAddr;
 | 
						|
 | 
						|
  if (RefName != NULL) {
 | 
						|
    mRefName          = new CHAR8[strlen (RefName) + 1];
 | 
						|
    strcpy (mRefName, RefName);
 | 
						|
  } else {
 | 
						|
    mRefName          = NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  mNext               = NULL;
 | 
						|
  mDefaultId          = DefaultId;
 | 
						|
  mDefaultStoreNameId = DefaultStoreNameId;
 | 
						|
}
 | 
						|
 | 
						|
SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (mRefName != NULL) {
 | 
						|
    delete mRefName;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
CVfrDefaultStore::CVfrDefaultStore (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  mDefaultStoreList = NULL;
 | 
						|
}
 | 
						|
 | 
						|
CVfrDefaultStore::~CVfrDefaultStore (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrDefaultStoreNode *pTmp = NULL;
 | 
						|
 | 
						|
  while (mDefaultStoreList != NULL) {
 | 
						|
    pTmp = mDefaultStoreList;
 | 
						|
    mDefaultStoreList = mDefaultStoreList->mNext;
 | 
						|
    delete pTmp;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrDefaultStore::RegisterDefaultStore (
 | 
						|
  IN CHAR8                *ObjBinAddr,
 | 
						|
  IN CHAR8                *RefName,
 | 
						|
  IN EFI_STRING_ID        DefaultStoreNameId,
 | 
						|
  IN UINT16               DefaultId
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrDefaultStoreNode *pNode = NULL;
 | 
						|
 | 
						|
  if (RefName == NULL) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (strcmp (pNode->mRefName, RefName) == 0) {
 | 
						|
      return VFR_RETURN_REDEFINED;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) {
 | 
						|
    return VFR_RETURN_OUT_FOR_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  pNode->mNext               = mDefaultStoreList;
 | 
						|
  mDefaultStoreList          = pNode;
 | 
						|
 | 
						|
  return VFR_RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * assign new reference name or new default store name id only if 
 | 
						|
 * the original is invalid
 | 
						|
 */
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrDefaultStore::ReRegisterDefaultStoreById (
 | 
						|
  IN UINT16          DefaultId,
 | 
						|
  IN CHAR8           *RefName,
 | 
						|
  IN EFI_STRING_ID   DefaultStoreNameId
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrDefaultStoreNode *pNode = NULL;
 | 
						|
 | 
						|
  for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (pNode->mDefaultId == DefaultId) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (pNode == NULL) {
 | 
						|
    return VFR_RETURN_UNDEFINED;
 | 
						|
  } else {
 | 
						|
    if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) {
 | 
						|
      pNode->mDefaultStoreNameId  = DefaultStoreNameId;
 | 
						|
      if (pNode->mObjBinAddr != NULL) {
 | 
						|
        pNode->mObjBinAddr->DefaultName = DefaultStoreNameId;
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      return VFR_RETURN_REDEFINED;
 | 
						|
    }
 | 
						|
 | 
						|
    if (RefName != NULL) {
 | 
						|
      delete pNode->mRefName;
 | 
						|
      pNode->mRefName = new CHAR8[strlen (RefName) + 1];
 | 
						|
      if (pNode->mRefName != NULL) {
 | 
						|
        strcpy (pNode->mRefName, RefName);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return VFR_RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
BOOLEAN
 | 
						|
CVfrDefaultStore::DefaultIdRegistered (
 | 
						|
  IN UINT16          DefaultId
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrDefaultStoreNode *pNode = NULL;
 | 
						|
 | 
						|
  for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (pNode->mDefaultId == DefaultId) {
 | 
						|
      return TRUE;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrDefaultStore::GetDefaultId (
 | 
						|
  IN  CHAR8           *RefName,
 | 
						|
  OUT UINT16          *DefaultId
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrDefaultStoreNode *pTmp = NULL;
 | 
						|
 | 
						|
  if (DefaultId == NULL) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) {
 | 
						|
    if (strcmp (pTmp->mRefName, RefName) == 0) {
 | 
						|
      *DefaultId = pTmp->mDefaultId;
 | 
						|
      return VFR_RETURN_SUCCESS;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return VFR_RETURN_UNDEFINED;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
AltCfgItemPrintToBuffer (
 | 
						|
  IN CHAR8              *NewAltCfg, 
 | 
						|
  IN EFI_VARSTORE_INFO  Info, 
 | 
						|
  IN UINT8              Type,
 | 
						|
  IN EFI_IFR_TYPE_VALUE Value
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32 Index;
 | 
						|
  UINT8  *BufChar = NULL;
 | 
						|
  UINT32 Count    = 0;
 | 
						|
 | 
						|
  if (NewAltCfg != NULL) {
 | 
						|
    Count = sprintf (
 | 
						|
              NewAltCfg,
 | 
						|
              "&OFFSET=%x&WIDTH=%x&VALUE=",
 | 
						|
              Info.mInfo.mVarOffset,
 | 
						|
              Info.mVarTotalSize
 | 
						|
              );
 | 
						|
    NewAltCfg += Count;
 | 
						|
 | 
						|
    switch (Type) {
 | 
						|
    case EFI_IFR_TYPE_NUM_SIZE_8 :
 | 
						|
      Count = sprintf (NewAltCfg, "%x", Value.u8);
 | 
						|
      NewAltCfg += Count;
 | 
						|
      break;
 | 
						|
    case EFI_IFR_TYPE_NUM_SIZE_16 :
 | 
						|
      Count = sprintf (NewAltCfg, "%x", Value.u16);
 | 
						|
      NewAltCfg += Count;
 | 
						|
      break;
 | 
						|
    case EFI_IFR_TYPE_NUM_SIZE_32 :
 | 
						|
      Count = sprintf (NewAltCfg, "%x", Value.u32);
 | 
						|
      NewAltCfg += Count;
 | 
						|
      break;
 | 
						|
    case EFI_IFR_TYPE_NUM_SIZE_64 :
 | 
						|
      Count = sprintf (NewAltCfg, "%x", Value.u64);
 | 
						|
      NewAltCfg += Count;
 | 
						|
      break;
 | 
						|
    case EFI_IFR_TYPE_BOOLEAN :
 | 
						|
      Count = sprintf (NewAltCfg, "%x", Value.b);
 | 
						|
      NewAltCfg += Count;
 | 
						|
      break;
 | 
						|
    case EFI_IFR_TYPE_TIME :
 | 
						|
#if 1
 | 
						|
      Count = sprintf (NewAltCfg, "%x", *((UINT32 *)(&Value.time)));
 | 
						|
      NewAltCfg += Count;
 | 
						|
#else
 | 
						|
      BufChar = (UINT8 *)&Value.time;
 | 
						|
      for (Index = 0; Index < sizeof(EFI_HII_TIME); Index++) {
 | 
						|
        Count = sprintf (NewAltCfg, "%02x", (UINT8)BufChar[Index]);
 | 
						|
        NewAltCfg += Count;
 | 
						|
      }
 | 
						|
#endif
 | 
						|
      break;
 | 
						|
    case EFI_IFR_TYPE_DATE :
 | 
						|
#if 1
 | 
						|
      Count = sprintf (NewAltCfg, "%x", *((UINT32 *)(&Value.date)));
 | 
						|
      NewAltCfg += Count;
 | 
						|
#else
 | 
						|
      BufChar = (UINT8 *)&Value.date;
 | 
						|
      for (Index = 0; Index < sizeof(EFI_HII_DATE); Index++) {
 | 
						|
        Count = sprintf (NewAltCfg, "%02x", (UINT8)BufChar[Index]);
 | 
						|
        NewAltCfg += Count;
 | 
						|
      }
 | 
						|
#endif
 | 
						|
      break;
 | 
						|
    case EFI_IFR_TYPE_STRING :
 | 
						|
      Count = sprintf (NewAltCfg, "%x", Value.string);
 | 
						|
      NewAltCfg += Count;
 | 
						|
      break;
 | 
						|
    case EFI_IFR_TYPE_OTHER :
 | 
						|
      return VFR_RETURN_UNSUPPORTED;
 | 
						|
	}
 | 
						|
  }
 | 
						|
 | 
						|
  return VFR_RETURN_FATAL_ERROR;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrDefaultStore::BufferVarStoreAltConfigAdd (
 | 
						|
  IN EFI_VARSTORE_ID    DefaultId,
 | 
						|
  IN EFI_VARSTORE_INFO  &Info,
 | 
						|
  IN CHAR8              *VarStoreName,
 | 
						|
  IN UINT8              Type,
 | 
						|
  IN EFI_IFR_TYPE_VALUE Value
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrDefaultStoreNode  *pNode = NULL;
 | 
						|
  CHAR8                 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,};
 | 
						|
  INTN                  Returnvalue = 0;
 | 
						|
 | 
						|
  if (VarStoreName == NULL) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (pNode->mDefaultId == DefaultId) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (pNode == NULL) {
 | 
						|
    return VFR_RETURN_UNDEFINED;
 | 
						|
  }
 | 
						|
 | 
						|
  gCVfrBufferConfig.Open ();
 | 
						|
 | 
						|
  sprintf (NewAltCfg, "%04x", pNode->mDefaultId);
 | 
						|
  if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName)) == 0) {
 | 
						|
    if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) {
 | 
						|
      goto WriteError;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  
 | 
						|
  gCVfrBufferConfig.Close ();
 | 
						|
 | 
						|
  return VFR_RETURN_SUCCESS;
 | 
						|
 | 
						|
WriteError:
 | 
						|
  gCVfrBufferConfig.Close ();
 | 
						|
  return (EFI_VFR_RETURN_CODE)Returnvalue;
 | 
						|
}
 | 
						|
 | 
						|
SVfrRuleNode::SVfrRuleNode (
 | 
						|
  IN CHAR8        *RuleName,
 | 
						|
  IN UINT8       RuleId
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (RuleName != NULL) {
 | 
						|
    mRuleName = new CHAR8[strlen (RuleName) + 1];
 | 
						|
    strcpy (mRuleName, RuleName);
 | 
						|
  } else {
 | 
						|
    mRuleName = NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  mNext       = NULL;
 | 
						|
  mRuleId     = RuleId;
 | 
						|
}
 | 
						|
 | 
						|
SVfrRuleNode::~SVfrRuleNode (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (mRuleName != NULL) {
 | 
						|
    delete mRuleName;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
CVfrRulesDB::CVfrRulesDB ()
 | 
						|
{
 | 
						|
  mRuleList   = NULL;
 | 
						|
  mFreeRuleId = EFI_VARSTORE_ID_START;
 | 
						|
}
 | 
						|
 | 
						|
CVfrRulesDB::~CVfrRulesDB ()
 | 
						|
{
 | 
						|
  SVfrRuleNode *pNode;
 | 
						|
 | 
						|
  while(mRuleList != NULL) {
 | 
						|
    pNode = mRuleList;
 | 
						|
    mRuleList = mRuleList->mNext;
 | 
						|
    delete pNode;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CVfrRulesDB::RegisterRule (
 | 
						|
  IN CHAR8  *RuleName
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrRuleNode *pNew;
 | 
						|
 | 
						|
  if (RuleName == NULL) {
 | 
						|
    return ;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) {
 | 
						|
    return ;
 | 
						|
  }
 | 
						|
 | 
						|
  mFreeRuleId++;
 | 
						|
 | 
						|
  pNew->mNext = mRuleList;
 | 
						|
  mRuleList   = pNew;
 | 
						|
}
 | 
						|
 | 
						|
UINT8
 | 
						|
CVfrRulesDB::GetRuleId (
 | 
						|
  IN CHAR8  *RuleName
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrRuleNode *pNode;
 | 
						|
 | 
						|
  if (RuleName == NULL) {
 | 
						|
    return EFI_RULE_ID_INVALID;
 | 
						|
  }
 | 
						|
 | 
						|
  for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (strcmp (pNode->mRuleName, RuleName) == 0) {
 | 
						|
      return pNode->mRuleId;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_RULE_ID_INVALID;
 | 
						|
}
 | 
						|
 | 
						|
CVfrRulesDB gCVfrRulesDB;
 | 
						|
 | 
						|
EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  mVarStoreId      = EFI_VARSTORE_ID_INVALID;
 | 
						|
  mInfo.mVarName   = EFI_STRING_ID_INVALID;
 | 
						|
  mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
 | 
						|
  mVarType         = EFI_IFR_TYPE_OTHER;
 | 
						|
  mVarTotalSize    = 0;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
 | 
						|
  IN EFI_VARSTORE_INFO &Info
 | 
						|
  )
 | 
						|
{
 | 
						|
  mVarStoreId      = Info.mVarStoreId;
 | 
						|
  mInfo.mVarName   = Info.mInfo.mVarName;
 | 
						|
  mInfo.mVarOffset = Info.mInfo.mVarOffset;
 | 
						|
  mVarType         = Info.mVarType;
 | 
						|
  mVarTotalSize    = Info.mVarTotalSize;
 | 
						|
}
 | 
						|
 | 
						|
BOOLEAN
 | 
						|
EFI_VARSTORE_INFO::operator == (
 | 
						|
  IN EFI_VARSTORE_INFO  *Info
 | 
						|
  )
 | 
						|
{
 | 
						|
  if ((mVarStoreId == Info->mVarStoreId) &&
 | 
						|
  	  (mInfo.mVarName == Info->mInfo.mVarName) &&
 | 
						|
      (mInfo.mVarOffset == Info->mInfo.mVarOffset) &&
 | 
						|
      (mVarType == Info->mVarType) &&
 | 
						|
      (mVarTotalSize == Info->mVarTotalSize)) {
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;
 | 
						|
 | 
						|
EFI_QUESTION_ID
 | 
						|
CVfrQuestionDB::GetFreeQuestionId (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32  Index, Mask, Offset;
 | 
						|
 | 
						|
  for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
 | 
						|
    if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
 | 
						|
    if ((mFreeQIdBitMap[Index] & Mask) == 0) {
 | 
						|
      mFreeQIdBitMap[Index] |= Mask;
 | 
						|
      return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_QUESTION_ID_INVALID;
 | 
						|
}
 | 
						|
 | 
						|
BOOLEAN
 | 
						|
CVfrQuestionDB::ChekQuestionIdFree (
 | 
						|
  IN EFI_QUESTION_ID QId
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32 Index  = (QId / EFI_BITS_PER_UINT32);
 | 
						|
  UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
 | 
						|
 | 
						|
  return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CVfrQuestionDB::MarkQuestionIdUsed (
 | 
						|
  IN EFI_QUESTION_ID QId
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32 Index  = (QId / EFI_BITS_PER_UINT32);
 | 
						|
  UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
 | 
						|
 | 
						|
  mFreeQIdBitMap[Index] |= (0x80000000 >> Offset);
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CVfrQuestionDB::MarkQuestionIdUnused (
 | 
						|
  IN EFI_QUESTION_ID QId
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32 Index  = (QId / EFI_BITS_PER_UINT32);
 | 
						|
  UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
 | 
						|
 | 
						|
  mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset);
 | 
						|
}
 | 
						|
 | 
						|
SVfrQuestionNode::SVfrQuestionNode (
 | 
						|
  IN CHAR8  *Name,
 | 
						|
  IN CHAR8  *VarIdStr,
 | 
						|
  IN UINT32 BitMask
 | 
						|
  )
 | 
						|
{
 | 
						|
  mName       = NULL;
 | 
						|
  mVarIdStr   = NULL;
 | 
						|
  mQuestionId = EFI_QUESTION_ID_INVALID;
 | 
						|
  mBitMask    = BitMask;
 | 
						|
  mNext       = NULL;
 | 
						|
 | 
						|
  if (Name == NULL) {
 | 
						|
    mName = new CHAR8[strlen ("$DEFAULT") + 1];
 | 
						|
    strcpy (mName, "$DEFAULT");
 | 
						|
  } else {
 | 
						|
    mName = new CHAR8[strlen (Name) + 1];
 | 
						|
    strcpy (mName, Name);
 | 
						|
  }
 | 
						|
 | 
						|
  if (VarIdStr != NULL) {
 | 
						|
    mVarIdStr = new CHAR8[strlen (VarIdStr) + 1];
 | 
						|
    strcpy (mVarIdStr, VarIdStr);
 | 
						|
  } else {
 | 
						|
    mVarIdStr = new CHAR8[strlen ("$") + 1];
 | 
						|
    strcpy (mVarIdStr, "$");
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
SVfrQuestionNode::~SVfrQuestionNode (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (mName != NULL) {
 | 
						|
    delete mName;
 | 
						|
  }
 | 
						|
 | 
						|
  if (mVarIdStr != NULL) {
 | 
						|
    delete mVarIdStr;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
CVfrQuestionDB::CVfrQuestionDB ()
 | 
						|
{
 | 
						|
  UINT32 Index;
 | 
						|
 | 
						|
  for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
 | 
						|
    mFreeQIdBitMap[Index] = 0;
 | 
						|
  }
 | 
						|
 | 
						|
  // Question ID 0 is reserved.
 | 
						|
  mFreeQIdBitMap[0] = 0x80000000;
 | 
						|
  mQuestionList     = NULL;
 | 
						|
}
 | 
						|
 | 
						|
CVfrQuestionDB::~CVfrQuestionDB ()
 | 
						|
{
 | 
						|
  SVfrQuestionNode     *pNode;
 | 
						|
 | 
						|
  while (mQuestionList != NULL) {
 | 
						|
    pNode = mQuestionList;
 | 
						|
    mQuestionList = mQuestionList->mNext;
 | 
						|
    delete pNode;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// Reset to init state
 | 
						|
//
 | 
						|
VOID
 | 
						|
CVfrQuestionDB::ResetInit(
 | 
						|
  IN VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32               Index;
 | 
						|
  SVfrQuestionNode     *pNode;
 | 
						|
 | 
						|
  while (mQuestionList != NULL) {
 | 
						|
    pNode = mQuestionList;
 | 
						|
    mQuestionList = mQuestionList->mNext;
 | 
						|
    delete pNode;
 | 
						|
  }
 | 
						|
 | 
						|
  for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
 | 
						|
    mFreeQIdBitMap[Index] = 0;
 | 
						|
  }
 | 
						|
 | 
						|
  // Question ID 0 is reserved.
 | 
						|
  mFreeQIdBitMap[0] = 0x80000000;
 | 
						|
  mQuestionList     = NULL;   
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CVfrQuestionDB::PrintAllQuestion (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrQuestionNode *pNode = NULL;
 | 
						|
 | 
						|
  for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrQuestionDB::RegisterQuestion (
 | 
						|
  IN     CHAR8             *Name,
 | 
						|
  IN     CHAR8             *VarIdStr,
 | 
						|
  IN OUT EFI_QUESTION_ID   &QuestionId
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrQuestionNode *pNode = NULL;
 | 
						|
 | 
						|
  if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) {
 | 
						|
    return VFR_RETURN_REDEFINED;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) {
 | 
						|
    return VFR_RETURN_OUT_FOR_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  if (QuestionId == EFI_QUESTION_ID_INVALID) {
 | 
						|
    QuestionId = GetFreeQuestionId ();
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // For Framework Vfr, don't check question ID conflict.
 | 
						|
    //
 | 
						|
    if (!VfrCompatibleMode && ChekQuestionIdFree (QuestionId) == FALSE) {
 | 
						|
      delete pNode;
 | 
						|
      return VFR_RETURN_QUESTIONID_REDEFINED;
 | 
						|
    }
 | 
						|
    MarkQuestionIdUsed (QuestionId);
 | 
						|
  }
 | 
						|
  pNode->mQuestionId = QuestionId;
 | 
						|
 | 
						|
  pNode->mNext       = mQuestionList;
 | 
						|
  mQuestionList      = pNode;
 | 
						|
 | 
						|
  gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
 | 
						|
 | 
						|
  return VFR_RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CVfrQuestionDB::RegisterOldDateQuestion (
 | 
						|
  IN     CHAR8            *YearVarId,
 | 
						|
  IN     CHAR8            *MonthVarId,
 | 
						|
  IN     CHAR8            *DayVarId,
 | 
						|
  IN OUT EFI_QUESTION_ID &QuestionId
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrQuestionNode *pNode[3] = {NULL, };
 | 
						|
  UINT32           Index;
 | 
						|
 | 
						|
  if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) {
 | 
						|
    goto Err;
 | 
						|
  }
 | 
						|
  if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) {
 | 
						|
    goto Err;
 | 
						|
  }
 | 
						|
  if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, DATE_DAY_BITMASK)) == NULL) {
 | 
						|
    goto Err;
 | 
						|
  }
 | 
						|
 | 
						|
  if (QuestionId == EFI_QUESTION_ID_INVALID) {
 | 
						|
    QuestionId = GetFreeQuestionId ();
 | 
						|
  } else {
 | 
						|
    if (ChekQuestionIdFree (QuestionId) == FALSE) {
 | 
						|
      goto Err;
 | 
						|
    }
 | 
						|
    MarkQuestionIdUsed (QuestionId);
 | 
						|
  }
 | 
						|
 | 
						|
  pNode[0]->mQuestionId = QuestionId;
 | 
						|
  pNode[1]->mQuestionId = QuestionId;
 | 
						|
  pNode[2]->mQuestionId = QuestionId;
 | 
						|
  pNode[0]->mNext       = pNode[1];
 | 
						|
  pNode[1]->mNext       = pNode[2];
 | 
						|
  pNode[2]->mNext       = mQuestionList;
 | 
						|
  mQuestionList         = pNode[0];
 | 
						|
 | 
						|
  gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
 | 
						|
  gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
 | 
						|
  gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
 | 
						|
 | 
						|
  return;
 | 
						|
 | 
						|
Err:
 | 
						|
  for (Index = 0; Index < 3; Index++) {
 | 
						|
    if (pNode[Index] != NULL) {
 | 
						|
      delete pNode[Index];
 | 
						|
    }
 | 
						|
  }
 | 
						|
  QuestionId = EFI_QUESTION_ID_INVALID;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CVfrQuestionDB::RegisterNewDateQuestion (
 | 
						|
  IN     CHAR8            *Name,
 | 
						|
  IN     CHAR8            *BaseVarId,
 | 
						|
  IN OUT EFI_QUESTION_ID &QuestionId
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrQuestionNode     *pNode[3] = {NULL, };
 | 
						|
  UINT32               Len;
 | 
						|
  CHAR8                *VarIdStr[3] = {NULL, };
 | 
						|
  CHAR8                 Index;
 | 
						|
 | 
						|
  if (BaseVarId == NULL) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  Len = strlen (BaseVarId);
 | 
						|
 | 
						|
  VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];
 | 
						|
  if (VarIdStr[0] != NULL) {
 | 
						|
    strcpy (VarIdStr[0], BaseVarId);
 | 
						|
    strcat (VarIdStr[0], ".Year");
 | 
						|
  }
 | 
						|
  VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];
 | 
						|
  if (VarIdStr[1] != NULL) {
 | 
						|
    strcpy (VarIdStr[1], BaseVarId);
 | 
						|
    strcat (VarIdStr[1], ".Month");
 | 
						|
  }
 | 
						|
  VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];
 | 
						|
  if (VarIdStr[2] != NULL) {
 | 
						|
    strcpy (VarIdStr[2], BaseVarId);
 | 
						|
    strcat (VarIdStr[2], ".Day");
 | 
						|
  }
 | 
						|
 | 
						|
  if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) {
 | 
						|
    goto Err;
 | 
						|
  }
 | 
						|
  if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) {
 | 
						|
    goto Err;
 | 
						|
  }
 | 
						|
  if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) {
 | 
						|
    goto Err;
 | 
						|
  }
 | 
						|
 | 
						|
  if (QuestionId == EFI_QUESTION_ID_INVALID) {
 | 
						|
    QuestionId = GetFreeQuestionId ();
 | 
						|
  } else {
 | 
						|
    if (ChekQuestionIdFree (QuestionId) == FALSE) {
 | 
						|
      goto Err;
 | 
						|
    }
 | 
						|
    MarkQuestionIdUsed (QuestionId);
 | 
						|
  }
 | 
						|
 | 
						|
  pNode[0]->mQuestionId = QuestionId;
 | 
						|
  pNode[1]->mQuestionId = QuestionId;
 | 
						|
  pNode[2]->mQuestionId = QuestionId;
 | 
						|
  pNode[0]->mNext       = pNode[1];
 | 
						|
  pNode[1]->mNext       = pNode[2];
 | 
						|
  pNode[2]->mNext       = mQuestionList;
 | 
						|
  mQuestionList         = pNode[0];
 | 
						|
 | 
						|
  for (Index = 0; Index < 3; Index++) {
 | 
						|
    if (VarIdStr[Index] != NULL) {
 | 
						|
      delete VarIdStr[Index];
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
 | 
						|
  gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
 | 
						|
  gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
 | 
						|
 | 
						|
  return;
 | 
						|
 | 
						|
Err:
 | 
						|
  for (Index = 0; Index < 3; Index++) {
 | 
						|
    if (pNode[Index] != NULL) {
 | 
						|
      delete pNode[Index];
 | 
						|
    }
 | 
						|
 | 
						|
    if (VarIdStr[Index] != NULL) {
 | 
						|
      delete VarIdStr[Index];
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CVfrQuestionDB::RegisterOldTimeQuestion (
 | 
						|
  IN     CHAR8            *HourVarId,
 | 
						|
  IN     CHAR8            *MinuteVarId,
 | 
						|
  IN     CHAR8            *SecondVarId,
 | 
						|
  IN OUT EFI_QUESTION_ID &QuestionId
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrQuestionNode *pNode[3] = {NULL, };
 | 
						|
  UINT32           Index;
 | 
						|
 | 
						|
  if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) {
 | 
						|
    goto Err;
 | 
						|
  }
 | 
						|
  if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) {
 | 
						|
    goto Err;
 | 
						|
  }
 | 
						|
  if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) {
 | 
						|
    goto Err;
 | 
						|
  }
 | 
						|
 | 
						|
  if (QuestionId == EFI_QUESTION_ID_INVALID) {
 | 
						|
    QuestionId = GetFreeQuestionId ();
 | 
						|
  } else {
 | 
						|
    if (ChekQuestionIdFree (QuestionId) == FALSE) {
 | 
						|
      goto Err;
 | 
						|
    }
 | 
						|
    MarkQuestionIdUsed (QuestionId);
 | 
						|
  }
 | 
						|
 | 
						|
  pNode[0]->mQuestionId = QuestionId;
 | 
						|
  pNode[1]->mQuestionId = QuestionId;
 | 
						|
  pNode[2]->mQuestionId = QuestionId;
 | 
						|
  pNode[0]->mNext       = pNode[1];
 | 
						|
  pNode[1]->mNext       = pNode[2];
 | 
						|
  pNode[2]->mNext       = mQuestionList;
 | 
						|
  mQuestionList         = pNode[0];
 | 
						|
 | 
						|
  gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
 | 
						|
  gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
 | 
						|
  gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
 | 
						|
 | 
						|
  return;
 | 
						|
 | 
						|
Err:
 | 
						|
  for (Index = 0; Index < 3; Index++) {
 | 
						|
    if (pNode[Index] != NULL) {
 | 
						|
      delete pNode[Index];
 | 
						|
    }
 | 
						|
  }
 | 
						|
  QuestionId = EFI_QUESTION_ID_INVALID;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CVfrQuestionDB::RegisterNewTimeQuestion (
 | 
						|
  IN     CHAR8           *Name,
 | 
						|
  IN     CHAR8           *BaseVarId,
 | 
						|
  IN OUT EFI_QUESTION_ID &QuestionId
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrQuestionNode     *pNode[3] = {NULL, };
 | 
						|
  UINT32               Len;
 | 
						|
  CHAR8                *VarIdStr[3] = {NULL, };
 | 
						|
  CHAR8                 Index;
 | 
						|
 | 
						|
  if (BaseVarId == NULL) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  Len = strlen (BaseVarId);
 | 
						|
 | 
						|
  VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];
 | 
						|
  if (VarIdStr[0] != NULL) {
 | 
						|
    strcpy (VarIdStr[0], BaseVarId);
 | 
						|
    strcat (VarIdStr[0], ".Hour");
 | 
						|
  }
 | 
						|
  VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];
 | 
						|
  if (VarIdStr[1] != NULL) {
 | 
						|
    strcpy (VarIdStr[1], BaseVarId);
 | 
						|
    strcat (VarIdStr[1], ".Minute");
 | 
						|
  }
 | 
						|
  VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];
 | 
						|
  if (VarIdStr[2] != NULL) {
 | 
						|
    strcpy (VarIdStr[2], BaseVarId);
 | 
						|
    strcat (VarIdStr[2], ".Second");
 | 
						|
  }
 | 
						|
 | 
						|
  if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) {
 | 
						|
    goto Err;
 | 
						|
  }
 | 
						|
  if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) {
 | 
						|
    goto Err;
 | 
						|
  }
 | 
						|
  if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) {
 | 
						|
    goto Err;
 | 
						|
  }
 | 
						|
 | 
						|
  if (QuestionId == EFI_QUESTION_ID_INVALID) {
 | 
						|
    QuestionId = GetFreeQuestionId ();
 | 
						|
  } else {
 | 
						|
    if (ChekQuestionIdFree (QuestionId) == FALSE) {
 | 
						|
      goto Err;
 | 
						|
    }
 | 
						|
    MarkQuestionIdUsed (QuestionId);
 | 
						|
  }
 | 
						|
 | 
						|
  pNode[0]->mQuestionId = QuestionId;
 | 
						|
  pNode[1]->mQuestionId = QuestionId;
 | 
						|
  pNode[2]->mQuestionId = QuestionId;
 | 
						|
  pNode[0]->mNext       = pNode[1];
 | 
						|
  pNode[1]->mNext       = pNode[2];
 | 
						|
  pNode[2]->mNext       = mQuestionList;
 | 
						|
  mQuestionList         = pNode[0];
 | 
						|
 | 
						|
  for (Index = 0; Index < 3; Index++) {
 | 
						|
    if (VarIdStr[Index] != NULL) {
 | 
						|
      delete VarIdStr[Index];
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
 | 
						|
  gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
 | 
						|
  gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
 | 
						|
 | 
						|
  return;
 | 
						|
 | 
						|
Err:
 | 
						|
  for (Index = 0; Index < 3; Index++) {
 | 
						|
    if (pNode[Index] != NULL) {
 | 
						|
      delete pNode[Index];
 | 
						|
    }
 | 
						|
 | 
						|
    if (VarIdStr[Index] != NULL) {
 | 
						|
      delete VarIdStr[Index];
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrQuestionDB::UpdateQuestionId (
 | 
						|
  IN EFI_QUESTION_ID   QId,
 | 
						|
  IN EFI_QUESTION_ID   NewQId
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrQuestionNode *pNode = NULL;
 | 
						|
  
 | 
						|
  if (QId == NewQId) {
 | 
						|
    // don't update
 | 
						|
    return VFR_RETURN_SUCCESS;
 | 
						|
  }
 | 
						|
  
 | 
						|
  //
 | 
						|
  // For Framework Vfr, don't check question ID conflict.
 | 
						|
  //  
 | 
						|
  if (!VfrCompatibleMode && ChekQuestionIdFree (NewQId) == FALSE) {
 | 
						|
    return VFR_RETURN_REDEFINED;
 | 
						|
  }
 | 
						|
 | 
						|
  for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (pNode->mQuestionId == QId) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (pNode == NULL) {
 | 
						|
    return VFR_RETURN_UNDEFINED;
 | 
						|
  }
 | 
						|
 | 
						|
  MarkQuestionIdUnused (QId);
 | 
						|
  pNode->mQuestionId = NewQId;
 | 
						|
  MarkQuestionIdUsed (NewQId);
 | 
						|
 | 
						|
  gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID));
 | 
						|
 | 
						|
  return VFR_RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CVfrQuestionDB::GetQuestionId (
 | 
						|
  IN  CHAR8             *Name,
 | 
						|
  IN  CHAR8             *VarIdStr,
 | 
						|
  OUT EFI_QUESTION_ID   &QuestionId,
 | 
						|
  OUT UINT32            &BitMask
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrQuestionNode *pNode;
 | 
						|
 | 
						|
  QuestionId = EFI_QUESTION_ID_INVALID;
 | 
						|
  BitMask    = 0x00000000;
 | 
						|
 | 
						|
  if ((Name == NULL) && (VarIdStr == NULL)) {
 | 
						|
    return ;
 | 
						|
  }
 | 
						|
 | 
						|
  for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (Name != NULL) {
 | 
						|
      if (strcmp (pNode->mName, Name) != 0) {
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (VarIdStr != NULL) {
 | 
						|
      if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
  	}
 | 
						|
 | 
						|
    QuestionId = pNode->mQuestionId;
 | 
						|
    BitMask    = pNode->mBitMask;
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  return ;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrQuestionDB::FindQuestion (
 | 
						|
  IN EFI_QUESTION_ID QuestionId
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrQuestionNode *pNode;
 | 
						|
 | 
						|
  if (QuestionId == EFI_QUESTION_ID_INVALID) {
 | 
						|
    return VFR_RETURN_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (pNode->mQuestionId == QuestionId) {
 | 
						|
      return VFR_RETURN_SUCCESS;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return VFR_RETURN_UNDEFINED;
 | 
						|
}
 | 
						|
 | 
						|
EFI_VFR_RETURN_CODE
 | 
						|
CVfrQuestionDB::FindQuestion (
 | 
						|
  IN CHAR8 *Name
 | 
						|
  )
 | 
						|
{
 | 
						|
  SVfrQuestionNode *pNode;
 | 
						|
 | 
						|
  if (Name == NULL) {
 | 
						|
    return VFR_RETURN_FATAL_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
 | 
						|
    if (strcmp (pNode->mName, Name) == 0) {
 | 
						|
      return VFR_RETURN_SUCCESS;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return VFR_RETURN_UNDEFINED;
 | 
						|
}
 | 
						|
 | 
						|
BOOLEAN  VfrCompatibleMode = FALSE;
 | 
						|
 | 
						|
CVfrVarDataTypeDB gCVfrVarDataTypeDB;
 | 
						|
 |