示例#1
0
/**
  Clean up the HII Thunk Context for a UEFI HII Handle.

  @param Private        The HII Thunk Module Private context.
  @param UefiHiiHandle  The UEFI HII Handle.

**/
VOID
DestroyThunkContextForUefiHiiHandle (
    IN HII_THUNK_PRIVATE_DATA     *Private,
    IN EFI_HII_HANDLE             UefiHiiHandle
)
{
    HII_THUNK_CONTEXT     *ThunkContext;

    ThunkContext = UefiHiiHandleToThunkContext (Private, UefiHiiHandle);
    ASSERT (ThunkContext != NULL);

    DestroyThunkContext (ThunkContext);
}
示例#2
0
/**

  Remove a package from the HII database.

  @param This      Pointer of Frameowk HII protocol instance.
  @param Handle    Handle value to be removed.

  @retval EFI_SUCCESS           Packages has added to HII database successfully.
  @retval EFI_INVALID_PARAMETER If Handle or Packages is NULL.

**/
EFI_STATUS
EFIAPI
HiiRemovePack (
  IN EFI_HII_PROTOCOL               *This,
  IN FRAMEWORK_EFI_HII_HANDLE       Handle
  )
{
  EFI_STATUS                 Status;
  HII_THUNK_PRIVATE_DATA     *Private;
  HII_THUNK_CONTEXT          *ThunkContext;
  EFI_TPL                    OldTpl;

  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);

  mInFrameworkHiiRemovePack = TRUE;

  Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);

  ThunkContext = FwHiiHandleToThunkContext (Private, Handle);

  if (ThunkContext != NULL) {
    Status = mHiiDatabase->RemovePackageList (
                                          mHiiDatabase,
                                          ThunkContext->UefiHiiHandle
                                          );
    ASSERT_EFI_ERROR (Status);

    if (ThunkContext->IfrPackageCount != 0) {
      UninstallDefaultConfigAccessProtocol (ThunkContext);
    }

    DestroyThunkContext (ThunkContext);
  }else {
    Status = EFI_NOT_FOUND;
  }

  mInFrameworkHiiRemovePack = FALSE;
  gBS->RestoreTPL (OldTpl);

  return Status;
}
示例#3
0
/**
  Register the Package List passed from the Framework HII NewPack () interface.
  The FRAMEWORK_EFI_HII_HANDLE will be returned.

  @param This                         The EFI_HII_PROTOCOL context data. Only used
                                      to call HiiRemovePack.
  @param Private                      The HII THUNK driver context data.
  @param Packages                     Package List.
  @param Handle                       On output, a FRAMEWORK_EFI_HII_HANDLE number is
                                      returned.

  @retval EFI_SUCCESS                 The Package List is registered successfully in
                                      the database.
  @retval EFI_UNSUPPORTED             The number of IFR package in the package list
                                      is greater than 1.
  @retval EFI_OUT_OF_RESOURCE         Not enough resouce.
  
**/
EFI_STATUS
UefiRegisterPackageList (
  IN  EFI_HII_PROTOCOL            *This,
  IN  HII_THUNK_PRIVATE_DATA      *Private,
  IN  EFI_HII_PACKAGES            *Packages,
  OUT FRAMEWORK_EFI_HII_HANDLE    *Handle
  )
{
  EFI_STATUS                  Status;
  UINTN                       StringPackageCount;
  UINTN                       IfrPackageCount;
  UINTN                       FontPackageCount;
  EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;
  HII_THUNK_CONTEXT           *ThunkContext;
  HII_THUNK_CONTEXT           *ThunkContextToRemove;
  EFI_GUID                    GuidId;
  EFI_HII_PACKAGE_HEADER      *IfrPackage;

  PackageListHeader = NULL;

  Status = GetPackageCount (Packages, &IfrPackageCount, &StringPackageCount, &FontPackageCount);
  ASSERT_EFI_ERROR (Status);
  
  if (IfrPackageCount > 1) {
    //
    // HII Thunk only handle package with 0 or 1 IFR package. 
    //
    ASSERT (FALSE);
    return EFI_UNSUPPORTED;
  }

  ThunkContext = CreateThunkContext (Private, StringPackageCount, IfrPackageCount);
  if (ThunkContext == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  ThunkContext->ByFrameworkHiiNewPack = TRUE;
  
  if (Packages->GuidId == NULL) {
    //
    // UEFI HII Database require Package List GUID must be unique.
    //
    // If Packages->GuidId is NULL, the caller of FramworkHii->NewPack is registering
    // packages with at least 1 StringPack and 1 IfrPack. Therefore, Packages->GuidId is
    // not used as the name of the package list.  Formset GUID is used as the Package List
    // GUID instead.
    //
    ASSERT ((StringPackageCount >=1 && IfrPackageCount == 1) || (FontPackageCount > 0));
    if (IfrPackageCount > 0) {
      IfrPackage = GetIfrPackage (Packages);
      if (IfrPackage == NULL) {
        Status = EFI_NOT_FOUND;
        goto Done;
      }
      GetFormSetGuid (IfrPackage, &ThunkContext->TagGuid);
    } else {
      ASSERT (FontPackageCount > 0);
      GenerateRandomGuid (&ThunkContext->TagGuid);
    }
    
  } else {
    ThunkContextToRemove = TagGuidToIfrPackThunkContext (Private, Packages->GuidId);
    
    if (IfrPackageCount > 0 && 
        StringPackageCount > 0 && 
        (ThunkContextToRemove != NULL)) {
        DEBUG((EFI_D_WARN, "Framework code registers HII package list with the same GUID more than once.\n"));
        DEBUG((EFI_D_WARN, "Remove the previously registered package list and register the new one.\n"));
        HiiRemovePack (This, ThunkContextToRemove->FwHiiHandle);
    }
    CopyGuid (&ThunkContext->TagGuid, Packages->GuidId);
    
  }

  //
  // UEFI HII require EFI_HII_CONFIG_ACCESS_PROTOCOL to be installed on a EFI_HANDLE, so
  // that Setup Utility can load the Buffer Storage using this protocol. An UEFI VFR can only
  // produce IFR package generated with Buffer Storage type and EFI Variable Storage.
  // The default EFI_HII_CONFIG_ACCESS_PROTOCOL is used to Get/Set the Buffer Storage.
  //
  if (IfrPackageCount != 0) {
    InstallDefaultConfigAccessProtocol (Packages, ThunkContext);
  }
  
  PackageListHeader = PrepareUefiPackageListFromFrameworkHiiPackages (Packages, &ThunkContext->TagGuid);
  Status = mHiiDatabase->NewPackageList (
              mHiiDatabase,
              PackageListHeader,  
              ThunkContext->UefiHiiDriverHandle,
              &ThunkContext->UefiHiiHandle
              );
  if (Status == EFI_INVALID_PARAMETER) {
    FreePool (PackageListHeader);
    
    //
    // UEFI HII database does not allow two package list with the same GUID.
    // In Framework HII implementation, Packages->GuidId is used as an identifier to associate 
    // a PackageList with only IFR to a Package list the with String package.
    //
    GenerateRandomGuid (&GuidId);

    PackageListHeader = PrepareUefiPackageListFromFrameworkHiiPackages (Packages, &GuidId);
    Status = mHiiDatabase->NewPackageList (
                mHiiDatabase,
                PackageListHeader,  
                ThunkContext->UefiHiiDriverHandle,
                &ThunkContext->UefiHiiHandle
                );
  }

  //
  // BUGBUG: Remove when development is done
  //
  ASSERT_EFI_ERROR (Status);
  if (EFI_ERROR (Status)) {
    goto Done;
  }
  
  if (IfrPackageCount == 0) {
    if (StringPackageCount != 0) {
      //
      // Look for a Package List with only IFR Package with the same TAG GUID name.
      // If found one, add the String Packages to the found Package List.
      // This is needed because Framework HII Module may not register the String Package
      // and IFR Package in one NewPack () call.
      //
      UpdatePackListWithOnlyIfrPack (
          Private,
          ThunkContext,
          PackageListHeader
      );
    }
  } else {
    if (StringPackageCount == 0) {
      //
      // Look for the String Package with the same TAG GUID name and add
      // the found String Package to this Package List.
      // This is needed because Framework HII Module may not register the String Package
      // and IFR Package in one NewPack () call.
      //
      Status = FindStringPackAndUpdatePackListWithOnlyIfrPack (
                  Private,
                  ThunkContext
                  );

      if (EFI_ERROR (Status)) {
        goto Done;
      }
    }
    
    //
    // Parse the Formset. Must be called after FindStringPackAndUpdatePackListWithOnlyIfrPack is called so
    // that String Package is ready.
    //
    ThunkContext->FormSet = ParseFormSet (ThunkContext->UefiHiiHandle);
    ASSERT (ThunkContext->FormSet != NULL);
        
  }

Done:
  if (EFI_ERROR (Status)) {
    DestroyThunkContext (ThunkContext);
  } else {
    InsertTailList (&Private->ThunkContextListHead, &ThunkContext->Link);
    *Handle = ThunkContext->FwHiiHandle;
  }

	if (PackageListHeader != NULL) {
    FreePool (PackageListHeader);
  }
  
  return Status;
}