package.c

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

C
679
字号
/*++

Copyright (c) 2004, 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:

  Package.c

Abstract:

  This file contains the package processing code to the HII database.

--*/

#include "HiiDatabase.h"

EFI_STATUS
GetPackSize (
  IN  VOID                *Pack,
  OUT UINTN               *PackSize,
  OUT UINT32              *NumberOfTokens
  )
/*++

Routine Description:
  Determines the passed in Pack's size and returns the value.
  
Arguments:

Returns: 

--*/
{
  EFI_HII_STRING_PACK *StringPack;
  UINT16              Type;
  UINT32              Length;

  *PackSize = 0;

  Type      = EFI_HII_IFR;
  if (!EfiCompareMem (&((EFI_HII_PACK_HEADER *) Pack)->Type, &Type, sizeof (UINT16))) {
    //
    // The header contains the full IFR length
    //
    EfiCopyMem (&Length, &((EFI_HII_PACK_HEADER *) Pack)->Length, sizeof (Length));
    *PackSize = (UINTN) Length;
    return EFI_SUCCESS;
  }

  Type = EFI_HII_STRING;
  if (!EfiCompareMem (&((EFI_HII_PACK_HEADER *) Pack)->Type, &Type, sizeof (UINT16))) {
    //
    // The header contains the STRING package length
    // The assumption is that the strings for all languages
    // are a contiguous block of data and there is a series of
    // these package instances which will terminate with a NULL package
    // instance.
    //
    StringPack = (EFI_HII_STRING_PACK *) Pack;

    //
    // There may be multiple instances packed together of strings
    // so we must walk the self describing structures until we encounter
    // the NULL structure to determine the full size.
    //
    EfiCopyMem (&Length, &StringPack->Header.Length, sizeof (Length));
    if (NumberOfTokens != NULL) {
      EfiCopyMem (NumberOfTokens, &StringPack->NumStringPointers, sizeof (UINT32));
    }

    while (Length != 0) {
      *PackSize   = *PackSize + Length;
      StringPack  = (EFI_HII_STRING_PACK *) ((CHAR8 *) StringPack + Length);
      EfiCopyMem (&Length, &StringPack->Header.Length, sizeof (Length));
    }
    //
    // Encountered a length of 0, so let's add the space for the NULL terminator
    // pack's length and call it done.
    //
    *PackSize = *PackSize + sizeof (EFI_HII_STRING_PACK);
    return EFI_SUCCESS;
  }
  //
  // We only determine the size of the non-global Package types.
  // If neither IFR or STRING data were found, return an error
  //
  return EFI_NOT_FOUND;
}

EFI_STATUS
ValidatePack (
  IN   EFI_HII_PROTOCOL          *This,
  IN   EFI_HII_PACKAGE_INSTANCE  *PackageInstance,
  OUT  EFI_HII_PACKAGE_INSTANCE  **StringPackageInstance,
  OUT  UINT32                    *TotalStringCount
  )
