mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-12-01 12:53:27 +01:00
196 lines
5.8 KiB
C
196 lines
5.8 KiB
C
/** @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);
|
|
}
|