TianoCore EDK2 master
Loading...
Searching...
No Matches
UefiLib.c
Go to the documentation of this file.
1
13#include "UefiLibInternal.h"
14
28EFIAPI
30 IN EFI_HANDLE ImageHandle,
31 IN EFI_SYSTEM_TABLE *SystemTable
32 )
33{
34 return EFI_SUCCESS;
35}
36
47BOOLEAN
49 IN CONST CHAR8 *Language1,
50 IN CONST CHAR8 *Language2
51 )
52{
53 UINT32 Name1;
54 UINT32 Name2;
55
56 Name1 = ReadUnaligned24 ((CONST UINT32 *)Language1);
57 Name2 = ReadUnaligned24 ((CONST UINT32 *)Language2);
58
59 return (BOOLEAN)(Name1 == Name2);
60}
61
81EFIAPI
83 IN EFI_GUID *TableGuid,
84 OUT VOID **Table
85 )
86{
87 EFI_SYSTEM_TABLE *SystemTable;
88 UINTN Index;
89
90 ASSERT (TableGuid != NULL);
91 ASSERT (Table != NULL);
92
93 SystemTable = gST;
94 *Table = NULL;
95 for (Index = 0; Index < SystemTable->NumberOfTableEntries; Index++) {
96 if (CompareGuid (TableGuid, &(SystemTable->ConfigurationTable[Index].VendorGuid))) {
97 *Table = SystemTable->ConfigurationTable[Index].VendorTable;
98 return EFI_SUCCESS;
99 }
100 }
101
102 return EFI_NOT_FOUND;
103}
104
133EFIAPI
135 IN EFI_GUID *ProtocolGuid,
136 IN EFI_TPL NotifyTpl,
138 IN VOID *NotifyContext OPTIONAL,
139 OUT VOID **Registration
140 )
141{
142 EFI_STATUS Status;
143 EFI_EVENT Event;
144
145 ASSERT (ProtocolGuid != NULL);
146 ASSERT (NotifyFunction != NULL);
147 ASSERT (Registration != NULL);
148
149 //
150 // Create the event
151 //
152
153 Status = gBS->CreateEvent (
154 EVT_NOTIFY_SIGNAL,
155 NotifyTpl,
157 NotifyContext,
158 &Event
159 );
160 ASSERT_EFI_ERROR (Status);
161
162 //
163 // Register for protocol notifications on this event
164 //
165
166 Status = gBS->RegisterProtocolNotify (
167 ProtocolGuid,
168 Event,
169 Registration
170 );
171
172 ASSERT_EFI_ERROR (Status);
173
174 //
175 // Kick the event so we will perform an initial pass of
176 // current installed drivers
177 //
178
179 gBS->SignalEvent (Event);
180 return Event;
181}
182
204EFIAPI
206 IN CONST EFI_GUID *Name,
207 IN EFI_TPL NotifyTpl,
209 IN CONST VOID *NotifyContext OPTIONAL,
210 OUT VOID *Registration OPTIONAL
211 )
212{
213 EFI_STATUS Status;
214 EFI_EVENT Event;
215 VOID *RegistrationLocal;
216
217 ASSERT (Name != NULL);
218 ASSERT (NotifyFunction != NULL);
219 ASSERT (NotifyTpl <= TPL_HIGH_LEVEL);
220
221 //
222 // Create event
223 //
224 Status = gBS->CreateEvent (
225 EVT_NOTIFY_SIGNAL,
226 NotifyTpl,
228 (VOID *)NotifyContext,
229 &Event
230 );
231 ASSERT_EFI_ERROR (Status);
232
233 //
234 // The Registration is not optional to RegisterProtocolNotify().
235 // To make it optional to EfiNamedEventListen(), may need to substitute with a local.
236 //
237 if (Registration != NULL) {
238 RegistrationLocal = Registration;
239 } else {
240 RegistrationLocal = &RegistrationLocal;
241 }
242
243 //
244 // Register for an installation of protocol interface
245 //
246
247 Status = gBS->RegisterProtocolNotify (
248 (EFI_GUID *)Name,
249 Event,
250 RegistrationLocal
251 );
252 ASSERT_EFI_ERROR (Status);
253
254 return Status;
255}
256
271EFIAPI
273 IN CONST EFI_GUID *Name
274 )
275{
276 EFI_STATUS Status;
277 EFI_HANDLE Handle;
278
279 ASSERT (Name != NULL);
280
281 Handle = NULL;
282 Status = gBS->InstallProtocolInterface (
283 &Handle,
284 (EFI_GUID *)Name,
286 NULL
287 );
288 ASSERT_EFI_ERROR (Status);
289
290 Status = gBS->UninstallProtocolInterface (
291 Handle,
292 (EFI_GUID *)Name,
293 NULL
294 );
295 ASSERT_EFI_ERROR (Status);
296
297 return Status;
298}
299
313EFIAPI
315 IN CONST EFI_GUID *EventGroup
316 )
317{
318 EFI_STATUS Status;
319 EFI_EVENT Event;
320
321 if (EventGroup == NULL) {
322 return EFI_INVALID_PARAMETER;
323 }
324
325 Status = gBS->CreateEventEx (
326 EVT_NOTIFY_SIGNAL,
327 TPL_CALLBACK,
329 NULL,
330 EventGroup,
331 &Event
332 );
333 if (EFI_ERROR (Status)) {
334 return Status;
335 }
336
337 Status = gBS->SignalEvent (Event);
338 gBS->CloseEvent (Event);
339
340 return Status;
341}
342
352VOID
353EFIAPI
355 IN EFI_EVENT Event,
356 IN VOID *Context
357 )
358{
359}
360
374EFIAPI
376 VOID
377 )
378{
379 EFI_TPL Tpl;
380
381 Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
382 gBS->RestoreTPL (Tpl);
383
384 return Tpl;
385}
386
403EFI_LOCK *
404EFIAPI
407 IN EFI_TPL Priority
408 )
409{
410 ASSERT (Lock != NULL);
411 ASSERT (Priority <= TPL_HIGH_LEVEL);
412
413 Lock->Tpl = Priority;
414 Lock->OwnerTpl = TPL_APPLICATION;
415 Lock->Lock = EfiLockReleased;
416 return Lock;
417}
418
432VOID
433EFIAPI
436 )
437{
438 ASSERT (Lock != NULL);
439 ASSERT (Lock->Lock == EfiLockReleased);
440
441 Lock->OwnerTpl = gBS->RaiseTPL (Lock->Tpl);
442 Lock->Lock = EfiLockAcquired;
443}
444
462EFIAPI
465 )
466{
467 ASSERT (Lock != NULL);
468 ASSERT (Lock->Lock != EfiLockUninitialized);
469
470 if (Lock->Lock == EfiLockAcquired) {
471 //
472 // Lock is already owned, so bail out
473 //
474 return EFI_ACCESS_DENIED;
475 }
476
477 Lock->OwnerTpl = gBS->RaiseTPL (Lock->Tpl);
478
479 Lock->Lock = EfiLockAcquired;
480
481 return EFI_SUCCESS;
482}
483
497VOID
498EFIAPI
501 )
502{
503 EFI_TPL Tpl;
504
505 ASSERT (Lock != NULL);
506 ASSERT (Lock->Lock == EfiLockAcquired);
507
508 Tpl = Lock->OwnerTpl;
509
510 Lock->Lock = EfiLockReleased;
511
512 gBS->RestoreTPL (Tpl);
513}
514
539EFIAPI
541 IN CONST EFI_HANDLE ControllerHandle,
542 IN CONST EFI_HANDLE DriverBindingHandle,
543 IN CONST EFI_GUID *ProtocolGuid
544 )
545{
546 EFI_STATUS Status;
547 VOID *ManagedInterface;
548
549 ASSERT (ProtocolGuid != NULL);
550
551 Status = gBS->OpenProtocol (
552 ControllerHandle,
553 (EFI_GUID *)ProtocolGuid,
554 &ManagedInterface,
555 DriverBindingHandle,
556 ControllerHandle,
557 EFI_OPEN_PROTOCOL_BY_DRIVER
558 );
559 if (!EFI_ERROR (Status)) {
560 gBS->CloseProtocol (
561 ControllerHandle,
562 (EFI_GUID *)ProtocolGuid,
563 DriverBindingHandle,
564 ControllerHandle
565 );
566 return EFI_UNSUPPORTED;
567 }
568
569 if (Status != EFI_ALREADY_STARTED) {
570 return EFI_UNSUPPORTED;
571 }
572
573 return EFI_SUCCESS;
574}
575
596EFIAPI
598 IN CONST EFI_HANDLE ControllerHandle,
599 IN CONST EFI_HANDLE ChildHandle,
600 IN CONST EFI_GUID *ProtocolGuid
601 )
602{
603 EFI_STATUS Status;
605 UINTN EntryCount;
606 UINTN Index;
607
608 ASSERT (ProtocolGuid != NULL);
609
610 //
611 // Retrieve the list of agents that are consuming the specific protocol
612 // on ControllerHandle.
613 //
614 Status = gBS->OpenProtocolInformation (
615 ControllerHandle,
616 (EFI_GUID *)ProtocolGuid,
617 &OpenInfoBuffer,
618 &EntryCount
619 );
620 if (EFI_ERROR (Status)) {
621 return EFI_UNSUPPORTED;
622 }
623
624 //
625 // Inspect if ChildHandle is one of the agents.
626 //
627 Status = EFI_UNSUPPORTED;
628 for (Index = 0; Index < EntryCount; Index++) {
629 if ((OpenInfoBuffer[Index].ControllerHandle == ChildHandle) &&
630 ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0))
631 {
632 Status = EFI_SUCCESS;
633 break;
634 }
635 }
636
637 FreePool (OpenInfoBuffer);
638 return Status;
639}
640
652EFIAPI
654 IN CONST CHAR8 *SupportedLanguages,
655 IN CONST CHAR8 *TargetLanguage
656 )
657{
658 UINTN Index;
659
660 while (*SupportedLanguages != 0) {
661 for (Index = 0; SupportedLanguages[Index] != 0 && SupportedLanguages[Index] != ';'; Index++) {
662 }
663
664 if ((AsciiStrnCmp (SupportedLanguages, TargetLanguage, Index) == 0) && (TargetLanguage[Index] == 0)) {
665 return EFI_SUCCESS;
666 }
667
668 SupportedLanguages += Index;
669 for ( ; *SupportedLanguages != 0 && *SupportedLanguages == ';'; SupportedLanguages++) {
670 }
671 }
672
673 return EFI_UNSUPPORTED;
674}
675
707EFIAPI
709 IN CONST CHAR8 *Language,
710 IN CONST CHAR8 *SupportedLanguages,
711 IN CONST EFI_UNICODE_STRING_TABLE *UnicodeStringTable,
712 OUT CHAR16 **UnicodeString
713 )
714{
715 //
716 // Make sure the parameters are valid
717 //
718 if ((Language == NULL) || (UnicodeString == NULL)) {
719 return EFI_INVALID_PARAMETER;
720 }
721
722 //
723 // If there are no supported languages, or the Unicode String Table is empty, then the
724 // Unicode String specified by Language is not supported by this Unicode String Table
725 //
726 if ((SupportedLanguages == NULL) || (UnicodeStringTable == NULL)) {
727 return EFI_UNSUPPORTED;
728 }
729
730 //
731 // Make sure Language is in the set of Supported Languages
732 //
733 while (*SupportedLanguages != 0) {
734 if (CompareIso639LanguageCode (Language, SupportedLanguages)) {
735 //
736 // Search the Unicode String Table for the matching Language specifier
737 //
738 while (UnicodeStringTable->Language != NULL) {
739 if (CompareIso639LanguageCode (Language, UnicodeStringTable->Language)) {
740 //
741 // A matching string was found, so return it
742 //
743 *UnicodeString = UnicodeStringTable->UnicodeString;
744 return EFI_SUCCESS;
745 }
746
747 UnicodeStringTable++;
748 }
749
750 return EFI_UNSUPPORTED;
751 }
752
753 SupportedLanguages += 3;
754 }
755
756 return EFI_UNSUPPORTED;
757}
758
800EFIAPI
802 IN CONST CHAR8 *Language,
803 IN CONST CHAR8 *SupportedLanguages,
804 IN CONST EFI_UNICODE_STRING_TABLE *UnicodeStringTable,
805 OUT CHAR16 **UnicodeString,
806 IN BOOLEAN Iso639Language
807 )
808{
809 BOOLEAN Found;
810 UINTN Index;
811 CHAR8 *LanguageString;
812
813 //
814 // Make sure the parameters are valid
815 //
816 if ((Language == NULL) || (UnicodeString == NULL)) {
817 return EFI_INVALID_PARAMETER;
818 }
819
820 //
821 // If there are no supported languages, or the Unicode String Table is empty, then the
822 // Unicode String specified by Language is not supported by this Unicode String Table
823 //
824 if ((SupportedLanguages == NULL) || (UnicodeStringTable == NULL)) {
825 return EFI_UNSUPPORTED;
826 }
827
828 //
829 // Make sure Language is in the set of Supported Languages
830 //
831 Found = FALSE;
832 if (Iso639Language) {
833 while (*SupportedLanguages != 0) {
834 if (CompareIso639LanguageCode (Language, SupportedLanguages)) {
835 Found = TRUE;
836 break;
837 }
838
839 SupportedLanguages += 3;
840 }
841 } else {
842 Found = !IsLanguageSupported (SupportedLanguages, Language);
843 }
844
845 //
846 // If Language is not a member of SupportedLanguages, then return EFI_UNSUPPORTED
847 //
848 if (!Found) {
849 return EFI_UNSUPPORTED;
850 }
851
852 //
853 // Search the Unicode String Table for the matching Language specifier
854 //
855 while (UnicodeStringTable->Language != NULL) {
856 LanguageString = UnicodeStringTable->Language;
857 while (0 != *LanguageString) {
858 for (Index = 0; LanguageString[Index] != 0 && LanguageString[Index] != ';'; Index++) {
859 }
860
861 if (AsciiStrnCmp (LanguageString, Language, Index) == 0) {
862 *UnicodeString = UnicodeStringTable->UnicodeString;
863 return EFI_SUCCESS;
864 }
865
866 LanguageString += Index;
867 for (Index = 0; LanguageString[Index] != 0 && LanguageString[Index] == ';'; Index++) {
868 }
869 }
870
871 UnicodeStringTable++;
872 }
873
874 return EFI_UNSUPPORTED;
875}
876
911EFIAPI
913 IN CONST CHAR8 *Language,
914 IN CONST CHAR8 *SupportedLanguages,
915 IN OUT EFI_UNICODE_STRING_TABLE **UnicodeStringTable,
916 IN CONST CHAR16 *UnicodeString
917 )
918{
919 UINTN NumberOfEntries;
920 EFI_UNICODE_STRING_TABLE *OldUnicodeStringTable;
921 EFI_UNICODE_STRING_TABLE *NewUnicodeStringTable;
922 UINTN UnicodeStringLength;
923
924 //
925 // Make sure the parameter are valid
926 //
927 if ((Language == NULL) || (UnicodeString == NULL) || (UnicodeStringTable == NULL)) {
928 return EFI_INVALID_PARAMETER;
929 }
930
931 //
932 // If there are no supported languages, then a Unicode String can not be added
933 //
934 if (SupportedLanguages == NULL) {
935 return EFI_UNSUPPORTED;
936 }
937
938 //
939 // If the Unicode String is empty, then a Unicode String can not be added
940 //
941 if (UnicodeString[0] == 0) {
942 return EFI_INVALID_PARAMETER;
943 }
944
945 //
946 // Make sure Language is a member of SupportedLanguages
947 //
948 while (*SupportedLanguages != 0) {
949 if (CompareIso639LanguageCode (Language, SupportedLanguages)) {
950 //
951 // Determine the size of the Unicode String Table by looking for a NULL Language entry
952 //
953 NumberOfEntries = 0;
954 if (*UnicodeStringTable != NULL) {
955 OldUnicodeStringTable = *UnicodeStringTable;
956 while (OldUnicodeStringTable->Language != NULL) {
957 if (CompareIso639LanguageCode (Language, OldUnicodeStringTable->Language)) {
958 return EFI_ALREADY_STARTED;
959 }
960
961 OldUnicodeStringTable++;
962 NumberOfEntries++;
963 }
964 }
965
966 //
967 // Allocate space for a new Unicode String Table. It must hold the current number of
968 // entries, plus 1 entry for the new Unicode String, plus 1 entry for the end of table
969 // marker
970 //
971 NewUnicodeStringTable = AllocatePool ((NumberOfEntries + 2) * sizeof (EFI_UNICODE_STRING_TABLE));
972 if (NewUnicodeStringTable == NULL) {
973 return EFI_OUT_OF_RESOURCES;
974 }
975
976 //
977 // If the current Unicode String Table contains any entries, then copy them to the
978 // newly allocated Unicode String Table.
979 //
980 if (*UnicodeStringTable != NULL) {
981 CopyMem (
982 NewUnicodeStringTable,
983 *UnicodeStringTable,
984 NumberOfEntries * sizeof (EFI_UNICODE_STRING_TABLE)
985 );
986 }
987
988 //
989 // Allocate space for a copy of the Language specifier
990 //
991 NewUnicodeStringTable[NumberOfEntries].Language = AllocateCopyPool (3, Language);
992 if (NewUnicodeStringTable[NumberOfEntries].Language == NULL) {
993 FreePool (NewUnicodeStringTable);
994 return EFI_OUT_OF_RESOURCES;
995 }
996
997 //
998 // Compute the length of the Unicode String
999 //
1000 for (UnicodeStringLength = 0; UnicodeString[UnicodeStringLength] != 0; UnicodeStringLength++) {
1001 }
1002
1003 //
1004 // Allocate space for a copy of the Unicode String
1005 //
1006 NewUnicodeStringTable[NumberOfEntries].UnicodeString = AllocateCopyPool (
1007 (UnicodeStringLength + 1) * sizeof (CHAR16),
1008 UnicodeString
1009 );
1010 if (NewUnicodeStringTable[NumberOfEntries].UnicodeString == NULL) {
1011 FreePool (NewUnicodeStringTable[NumberOfEntries].Language);
1012 FreePool (NewUnicodeStringTable);
1013 return EFI_OUT_OF_RESOURCES;
1014 }
1015
1016 //
1017 // Mark the end of the Unicode String Table
1018 //
1019 NewUnicodeStringTable[NumberOfEntries + 1].Language = NULL;
1020 NewUnicodeStringTable[NumberOfEntries + 1].UnicodeString = NULL;
1021
1022 //
1023 // Free the old Unicode String Table
1024 //
1025 if (*UnicodeStringTable != NULL) {
1026 FreePool (*UnicodeStringTable);
1027 }
1028
1029 //
1030 // Point UnicodeStringTable at the newly allocated Unicode String Table
1031 //
1032 *UnicodeStringTable = NewUnicodeStringTable;
1033
1034 return EFI_SUCCESS;
1035 }
1036
1037 SupportedLanguages += 3;
1038 }
1039
1040 return EFI_UNSUPPORTED;
1041}
1042
1086EFIAPI
1088 IN CONST CHAR8 *Language,
1089 IN CONST CHAR8 *SupportedLanguages,
1090 IN OUT EFI_UNICODE_STRING_TABLE **UnicodeStringTable,
1091 IN CONST CHAR16 *UnicodeString,
1092 IN BOOLEAN Iso639Language
1093 )
1094{
1095 UINTN NumberOfEntries;
1096 EFI_UNICODE_STRING_TABLE *OldUnicodeStringTable;
1097 EFI_UNICODE_STRING_TABLE *NewUnicodeStringTable;
1098 UINTN UnicodeStringLength;
1099 BOOLEAN Found;
1100 UINTN Index;
1101 CHAR8 *LanguageString;
1102
1103 //
1104 // Make sure the parameter are valid
1105 //
1106 if ((Language == NULL) || (UnicodeString == NULL) || (UnicodeStringTable == NULL)) {
1107 return EFI_INVALID_PARAMETER;
1108 }
1109
1110 //
1111 // If there are no supported languages, then a Unicode String can not be added
1112 //
1113 if (SupportedLanguages == NULL) {
1114 return EFI_UNSUPPORTED;
1115 }
1116
1117 //
1118 // If the Unicode String is empty, then a Unicode String can not be added
1119 //
1120 if (UnicodeString[0] == 0) {
1121 return EFI_INVALID_PARAMETER;
1122 }
1123
1124 //
1125 // Make sure Language is a member of SupportedLanguages
1126 //
1127 Found = FALSE;
1128 if (Iso639Language) {
1129 while (*SupportedLanguages != 0) {
1130 if (CompareIso639LanguageCode (Language, SupportedLanguages)) {
1131 Found = TRUE;
1132 break;
1133 }
1134
1135 SupportedLanguages += 3;
1136 }
1137 } else {
1138 Found = !IsLanguageSupported (SupportedLanguages, Language);
1139 }
1140
1141 //
1142 // If Language is not a member of SupportedLanguages, then return EFI_UNSUPPORTED
1143 //
1144 if (!Found) {
1145 return EFI_UNSUPPORTED;
1146 }
1147
1148 //
1149 // Determine the size of the Unicode String Table by looking for a NULL Language entry
1150 //
1151 NumberOfEntries = 0;
1152 if (*UnicodeStringTable != NULL) {
1153 OldUnicodeStringTable = *UnicodeStringTable;
1154 while (OldUnicodeStringTable->Language != NULL) {
1155 LanguageString = OldUnicodeStringTable->Language;
1156
1157 while (*LanguageString != 0) {
1158 for (Index = 0; LanguageString[Index] != 0 && LanguageString[Index] != ';'; Index++) {
1159 }
1160
1161 if (AsciiStrnCmp (Language, LanguageString, Index) == 0) {
1162 return EFI_ALREADY_STARTED;
1163 }
1164
1165 LanguageString += Index;
1166 for ( ; *LanguageString != 0 && *LanguageString == ';'; LanguageString++) {
1167 }
1168 }
1169
1170 OldUnicodeStringTable++;
1171 NumberOfEntries++;
1172 }
1173 }
1174
1175 //
1176 // Allocate space for a new Unicode String Table. It must hold the current number of
1177 // entries, plus 1 entry for the new Unicode String, plus 1 entry for the end of table
1178 // marker
1179 //
1180 NewUnicodeStringTable = AllocatePool ((NumberOfEntries + 2) * sizeof (EFI_UNICODE_STRING_TABLE));
1181 if (NewUnicodeStringTable == NULL) {
1182 return EFI_OUT_OF_RESOURCES;
1183 }
1184
1185 //
1186 // If the current Unicode String Table contains any entries, then copy them to the
1187 // newly allocated Unicode String Table.
1188 //
1189 if (*UnicodeStringTable != NULL) {
1190 CopyMem (
1191 NewUnicodeStringTable,
1192 *UnicodeStringTable,
1193 NumberOfEntries * sizeof (EFI_UNICODE_STRING_TABLE)
1194 );
1195 }
1196
1197 //
1198 // Allocate space for a copy of the Language specifier
1199 //
1200 NewUnicodeStringTable[NumberOfEntries].Language = AllocateCopyPool (AsciiStrSize (Language), Language);
1201 if (NewUnicodeStringTable[NumberOfEntries].Language == NULL) {
1202 FreePool (NewUnicodeStringTable);
1203 return EFI_OUT_OF_RESOURCES;
1204 }
1205
1206 //
1207 // Compute the length of the Unicode String
1208 //
1209 for (UnicodeStringLength = 0; UnicodeString[UnicodeStringLength] != 0; UnicodeStringLength++) {
1210 }
1211
1212 //
1213 // Allocate space for a copy of the Unicode String
1214 //
1215 NewUnicodeStringTable[NumberOfEntries].UnicodeString = AllocateCopyPool (StrSize (UnicodeString), UnicodeString);
1216 if (NewUnicodeStringTable[NumberOfEntries].UnicodeString == NULL) {
1217 FreePool (NewUnicodeStringTable[NumberOfEntries].Language);
1218 FreePool (NewUnicodeStringTable);
1219 return EFI_OUT_OF_RESOURCES;
1220 }
1221
1222 //
1223 // Mark the end of the Unicode String Table
1224 //
1225 NewUnicodeStringTable[NumberOfEntries + 1].Language = NULL;
1226 NewUnicodeStringTable[NumberOfEntries + 1].UnicodeString = NULL;
1227
1228 //
1229 // Free the old Unicode String Table
1230 //
1231 if (*UnicodeStringTable != NULL) {
1232 FreePool (*UnicodeStringTable);
1233 }
1234
1235 //
1236 // Point UnicodeStringTable at the newly allocated Unicode String Table
1237 //
1238 *UnicodeStringTable = NewUnicodeStringTable;
1239
1240 return EFI_SUCCESS;
1241}
1242
1256EFIAPI
1258 IN EFI_UNICODE_STRING_TABLE *UnicodeStringTable
1259 )
1260{
1261 UINTN Index;
1262
1263 //
1264 // If the Unicode String Table is NULL, then it is already freed
1265 //
1266 if (UnicodeStringTable == NULL) {
1267 return EFI_SUCCESS;
1268 }
1269
1270 //
1271 // Loop through the Unicode String Table until we reach the end of table marker
1272 //
1273 for (Index = 0; UnicodeStringTable[Index].Language != NULL; Index++) {
1274 //
1275 // Free the Language string from the Unicode String Table
1276 //
1277 FreePool (UnicodeStringTable[Index].Language);
1278
1279 //
1280 // Free the Unicode String from the Unicode String Table
1281 //
1282 if (UnicodeStringTable[Index].UnicodeString != NULL) {
1283 FreePool (UnicodeStringTable[Index].UnicodeString);
1284 }
1285 }
1286
1287 //
1288 // Free the Unicode String Table itself
1289 //
1290 FreePool (UnicodeStringTable);
1291
1292 return EFI_SUCCESS;
1293}
1294
1316EFIAPI
1318 IN CONST CHAR16 *Name,
1319 IN CONST EFI_GUID *Guid,
1320 OUT VOID **Value,
1321 OUT UINTN *Size OPTIONAL
1322 )
1323{
1324 EFI_STATUS Status;
1325 UINTN BufferSize;
1326
1327 ASSERT (Name != NULL && Guid != NULL && Value != NULL);
1328
1329 //
1330 // Try to get the variable size.
1331 //
1332 BufferSize = 0;
1333 *Value = NULL;
1334 if (Size != NULL) {
1335 *Size = 0;
1336 }
1337
1338 Status = gRT->GetVariable ((CHAR16 *)Name, (EFI_GUID *)Guid, NULL, &BufferSize, *Value);
1339 if (Status != EFI_BUFFER_TOO_SMALL) {
1340 return Status;
1341 }
1342
1343 //
1344 // Allocate buffer to get the variable.
1345 //
1346 *Value = AllocatePool (BufferSize);
1347 ASSERT (*Value != NULL);
1348 if (*Value == NULL) {
1349 return EFI_OUT_OF_RESOURCES;
1350 }
1351
1352 //
1353 // Get the variable data.
1354 //
1355 Status = gRT->GetVariable ((CHAR16 *)Name, (EFI_GUID *)Guid, NULL, &BufferSize, *Value);
1356 if (EFI_ERROR (Status)) {
1357 FreePool (*Value);
1358 *Value = NULL;
1359 }
1360
1361 if (Size != NULL) {
1362 *Size = BufferSize;
1363 }
1364
1365 return Status;
1366}
1367
1392EFIAPI
1394 IN CONST CHAR16 *Name,
1395 IN CONST EFI_GUID *Guid,
1396 OUT VOID **Value,
1397 OUT UINTN *Size OPTIONAL,
1398 OUT UINT32 *Attr OPTIONAL
1399 )
1400{
1401 EFI_STATUS Status;
1402 UINTN BufferSize;
1403
1404 ASSERT (Name != NULL && Guid != NULL && Value != NULL);
1405
1406 //
1407 // Try to get the variable size.
1408 //
1409 BufferSize = 0;
1410 *Value = NULL;
1411 if (Size != NULL) {
1412 *Size = 0;
1413 }
1414
1415 if (Attr != NULL) {
1416 *Attr = 0;
1417 }
1418
1419 Status = gRT->GetVariable ((CHAR16 *)Name, (EFI_GUID *)Guid, Attr, &BufferSize, *Value);
1420 if (Status != EFI_BUFFER_TOO_SMALL) {
1421 return Status;
1422 }
1423
1424 //
1425 // Allocate buffer to get the variable.
1426 //
1427 *Value = AllocatePool (BufferSize);
1428 ASSERT (*Value != NULL);
1429 if (*Value == NULL) {
1430 return EFI_OUT_OF_RESOURCES;
1431 }
1432
1433 //
1434 // Get the variable data.
1435 //
1436 Status = gRT->GetVariable ((CHAR16 *)Name, (EFI_GUID *)Guid, Attr, &BufferSize, *Value);
1437 if (EFI_ERROR (Status)) {
1438 FreePool (*Value);
1439 *Value = NULL;
1440 }
1441
1442 if (Size != NULL) {
1443 *Size = BufferSize;
1444 }
1445
1446 return Status;
1447}
1448
1469EFIAPI
1471 IN CONST CHAR16 *Name,
1472 OUT VOID **Value,
1473 OUT UINTN *Size OPTIONAL
1474 )
1475{
1476 return GetVariable2 (Name, &gEfiGlobalVariableGuid, Value, Size);
1477}
1478
1520CHAR8 *
1521EFIAPI
1523 IN CONST CHAR8 *SupportedLanguages,
1524 IN UINTN Iso639Language,
1525 ...
1526 )
1527{
1528 VA_LIST Args;
1529 CHAR8 *Language;
1530 UINTN CompareLength;
1531 UINTN LanguageLength;
1532 CONST CHAR8 *Supported;
1533 CHAR8 *BestLanguage;
1534
1535 ASSERT (SupportedLanguages != NULL);
1536
1537 VA_START (Args, Iso639Language);
1538 while ((Language = VA_ARG (Args, CHAR8 *)) != NULL) {
1539 //
1540 // Default to ISO 639-2 mode
1541 //
1542 CompareLength = 3;
1543 LanguageLength = MIN (3, AsciiStrLen (Language));
1544
1545 //
1546 // If in RFC 4646 mode, then determine the length of the first RFC 4646 language code in Language
1547 //
1548 if (Iso639Language == 0) {
1549 for (LanguageLength = 0; Language[LanguageLength] != 0 && Language[LanguageLength] != ';'; LanguageLength++) {
1550 }
1551 }
1552
1553 //
1554 // Trim back the length of Language used until it is empty
1555 //
1556 while (LanguageLength > 0) {
1557 //
1558 // Loop through all language codes in SupportedLanguages
1559 //
1560 for (Supported = SupportedLanguages; *Supported != '\0'; Supported += CompareLength) {
1561 //
1562 // In RFC 4646 mode, then Loop through all language codes in SupportedLanguages
1563 //
1564 if (Iso639Language == 0) {
1565 //
1566 // Skip ';' characters in Supported
1567 //
1568 for ( ; *Supported != '\0' && *Supported == ';'; Supported++) {
1569 }
1570
1571 //
1572 // Determine the length of the next language code in Supported
1573 //
1574 for (CompareLength = 0; Supported[CompareLength] != 0 && Supported[CompareLength] != ';'; CompareLength++) {
1575 }
1576
1577 //
1578 // If Language is longer than the Supported, then skip to the next language
1579 //
1580 if (LanguageLength > CompareLength) {
1581 continue;
1582 }
1583 }
1584
1585 //
1586 // See if the first LanguageLength characters in Supported match Language
1587 //
1588 if (AsciiStrnCmp (Supported, Language, LanguageLength) == 0) {
1589 VA_END (Args);
1590 //
1591 // Allocate, copy, and return the best matching language code from SupportedLanguages
1592 //
1593 BestLanguage = AllocateZeroPool (CompareLength + 1);
1594 if (BestLanguage == NULL) {
1595 return NULL;
1596 }
1597
1598 return CopyMem (BestLanguage, Supported, CompareLength);
1599 }
1600 }
1601
1602 if (Iso639Language != 0) {
1603 //
1604 // If ISO 639 mode, then each language can only be tested once
1605 //
1606 LanguageLength = 0;
1607 } else {
1608 //
1609 // If RFC 4646 mode, then trim Language from the right to the next '-' character
1610 //
1611 for (LanguageLength--; LanguageLength > 0 && Language[LanguageLength] != '-'; LanguageLength--) {
1612 }
1613 }
1614 }
1615 }
1616
1617 VA_END (Args);
1618
1619 //
1620 // No matches were found
1621 //
1622 return NULL;
1623}
1624
1649EFIAPI
1651 IN EFI_GUID *Protocol,
1652 OUT UINTN *NoProtocols,
1653 OUT VOID ***Buffer
1654 )
1655{
1656 EFI_STATUS Status;
1657 UINTN NoHandles;
1658 EFI_HANDLE *HandleBuffer;
1659 UINTN Index;
1660
1661 //
1662 // Check input parameters
1663 //
1664 if ((Protocol == NULL) || (NoProtocols == NULL) || (Buffer == NULL)) {
1665 return EFI_INVALID_PARAMETER;
1666 }
1667
1668 //
1669 // Initialze output parameters
1670 //
1671 *NoProtocols = 0;
1672 *Buffer = NULL;
1673
1674 //
1675 // Retrieve the array of handles that support Protocol
1676 //
1677 Status = gBS->LocateHandleBuffer (
1678 ByProtocol,
1679 Protocol,
1680 NULL,
1681 &NoHandles,
1682 &HandleBuffer
1683 );
1684 if (EFI_ERROR (Status)) {
1685 return Status;
1686 }
1687
1688 //
1689 // Allocate array of protocol instances
1690 //
1691 Status = gBS->AllocatePool (
1693 NoHandles * sizeof (VOID *),
1694 (VOID **)Buffer
1695 );
1696 if (EFI_ERROR (Status)) {
1697 //
1698 // Free the handle buffer
1699 //
1700 gBS->FreePool (HandleBuffer);
1701 return EFI_OUT_OF_RESOURCES;
1702 }
1703
1704 ZeroMem (*Buffer, NoHandles * sizeof (VOID *));
1705
1706 //
1707 // Lookup Protocol on each handle in HandleBuffer to fill in the array of
1708 // protocol instances. Handle case where protocol instance was present when
1709 // LocateHandleBuffer() was called, but is not present when HandleProtocol()
1710 // is called.
1711 //
1712 for (Index = 0, *NoProtocols = 0; Index < NoHandles; Index++) {
1713 Status = gBS->HandleProtocol (
1714 HandleBuffer[Index],
1715 Protocol,
1716 &((*Buffer)[*NoProtocols])
1717 );
1718 if (!EFI_ERROR (Status)) {
1719 (*NoProtocols)++;
1720 }
1721 }
1722
1723 //
1724 // Free the handle buffer
1725 //
1726 gBS->FreePool (HandleBuffer);
1727
1728 //
1729 // Make sure at least one protocol instance was found
1730 //
1731 if (*NoProtocols == 0) {
1732 gBS->FreePool (*Buffer);
1733 *Buffer = NULL;
1734 return EFI_NOT_FOUND;
1735 }
1736
1737 return EFI_SUCCESS;
1738}
1739
1805EFIAPI
1807 IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath,
1808 OUT EFI_FILE_PROTOCOL **File,
1809 IN UINT64 OpenMode,
1810 IN UINT64 Attributes
1811 )
1812{
1813 EFI_STATUS Status;
1814 EFI_HANDLE FileSystemHandle;
1816 EFI_FILE_PROTOCOL *LastFile;
1817 FILEPATH_DEVICE_PATH *FilePathNode;
1818 CHAR16 *AlignedPathName;
1819 CHAR16 *PathName;
1820 EFI_FILE_PROTOCOL *NextFile;
1821
1822 if (File == NULL) {
1823 return EFI_INVALID_PARAMETER;
1824 }
1825
1826 *File = NULL;
1827
1828 if (FilePath == NULL) {
1829 return EFI_INVALID_PARAMETER;
1830 }
1831
1832 //
1833 // Look up the filesystem.
1834 //
1835 Status = gBS->LocateDevicePath (
1836 &gEfiSimpleFileSystemProtocolGuid,
1837 FilePath,
1838 &FileSystemHandle
1839 );
1840 if (EFI_ERROR (Status)) {
1841 return Status;
1842 }
1843
1844 Status = gBS->OpenProtocol (
1845 FileSystemHandle,
1846 &gEfiSimpleFileSystemProtocolGuid,
1847 (VOID **)&FileSystem,
1849 NULL,
1850 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1851 );
1852 if (EFI_ERROR (Status)) {
1853 return Status;
1854 }
1855
1856 //
1857 // Open the root directory of the filesystem. After this operation succeeds,
1858 // we have to release LastFile on error.
1859 //
1860 Status = FileSystem->OpenVolume (FileSystem, &LastFile);
1861 if (EFI_ERROR (Status)) {
1862 return Status;
1863 }
1864
1865 //
1866 // Traverse the device path nodes relative to the filesystem.
1867 //
1868 while (!IsDevicePathEnd (*FilePath)) {
1869 if ((DevicePathType (*FilePath) != MEDIA_DEVICE_PATH) ||
1870 (DevicePathSubType (*FilePath) != MEDIA_FILEPATH_DP))
1871 {
1872 Status = EFI_INVALID_PARAMETER;
1873 goto CloseLastFile;
1874 }
1875
1876 FilePathNode = (FILEPATH_DEVICE_PATH *)*FilePath;
1877
1878 //
1879 // FilePathNode->PathName may be unaligned, and the UEFI specification
1880 // requires pointers that are passed to protocol member functions to be
1881 // aligned. Create an aligned copy of the pathname if necessary.
1882 //
1883 if ((UINTN)FilePathNode->PathName % sizeof *FilePathNode->PathName == 0) {
1884 AlignedPathName = NULL;
1885 PathName = FilePathNode->PathName;
1886 } else {
1887 AlignedPathName = AllocateCopyPool (
1888 (DevicePathNodeLength (FilePathNode) -
1889 SIZE_OF_FILEPATH_DEVICE_PATH),
1890 FilePathNode->PathName
1891 );
1892 if (AlignedPathName == NULL) {
1893 Status = EFI_OUT_OF_RESOURCES;
1894 goto CloseLastFile;
1895 }
1896
1897 PathName = AlignedPathName;
1898 }
1899
1900 //
1901 // Open or create the file corresponding to the next pathname fragment.
1902 //
1903 Status = LastFile->Open (
1904 LastFile,
1905 &NextFile,
1906 PathName,
1907 OpenMode,
1908 Attributes
1909 );
1910
1911 //
1912 // Release any AlignedPathName on both error and success paths; PathName is
1913 // no longer needed.
1914 //
1915 if (AlignedPathName != NULL) {
1916 FreePool (AlignedPathName);
1917 }
1918
1919 if (EFI_ERROR (Status)) {
1920 goto CloseLastFile;
1921 }
1922
1923 //
1924 // Advance to the next device path node.
1925 //
1926 LastFile->Close (LastFile);
1927 LastFile = NextFile;
1928 *FilePath = NextDevicePathNode (FilePathNode);
1929 }
1930
1931 *File = LastFile;
1932 return EFI_SUCCESS;
1933
1934CloseLastFile:
1935 LastFile->Close (LastFile);
1936
1937 //
1938 // We are on the error path; we must have set an error Status for returning
1939 // to the caller.
1940 //
1941 ASSERT (EFI_ERROR (Status));
1942 return Status;
1943}
UINT64 UINTN
UINTN EFIAPI StrSize(IN CONST CHAR16 *String)
Definition: String.c:72
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
Definition: String.c:641
INTN EFIAPI AsciiStrnCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString, IN UINTN Length)
Definition: String.c:872
UINT32 EFIAPI ReadUnaligned24(IN CONST UINT32 *Buffer)
Definition: Unaligned.c:89
UINTN EFIAPI AsciiStrSize(IN CONST CHAR8 *String)
Definition: String.c:681
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define MEDIA_FILEPATH_DP
Definition: DevicePath.h:1098
UINT8 EFIAPI DevicePathType(IN CONST VOID *Node)
UINTN EFIAPI DevicePathNodeLength(IN CONST VOID *Node)
UINT8 EFIAPI DevicePathSubType(IN CONST VOID *Node)
BOOLEAN EFIAPI IsDevicePathEnd(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI NextDevicePathNode(IN CONST VOID *Node)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
EFI_RUNTIME_SERVICES * gRT
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define MIN(a, b)
Definition: Base.h:1007
#define VA_ARG(Marker, TYPE)
Definition: Base.h:679
#define VA_START(Marker, Parameter)
Definition: Base.h:661
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
CHAR8 * VA_LIST
Definition: Base.h:643
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define VA_END(Marker)
Definition: Base.h:691
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
VOID EFIAPI NotifyFunction(IN EFI_EVENT Event, IN VOID *Context)
Definition: ScsiBus.c:1492
EFI_STATUS EFIAPI Lock(IN EFI_SMM_ACCESS2_PROTOCOL *This)
Definition: SmmAccessDxe.c:133
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
UINTN EFI_TPL
Definition: UefiBaseType.h:41
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_SYSTEM_TABLE * gST
EFI_HANDLE gImageHandle
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI AddUnicodeString2(IN CONST CHAR8 *Language, IN CONST CHAR8 *SupportedLanguages, IN OUT EFI_UNICODE_STRING_TABLE **UnicodeStringTable, IN CONST CHAR16 *UnicodeString, IN BOOLEAN Iso639Language)
Definition: UefiLib.c:1087
EFI_STATUS EFIAPI EfiOpenFileByDevicePath(IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath, OUT EFI_FILE_PROTOCOL **File, IN UINT64 OpenMode, IN UINT64 Attributes)
Definition: UefiLib.c:1806
EFI_TPL EFIAPI EfiGetCurrentTpl(VOID)
Definition: UefiLib.c:375
VOID EFIAPI EfiReleaseLock(IN EFI_LOCK *Lock)
Definition: UefiLib.c:499
EFI_STATUS EFIAPI EfiNamedEventListen(IN CONST EFI_GUID *Name, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction, IN CONST VOID *NotifyContext OPTIONAL, OUT VOID *Registration OPTIONAL)
Definition: UefiLib.c:205
EFI_STATUS EFIAPI GetEfiGlobalVariable2(IN CONST CHAR16 *Name, OUT VOID **Value, OUT UINTN *Size OPTIONAL)
Definition: UefiLib.c:1470
EFI_STATUS EFIAPI EfiTestChildHandle(IN CONST EFI_HANDLE ControllerHandle, IN CONST EFI_HANDLE ChildHandle, IN CONST EFI_GUID *ProtocolGuid)
Definition: UefiLib.c:597
EFI_STATUS EFIAPI EfiAcquireLockOrFail(IN EFI_LOCK *Lock)
Definition: UefiLib.c:463
VOID EFIAPI EfiEventEmptyFunction(IN EFI_EVENT Event, IN VOID *Context)
Definition: UefiLib.c:354
EFI_STATUS EFIAPI EfiGetSystemConfigurationTable(IN EFI_GUID *TableGuid, OUT VOID **Table)
Definition: UefiLib.c:82
EFI_STATUS EFIAPI LookupUnicodeString(IN CONST CHAR8 *Language, IN CONST CHAR8 *SupportedLanguages, IN CONST EFI_UNICODE_STRING_TABLE *UnicodeStringTable, OUT CHAR16 **UnicodeString)
Definition: UefiLib.c:708
EFI_STATUS EFIAPI EfiNamedEventSignal(IN CONST EFI_GUID *Name)
Definition: UefiLib.c:272
EFI_STATUS EFIAPI EfiEventGroupSignal(IN CONST EFI_GUID *EventGroup)
Definition: UefiLib.c:314
EFI_STATUS EFIAPI GetVariable2(IN CONST CHAR16 *Name, IN CONST EFI_GUID *Guid, OUT VOID **Value, OUT UINTN *Size OPTIONAL)
Definition: UefiLib.c:1317
VOID EFIAPI EfiAcquireLock(IN EFI_LOCK *Lock)
Definition: UefiLib.c:434
EFI_STATUS EFIAPI GetVariable3(IN CONST CHAR16 *Name, IN CONST EFI_GUID *Guid, OUT VOID **Value, OUT UINTN *Size OPTIONAL, OUT UINT32 *Attr OPTIONAL)
Definition: UefiLib.c:1393
BOOLEAN CompareIso639LanguageCode(IN CONST CHAR8 *Language1, IN CONST CHAR8 *Language2)
Definition: UefiLib.c:48
EFI_LOCK *EFIAPI EfiInitializeLock(IN OUT EFI_LOCK *Lock, IN EFI_TPL Priority)
Definition: UefiLib.c:405
EFI_STATUS EFIAPI LookupUnicodeString2(IN CONST CHAR8 *Language, IN CONST CHAR8 *SupportedLanguages, IN CONST EFI_UNICODE_STRING_TABLE *UnicodeStringTable, OUT CHAR16 **UnicodeString, IN BOOLEAN Iso639Language)
Definition: UefiLib.c:801
EFI_STATUS EFIAPI EfiTestManagedDevice(IN CONST EFI_HANDLE ControllerHandle, IN CONST EFI_HANDLE DriverBindingHandle, IN CONST EFI_GUID *ProtocolGuid)
Definition: UefiLib.c:540
EFI_STATUS EFIAPI UefiLibConstructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: UefiLib.c:29
EFI_STATUS EFIAPI IsLanguageSupported(IN CONST CHAR8 *SupportedLanguages, IN CONST CHAR8 *TargetLanguage)
Definition: UefiLib.c:653
EFI_STATUS EFIAPI EfiLocateProtocolBuffer(IN EFI_GUID *Protocol, OUT UINTN *NoProtocols, OUT VOID ***Buffer)
Definition: UefiLib.c:1650
EFI_EVENT EFIAPI EfiCreateProtocolNotifyEvent(IN EFI_GUID *ProtocolGuid, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction, IN VOID *NotifyContext OPTIONAL, OUT VOID **Registration)
Definition: UefiLib.c:134
EFI_STATUS EFIAPI AddUnicodeString(IN CONST CHAR8 *Language, IN CONST CHAR8 *SupportedLanguages, IN OUT EFI_UNICODE_STRING_TABLE **UnicodeStringTable, IN CONST CHAR16 *UnicodeString)
Definition: UefiLib.c:912
EFI_STATUS EFIAPI FreeUnicodeStringTable(IN EFI_UNICODE_STRING_TABLE *UnicodeStringTable)
Definition: UefiLib.c:1257
CHAR8 *EFIAPI GetBestLanguage(IN CONST CHAR8 *SupportedLanguages, IN UINTN Iso639Language,...)
Definition: UefiLib.c:1522
@ EfiBootServicesData
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
VOID(EFIAPI * EFI_EVENT_NOTIFY)(IN EFI_EVENT Event, IN VOID *Context)
Definition: UefiSpec.h:463
@ ByProtocol
Definition: UefiSpec.h:1518
EFI_CONFIGURATION_TABLE * ConfigurationTable
Definition: UefiSpec.h:2092
UINTN NumberOfTableEntries
Definition: UefiSpec.h:2087
Definition: Base.h:213