123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- /** @file
- Unicode collation routines
- Copyright (c) 2021 - 2023 Pedro Falcato All rights reserved.
- Copyright (c) 2005 - 2017, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <Uefi.h>
- #include <Library/DebugLib.h>
- #include <Library/UefiLib.h>
- #include <Library/UefiBootServicesTableLib.h>
- #include <Library/MemoryAllocationLib.h>
- #include <Protocol/UnicodeCollation.h>
- STATIC EFI_UNICODE_COLLATION_PROTOCOL *gUnicodeCollationInterface = NULL;
- /*
- * Note: This code is heavily based on FatPkg's Unicode collation, since they seem to know what
- * they're doing.
- * PS: Maybe all this code could be put in a library? It looks heavily shareable.
- **/
- /**
- Check if unicode collation is initialized
- @retval TRUE if Ext4InitialiseUnicodeCollation() was already called successfully
- @retval FALSE if Ext4InitialiseUnicodeCollation() was not yet called successfully
- **/
- STATIC
- BOOLEAN
- Ext4IsCollationInitialized (
- VOID
- )
- {
- return gUnicodeCollationInterface != NULL;
- }
- /**
- Worker function to initialize Unicode Collation support.
- It tries to locate Unicode Collation (2) protocol and matches it with current
- platform language code.
- @param[in] DriverHandle The handle used to open Unicode Collation (2) protocol.
- @param[in] ProtocolGuid The pointer to Unicode Collation (2) protocol GUID.
- @param[in] VariableName The name of the RFC 4646 or ISO 639-2 language variable.
- @param[in] DefaultLanguage The default language in case the RFC 4646 or ISO 639-2 language is absent.
- @retval EFI_SUCCESS The Unicode Collation (2) protocol has been successfully located.
- @retval Others The Unicode Collation (2) protocol has not been located.
- **/
- STATIC
- EFI_STATUS
- Ext4InitialiseUnicodeCollationInternal (
- IN EFI_HANDLE DriverHandle,
- IN EFI_GUID *ProtocolGuid,
- IN CONST CHAR16 *VariableName,
- IN CONST CHAR8 *DefaultLanguage
- )
- {
- UINTN NumHandles;
- EFI_HANDLE *Handles;
- EFI_UNICODE_COLLATION_PROTOCOL *Uci;
- BOOLEAN Iso639Language;
- CHAR8 *Language;
- EFI_STATUS RetStatus;
- EFI_STATUS Status;
- UINTN Idx;
- CHAR8 *BestLanguage;
- Iso639Language = (BOOLEAN)(ProtocolGuid == &gEfiUnicodeCollationProtocolGuid);
- RetStatus = EFI_UNSUPPORTED;
- GetEfiGlobalVariable2 (VariableName, (VOID **)&Language, NULL);
- Status = gBS->LocateHandleBuffer (
- ByProtocol,
- ProtocolGuid,
- NULL,
- &NumHandles,
- &Handles
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- for (Idx = 0; Idx < NumHandles; Idx++) {
- Status = gBS->OpenProtocol (
- Handles[Idx],
- ProtocolGuid,
- (VOID **)&Uci,
- DriverHandle,
- NULL,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- continue;
- }
- BestLanguage = GetBestLanguage (
- Uci->SupportedLanguages,
- Iso639Language,
- (Language == NULL) ? "" : Language,
- DefaultLanguage,
- NULL
- );
- if (BestLanguage != NULL) {
- FreePool (BestLanguage);
- gUnicodeCollationInterface = Uci;
- RetStatus = EFI_SUCCESS;
- break;
- }
- }
- if (Language != NULL) {
- FreePool (Language);
- }
- FreePool (Handles);
- return RetStatus;
- }
- /**
- Initialises Unicode collation, which is needed for case-insensitive string comparisons
- within the driver (a good example of an application of this is filename comparison).
- @param[in] DriverHandle Handle to the driver image.
- @retval EFI_SUCCESS Unicode collation was successfully initialised.
- @retval !EFI_SUCCESS Failure.
- **/
- EFI_STATUS
- Ext4InitialiseUnicodeCollation (
- EFI_HANDLE DriverHandle
- )
- {
- EFI_STATUS Status;
- Status = EFI_UNSUPPORTED;
- // If already done, just return success.
- if (Ext4IsCollationInitialized ()) {
- return EFI_SUCCESS;
- }
- //
- // First try to use RFC 4646 Unicode Collation 2 Protocol.
- //
- Status = Ext4InitialiseUnicodeCollationInternal (
- DriverHandle,
- &gEfiUnicodeCollation2ProtocolGuid,
- L"PlatformLang",
- (CONST CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLang)
- );
- //
- // If the attempt to use Unicode Collation 2 Protocol fails, then we fall back
- // on the ISO 639-2 Unicode Collation Protocol.
- //
- if (EFI_ERROR (Status)) {
- Status = Ext4InitialiseUnicodeCollationInternal (
- DriverHandle,
- &gEfiUnicodeCollationProtocolGuid,
- L"Lang",
- (CONST CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultLang)
- );
- }
- return Status;
- }
- /**
- Does a case-insensitive string comparison. Refer to EFI_UNICODE_COLLATION_PROTOCOL's StriColl
- for more details.
- @param[in] Str1 Pointer to a null terminated string.
- @param[in] Str2 Pointer to a null terminated string.
- @retval 0 Str1 is equivalent to Str2.
- @retval >0 Str1 is lexically greater than Str2.
- @retval <0 Str1 is lexically less than Str2.
- **/
- INTN
- Ext4StrCmpInsensitive (
- IN CHAR16 *Str1,
- IN CHAR16 *Str2
- )
- {
- ASSERT (gUnicodeCollationInterface != NULL);
- return gUnicodeCollationInterface->StriColl (gUnicodeCollationInterface, Str1, Str2);
- }
|