git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2579 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			594 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			594 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*++
 | |
| Copyright (c) 2006 - 2007, 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.             
 | |
| 
 | |
| Module Name:
 | |
|   DriverSample.c
 | |
| 
 | |
| Abstract:
 | |
| 
 | |
|   This is an example of how a driver might export data to the HII protocol to be 
 | |
|   later utilized by the Setup Protocol
 | |
| 
 | |
| --*/
 | |
| 
 | |
| #include "DriverSample.h"
 | |
| 
 | |
| #define DISPLAY_ONLY_MY_ITEM  0x0001
 | |
| 
 | |
| #define STRING_PACK_GUID \
 | |
|   { \
 | |
|     0x8160a85f, 0x934d, 0x468b, { 0xa2, 0x35, 0x72, 0x89, 0x59, 0x14, 0xf6, 0xfc } \
 | |
|   }
 | |
| 
 | |
| EFI_GUID  mFormSetGuid    = FORMSET_GUID;
 | |
| EFI_GUID  mStringPackGuid = STRING_PACK_GUID; 
 | |
| 
 | |
| STATIC
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| DriverCallback (
 | |
|   IN EFI_FORM_CALLBACK_PROTOCOL       *This,
 | |
|   IN UINT16                           KeyValue,
 | |
|   IN EFI_IFR_DATA_ARRAY               *Data,
 | |
|   OUT EFI_HII_CALLBACK_PACKET         **Packet
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
| 
 | |
|   This is the function that is called to provide results data to the driver.  This data
 | |
|   consists of a unique key which is used to identify what data is either being passed back
 | |
|   or being asked for. 
 | |
| 
 | |
| Arguments:
 | |
| 
 | |
|   KeyValue -        A unique value which is sent to the original exporting driver so that it
 | |
|                     can identify the type of data to expect.  The format of the data tends to
 | |
|                     vary based on the op-code that geerated the callback.
 | |
| 
 | |
|   Data -            A pointer to the data being sent to the original exporting driver.
 | |
| 
 | |
| Returns: 
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   EFI_CALLBACK_INFO       *Private;
 | |
|   EFI_HII_UPDATE_DATA     *UpdateData;
 | |
|   UINT8                   *Location;
 | |
|   EFI_HII_CALLBACK_PACKET *DataPacket;
 | |
|   UINT16                  Value;
 | |
|   CHAR16                  VariableName[40];
 | |
|   STATIC UINT16           QuestionId = 0;
 | |
|   IFR_OPTION              *OptionList;
 | |
|   UINTN                   Index;
 | |
|   MyIfrNVData             NVStruc;
 | |
| 
 | |
|   Private     = EFI_CALLBACK_INFO_FROM_THIS (This);
 | |
| 
 | |
|   //
 | |
|   // This should tell me the first offset AFTER the end of the compiled NV map
 | |
|   // If op-code results are not going to be saved to NV locations ensure the QuestionId
 | |
|   // is beyond the end of the NVRAM mapping.
 | |
|   //
 | |
|   if (QuestionId == 0) {
 | |
|     QuestionId = sizeof (MyIfrNVData);
 | |
|   }
 | |
| 
 | |
|   ZeroMem (VariableName, (sizeof (CHAR16) * 40));
 | |
| 
 | |
|   switch (KeyValue) {
 | |
|   case 0x0001:
 | |
|     //
 | |
|     // Create a small boot order list
 | |
|     //
 | |
|     QuestionId = (UINT16) ((UINTN) (&NVStruc.BootOrder) - (UINTN) (&NVStruc));
 | |
| 
 | |
|     //
 | |
|     // Need some memory for OptionList. Allow for up to 8 options.
 | |
|     //
 | |
|     OptionList = AllocateZeroPool (sizeof (IFR_OPTION) * 8);
 | |
|     ASSERT (OptionList != NULL);
 | |
| 
 | |
|     //
 | |
|     // Allocate space for creation of Buffer
 | |
|     //
 | |
|     UpdateData = AllocateZeroPool (0x1000);
 | |
|     ASSERT (UpdateData != NULL);
 | |
| 
 | |
|     //
 | |
|     // Remove all the op-codes starting with Label 0x2222 to next Label (second label is for convenience
 | |
|     // so we don't have to keep track of how many op-codes we added or subtracted.  The rules for removal
 | |
|     // of op-codes are simply that the removal will always stop as soon as a label or the end of a form is
 | |
|     // encountered.  Therefore, giving a large obnoxious count such as below takes care of other complexities.
 | |
|     //
 | |
|     UpdateData->DataCount = 0xFF;
 | |
| 
 | |
|     //
 | |
|     // Delete set of op-codes
 | |
|     //
 | |
|     Private->Hii->UpdateForm (
 | |
|                     Private->Hii,
 | |
|                     Private->RegisteredHandle,
 | |
|                     (EFI_FORM_LABEL) 0x2222,
 | |
|                     FALSE,  // If we aren't adding, we are deleting
 | |
|                     UpdateData
 | |
|                     );
 | |
| 
 | |
|     //
 | |
|     // Create 3 options
 | |
|     //
 | |
|     for (Index = 0; Index < 3; Index++) {
 | |
|       OptionList[Index].StringToken = (UINT16) (STR_BOOT_OPTION1 + Index);
 | |
|       OptionList[Index].Value       = (UINT16) (Index + 1);
 | |
|       OptionList[Index].Flags       = RESET_REQUIRED;
 | |
|     }
 | |
| 
 | |
|     CreateOrderedListOpCode (
 | |
|       QuestionId,                               // Question ID
 | |
|       8,                                        // Max Entries
 | |
|       (UINT16) STRING_TOKEN (STR_BOOT_OPTIONS), // Token value for the Prompt
 | |
|       (UINT16) STRING_TOKEN (STR_NULL_STRING),  // Token value for the Help
 | |
|       OptionList,
 | |
|       3,
 | |
|       &UpdateData->Data                         // Buffer location to place op-codes
 | |
|       );
 | |
| 
 | |
|     //
 | |
|     // For one-of/ordered lists commands, they really consist of 2 op-codes (a header and a footer)
 | |
|     // Each option within a one-of/ordered list is also an op-code
 | |
|     // So this example has 5 op-codes it is adding since we have a one-of header + 3 options + one-of footer
 | |
|     //
 | |
|     UpdateData->DataCount = 0x5;
 | |
| 
 | |
|     //
 | |
|     // Add one op-code
 | |
|     //
 | |
|     Private->Hii->UpdateForm (
 | |
|                     Private->Hii,
 | |
|                     Private->RegisteredHandle,
 | |
|                     (EFI_FORM_LABEL) 0x2222,
 | |
|                     TRUE,
 | |
|                     UpdateData
 | |
|                     );
 | |
| 
 | |
|     FreePool (UpdateData);
 | |
|     FreePool (OptionList);
 | |
|     break;
 | |
| 
 | |
|   case 0x0002:
 | |
|     //
 | |
|     // Create a large boot order list
 | |
|     //
 | |
|     QuestionId = (UINT16) ((UINTN) (&NVStruc.BootOrder) - (UINTN) (&NVStruc));
 | |
| 
 | |
|     //
 | |
|     // Need some memory for OptionList. Allow for up to 8 options.
 | |
|     //
 | |
|     OptionList = AllocateZeroPool (sizeof (IFR_OPTION) * 8);
 | |
|     ASSERT (OptionList != NULL);
 | |
| 
 | |
|     //
 | |
|     // Allocate space for creation of Buffer
 | |
|     //
 | |
|     UpdateData = AllocateZeroPool (0x1000);
 | |
|     ASSERT (UpdateData != NULL);
 | |
| 
 | |
|     //
 | |
|     // Remove all the op-codes starting with Label 0x2222 to next Label (second label is for convenience
 | |
|     // so we don't have to keep track of how many op-codes we added or subtracted
 | |
|     //
 | |
|     UpdateData->DataCount = 0xFF;
 | |
| 
 | |
|     //
 | |
|     // Delete one op-code
 | |
|     //
 | |
|     Private->Hii->UpdateForm (
 | |
|                     Private->Hii,
 | |
|                     Private->RegisteredHandle,
 | |
|                     (EFI_FORM_LABEL) 0x2222,
 | |
|                     FALSE,
 | |
|                     UpdateData
 | |
|                     );
 | |
| 
 | |
|     //
 | |
|     // Create 4 options
 | |
|     //
 | |
|     for (Index = 0; Index < 4; Index++) {
 | |
|       OptionList[Index].StringToken = (UINT16) (STR_BOOT_OPTION1 + Index);
 | |
|       OptionList[Index].Value       = (UINT16) (Index + 1);
 | |
|       OptionList[Index].Flags       = RESET_REQUIRED;
 | |
|     }
 | |
| 
 | |
|     CreateOrderedListOpCode (
 | |
|       QuestionId,                               // Question ID
 | |
|       8,                                        // Max Entries
 | |
|       (UINT16) STRING_TOKEN (STR_BOOT_OPTIONS), // Token value for the Prompt
 | |
|       (UINT16) STRING_TOKEN (STR_NULL_STRING),  // Token value for the Help
 | |
|       OptionList,
 | |
|       4,
 | |
|       &UpdateData->Data                         // Buffer location to place op-codes
 | |
|       );
 | |
| 
 | |
|     //
 | |
|     // For one-of commands, they really consist of 2 op-codes (a header and a footer)
 | |
|     // Each option within a one-of is also an op-code
 | |
|     // So this example has 6 op-codes it is adding since we have a one-of header + 4 options + one-of footer
 | |
|     //
 | |
|     UpdateData->DataCount = 0x6;
 | |
| 
 | |
|     //
 | |
|     // Add one op-code
 | |
|     //
 | |
|     Private->Hii->UpdateForm (
 | |
|                     Private->Hii,
 | |
|                     Private->RegisteredHandle,
 | |
|                     (EFI_FORM_LABEL) 0x2222,
 | |
|                     TRUE,
 | |
|                     UpdateData
 | |
|                     );
 | |
| 
 | |
|     FreePool (UpdateData);
 | |
|     FreePool (OptionList);
 | |
|     break;
 | |
| 
 | |
|   case 0x1234:
 | |
|     //
 | |
|     // Allocate space for creation of Buffer
 | |
|     //
 | |
|     QuestionId = (UINT16) ((UINTN) (&NVStruc.DynamicCheck) - (UINTN) (&NVStruc));
 | |
|     UpdateData = AllocateZeroPool (0x1000);
 | |
|     ASSERT (UpdateData != NULL);
 | |
| 
 | |
|     Location                        = (UINT8 *) &UpdateData->Data;
 | |
| 
 | |
|     UpdateData->FormSetUpdate       = TRUE;
 | |
|     UpdateData->FormCallbackHandle  = (EFI_PHYSICAL_ADDRESS) (UINTN) Private->CallbackHandle;
 | |
|     UpdateData->FormUpdate          = FALSE;
 | |
|     UpdateData->FormTitle           = 0;
 | |
|     UpdateData->DataCount           = 2;
 | |
| 
 | |
|     CreateGotoOpCode (
 | |
|       1,
 | |
|       STR_GOTO_FORM1,                                   // Token value for the Prompt
 | |
|       0,                                                // Goto Help
 | |
|       0,                                                // Flags
 | |
|       0,                                                // Key
 | |
|       &UpdateData->Data                                 // Buffer location to place op-codes
 | |
|       );
 | |
| 
 | |
|     Location = Location + ((EFI_IFR_OP_HEADER *) &UpdateData->Data)->Length;
 | |
| 
 | |
|     CreateCheckBoxOpCode (
 | |
|       QuestionId,                                       // Question ID
 | |
|       1,                                                // Data width (BOOLEAN = 1)
 | |
|       (UINT16) STRING_TOKEN (STR_CHECK_DYNAMIC_PROMPT), // Token value for the Prompt
 | |
|       (UINT16) STRING_TOKEN (STR_CHECK_DYNAMIC_HELP),   // Token value for the Help
 | |
|       EFI_IFR_FLAG_INTERACTIVE,                         // Flags
 | |
|       0x1236,   // Key
 | |
|       Location  // Buffer location to place op-codes
 | |
|       );
 | |
| 
 | |
|     Private->Hii->UpdateForm (
 | |
|                     Private->Hii,
 | |
|                     Private->RegisteredHandle,
 | |
|                     (EFI_FORM_LABEL) 0x1234,
 | |
|                     TRUE,
 | |
|                     UpdateData
 | |
|                     );
 | |
| 
 | |
|     FreePool (UpdateData);
 | |
|     QuestionId++;
 | |
|     break;
 | |
| 
 | |
|   case 0x1235:
 | |
|     //
 | |
|     // Allocate space for creation of Buffer
 | |
|     //
 | |
|     UpdateData = AllocateZeroPool (0x1000);
 | |
|     ASSERT (UpdateData != NULL);
 | |
| 
 | |
|     //
 | |
|     // Initialize DataPacket with information intended to remove all
 | |
|     // previously created op-codes in the dynamic page
 | |
|     //
 | |
|     UpdateData->FormSetUpdate       = FALSE;
 | |
|     UpdateData->FormCallbackHandle  = 0;
 | |
|     UpdateData->FormUpdate          = FALSE;
 | |
|     UpdateData->FormTitle           = 0;
 | |
|     //
 | |
|     // Unlikely to be more than 0xff op-codes in the dynamic page to remove
 | |
|     //
 | |
|     UpdateData->DataCount           = 0xff;
 | |
|     UpdateData->Data = NULL;
 | |
| 
 | |
|     //
 | |
|     // Remove all op-codes from dynamic page
 | |
|     //
 | |
|     Private->Hii->UpdateForm (
 | |
|                     Private->Hii,
 | |
|                     Private->RegisteredHandle,
 | |
|                     (EFI_FORM_LABEL) 0x1234,  // Label 0x1234
 | |
|                     FALSE,                    // Remove Op-codes (will never remove form/endform)
 | |
|                     UpdateData                // Significant value is UpdateData->DataCount
 | |
|                     );
 | |
| 
 | |
|     UpdateData->FormSetUpdate       = FALSE;
 | |
|     UpdateData->FormCallbackHandle  = 0;
 | |
|     UpdateData->FormUpdate          = FALSE;
 | |
|     UpdateData->FormTitle           = 0;
 | |
|     UpdateData->DataCount           = 1;
 | |
| 
 | |
|     CreateGotoOpCode (
 | |
|       1,
 | |
|       STR_GOTO_FORM1,                         // Token value for the Prompt
 | |
|       0,                                      // Goto Help
 | |
|       0,                                      // Flags
 | |
|       0,                                      // Key
 | |
|       &UpdateData->Data                       // Buffer location to place op-codes
 | |
|       );
 | |
| 
 | |
|     Private->Hii->UpdateForm (
 | |
|                     Private->Hii,
 | |
|                     Private->RegisteredHandle,
 | |
|                     (EFI_FORM_LABEL) 0x1234,
 | |
|                     TRUE,
 | |
|                     UpdateData
 | |
|                     );
 | |
| 
 | |
|     FreePool (UpdateData);
 | |
|     break;
 | |
| 
 | |
|   case 0x1236:
 | |
|     //
 | |
|     // If I hit the checkbox, I enter this case statement...
 | |
|     //
 | |
|     //
 | |
|     // Since I am returning an error (for test purposes) I need to pass in the string for the error
 | |
|     // I will allocate space for the return value.  If an error occurs (which is the case) I can simply return
 | |
|     // an error and fill in the string parameter, otherwise, I will return information in the DataArray structure.
 | |
|     // The browser will free this packet structure
 | |
|     //
 | |
|     *Packet = AllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET) + sizeof (SAMPLE_STRING) + 2);
 | |
