+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-\r
-**/\r
-\r
-#include "EdkIIGlueUefi.h"\r
-#include "Library/EdkIIGlueMemoryAllocationLib.h"\r
-\r
-\r
-/**\r
- This function searches the list of configuration tables stored in the EFI System \r
- Table for a table with a GUID that matches TableGuid. If a match is found, \r
- then a pointer to the configuration table is returned in Table, and EFI_SUCCESS \r
- is returned. If a matching GUID is not found, then EFI_NOT_FOUND is returned.\r
-\r
- @param TableGuid Pointer to table's GUID type..\r
- @param Table Pointer to the table associated with TableGuid in the EFI System Table.\r
-\r
- @retval EFI_SUCCESS A configuration table matching TableGuid was found.\r
- @retval EFI_NOT_FOUND A configuration table matching TableGuid could not be found.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EfiGetSystemConfigurationTable ( \r
- IN EFI_GUID *TableGuid,\r
- OUT VOID **Table\r
- )\r
-{\r
- EFI_SYSTEM_TABLE *SystemTable;\r
- UINTN Index;\r
-\r
- ASSERT (TableGuid != NULL);\r
- ASSERT (Table != NULL);\r
-\r
- SystemTable = gST;\r
- *Table = NULL;\r
- for (Index = 0; Index < SystemTable->NumberOfTableEntries; Index++) {\r
- if (CompareGuid (TableGuid, &(SystemTable->ConfigurationTable[Index].VendorGuid))) {\r
- *Table = SystemTable->ConfigurationTable[Index].VendorTable;\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-/**\r
- This function causes the notification function to be executed for every protocol \r
- of type ProtocolGuid instance that exists in the system when this function is \r
- invoked. In addition, every time a protocol of type ProtocolGuid instance is \r
- installed or reinstalled, the notification function is also executed.\r
-\r
- @param ProtocolGuid Supplies GUID of the protocol upon whose installation the event is fired.\r
- @param NotifyTpl Supplies the task priority level of the event notifications.\r
- @param NotifyFunction Supplies the function to notify when the event is signaled.\r
- @param NotifyContext The context parameter to pass to NotifyFunction.\r
- @param Registration A pointer to a memory location to receive the registration value.\r
-\r
- @return The notification event that was created. \r
-\r
-**/\r
-EFI_EVENT\r
-EFIAPI\r
-EfiCreateProtocolNotifyEvent(\r
- IN EFI_GUID *ProtocolGuid,\r
- IN EFI_TPL NotifyTpl,\r
- IN EFI_EVENT_NOTIFY NotifyFunction,\r
- IN VOID *NotifyContext, OPTIONAL\r
- OUT VOID **Registration\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_EVENT Event;\r
-\r
- //\r
- // Create the event\r
- //\r
-\r
- Status = gBS->CreateEvent (\r
- EFI_EVENT_NOTIFY_SIGNAL,\r
- NotifyTpl,\r
- NotifyFunction,\r
- NotifyContext,\r
- &Event\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Register for protocol notifactions on this event\r
- //\r
-\r
- Status = gBS->RegisterProtocolNotify (\r
- ProtocolGuid,\r
- Event,\r
- Registration\r
- );\r
-\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Kick the event so we will perform an initial pass of\r
- // current installed drivers\r
- //\r
-\r
- gBS->SignalEvent (Event);\r
- return Event;\r
-}\r
-\r
-/**\r
- This function creates an event using NotifyTpl, NoifyFunction, and NotifyContext.\r
- This event is signaled with EfiNamedEventSignal(). This provide the ability for \r
- one or more listeners on the same event named by the GUID specified by Name.\r
-\r
- @param Name Supplies GUID name of the event.\r
- @param NotifyTpl Supplies the task priority level of the event notifications.\r
- @param NotifyFunction Supplies the function to notify when the event is signaled.\r
- @param NotifyContext The context parameter to pass to NotifyFunction. \r
- @param Registration A pointer to a memory location to receive the registration value.\r
-\r
- @retval EFI_SUCCESS A named event was created.\r
- @retval EFI_OUT_OF_RESOURCES There are not enough resource to create the named event.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EfiNamedEventListen (\r
- IN CONST EFI_GUID *Name,\r
- IN EFI_TPL NotifyTpl,\r
- IN EFI_EVENT_NOTIFY NotifyFunction,\r
- IN CONST VOID *NotifyContext, OPTIONAL\r
- OUT VOID *Registration OPTIONAL\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_EVENT Event;\r
- VOID *RegistrationLocal;\r
-\r
- //\r
- // Create event\r
- //\r
- Status = gBS->CreateEvent (\r
- EFI_EVENT_NOTIFY_SIGNAL,\r
- NotifyTpl,\r
- NotifyFunction,\r
- (VOID *) NotifyContext,\r
- &Event\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // The Registration is not optional to RegisterProtocolNotify().\r
- // To make it optional to EfiNamedEventListen(), may need to substitute with a local.\r
- //\r
- if (Registration != NULL) {\r
- RegistrationLocal = Registration;\r
- } else {\r
- RegistrationLocal = &RegistrationLocal;\r
- }\r
-\r
- //\r
- // Register for an installation of protocol interface\r
- //\r
-\r
- Status = gBS->RegisterProtocolNotify (\r
- (EFI_GUID *) Name,\r
- Event,\r
- RegistrationLocal\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function signals the named event specified by Name. The named event must \r
- have been created with EfiNamedEventListen().\r
-\r
- @param Name Supplies GUID name of the event.\r
-\r
- @retval EFI_SUCCESS A named event was signaled.\r
- @retval EFI_OUT_OF_RESOURCES There are not enough resource to signal the named event.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EfiNamedEventSignal (\r
- IN CONST EFI_GUID *Name\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HANDLE Handle;\r
-\r
- Handle = NULL;\r
- Status = gBS->InstallProtocolInterface (\r
- &Handle,\r
- (EFI_GUID *) Name,\r
- EFI_NATIVE_INTERFACE,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- Status = gBS->UninstallProtocolInterface (\r
- Handle,\r
- (EFI_GUID *) Name,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/** \r
- Returns the current TPL.\r
-\r
- This function returns the current TPL. There is no EFI service to directly \r
- retrieve the current TPL. Instead, the RaiseTPL() function is used to raise \r
- the TPL to TPL_HIGH_LEVEL. This will return the current TPL. The TPL level \r
- can then immediately be restored back to the current TPL level with a call \r
- to RestoreTPL().\r
-\r
- @param VOID\r
-\r
- @retvale EFI_TPL The current TPL.\r
-\r
-**/\r
-EFI_TPL\r
-EFIAPI\r
-EfiGetCurrentTpl (\r
- VOID\r
- )\r
-{\r
- EFI_TPL Tpl;\r
-\r
- Tpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL); \r
- gBS->RestoreTPL (Tpl);\r
-\r
- return Tpl;\r
-}\r
-\r
-\r
-/**\r
- This function initializes a basic mutual exclusion lock to the released state \r
- and returns the lock. Each lock provides mutual exclusion access at its task \r
- priority level. Since there is no preemption or multiprocessor support in EFI,\r
- acquiring the lock only consists of raising to the locks TPL.\r
-\r
- @param Lock A pointer to the lock data structure to initialize.\r
- @param Priority EFI TPL associated with the lock.\r
-\r
- @return The lock.\r
-\r
-**/\r
-EFI_LOCK *\r
-EFIAPI\r
-GlueEfiInitializeLock (\r
- IN OUT EFI_LOCK *Lock,\r
- IN EFI_TPL Priority\r
- )\r
-{\r
- ASSERT (Lock != NULL);\r
- ASSERT (Priority <= EFI_TPL_HIGH_LEVEL);\r
-\r
- Lock->Tpl = Priority;\r
- Lock->OwnerTpl = EFI_TPL_APPLICATION;\r
- Lock->Lock = EfiLockReleased ;\r
- return Lock;\r
-}\r
-\r
-/**\r
- This function raises the system's current task priority level to the task \r
- priority level of the mutual exclusion lock. Then, it places the lock in the \r
- acquired state.\r
-\r
- @param Priority The task priority level of the lock.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-GlueEfiAcquireLock (\r
- IN EFI_LOCK *Lock\r
- )\r
-{\r
- ASSERT (Lock != NULL);\r
- ASSERT (Lock->Lock == EfiLockReleased);\r
-\r
- Lock->OwnerTpl = gBS->RaiseTPL (Lock->Tpl);\r
- Lock->Lock = EfiLockAcquired;\r
-}\r
-\r
-/**\r
- This function raises the system's current task priority level to the task \r
- priority level of the mutual exclusion lock. Then, it attempts to place the \r
- lock in the acquired state.\r
-\r
- @param Lock A pointer to the lock to acquire.\r
-\r
- @retval EFI_SUCCESS The lock was acquired.\r
- @retval EFI_ACCESS_DENIED The lock could not be acquired because it is already owned.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-GlueEfiAcquireLockOrFail (\r
- IN EFI_LOCK *Lock\r
- )\r
-{\r
-\r
- ASSERT (Lock != NULL);\r
- ASSERT (Lock->Lock != EfiLockUninitialized);\r
-\r
- if (Lock->Lock == EfiLockAcquired) {\r
- //\r
- // Lock is already owned, so bail out\r
- //\r
- return EFI_ACCESS_DENIED;\r
- }\r
-\r
- Lock->OwnerTpl = gBS->RaiseTPL (Lock->Tpl);\r
-\r
- Lock->Lock = EfiLockAcquired;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function transitions a mutual exclusion lock from the acquired state to \r
- the released state, and restores the system's task priority level to its \r
- previous level.\r
-\r
- @param Lock A pointer to the lock to release.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-GlueEfiReleaseLock (\r
- IN EFI_LOCK *Lock\r
- )\r
-{\r
- EFI_TPL Tpl;\r
-\r
- ASSERT (Lock != NULL);\r
- ASSERT (Lock->Lock == EfiLockAcquired);\r
-\r
- Tpl = Lock->OwnerTpl;\r
- \r
- Lock->Lock = EfiLockReleased;\r
-\r
- gBS->RestoreTPL (Tpl);\r
-}\r
-\r
-/**\r
- Tests whether a controller handle is being managed by a specific driver.\r
-\r
- This function tests whether the driver specified by DriverBindingHandle is\r
- currently managing the controller specified by ControllerHandle. This test\r
- is performed by evaluating if the the protocol specified by ProtocolGuid is\r
- present on ControllerHandle and is was opened by DriverBindingHandle with an\r
- attribute of EFI_OPEN_PROTOCOL_BY_DRIVER. \r
- If ProtocolGuid is NULL, then ASSERT().\r
-\r
- @param ControllerHandle A handle for a controller to test.\r
- @param DriverBindingHandle Specifies the driver binding handle for the\r
- driver.\r
- @param ProtocolGuid Specifies the protocol that the driver specified\r
- by DriverBindingHandle opens in its Start()\r
- function.\r
-\r
- @retval EFI_SUCCESS ControllerHandle is managed by the driver\r
- specifed by DriverBindingHandle.\r
- @retval EFI_UNSUPPORTED ControllerHandle is not managed by the driver\r
- specifed by DriverBindingHandle.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EfiTestManagedDevice (\r
- IN CONST EFI_HANDLE ControllerHandle,\r
- IN CONST EFI_HANDLE DriverBindingHandle,\r
- IN CONST EFI_GUID *ProtocolGuid\r
- )\r
-{\r
- EFI_STATUS Status;\r
- VOID *ManagedInterface;\r
-\r
- ASSERT (ProtocolGuid != NULL);\r
-\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- (EFI_GUID *) ProtocolGuid,\r
- &ManagedInterface,\r
- DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- gBS->CloseProtocol (\r
- ControllerHandle,\r
- (EFI_GUID *) ProtocolGuid,\r
- DriverBindingHandle,\r
- ControllerHandle\r
- );\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- if (Status != EFI_ALREADY_STARTED) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Tests whether a child handle is a child device of the controller.\r
-\r
- This function tests whether ChildHandle is one of the children of\r
- ControllerHandle. This test is performed by checking to see if the protocol\r
- specified by ProtocolGuid is present on ControllerHandle and opened by\r
- ChildHandle with an attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
- If ProtocolGuid is NULL, then ASSERT().\r
-\r
- @param ControllerHandle A handle for a (parent) controller to test. \r
- @param ChildHandle A child handle to test.\r
- @param ConsumsedGuid Supplies the protocol that the child controller\r
- opens on its parent controller. \r
-\r
- @retval EFI_SUCCESS ChildHandle is a child of the ControllerHandle.\r
- @retval EFI_UNSUPPORTED ChildHandle is not a child of the\r
- ControllerHandle.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EfiTestChildHandle (\r
- IN CONST EFI_HANDLE ControllerHandle,\r
- IN CONST EFI_HANDLE ChildHandle,\r
- IN CONST EFI_GUID *ProtocolGuid\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;\r
- UINTN EntryCount;\r
- UINTN Index;\r
-\r
- ASSERT (ProtocolGuid != NULL);\r
-\r
- //\r
- // Retrieve the list of agents that are consuming the specific protocol\r
- // on ControllerHandle.\r
- //\r
- Status = gBS->OpenProtocolInformation (\r
- ControllerHandle,\r
- (EFI_GUID *) ProtocolGuid,\r
- &OpenInfoBuffer,\r
- &EntryCount\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Inspect if ChildHandle is one of the agents.\r
- //\r
- Status = EFI_UNSUPPORTED;\r
- for (Index = 0; Index < EntryCount; Index++) {\r
- if ((OpenInfoBuffer[Index].ControllerHandle == ChildHandle) &&\r
- (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
- Status = EFI_SUCCESS;\r
- break;\r
- }\r
- }\r
- \r
- FreePool (OpenInfoBuffer);\r
- return Status;\r
-}\r
-\r
-/**\r
- Tests whether a language code has format of ISO639-2.\r
-\r
- @param Languages The language code to be tested.\r
-\r
- @retval TRUE Language code format is ISO 639-2.\r
- @retval FALSE Language code format is not ISO639-2.\r
-\r
-**/\r
-STATIC\r
-BOOLEAN\r
-IsIso639LanguageCode (\r
- IN CONST CHAR8 *Languages\r
- )\r
-{\r
- UINTN Index;\r
-\r
- //\r
- // Find out format of Languages\r
- //\r
- for (Index = 0; Languages[Index] != 0 && Languages[Index] != ';' && Languages[Index] != '-'; Index++);\r
- if (Languages[Index] != 0) {\r
- //\r
- // RFC4646 language code\r
- //\r
- return FALSE;\r
- }\r
-\r
- //\r
- // No ';' and '-', it's either ISO639-2 code (list) or single RFC4646 code\r
- //\r
- if (Index == 2) {\r
- //\r
- // Single RFC4646 language code without country code, e.g. "en"\r
- //\r
- return FALSE;\r
- }\r
-\r
- //\r
- // Languages in format of ISO639-2\r
- //\r
- return TRUE;\r
-}\r
-\r
-/**\r
- Compare the first language instance of two language codes, either could be a\r
- single language code or a language code list. This function assume Language1\r
- and Language2 has the same language code format, i.e. either ISO639-2 or RFC4646.\r
-\r
- @param Language1 The first language code to be tested.\r
- @param Language2 The second language code to be tested.\r
-\r
- @retval TRUE Language code match.\r
- @retval FALSE Language code mismatch.\r
-\r
-**/\r
-STATIC\r
-BOOLEAN\r
-CompareLanguageCode (\r
- IN CONST CHAR8 *Language1,\r
- IN CONST CHAR8 *Language2\r
- )\r
-{\r
- UINTN Index;\r
-\r
- //\r
- // Compare first two bytes of language tag\r
- //\r
- if ((Language1[0] != Language2[0]) || (Language1[1] != Language2[1])) {\r
- return FALSE;\r
- }\r
-\r
- if (IsIso639LanguageCode (Language1)) {\r
- //\r
- // ISO639-2 language code, compare the third byte of language tag\r
- //\r
- return (BOOLEAN) ((Language1[2] == Language2[2]) ? TRUE : FALSE);\r
- }\r
-\r
- //\r
- // RFC4646 language code\r
- //\r
- for (Index = 0; Language1[Index] != 0 && Language1[Index] != ';'; Index++);\r
- if ((AsciiStrnCmp (Language1, Language2, Index) == 0) && (Language2[Index] == 0 || Language2[Index] == ';')) {\r
- return TRUE;\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-/**\r
- Step to next language code of a language code list.\r
-\r
- @param Languages The language code list to traverse.\r
-\r
- @return Pointer to next language code or NULL terminator if it's the last one.\r
-\r
-**/\r
-STATIC\r
-CONST\r
-CHAR8 *\r
-NextSupportedLanguage (\r
- IN CONST CHAR8 *Languages\r
- )\r
-{\r
- UINTN Index;\r
-\r
- if (IsIso639LanguageCode (Languages)) {\r
- //\r
- // ISO639-2 language code\r
- //\r
- return (Languages + 3);\r
- }\r
-\r
- //\r
- // Search in RFC4646 language code list\r
- //\r
- for (Index = 0; Languages[Index] != 0 && Languages[Index] != ';'; Index++);\r
- if (Languages[Index] == ';') {\r
- Index++;\r
- }\r
- return (Languages + Index);\r
-}\r
-\r
-/**\r
- This function looks up a Unicode string in UnicodeStringTable. If Language is \r
- a member of SupportedLanguages and a Unicode string is found in UnicodeStringTable\r
- that matches the language code specified by Language, then it is returned in \r
- UnicodeString.\r
-\r
- @param Language A pointer to the ISO 639-2 language code for the \r
- Unicode string to look up and return.\r
- @param SupportedLanguages A pointer to the set of ISO 639-2 language codes \r
- that the Unicode string table supports. Language \r
- must be a member of this set.\r
- @param UnicodeStringTable A pointer to the table of Unicode strings.\r
- @param UnicodeString A pointer to the Unicode string from UnicodeStringTable\r
- that matches the language specified by Language.\r
-\r
- @retval EFI_SUCCESS The Unicode string that matches the language \r
- specified by Language was found\r
- in the table of Unicoide strings UnicodeStringTable, \r
- and it was returned in UnicodeString.\r
- @retval EFI_INVALID_PARAMETER Language is NULL.\r
- @retval EFI_INVALID_PARAMETER UnicodeString is NULL.\r
- @retval EFI_UNSUPPORTED SupportedLanguages is NULL.\r
- @retval EFI_UNSUPPORTED UnicodeStringTable is NULL.\r
- @retval EFI_UNSUPPORTED The language specified by Language is not a \r
- member of SupportedLanguages.\r
- @retval EFI_UNSUPPORTED The language specified by Language is not \r
- supported by UnicodeStringTable.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-LookupUnicodeString (\r
- IN CONST CHAR8 *Language,\r
- IN CONST CHAR8 *SupportedLanguages,\r
- IN CONST EFI_UNICODE_STRING_TABLE *UnicodeStringTable,\r
- OUT CHAR16 **UnicodeString\r
- )\r
-{\r
- //\r
- // Make sure the parameters are valid\r
- //\r
- if (Language == NULL || UnicodeString == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // If there are no supported languages, or the Unicode String Table is empty, then the\r
- // Unicode String specified by Language is not supported by this Unicode String Table\r
- //\r
- if (SupportedLanguages == NULL || UnicodeStringTable == NULL) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Make sure Language is in the set of Supported Languages\r
- //\r
- while (*SupportedLanguages != 0) {\r
- if (CompareLanguageCode (Language, SupportedLanguages)) {\r
-\r
- //\r
- // Search the Unicode String Table for the matching Language specifier\r
- //\r
- while (UnicodeStringTable->Language != NULL) {\r
- if (CompareLanguageCode (Language, UnicodeStringTable->Language)) {\r
-\r
- //\r
- // A matching string was found, so return it\r
- //\r
- *UnicodeString = UnicodeStringTable->UnicodeString;\r
- return EFI_SUCCESS;\r
- }\r
-\r
- UnicodeStringTable++;\r
- }\r
-\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- SupportedLanguages = NextSupportedLanguage (SupportedLanguages);\r
- }\r
-\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-/**\r
- This function adds a Unicode string to UnicodeStringTable.\r
- If Language is a member of SupportedLanguages then UnicodeString is added to \r
- UnicodeStringTable. New buffers are allocated for both Language and \r
- UnicodeString. The contents of Language and UnicodeString are copied into \r
- these new buffers. These buffers are automatically freed when \r
- FreeUnicodeStringTable() is called.\r
-\r
- @param Language A pointer to the ISO 639-2 language code for the Unicode \r
- string to add.\r
- @param SupportedLanguages A pointer to the set of ISO 639-2 language codes\r
- that the Unicode string table supports.\r
- Language must be a member of this set.\r
- @param UnicodeStringTable A pointer to the table of Unicode strings.\r
- @param UnicodeString A pointer to the Unicode string to add.\r
-\r
- @retval EFI_SUCCESS The Unicode string that matches the language \r
- specified by Language was found in the table of \r
- Unicode strings UnicodeStringTable, and it was \r
- returned in UnicodeString.\r
- @retval EFI_INVALID_PARAMETER Language is NULL.\r
- @retval EFI_INVALID_PARAMETER UnicodeString is NULL.\r
- @retval EFI_INVALID_PARAMETER UnicodeString is an empty string.\r
- @retval EFI_UNSUPPORTED SupportedLanguages is NULL.\r
- @retval EFI_ALREADY_STARTED A Unicode string with language Language is \r
- already present in UnicodeStringTable.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough memory to add another \r
- Unicode string to UnicodeStringTable.\r
- @retval EFI_UNSUPPORTED The language specified by Language is not a \r
- member of SupportedLanguages.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AddUnicodeString (\r
- IN CONST CHAR8 *Language,\r
- IN CONST CHAR8 *SupportedLanguages,\r
- IN EFI_UNICODE_STRING_TABLE **UnicodeStringTable,\r
- IN CONST CHAR16 *UnicodeString\r
- )\r
-{\r
- UINTN NumberOfEntries;\r
- EFI_UNICODE_STRING_TABLE *OldUnicodeStringTable;\r
- EFI_UNICODE_STRING_TABLE *NewUnicodeStringTable;\r
- UINTN UnicodeStringLength;\r
-\r
- //\r
- // Make sure the parameter are valid\r
- //\r
- if (Language == NULL || UnicodeString == NULL || UnicodeStringTable == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // If there are no supported languages, then a Unicode String can not be added\r
- //\r
- if (SupportedLanguages == NULL) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // If the Unicode String is empty, then a Unicode String can not be added\r
- //\r
- if (UnicodeString[0] == 0) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Make sure Language is a member of SupportedLanguages\r
- //\r
- while (*SupportedLanguages != 0) {\r
- if (CompareLanguageCode (Language, SupportedLanguages)) {\r
-\r
- //\r
- // Determine the size of the Unicode String Table by looking for a NULL Language entry\r
- //\r
- NumberOfEntries = 0;\r
- if (*UnicodeStringTable != NULL) {\r
- OldUnicodeStringTable = *UnicodeStringTable;\r
- while (OldUnicodeStringTable->Language != NULL) {\r
- if (CompareLanguageCode (Language, OldUnicodeStringTable->Language)) {\r
- return EFI_ALREADY_STARTED;\r
- }\r
-\r
- OldUnicodeStringTable++;\r
- NumberOfEntries++;\r
- }\r
- }\r
-\r
- //\r
- // Allocate space for a new Unicode String Table. It must hold the current number of\r
- // entries, plus 1 entry for the new Unicode String, plus 1 entry for the end of table\r
- // marker\r
- //\r
- NewUnicodeStringTable = AllocatePool ((NumberOfEntries + 2) * sizeof (EFI_UNICODE_STRING_TABLE));\r
- if (NewUnicodeStringTable == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // If the current Unicode String Table contains any entries, then copy them to the\r
- // newly allocated Unicode String Table.\r
- //\r
- if (*UnicodeStringTable != NULL) {\r
- CopyMem (\r
- NewUnicodeStringTable,\r
- *UnicodeStringTable,\r
- NumberOfEntries * sizeof (EFI_UNICODE_STRING_TABLE)\r
- );\r
- }\r
-\r
- //\r
- // Allocate space for a copy of the Language specifier\r
- //\r
- NewUnicodeStringTable[NumberOfEntries].Language = AllocateCopyPool (AsciiStrSize (Language), Language);\r
- if (NewUnicodeStringTable[NumberOfEntries].Language == NULL) {\r
- (gBS->FreePool) (NewUnicodeStringTable);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Compute the length of the Unicode String\r
- //\r
- for (UnicodeStringLength = 0; UnicodeString[UnicodeStringLength] != 0; UnicodeStringLength++)\r
- ;\r
-\r
- //\r
- // Allocate space for a copy of the Unicode String\r
- //\r
- NewUnicodeStringTable[NumberOfEntries].UnicodeString = AllocateCopyPool (\r
- (UnicodeStringLength + 1) * sizeof (CHAR16),\r
- UnicodeString\r
- );\r
- if (NewUnicodeStringTable[NumberOfEntries].UnicodeString == NULL) {\r
- (gBS->FreePool) (NewUnicodeStringTable[NumberOfEntries].Language);\r
- (gBS->FreePool) (NewUnicodeStringTable);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Mark the end of the Unicode String Table\r
- //\r
- NewUnicodeStringTable[NumberOfEntries + 1].Language = NULL;\r
- NewUnicodeStringTable[NumberOfEntries + 1].UnicodeString = NULL;\r
-\r
- //\r
- // Free the old Unicode String Table\r
- //\r
- if (*UnicodeStringTable != NULL) {\r
- (gBS->FreePool) (*UnicodeStringTable);\r
- }\r
-\r
- //\r
- // Point UnicodeStringTable at the newly allocated Unicode String Table\r
- //\r
- *UnicodeStringTable = NewUnicodeStringTable;\r
-\r
- return EFI_SUCCESS;\r
- }\r
-\r
- SupportedLanguages = NextSupportedLanguage (SupportedLanguages);\r
- }\r
-\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-/**\r
- This function frees the table of Unicode strings in UnicodeStringTable.\r
- If UnicodeStringTable is NULL, then EFI_SUCCESS is returned.\r
- Otherwise, each language code, and each Unicode string in the Unicode string \r
- table are freed, and EFI_SUCCESS is returned.\r
-\r
- @param UnicodeStringTable A pointer to the table of Unicode strings.\r
-\r
- @retval EFI_SUCCESS The Unicode string table was freed.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FreeUnicodeStringTable (\r
- IN EFI_UNICODE_STRING_TABLE *UnicodeStringTable\r
- )\r
-{\r
- UINTN Index;\r
-\r
- //\r
- // If the Unicode String Table is NULL, then it is already freed\r
- //\r
- if (UnicodeStringTable == NULL) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Loop through the Unicode String Table until we reach the end of table marker\r
- //\r
- for (Index = 0; UnicodeStringTable[Index].Language != NULL; Index++) {\r
-\r
- //\r
- // Free the Language string from the Unicode String Table\r
- //\r
- (gBS->FreePool) (UnicodeStringTable[Index].Language);\r
-\r
- //\r
- // Free the Unicode String from the Unicode String Table\r
- //\r
- if (UnicodeStringTable[Index].UnicodeString != NULL) {\r
- (gBS->FreePool) (UnicodeStringTable[Index].UnicodeString);\r
- }\r
- }\r
-\r
- //\r
- // Free the Unicode String Table itself\r
- //\r
- (gBS->FreePool) (UnicodeStringTable);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r