1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
/** @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;
CHAR8 *Language;
EFI_STATUS RetStatus;
EFI_STATUS Status;
UINTN Idx;
CHAR8 *BestLanguage;
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,
FALSE,
(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;
}
//
// Use RFC 4646 Unicode Collation 2 Protocol.
//
Status = Ext4InitialiseUnicodeCollationInternal (
DriverHandle,
&gEfiUnicodeCollation2ProtocolGuid,
L"PlatformLang",
(CONST CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLang)
);
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);
}
|