|     ASSERT (*Packet != NULL);
 | |
| 
 | |
|     //
 | |
|     // Assign the buffer address to DataPacket
 | |
|     //
 | |
|     DataPacket = *Packet;
 | |
| 
 | |
|     StrCpy (DataPacket->String, (CHAR16 *) SAMPLE_STRING);
 | |
|     return EFI_DEVICE_ERROR;
 | |
| 
 | |
|   case 0x1237:
 | |
| 
 | |
|     *Packet = AllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET) + 2);
 | |
|     ASSERT (*Packet != NULL);
 | |
| 
 | |
|     //
 | |
|     // Assign the buffer address to DataPacket
 | |
|     //
 | |
|     DataPacket                        = *Packet;
 | |
| 
 | |
|     DataPacket->DataArray.EntryCount  = 1;
 | |
|     DataPacket->DataArray.NvRamMap    = NULL;
 | |
|     ((EFI_IFR_DATA_ENTRY *) (&DataPacket->DataArray + 1))->Flags = EXIT_REQUIRED;
 | |
|     break;
 | |
| 
 | |
|   case 0x1555:
 | |
|     Value = 0x0001;
 | |
|     UnicodeSPrint (VariableName, 0x80, (CHAR16 *) L"%d", VAR_EQ_TEST_NAME);
 | |