/*++

Routine Description:
  Verifies that the package instance is using the correct handle for string operations.
  
Arguments:

Returns: 

--*/
{
  EFI_HII_DATA              *HiiData;
  EFI_HII_HANDLE_DATABASE   *HandleDatabase;
  EFI_HII_PACKAGE_INSTANCE  *HandlePackageInstance;
  UINT8                     *RawData;
  EFI_GUID                  Guid;
  EFI_HII_IFR_PACK          *FormPack;
  UINTN                     Index;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  HiiData         = EFI_HII_DATA_FROM_THIS (This);

  HandleDatabase  = HiiData->DatabaseHead;
  EfiZeroMem (&Guid, sizeof (EFI_GUID));

  *StringPackageInstance = PackageInstance;

  //
  // Based on if there is IFR data in this package instance, determine
  // what the location is of the beginning of the string data.
  //
  if (PackageInstance->IfrSize > 0) {
    FormPack = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));
  } else {
    //
    // If there is no IFR data assume the caller knows what they are doing.
    //
    return EFI_SUCCESS;
  }

  RawData = (UINT8 *) FormPack;

  for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {
    if (RawData[Index] == EFI_IFR_FORM_SET_OP) {
      //
      // Cache the guid for this formset
      //
      EfiCopyMem (&Guid, &((EFI_IFR_FORM_SET *) &RawData[Index])->Guid, sizeof (EFI_GUID));
      break;
    }

    Index = RawData[Index + 1] + Index;
  }
  //
  // If there is no string package, and the PackageInstance->IfrPack.Guid and PackageInstance->Guid are
  // different, we should return the correct handle for the caller to use for strings.
  //
  if ((PackageInstance->StringSize == 0) && (!EfiCompareGuid (&Guid, &PackageInstance->Guid))) {
    //
    // Search the database for a handle that matches the PackageInstance->Guid
    //
    for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {
      //
      // Get Ifrdata and extract the Guid for it
      //
      HandlePackageInstance = HandleDatabase->Buffer;

      ASSERT (HandlePackageInstance->IfrSize != 0);

      FormPack  = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&HandlePackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));
      RawData   = (UINT8 *) FormPack;

      for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {
        if (RawData[Index] == EFI_IFR_FORM_SET_OP) {
          //
          // Cache the guid for this formset
          //
          EfiCopyMem (&Guid, &((EFI_IFR_FORM_SET *) &RawData[Index])->Guid, sizeof (EFI_GUID));
          break;
        }

        Index = RawData[Index + 1] + Index;
      }
      //
      // If the Guid from the new handle matches the original Guid referenced in the original package data
      // return the appropriate package instance data to use.
      //
      if (EfiCompareGuid (&Guid, &PackageInstance->Guid)) {
        if (TotalStringCount != NULL) {
          *TotalStringCount = HandleDatabase->NumberOfTokens;
        }

        *StringPackageInstance = HandlePackageInstance;
      }
    }
    //
    // end for
    //
  } else {
    return EFI_SUCCESS;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
EFIAPI
HiiNewPack (
  IN  EFI_HII_PROTOCOL    *This,
  IN  EFI_HII_PACKAGES    *Packages,
  OUT EFI_HII_HANDLE      *Handle
  )
/*++

Routine Description:

  Extracts the various packs from a package list.
  
Arguments:

  This      - Pointer of HII protocol.
  Packages  - Pointer of HII packages.
  Handle    - Handle value to be returned.

Returns: 

  EFI_SUCCESS           - Pacakges has added to HII database successfully.
  EFI_INVALID_PARAMETER - Invalid parameter.

--*/
{
  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;
  EFI_HII_DATA              *HiiData;
  EFI_HII_HANDLE_DATABASE   *HandleDatabase;
  EFI_HII_HANDLE_DATABASE   *Database;
  EFI_HII_PACK_HEADER       *PackageHeader;
  EFI_HII_GLOBAL_DATA       *GlobalData;
  EFI_HII_IFR_PACK          *IfrPack;
  EFI_HII_STRING_PACK       *StringPack;
  EFI_HII_HANDLE_PACK       *Handlepack;
  EFI_HII_FONT_PACK         *FontPack;
  EFI_HII_KEYBOARD_PACK     *KeyboardPack;
  EFI_STATUS                Status;
  UINTN                     IfrSize;
  UINTN                     StringSize;
  UINTN                     TotalStringSize;
  UINTN                     InstanceSize;
  UINTN                     Count;
  UINTN                     Index;
  UINT16                    Member;
  EFI_GUID                  Guid;
  EFI_FORM_SET_STUB         FormSetStub;
  UINT8                     *Location;
  UINT16                    Unicode;
  UINT16                    NumWideGlyphs;
  UINT16                    NumNarrowGlyphs;
  UINT32                    NumberOfTokens;
  UINT32                    TotalTokenNumber;
  UINT8                     *Local;
  EFI_NARROW_GLYPH          *NarrowGlyph;
  EFI_WIDE_GLYPH            *WideGlyph;

  if (Packages->NumberOfPackages == 0 || This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  HiiData           = EFI_HII_DATA_FROM_THIS (This);

  GlobalData        = HiiData->GlobalData;

  Database          = HiiData->DatabaseHead;

  PackageInstance   = NULL;
  IfrPack           = NULL;
  StringPack        = NULL;
  InstanceSize      = 0;
  IfrSize           = 0;
  StringSize        = 0;
  TotalStringSize   = 0;
  NumberOfTokens    = 0;
  TotalTokenNumber  = 0;

  //
  // Search through the passed in Packages for the IfrPack and any StringPack.
  //
  for (Index = 0; Index < Packages->NumberOfPackages; Index++) {

    PackageHeader = *(EFI_HII_PACK_HEADER **) (((UINT8 *) Packages) + sizeof (EFI_HII_PACKAGES) + Index * sizeof (VOID *));

    switch (PackageHeader->Type) {
    case EFI_HII_IFR:
      //
      // There shoule be only one Ifr package.
      //
      ASSERT (IfrPack == NULL);
      IfrPack = (EFI_HII_IFR_PACK *) PackageHeader;
      break;

    case EFI_HII_STRING:
      StringPack = (EFI_HII_STRING_PACK *) PackageHeader;
      //
      // Sending me a String Package. Get its size.
      //
      Status = GetPackSize ((VOID *) StringPack, &StringSize, &NumberOfTokens);
      ASSERT (!EFI_ERROR (Status));

      //
      // The size which GetPackSize() returns include the null terminator. So if multiple
      // string packages are passed in, merge all these packages, and only pad one null terminator.
      //
      if (TotalStringSize > 0) {
        TotalStringSize -= sizeof (EFI_HII_STRING_PACK);
      }

      TotalStringSize += StringSize;
      TotalTokenNumber += NumberOfTokens;
      break;
    }
  }
  //
  // If sending a StringPack without an IfrPack, you must include a GuidId
  //
  if ((StringPack != NULL) && (IfrPack == NULL)) {
    if (Packages->GuidId == NULL) {
      return EFI_INVALID_PARAMETER;
    }
  }
  //
  // If passing in an IfrPack and a GuidId is provided, ensure they are the same value.
  //
  if ((IfrPack != NULL) && (Packages->GuidId != NULL)) {
    Location  = ((UINT8 *) IfrPack);
    Location  = (UINT8 *) (((UINTN) Location) + sizeof (EFI_HII_PACK_HEADER));

⌨️ 快捷键说明

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