2. Add FRAMEWORK_MIDIA_FW_VOL_FILEPATH_DEVICE_PATH definition in FrameworkDxeCis.h git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2830 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			814 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			814 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Mde UEFI library functions.
 | 
						|
 | 
						|
  Copyright (c) 2006 - 2007, Intel Corporation<BR>
 | 
						|
  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:  UefiLib.c
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "UefiLibFramework.h"
 | 
						|
 | 
						|
/**
 | 
						|
  Compare whether two names of languages are identical.
 | 
						|
 | 
						|
  @param  Language1 Name of language 1.
 | 
						|
  @param  Language2 Name of language 2.
 | 
						|
 | 
						|
  @retval TRUE      Language 1 and language 2 are the same.
 | 
						|
  @retval FALSE     Language 1 and language 2 are not the same.
 | 
						|
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
BOOLEAN
 | 
						|
CompareIso639LanguageCode (
 | 
						|
  IN CONST CHAR8  *Language1,
 | 
						|
  IN CONST CHAR8  *Language2
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32  Name1;
 | 
						|
  UINT32  Name2;
 | 
						|
 | 
						|
  Name1 = ReadUnaligned24 ((CONST UINT32 *) Language1);
 | 
						|
  Name2 = ReadUnaligned24 ((CONST UINT32 *) Language2);
 | 
						|
 | 
						|
  return (BOOLEAN) (Name1 == Name2);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This function searches the list of configuration tables stored in the EFI System
 | 
						|
  Table for a table with a GUID that matches TableGuid.  If a match is found,
 | 
						|
  then a pointer to the configuration table is returned in Table, and EFI_SUCCESS
 | 
						|
  is returned.  If a matching GUID is not found, then EFI_NOT_FOUND is returned.
 | 
						|
 | 
						|
  @param  TableGuid       Pointer to table's GUID type..
 | 
						|
  @param  Table           Pointer to the table associated with TableGuid in the EFI System Table.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS     A configuration table matching TableGuid was found.
 | 
						|
  @retval EFI_NOT_FOUND   A configuration table matching TableGuid could not be found.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
EfiGetSystemConfigurationTable (
 | 
						|
  IN  EFI_GUID  *TableGuid,
 | 
						|
  OUT VOID      **Table
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_SYSTEM_TABLE  *SystemTable;
 | 
						|
  UINTN             Index;
 | 
						|
 | 
						|
  ASSERT (TableGuid != NULL);
 | 
						|
  ASSERT (Table != NULL);
 | 
						|
 | 
						|
  SystemTable = gST;
 | 
						|
  *Table = NULL;
 | 
						|
  for (Index = 0; Index < SystemTable->NumberOfTableEntries; Index++) {
 | 
						|
    if (CompareGuid (TableGuid, &(SystemTable->ConfigurationTable[Index].VendorGuid))) {
 | 
						|
      *Table = SystemTable->ConfigurationTable[Index].VendorTable;
 | 
						|
      return EFI_SUCCESS;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_NOT_FOUND;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This function causes the notification function to be executed for every protocol
 | 
						|
  of type ProtocolGuid instance that exists in the system when this function is
 | 
						|
  invoked.  In addition, every time a protocol of type ProtocolGuid instance is
 | 
						|
  installed or reinstalled, the notification function is also executed.
 | 
						|
 | 
						|
  @param  ProtocolGuid    Supplies GUID of the protocol upon whose installation the event is fired.
 | 
						|
  @param  NotifyTpl       Supplies the task priority level of the event notifications.
 | 
						|
  @param  NotifyFunction  Supplies the function to notify when the event is signaled.
 | 
						|
  @param  NotifyContext   The context parameter to pass to NotifyFunction.
 | 
						|
  @param  Registration    A pointer to a memory location to receive the registration value.
 | 
						|
 | 
						|
  @return The notification event that was created.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_EVENT
 | 
						|
EFIAPI
 | 
						|
EfiCreateProtocolNotifyEvent(
 | 
						|
  IN  EFI_GUID          *ProtocolGuid,
 | 
						|
  IN  EFI_TPL           NotifyTpl,
 | 
						|
  IN  EFI_EVENT_NOTIFY  NotifyFunction,
 | 
						|
  IN  VOID              *NotifyContext,  OPTIONAL
 | 
						|
  OUT VOID              **Registration
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  EFI_EVENT   Event;
 | 
						|
 | 
						|
  //
 | 
						|
  // Create the event
 | 
						|
  //
 | 
						|
 | 
						|
  Status = gBS->CreateEvent (
 | 
						|
                  EVT_NOTIFY_SIGNAL,
 | 
						|
                  NotifyTpl,
 | 
						|
                  NotifyFunction,
 | 
						|
                  NotifyContext,
 | 
						|
                  &Event
 | 
						|
                  );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  //
 | 
						|
  // Register for protocol notifactions on this event
 | 
						|
  //
 | 
						|
 | 
						|
  Status = gBS->RegisterProtocolNotify (
 | 
						|
                  ProtocolGuid,
 | 
						|
                  Event,
 | 
						|
                  Registration
 | 
						|
                  );
 | 
						|
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  //
 | 
						|
  // Kick the event so we will perform an initial pass of
 | 
						|
  // current installed drivers
 | 
						|
  //
 | 
						|
 | 
						|
  gBS->SignalEvent (Event);
 | 
						|
  return Event;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This function creates an event using NotifyTpl, NoifyFunction, and NotifyContext.
 | 
						|
  This event is signaled with EfiNamedEventSignal().  This provide the ability for
 | 
						|
  one or more listeners on the same event named by the GUID specified by Name.
 | 
						|
 | 
						|
  @param  Name                  Supplies GUID name of the event.
 | 
						|
  @param  NotifyTpl             Supplies the task priority level of the event notifications.
 | 
						|
  @param  NotifyFunction        Supplies the function to notify when the event is signaled.
 | 
						|
  @param  NotifyContext         The context parameter to pass to NotifyFunction.
 | 
						|
  @param  Registration          A pointer to a memory location to receive the registration value.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           A named event was created.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES  There are not enough resource to create the named event.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
EfiNamedEventListen (
 | 
						|
  IN CONST EFI_GUID    *Name,
 | 
						|
  IN EFI_TPL           NotifyTpl,
 | 
						|
  IN EFI_EVENT_NOTIFY  NotifyFunction,
 | 
						|
  IN CONST VOID        *NotifyContext,  OPTIONAL
 | 
						|
  OUT VOID             *Registration OPTIONAL
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  EFI_EVENT   Event;
 | 
						|
  VOID        *RegistrationLocal;
 | 
						|
 | 
						|
  //
 | 
						|
  // Create event
 | 
						|
  //
 | 
						|
  Status = gBS->CreateEvent (
 | 
						|
                  EVT_NOTIFY_SIGNAL,
 | 
						|
                  NotifyTpl,
 | 
						|
                  NotifyFunction,
 | 
						|
                  (VOID *) NotifyContext,
 | 
						|
                  &Event
 | 
						|
                  );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  //
 | 
						|
  // The Registration is not optional to RegisterProtocolNotify().
 | 
						|
  // To make it optional to EfiNamedEventListen(), may need to substitute with a local.
 | 
						|
  //
 | 
						|
  if (Registration != NULL) {
 | 
						|
    RegistrationLocal = Registration;
 | 
						|
  } else {
 | 
						|
    RegistrationLocal = &RegistrationLocal;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Register for an installation of protocol interface
 | 
						|
  //
 | 
						|
 | 
						|
  Status = gBS->RegisterProtocolNotify (
 | 
						|
                  (EFI_GUID *) Name,
 | 
						|
                  Event,
 | 
						|
                  RegistrationLocal
 | 
						|
                  );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This function signals the named event specified by Name.  The named event must
 | 
						|
  have been created with EfiNamedEventListen().
 | 
						|
 | 
						|
  @param  Name                  Supplies GUID name of the event.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           A named event was signaled.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES  There are not enough resource to signal the named event.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
EfiNamedEventSignal (
 | 
						|
  IN CONST EFI_GUID  *Name
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  EFI_HANDLE  Handle;
 | 
						|
 | 
						|
  Handle = NULL;
 | 
						|
  Status = gBS->InstallProtocolInterface (
 | 
						|
                  &Handle,
 | 
						|
                  (EFI_GUID *) Name,
 | 
						|
                  EFI_NATIVE_INTERFACE,
 | 
						|
                  NULL
 | 
						|
                  );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  Status = gBS->UninstallProtocolInterface (
 | 
						|
                  Handle,
 | 
						|
                  (EFI_GUID *) Name,
 | 
						|
                  NULL
 | 
						|
                  );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Returns the current TPL.
 | 
						|
 | 
						|
  This function returns the current TPL.  There is no EFI service to directly
 | 
						|
  retrieve the current TPL. Instead, the RaiseTPL() function is used to raise
 | 
						|
  the TPL to TPL_HIGH_LEVEL.  This will return the current TPL.  The TPL level
 | 
						|
  can then immediately be restored back to the current TPL level with a call
 | 
						|
  to RestoreTPL().
 | 
						|
 | 
						|
  @param  VOID
 | 
						|
 | 
						|
  @retvale EFI_TPL              The current TPL.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_TPL
 | 
						|
EFIAPI
 | 
						|
EfiGetCurrentTpl (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_TPL Tpl;
 | 
						|
 | 
						|
  Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
 | 
						|
  gBS->RestoreTPL (Tpl);
 | 
						|
 | 
						|
  return Tpl;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  This function initializes a basic mutual exclusion lock to the released state
 | 
						|
  and returns the lock.  Each lock provides mutual exclusion access at its task
 | 
						|
  priority level.  Since there is no preemption or multiprocessor support in EFI,
 | 
						|
  acquiring the lock only consists of raising to the locks TPL.
 | 
						|
 | 
						|
  @param  Lock       A pointer to the lock data structure to initialize.
 | 
						|
  @param  Priority   EFI TPL associated with the lock.
 | 
						|
 | 
						|
  @return The lock.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_LOCK *
 | 
						|
EFIAPI
 | 
						|
EfiInitializeLock (
 | 
						|
  IN OUT EFI_LOCK  *Lock,
 | 
						|
  IN EFI_TPL        Priority
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (Lock != NULL);
 | 
						|
  ASSERT (Priority <= TPL_HIGH_LEVEL);
 | 
						|
 | 
						|
  Lock->Tpl       = Priority;
 | 
						|
  Lock->OwnerTpl  = TPL_APPLICATION;
 | 
						|
  Lock->Lock      = EfiLockReleased ;
 | 
						|
  return Lock;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This function raises the system's current task priority level to the task
 | 
						|
  priority level of the mutual exclusion lock.  Then, it places the lock in the
 | 
						|
  acquired state.
 | 
						|
 | 
						|
  @param  Priority  The task priority level of the lock.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
EfiAcquireLock (
 | 
						|
  IN EFI_LOCK  *Lock
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (Lock != NULL);
 | 
						|
  ASSERT (Lock->Lock == EfiLockReleased);
 | 
						|
 | 
						|
  Lock->OwnerTpl = gBS->RaiseTPL (Lock->Tpl);
 | 
						|
  Lock->Lock     = EfiLockAcquired;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This function raises the system's current task priority level to the task
 | 
						|
  priority level of the mutual exclusion lock.  Then, it attempts to place the
 | 
						|
  lock in the acquired state.
 | 
						|
 | 
						|
  @param  Lock              A pointer to the lock to acquire.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       The lock was acquired.
 | 
						|
  @retval EFI_ACCESS_DENIED The lock could not be acquired because it is already owned.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
EfiAcquireLockOrFail (
 | 
						|
  IN EFI_LOCK  *Lock
 | 
						|
  )
 | 
						|
{
 | 
						|
 | 
						|
  ASSERT (Lock != NULL);
 | 
						|
  ASSERT (Lock->Lock != EfiLockUninitialized);
 | 
						|
 | 
						|
  if (Lock->Lock == EfiLockAcquired) {
 | 
						|
    //
 | 
						|
    // Lock is already owned, so bail out
 | 
						|
    //
 | 
						|
    return EFI_ACCESS_DENIED;
 | 
						|
  }
 | 
						|
 | 
						|
  Lock->OwnerTpl = gBS->RaiseTPL (Lock->Tpl);
 | 
						|
 | 
						|
  Lock->Lock = EfiLockAcquired;
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This function transitions a mutual exclusion lock from the acquired state to
 | 
						|
  the released state, and restores the system's task priority level to its
 | 
						|
  previous level.
 | 
						|
 | 
						|
  @param  Lock  A pointer to the lock to release.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
EfiReleaseLock (
 | 
						|
  IN EFI_LOCK  *Lock
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_TPL Tpl;
 | 
						|
 | 
						|
  ASSERT (Lock != NULL);
 | 
						|
  ASSERT (Lock->Lock == EfiLockAcquired);
 | 
						|
 | 
						|
  Tpl = Lock->OwnerTpl;
 | 
						|
 | 
						|
  Lock->Lock = EfiLockReleased;
 | 
						|
 | 
						|
  gBS->RestoreTPL (Tpl);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Tests whether a controller handle is being managed by a specific driver.
 | 
						|
 | 
						|
  This function tests whether the driver specified by DriverBindingHandle is
 | 
						|
  currently managing the controller specified by ControllerHandle.  This test
 | 
						|
  is performed by evaluating if the the protocol specified by ProtocolGuid is
 | 
						|
  present on ControllerHandle and is was opened by DriverBindingHandle with an
 | 
						|
  attribute of EFI_OPEN_PROTOCOL_BY_DRIVER.
 | 
						|
  If ProtocolGuid is NULL, then ASSERT().
 | 
						|
 | 
						|
  @param  ControllerHandle     A handle for a controller to test.
 | 
						|
  @param  DriverBindingHandle  Specifies the driver binding handle for the
 | 
						|
                               driver.
 | 
						|
  @param  ProtocolGuid         Specifies the protocol that the driver specified
 | 
						|
                               by DriverBindingHandle opens in its Start()
 | 
						|
                               function.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS          ControllerHandle is managed by the driver
 | 
						|
                               specifed by DriverBindingHandle.
 | 
						|
  @retval EFI_UNSUPPORTED      ControllerHandle is not managed by the driver
 | 
						|
                               specifed by DriverBindingHandle.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
EfiTestManagedDevice (
 | 
						|
  IN CONST EFI_HANDLE       ControllerHandle,
 | 
						|
  IN CONST EFI_HANDLE       DriverBindingHandle,
 | 
						|
  IN CONST EFI_GUID         *ProtocolGuid
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS     Status;
 | 
						|
  VOID           *ManagedInterface;
 | 
						|
 | 
						|
  ASSERT (ProtocolGuid != NULL);
 | 
						|
 | 
						|
  Status = gBS->OpenProtocol (
 | 
						|
                  ControllerHandle,
 | 
						|
                  (EFI_GUID *) ProtocolGuid,
 | 
						|
                  &ManagedInterface,
 | 
						|
                  DriverBindingHandle,
 | 
						|
                  ControllerHandle,
 | 
						|
                  EFI_OPEN_PROTOCOL_BY_DRIVER
 | 
						|
                  );
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    gBS->CloseProtocol (
 | 
						|
           ControllerHandle,
 | 
						|
           (EFI_GUID *) ProtocolGuid,
 | 
						|
           DriverBindingHandle,
 | 
						|
           ControllerHandle
 | 
						|
           );
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  if (Status != EFI_ALREADY_STARTED) {
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Tests whether a child handle is a child device of the controller.
 | 
						|
 | 
						|
  This function tests whether ChildHandle is one of the children of
 | 
						|
  ControllerHandle.  This test is performed by checking to see if the protocol
 | 
						|
  specified by ProtocolGuid is present on ControllerHandle and opened by
 | 
						|
  ChildHandle with an attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
 | 
						|
  If ProtocolGuid is NULL, then ASSERT().
 | 
						|
 | 
						|
  @param  ControllerHandle     A handle for a (parent) controller to test.
 | 
						|
  @param  ChildHandle          A child handle to test.
 | 
						|
  @param  ConsumsedGuid        Supplies the protocol that the child controller
 | 
						|
                               opens on its parent controller.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS          ChildHandle is a child of the ControllerHandle.
 | 
						|
  @retval EFI_UNSUPPORTED      ChildHandle is not a child of the
 | 
						|
                               ControllerHandle.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
EfiTestChildHandle (
 | 
						|
  IN CONST EFI_HANDLE       ControllerHandle,
 | 
						|
  IN CONST EFI_HANDLE       ChildHandle,
 | 
						|
  IN CONST EFI_GUID         *ProtocolGuid
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                            Status;
 | 
						|
  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY   *OpenInfoBuffer;
 | 
						|
  UINTN                                 EntryCount;
 | 
						|
  UINTN                                 Index;
 | 
						|
 | 
						|
  ASSERT (ProtocolGuid != NULL);
 | 
						|
 | 
						|
  //
 | 
						|
  // Retrieve the list of agents that are consuming the specific protocol
 | 
						|
  // on ControllerHandle.
 | 
						|
  //
 | 
						|
  Status = gBS->OpenProtocolInformation (
 | 
						|
                  ControllerHandle,
 | 
						|
                  (EFI_GUID *) ProtocolGuid,
 | 
						|
                  &OpenInfoBuffer,
 | 
						|
                  &EntryCount
 | 
						|
                  );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Inspect if ChildHandle is one of the agents.
 | 
						|
  //
 | 
						|
  Status = EFI_UNSUPPORTED;
 | 
						|
  for (Index = 0; Index < EntryCount; Index++) {
 | 
						|
    if ((OpenInfoBuffer[Index].ControllerHandle == ChildHandle) &&
 | 
						|
        (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
 | 
						|
      Status = EFI_SUCCESS;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  FreePool (OpenInfoBuffer);
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This function looks up a Unicode string in UnicodeStringTable.  If Language is
 | 
						|
  a member of SupportedLanguages and a Unicode string is found in UnicodeStringTable
 | 
						|
  that matches the language code specified by Language, then it is returned in
 | 
						|
  UnicodeString.
 | 
						|
 | 
						|
  @param  Language                A pointer to the ISO 639-2 language code for the
 | 
						|
                                  Unicode string to look up and return.
 | 
						|
  @param  SupportedLanguages      A pointer to the set of ISO 639-2 language codes
 | 
						|
                                  that the Unicode string table supports.  Language
 | 
						|
                                  must be a member of this set.
 | 
						|
  @param  UnicodeStringTable      A pointer to the table of Unicode strings.
 | 
						|
  @param  UnicodeString           A pointer to the Unicode string from UnicodeStringTable
 | 
						|
                                  that matches the language specified by Language.
 | 
						|
 | 
						|
  @retval  EFI_SUCCESS            The Unicode string that matches the language
 | 
						|
                                  specified by Language was found
 | 
						|
                                  in the table of Unicoide strings UnicodeStringTable,
 | 
						|
                                  and it was returned in UnicodeString.
 | 
						|
  @retval  EFI_INVALID_PARAMETER  Language is NULL.
 | 
						|
  @retval  EFI_INVALID_PARAMETER  UnicodeString is NULL.
 | 
						|
  @retval  EFI_UNSUPPORTED        SupportedLanguages is NULL.
 | 
						|
  @retval  EFI_UNSUPPORTED        UnicodeStringTable is NULL.
 | 
						|
  @retval  EFI_UNSUPPORTED        The language specified by Language is not a
 | 
						|
                                  member of SupportedLanguages.
 | 
						|
  @retval  EFI_UNSUPPORTED        The language specified by Language is not
 | 
						|
                                  supported by UnicodeStringTable.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
LookupUnicodeString (
 | 
						|
  IN CONST CHAR8                     *Language,
 | 
						|
  IN CONST CHAR8                     *SupportedLanguages,
 | 
						|
  IN CONST EFI_UNICODE_STRING_TABLE  *UnicodeStringTable,
 | 
						|
  OUT CHAR16                         **UnicodeString
 | 
						|
  )
 | 
						|
{
 | 
						|
  //
 | 
						|
  // Make sure the parameters are valid
 | 
						|
  //
 | 
						|
  if (Language == NULL || UnicodeString == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // If there are no supported languages, or the Unicode String Table is empty, then the
 | 
						|
  // Unicode String specified by Language is not supported by this Unicode String Table
 | 
						|
  //
 | 
						|
  if (SupportedLanguages == NULL || UnicodeStringTable == NULL) {
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Make sure Language is in the set of Supported Languages
 | 
						|
  //
 | 
						|
  while (*SupportedLanguages != 0) {
 | 
						|
    if (CompareIso639LanguageCode (Language, SupportedLanguages)) {
 | 
						|
 | 
						|
      //
 | 
						|
      // Search the Unicode String Table for the matching Language specifier
 | 
						|
      //
 | 
						|
      while (UnicodeStringTable->Language != NULL) {
 | 
						|
        if (CompareIso639LanguageCode (Language, UnicodeStringTable->Language)) {
 | 
						|
 | 
						|
          //
 | 
						|
          // A matching string was found, so return it
 | 
						|
          //
 | 
						|
          *UnicodeString = UnicodeStringTable->UnicodeString;
 | 
						|
          return EFI_SUCCESS;
 | 
						|
        }
 | 
						|
 | 
						|
        UnicodeStringTable++;
 | 
						|
      }
 | 
						|
 | 
						|
      return EFI_UNSUPPORTED;
 | 
						|
    }
 | 
						|
 | 
						|
    SupportedLanguages += 3;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_UNSUPPORTED;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This function adds a Unicode string to UnicodeStringTable.
 | 
						|
  If Language is a member of SupportedLanguages then UnicodeString is added to
 | 
						|
  UnicodeStringTable.  New buffers are allocated for both Language and
 | 
						|
  UnicodeString.  The contents of Language and UnicodeString are copied into
 | 
						|
  these new buffers.  These buffers are automatically freed when
 | 
						|
  FreeUnicodeStringTable() is called.
 | 
						|
 | 
						|
  @param  Language                A pointer to the ISO 639-2 language code for the Unicode
 | 
						|
                                  string to add.
 | 
						|
  @param  SupportedLanguages      A pointer to the set of ISO 639-2 language codes
 | 
						|
                                  that the Unicode string table supports.
 | 
						|
                                  Language must be a member of this set.
 | 
						|
  @param  UnicodeStringTable      A pointer to the table of Unicode strings.
 | 
						|
  @param  UnicodeString           A pointer to the Unicode string to add.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The Unicode string that matches the language
 | 
						|
                                  specified by Language was found in the table of
 | 
						|
                                  Unicode strings UnicodeStringTable, and it was
 | 
						|
                                  returned in UnicodeString.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Language is NULL.
 | 
						|
  @retval EFI_INVALID_PARAMETER   UnicodeString is NULL.
 | 
						|
  @retval EFI_INVALID_PARAMETER   UnicodeString is an empty string.
 | 
						|
  @retval EFI_UNSUPPORTED         SupportedLanguages is NULL.
 | 
						|
  @retval EFI_ALREADY_STARTED     A Unicode string with language Language is
 | 
						|
                                  already present in UnicodeStringTable.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    There is not enough memory to add another
 | 
						|
                                  Unicode string to UnicodeStringTable.
 | 
						|
  @retval EFI_UNSUPPORTED         The language specified by Language is not a
 | 
						|
                                  member of SupportedLanguages.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AddUnicodeString (
 | 
						|
  IN CONST CHAR8               *Language,
 | 
						|
  IN CONST CHAR8               *SupportedLanguages,
 | 
						|
  IN EFI_UNICODE_STRING_TABLE  **UnicodeStringTable,
 | 
						|
  IN CONST CHAR16              *UnicodeString
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN                     NumberOfEntries;
 | 
						|
  EFI_UNICODE_STRING_TABLE  *OldUnicodeStringTable;
 | 
						|
  EFI_UNICODE_STRING_TABLE  *NewUnicodeStringTable;
 | 
						|
  UINTN                     UnicodeStringLength;
 | 
						|
 | 
						|
  //
 | 
						|
  // Make sure the parameter are valid
 | 
						|
  //
 | 
						|
  if (Language == NULL || UnicodeString == NULL || UnicodeStringTable == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // If there are no supported languages, then a Unicode String can not be added
 | 
						|
  //
 | 
						|
  if (SupportedLanguages == NULL) {
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // If the Unicode String is empty, then a Unicode String can not be added
 | 
						|
  //
 | 
						|
  if (UnicodeString[0] == 0) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Make sure Language is a member of SupportedLanguages
 | 
						|
  //
 | 
						|
  while (*SupportedLanguages != 0) {
 | 
						|
    if (CompareIso639LanguageCode (Language, SupportedLanguages)) {
 | 
						|
 | 
						|
      //
 | 
						|
      // Determine the size of the Unicode String Table by looking for a NULL Language entry
 | 
						|
      //
 | 
						|
      NumberOfEntries = 0;
 | 
						|
      if (*UnicodeStringTable != NULL) {
 | 
						|
        OldUnicodeStringTable = *UnicodeStringTable;
 | 
						|
        while (OldUnicodeStringTable->Language != NULL) {
 | 
						|
          if (CompareIso639LanguageCode (Language, OldUnicodeStringTable->Language)) {
 | 
						|
            return EFI_ALREADY_STARTED;
 | 
						|
          }
 | 
						|
 | 
						|
          OldUnicodeStringTable++;
 | 
						|
          NumberOfEntries++;
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      // Allocate space for a new Unicode String Table.  It must hold the current number of
 | 
						|
      // entries, plus 1 entry for the new Unicode String, plus 1 entry for the end of table
 | 
						|
      // marker
 | 
						|
      //
 | 
						|
      NewUnicodeStringTable = AllocatePool ((NumberOfEntries + 2) * sizeof (EFI_UNICODE_STRING_TABLE));
 | 
						|
      if (NewUnicodeStringTable == NULL) {
 | 
						|
        return EFI_OUT_OF_RESOURCES;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      // If the current Unicode String Table contains any entries, then copy them to the
 | 
						|
      // newly allocated Unicode String Table.
 | 
						|
      //
 | 
						|
      if (*UnicodeStringTable != NULL) {
 | 
						|
        CopyMem (
 | 
						|
           NewUnicodeStringTable,
 | 
						|
           *UnicodeStringTable,
 | 
						|
           NumberOfEntries * sizeof (EFI_UNICODE_STRING_TABLE)
 | 
						|
           );
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      // Allocate space for a copy of the Language specifier
 | 
						|
      //
 | 
						|
      NewUnicodeStringTable[NumberOfEntries].Language = AllocateCopyPool (3, Language);
 | 
						|
      if (NewUnicodeStringTable[NumberOfEntries].Language == NULL) {
 | 
						|
        gBS->FreePool (NewUnicodeStringTable);
 | 
						|
        return EFI_OUT_OF_RESOURCES;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      // Compute the length of the Unicode String
 | 
						|
      //
 | 
						|
      for (UnicodeStringLength = 0; UnicodeString[UnicodeStringLength] != 0; UnicodeStringLength++)
 | 
						|
        ;
 | 
						|
 | 
						|
      //
 | 
						|
      // Allocate space for a copy of the Unicode String
 | 
						|
      //
 | 
						|
      NewUnicodeStringTable[NumberOfEntries].UnicodeString = AllocateCopyPool (
 | 
						|
                                                              (UnicodeStringLength + 1) * sizeof (CHAR16),
 | 
						|
                                                              UnicodeString
 | 
						|
                                                              );
 | 
						|
      if (NewUnicodeStringTable[NumberOfEntries].UnicodeString == NULL) {
 | 
						|
        gBS->FreePool (NewUnicodeStringTable[NumberOfEntries].Language);
 | 
						|
        gBS->FreePool (NewUnicodeStringTable);
 | 
						|
        return EFI_OUT_OF_RESOURCES;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      // Mark the end of the Unicode String Table
 | 
						|
      //
 | 
						|
      NewUnicodeStringTable[NumberOfEntries + 1].Language       = NULL;
 | 
						|
      NewUnicodeStringTable[NumberOfEntries + 1].UnicodeString  = NULL;
 | 
						|
 | 
						|
      //
 | 
						|
      // Free the old Unicode String Table
 | 
						|
      //
 | 
						|
      if (*UnicodeStringTable != NULL) {
 | 
						|
        gBS->FreePool (*UnicodeStringTable);
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      // Point UnicodeStringTable at the newly allocated Unicode String Table
 | 
						|
      //
 | 
						|
      *UnicodeStringTable = NewUnicodeStringTable;
 | 
						|
 | 
						|
      return EFI_SUCCESS;
 | 
						|
    }
 | 
						|
 | 
						|
    SupportedLanguages += 3;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_UNSUPPORTED;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This function frees the table of Unicode strings in UnicodeStringTable.
 | 
						|
  If UnicodeStringTable is NULL, then EFI_SUCCESS is returned.
 | 
						|
  Otherwise, each language code, and each Unicode string in the Unicode string
 | 
						|
  table are freed, and EFI_SUCCESS is returned.
 | 
						|
 | 
						|
  @param  UnicodeStringTable  A pointer to the table of Unicode strings.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS         The Unicode string table was freed.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
FreeUnicodeStringTable (
 | 
						|
  IN EFI_UNICODE_STRING_TABLE  *UnicodeStringTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN Index;
 | 
						|
 | 
						|
  //
 | 
						|
  // If the Unicode String Table is NULL, then it is already freed
 | 
						|
  //
 | 
						|
  if (UnicodeStringTable == NULL) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Loop through the Unicode String Table until we reach the end of table marker
 | 
						|
  //
 | 
						|
  for (Index = 0; UnicodeStringTable[Index].Language != NULL; Index++) {
 | 
						|
 | 
						|
    //
 | 
						|
    // Free the Language string from the Unicode String Table
 | 
						|
    //
 | 
						|
    gBS->FreePool (UnicodeStringTable[Index].Language);
 | 
						|
 | 
						|
    //
 | 
						|
    // Free the Unicode String from the Unicode String Table
 | 
						|
    //
 | 
						|
    if (UnicodeStringTable[Index].UnicodeString != NULL) {
 | 
						|
      gBS->FreePool (UnicodeStringTable[Index].UnicodeString);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Free the Unicode String Table itself
 | 
						|
  //
 | 
						|
  gBS->FreePool (UnicodeStringTable);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 |