| 
 | |
|     gRT->SetVariable (
 | |
|           VariableName,
 | |
|           &mFormSetGuid,
 | |
|           EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
 | |
|           2,
 | |
|           (VOID *) &Value
 | |
|           );
 | |
|     break;
 | |
| 
 | |
|   case 0x1556:
 | |
|     Value = 0x1000;
 | |
|     UnicodeSPrint (VariableName, 0x80, (CHAR16 *) L"%d", VAR_EQ_TEST_NAME);
 | |
| 
 | |
|     gRT->SetVariable (
 | |
|           VariableName,
 | |
|           &mFormSetGuid,
 | |
|           EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
 | |
|           2,
 | |
|           (VOID *) &Value
 | |
|           );
 | |
|     break;
 | |
| 
 | |
|   case 0x1557:
 | |
|     Value = 0x0000;
 | |
|     UnicodeSPrint (VariableName, 0x80, (CHAR16 *) L"%d", VAR_EQ_TEST_NAME);
 | |
| 
 | |
|     gRT->SetVariable (
 | |
|           VariableName,
 | |
|           &mFormSetGuid,
 | |
|           EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
 | |
|           2,
 | |
|           (VOID *) &Value
 | |
|           );
 | |
|     break;
 | |
| 
 | |
|   default:
 | |
