18#include <Library/BaseLib.h>
19#include <Library/BaseMemoryLib.h>
20#include <Library/BaseOverflowLib.h>
21#include <Library/DebugLib.h>
22#include <Library/MemoryAllocationLib.h>
23#include <Library/PrintLib.h>
42 if (BuiltinKext->PlistPath != NULL) {
43 FreePool (BuiltinKext->PlistPath);
46 if (BuiltinKext->Identifier != NULL) {
47 FreePool (BuiltinKext->Identifier);
50 if (BuiltinKext->BinaryFileName != NULL) {
51 FreePool (BuiltinKext->BinaryFileName);
54 if (BuiltinKext->BinaryPath != NULL) {
55 FreePool (BuiltinKext->BinaryPath);
58 while (!IsListEmpty (&BuiltinKext->Dependencies)) {
59 KextLink = GetFirstNode (&BuiltinKext->Dependencies);
61 RemoveEntryList (KextLink);
67 FreePool (DependKext);
70 FreePool (BuiltinKext);
76 IN OUT LIST_ENTRY *Dependencies,
77 IN CONST CHAR8 *Identifier
83 KextLink = GetFirstNode (Dependencies);
84 while (!IsNull (Dependencies, KextLink)) {
87 if (AsciiStrCmp (DependKext->
Identifier, Identifier) == 0) {
91 KextLink = GetNextNode (Dependencies, KextLink);
94 DependKext = AllocateZeroPool (
sizeof (*DependKext));
95 if (DependKext == NULL) {
96 return EFI_OUT_OF_RESOURCES;
100 DependKext->
Identifier = AllocateCopyPool (AsciiStrSize (Identifier), Identifier);
102 FreePool (DependKext);
103 return EFI_OUT_OF_RESOURCES;
106 InsertTailList (Dependencies, &DependKext->
Link);
113 IN OUT LIST_ENTRY *Dependencies,
120 CONST CHAR8 *ChildPlistKey;
123 for (ChildIndex = 0; ChildIndex < ChildCount; ChildIndex++) {
125 if (ChildPlistKey == NULL) {
130 if (EFI_ERROR (Status)) {
142 IN EFI_FILE_PROTOCOL *File,
144 IN BOOLEAN ReadPlugins
148 EFI_FILE_PROTOCOL *FileKext;
149 EFI_FILE_PROTOCOL *FilePlist;
150 EFI_FILE_PROTOCOL *FilePlugins;
151 EFI_FILE_INFO *FileInfo;
156 UINT32 InfoPlistSize;
162 CONST CHAR8 *TmpKeyValue;
169 DEBUG ((DEBUG_INFO,
"OCAK: Scanning %s...\n",
FilePath));
171 FileInfo = AllocatePool (SIZE_1KB);
172 if (FileInfo == NULL) {
173 return EFI_OUT_OF_RESOURCES;
176 File->SetPosition (File, 0);
184 FileInfoSize = SIZE_1KB -
sizeof (CHAR16);
185 Status = File->Read (File, &FileInfoSize, FileInfo);
186 if (EFI_ERROR (Status)) {
187 FileKext->Close (FileKext);
188 File->SetPosition (File, 0);
193 if (FileInfoSize > 0) {
195 Status = File->Open (File, &FileKext, FileInfo->FileName, EFI_FILE_MODE_READ, EFI_FILE_DIRECTORY);
196 if (EFI_ERROR (Status)) {
204 Status = FileKext->Open (FileKext, &FilePlist, L
"Contents", EFI_FILE_MODE_READ, EFI_FILE_DIRECTORY);
205 UseContents = !EFI_ERROR (Status);
211 Status = FileKext->Open (
214 UseContents ? L
"Contents\\Info.plist" : L
"Info.plist",
218 if (!EFI_ERROR (Status)) {
223 FilePlist->Close (FilePlist);
224 if (EFI_ERROR (Status)) {
225 FileKext->Close (FileKext);
226 File->SetPosition (File, 0);
232 if (InfoPlistDocument == NULL) {
233 FreePool (InfoPlist);
234 FileKext->Close (FileKext);
235 File->SetPosition (File, 0);
237 return EFI_INVALID_PARAMETER;
241 if (InfoPlistRoot == NULL) {
243 FreePool (InfoPlist);
244 FileKext->Close (FileKext);
245 File->SetPosition (File, 0);
247 return EFI_INVALID_PARAMETER;
253 BuiltinKext = AllocateZeroPool (
sizeof (*BuiltinKext));
254 if (BuiltinKext == NULL) {
256 FreePool (InfoPlist);
257 FileKext->Close (FileKext);
258 File->SetPosition (File, 0);
260 return EFI_OUT_OF_RESOURCES;
269 InfoPlistLibraries = NULL;
271 for (FieldIndex = 0; FieldIndex < FieldCount; ++FieldIndex) {
273 if (TmpKeyValue == NULL) {
282 FreePool (InfoPlist);
283 FileKext->Close (FileKext);
284 File->SetPosition (File, 0);
286 return EFI_OUT_OF_RESOURCES;
293 FreePool (InfoPlist);
294 FileKext->Close (FileKext);
295 File->SetPosition (File, 0);
297 return EFI_OUT_OF_RESOURCES;
309 if (!Context->Is32Bit && (InfoPlistLibraries64 == NULL)) {
311 if (InfoPlistLibraries == NULL) {
314 FreePool (InfoPlist);
315 FileKext->Close (FileKext);
316 File->SetPosition (File, 0);
318 return EFI_INVALID_PARAMETER;
323 if (InfoPlistLibraries64 == NULL) {
326 FreePool (InfoPlist);
327 FileKext->Close (FileKext);
328 File->SetPosition (File, 0);
330 return EFI_INVALID_PARAMETER;
333 if (!Context->Is32Bit) {
334 InfoPlistLibraries = InfoPlistLibraries64;
339 if (InfoPlistLibraries != NULL) {
341 if (EFI_ERROR (Status)) {
344 FreePool (InfoPlist);
345 FileKext->Close (FileKext);
346 File->SetPosition (File, 0);
353 FreePool (InfoPlist);
357 FileKext->Close (FileKext);
358 File->SetPosition (File, 0);
360 return EFI_INVALID_PARAMETER;
372 UseContents ? L
"Contents\\Info.plist" : L
"Info.plist"
374 if (EFI_ERROR (Status)) {
376 FileKext->Close (FileKext);
377 File->SetPosition (File, 0);
379 return EFI_INVALID_PARAMETER;
382 BuiltinKext->
PlistPath = AllocateCopyPool (StrSize (TmpPath), TmpPath);
385 FileKext->Close (FileKext);
386 File->SetPosition (File, 0);
388 return EFI_OUT_OF_RESOURCES;
401 UseContents ? L
"Contents\\MacOS\\" : L
"",
404 if (EFI_ERROR (Status)) {
406 FileKext->Close (FileKext);
407 File->SetPosition (File, 0);
409 return EFI_INVALID_PARAMETER;
412 BuiltinKext->
BinaryPath = AllocateCopyPool (StrSize (TmpPath), TmpPath);
415 FileKext->Close (FileKext);
416 File->SetPosition (File, 0);
418 return EFI_OUT_OF_RESOURCES;
422 InsertTailList (&Context->BuiltInKexts, &BuiltinKext->
Link);
425 "OCAK: Discovered bundle %a %s %s %u\n",
437 Status = FileKext->Open (FileKext, &FilePlugins, UseContents ? L
"Contents\\PlugIns" : L
"PlugIns", EFI_FILE_MODE_READ, EFI_FILE_DIRECTORY);
438 if (Status == EFI_SUCCESS) {
445 UseContents ? L
"Contents\\PlugIns" : L
"PlugIns"
449 FilePlugins->Close (FilePlugins);
450 if (EFI_ERROR (Status)) {
451 FileKext->Close (FileKext);
452 File->SetPosition (File, 0);
456 }
else if (Status != EFI_NOT_FOUND) {
457 FileKext->Close (FileKext);
458 File->SetPosition (File, 0);
464 FileKext->Close (FileKext);
467 }
while (FileInfoSize > 0);
469 File->SetPosition (File, 0);
479 IN CONST CHAR8 *Identifier
483 LIST_ENTRY *KextLink;
485 KextLink = GetFirstNode (&Context->PatchedKexts);
486 while (!IsNull (&Context->PatchedKexts, KextLink)) {
489 if (AsciiStrCmp (Identifier, PatchedKext->
Identifier) == 0) {
493 KextLink = GetNextNode (&Context->PatchedKexts, KextLink);
503 IN CONST CHAR8 *Identifier
507 LIST_ENTRY *KextLink;
509 KextLink = GetFirstNode (&Context->BuiltInKexts);
510 while (!IsNull (&Context->BuiltInKexts, KextLink)) {
513 if (AsciiStrCmp (Identifier, BuiltinKext->
Identifier) == 0) {
517 KextLink = GetNextNode (&Context->BuiltInKexts, KextLink);
527 IN CONST CHAR16 *PlistPath
531 LIST_ENTRY *KextLink;
533 KextLink = GetFirstNode (&Context->BuiltInKexts);
534 while (!IsNull (&Context->BuiltInKexts, KextLink)) {
537 if (StrCmp (PlistPath, BuiltinKext->
PlistPath) == 0) {
541 KextLink = GetNextNode (&Context->BuiltInKexts, KextLink);
551 IN CONST CHAR16 *BinaryPath
555 LIST_ENTRY *KextLink;
557 KextLink = GetFirstNode (&Context->BuiltInKexts);
558 while (!IsNull (&Context->BuiltInKexts, KextLink)) {
562 && (StrCmp (BinaryPath, BuiltinKext->
BinaryPath) == 0))
567 KextLink = GetNextNode (&Context->BuiltInKexts, KextLink);
583 LIST_ENTRY *KextLink;
585 DEBUG ((DEBUG_VERBOSE,
"OCAK: Scanning dependencies for %a\n", Identifier));
599 if (EFI_ERROR (Status)) {
604 while (!IsNull (&BuiltinKext->
Dependencies, KextLink)) {
608 if (EFI_ERROR (Status)) {
612 KextLink = GetNextNode (&BuiltinKext->
Dependencies, KextLink);
622 IN CONST CHAR8 *Identifier,
628 PatchedKext = AllocateZeroPool (
sizeof (*PatchedKext));
629 if (PatchedKext == NULL) {
630 return EFI_OUT_OF_RESOURCES;
634 PatchedKext->
Identifier = AllocateCopyPool (AsciiStrSize (Identifier), Identifier);
636 FreePool (PatchedKext);
637 return EFI_OUT_OF_RESOURCES;
640 InitializeListHead (&PatchedKext->
Patches);
642 InsertTailList (&Context->PatchedKexts, &PatchedKext->
Link);
652 IN CONST CHAR8 *Identifier,
673 if (PatchedKext == NULL) {
675 if (EFI_ERROR (Status)) {
683 KextPatch = AllocateZeroPool (
sizeof (*KextPatch));
684 if (KextPatch == NULL) {
685 return EFI_OUT_OF_RESOURCES;
700 InsertTailList (&PatchedKext->
Patches, &KextPatch->
Link);
708 IN CONST CHAR16 *FileName,
709 IN EFI_FILE_PROTOCOL *ExtensionsDir,
715 ASSERT (FileName != NULL);
716 ASSERT (ExtensionsDir != NULL);
718 ZeroMem (Context,
sizeof (*Context));
720 Context->ExtensionsDir = ExtensionsDir;
721 Context->ExtensionsDirFileName = FileName;
723 Context->Is32Bit = Is32Bit;
725 InitializeListHead (&Context->InjectedKexts);
726 InitializeListHead (&Context->InjectedDependencies);
727 InitializeListHead (&Context->PatchedKexts);
728 InitializeListHead (&Context->BuiltInKexts);
742 LIST_ENTRY *KextLink;
743 LIST_ENTRY *PatchLink;
747 while (!IsListEmpty (&Context->InjectedKexts)) {
748 KextLink = GetFirstNode (&Context->InjectedKexts);
750 RemoveEntryList (KextLink);
764 FreePool (CachelessKext);
767 while (!IsListEmpty (&Context->PatchedKexts)) {
768 KextLink = GetFirstNode (&Context->PatchedKexts);
770 RemoveEntryList (KextLink);
772 while (!IsListEmpty (&PatchedKext->
Patches)) {
773 PatchLink = GetFirstNode (&PatchedKext->
Patches);
775 RemoveEntryList (PatchLink);
777 FreePool (KextPatch);
780 FreePool (PatchedKext);
783 while (!IsListEmpty (&Context->BuiltInKexts)) {
784 KextLink = GetFirstNode (&Context->BuiltInKexts);
786 RemoveEntryList (KextLink);
800 FreePool (BuiltinKext);
803 ZeroMem (Context,
sizeof (*Context));
809 IN CONST CHAR8 *InfoPlist,
810 IN UINT32 InfoPlistSize,
811 IN UINT8 *Executable OPTIONAL,
812 IN UINT32 ExecutableSize OPTIONAL,
825 CONST CHAR8 *TmpKeyValue;
828 CONST CHAR8 *BundleVerStr;
832 BOOLEAN PlistHasChanges;
834 UINT32 NewPlistDataSize;
837 ASSERT (InfoPlist != NULL);
838 ASSERT (InfoPlistSize > 0);
841 PlistHasChanges = FALSE;
843 NewKext = AllocateZeroPool (
sizeof (*NewKext));
844 if (NewKext == NULL) {
845 return EFI_OUT_OF_RESOURCES;
849 NewKext->
PlistData = AllocateCopyPool (InfoPlistSize, InfoPlist);
852 return EFI_OUT_OF_RESOURCES;
860 TmpInfoPlist = AllocateCopyPool (InfoPlistSize, InfoPlist);
861 if (TmpInfoPlist == NULL) {
864 return EFI_OUT_OF_RESOURCES;
868 if (InfoPlistDocument == NULL) {
869 FreePool (TmpInfoPlist);
872 return EFI_INVALID_PARAMETER;
876 if (InfoPlistRoot == NULL) {
878 FreePool (TmpInfoPlist);
881 return EFI_INVALID_PARAMETER;
887 InfoPlistLibraries = NULL;
889 for (FieldIndex = 0; FieldIndex < FieldCount; ++FieldIndex) {
891 if (TmpKeyValue == NULL) {
902 if (Executable == NULL) {
913 FreePool (TmpInfoPlist);
916 return EFI_INVALID_PARAMETER;
924 PlistHasChanges = TRUE;
929 if (!Context->Is32Bit && (InfoPlistLibraries64 == NULL)) {
931 if (InfoPlistLibraries == NULL) {
933 FreePool (TmpInfoPlist);
936 return EFI_INVALID_PARAMETER;
941 if (InfoPlistLibraries64 == NULL) {
943 FreePool (TmpInfoPlist);
946 return EFI_INVALID_PARAMETER;
949 if (!Context->Is32Bit) {
950 InfoPlistLibraries = InfoPlistLibraries64;
957 FreePool (TmpInfoPlist);
960 return EFI_INVALID_PARAMETER;
971 if (InfoPlistLibraries != NULL) {
973 if (EFI_ERROR (Status)) {
975 FreePool (TmpInfoPlist);
992 FreePool (TmpInfoPlist);
999 return EFI_OUT_OF_RESOURCES;
1002 PlistHasChanges = TRUE;
1005 if (PlistHasChanges) {
1006 NewPlistData =
XmlDocumentExport (InfoPlistDocument, &NewPlistDataSize, 0, TRUE);
1007 if (NewPlistData == NULL) {
1009 FreePool (TmpInfoPlist);
1016 return EFI_OUT_OF_RESOURCES;
1025 FreePool (TmpInfoPlist);
1027 if (Executable != NULL) {
1028 ASSERT (ExecutableSize > 0);
1043 return EFI_INVALID_PARAMETER;
1046 NewKext->
BinaryData = AllocateCopyPool (ExecutableSize, Executable);
1054 return EFI_OUT_OF_RESOURCES;
1060 InsertTailList (&Context->InjectedKexts, &NewKext->
Link);
1067 IN CONST CHAR8 *Identifier
1070 ASSERT (Context != NULL);
1071 ASSERT (Identifier != NULL);
1079 IN CONST CHAR8 *Identifier,
1083 ASSERT (Context != NULL);
1084 ASSERT (Identifier != NULL);
1096 ASSERT (Context != NULL);
1104 IN CONST CHAR8 *Identifier,
1115 if (PatchedKext == NULL) {
1117 if (EFI_ERROR (Status)) {
1122 PatchedKext->
Block = TRUE;
1130 OUT EFI_FILE_PROTOCOL **File
1134 EFI_FILE_PROTOCOL *ExtensionsDirOverlay;
1137 LIST_ENTRY *KextLink;
1138 EFI_FILE_INFO *DirectoryEntry;
1139 EFI_FILE_PROTOCOL *NewFile;
1140 EFI_TIME ModificationTime;
1141 UINT32 FileNameIndex;
1143 ASSERT (Context != NULL);
1150 if (EFI_ERROR (Status)) {
1151 ZeroMem (&ModificationTime,
sizeof (ModificationTime));
1155 if (EFI_ERROR (Status)) {
1163 KextLink = GetFirstNode (&Context->InjectedKexts);
1164 while (!IsNull (&Context->InjectedKexts, KextLink)) {
1171 if (FileNameIndex == MAX_UINT32) {
1172 return EFI_DEVICE_ERROR;
1177 Status = Context->ExtensionsDir->Open (Context->ExtensionsDir, &NewFile, Kext->
BundleFileName, EFI_FILE_MODE_READ, 0);
1178 if (!EFI_ERROR (Status)) {
1179 NewFile->Close (NewFile);
1181 }
while (!EFI_ERROR (Status));
1184 if (DirectoryEntry == NULL) {
1186 return EFI_OUT_OF_RESOURCES;
1194 DirectoryEntry->Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;
1195 DirectoryEntry->FileSize = SIZE_OF_EFI_FILE_INFO +
L_STR_SIZE (L
"Contents");
1196 DirectoryEntry->PhysicalSize = DirectoryEntry->FileSize;
1200 KextLink = GetNextNode (&Context->InjectedKexts, KextLink);
1206 *File = ExtensionsDirOverlay;
1213 IN CONST CHAR16 *FileName,
1214 OUT EFI_FILE_PROTOCOL **File
1218 EFI_FILE_PROTOCOL *VirtualFileHandle;
1219 CHAR16 *RealFileName;
1224 LIST_ENTRY *KextLink;
1226 BOOLEAN IsBinaryKext;
1228 CHAR16 *KextExtension;
1230 CHAR16 *BundleBinaryPath;
1231 UINTN BundleBinaryPathSize;
1234 EFI_FILE_INFO *ContentsInfo;
1235 EFI_FILE_INFO *ContentsMacOs;
1236 UINTN ContentsInfoEntrySize;
1237 UINTN ContentsMacOsEntrySize;
1239 ASSERT (Context != NULL);
1240 ASSERT (FileName != NULL);
1246 BundleName = StrStr (FileName, L
"Oc");
1247 if (BundleName == NULL) {
1248 return EFI_NOT_FOUND;
1251 KextExtension = StrStr (BundleName, L
".kext");
1252 if (KextExtension == NULL) {
1253 return EFI_NOT_FOUND;
1256 BundlePath = KextExtension +
L_STR_LEN (L
".kext");
1257 BundleLength = BundlePath - BundleName;
1262 KextLink = GetFirstNode (&Context->InjectedKexts);
1263 while (!IsNull (&Context->InjectedKexts, KextLink)) {
1265 if (StrnCmp (BundleName, Kext->
BundleFileName, BundleLength) == 0) {
1271 if (StrCmp (BundlePath, L
"\\Contents") == 0) {
1276 if (EFI_ERROR (Status)) {
1283 ContentsInfoEntrySize = SIZE_OF_EFI_FILE_INFO +
L_STR_SIZE (L
"Info.plist");
1284 ContentsInfo = AllocateZeroPool (ContentsInfoEntrySize);
1285 if (ContentsInfo == NULL) {
1287 return EFI_OUT_OF_RESOURCES;
1290 ContentsInfo->Size = ContentsInfoEntrySize;
1292 ContentsInfo->Attribute = EFI_FILE_READ_ONLY;
1293 ContentsInfo->PhysicalSize = ContentsInfo->FileSize = Kext->
PlistDataSize;
1300 ContentsMacOsEntrySize = SIZE_OF_EFI_FILE_INFO +
L_STR_SIZE (L
"MacOS");
1301 ContentsMacOs = AllocateZeroPool (ContentsMacOsEntrySize);
1302 if (ContentsMacOs == NULL) {
1303 FreePool (ContentsInfo);
1305 return EFI_OUT_OF_RESOURCES;
1308 ContentsMacOs->Size = ContentsMacOsEntrySize;
1310 ContentsMacOs->Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;
1311 if (BaseOverflowAddU64 (SIZE_OF_EFI_FILE_INFO, StrSize (Kext->
BinaryFileName), &ContentsMacOs->FileSize)) {
1312 FreePool (ContentsInfo);
1314 return EFI_INVALID_PARAMETER;
1317 ContentsMacOs->PhysicalSize = ContentsMacOs->FileSize;
1324 if (StrCmp (BundlePath, L
"\\Contents\\Info.plist") == 0) {
1325 RealFileName = L
"Info.plist";
1329 return EFI_OUT_OF_RESOURCES;
1336 }
else if (IsBinaryKext) {
1337 if (BaseOverflowAddUN (
L_STR_SIZE (L
"\\Contents\\MacOS\\"), StrSize (Kext->
BinaryFileName), &BundleBinaryPathSize)) {
1338 return EFI_OUT_OF_RESOURCES;
1341 BundleBinaryPath = AllocateZeroPool (BundleBinaryPathSize);
1342 if (BundleBinaryPath == NULL) {
1343 return EFI_OUT_OF_RESOURCES;
1346 StrCatS (BundleBinaryPath, BundleBinaryPathSize /
sizeof (CHAR16), L
"\\Contents\\MacOS\\");
1347 StrCatS (BundleBinaryPath, BundleBinaryPathSize /
sizeof (CHAR16), Kext->
BinaryFileName);
1349 if (StrCmp (BundlePath, BundleBinaryPath) == 0) {
1350 FreePool (BundleBinaryPath);
1356 return EFI_OUT_OF_RESOURCES;
1359 FreePool (BundleBinaryPath);
1360 return EFI_NOT_FOUND;
1363 return EFI_NOT_FOUND;
1370 if (EFI_ERROR (Status)) {
1372 return EFI_OUT_OF_RESOURCES;
1379 *File = VirtualFileHandle;
1383 KextLink = GetNextNode (&Context->InjectedKexts, KextLink);
1386 return EFI_NOT_FOUND;
1392 IN CONST CHAR16 *FileName,
1393 IN EFI_FILE_PROTOCOL *File,
1394 OUT EFI_FILE_PROTOCOL **VirtualFile
1398 EFI_TIME ModificationTime;
1403 LIST_ENTRY *KextLink;
1412 CONST CHAR8 *TmpKeyValue;
1417 CHAR8 *NewPlistData;
1418 UINT32 NewPlistDataSize;
1420 ASSERT (Context != NULL);
1421 ASSERT (FileName != NULL);
1423 ASSERT (VirtualFile != NULL);
1428 if (!Context->BuiltInKextsValid) {
1429 DEBUG ((DEBUG_INFO,
"OCAK: Built-in kext cache is not yet built, building...\n"));
1434 Status =
ScanExtensions (Context, Context->ExtensionsDir, Context->ExtensionsDirFileName, TRUE);
1435 if (EFI_ERROR (Status)) {
1442 KextLink = GetFirstNode (&Context->PatchedKexts);
1443 while (!IsNull (&Context->PatchedKexts, KextLink)) {
1447 if (BuiltinKext == NULL) {
1451 DEBUG ((DEBUG_WARN,
"OCAK: Attempted to patch non-existent kext %a\n", PatchedKext->
Identifier));
1455 if (EFI_ERROR (Status)) {
1460 KextLink = GetNextNode (&Context->PatchedKexts, KextLink);
1466 KextLink = GetFirstNode (&Context->InjectedDependencies);
1467 while (!IsNull (&Context->InjectedDependencies, KextLink)) {
1471 if (EFI_ERROR (Status)) {
1475 KextLink = GetNextNode (&Context->InjectedDependencies, KextLink);
1478 Context->BuiltInKextsValid = TRUE;
1479 DEBUG ((DEBUG_INFO,
"OCAK: Built-in kext cache successfully built\n"));
1488 DEBUG ((DEBUG_INFO,
"OCAK: Processing plist patches for %s\n", FileName));
1494 if (EFI_ERROR (Status)) {
1499 if (InfoPlistDocument == NULL) {
1501 return EFI_INVALID_PARAMETER;
1505 if (InfoPlistRoot == NULL) {
1508 return EFI_INVALID_PARAMETER;
1517 for (FieldIndex = 0; FieldIndex < FieldCount; ++FieldIndex) {
1519 if (TmpKeyValue == NULL) {
1534 return EFI_OUT_OF_RESOURCES;
1541 NewPlistData =
XmlDocumentExport (InfoPlistDocument, &NewPlistDataSize, 0, TRUE);
1542 if (NewPlistData == NULL) {
1545 return EFI_OUT_OF_RESOURCES;
1555 if (EFI_ERROR (Status)) {
1556 ZeroMem (&ModificationTime,
sizeof (ModificationTime));
1560 if (EFI_ERROR (Status)) {
1561 *VirtualFile = NULL;
1562 FreePool (NewPlistData);
1572 if ((BuiltinKext != NULL) && BuiltinKext->
PatchKext) {
1573 DEBUG ((DEBUG_INFO,
"OCAK: Processing binary patches for %s\n", FileName));
1576 if (PatchedKext == NULL) {
1577 return EFI_INVALID_PARAMETER;
1581 if (EFI_ERROR (Status)) {
1586 if (EFI_ERROR (Status)) {
1594 KextLink = GetFirstNode (&PatchedKext->
Patches);
1595 while (!IsNull (&PatchedKext->
Patches, KextLink)) {
1601 EFI_ERROR (Status) ? DEBUG_WARN : DEBUG_INFO,
1602 "OCAK: Cacheless kernel quirk result for %a (%u) - %r\n",
1610 EFI_ERROR (Status) ? DEBUG_WARN : DEBUG_INFO,
1611 "OCAK: Cacheless patcher result for %a (%a) - %r\n",
1618 KextLink = GetNextNode (&PatchedKext->
Patches, KextLink);
1624 if (PatchedKext->
Block) {
1627 EFI_ERROR (Status) ? DEBUG_WARN : DEBUG_INFO,
1628 "OCAK: Cacheless blocker result for %a - %r\n",
1638 if (EFI_ERROR (Status)) {
1639 ZeroMem (&ModificationTime,
sizeof (ModificationTime));
1643 if (EFI_ERROR (Status)) {
1644 *VirtualFile = NULL;
1655 *VirtualFile = NULL;
STATIC EFI_STATUS AddKextDependencies(IN OUT LIST_ENTRY *Dependencies, IN XML_NODE *InfoPlistLibraries)
VOID CachelessContextFree(IN OUT CACHELESS_CONTEXT *Context)
STATIC BUILTIN_KEXT * LookupBuiltinKextForPlistPath(IN OUT CACHELESS_CONTEXT *Context, IN CONST CHAR16 *PlistPath)
EFI_STATUS CachelessContextHookBuiltin(IN OUT CACHELESS_CONTEXT *Context, IN CONST CHAR16 *FileName, IN EFI_FILE_PROTOCOL *File, OUT EFI_FILE_PROTOCOL **VirtualFile)
EFI_STATUS CachelessContextPerformInject(IN OUT CACHELESS_CONTEXT *Context, IN CONST CHAR16 *FileName, OUT EFI_FILE_PROTOCOL **File)
STATIC BUILTIN_KEXT * LookupBuiltinKextForIdentifier(IN OUT CACHELESS_CONTEXT *Context, IN CONST CHAR8 *Identifier)
STATIC PATCHED_KEXT * LookupPatchedKextForIdentifier(IN OUT CACHELESS_CONTEXT *Context, IN CONST CHAR8 *Identifier)
STATIC EFI_STATUS ScanExtensions(IN OUT CACHELESS_CONTEXT *Context, IN EFI_FILE_PROTOCOL *File, IN CONST CHAR16 *FilePath, IN BOOLEAN ReadPlugins)
EFI_STATUS CachelessContextInit(IN OUT CACHELESS_CONTEXT *Context, IN CONST CHAR16 *FileName, IN EFI_FILE_PROTOCOL *ExtensionsDir, IN UINT32 KernelVersion, IN BOOLEAN Is32Bit)
EFI_STATUS CachelessContextAddQuirk(IN OUT CACHELESS_CONTEXT *Context, IN KERNEL_QUIRK_NAME Quirk)
EFI_STATUS CachelessContextAddKext(IN OUT CACHELESS_CONTEXT *Context, IN CONST CHAR8 *InfoPlist, IN UINT32 InfoPlistSize, IN UINT8 *Executable OPTIONAL, IN UINT32 ExecutableSize OPTIONAL, OUT CHAR8 BundleVersion[MAX_INFO_BUNDLE_VERSION_KEY_SIZE] OPTIONAL)
EFI_STATUS CachelessContextForceKext(IN OUT CACHELESS_CONTEXT *Context, IN CONST CHAR8 *Identifier)
EFI_STATUS CachelessContextOverlayExtensionsDir(IN OUT CACHELESS_CONTEXT *Context, OUT EFI_FILE_PROTOCOL **File)
STATIC EFI_STATUS InternalAddKextPatch(IN OUT CACHELESS_CONTEXT *Context, IN CONST CHAR8 *Identifier, IN PATCHER_GENERIC_PATCH *Patch OPTIONAL, IN KERNEL_QUIRK_NAME QuirkName)
STATIC EFI_STATUS InternalAddPatchedKext(IN OUT CACHELESS_CONTEXT *Context, IN CONST CHAR8 *Identifier, OUT PATCHED_KEXT **Kext)
STATIC EFI_STATUS ScanDependencies(IN OUT CACHELESS_CONTEXT *Context, IN CHAR8 *Identifier)
STATIC EFI_STATUS AddKextDependency(IN OUT LIST_ENTRY *Dependencies, IN CONST CHAR8 *Identifier)
EFI_STATUS CachelessContextAddPatch(IN OUT CACHELESS_CONTEXT *Context, IN CONST CHAR8 *Identifier, IN PATCHER_GENERIC_PATCH *Patch)
EFI_STATUS CachelessContextBlock(IN OUT CACHELESS_CONTEXT *Context, IN CONST CHAR8 *Identifier, IN BOOLEAN Exclude)
STATIC BUILTIN_KEXT * LookupBuiltinKextForBinaryPath(IN OUT CACHELESS_CONTEXT *Context, IN CONST CHAR16 *BinaryPath)
STATIC VOID FreeBuiltInKext(IN BUILTIN_KEXT *BuiltinKext)
#define GET_DEPEND_KEXT_FROM_LINK(This)
#define PATCHED_KEXT_SIGNATURE
#define KEXT_BUNDLE_INFO_SIZE
#define GET_PATCHED_KEXT_FROM_LINK(This)
#define KEXT_BUNDLE_NAME_SIZE
@ KEXT_OSBUNDLE_REQUIRED_VALID
@ KEXT_OSBUNDLE_REQUIRED_NONE
@ KEXT_OSBUNDLE_REQUIRED_INVALID
#define KEXT_PATCH_SIGNATURE
#define GET_CACHELESS_KEXT_FROM_LINK(This)
#define GET_BUILTIN_KEXT_FROM_LINK(This)
#define DEPEND_KEXT_SIGNATURE
#define GET_KEXT_PATCH_FROM_LINK(This)
#define BUILTIN_KEXT_SIGNATURE
#define CACHELESS_KEXT_SIGNATURE
KERNEL_QUIRK gKernelQuirks[]
STATIC UINT32 KernelVersion
BOOLEAN InternalParseKextBinary(IN OUT UINT8 **Buffer, IN OUT UINT32 *BufferSize, IN BOOLEAN Is32Bit)
DMG_FILEPATH_DEVICE_PATH FilePath
EFI_STATUS PatcherBlockKext(IN OUT PATCHER_CONTEXT *Context)
#define INFO_BUNDLE_LIBRARIES_64_KEY
EFI_STATUS KernelApplyQuirk(IN KERNEL_QUIRK_NAME Name, IN OUT PATCHER_CONTEXT *Patcher OPTIONAL, IN UINT32 KernelVersion)
#define INFO_BUNDLE_OS_BUNDLE_REQUIRED_KEY
#define MAX_INFO_BUNDLE_VERSION_KEY_SIZE
#define OS_BUNDLE_REQUIRED_SAFE_BOOT
#define INFO_BUNDLE_EXECUTABLE_KEY
EFI_STATUS PatcherApplyGenericPatch(IN OUT PATCHER_CONTEXT *Context, IN PATCHER_GENERIC_PATCH *Patch)
#define INFO_BUNDLE_VERSION_KEY
#define INFO_BUNDLE_LIBRARIES_KEY
EFI_STATUS PatcherInitContextFromBuffer(IN OUT PATCHER_CONTEXT *Context, IN OUT UINT8 *Buffer, IN UINT32 BufferSize, IN BOOLEAN Use32Bit)
#define INFO_BUNDLE_IDENTIFIER_KEY
#define OS_BUNDLE_REQUIRED_ROOT
EFI_STATUS OcGetFileModificationTime(IN EFI_FILE_PROTOCOL *File, OUT EFI_TIME *Time)
EFI_STATUS OcAllocateCopyFileData(IN EFI_FILE_PROTOCOL *File, OUT UINT8 **Buffer, OUT UINT32 *BufferSize)
#define L_STR_LEN(String)
#define L_STR_SIZE(String)
CHAR16 * AsciiStrCopyToUnicode(IN CONST CHAR8 *String, IN UINTN Length)
EFI_STATUS EFIAPI OcUnicodeSafeSPrint(OUT CHAR16 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR16 *FormatString,...)
BOOLEAN EFIAPI OcUnicodeEndsWith(IN CONST CHAR16 *String, IN CONST CHAR16 *SearchString, IN BOOLEAN CaseInsensitiveMatch)
OC_TYPING_BUFFER_ENTRY Buffer[OC_TYPING_BUFFER_SIZE]
EFI_STATUS VirtualDirAddEntry(IN EFI_FILE_PROTOCOL *This, IN EFI_FILE_INFO *FileInfo)
EFI_STATUS VirtualDirCreateOverlayFileNameCopy(IN CONST CHAR16 *FileName, IN CONST EFI_TIME *ModificationTime OPTIONAL, IN EFI_FILE_PROTOCOL *UnderlyingFile OPTIONAL, OUT EFI_FILE_PROTOCOL **File)
VOID VirtualDirFree(IN EFI_FILE_PROTOCOL *This)
EFI_STATUS CreateVirtualFileFileNameCopy(IN CONST CHAR16 *FileName, IN VOID *FileBuffer, IN UINT64 FileSize, IN CONST EFI_TIME *ModificationTime OPTIONAL, OUT EFI_FILE_PROTOCOL **File)
XML_DOCUMENT * XmlDocumentParse(IN OUT CHAR8 *Buffer, IN UINT32 Length, IN BOOLEAN WithRefs)
CONST CHAR8 * PlistKeyValue(IN XML_NODE *Node OPTIONAL)
CHAR8 * XmlDocumentExport(IN CONST XML_DOCUMENT *Document, OUT UINT32 *Length OPTIONAL, IN UINT32 Skip, IN BOOLEAN PrependPlistInfo)
CONST CHAR8 * XmlNodeContent(IN CONST XML_NODE *Node)
UINT32 PlistDictChildren(IN CONST XML_NODE *Node)
XML_NODE * PlistNodeCast(IN XML_NODE *Node OPTIONAL, IN PLIST_NODE_TYPE Type)
XML_NODE * XmlNodeAppend(IN OUT XML_NODE *Node, IN CONST CHAR8 *Name, IN CONST CHAR8 *Attributes OPTIONAL, IN CONST CHAR8 *Content OPTIONAL)
XML_NODE * PlistDocumentRoot(IN CONST XML_DOCUMENT *Document)
VOID XmlDocumentFree(IN OUT XML_DOCUMENT *Document)
VOID XmlNodeChangeContent(IN OUT XML_NODE *Node, IN CONST CHAR8 *Content)
XML_NODE * PlistDictChild(IN CONST XML_NODE *Node, IN UINT32 Child, OUT XML_NODE **Value OPTIONAL)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
UINT8 OSBundleRequiredValue
BOOLEAN PatchValidOSBundleRequired
CHAR16 BundleFileName[KEXT_BUNDLE_NAME_LEN+1]
PATCHER_GENERIC_PATCH Patch
KERNEL_QUIRK_NAME QuirkName