driversample.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 648 行 · 第 1/2 页

C
648
字号
/*++
Copyright (c) 2004 - 2006, 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_DRIVER_ENTRY_POINT (DriverSampleInit)

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;
  EFI_STATUS              Status;
  UINT8                   *Location;
  EFI_HII_CALLBACK_PACKET *DataPacket;
  UINT16                  Value;
  CHAR16                  VariableName[40];
  EFI_GUID                FormSetGuid = FORMSET_GUID;
  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);
  }

  EfiZeroMem (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 = EfiLibAllocateZeroPool (sizeof (IFR_OPTION) * 8);
    ASSERT ( OptionList != NULL );
    
    //
    // Allocate space for creation of Buffer
    //
    UpdateData = EfiLibAllocateZeroPool (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
                    );

    gBS->FreePool (UpdateData);
    gBS->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 = EfiLibAllocateZeroPool (sizeof (IFR_OPTION) * 8);
    ASSERT ( OptionList != NULL );
    
    //
    // Allocate space for creation of Buffer
    //
    UpdateData = EfiLibAllocateZeroPool (0x1000);
    ASSERT ( OptionList != 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
                    );

    gBS->FreePool (UpdateData);
    gBS->FreePool (OptionList);
    break;

  case 0x1234:
    //
    // Allocate space for creation of Buffer
    //
    QuestionId = (UINT16) ((UINTN) (&NVStruc.DynamicCheck) - (UINTN) (&NVStruc));
    Status = gBS->AllocatePool (
                    EfiBootServicesData,
                    0x1000,
                    &UpdateData
                    );
    ASSERT_EFI_ERROR (Status);
    
    EfiZeroMem (UpdateData, 0x1000);

    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
                    );

    gBS->FreePool (UpdateData);
    QuestionId++;
    break;

  case 0x1235:
    //
    // Allocate space for creation of Buffer
    //
    Status = gBS->AllocatePool (
                    EfiBootServicesData,
                    0x1000,
                    &UpdateData
                    );
    ASSERT_EFI_ERROR (Status);

    EfiZeroMem (UpdateData, 0x1000);

    //
    // 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

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?