|     break;
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| DriverSampleInit (
 | |
|   IN EFI_HANDLE                   ImageHandle,
 | |
|   IN EFI_SYSTEM_TABLE             *SystemTable
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS          Status;
 | |
|   EFI_HII_PROTOCOL    *Hii;
 | |
|   //
 | |
|   //  EFI_FORM_BROWSER_PROTOCOL       *FormConfig;
 | |
|   //
 | |
|   EFI_HII_PACKAGES    *PackageList;
 | |
|   EFI_HII_HANDLE      HiiHandle;
 | |
|   STRING_REF          TokenToUpdate;
 | |
|   STRING_REF          TokenToUpdate2;
 | |
|   STRING_REF          TokenToUpdate3;
 | |
|   CHAR16              *NewString;
 | |
|   EFI_HII_UPDATE_DATA *UpdateData;
 | |
|   EFI_CALLBACK_INFO   *CallbackInfo;
 | |
|   EFI_HANDLE          Handle;
 | |
|   EFI_SCREEN_DESCRIPTOR   Screen;
 | |
| 
 | |
|   ZeroMem (&Screen, sizeof (EFI_SCREEN_DESCRIPTOR));
 | |
| 
 | |
|   gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &Screen.RightColumn, &Screen.BottomRow);
 | |
