1 /** @file 2 Unicode Collation Support component that hides the trivial difference of Unicode Collation 3 and Unicode collation 2 Protocol. 4 5 Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR> 6 This program and the accompanying materials are licensed and made available 7 under the terms and conditions of the BSD License which accompanies this 8 distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 #include "Fat.h" 17 18 EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollationInterface = NULL; 19 20 /** 21 Worker function to initialize Unicode Collation support. 22 23 It tries to locate Unicode Collation (2) protocol and matches it with current 24 platform language code. 25 26 @param AgentHandle The handle used to open Unicode Collation (2) protocol. 27 @param ProtocolGuid The pointer to Unicode Collation (2) protocol GUID. 28 @param VariableName The name of the RFC 4646 or ISO 639-2 language variable. 29 @param DefaultLanguage The default language in case the RFC 4646 or ISO 639-2 language is absent. 30 31 @retval EFI_SUCCESS The Unicode Collation (2) protocol has been successfully located. 32 @retval Others The Unicode Collation (2) protocol has not been located. 33 34 **/ 35 EFI_STATUS 36 InitializeUnicodeCollationSupportWorker ( 37 IN EFI_HANDLE AgentHandle, 38 IN EFI_GUID *ProtocolGuid, 39 IN CONST CHAR16 *VariableName, 40 IN CONST CHAR8 *DefaultLanguage 41 ) 42 { 43 EFI_STATUS ReturnStatus; 44 EFI_STATUS Status; 45 UINTN NumHandles; 46 UINTN Index; 47 EFI_HANDLE *Handles; 48 EFI_UNICODE_COLLATION_PROTOCOL *Uci; 49 BOOLEAN Iso639Language; 50 CHAR8 *Language; 51 CHAR8 *BestLanguage; 52 53 Status = gBS->LocateHandleBuffer ( 54 ByProtocol, 55 ProtocolGuid, 56 NULL, 57 &NumHandles, 58 &Handles 59 ); 60 if (EFI_ERROR (Status)) { 61 return Status; 62 } 63 64 Iso639Language = (BOOLEAN) (ProtocolGuid == &gEfiUnicodeCollationProtocolGuid); 65 GetEfiGlobalVariable2 (VariableName, (VOID**) &Language, NULL); 66 67 ReturnStatus = EFI_UNSUPPORTED; 68 for (Index = 0; Index < NumHandles; Index++) { 69 // 70 // Open Unicode Collation Protocol 71 // 72 Status = gBS->OpenProtocol ( 73 Handles[Index], 74 ProtocolGuid, 75 (VOID **) &Uci, 76 AgentHandle, 77 NULL, 78 EFI_OPEN_PROTOCOL_GET_PROTOCOL 79 ); 80 if (EFI_ERROR (Status)) { 81 continue; 82 } 83 84 // 85 // Find the best matching matching language from the supported languages 86 // of Unicode Collation (2) protocol. 87 // 88 BestLanguage = GetBestLanguage ( 89 Uci->SupportedLanguages, 90 Iso639Language, 91 (Language == NULL) ? "" : Language, 92 DefaultLanguage, 93 NULL 94 ); 95 if (BestLanguage != NULL) { 96 FreePool (BestLanguage); 97 mUnicodeCollationInterface = Uci; 98 ReturnStatus = EFI_SUCCESS; 99 break; 100 } 101 } 102 103 if (Language != NULL) { 104 FreePool (Language); 105 } 106 107 FreePool (Handles); 108 109 return ReturnStatus; 110 } 111 112 /** 113 Initialize Unicode Collation support. 114 115 It tries to locate Unicode Collation 2 protocol and matches it with current 116 platform language code. If for any reason the first attempt fails, it then tries to 117 use Unicode Collation Protocol. 118 119 @param AgentHandle The handle used to open Unicode Collation (2) protocol. 120 121 @retval EFI_SUCCESS The Unicode Collation (2) protocol has been successfully located. 122 @retval Others The Unicode Collation (2) protocol has not been located. 123 124 **/ 125 EFI_STATUS 126 InitializeUnicodeCollationSupport ( 127 IN EFI_HANDLE AgentHandle 128 ) 129 { 130 131 EFI_STATUS Status; 132 133 Status = EFI_UNSUPPORTED; 134 135 // 136 // First try to use RFC 4646 Unicode Collation 2 Protocol. 137 // 138 Status = InitializeUnicodeCollationSupportWorker ( 139 AgentHandle, 140 &gEfiUnicodeCollation2ProtocolGuid, 141 L"PlatformLang", 142 (CONST CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang) 143 ); 144 // 145 // If the attempt to use Unicode Collation 2 Protocol fails, then we fall back 146 // on the ISO 639-2 Unicode Collation Protocol. 147 // 148 if (EFI_ERROR (Status)) { 149 Status = InitializeUnicodeCollationSupportWorker ( 150 AgentHandle, 151 &gEfiUnicodeCollationProtocolGuid, 152 L"Lang", 153 (CONST CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultLang) 154 ); 155 } 156 157 return Status; 158 } 159 160 161 /** 162 Performs a case-insensitive comparison of two Null-terminated Unicode strings. 163 164 @param S1 A pointer to a Null-terminated Unicode string. 165 @param S2 A pointer to a Null-terminated Unicode string. 166 167 @retval 0 S1 is equivalent to S2. 168 @retval >0 S1 is lexically greater than S2. 169 @retval <0 S1 is lexically less than S2. 170 **/ 171 INTN 172 FatStriCmp ( 173 IN CHAR16 *S1, 174 IN CHAR16 *S2 175 ) 176 { 177 ASSERT (StrSize (S1) != 0); 178 ASSERT (StrSize (S2) != 0); 179 ASSERT (mUnicodeCollationInterface != NULL); 180 181 return mUnicodeCollationInterface->StriColl ( 182 mUnicodeCollationInterface, 183 S1, 184 S2 185 ); 186 } 187 188 189 /** 190 Uppercase a string. 191 192 @param String The string which will be upper-cased. 193 194 195 **/ 196 VOID 197 FatStrUpr ( 198 IN OUT CHAR16 *String 199 ) 200 { 201 ASSERT (StrSize (String) != 0); 202 ASSERT (mUnicodeCollationInterface != NULL); 203 204 mUnicodeCollationInterface->StrUpr (mUnicodeCollationInterface, String); 205 } 206 207 208 /** 209 Lowercase a string 210 211 @param String The string which will be lower-cased. 212 213 214 **/ 215 VOID 216 FatStrLwr ( 217 IN OUT CHAR16 *String 218 ) 219 { 220 ASSERT (StrSize (String) != 0); 221 ASSERT (mUnicodeCollationInterface != NULL); 222 223 mUnicodeCollationInterface->StrLwr (mUnicodeCollationInterface, String); 224 } 225 226 227 /** 228 Convert FAT string to unicode string. 229 230 @param FatSize The size of FAT string. 231 @param Fat The FAT string. 232 @param String The unicode string. 233 234 @return None. 235 236 **/ 237 VOID 238 FatFatToStr ( 239 IN UINTN FatSize, 240 IN CHAR8 *Fat, 241 OUT CHAR16 *String 242 ) 243 { 244 ASSERT (Fat != NULL); 245 ASSERT (String != NULL); 246 ASSERT (((UINTN) String & 0x01) == 0); 247 ASSERT (mUnicodeCollationInterface != NULL); 248 249 mUnicodeCollationInterface->FatToStr (mUnicodeCollationInterface, FatSize, Fat, String); 250 } 251 252 253 /** 254 Convert unicode string to Fat string. 255 256 @param String The unicode string. 257 @param FatSize The size of the FAT string. 258 @param Fat The FAT string. 259 260 @retval TRUE Convert successfully. 261 @retval FALSE Convert error. 262 263 **/ 264 BOOLEAN 265 FatStrToFat ( 266 IN CHAR16 *String, 267 IN UINTN FatSize, 268 OUT CHAR8 *Fat 269 ) 270 { 271 ASSERT (Fat != NULL); 272 ASSERT (StrSize (String) != 0); 273 ASSERT (mUnicodeCollationInterface != NULL); 274 275 return mUnicodeCollationInterface->StrToFat ( 276 mUnicodeCollationInterface, 277 String, 278 FatSize, 279 Fat 280 ); 281 } 282