1 /** @file
2 Module produce UC on top of UC2.
3 
4 UEFI 2.1 specification supersedes Inte's EFI Specification 1.10.
5 UNICODE_COLLATION_PROTOCOL defined in Inte's EFI Specification 1.10 is replaced by
6 EFI_UNICODE_COLLATION_PROTOCOL in UEFI 2.1.
7 This module produces UC on top of UC2. This module is used on platform when both of
8 these two conditions are true:
9 1) EFI 1.10 module consuming UC present
10 2) And the rest of modules on the platform produce UC2
11 
12 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
13 This program and the accompanying materials
14 are licensed and made available under the terms and conditions of the BSD License
15 which accompanies this distribution.  The full text of the license may be found at
16 http://opensource.org/licenses/bsd-license.php
17 
18 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
19 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 Module Name:
21 
22 **/
23 
24 #include <PiDxe.h>
25 #include <Protocol/UnicodeCollation.h>
26 #include <Library/BaseLib.h>
27 #include <Library/DebugLib.h>
28 #include <Library/UefiBootServicesTableLib.h>
29 #include <Library/UefiDriverEntryPoint.h>
30 #include <Library/UefiLib.h>
31 #include <Library/MemoryAllocationLib.h>
32 #include <Library/HiiLib.h>
33 #include <Library/BaseMemoryLib.h>
34 #include <Library/LanguageLib.h>
35 
36 /**
37   Performs a case-insensitive comparison of two Null-terminated strings.
38 
39   @param  This Protocol instance pointer.
40   @param  Str1 A pointer to a Null-terminated string.
41   @param  Str2 A pointer to a Null-terminated string.
42 
43   @retval 0   Str1 is equivalent to Str2
44   @retval > 0 Str1 is lexically greater than Str2
45   @retval < 0 Str1 is lexically less than Str2
46 
47 **/
48 INTN
49 EFIAPI
50 StriColl (
51   IN EFI_UNICODE_COLLATION_PROTOCOL   *This,
52   IN CHAR16                           *Str1,
53   IN CHAR16                           *Str2
54   );
55 
56 /**
57   Converts all the characters in a Null-terminated string to
58   lower case characters.
59 
60   @param  This   Protocol instance pointer.
61   @param  Str    A pointer to a Null-terminated string.
62 
63 **/
64 VOID
65 EFIAPI
66 StrLwr (
67   IN EFI_UNICODE_COLLATION_PROTOCOL   *This,
68   IN OUT CHAR16                       *Str
69   );
70 
71 /**
72   Converts all the characters in a Null-terminated string to upper
73   case characters.
74 
75   @param  This   Protocol instance pointer.
76   @param  Str    A pointer to a Null-terminated string.
77 
78 **/
79 VOID
80 EFIAPI
81 StrUpr (
82   IN EFI_UNICODE_COLLATION_PROTOCOL   *This,
83   IN OUT CHAR16                       *Str
84   );
85 
86 /**
87   Performs a case-insensitive comparison of a Null-terminated
88   pattern string and a Null-terminated string.
89 
90   @param  This    Protocol instance pointer.
91   @param  String  A pointer to a Null-terminated string.
92   @param  Pattern A pointer to a Null-terminated pattern string.
93 
94   @retval TRUE    Pattern was found in String.
95   @retval FALSE   Pattern was not found in String.
96 
97 **/
98 BOOLEAN
99 EFIAPI
100 MetaiMatch (
101   IN EFI_UNICODE_COLLATION_PROTOCOL   *This,
102   IN CHAR16                           *String,
103   IN CHAR16                           *Pattern
104   );
105 
106 /**
107   Converts an 8.3 FAT file name in an OEM character set to a Null-terminated string.
108 
109   @param  This    Protocol instance pointer.
110   @param  FatSize The size of the string Fat in bytes.
111   @param  Fat     A pointer to a Null-terminated string that contains an 8.3 file
112                   name using an OEM character set.
113   @param  String  A pointer to a Null-terminated string. The string must
114                   be preallocated to hold FatSize characters.
115 
116 **/
117 VOID
118 EFIAPI
119 FatToStr (
120   IN EFI_UNICODE_COLLATION_PROTOCOL   *This,
121   IN UINTN                            FatSize,
122   IN CHAR8                            *Fat,
123   OUT CHAR16                          *String
124   );
125 
126 /**
127   Converts a Null-terminated string to legal characters in a FAT
128   filename using an OEM character set.
129 
130   @param  This    Protocol instance pointer.
131   @param  String  A pointer to a Null-terminated string. The string must
132                   be preallocated to hold FatSize characters.
133   @param  FatSize The size of the string Fat in bytes.
134   @param  Fat     A pointer to a Null-terminated string that contains an 8.3 file
135                   name using an OEM character set.
136 
137   @retval TRUE    Fat is a Long File Name
138   @retval FALSE   Fat is an 8.3 file name
139 
140 **/
141 BOOLEAN
142 EFIAPI
143 StrToFat (
144   IN EFI_UNICODE_COLLATION_PROTOCOL   *This,
145   IN CHAR16                           *String,
146   IN UINTN                            FatSize,
147   OUT CHAR8                           *Fat
148   );
149 
150 #define UC_PRIVATE_DATA_SIGNATURE  SIGNATURE_32 ('_', 'U', 'C', '_')
151 
152 typedef struct {
153   UINT32                          Signature;
154   EFI_UNICODE_COLLATION_PROTOCOL  Uc;
155   EFI_UNICODE_COLLATION_PROTOCOL *Uc2;
156 } UC_PRIVATE_DATA;
157 
158 #define UC_PRIVATE_DATA_FROM_THIS(a) CR (a, UC_PRIVATE_DATA, Uc, UC_PRIVATE_DATA_SIGNATURE)
159 
160 //
161 // Firmware Volume Protocol template
162 //
163 EFI_EVENT  mUcRegistration;
164 
165 UC_PRIVATE_DATA gUCPrivateDataTemplate = {
166   UC_PRIVATE_DATA_SIGNATURE,
167   {
168     StriColl,
169     MetaiMatch,
170     StrLwr,
171     StrUpr,
172     FatToStr,
173     StrToFat,
174     NULL
175   },
176   NULL
177 };
178 
179 //
180 // Module globals
181 //
182 /**
183   This notification function is invoked when an instance of the
184   EFI_UNICODE_COLLATION_PROTOCOL2 is produced. It installs another instance of the
185   EFI_UNICODE_COLLATION_PROTOCOL on the same handle.
186 
187   @param  Event                 The event that occured
188   @param  Context               Context of event. Not used in this nofication function.
189 
190 **/
191 VOID
192 EFIAPI
Uc2NotificationEvent(IN EFI_EVENT Event,IN VOID * Context)193 Uc2NotificationEvent (
194   IN  EFI_EVENT       Event,
195   IN  VOID            *Context
196   )
197 {
198   EFI_STATUS                     Status;
199   UINTN                          BufferSize;
200   EFI_HANDLE                     Handle;
201   UC_PRIVATE_DATA               *Private;
202   EFI_UNICODE_COLLATION_PROTOCOL *Uc2;
203 
204   while (TRUE) {
205     BufferSize = sizeof (Handle);
206     Status = gBS->LocateHandle (
207                     ByRegisterNotify,
208                     &gEfiUnicodeCollation2ProtocolGuid,
209                     mUcRegistration,
210                     &BufferSize,
211                     &Handle
212                     );
213     if (EFI_ERROR (Status)) {
214       //
215       // Exit Path of While Loop....
216       //
217       break;
218     }
219 
220     //
221     // Skip this handle if the Firmware Volume Protocol is already installed
222     //
223     Status = gBS->HandleProtocol (
224                     Handle,
225                     &gEfiUnicodeCollationProtocolGuid,
226                     (VOID **)&Uc2
227                     );
228     if (!EFI_ERROR (Status)) {
229       continue;
230     }
231 
232     //
233     // Allocate private data structure
234     //
235     Private = AllocateCopyPool (sizeof (UC_PRIVATE_DATA), &gUCPrivateDataTemplate);
236     if (Private == NULL) {
237       continue;
238     }
239 
240     //
241     // Retrieve the UC Protocol
242     //
243     Status = gBS->HandleProtocol (
244                     Handle,
245                     &gEfiUnicodeCollation2ProtocolGuid,
246                     (VOID **)&Private->Uc2
247                     );
248     ASSERT_EFI_ERROR (Status);
249 
250     //
251     // Fill in rest of private data structure
252     //
253     Private->Uc.SupportedLanguages = ConvertLanguagesRfc4646ToIso639 (Private->Uc2->SupportedLanguages);
254 
255     if (Private->Uc.SupportedLanguages != NULL) {
256 
257       //
258       // Install Firmware Volume Protocol onto same handle
259       //
260       Status = gBS->InstallMultipleProtocolInterfaces (
261                       &Handle,
262                       &gEfiUnicodeCollationProtocolGuid,
263                       &Private->Uc,
264                       NULL
265                       );
266       ASSERT_EFI_ERROR (Status);
267     }
268   }
269 }
270 
271 
272 /**
273   The user Entry Point for DXE driver. The user code starts with this function
274   as the real entry point for the image goes into a library that calls this
275   function.
276 
277   @param[in] ImageHandle    The firmware allocated handle for the EFI image.
278   @param[in] SystemTable    A pointer to the EFI System Table.
279 
280   @retval EFI_SUCCESS       The entry point is executed successfully.
281   @retval other             Some error occurs when executing this entry point.
282 
283 **/
284 EFI_STATUS
285 EFIAPI
InitializeUC(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)286 InitializeUC (
287   IN EFI_HANDLE        ImageHandle,
288   IN EFI_SYSTEM_TABLE  *SystemTable
289   )
290 {
291   EfiCreateProtocolNotifyEvent (
292     &gEfiUnicodeCollation2ProtocolGuid,
293     TPL_CALLBACK,
294     Uc2NotificationEvent,
295     NULL,
296     &mUcRegistration
297     );
298   return EFI_SUCCESS;
299 }
300 
301 
302 /**
303   Performs a case-insensitive comparison of two Null-terminated strings.
304 
305   @param  This Protocol instance pointer.
306   @param  Str1 A pointer to a Null-terminated string.
307   @param  Str2 A pointer to a Null-terminated string.
308 
309   @retval 0   Str1 is equivalent to Str2
310   @retval > 0 Str1 is lexically greater than Str2
311   @retval < 0 Str1 is lexically less than Str2
312 
313 **/
314 INTN
315 EFIAPI
StriColl(IN EFI_UNICODE_COLLATION_PROTOCOL * This,IN CHAR16 * Str1,IN CHAR16 * Str2)316 StriColl (
317   IN EFI_UNICODE_COLLATION_PROTOCOL   *This,
318   IN CHAR16                           *Str1,
319   IN CHAR16                           *Str2
320   )
321 {
322   UC_PRIVATE_DATA *Private;
323 
324   Private = UC_PRIVATE_DATA_FROM_THIS (This);
325 
326   return Private->Uc2->StriColl (Private->Uc2, Str1, Str2);
327 }
328 
329 
330 /**
331   Converts all the characters in a Null-terminated string to
332   lower case characters.
333 
334   @param  This   Protocol instance pointer.
335   @param  Str    A pointer to a Null-terminated string.
336 
337 **/
338 VOID
339 EFIAPI
StrLwr(IN EFI_UNICODE_COLLATION_PROTOCOL * This,IN OUT CHAR16 * Str)340 StrLwr (
341   IN EFI_UNICODE_COLLATION_PROTOCOL   *This,
342   IN OUT CHAR16                       *Str
343   )
344 {
345   UC_PRIVATE_DATA *Private;
346 
347   Private = UC_PRIVATE_DATA_FROM_THIS (This);
348 
349   Private->Uc2->StrLwr (Private->Uc2, Str);
350 }
351 
352 
353 /**
354   Converts all the characters in a Null-terminated string to upper
355   case characters.
356 
357   @param  This   Protocol instance pointer.
358   @param  Str    A pointer to a Null-terminated string.
359 
360 **/
361 VOID
362 EFIAPI
StrUpr(IN EFI_UNICODE_COLLATION_PROTOCOL * This,IN OUT CHAR16 * Str)363 StrUpr (
364   IN EFI_UNICODE_COLLATION_PROTOCOL   *This,
365   IN OUT CHAR16                       *Str
366   )
367 {
368   UC_PRIVATE_DATA *Private;
369 
370   Private = UC_PRIVATE_DATA_FROM_THIS (This);
371 
372   Private->Uc2->StrUpr (Private->Uc2, Str);
373 }
374 
375 /**
376   Performs a case-insensitive comparison of a Null-terminated
377   pattern string and a Null-terminated string.
378 
379   @param  This    Protocol instance pointer.
380   @param  String  A pointer to a Null-terminated string.
381   @param  Pattern A pointer to a Null-terminated pattern string.
382 
383   @retval TRUE    Pattern was found in String.
384   @retval FALSE   Pattern was not found in String.
385 
386 **/
387 BOOLEAN
388 EFIAPI
MetaiMatch(IN EFI_UNICODE_COLLATION_PROTOCOL * This,IN CHAR16 * String,IN CHAR16 * Pattern)389 MetaiMatch (
390   IN EFI_UNICODE_COLLATION_PROTOCOL   *This,
391   IN CHAR16                           *String,
392   IN CHAR16                           *Pattern
393   )
394 {
395   UC_PRIVATE_DATA *Private;
396 
397   Private = UC_PRIVATE_DATA_FROM_THIS (This);
398 
399   return Private->Uc2->MetaiMatch (Private->Uc2, String, Pattern);
400 }
401 
402 
403 /**
404   Converts an 8.3 FAT file name in an OEM character set to a Null-terminated string.
405 
406   @param  This    Protocol instance pointer.
407   @param  FatSize The size of the string Fat in bytes.
408   @param  Fat     A pointer to a Null-terminated string that contains an 8.3 file
409                   name using an 8-bit OEM character set.
410   @param  String  A pointer to a Null-terminated string. The string must
411                   be preallocated to hold FatSize characters.
412 
413 **/
414 VOID
415 EFIAPI
FatToStr(IN EFI_UNICODE_COLLATION_PROTOCOL * This,IN UINTN FatSize,IN CHAR8 * Fat,OUT CHAR16 * String)416 FatToStr (
417   IN EFI_UNICODE_COLLATION_PROTOCOL   *This,
418   IN UINTN                            FatSize,
419   IN CHAR8                            *Fat,
420   OUT CHAR16                          *String
421   )
422 {
423   UC_PRIVATE_DATA *Private;
424 
425   Private = UC_PRIVATE_DATA_FROM_THIS (This);
426 
427   Private->Uc2->FatToStr (Private->Uc2, FatSize, Fat, String);
428 }
429 
430 
431 /**
432   Converts a Null-terminated string to legal characters in a FAT
433   filename using an OEM character set.
434 
435   @param  This    Protocol instance pointer.
436   @param  String  A pointer to a Null-terminated string. The string must
437                   be preallocated to hold FatSize characters.
438   @param  FatSize The size of the string Fat in bytes.
439   @param  Fat     A pointer to a Null-terminated string that contains an 8.3 file
440                   name using an OEM character set.
441 
442   @retval TRUE    Fat is a Long File Name
443   @retval FALSE   Fat is an 8.3 file name
444 
445 **/
446 BOOLEAN
447 EFIAPI
StrToFat(IN EFI_UNICODE_COLLATION_PROTOCOL * This,IN CHAR16 * String,IN UINTN FatSize,OUT CHAR8 * Fat)448 StrToFat (
449   IN EFI_UNICODE_COLLATION_PROTOCOL   *This,
450   IN CHAR16                           *String,
451   IN UINTN                            FatSize,
452   OUT CHAR8                           *Fat
453   )
454 {
455   UC_PRIVATE_DATA *Private;
456 
457   Private = UC_PRIVATE_DATA_FROM_THIS (This);
458 
459   return Private->Uc2->StrToFat (Private->Uc2, String, FatSize, Fat);
460 }
461 
462