| 
 | |
|   //
 | |
|   // Remove 3 characters from top and bottom
 | |
|   //
 | |
|   Screen.TopRow     = 3;
 | |
|   Screen.BottomRow  = Screen.BottomRow - 3;
 | |
| 
 | |
|   //
 | |
|   // There should only be one HII protocol
 | |
|   //
 | |
|   Status = gBS->LocateProtocol (
 | |
|                   &gEfiHiiProtocolGuid,
 | |
|                   NULL,
 | |
|                   (VOID **) &Hii
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;;
 | |
|   }
 | |
| 
 | |
|   CallbackInfo = AllocatePool (sizeof (EFI_CALLBACK_INFO));
 | |
|   if (CallbackInfo == NULL) {
 | |
|     return EFI_OUT_OF_RESOURCES;
 | |
|   }
 | |
| 
 | |
|   CallbackInfo->Signature = EFI_CALLBACK_INFO_SIGNATURE;
 | |
|   CallbackInfo->Hii       = Hii;
 | |
| 
 | |
|   //
 | |
|   // This example does not implement worker functions for the NV accessor functions.  Only a callback evaluator
 | |
|   //
 | |
|   CallbackInfo->DriverCallback.NvRead   = NULL;
 | |
|   CallbackInfo->DriverCallback.NvWrite  = NULL;
 | |
|   CallbackInfo->DriverCallback.Callback = DriverCallback;
 | |
| 
 | |
|   //
 | |
|   // Install protocol interface
 | |
|   //
 | |
|   Handle = NULL;
 | |
|   Status = gBS->InstallProtocolInterface (
 | |
|                   &Handle,
 | |
|                   &gEfiFormCallbackProtocolGuid,
 | |
|                   EFI_NATIVE_INTERFACE,
 | |
|                   &CallbackInfo->DriverCallback
 | |
|                   );
 | |
| 
 | |
|   ASSERT_EFI_ERROR (Status);
 | |
| 
 | |
|   CallbackInfo->CallbackHandle  = Handle;
 | |
| 
 | |
