+++ /dev/null
-/**@file\r
- Entry and initialization module for the browser.\r
-\r
-Copyright (c) 2006 - 2007 Intel Corporation. <BR>\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "Setup.h"\r
-#include "Ui.h"\r
-\r
-FUNCTIION_KEY_SETTING gFunctionKeySettingTable[] = {\r
- //\r
- // Boot Manager\r
- //\r
- {\r
- {\r
- 0x847bc3fe,\r
- 0xb974,\r
- 0x446d,\r
- {\r
- 0x94,\r
- 0x49,\r
- 0x5a,\r
- 0xd5,\r
- 0x41,\r
- 0x2e,\r
- 0x99,\r
- 0x3b\r
- }\r
- },\r
- NONE_FUNCTION_KEY_SETTING\r
- },\r
- //\r
- // Device Manager\r
- //\r
- {\r
- {\r
- 0x3ebfa8e6,\r
- 0x511d,\r
- 0x4b5b,\r
- {\r
- 0xa9,\r
- 0x5f,\r
- 0xfb,\r
- 0x38,\r
- 0x26,\r
- 0xf,\r
- 0x1c,\r
- 0x27\r
- }\r
- },\r
- NONE_FUNCTION_KEY_SETTING\r
- },\r
- //\r
- // BMM Formset.\r
- //\r
- {\r
- {\r
- 0x642237c7,\r
- 0x35d4,\r
- 0x472d,\r
- {\r
- 0x83,\r
- 0x65,\r
- 0x12,\r
- 0xe0,\r
- 0xcc,\r
- 0xf2,\r
- 0x7a,\r
- 0x22\r
- }\r
- },\r
- NONE_FUNCTION_KEY_SETTING\r
- },\r
- //\r
- // BMM File Explorer Formset.\r
- //\r
- {\r
- {\r
- 0x1f2d63e1,\r
- 0xfebd,\r
- 0x4dc7,\r
- {\r
- 0x9c,\r
- 0xc5,\r
- 0xba,\r
- 0x2b,\r
- 0x1c,\r
- 0xef,\r
- 0x9c,\r
- 0x5b\r
- }\r
- },\r
- NONE_FUNCTION_KEY_SETTING\r
- },\r
-};\r
-\r
-STATIC\r
-EFI_STATUS\r
-InitializeBinaryStructures (\r
- IN EFI_HII_HANDLE *Handle,\r
- IN BOOLEAN UseDatabase,\r
- IN EFI_IFR_PACKET *Packet,\r
- IN UINT8 *NvMapOverride,\r
- IN UINTN NumberOfIfrImages,\r
- EFI_FILE_FORM_TAGS **FileFormTagsHead\r
- );\r
-\r
-STATIC\r
-EFI_STATUS\r
-InitializeTagStructures (\r
- IN EFI_IFR_BINARY *BinaryData,\r
- OUT EFI_FILE_FORM_TAGS *FileFormTags\r
- );\r
-\r
-STATIC\r
-UI_MENU_OPTION *\r
-DisplayHomePage (\r
- IN UINTN NumberOfIfrImages,\r
- IN EFI_FILE_FORM_TAGS *FileFormTagsHead,\r
- IN UINT8 *CallbackData\r
- );\r
-\r
-STATIC\r
-EFI_STATUS\r
-GetIfrBinaryData (\r
- IN EFI_HII_PROTOCOL *Hii,\r
- IN EFI_HII_HANDLE HiiHandle,\r
- IN EFI_IFR_PACKET *Packet,\r
- IN EFI_IFR_BINARY *BinaryData\r
- );\r
-\r
-STATIC\r
-EFI_STATUS\r
-InstallPrint (\r
- VOID\r
- );\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-SendForm (\r
- IN EFI_FORM_BROWSER_PROTOCOL * This,\r
- IN BOOLEAN UseDatabase,\r
- IN EFI_HII_HANDLE * Handle,\r
- IN UINTN HandleCount,\r
- IN EFI_IFR_PACKET * Packet,\r
- IN EFI_HANDLE CallbackHandle,\r
- IN UINT8 *NvMapOverride,\r
- IN EFI_SCREEN_DESCRIPTOR *ScreenDimensions, OPTIONAL\r
- OUT BOOLEAN *ResetRequired OPTIONAL\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This is the routine which an external caller uses to direct the browser\r
- where to obtain it's information.\r
-\r
-Arguments:\r
-\r
- UseDatabase - If set to TRUE, then all information is retrieved from the HII database handle specified\r
- If set to FALSE, then the passed in Packet and CallbackHandle is used and Handle is ignored\r
-\r
- Handle - A pointer to an array of Handles. If HandleCount > 1 we display a list of the formsets for the handles specified\r
-\r
- HandleCount - The number of Handles specified in Handle.\r
-\r
- Packet - Valid only if UseDatabase is FALSE. Packet defines the pages being passed into\r
- the browser. This is composed of IFR data as well as String information.\r
-\r
- CallbackHandle - The handle which contains the calling driver's EFI_FORM_CALLBACK_PROTOCOL interface.\r
-\r
- ScreenDimenions - This allows the browser to be called so that it occupies a portion of the physical screen instead of\r
- dynamically determining the screen dimensions.\r
-\r
- NvMapOverride - This buffer is used only when there is no NV variable to define the current settings and the caller\r
- needs to provide to the browser the current settings for the "fake" NV variable. If used, no saving\r
- of an NV variable will be possible. This parameter is also ignored if HandleCount > 1.\r
-\r
-Returns:\r
-\r
---*/\r
-{\r
- EFI_FORM_CALLBACK_PROTOCOL *FormCallback;\r
- EFI_FILE_FORM_TAGS *FileFormTagsHead;\r
- UI_MENU_OPTION *Selection;\r
- UI_MENU_OPTION *AltSelection;\r
- EFI_STATUS Status;\r
- BOOLEAN Callback;\r
- VOID *CallbackData;\r
- EFI_HII_HANDLE BackupHandle;\r
-\r
- ZeroMem (&gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
-\r
- gPreviousValue = AllocatePool (0x1000);\r
- CallbackData = AllocatePool (0x10000);\r
- ASSERT (gPreviousValue != NULL);\r
- ASSERT (CallbackData != NULL);\r
-\r
- do {\r
- //\r
- // Seed the dimensions in the global\r
- //\r
- gST->ConOut->QueryMode (\r
- gST->ConOut,\r
- gST->ConOut->Mode->Mode,\r
- &gScreenDimensions.RightColumn,\r
- &gScreenDimensions.BottomRow\r
- );\r
-\r
- if (ScreenDimensions != NULL) {\r
- //\r
- // Check local dimension vs. global dimension.\r
- //\r
- if ((gScreenDimensions.RightColumn < ScreenDimensions->RightColumn) ||\r
- (gScreenDimensions.BottomRow < ScreenDimensions->BottomRow)\r
- ) {\r
- return EFI_INVALID_PARAMETER;\r
- } else {\r
- //\r
- // Local dimension validation.\r
- //\r
- if ((ScreenDimensions->RightColumn > ScreenDimensions->LeftColumn) &&\r
- (ScreenDimensions->BottomRow > ScreenDimensions->TopRow) &&\r
- ((ScreenDimensions->RightColumn - ScreenDimensions->LeftColumn) > 2) &&\r
- (\r
- (ScreenDimensions->BottomRow - ScreenDimensions->TopRow) > STATUS_BAR_HEIGHT +\r
- SCROLL_ARROW_HEIGHT *\r
- 2 +\r
- FRONT_PAGE_HEADER_HEIGHT +\r
- FOOTER_HEIGHT +\r
- 1\r
- )\r
- ) {\r
- CopyMem (&gScreenDimensions, ScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
- } else {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
- }\r
-\r
- gOptionBlockWidth = (CHAR16) ((gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3);\r
- gHelpBlockWidth = gOptionBlockWidth;\r
- gPromptBlockWidth = gOptionBlockWidth;\r
-\r
- //\r
- // Initialize the strings for the browser, upon exit of the browser, the strings will be freed\r
- //\r
- InitializeBrowserStrings ();\r
-\r
- gFunctionKeySetting = DEFAULT_FUNCTION_KEY_SETTING;\r
- gClassOfVfr = EFI_SETUP_APPLICATION_SUBCLASS;\r
- gResetRequired = FALSE;\r
- gExitRequired = FALSE;\r
- gSaveRequired = FALSE;\r
- gNvUpdateRequired = FALSE;\r
- gActiveIfr = 0;\r
- gConsistencyId = 0;\r
- gPriorMenuEntry = 0;\r
- BackupHandle = *Handle;\r
- gMenuRefreshHead = NULL;\r
- ASSERT (CallbackData);\r
- ZeroMem (CallbackData, 0x10000);\r
-\r
- //\r
- // We can recurse through this and might need to re-allocate this particular buffer\r
- //\r
- if (gPreviousValue == NULL) {\r
- gPreviousValue = AllocatePool (0x1000);\r
- ASSERT (gPreviousValue != NULL);\r
- }\r
-\r
- Callback = FALSE;\r
- FormCallback = NULL;\r
-\r
- if (CallbackHandle != NULL) {\r
- //\r
- // Retrieve the Callback protocol interface\r
- //\r
- Status = gBS->HandleProtocol (\r
- CallbackHandle,\r
- &gEfiFormCallbackProtocolGuid,\r
- (VOID **) &FormCallback\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- FreePool (CallbackData);\r
- return Status;;\r
- }\r
-\r
- Callback = TRUE;\r
- }\r
- //\r
- // Initializes all the internal state structures for all IFR images in system\r
- //\r
- Status = InitializeBinaryStructures (Handle, UseDatabase, Packet, NvMapOverride, HandleCount, &FileFormTagsHead);\r
-\r
- if (EFI_ERROR (Status)) {\r
- FreePool (CallbackData);\r
- return Status;\r
- }\r
- //\r
- // Beginning of the Presentation of the Data\r
- //\r
- if (UseDatabase && (HandleCount > 1)) {\r
- Selection = DisplayHomePage (HandleCount, FileFormTagsHead, CallbackData);\r
- } else {\r
- //\r
- // If passing something specific, we know there is only one Ifr\r
- //\r
- Selection = AllocateZeroPool (sizeof (UI_MENU_OPTION));\r
- ASSERT (Selection != NULL);\r
- Selection->IfrNumber = 0;\r
- Selection->Handle = Handle[0];\r
- UiInitMenu ();\r
- }\r
-\r
- UiInitMenuList ();\r
-\r
- if (UseDatabase && (HandleCount > 1)) {\r
- if (Selection == NULL) {\r
- FreePool (CallbackData);\r
- return EFI_SUCCESS;\r
- }\r
- }\r
- //\r
- // Launch the setup browser with the user's selection information\r
- //\r
- AltSelection = SetupBrowser (Selection, Callback, FileFormTagsHead, CallbackData);\r
-\r
- //\r
- // If the caller cares about Reset status, we can return to the caller if something happened that required a reset\r
- //\r
- if (ResetRequired != NULL) {\r
- *ResetRequired = gResetRequired;\r
- }\r
-\r
- if (Callback && (AltSelection != NULL)) {\r
- if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) {\r
- Status = FormCallback->Callback (\r
- FormCallback,\r
- AltSelection->ThisTag->Key,\r
- CallbackData,\r
- (EFI_HII_CALLBACK_PACKET **) &Packet\r
- );\r
- }\r
- }\r
-\r
- *Handle = BackupHandle;\r
-\r
- if (EFI_ERROR (Status)) {\r
- FreePool (CallbackData);\r
- return Status;\r
- }\r
-\r
- if (Callback && (AltSelection == NULL)) {\r
- FreePool (CallbackData);\r
- return Status;\r
- }\r
-\r
- if (UseDatabase && (HandleCount > 1)) {\r
- } else {\r
-\r
- if (gBinaryDataHead->UnRegisterOnExit) {\r
- Hii->RemovePack (Hii, Handle[0]);\r
- }\r
-\r
- if (Callback &&\r
- ((AltSelection->ThisTag->SubClass == EFI_FRONT_PAGE_SUBCLASS) ||\r
- (AltSelection->ThisTag->SubClass == EFI_SINGLE_USE_SUBCLASS))) {\r
- //\r
- // If this is the FrontPage, return after every selection\r
- //\r
- FreePool (Selection);\r
- UiFreeMenu ();\r
-\r
- //\r
- // Clean up the allocated data buffers\r
- //\r
- FreeData (FileFormTagsHead, NULL, NULL);\r
-\r
- gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
- gST->ConOut->ClearScreen (gST->ConOut);\r
-\r
- FreePool (CallbackData);\r
- return EFI_SUCCESS;\r
- }\r
-\r
- FreePool (Selection);\r
- UiFreeMenu ();\r
-\r
- //\r
- // Clean up the allocated data buffers\r
- //\r
- FreeData (FileFormTagsHead, NULL, NULL);\r
-\r
- gST->ConOut->ClearScreen (gST->ConOut);\r
-\r
- if (!Callback) {\r
- FreePool (CallbackData);\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- } while (!EFI_ERROR (Status));\r
-\r
- FreePool (CallbackData);\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-InitializeSetup (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Initialize Setup\r
-\r
-Arguments:\r
- (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)\r
-\r
-Returns:\r
- EFI_SUCCESS - Setup loaded.\r
- other - Setup Error\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_FORM_CONFIGURATION_DATA *FormData;\r
- EFI_FORM_BROWSER_PROTOCOL *FormBrowser;\r
- EFI_HANDLE Handle;\r
- EFI_HII_PACKAGES *PackageList;\r
-\r
- //\r
- // There will be only one FormConfig in the system\r
- // If there is another out there, someone is trying to install us\r
- // again. Fail that scenario.\r
- //\r
- Status = gBS->LocateProtocol (\r
- &gEfiFormBrowserProtocolGuid,\r
- NULL,\r
- (VOID **) &FormBrowser\r
- );\r
-\r
- gFirstIn = TRUE;\r
-\r
- //\r
- // If there was no error, assume there is an installation and fail to load\r
- //\r
- if (!EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- FormData = AllocatePool (sizeof (EFI_FORM_CONFIGURATION_DATA));\r
-\r
- if (FormData == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // Fill in HII data\r
- //\r
- FormData->Signature = EFI_FORM_DATA_SIGNATURE;\r
- FormData->FormConfig.SendForm = SendForm;\r
- FormData->FormConfig.CreatePopUp = CreateDialog;\r
-\r
- //\r
- // There should only be one HII image\r
- //\r
- Status = gBS->LocateProtocol (\r
- &gEfiHiiProtocolGuid,\r
- NULL,\r
- (VOID **) &FormData->Hii\r
- );\r
-\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- Hii = FormData->Hii;\r
-\r
- PackageList = PreparePackages (1, &gEfiFormBrowserProtocolGuid, SetupBrowserStrings);\r
-\r
- Status = Hii->NewPack (Hii, PackageList, &gHiiHandle);\r
-\r
- FreePool (PackageList);\r
-\r
- //\r
- // Install protocol interface\r
- //\r
- Handle = NULL;\r
- Status = gBS->InstallProtocolInterface (\r
- &Handle,\r
- &gEfiFormBrowserProtocolGuid,\r
- EFI_NATIVE_INTERFACE,\r
- &FormData->FormConfig\r
- );\r
-\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- BannerData = AllocateZeroPool (sizeof (BANNER_DATA));\r
- ASSERT (BannerData != NULL);\r
-\r
- Status = InstallPrint ();\r
- return Status;\r
-}\r
-\r
-VOID\r
-GetQuestionHeader (\r
- IN EFI_TAG *Tag,\r
- IN UINT8 *RawFormSet,\r
- IN UINT16 Index,\r
- IN EFI_FILE_FORM_TAGS *FileFormTags,\r
- IN UINT16 CurrentVariable\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Initialize question tag's members.\r
-\r
-Arguments:\r
- Tag - Pointer of the current EFI_TAG structure.\r
- RawFormSet - Pointer of the formset raw data.\r
- Index - Offset of the current opcode in the Ifr raw data.\r
- FileFormTags - Pointer of current EFI_FILE_FORM_TAGS structure.\r
- CurrentVariable - Current variable number.\r
-\r
-Returns:\r
- None.\r
---*/\r
-{\r
- EFI_VARIABLE_DEFINITION *VariableDefinition;\r
-\r
- Tag->NumberOfLines = 1;\r
- Tag->VariableNumber = CurrentVariable;\r
- CopyMem (&Tag->Id, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->QuestionId, sizeof (UINT16));\r
- CopyMem (&Tag->StorageStart, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->QuestionId, sizeof (UINT16));\r
- CopyMem (&Tag->StorageWidth, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Width, sizeof (UINT8));\r
- CopyMem (&Tag->Text, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Prompt, sizeof (UINT16));\r
- CopyMem (&Tag->Help, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Help, sizeof (UINT16));\r
-\r
- VariableDefinition = FileFormTags->VariableDefinitions;\r
-\r
- for (; VariableDefinition != NULL; VariableDefinition = VariableDefinition->Next) {\r
- //\r
- // Have we found the correct variable for the request?\r
- //\r
- if (CurrentVariable == VariableDefinition->VariableId) {\r
- if (VariableDefinition->VariableSize < (UINTN) (Tag->StorageStart + Tag->StorageWidth)) {\r
- VariableDefinition->VariableFakeSize = (UINT16) (VariableDefinition->VariableFakeSize + Tag->StorageWidth);\r
- }\r
-\r
- if (VariableDefinition->NvRamMap != NULL) {\r
- //\r
- // If it is an 8bit or 16bit width, then move it to Tag->Value, otherwise\r
- // we will never be looking for the data in Tag->Value (e.g. strings, password, etc)\r
- //\r
- if (Tag->StorageWidth == (UINT16) 1) {\r
- CopyMem (&Tag->Value, &VariableDefinition->NvRamMap[Tag->StorageStart], sizeof (UINT16));\r
- }\r
-\r
- if (Tag->StorageWidth == (UINT16) 2) {\r
- Index = (UINT16)\r
- (\r
- VariableDefinition->NvRamMap[Tag->StorageStart] +\r
- (VariableDefinition->NvRamMap[Tag->StorageStart + 1] * 0x100)\r
- );\r
- CopyMem (&Tag->Value, &Index, sizeof (UINT16));\r
- }\r
- } else {\r
- Index = 0;\r
- CopyMem (&Tag->Value, &Index, sizeof (UINT16));\r
- }\r
- break;\r
- }\r
- }\r
-}\r
-\r
-VOID\r
-GetNumericHeader (\r
- IN EFI_TAG *Tag,\r
- IN UINT8 *RawFormSet,\r
- IN UINT16 Index,\r
- IN UINT16 NumberOfLines,\r
- IN EFI_FILE_FORM_TAGS *FileFormTags,\r
- IN UINT16 CurrentVariable\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Initialize numeric tag's members.\r
-\r
-Arguments:\r
- Tag - Pointer of the current EFI_TAG structure.\r
- RawFormSet - Pointer of the formset raw data.\r
- Index - Offset of the current opcode in the Ifr raw data.\r
- NumberOfLines - Number of lines this opcode occupied.\r
- FileFormTags - Pointer of current EFI_FILE_FORM_TAGS structure.\r
- CurrentVariable - Current variable number.\r
-\r
-Returns:\r
- None.\r
---*/\r
-{\r
- EFI_VARIABLE_DEFINITION *VariableDefinition;\r
-\r
- Tag->NumberOfLines = NumberOfLines;\r
- Tag->VariableNumber = CurrentVariable;\r
- CopyMem (&Tag->Id, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->QuestionId, sizeof (UINT16));\r
- CopyMem (&Tag->StorageStart, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->QuestionId, sizeof (UINT16));\r
- CopyMem (&Tag->StorageWidth, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Width, sizeof (UINT8));\r
- CopyMem (&Tag->Text, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Prompt, sizeof (UINT16));\r
- CopyMem (&Tag->Help, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Help, sizeof (UINT16));\r
- CopyMem (&Tag->Minimum, &((EFI_IFR_NUMERIC *) &RawFormSet[Index])->Minimum, sizeof (UINT16));\r
- CopyMem (&Tag->Maximum, &((EFI_IFR_NUMERIC *) &RawFormSet[Index])->Maximum, sizeof (UINT16));\r
- CopyMem (&Tag->Step, &((EFI_IFR_NUMERIC *) &RawFormSet[Index])->Step, sizeof (UINT16));\r
- CopyMem (&Tag->Default, &((EFI_IFR_NUMERIC *) &RawFormSet[Index])->Default, sizeof (UINT16));\r
- Tag->ResetRequired = (BOOLEAN) (((EFI_IFR_NUMERIC *) &RawFormSet[Index])->Flags & EFI_IFR_FLAG_RESET_REQUIRED);\r
-\r
- VariableDefinition = FileFormTags->VariableDefinitions;\r
-\r
- for (; VariableDefinition != NULL; VariableDefinition = VariableDefinition->Next) {\r
- //\r
- // Have we found the correct variable for the request?\r
- //\r
- if (CurrentVariable == VariableDefinition->VariableId) {\r
- if (VariableDefinition->VariableSize <= (UINTN) (Tag->StorageStart + Tag->StorageWidth)) {\r
- if (Tag->StorageWidth == 0) {\r
- VariableDefinition->VariableFakeSize = (UINT16) (VariableDefinition->VariableFakeSize + 2);\r
- } else {\r
- VariableDefinition->VariableFakeSize = (UINT16) (VariableDefinition->VariableFakeSize + Tag->StorageWidth);\r
- }\r
- }\r
-\r
- if (VariableDefinition->NvRamMap != NULL) {\r
- //\r
- // If it is an 8bit or 16bit width, then move it to Tag->Value, otherwise\r
- // we will never be looking for the data in Tag->Value (e.g. strings, password, etc)\r
- //\r
- if (Tag->StorageWidth == (UINT16) 1) {\r
- CopyMem (&Tag->Value, &VariableDefinition->NvRamMap[Tag->StorageStart], sizeof (UINT16));\r
- }\r
-\r
- if (Tag->StorageWidth == (UINT16) 2) {\r
- Index = (UINT16)\r
- (\r
- VariableDefinition->NvRamMap[Tag->StorageStart] +\r
- (VariableDefinition->NvRamMap[Tag->StorageStart + 1] * 0x100)\r
- );\r
- CopyMem (&Tag->Value, &Index, sizeof (UINT16));\r
- }\r
- } else {\r
- CopyMem (&Tag->Value, &Tag->Default, sizeof (UINT16));\r
- }\r
- break;\r
- }\r
- }\r
-}\r
-\r
-VOID\r
-GetTagCount (\r
- IN UINT8 *RawFormSet,\r
- IN OUT UINT16 *NumberOfTags\r
- )\r
-{\r
- UINT16 Index;\r
-\r
- //\r
- // Assume on entry we are pointing to an OpCode - reasonably this should\r
- // be a FormOp since the purpose is to count the tags in a particular Form.\r
- //\r
- for (Index = 0; RawFormSet[Index] != EFI_IFR_END_FORM_OP;) {\r
- //\r
- // If we encounter the end of a form set, bail out\r
- //\r
- if (RawFormSet[Index] == EFI_IFR_END_FORM_SET_OP) {\r
- break;\r
- }\r
- //\r
- // We treat date/time internally as three op-codes\r
- //\r
- if (RawFormSet[Index] == EFI_IFR_DATE_OP || RawFormSet[Index] == EFI_IFR_TIME_OP) {\r
- *NumberOfTags = (UINT16) (*NumberOfTags + 3);\r
- } else {\r
- //\r
- // Assume that we could have no more tags than op-codes\r
- //\r
- (*NumberOfTags)++;\r
- }\r
-\r
- Index = (UINT16) (Index + RawFormSet[Index + 1]);\r
- }\r
- //\r
- // Increase the tag count by one so it is inclusive of the end_form_op\r
- //\r
- (*NumberOfTags)++;\r
-}\r
-\r
-STATIC\r
-VOID\r
-AddNextInconsistentTag (\r
- IN OUT EFI_INCONSISTENCY_DATA **InconsistentTagsPtr\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Initialize the next inconsistent tag data and add it to the inconsistent tag list.\r
-\r
-Arguments:\r
- InconsistentTagsPtr - Pointer of the inconsistent tag's pointer.\r
-\r
-Returns:\r
- None.\r
-\r
---*/\r
-{\r
- EFI_INCONSISTENCY_DATA *PreviousInconsistentTags;\r
- EFI_INCONSISTENCY_DATA *InconsistentTags;\r
-\r
- InconsistentTags = *InconsistentTagsPtr;\r
- //\r
- // We just hit the end of an inconsistent expression. Let's allocate the ->Next structure\r
- //\r
- InconsistentTags->Next = AllocatePool (sizeof (EFI_INCONSISTENCY_DATA));\r
- ASSERT (InconsistentTags->Next != NULL);\r
-\r
- //\r
- // Preserve current Tag entry\r
- //\r
- PreviousInconsistentTags = InconsistentTags;\r
-\r
- InconsistentTags = InconsistentTags->Next;\r
-\r
- //\r
- // This will zero on the entry including the ->Next so I don't have to do it\r
- //\r
- ZeroMem (InconsistentTags, sizeof (EFI_INCONSISTENCY_DATA));\r
-\r
- //\r
- // Point our Previous field to the previous entry\r
- //\r
- InconsistentTags->Previous = PreviousInconsistentTags;\r
-\r
- *InconsistentTagsPtr = InconsistentTags;\r
-\r
- return ;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-InitializeTagStructures (\r
- IN EFI_IFR_BINARY *BinaryData,\r
- OUT EFI_FILE_FORM_TAGS *FileFormTags\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 *RawFormSet;\r
- UINT16 Index;\r
- UINT16 QuestionIndex;\r
- UINT16 NumberOfTags;\r
- INT16 CurrTag;\r
- UINT8 TagLength;\r
- EFI_FORM_TAGS *FormTags;\r
- EFI_FORM_TAGS *SavedFormTags;\r
- EFI_INCONSISTENCY_DATA *InconsistentTags;\r
- EFI_VARIABLE_DEFINITION *VariableDefinitions;\r
- UINTN Count;\r
- UINT16 Class;\r
- UINT16 SubClass;\r
- UINT16 TempValue;\r
- UINT16 CurrentVariable;\r
- UINT16 CurrentVariable2;\r
-\r
- //\r
- // Initialize some Index variable and Status\r
- //\r
- Count = 0;\r
- Class = 0;\r
- SubClass = 0;\r
- CurrentVariable = 0;\r
- CurrentVariable2 = 0;\r
- QuestionIndex = 0;\r
- NumberOfTags = 1;\r
- Status = EFI_SUCCESS;\r
- FormTags = &FileFormTags->FormTags;\r
- FormTags->Next = NULL;\r
- if (FileFormTags->InconsistentTags == NULL) {\r
- InconsistentTags = NULL;\r
- } else {\r
- InconsistentTags = FileFormTags->InconsistentTags;\r
- }\r
-\r
- if (FileFormTags->VariableDefinitions == NULL) {\r
- VariableDefinitions = NULL;\r
- } else {\r
- VariableDefinitions = FileFormTags->VariableDefinitions;\r
- }\r
- //\r
- // RawFormSet now points to the beginning of the forms portion of\r
- // the specific IFR Binary.\r
- //\r
- RawFormSet = (UINT8 *) BinaryData->FormBinary;\r
-\r
- //\r
- // Determine the number of tags for the first form\r
- //\r
- GetTagCount (&RawFormSet[0], &NumberOfTags);\r
-\r
- SavedFormTags = FormTags;\r
-\r
- if (FormTags->Tags != NULL) {\r
- do {\r
- //\r
- // Advance FormTags to the last entry\r
- //\r
- for (; FormTags->Next != NULL; FormTags = FormTags->Next)\r
- ;\r
-\r
- //\r
- // Walk through each of the tags and free the IntList allocation\r
- //\r
- for (Index = 0; Index < NumberOfTags; Index++) {\r
- if (FormTags->Tags[Index].IntList != NULL) {\r
- FreePool (FormTags->Tags[Index].IntList);\r
- }\r
- }\r
-\r
- FreePool (FormTags->Tags);\r
-\r
- ASSERT (FormTags->Next == NULL);\r
-\r
- FormTags->Tags = NULL;\r
-\r
- FormTags = SavedFormTags;\r
-\r
- } while (FormTags->Next != NULL);\r
- }\r
-\r
- Index = 0;\r
-\r
- //\r
- // Test for an allocated buffer. If already allocated this is due to having called this routine\r
- // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize\r
- // the tag structure with current values from the NV\r
- //\r
- if (FormTags->Tags == NULL) {\r
- //\r
- // Allocate memory for our tags on the first form\r
- //\r
- FormTags->Tags = AllocateZeroPool (NumberOfTags * sizeof (EFI_TAG));\r
- ASSERT (FormTags->Tags);\r
- }\r
- //\r
- // Test for an allocated buffer. If already allocated this is due to having called this routine\r
- // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize\r
- // the tag structure with current values from the NV\r
- //\r
- if (InconsistentTags == NULL) {\r
- //\r
- // We just hit the end of an inconsistent expression. Let's allocate the ->Next structure\r
- //\r
- InconsistentTags = AllocateZeroPool (sizeof (EFI_INCONSISTENCY_DATA));\r
- ASSERT (InconsistentTags != NULL);\r
-\r
- FileFormTags->InconsistentTags = InconsistentTags;\r
- }\r
-\r
- ZeroMem (FormTags->Tags, NumberOfTags * sizeof (EFI_TAG));\r
-\r
- for (CurrTag = 0; RawFormSet[Index] != EFI_IFR_END_FORM_SET_OP; CurrTag++) {\r
- //\r
- // Operand = IFR OpCode\r
- //\r
- FormTags->Tags[CurrTag].Operand = RawFormSet[Index];\r
-\r
- //\r
- // Assume for now 0 lines occupied by this OpCode\r
- //\r
- FormTags->Tags[CurrTag].NumberOfLines = 0;\r
-\r
- FormTags->Tags[CurrTag].Class = Class;\r
- FormTags->Tags[CurrTag].SubClass = SubClass;\r
-\r
- //\r
- // Determine the length of the Tag so we can later skip to the next tag in the form\r
- //\r
- TagLength = RawFormSet[Index + 1];\r
- //\r
- // get the length\r
- //\r
- // Operate on the Found OpCode\r
- //\r
- switch (RawFormSet[Index]) {\r
-\r
- case EFI_IFR_FORM_OP:\r
- //\r
- // If there was no variable op-code defined, create a dummy entry for one\r
- //\r
- if (FileFormTags->VariableDefinitions == NULL) {\r
- FileFormTags->VariableDefinitions = AllocateZeroPool (sizeof (EFI_VARIABLE_DEFINITION));\r
- ASSERT (FileFormTags->VariableDefinitions != NULL);\r
- IfrToFormTag (\r
- RawFormSet[Index],\r
- &FormTags->Tags[CurrTag],\r
- (VOID *) &RawFormSet[Index],\r
- FileFormTags->VariableDefinitions\r
- );\r
- } else {\r
- IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);\r
- }\r
- break;\r
-\r
- case EFI_IFR_SUBTITLE_OP:\r
- case EFI_IFR_TEXT_OP:\r
- case EFI_IFR_REF_OP:\r
- IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);\r
- break;\r
-\r
- case EFI_IFR_VARSTORE_OP:\r
- if (FileFormTags->VariableDefinitions == NULL) {\r
- VariableDefinitions = AllocateZeroPool (sizeof (EFI_VARIABLE_DEFINITION));\r
- ASSERT (VariableDefinitions != NULL);\r
- FileFormTags->VariableDefinitions = VariableDefinitions;\r
- }\r
-\r
- IfrToFormTag (\r
- RawFormSet[Index],\r
- &FormTags->Tags[CurrTag],\r
- (VOID *) &RawFormSet[Index],\r
- FileFormTags->VariableDefinitions\r
- );\r
- break;\r
-\r
- case EFI_IFR_VARSTORE_SELECT_OP:\r
- IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);\r
- CopyMem (&CurrentVariable, &((EFI_IFR_VARSTORE_SELECT *) &RawFormSet[Index])->VarId, sizeof (UINT16));\r
- CurrentVariable2 = CurrentVariable;\r
- break;\r
-\r
- case EFI_IFR_VARSTORE_SELECT_PAIR_OP:\r
- IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);\r
- CopyMem(&CurrentVariable, &((EFI_IFR_VARSTORE_SELECT_PAIR *)&RawFormSet[Index])->VarId, sizeof (UINT16));\r
- CopyMem (\r
- &CurrentVariable2,\r
- &((EFI_IFR_VARSTORE_SELECT_PAIR *) &RawFormSet[Index])->SecondaryVarId,\r
- sizeof (UINT16)\r
- );\r
- break;\r
-\r
- case EFI_IFR_END_FORM_OP:\r
- //\r
- // Test for an allocated buffer. If already allocated this is due to having called this routine\r
- // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize\r
- // the tag structure with current values from the NV\r
- //\r
- if (FormTags->Next == NULL) {\r
- //\r
- // We just hit the end of a form. Let's allocate the ->Next structure\r
- //\r
- FormTags->Next = AllocatePool (sizeof (EFI_FORM_TAGS));\r
- ASSERT (FormTags->Next);\r
- }\r
-\r
- FormTags = FormTags->Next;\r
- ZeroMem (FormTags, sizeof (EFI_FORM_TAGS));\r
-\r
- //\r
- // Reset the tag count to one\r
- //\r
- NumberOfTags = 1;\r
-\r
- //\r
- // Reset the CurrTag value (it will be incremented, after this case statement\r
- // so set to a negative one so that we get the desired effect.) Fish can beat me later.\r
- //\r
- CurrTag = -1;\r
-\r
- //\r
- // Determine the number of tags after this form. If this is the last\r
- // form, then we will count the endformset and preserve that information\r
- // in the tag structure.\r
- //\r
- GetTagCount (&RawFormSet[Index + TagLength], &NumberOfTags);\r
-\r
- //\r
- // Allocate memory for our tags\r
- //\r
- FormTags->Tags = AllocateZeroPool (NumberOfTags * sizeof (EFI_TAG));\r
- ASSERT (FormTags->Tags);\r
- break;\r
-\r
- //\r
- // Two types of tags constitute the One Of question: a one-of header and\r
- // several one-of options.\r
- //\r
- case EFI_IFR_ONE_OF_OP:\r
- case EFI_IFR_ORDERED_LIST_OP:\r
- GetQuestionHeader (&FormTags->Tags[CurrTag], RawFormSet, Index, FileFormTags, CurrentVariable);\r
-\r
- //\r
- // Store away the CurrTag since what follows will be the answer that we\r
- // need to place into the appropriate location in the tag array\r
- //\r
- //\r
- // record for setting default later\r
- //\r
- QuestionIndex = (UINT16) CurrTag;\r
- break;\r
-\r
- case EFI_IFR_ONE_OF_OPTION_OP:\r
- IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);\r
- FormTags->Tags[QuestionIndex].Flags = ((EFI_IFR_ONE_OF_OPTION *) &RawFormSet[Index])->Flags;\r
- CopyMem (\r
- &FormTags->Tags[QuestionIndex].Key,\r
- &((EFI_IFR_ONE_OF_OPTION *) &RawFormSet[Index])->Key,\r
- sizeof (UINT16)\r
- );\r
- FormTags->Tags[QuestionIndex].ResetRequired = (BOOLEAN) (FormTags->Tags[QuestionIndex].Flags & EFI_IFR_FLAG_RESET_REQUIRED);\r
- break;\r
-\r
- case EFI_IFR_CHECKBOX_OP:\r
- GetQuestionHeader (&FormTags->Tags[CurrTag], RawFormSet, Index, FileFormTags, CurrentVariable);\r
- IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);\r
- break;\r
-\r
- case EFI_IFR_NUMERIC_OP:\r
- GetNumericHeader (&FormTags->Tags[CurrTag], RawFormSet, Index, (UINT16) 1, FileFormTags, CurrentVariable);\r
- IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);\r
- break;\r
-\r
- case EFI_IFR_DATE_OP:\r
- //\r
- // Date elements come in as a Year, Month, Day. We need to process them as a country-based\r
- // Order. It is much easier to do it here than anywhere else.\r
- //\r
- // For US standards - we want Month/Day/Year, thus we advance "Index" +1, +2, +0 while CurrTag is +0, +1, +2\r
- //\r
- GetNumericHeader (\r
- &FormTags->Tags[CurrTag],\r
- RawFormSet,\r
- (UINT16) (Index + TagLength),\r
- (UINT16) 0,\r
- FileFormTags,\r
- CurrentVariable\r
- );\r
-\r
- //\r
- // The current language selected + the Date operand\r
- //\r
- FormTags->Tags[CurrTag + 1].Operand = RawFormSet[Index];\r
- GetNumericHeader (\r
- &FormTags->Tags[CurrTag + 1],\r
- RawFormSet,\r
- (UINT16) (Index + TagLength + RawFormSet[Index + TagLength + 1]),\r
- (UINT16) 0,\r
- FileFormTags,\r
- CurrentVariable\r
- );\r
-\r
- //\r
- // The current language selected + the Date operand\r
- //\r
- FormTags->Tags[CurrTag + 2].Operand = RawFormSet[Index];\r
- GetNumericHeader (&FormTags->Tags[CurrTag + 2], RawFormSet, Index, (UINT16) 1, FileFormTags, CurrentVariable);\r
-\r
- CurrTag = (INT16) (CurrTag + 2);\r
-\r
- Index = (UINT16) (Index + TagLength);\r
- //\r
- // get the length\r
- //\r
- TagLength = RawFormSet[Index + 1];\r
- Index = (UINT16) (Index + TagLength);\r
- //\r
- // get the length\r
- //\r
- TagLength = RawFormSet[Index + 1];\r
- break;\r
-\r
- case EFI_IFR_TIME_OP:\r
- GetNumericHeader (&FormTags->Tags[CurrTag], RawFormSet, Index, (UINT16) 0, FileFormTags, CurrentVariable);\r
-\r
- if (Count == 2) {\r
- //\r
- // Override the GetQuestionHeader information - date/time are treated very differently\r
- //\r
- FormTags->Tags[CurrTag].NumberOfLines = 1;\r
- Count = 0;\r
- } else {\r
- //\r
- // The premise is that every date/time op-code have 3 elements, the first 2 have 0 lines\r
- // associated with them, and the third has 1 line to allow to space beyond the choice.\r
- //\r
- Count++;\r
- }\r
- break;\r
-\r
- case EFI_IFR_PASSWORD_OP:\r
- case EFI_IFR_STRING_OP:\r
- GetQuestionHeader (&FormTags->Tags[CurrTag], RawFormSet, Index, FileFormTags, CurrentVariable);\r
- IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);\r
- break;\r
-\r
- case EFI_IFR_SUPPRESS_IF_OP:\r
- case EFI_IFR_GRAYOUT_IF_OP:\r
- InconsistentTags->Operand = ((EFI_IFR_INCONSISTENT *) &RawFormSet[Index])->Header.OpCode;\r
- gConsistencyId++;\r
-\r
- //\r
- // Since this op-code doesn't use the next field(s), initialize them with something invalid.\r
- // Unfortunately 0 is a valid offset value for a QuestionId\r
- //\r
- InconsistentTags->QuestionId1 = INVALID_OFFSET_VALUE;\r
- InconsistentTags->QuestionId2 = INVALID_OFFSET_VALUE;\r
-\r
- //\r
- // Test for an allocated buffer. If already allocated this is due to having called this routine\r
- // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize\r
- // the tag structure with current values from the NV\r
- //\r
- if (InconsistentTags->Next == NULL) {\r
- AddNextInconsistentTag (&InconsistentTags);\r
- break;\r
- }\r
-\r
- InconsistentTags = InconsistentTags->Next;\r
- break;\r
-\r
- case EFI_IFR_FORM_SET_OP:\r
- CopyMem (\r
- &FormTags->Tags[CurrTag].GuidValue,\r
- &((EFI_IFR_FORM_SET *) &RawFormSet[Index])->Guid,\r
- sizeof (EFI_GUID)\r
- );\r
- CopyMem (\r
- &FormTags->Tags[CurrTag].CallbackHandle,\r
- &((EFI_IFR_FORM_SET *) &RawFormSet[Index])->CallbackHandle,\r
- sizeof (EFI_PHYSICAL_ADDRESS)\r
- );\r
- CopyMem (&FormTags->Tags[CurrTag].Class, &((EFI_IFR_FORM_SET *) &RawFormSet[Index])->Class, sizeof (UINT8));\r
- CopyMem (\r
- &FormTags->Tags[CurrTag].SubClass,\r
- &((EFI_IFR_FORM_SET *) &RawFormSet[Index])->SubClass,\r
- sizeof (UINT8)\r
- );\r
- CopyMem (\r
- &FormTags->Tags[CurrTag].NvDataSize,\r
- &((EFI_IFR_FORM_SET *) &RawFormSet[Index])->NvDataSize,\r
- sizeof (UINT16)\r
- );\r
- Class = ((EFI_IFR_FORM_SET *) &RawFormSet[Index])->Class;\r
- SubClass = ((EFI_IFR_FORM_SET *) &RawFormSet[Index])->SubClass;\r
- //\r
- // If the formset has a size value, that means someone must be using this, so create a variable\r
- // We also shall reserve the formid of 0 for this specific purpose.\r
- //\r
- if ((FileFormTags->VariableDefinitions == NULL) && (FormTags->Tags[CurrTag].NvDataSize > 0)) {\r
- FileFormTags->VariableDefinitions = AllocateZeroPool (sizeof (EFI_VARIABLE_DEFINITION));\r
- ASSERT (FileFormTags->VariableDefinitions != NULL);\r
- IfrToFormTag (\r
- RawFormSet[Index],\r
- &FormTags->Tags[CurrTag],\r
- (VOID *) &RawFormSet[Index],\r
- FileFormTags->VariableDefinitions\r
- );\r
- } else {\r
- IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);\r
- }\r
- break;\r
-\r
- case EFI_IFR_BANNER_OP:\r
- if (gClassOfVfr == EFI_FRONT_PAGE_SUBCLASS) {\r
- TempValue = 0;\r
- CopyMem (&TempValue, &((EFI_IFR_BANNER *) &RawFormSet[Index])->Alignment, sizeof (UINT8));\r
- //\r
- // If this is the special timeout value, we will dynamically figure out where to put it\r
- // Also the least significant byte refers to the TimeOut desired.\r
- //\r
- if (TempValue == EFI_IFR_BANNER_TIMEOUT) {\r
- CopyMem (&FrontPageTimeOutTitle, &((EFI_IFR_BANNER *) &RawFormSet[Index])->Title, sizeof (UINT16));\r
- if (FrontPageTimeOutValue != (INT16) -1) {\r
- CopyMem (&FrontPageTimeOutValue, &((EFI_IFR_BANNER *) &RawFormSet[Index])->LineNumber, sizeof (UINT16));\r
- }\r
- break;\r
- }\r
-\r
- CopyMem (\r
- &BannerData->Banner[((EFI_IFR_BANNER *) &RawFormSet[Index])->LineNumber][\r
- ((EFI_IFR_BANNER *) &RawFormSet[Index])->Alignment],\r
- &((EFI_IFR_BANNER *) &RawFormSet[Index])->Title,\r
- sizeof (STRING_REF)\r
- );\r
- }\r
- break;\r
-\r
- case EFI_IFR_INCONSISTENT_IF_OP:\r
- CopyMem (\r
- &FormTags->Tags[CurrTag].Text,\r
- &((EFI_IFR_INCONSISTENT *) &RawFormSet[Index])->Popup,\r
- sizeof (UINT16)\r
- );\r
- gConsistencyId++;\r
-\r
- InconsistentTags->Operand = ((EFI_IFR_INCONSISTENT *) &RawFormSet[Index])->Header.OpCode;\r
- CopyMem (&InconsistentTags->Popup, &((EFI_IFR_INCONSISTENT *) &RawFormSet[Index])->Popup, sizeof (UINT16));\r
-\r
- //\r
- // Since this op-code doesn't use the next field(s), initialize them with something invalid.\r
- // Unfortunately 0 is a valid offset value for a QuestionId\r
- //\r
- InconsistentTags->QuestionId1 = INVALID_OFFSET_VALUE;\r
- InconsistentTags->QuestionId2 = INVALID_OFFSET_VALUE;\r
-\r
- InconsistentTags->VariableNumber = CurrentVariable;\r
-\r
- //\r
- // Test for an allocated buffer. If already allocated this is due to having called this routine\r
- // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize\r
- // the tag structure with current values from the NV\r
- //\r
- if (InconsistentTags->Next == NULL) {\r
- AddNextInconsistentTag (&InconsistentTags);\r
- break;\r
- }\r
-\r
- InconsistentTags = InconsistentTags->Next;\r
- break;\r
-\r
- case EFI_IFR_EQ_ID_VAL_OP:\r
- IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);\r
-\r
- InconsistentTags->Operand = ((EFI_IFR_EQ_ID_VAL *) &RawFormSet[Index])->Header.OpCode;\r
- CopyMem (&InconsistentTags->Value, &((EFI_IFR_EQ_ID_VAL *) &RawFormSet[Index])->Value, sizeof (UINT16));\r
- CopyMem (\r
- &InconsistentTags->QuestionId1,\r
- &((EFI_IFR_EQ_ID_VAL *) &RawFormSet[Index])->QuestionId,\r
- sizeof (UINT16)\r
- );\r
-\r
- //\r
- // Since this op-code doesn't use the next field(s), initialize them with something invalid.\r
- // Unfortunately 0 is a valid offset value for a QuestionId\r
- //\r
- InconsistentTags->Width = FormTags->Tags[CurrTag].StorageWidth;\r
- InconsistentTags->QuestionId2 = INVALID_OFFSET_VALUE;\r
- InconsistentTags->ConsistencyId = gConsistencyId;\r
- FormTags->Tags[CurrTag].ConsistencyId = gConsistencyId;\r
-\r
- InconsistentTags->VariableNumber = CurrentVariable;\r
-\r
- //\r
- // Test for an allocated buffer. If already allocated this is due to having called this routine\r
- // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize\r
- // the tag structure with current values from the NV\r
- //\r
- if (InconsistentTags->Next == NULL) {\r
- AddNextInconsistentTag (&InconsistentTags);\r
- break;\r
- }\r
-\r
- InconsistentTags = InconsistentTags->Next;\r
- break;\r
-\r
- case EFI_IFR_EQ_VAR_VAL_OP:\r
- IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);\r
-\r
- InconsistentTags->Operand = ((EFI_IFR_EQ_VAR_VAL *) &RawFormSet[Index])->Header.OpCode;\r
- CopyMem (&InconsistentTags->Value, &((EFI_IFR_EQ_VAR_VAL *) &RawFormSet[Index])->Value, sizeof (UINT16));\r
- CopyMem (\r
- &InconsistentTags->QuestionId1,\r
- &((EFI_IFR_EQ_VAR_VAL *) &RawFormSet[Index])->VariableId,\r
- sizeof (UINT16)\r
- );\r
-\r
- //\r
- // Since this op-code doesn't use the next field(s), initialize them with something invalid.\r
- // Unfortunately 0 is a valid offset value for a QuestionId\r
- //\r
- InconsistentTags->QuestionId2 = INVALID_OFFSET_VALUE;\r
- InconsistentTags->ConsistencyId = gConsistencyId;\r
- FormTags->Tags[CurrTag].ConsistencyId = gConsistencyId;\r
-\r
- InconsistentTags->VariableNumber = CurrentVariable;\r
-\r
- //\r
- // Test for an allocated buffer. If already allocated this is due to having called this routine\r
- // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize\r
- // the tag structure with current values from the NV\r
- //\r
- if (InconsistentTags->Next == NULL) {\r
- AddNextInconsistentTag (&InconsistentTags);\r
- break;\r
- }\r
-\r
- InconsistentTags = InconsistentTags->Next;\r
- break;\r
-\r
- case EFI_IFR_EQ_ID_ID_OP:\r
- IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);\r
-\r
- InconsistentTags->Operand = ((EFI_IFR_EQ_ID_ID *) &RawFormSet[Index])->Header.OpCode;\r
- CopyMem (\r
- &InconsistentTags->QuestionId1,\r
- &((EFI_IFR_EQ_ID_ID *) &RawFormSet[Index])->QuestionId1,\r
- sizeof (UINT16)\r
- );\r
- CopyMem (\r
- &InconsistentTags->QuestionId2,\r
- &((EFI_IFR_EQ_ID_ID *) &RawFormSet[Index])->QuestionId2,\r
- sizeof (UINT16)\r
- );\r
-\r
- InconsistentTags->Width = FormTags->Tags[CurrTag].StorageWidth;\r
- InconsistentTags->ConsistencyId = gConsistencyId;\r
- FormTags->Tags[CurrTag].ConsistencyId = gConsistencyId;\r
-\r
- InconsistentTags->VariableNumber = CurrentVariable;\r
- InconsistentTags->VariableNumber2 = CurrentVariable2;\r
-\r
- //\r
- // Test for an allocated buffer. If already allocated this is due to having called this routine\r
- // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize\r
- // the tag structure with current values from the NV\r
- //\r
- if (InconsistentTags->Next == NULL) {\r
- AddNextInconsistentTag (&InconsistentTags);\r
- break;\r
- }\r
-\r
- InconsistentTags = InconsistentTags->Next;\r
- break;\r
-\r
- case EFI_IFR_AND_OP:\r
- case EFI_IFR_OR_OP:\r
- case EFI_IFR_NOT_OP:\r
- case EFI_IFR_GT_OP:\r
- case EFI_IFR_GE_OP:\r
- case EFI_IFR_TRUE_OP:\r
- case EFI_IFR_FALSE_OP:\r
- InconsistentTags->Operand = ((EFI_IFR_NOT *) &RawFormSet[Index])->Header.OpCode;\r
-\r
- //\r
- // Since this op-code doesn't use the next field(s), initialize them with something invalid.\r
- // Unfortunately 0 is a valid offset value for a QuestionId\r
- //\r
-\r
- //\r
- // Reserve INVALID_OFFSET_VALUE - 1 for TRUE or FALSE because they are inconsistency tags also, but\r
- // have no coresponding id. The examination of id is needed by evaluating boolean expression.\r
- //\r
- if (RawFormSet[Index] == EFI_IFR_TRUE_OP ||\r
- RawFormSet[Index] == EFI_IFR_FALSE_OP) {\r
- InconsistentTags->QuestionId1 = INVALID_OFFSET_VALUE - 1;\r
- } else {\r
- InconsistentTags->QuestionId1 = INVALID_OFFSET_VALUE;\r
- }\r
- InconsistentTags->QuestionId2 = INVALID_OFFSET_VALUE;\r
- InconsistentTags->ConsistencyId = gConsistencyId;\r
- FormTags->Tags[CurrTag].ConsistencyId = gConsistencyId;\r
-\r
- //\r
- // Test for an allocated buffer. If already allocated this is due to having called this routine\r
- // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize\r
- // the tag structure with current values from the NV\r
- //\r
- if (InconsistentTags->Next == NULL) {\r
- AddNextInconsistentTag (&InconsistentTags);\r
- break;\r
- }\r
-\r
- InconsistentTags = InconsistentTags->Next;\r
- break;\r
-\r
- case EFI_IFR_EQ_ID_LIST_OP:\r
- IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);\r
-\r
- InconsistentTags->Operand = ((EFI_IFR_EQ_ID_LIST *) &RawFormSet[Index])->Header.OpCode;\r
- CopyMem (\r
- &InconsistentTags->QuestionId1,\r
- &((EFI_IFR_EQ_ID_LIST *) &RawFormSet[Index])->QuestionId,\r
- sizeof (UINT16)\r
- );\r
- CopyMem (\r
- &InconsistentTags->ListLength,\r
- &((EFI_IFR_EQ_ID_LIST *) &RawFormSet[Index])->ListLength,\r
- sizeof (UINT16)\r
- );\r
- InconsistentTags->ValueList = FormTags->Tags[CurrTag].IntList;\r
-\r
- //\r
- // Since this op-code doesn't use the next field(s), initialize them with something invalid.\r
- // Unfortunately 0 is a valid offset value for a QuestionId\r
- //\r
- InconsistentTags->Width = FormTags->Tags[CurrTag].StorageWidth;\r
- InconsistentTags->QuestionId2 = INVALID_OFFSET_VALUE;\r
- InconsistentTags->ConsistencyId = gConsistencyId;\r
- FormTags->Tags[CurrTag].ConsistencyId = gConsistencyId;\r
-\r
- //\r
- // Test for an allocated buffer. If already allocated this is due to having called this routine\r
- // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize\r
- // the tag structure with current values from the NV\r
- //\r
- if (InconsistentTags->Next == NULL) {\r
- AddNextInconsistentTag (&InconsistentTags);\r
- break;\r
- }\r
-\r
- InconsistentTags = InconsistentTags->Next;\r
- break;\r
-\r
- case EFI_IFR_END_IF_OP:\r
- InconsistentTags->Operand = ((EFI_IFR_END_EXPR *) &RawFormSet[Index])->Header.OpCode;\r
-\r
- //\r
- // Since this op-code doesn't use the next field(s), initialize them with something invalid.\r
- // Unfortunately 0 is a valid offset value for a QuestionId\r
- //\r
- InconsistentTags->QuestionId1 = INVALID_OFFSET_VALUE;\r
- InconsistentTags->QuestionId2 = INVALID_OFFSET_VALUE;\r
-\r
- //\r
- // Test for an allocated buffer. If already allocated this is due to having called this routine\r
- // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize\r
- // the tag structure with current values from the NV\r
- //\r
- if (InconsistentTags->Next == NULL) {\r
- AddNextInconsistentTag (&InconsistentTags);\r
- break;\r
- }\r
-\r
- InconsistentTags = InconsistentTags->Next;\r
- break;\r
-\r
- case EFI_IFR_END_ONE_OF_OP:\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- //\r
- // End of switch\r
- //\r
- // Per spec., we ignore ops that we don't know how to deal with. Skip to next tag\r
- //\r
- Index = (UINT16) (Index + TagLength);\r
- }\r
- //\r
- // End of Index\r
- //\r
- // When we eventually exit, make sure we mark the last tag with an op-code\r
- //\r
- FormTags->Tags[CurrTag].Operand = RawFormSet[Index];\r
-\r
- IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);\r
-\r
- //\r
- // Place this as an end of the database marker\r
- //\r
- InconsistentTags->Operand = 0xFF;\r
-\r
- //\r
- // This is the Head of the linked list of pages. Each page is an array of tags\r
- //\r
- FormTags = &FileFormTags->FormTags;\r
- InconsistentTags = FileFormTags->InconsistentTags;\r
-\r
- for (; InconsistentTags->Operand != 0xFF;) {\r
- if (InconsistentTags->QuestionId1 != INVALID_OFFSET_VALUE) {\r
- //\r
- // Search the tags for the tag which corresponds to this ID\r
- //\r
- for (CurrTag = 0; FormTags->Tags[0].Operand != EFI_IFR_END_FORM_SET_OP; CurrTag++) {\r
- //\r
- // If we hit the end of a form, go to the next set of Tags.\r
- // Remember - EndFormSet op-codes sit on their own page after an end form.\r
- //\r
- if (FormTags->Tags[CurrTag].Operand == EFI_IFR_END_FORM_OP) {\r
- //\r
- // Reset the CurrTag value (it will be incremented, after this case statement\r
- // so set to a negative one so that we get the desired effect.) Fish can beat me later.\r
- //\r
- CurrTag = -1;\r
- FormTags = FormTags->Next;\r
- continue;\r
- }\r
-\r
- if (FormTags->Tags[CurrTag].Id == InconsistentTags->QuestionId1) {\r
- FormTags->Tags[CurrTag].Consistency++;\r
- }\r
- }\r
- }\r
-\r
- FormTags = &FileFormTags->FormTags;\r
-\r
- if (InconsistentTags->QuestionId2 != INVALID_OFFSET_VALUE) {\r
- //\r
- // Search the tags for the tag which corresponds to this ID\r
- //\r
- for (CurrTag = 0; FormTags->Tags[CurrTag].Operand != EFI_IFR_END_FORM_SET_OP; CurrTag++) {\r
- //\r
- // If we hit the end of a form, go to the next set of Tags.\r
- // Remember - EndFormSet op-codes sit on their own page after an end form.\r
- //\r
- if (FormTags->Tags[CurrTag].Operand == EFI_IFR_END_FORM_OP) {\r
- //\r
- // Reset the CurrTag value (it will be incremented, after this case statement\r
- // so set to a negative one so that we get the desired effect.) Fish can beat me later.\r
- //\r
- CurrTag = -1;\r
- FormTags = FormTags->Next;\r
- continue;\r
- }\r
-\r
- if (FormTags->Tags[CurrTag].Id == InconsistentTags->QuestionId2) {\r
- FormTags->Tags[CurrTag].Consistency++;\r
- }\r
- }\r
- }\r
-\r
- InconsistentTags = InconsistentTags->Next;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-VOID\r
-InitPage (\r
- VOID\r
- )\r
-{\r
- CHAR16 *HomePageString;\r
- CHAR16 *HomeEscapeString;\r
-\r
- //\r
- // Displays the Header and Footer borders\r
- //\r
- DisplayPageFrame ();\r
-\r
- HomePageString = GetToken (STRING_TOKEN (HOME_PAGE_TITLE), gHiiHandle);\r
- HomeEscapeString = GetToken (STRING_TOKEN (HOME_ESCAPE_STRING), gHiiHandle);\r
-\r
- gST->ConOut->SetAttribute (gST->ConOut, EFI_YELLOW | EFI_BRIGHT);\r
- //\r
- // PrintStringAt ((gScreenDimensions.RightColumn - GetStringWidth(HomePageString)/2)/2, 1, HomePageString);\r
- //\r
- PrintStringAt (\r
- (gScreenDimensions.RightColumn + gScreenDimensions.LeftColumn - GetStringWidth (HomePageString) / 2) / 2,\r
- 1,\r
- HomePageString\r
- );\r
- PrintAt (\r
- gScreenDimensions.LeftColumn + 2,\r
- gScreenDimensions.BottomRow - 3,\r
- (CHAR16 *) L"%c%c%s",\r
- ARROW_UP,\r
- ARROW_DOWN,\r
- gMoveHighlight\r
- );\r
- PrintAt (\r
- gScreenDimensions.RightColumn - (GetStringWidth (HomeEscapeString) / 2) - 2,\r
- gScreenDimensions.BottomRow - 3,\r
- (CHAR16 *) L" %s",\r
- HomeEscapeString\r
- );\r
- gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
- FreePool (HomeEscapeString);\r
- FreePool (HomePageString);\r
-\r
- return ;\r
-}\r
-\r
-CHAR16 *\r
-GetToken (\r
- IN STRING_REF Token,\r
- IN EFI_HII_HANDLE HiiHandle\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Get the string based on the TokenID and HII Handle.\r
-\r
-Arguments:\r
-\r
- Token - The Token ID.\r
- HiiHandle - Handle of Ifr to be fetched.\r
-\r
-Returns:\r
-\r
- The output string.\r
-\r
---*/\r
-{\r
- CHAR16 *Buffer;\r
- UINTN BufferLength;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Set default string size assumption at no more than 256 bytes\r
- //\r
- BufferLength = 0x100;\r
-\r
- Buffer = AllocateZeroPool (BufferLength);\r
- ASSERT (Buffer != NULL);\r
-\r
- Status = Hii->GetString (Hii, HiiHandle, Token, TRUE, NULL, &BufferLength, Buffer);\r
-\r
- if (EFI_ERROR (Status)) {\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- //\r
- // Free the old pool\r
- //\r
- FreePool (Buffer);\r
-\r
- //\r
- // Allocate new pool with correct value\r
- //\r
- Buffer = AllocatePool (BufferLength);\r
- ASSERT (Buffer != NULL);\r
-\r
- Status = Hii->GetString (Hii, HiiHandle, Token, TRUE, NULL, &BufferLength, Buffer);\r
-\r
- if (!EFI_ERROR (Status)) {\r
- return Buffer;\r
- }\r
- }\r
-\r
- ASSERT_EFI_ERROR (Status);\r
- }\r
-\r
- return Buffer;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-PopulateHomePage (\r
- IN UINTN NumberOfIfrImages,\r
- IN EFI_FILE_FORM_TAGS *FileFormTagsHead\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- EFI_IFR_BINARY *IfrBinary;\r
- CHAR16 *StringPtr;\r
- EFI_FILE_FORM_TAGS *FileFormTags;\r
- EFI_FORM_TAGS LocalTags;\r
-\r
- FileFormTags = FileFormTagsHead;\r
-\r
- UiInitMenu ();\r
-\r
- Status = EFI_SUCCESS;\r
-\r
- //\r
- // If there are no images\r
- //\r
- if (NumberOfIfrImages == 0) {\r
- Status = EFI_NO_MEDIA;\r
- return Status;\r
- }\r
- //\r
- // IfrBinary points to the beginning of the Binary data linked-list\r
- //\r
- IfrBinary = gBinaryDataHead;\r
-\r
- //\r
- // Print the entries which were in the default language.\r
- //\r
- for (Index = 0; Index < NumberOfIfrImages; Index++) {\r
- LocalTags = FileFormTags->FormTags;\r
-\r
- //\r
- // Populate the Menu\r
- //\r
- StringPtr = GetToken (IfrBinary->TitleToken, IfrBinary->Handle);\r
-\r
- //\r
- // If the default language doesn't exist, don't add a menu option yet\r
- //\r
- if (StringPtr[0] != CHAR_NULL) {\r
- //\r
- // We are NOT!! removing this StringPtr buffer via FreePool since it is being used in the menuoptions, we will do\r
- // it in UiFreeMenu.\r
- //\r
- UiAddMenuOption (StringPtr, IfrBinary->Handle, LocalTags.Tags, IfrBinary->FormBinary, Index);\r
- }\r
- //\r
- // Advance to the next HII handle\r
- //\r
- IfrBinary = IfrBinary->Next;\r
- FileFormTags = FileFormTags->NextFile;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-STATIC\r
-UI_MENU_OPTION *\r
-DisplayHomePage (\r
- IN UINTN NumberOfIfrImages,\r
- IN EFI_FILE_FORM_TAGS *FileFormTagsHead,\r
- IN UINT8 *CallbackData\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UI_MENU_OPTION *Selection;\r
-\r
- //\r
- // This prints the basic home page template which the user sees\r
- //\r
- InitPage ();\r
-\r
- Status = PopulateHomePage (NumberOfIfrImages, FileFormTagsHead);\r
-\r
- if (EFI_ERROR (Status)) {\r
- Selection = NULL;\r
- return Selection;\r
- }\r
-\r
- Selection = UiDisplayMenu (FALSE, FileFormTagsHead, (EFI_IFR_DATA_ARRAY *) CallbackData);\r
-\r
- return Selection;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-InitializeBinaryStructures (\r
- IN EFI_HII_HANDLE *Handle,\r
- IN BOOLEAN UseDatabase,\r
- IN EFI_IFR_PACKET *Packet,\r
- IN UINT8 *NvMapOverride,\r
- IN UINTN NumberOfIfrImages,\r
- OUT EFI_FILE_FORM_TAGS **FileFormTagsHead\r
- )\r
-{\r
- UINTN HandleIndex;\r
- EFI_STATUS Status;\r
- EFI_IFR_BINARY *BinaryData;\r
- EFI_FILE_FORM_TAGS *FileFormTags;\r
- UINTN SizeOfNvStore;\r
- EFI_FORM_CALLBACK_PROTOCOL *FormCallback;\r
- EFI_VARIABLE_DEFINITION *VariableDefinition;\r
- EFI_VARIABLE_DEFINITION *OverrideDefinition;\r
- VOID *NvMap;\r
- UINTN NvMapSize;\r
- EFI_HII_VARIABLE_PACK_LIST *NvMapListHead;\r
- EFI_HII_VARIABLE_PACK_LIST *NvMapListNode;\r
-\r
- //\r
- // Initialize some variables to avoid warnings\r
- //\r
- BinaryData = NULL;\r
- *FileFormTagsHead = NULL;\r
- FileFormTags = NULL;\r
- gBinaryDataHead = NULL;\r
- Status = EFI_SUCCESS;\r
- FormCallback = NULL;\r
- NvMap = NULL;\r
- NvMapSize = 0;\r
-\r
- if (NumberOfIfrImages > 1) {\r
- NvMapOverride = NULL;\r
- }\r
-\r
- for (HandleIndex = 0; HandleIndex < NumberOfIfrImages; HandleIndex += 1) {\r
- //\r
- // If the buffers are uninitialized, allocate them, otherwise work on the ->Next members\r
- //\r
- if ((BinaryData == NULL) || (FileFormTags == NULL)) {\r
- //\r
- // Allocate memory for our Binary Data\r
- //\r
- BinaryData = AllocateZeroPool (sizeof (EFI_IFR_BINARY));\r
- ASSERT (BinaryData);\r
-\r
- //\r
- // Preserve the Head of what will be a linked-list.\r
- //\r
- gBinaryDataHead = BinaryData;\r
- gBinaryDataHead->Next = NULL;\r
-\r
- if (UseDatabase) {\r
- Status = GetIfrBinaryData (Hii, Handle[HandleIndex], NULL, BinaryData);\r
- } else {\r
- Status = GetIfrBinaryData (Hii, Handle[HandleIndex], Packet, BinaryData);\r
- }\r
- //\r
- // Allocate memory for our File Form Tags\r
- //\r
- FileFormTags = AllocateZeroPool (sizeof (EFI_FILE_FORM_TAGS));\r
- ASSERT (FileFormTags);\r
-\r
- //\r
- // Preserve the Head of what will be a linked-list.\r
- //\r
- *FileFormTagsHead = FileFormTags;\r
- (*FileFormTagsHead)->NextFile = NULL;\r
-\r
- } else {\r
- //\r
- // Allocate memory for our Binary Data linked-list\r
- // Each handle represents a Binary and we will store that data away.\r
- //\r
- BinaryData->Next = AllocateZeroPool (sizeof (EFI_IFR_BINARY));\r
- ASSERT (BinaryData->Next);\r
-\r
- BinaryData = BinaryData->Next;\r
- BinaryData->Next = NULL;\r
-\r
- if (UseDatabase) {\r
- Status = GetIfrBinaryData (Hii, Handle[HandleIndex], NULL, BinaryData);\r
- } else {\r
- Status = GetIfrBinaryData (Hii, Handle[HandleIndex], Packet, BinaryData);\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- //\r
- // Allocate memory for our FileFormTags linked-list\r
- // Each allocation reserves handle represents a Binary and we will store that data away.\r
- //\r
- FileFormTags->NextFile = AllocateZeroPool (sizeof (EFI_FILE_FORM_TAGS));\r
- ASSERT (FileFormTags->NextFile);\r
-\r
- FileFormTags = FileFormTags->NextFile;\r
- }\r
- //\r
- // endif\r
- //\r
- // Tag Structure Initialization\r
- //\r
- Status = InitializeTagStructures (BinaryData, FileFormTags);\r
-\r
- VariableDefinition = FileFormTags->VariableDefinitions;\r
-\r
- //\r
- // Allocate memory for our NVRAM Maps for all of our variables\r
- //\r
- for (; VariableDefinition != NULL; VariableDefinition = VariableDefinition->Next) {\r
- //\r
- // Pad the fake variable size accordingly - this value should reflect the size of information that is not accounted by\r
- // the mainstream NVRAM variable such as DATE/TIME information that the browser needs to track but is saved to an RTC\r
- //\r
- VariableDefinition->VariableFakeSize = (UINT16) (VariableDefinition->VariableSize + VariableDefinition->VariableFakeSize);\r
-\r
- //\r
- // In the case where a file has no "real" NV data, we should pad the buffer accordingly\r
- //\r
- if (VariableDefinition->VariableSize == 0) {\r
- if (VariableDefinition->VariableFakeSize != 0) {\r
- VariableDefinition->NvRamMap = AllocateZeroPool (VariableDefinition->VariableFakeSize);\r
- ASSERT (VariableDefinition->NvRamMap != NULL);\r
- }\r
- } else {\r
- VariableDefinition->NvRamMap = AllocateZeroPool (VariableDefinition->VariableSize);\r
- ASSERT (VariableDefinition->NvRamMap != NULL);\r
- }\r
-\r
- if (VariableDefinition->VariableFakeSize != 0) {\r
- VariableDefinition->FakeNvRamMap = AllocateZeroPool (VariableDefinition->VariableFakeSize);\r
- ASSERT (VariableDefinition->FakeNvRamMap != NULL);\r
- }\r
- }\r
-\r
- Status = gBS->HandleProtocol (\r
- (VOID *) (UINTN) FileFormTags->FormTags.Tags[0].CallbackHandle,\r
- &gEfiFormCallbackProtocolGuid,\r
- (VOID **) &FormCallback\r
- );\r
-\r
- //\r
- // Since we might have multiple variables, if there is an NvMapOverride we need to use the EFI_VARIABLE_DEFINITION\r
- // information as the information that we pass back and forth. NOTE that callbacks that are initiated will only have the\r
- // NVRAM data refreshed based on the op-code that initiated the callback. In other words, we will pass to the caller a single\r
- // NVRAM map for a single variable based on the op-code that the user selected.\r
- //\r
- if (NvMapOverride != NULL) {\r
- VariableDefinition = FileFormTags->VariableDefinitions;\r
- OverrideDefinition = ((EFI_VARIABLE_DEFINITION *) NvMapOverride);\r
-\r
- //\r
- // Search through the variable definitions. There should be sufficient passed in settings for the variable op-codes specified\r
- //\r
- for (; VariableDefinition != NULL; VariableDefinition = VariableDefinition->Next) {\r
- if ((!CompareMem (VariableDefinition->VariableName, L"Setup", 10)) && (VariableDefinition->Next == NULL)) {\r
- if (VariableDefinition->VariableSize != 0) {\r
- CopyMem (VariableDefinition->NvRamMap, NvMapOverride, VariableDefinition->VariableSize);\r
- } else {\r
- CopyMem (VariableDefinition->NvRamMap, NvMapOverride, VariableDefinition->VariableFakeSize);\r
- }\r
- break;\r
- } else {\r
- VariableDefinition->NvRamMap = OverrideDefinition->NvRamMap;\r
- }\r
- //\r
- // There should NEVER be a ->Next for VariableDefinition and a NULL ->Next for the OverrideDefinition\r
- //\r
- ASSERT (OverrideDefinition->Next);\r
- OverrideDefinition = OverrideDefinition->Next;\r
- }\r
- } else {\r
- VariableDefinition = FileFormTags->VariableDefinitions;\r
-\r
- //\r
- // Search through the variable definitions. There should be sufficient passed in settings for the variable op-codes specified\r
- //\r
- for (; VariableDefinition != NULL; VariableDefinition = VariableDefinition->Next) {\r
- SizeOfNvStore = VariableDefinition->VariableSize;\r
-\r
- //\r
- // Getting the NvStore and placing it into our Global Data\r
- //\r
- if ((FormCallback != NULL) && (FormCallback->NvRead != NULL)) {\r
- Status = FormCallback->NvRead (\r
- FormCallback,\r
- VariableDefinition->VariableName,\r
- &VariableDefinition->Guid,\r
- NULL,\r
- &SizeOfNvStore,\r
- (VOID *) VariableDefinition->NvRamMap\r
- );\r
- } else {\r
- Status = gRT->GetVariable (\r
- VariableDefinition->VariableName,\r
- &VariableDefinition->Guid,\r
- NULL,\r
- &SizeOfNvStore,\r
- (VOID *) VariableDefinition->NvRamMap\r
- );\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // If there is a variable that exists already and it is larger than what we calculated the\r
- // storage needs to be, we must assume the variable size from GetVariable is correct and not\r
- // allow the truncation of the variable. It is very possible that the user who created the IFR\r
- // we are cracking is not referring to a variable that was in a previous map, however we cannot\r
- // allow it's truncation.\r
- //\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- //\r
- // If the buffer was too small, we should have the expanded size requirement in SizeOfNvStore now.\r
- //\r
- VariableDefinition->VariableSize = (UINT16) SizeOfNvStore;\r
-\r
- //\r
- // Free the buffer that was allocated that was too small\r
- //\r
- FreePool (VariableDefinition->NvRamMap);\r
- FreePool (VariableDefinition->FakeNvRamMap);\r
-\r
- VariableDefinition->NvRamMap = AllocateZeroPool (SizeOfNvStore);\r
- VariableDefinition->FakeNvRamMap = AllocateZeroPool (SizeOfNvStore + VariableDefinition->VariableFakeSize);\r
- ASSERT (VariableDefinition->NvRamMap);\r
- ASSERT (VariableDefinition->FakeNvRamMap);\r
-\r
- if ((FormCallback != NULL) && (FormCallback->NvRead != NULL)) {\r
- Status = FormCallback->NvRead (\r
- FormCallback,\r
- VariableDefinition->VariableName,\r
- &VariableDefinition->Guid,\r
- NULL,\r
- &SizeOfNvStore,\r
- (VOID *) VariableDefinition->NvRamMap\r
- );\r
- } else {\r
- Status = gRT->GetVariable (\r
- VariableDefinition->VariableName,\r
- &VariableDefinition->Guid,\r
- NULL,\r
- &SizeOfNvStore,\r
- (VOID *) VariableDefinition->NvRamMap\r
- );\r
- }\r
- }\r
- //\r
- // if the variable was not found, we will retrieve default values\r
- //\r
- if (Status == EFI_NOT_FOUND) {\r
-\r
- if (0 == CompareMem (VariableDefinition->VariableName, L"Setup", 10)) {\r
-\r
- NvMapListHead = NULL;\r
-\r
- Status = Hii->GetDefaultImage (Hii, Handle[HandleIndex], EFI_IFR_FLAG_DEFAULT, &NvMapListHead);\r
-\r
- if (!EFI_ERROR (Status)) {\r
- ASSERT_EFI_ERROR (NULL != NvMapListHead);\r
-\r
- NvMapListNode = NvMapListHead;\r
-\r
- while (NULL != NvMapListNode) {\r
- if (VariableDefinition->VariableId == NvMapListNode->VariablePack->VariableId) {\r
- NvMap = (VOID *) ((CHAR8 *) NvMapListNode->VariablePack + sizeof (EFI_HII_VARIABLE_PACK) + NvMapListNode->VariablePack->VariableNameLength);\r
- NvMapSize = NvMapListNode->VariablePack->Header.Length - sizeof (EFI_HII_VARIABLE_PACK) - NvMapListNode->VariablePack->VariableNameLength;\r
- break;\r
- }\r
- NvMapListNode = NvMapListNode->NextVariablePack;\r
- }\r
-\r
- //\r
- // Free the buffer that was allocated.\r
- //\r
- FreePool (VariableDefinition->NvRamMap);\r
- FreePool (VariableDefinition->FakeNvRamMap);\r
-\r
- //\r
- // Allocate, copy the NvRamMap.\r
- //\r
- VariableDefinition->VariableFakeSize = (UINT16) (VariableDefinition->VariableFakeSize - VariableDefinition->VariableSize);\r
- VariableDefinition->VariableSize = (UINT16) NvMapSize;\r
- VariableDefinition->VariableFakeSize = (UINT16) (VariableDefinition->VariableFakeSize + VariableDefinition->VariableSize);\r
-\r
- VariableDefinition->NvRamMap = AllocateZeroPool (VariableDefinition->VariableSize);\r
- VariableDefinition->FakeNvRamMap = AllocateZeroPool (NvMapSize + VariableDefinition->VariableFakeSize);\r
-\r
- CopyMem (VariableDefinition->NvRamMap, NvMap, NvMapSize);\r
- FreePool (NvMapListHead);\r
- }\r
-\r
- }\r
- Status = EFI_SUCCESS;\r
- }\r
- }\r
- }\r
- }\r
-\r
- InitializeTagStructures (BinaryData, FileFormTags);\r
- }\r
- //\r
- // endfor\r
- //\r
- return Status;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-GetIfrBinaryData (\r
- IN EFI_HII_PROTOCOL *Hii,\r
- IN EFI_HII_HANDLE HiiHandle,\r
- IN EFI_IFR_PACKET *Packet,\r
- IN OUT EFI_IFR_BINARY *BinaryData\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Fetch the Ifr binary data.\r
-\r
-Arguments:\r
- Hii - Point to HII protocol.\r
- HiiHandle - Handle of Ifr to be fetched.\r
- Packet - Pointer to IFR packet.\r
- BinaryData - Buffer to copy the string into\r
-\r
-Returns:\r
- Returns the number of CHAR16 characters that were copied into the OutputString buffer.\r
-\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_HII_PACKAGES *PackageList;\r
- UINTN BufferSize;\r
- VOID *Buffer;\r
- UINT8 *RawFormBinary;\r
- EFI_IFR_FORM_SET *FormOp;\r
- UINT16 Index;\r
- UINT16 Index2;\r
- UINT16 TitleToken;\r
-\r
- //\r
- // Initialize the TitleToken to 0 just in case not found\r
- //\r
- TitleToken = 0;\r
-\r
- //\r
- // Try for a 32K Buffer\r
- //\r
- BufferSize = 0x8000;\r
-\r
- //\r
- // Allocate memory for our Form binary\r
- //\r
- Buffer = AllocateZeroPool (BufferSize);\r
- ASSERT (Buffer);\r
-\r
- if (Packet == NULL) {\r
- Status = Hii->GetForms (Hii, HiiHandle, 0, &BufferSize, Buffer);\r
-\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
-\r
- FreePool (Buffer);\r
-\r
- //\r
- // Allocate memory for our Form binary\r
- //\r
- Buffer = AllocatePool (BufferSize);\r
- ASSERT (Buffer);\r
-\r
- Status = Hii->GetForms (Hii, HiiHandle, 0, &BufferSize, Buffer);\r
- }\r
- } else {\r
- //\r
- // Copies the data to local usable buffer\r
- //\r
- CopyMem (Buffer, Packet->IfrData, Packet->IfrData->Header.Length);\r
-\r
- //\r
- // Register the string data with HII\r
- //\r
- PackageList = PreparePackages (2, NULL, Packet->IfrData, Packet->StringData);\r
-\r
- Status = Hii->NewPack (Hii, PackageList, &HiiHandle);\r
-\r
- FreePool (PackageList);\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // We now have the IFR binary in our Buffer\r
- //\r
- BinaryData->IfrPackage = Buffer;\r
- RawFormBinary = (UINT8 *) ((CHAR8 *) (Buffer) + sizeof (EFI_HII_PACK_HEADER));\r
- BinaryData->FormBinary = (UINT8 *) ((CHAR8 *) (Buffer) + sizeof (EFI_HII_PACK_HEADER));\r
- BinaryData->Handle = HiiHandle;\r
-\r
- //\r
- // If a packet was passed in, remove the string data when exiting.\r
- //\r
- if (Packet != NULL) {\r
- BinaryData->UnRegisterOnExit = TRUE;\r
- } else {\r
- BinaryData->UnRegisterOnExit = FALSE;\r
- }\r
- //\r
- // Walk through the FormSet Opcodes looking for the FormSet opcode\r
- // If we hit EFI_IFR_END_SET_OP we know we hit the end of the FormSet.\r
- //\r
- for (Index = 0; RawFormBinary[Index] != EFI_IFR_END_FORM_SET_OP;) {\r
- FormOp = (EFI_IFR_FORM_SET *) &RawFormBinary[Index];\r
- Index = (UINT16) (Index + FormOp->Header.Length);\r
-\r
- if (FormOp->Header.OpCode == EFI_IFR_FORM_SET_OP) {\r
- TitleToken = FormOp->FormSetTitle;\r
- //\r
- // If displaying FrontPage - set the flag signifying it\r
- //\r
- switch (FormOp->SubClass) {\r
- case EFI_FRONT_PAGE_SUBCLASS:\r
- FrontPageHandle = HiiHandle;\r
-\r
- default:\r
- gClassOfVfr = FormOp->SubClass;\r
- }\r
- //\r
- // Match GUID to find out the function key setting. If match fail, use the default setting.\r
- //\r
- for (Index2 = 0; Index2 < sizeof (gFunctionKeySettingTable) / sizeof (FUNCTIION_KEY_SETTING); Index2++) {\r
- if (CompareGuid ((EFI_GUID *)(UINTN)&FormOp->Guid, &(gFunctionKeySettingTable[Index2].FormSetGuid))) {\r
- //\r
- // Update the function key setting.\r
- //\r
- gFunctionKeySetting = gFunctionKeySettingTable[Index2].KeySetting;\r
- //\r
- // Function key prompt can not be displayed if the function key has been disabled.\r
- //\r
- if ((gFunctionKeySetting & FUNCTION_ONE) != FUNCTION_ONE) {\r
- gFunctionOneString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);\r
- }\r
-\r
- if ((gFunctionKeySetting & FUNCTION_TWO) != FUNCTION_TWO) {\r
- gFunctionTwoString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);\r
- }\r
-\r
- if ((gFunctionKeySetting & FUNCTION_NINE) != FUNCTION_NINE) {\r
- gFunctionNineString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);\r
- }\r
-\r
- if ((gFunctionKeySetting & FUNCTION_TEN) != FUNCTION_TEN) {\r
- gFunctionTenString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- BinaryData->TitleToken = TitleToken;\r
-\r
- return Status;\r
-}\r
-\r
-EFI_HANDLE PrintHandle = NULL;\r
-EFI_PRINT_PROTOCOL mPrintProtocol = { UnicodeVSPrint };\r
-\r
-STATIC\r
-EFI_STATUS\r
-InstallPrint (\r
- VOID\r
- )\r
-{\r
- return gBS->InstallProtocolInterface (\r
- &PrintHandle,\r
- &gEfiPrintProtocolGuid,\r
- EFI_NATIVE_INTERFACE,\r
- &mPrintProtocol\r
- );\r
-}\r