- Index = 0;\r
- VarStoreName = NULL;\r
- Status = EFI_SUCCESS;\r
- BlockData = NULL;\r
- NewBlockData = NULL;\r
- TmpBuffer = NULL;\r
- MaxBufferSize = HII_LIB_DEFAULT_VARSTORE_SIZE;\r
- VarBuffer = AllocateZeroPool (MaxBufferSize);\r
- if (VarBuffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Init CurrentBlockArray\r
- //\r
- CurrentBlockArray = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
- if (CurrentBlockArray == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
- InitializeListHead (&CurrentBlockArray->Entry);\r
- \r
- //\r
- // Parse each <RequestElement> if exists\r
- // Only <BlockName> format is supported by this help function.\r
- // <BlockName> ::= &'OFFSET='<Number>&'WIDTH='<Number>\r
- //\r
- while (*StringPtr != 0 && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) == 0) {\r
- //\r
- // Skip the &OFFSET= string\r
- // \r
- StringPtr += StrLen (L"&OFFSET=");\r
-\r
- //\r
- // Get Offset\r
- //\r
- Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- Offset = 0;\r
- CopyMem (\r
- &Offset,\r
- TmpBuffer,\r
- (((Length + 1) / 2) < sizeof (UINT16)) ? ((Length + 1) / 2) : sizeof (UINT16)\r
- );\r
- FreePool (TmpBuffer);\r
- TmpBuffer = NULL;\r
-\r
- StringPtr += Length;\r
- if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
- StringPtr += StrLen (L"&WIDTH=");\r
-\r
- //\r
- // Get Width\r
- //\r
- Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- Width = 0;\r
- CopyMem (\r
- &Width,\r
- TmpBuffer,\r
- (((Length + 1) / 2) < sizeof (UINT16)) ? ((Length + 1) / 2) : sizeof (UINT16)\r
- );\r
- FreePool (TmpBuffer);\r
- TmpBuffer = NULL;\r
-\r
- StringPtr += Length;\r
- if (*StringPtr != 0 && *StringPtr != L'&') {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) != 0) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
- StringPtr += StrLen (L"&VALUE=");\r
-\r
- //\r
- // Get Value\r
- //\r
- Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- StringPtr += Length;\r
- if (*StringPtr != 0 && *StringPtr != L'&') {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- //\r
- // Check whether VarBuffer is enough\r
- //\r
- if ((UINTN) (Offset + Width) > MaxBufferSize) {\r
- VarBuffer = ReallocatePool (\r
- MaxBufferSize,\r
- Offset + Width + HII_LIB_DEFAULT_VARSTORE_SIZE,\r
- VarBuffer\r
- );\r
- if (VarBuffer == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
- MaxBufferSize = Offset + Width + HII_LIB_DEFAULT_VARSTORE_SIZE;\r
- }\r
-\r
- //\r
- // Update the Block with configuration info\r
- //\r
- CopyMem (VarBuffer + Offset, TmpBuffer, Width);\r
- FreePool (TmpBuffer);\r
- TmpBuffer = NULL;\r
-\r
- //\r
- // Set new Block Data\r
- //\r
- NewBlockData = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
- if (NewBlockData == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
- NewBlockData->Offset = Offset;\r
- NewBlockData->Width = Width;\r
-\r
- //\r
- // Insert the new block data into the block data array.\r
- //\r
- for (Link = CurrentBlockArray->Entry.ForwardLink; Link != &CurrentBlockArray->Entry; Link = Link->ForwardLink) {\r
- BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
- if (NewBlockData->Offset == BlockData->Offset) {\r
- if (NewBlockData->Width > BlockData->Width) {\r
- BlockData->Width = NewBlockData->Width;\r
- }\r
- FreePool (NewBlockData);\r
- break;\r
- } else if (NewBlockData->Offset < BlockData->Offset) {\r
- //\r
- // Insert new block data as the previous one of this link.\r
- //\r
- InsertTailList (Link, &NewBlockData->Entry);\r
- break;\r
- }\r
- }\r
-\r
- //\r
- // Insert new block data into the array tail.\r
- //\r
- if (Link == &CurrentBlockArray->Entry) {\r
- InsertTailList (Link, &NewBlockData->Entry);\r
- }\r
-\r
- //\r
- // If '\0', parsing is finished. \r
- //\r
- if (*StringPtr == 0) {\r
- break;\r
- }\r
- //\r
- // Go to next ConfigBlock \r
- //\r
- }\r
-\r
- //\r
- // Merge the aligned block data into the single block data.\r
- //\r
- Link = CurrentBlockArray->Entry.ForwardLink;\r
- while ((Link != &CurrentBlockArray->Entry) && (Link->ForwardLink != &CurrentBlockArray->Entry)) {\r
- BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
- NewBlockData = BASE_CR (Link->ForwardLink, IFR_BLOCK_DATA, Entry);\r
- if ((NewBlockData->Offset >= BlockData->Offset) && (NewBlockData->Offset <= (BlockData->Offset + BlockData->Width))) {\r
- if ((NewBlockData->Offset + NewBlockData->Width) > (BlockData->Offset + BlockData->Width)) {\r
- BlockData->Width = (UINT16) (NewBlockData->Offset + NewBlockData->Width - BlockData->Offset);\r
- }\r
- RemoveEntryList (Link->ForwardLink);\r
- FreePool (NewBlockData);\r
- continue;\r
- }\r
- Link = Link->ForwardLink; \r
- }\r
- \r
- if (IsListEmpty (&CurrentBlockArray->Entry)) {\r
- Status = EFI_SUCCESS;\r
- goto Done;\r
- }\r