|   PackageList                   = PreparePackages (1, &mStringPackGuid, DriverSampleStrings);
 | |
|   Status                        = Hii->NewPack (Hii, PackageList, &HiiHandle);
 | |
|   FreePool (PackageList);
 | |
| 
 | |
|   PackageList = PreparePackages (1, &mStringPackGuid, InventoryBin);
 | |
|   Status      = Hii->NewPack (Hii, PackageList, &HiiHandle);
 | |
|   FreePool (PackageList);
 | |
| 
 | |
|   PackageList = PreparePackages (1, &mStringPackGuid, VfrBin);
 | |
|   Status      = Hii->NewPack (Hii, PackageList, &HiiHandle);
 | |
|   FreePool (PackageList);
 | |
| 
 | |
|   CallbackInfo->RegisteredHandle = HiiHandle;
 | |
| 
 | |
|   //
 | |
|   // Very simple example of how one would update a string that is already
 | |
|   // in the HII database
 | |
|   //
 | |
|   TokenToUpdate = (STRING_REF) STR_CPU_STRING2;
 | |
|   NewString     = (CHAR16 *) L"700 Mhz";
 | |
| 
 | |
|   Hii->NewString (Hii, NULL, HiiHandle, &TokenToUpdate, NewString);
 | |
| 
 | |
|   //
 | |
|   // Add a string - if 0 will be updated with new Token number
 | |
|   //
 | |
|   TokenToUpdate = (STRING_REF) 0;
 | |
| 
 | |
|   //
 | |
|   // Add a string - if 0 will be updated with new Token number
 | |
|   //
 | |
|   TokenToUpdate2 = (STRING_REF) 0;
 | |
| 
 | |
|   //
 | |
|   // Add a string - if 0 will be updated with new Token number
 | |
|   //
 | |
|   TokenToUpdate3 = (STRING_REF) 0;
 | |
| 
 | |
|   Hii->NewString (Hii, NULL, HiiHandle, &TokenToUpdate, (CHAR16 *) L"Desired Speed");
 | |
|   Hii->NewString (Hii, NULL, HiiHandle, &TokenToUpdate2, (CHAR16 *) L"5 Thz");
 | |
|   Hii->NewString (Hii, NULL, HiiHandle, &TokenToUpdate3, (CHAR16 *) L"This is next year's desired speed - right?");
 | |
| 
 | |
|   //
 | |
|   // Allocate space for creation of Buffer
 | |
|   //
 | |
|   UpdateData = AllocateZeroPool (0x1000);
 | |
|   ASSERT (UpdateData != NULL);
 | |
| 
 | |
|   //
 | |
|   // Flag update pending in FormSet
 | |
|   //
 | |
|   UpdateData->FormSetUpdate = TRUE;
 | |
|   //
 | |
|   // Register CallbackHandle data for FormSet
 | |
|   //
 | |
|   UpdateData->FormCallbackHandle = (EFI_PHYSICAL_ADDRESS) (UINTN) CallbackInfo->CallbackHandle;
 | |
|   UpdateData->FormUpdate  = FALSE;
 | |
|   UpdateData->FormTitle   = 0;
 | |
|   UpdateData->DataCount   = 1;
 | |
| 
 | |
|   CreateTextOpCode (TokenToUpdate, TokenToUpdate2, TokenToUpdate3, 0, 0, &UpdateData->Data);
 | |
| 
 | |
|   Hii->UpdateForm (Hii, HiiHandle, (EFI_FORM_LABEL) 100, TRUE, UpdateData);
 | |
| 
 | |
|   FreePool (UpdateData);
 | |
| 
 | |
|   //
 | |
|   // Example of how to display only the item we sent to HII
 | |
|   //
 | |
|   if (DISPLAY_ONLY_MY_ITEM == 0x0001) {
 | |
|     //
 | |
|     // Have the browser pull out our copy of the data, and only display our data
 | |
|     //
 | |
|     //    Status = FormConfig->SendForm (FormConfig, TRUE, HiiHandle, NULL, NULL, NULL, &Screen, NULL);
 | |
|     //
 | |
|   } else {
 | |
|     //
 | |
|     // Have the browser pull out all the data in the HII Database and display it.
 | |
|     //
 | |
|     //    Status = FormConfig->SendForm (FormConfig, TRUE, 0, NULL, NULL, NULL, NULL, NULL);
 | |
|     //
 | |
|   }
 | |
| 
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 |