+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES\r
+\r
+/**\r
+ [ATTENTION] This function will be deprecated for security reason.\r
+\r
+ Returns a pointer to an allocated buffer that contains the contents of a \r
+ variable retrieved through the UEFI Runtime Service GetVariable(). The \r
+ returned buffer is allocated using AllocatePool(). The caller is responsible\r
+ for freeing this buffer with FreePool().\r
+\r
+ If Name is NULL, then ASSERT().\r
+ If Guid is NULL, then ASSERT().\r
+\r
+ @param[in] Name The pointer to a Null-terminated Unicode string.\r
+ @param[in] Guid The pointer to an EFI_GUID structure\r
+\r
+ @retval NULL The variable could not be retrieved.\r
+ @retval NULL There are not enough resources available for the variable contents.\r
+ @retval Other A pointer to allocated buffer containing the variable contents.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetVariable (\r
+ IN CONST CHAR16 *Name,\r
+ IN CONST EFI_GUID *Guid\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Size;\r
+ VOID *Value;\r
+\r
+ ASSERT (Name != NULL);\r
+ ASSERT (Guid != NULL);\r
+\r
+ //\r
+ // Try to get the variable size.\r
+ //\r
+ Value = NULL;\r
+ Size = 0;\r
+ Status = gRT->GetVariable ((CHAR16 *) Name, (EFI_GUID *) Guid, NULL, &Size, Value);\r
+ if (Status != EFI_BUFFER_TOO_SMALL) {\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Allocate buffer to get the variable.\r
+ //\r
+ Value = AllocatePool (Size);\r
+ if (Value == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Get the variable data.\r
+ //\r
+ Status = gRT->GetVariable ((CHAR16 *) Name, (EFI_GUID *) Guid, NULL, &Size, Value);\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool(Value);\r
+ return NULL;\r
+ }\r
+\r
+ return Value;\r
+}\r
+\r
+/**\r
+ [ATTENTION] This function will be deprecated for security reason.\r
+\r
+ Returns a pointer to an allocated buffer that contains the contents of a \r
+ variable retrieved through the UEFI Runtime Service GetVariable(). This \r
+ function always uses the EFI_GLOBAL_VARIABLE GUID to retrieve variables.\r
+ The returned buffer is allocated using AllocatePool(). The caller is \r
+ responsible for freeing this buffer with FreePool().\r
+\r
+ If Name is NULL, then ASSERT().\r
+\r
+ @param[in] Name The pointer to a Null-terminated Unicode string.\r
+\r
+ @retval NULL The variable could not be retrieved.\r
+ @retval NULL There are not enough resources available for the variable contents.\r
+ @retval Other A pointer to allocated buffer containing the variable contents.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetEfiGlobalVariable (\r
+ IN CONST CHAR16 *Name\r
+ )\r
+{\r
+ return GetVariable (Name, &gEfiGlobalVariableGuid);\r
+}\r
+#endif\r
+\r
+/**\r
+ Returns the status whether get the variable success. The function retrieves \r
+ variable through the UEFI Runtime Service GetVariable(). The \r
+ returned buffer is allocated using AllocatePool(). The caller is responsible\r
+ for freeing this buffer with FreePool().\r
+\r
+ If Name is NULL, then ASSERT().\r
+ If Guid is NULL, then ASSERT().\r
+ If Value is NULL, then ASSERT().\r
+\r
+ @param[in] Name The pointer to a Null-terminated Unicode string.\r
+ @param[in] Guid The pointer to an EFI_GUID structure\r
+ @param[out] Value The buffer point saved the variable info.\r
+ @param[out] Size The buffer size of the variable.\r
+\r
+ @return EFI_OUT_OF_RESOURCES Allocate buffer failed.\r
+ @return EFI_SUCCESS Find the specified variable.\r
+ @return Others Errors Return errors from call to gRT->GetVariable.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetVariable2 (\r
+ IN CONST CHAR16 *Name,\r
+ IN CONST EFI_GUID *Guid,\r
+ OUT VOID **Value,\r
+ OUT UINTN *Size OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN BufferSize;\r
+\r
+ ASSERT (Name != NULL && Guid != NULL && Value != NULL);\r
+\r
+ //\r
+ // Try to get the variable size.\r
+ //\r
+ BufferSize = 0;\r
+ *Value = NULL;\r
+ if (Size != NULL) {\r
+ *Size = 0;\r
+ }\r
+ \r
+ Status = gRT->GetVariable ((CHAR16 *) Name, (EFI_GUID *) Guid, NULL, &BufferSize, *Value);\r
+ if (Status != EFI_BUFFER_TOO_SMALL) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Allocate buffer to get the variable.\r
+ //\r
+ *Value = AllocatePool (BufferSize);\r
+ ASSERT (*Value != NULL);\r
+ if (*Value == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Get the variable data.\r
+ //\r
+ Status = gRT->GetVariable ((CHAR16 *) Name, (EFI_GUID *) Guid, NULL, &BufferSize, *Value);\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool(*Value);\r
+ *Value = NULL;\r
+ }\r
+\r
+ if (Size != NULL) {\r
+ *Size = BufferSize;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Returns a pointer to an allocated buffer that contains the contents of a \r
+ variable retrieved through the UEFI Runtime Service GetVariable(). This \r
+ function always uses the EFI_GLOBAL_VARIABLE GUID to retrieve variables.\r
+ The returned buffer is allocated using AllocatePool(). The caller is \r
+ responsible for freeing this buffer with FreePool().\r
+\r
+ If Name is NULL, then ASSERT().\r
+ If Value is NULL, then ASSERT().\r
+\r
+ @param[in] Name The pointer to a Null-terminated Unicode string.\r
+ @param[out] Value The buffer point saved the variable info.\r
+ @param[out] Size The buffer size of the variable.\r
+\r
+ @return EFI_OUT_OF_RESOURCES Allocate buffer failed.\r
+ @return EFI_SUCCESS Find the specified variable.\r
+ @return Others Errors Return errors from call to gRT->GetVariable.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetEfiGlobalVariable2 (\r
+ IN CONST CHAR16 *Name,\r
+ OUT VOID **Value,\r
+ OUT UINTN *Size OPTIONAL\r
+ )\r
+{\r
+ return GetVariable2 (Name, &gEfiGlobalVariableGuid, Value, Size);\r
+}\r
+\r
+/**\r
+ Returns a pointer to an allocated buffer that contains the best matching language \r
+ from a set of supported languages. \r
+ \r
+ This function supports both ISO 639-2 and RFC 4646 language codes, but language \r
+ code types may not be mixed in a single call to this function. The language \r
+ code returned is allocated using AllocatePool(). The caller is responsible for \r
+ freeing the allocated buffer using FreePool(). This function supports a variable\r
+ argument list that allows the caller to pass in a prioritized list of language \r
+ codes to test against all the language codes in SupportedLanguages. \r
+\r
+ If SupportedLanguages is NULL, then ASSERT().\r
+\r
+ @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that\r
+ contains a set of language codes in the format \r
+ specified by Iso639Language.\r
+ @param[in] Iso639Language If TRUE, then all language codes are assumed to be\r
+ in ISO 639-2 format. If FALSE, then all language\r
+ codes are assumed to be in RFC 4646 language format\r
+ @param[in] ... A variable argument list that contains pointers to \r
+ Null-terminated ASCII strings that contain one or more\r
+ language codes in the format specified by Iso639Language.\r
+ The first language code from each of these language\r
+ code lists is used to determine if it is an exact or\r
+ close match to any of the language codes in \r
+ SupportedLanguages. Close matches only apply to RFC 4646\r
+ language codes, and the matching algorithm from RFC 4647\r
+ is used to determine if a close match is present. If \r
+ an exact or close match is found, then the matching\r
+ language code from SupportedLanguages is returned. If\r
+ no matches are found, then the next variable argument\r
+ parameter is evaluated. The variable argument list \r
+ is terminated by a NULL.\r
+\r
+ @retval NULL The best matching language could not be found in SupportedLanguages.\r
+ @retval NULL There are not enough resources available to return the best matching \r
+ language.\r
+ @retval Other A pointer to a Null-terminated ASCII string that is the best matching \r
+ language in SupportedLanguages.\r
+\r
+**/\r
+CHAR8 *\r
+EFIAPI\r
+GetBestLanguage (\r
+ IN CONST CHAR8 *SupportedLanguages, \r
+ IN BOOLEAN Iso639Language,\r
+ ...\r
+ )\r
+{\r
+ VA_LIST Args;\r
+ CHAR8 *Language;\r
+ UINTN CompareLength;\r
+ UINTN LanguageLength;\r
+ CONST CHAR8 *Supported;\r
+ CHAR8 *BestLanguage;\r
+\r
+ ASSERT (SupportedLanguages != NULL);\r
+\r
+ VA_START (Args, Iso639Language);\r
+ while ((Language = VA_ARG (Args, CHAR8 *)) != NULL) {\r
+ //\r
+ // Default to ISO 639-2 mode\r
+ //\r
+ CompareLength = 3;\r
+ LanguageLength = MIN (3, AsciiStrLen (Language));\r
+\r
+ //\r
+ // If in RFC 4646 mode, then determine the length of the first RFC 4646 language code in Language\r
+ //\r
+ if (!Iso639Language) {\r
+ for (LanguageLength = 0; Language[LanguageLength] != 0 && Language[LanguageLength] != ';'; LanguageLength++);\r
+ }\r
+\r
+ //\r
+ // Trim back the length of Language used until it is empty\r
+ //\r
+ while (LanguageLength > 0) {\r
+ //\r
+ // Loop through all language codes in SupportedLanguages\r
+ //\r
+ for (Supported = SupportedLanguages; *Supported != '\0'; Supported += CompareLength) {\r
+ //\r
+ // In RFC 4646 mode, then Loop through all language codes in SupportedLanguages\r
+ //\r
+ if (!Iso639Language) {\r
+ //\r
+ // Skip ';' characters in Supported\r
+ //\r
+ for (; *Supported != '\0' && *Supported == ';'; Supported++);\r
+ //\r
+ // Determine the length of the next language code in Supported\r
+ //\r
+ for (CompareLength = 0; Supported[CompareLength] != 0 && Supported[CompareLength] != ';'; CompareLength++);\r
+ //\r
+ // If Language is longer than the Supported, then skip to the next language\r
+ //\r
+ if (LanguageLength > CompareLength) {\r
+ continue;\r
+ }\r
+ }\r
+ //\r
+ // See if the first LanguageLength characters in Supported match Language\r
+ //\r
+ if (AsciiStrnCmp (Supported, Language, LanguageLength) == 0) {\r
+ VA_END (Args);\r
+ //\r
+ // Allocate, copy, and return the best matching language code from SupportedLanguages\r
+ //\r
+ BestLanguage = AllocateZeroPool (CompareLength + 1);\r
+ if (BestLanguage == NULL) {\r
+ return NULL;\r
+ }\r
+ return CopyMem (BestLanguage, Supported, CompareLength);\r
+ }\r
+ }\r
+\r
+ if (Iso639Language) {\r
+ //\r
+ // If ISO 639 mode, then each language can only be tested once\r
+ //\r
+ LanguageLength = 0;\r
+ } else {\r
+ //\r
+ // If RFC 4646 mode, then trim Language from the right to the next '-' character \r
+ //\r
+ for (LanguageLength--; LanguageLength > 0 && Language[LanguageLength] != '-'; LanguageLength--);\r
+ }\r
+ }\r
+ }\r
+ VA_END (Args);\r
+\r
+ //\r
+ // No matches were found \r
+ //\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ Returns an array of protocol instance that matches the given protocol.\r
+\r
+ @param[in] Protocol Provides the protocol to search for.\r
+ @param[out] NoProtocols The number of protocols returned in Buffer.\r
+ @param[out] Buffer A pointer to the buffer to return the requested\r
+ array of protocol instances that match Protocol.\r
+ The returned buffer is allocated using\r
+ EFI_BOOT_SERVICES.AllocatePool(). The caller is\r
+ responsible for freeing this buffer with\r
+ EFI_BOOT_SERVICES.FreePool().\r
+\r
+ @retval EFI_SUCCESS The array of protocols was returned in Buffer,\r
+ and the number of protocols in Buffer was\r
+ returned in NoProtocols.\r
+ @retval EFI_NOT_FOUND No protocols found.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the\r
+ matching results.\r
+ @retval EFI_INVALID_PARAMETER Protocol is NULL.\r
+ @retval EFI_INVALID_PARAMETER NoProtocols is NULL.\r
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EfiLocateProtocolBuffer (\r
+ IN EFI_GUID *Protocol,\r
+ OUT UINTN *NoProtocols,\r
+ OUT VOID ***Buffer\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN NoHandles;\r
+ EFI_HANDLE *HandleBuffer;\r
+ UINTN Index;\r
+\r
+ //\r
+ // Check input parameters\r
+ //\r
+ if (Protocol == NULL || NoProtocols == NULL || Buffer == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Initialze output parameters\r
+ //\r
+ *NoProtocols = 0;\r
+ *Buffer = NULL;\r
+\r
+ //\r
+ // Retrieve the array of handles that support Protocol\r
+ //\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ Protocol,\r
+ NULL,\r
+ &NoHandles,\r
+ &HandleBuffer\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Allocate array of protocol instances\r
+ //\r
+ Status = gBS->AllocatePool (\r
+ EfiBootServicesData,\r
+ NoHandles * sizeof (VOID *),\r
+ (VOID **)Buffer\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ ZeroMem (*Buffer, NoHandles * sizeof (VOID *));\r
+\r
+ //\r
+ // Lookup Protocol on each handle in HandleBuffer to fill in the array of\r
+ // protocol instances. Handle case where protocol instance was present when\r
+ // LocateHandleBuffer() was called, but is not present when HandleProtocol()\r
+ // is called.\r
+ //\r
+ for (Index = 0, *NoProtocols = 0; Index < NoHandles; Index++) {\r
+ Status = gBS->HandleProtocol (\r
+ HandleBuffer[Index],\r
+ Protocol,\r
+ &((*Buffer)[*NoProtocols])\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ (*NoProtocols)++;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Free the handle buffer\r
+ //\r
+ gBS->FreePool (HandleBuffer);\r
+\r
+ //\r
+ // Make sure at least one protocol instance was found\r
+ //\r
+ if (*NoProtocols == 0) {\r
+ gBS->FreePool (*Buffer);\r
+ *Buffer = NULL;\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r