OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
FileProtocol.c
Go to the documentation of this file.
1
6#include <Uefi.h>
7#include <Guid/FileInfo.h>
9#include <Protocol/SimpleFileSystem.h>
10
11#include <Library/BaseLib.h>
12#include <Library/BaseMemoryLib.h>
13#include <Library/DebugLib.h>
14#include <Library/MemoryAllocationLib.h>
15#include <Library/OcFileLib.h>
16#include <Library/UefiBootServicesTableLib.h>
17
18// Define EPOCH (1970-JANUARY-01) in the Julian Date representation
19#define EPOCH_JULIAN_DATE 2440588
20
21// Seconds per unit
22#define SEC_PER_MIN ((UINTN) 60)
23#define SEC_PER_HOUR ((UINTN) 3600)
24#define SEC_PER_DAY ((UINTN) 86400)
25#define SEC_PER_MONTH ((UINTN) 2,592,000)
26#define SEC_PER_YEAR ((UINTN) 31,536,000)
27
28STATIC
29UINT32
31 IN EFI_TIME *Time
32 )
33{
34 UINT8 a;
35 UINT32 y;
36 UINT8 m;
37 UINT32 JulianDate; // Absolute Julian Date representation of the supplied Time
38 UINT32 EpochDays; // Number of days elapsed since EPOCH_JULIAN_DAY
39
40 a = (14 - Time->Month) / 12;
41 y = Time->Year + 4800 - a;
42 m = Time->Month + (12*a) - 3;
43
44 JulianDate = Time->Day + ((153*m + 2)/5) + (365*y) + (y/4) - (y/100) + (y/400) - 32045;
45
46 ASSERT (JulianDate >= EPOCH_JULIAN_DATE);
47 EpochDays = JulianDate - EPOCH_JULIAN_DATE;
48
49 return EpochDays;
50}
51
52STATIC
53UINT32
55 IN EFI_TIME *Time
56 )
57{
58 UINT32 EpochDays; // Number of days elapsed since EPOCH_JULIAN_DAY
59 UINT32 EpochSeconds;
60
61 EpochDays = EfiGetEpochDays (Time);
62
63 EpochSeconds = (EpochDays * SEC_PER_DAY) + (Time->Hour * SEC_PER_HOUR) + (Time->Minute * SEC_PER_MIN) + Time->Second;
64
65 return EpochSeconds;
66}
67
68EFI_STATUS
70 IN EFI_FILE_PROTOCOL *File,
71 IN UINT32 Position,
72 IN UINT32 Size,
73 OUT UINT8 *Buffer
74 )
75{
76 EFI_STATUS Status;
77 UINTN ReadSize;
78 UINTN RequestedSize;
79
80 while (Size > 0) {
81 Status = File->SetPosition (File, Position);
82 if (EFI_ERROR (Status)) {
83 return Status;
84 }
85
86 //
87 // We are required to read in 1 MB portions, because otherwise some
88 // systems namely MacBook7,1 will not read file data from APFS volumes
89 // but will pretend they did. Repeoduced with BootKernelExtensions.kc.
90 //
91 ReadSize = RequestedSize = MIN (Size, BASE_1MB);
92 Status = File->Read (File, &ReadSize, Buffer);
93 if (EFI_ERROR (Status)) {
94 File->SetPosition (File, 0);
95 return Status;
96 }
97
98 if (ReadSize != RequestedSize) {
99 File->SetPosition (File, 0);
100 return EFI_BAD_BUFFER_SIZE;
101 }
102
103 Position += (UINT32)ReadSize;
104 Buffer += ReadSize;
105 Size -= (UINT32)ReadSize;
106 }
107
108 File->SetPosition (File, 0);
109
110 return EFI_SUCCESS;
111}
112
113EFI_STATUS
115 IN EFI_FILE_PROTOCOL *File,
116 OUT UINT32 *Size
117 )
118{
119 EFI_STATUS Status;
120 UINT64 Position;
121 EFI_FILE_INFO *FileInfo;
122
123 Status = File->SetPosition (File, 0xFFFFFFFFFFFFFFFFULL);
124 if (EFI_ERROR (Status)) {
125 //
126 // Some drivers, like EfiFs, return EFI_UNSUPPORTED when trying to seek
127 // past the file size. Use slow method via attributes for them.
128 //
129 FileInfo = OcGetFileInfo (File, &gEfiFileInfoGuid, sizeof (*FileInfo), NULL);
130 if (FileInfo != NULL) {
131 if ((UINT32)FileInfo->FileSize == FileInfo->FileSize) {
132 *Size = (UINT32)FileInfo->FileSize;
133 Status = EFI_SUCCESS;
134 }
135
136 FreePool (FileInfo);
137 }
138
139 return Status;
140 }
141
142 Status = File->GetPosition (File, &Position);
143 File->SetPosition (File, 0);
144 if (EFI_ERROR (Status)) {
145 return Status;
146 }
147
148 if ((UINT32)Position != Position) {
149 return EFI_OUT_OF_RESOURCES;
150 }
151
152 *Size = (UINT32)Position;
153
154 return EFI_SUCCESS;
155}
156
157EFI_STATUS
159 IN EFI_FILE_PROTOCOL *File,
160 OUT EFI_TIME *Time
161 )
162{
163 EFI_FILE_INFO *FileInfo;
164
165 FileInfo = OcGetFileInfo (File, &gEfiFileInfoGuid, 0, NULL);
166 if (FileInfo == NULL) {
167 return EFI_INVALID_PARAMETER;
168 }
169
170 CopyMem (Time, &FileInfo->ModificationTime, sizeof (*Time));
171 FreePool (FileInfo);
172
173 return EFI_SUCCESS;
174}
175
176BOOLEAN
178 IN EFI_FILE_PROTOCOL *Fs
179 )
180{
181 EFI_STATUS Status;
182 EFI_FILE_PROTOCOL *File;
183
184 //
185 // We cannot test if the file system is writeable without attempting to create some file.
186 //
187 Status = OcSafeFileOpen (
188 Fs,
189 &File,
190 L"octest.fil",
191 EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE,
192 0
193 );
194 if (EFI_ERROR (Status)) {
195 return FALSE;
196 }
197
198 //
199 // Delete the temporary file and report the found file system.
200 //
201 Fs->Delete (File);
202 return TRUE;
203}
204
205EFI_STATUS
207 IN OUT EFI_FILE_PROTOCOL **WritableFs
208 )
209{
210 EFI_HANDLE *HandleBuffer;
211 UINTN HandleCount;
212 UINTN Index;
213 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs;
214 EFI_FILE_PROTOCOL *Fs;
215
216 //
217 // Locate all the simple file system devices in the system.
218 //
219 EFI_STATUS Status = gBS->LocateHandleBuffer (
220 ByProtocol,
222 NULL,
223 &HandleCount,
224 &HandleBuffer
225 );
226
227 if (EFI_ERROR (Status)) {
228 return Status;
229 }
230
231 for (Index = 0; Index < HandleCount; ++Index) {
232 Status = gBS->HandleProtocol (
233 HandleBuffer[Index],
235 (VOID **)&SimpleFs
236 );
237
238 if (EFI_ERROR (Status)) {
239 DEBUG ((
240 DEBUG_VERBOSE,
241 "OCFS: FindWritableFileSystem gBS->HandleProtocol[%u] returned %r\n",
242 (UINT32)Index,
243 Status
244 ));
245 continue;
246 }
247
248 Status = SimpleFs->OpenVolume (SimpleFs, &Fs);
249 if (EFI_ERROR (Status)) {
250 DEBUG ((
251 DEBUG_VERBOSE,
252 "OCFS: FindWritableFileSystem SimpleFs->OpenVolume[%u] returned %r\n",
253 (UINT32)Index,
254 Status
255 ));
256 continue;
257 }
258
259 if (OcIsWritableFileSystem (Fs)) {
260 FreePool (HandleBuffer);
261 *WritableFs = Fs;
262 return EFI_SUCCESS;
263 }
264
265 DEBUG ((
266 DEBUG_VERBOSE,
267 "OCFS: FindWritableFileSystem Fs->Open[%u] failed\n",
268 (UINT32)Index
269 ));
270 }
271
272 FreePool (HandleBuffer);
273 return EFI_NOT_FOUND;
274}
275
276EFI_STATUS
278 OUT EFI_FILE_PROTOCOL **FileSystem
279 )
280{
281 EFI_STATUS Status;
282 OC_BOOTSTRAP_PROTOCOL *Bootstrap;
283 EFI_HANDLE PreferedHandle;
284
285 PreferedHandle = NULL;
286
287 Status = gBS->LocateProtocol (
289 NULL,
290 (VOID **)&Bootstrap
291 );
292 if (!EFI_ERROR (Status) && (Bootstrap->Revision == OC_BOOTSTRAP_PROTOCOL_REVISION)) {
293 PreferedHandle = Bootstrap->GetLoadHandle (Bootstrap);
294 }
295
296 if (PreferedHandle != NULL) {
297 *FileSystem = OcLocateRootVolume (PreferedHandle, NULL);
298 } else {
299 *FileSystem = NULL;
300 }
301
302 DEBUG ((DEBUG_INFO, "OCFS: Preferred handle is %p found fs %p\n", PreferedHandle, *FileSystem));
303
304 if (*FileSystem == NULL) {
305 return OcFindWritableFileSystem (FileSystem);
306 }
307
308 return EFI_SUCCESS;
309}
310
311EFI_STATUS
313 IN EFI_FILE_PROTOCOL *WritableFs OPTIONAL,
314 IN CONST CHAR16 *FileName,
315 IN CONST VOID *Buffer,
316 IN UINT32 Size
317 )
318{
319 EFI_STATUS Status;
320 EFI_FILE_PROTOCOL *Fs;
321 EFI_FILE_PROTOCOL *File;
322 UINTN WrittenSize;
323
324 ASSERT (FileName != NULL);
325 ASSERT (Buffer != NULL);
326
327 if (WritableFs == NULL) {
328 Status = OcFindWritableFileSystem (&Fs);
329 if (EFI_ERROR (Status)) {
330 DEBUG ((DEBUG_VERBOSE, "OCFS: WriteFileData can't find writable FS\n"));
331 return Status;
332 }
333 } else {
334 Fs = WritableFs;
335 }
336
337 Status = OcSafeFileOpen (
338 Fs,
339 &File,
340 (CHAR16 *)FileName,
341 EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE,
342 0
343 );
344
345 if (!EFI_ERROR (Status)) {
346 WrittenSize = Size;
347 Status = File->Write (File, &WrittenSize, (VOID *)Buffer);
348 Fs->Close (File);
349
350 if (EFI_ERROR (Status)) {
351 DEBUG ((DEBUG_VERBOSE, "OCFS: WriteFileData file->Write returned %r\n", Status));
352 } else if (WrittenSize != Size) {
353 DEBUG ((
354 DEBUG_VERBOSE,
355 "WriteFileData: File->Write truncated %u to %u\n",
356 Size,
357 (UINT32)WrittenSize
358 ));
359 Status = EFI_BAD_BUFFER_SIZE;
360 }
361 } else {
362 DEBUG ((DEBUG_VERBOSE, "OCFS: WriteFileData Fs->Open of %s returned %r\n", FileName, Status));
363 }
364
365 if (WritableFs == NULL) {
366 Fs->Close (Fs);
367 }
368
369 return Status;
370}
371
372EFI_STATUS
374 IN EFI_FILE_PROTOCOL *File,
375 OUT UINT8 **Buffer,
376 OUT UINT32 *BufferSize
377 )
378{
379 EFI_STATUS Status;
380 UINT8 *FileBuffer;
381 UINT32 ReadSize;
382
383 //
384 // Get full file data.
385 //
386 Status = OcGetFileSize (File, &ReadSize);
387 if (EFI_ERROR (Status)) {
388 return Status;
389 }
390
391 FileBuffer = AllocatePool (ReadSize);
392 if (FileBuffer == NULL) {
393 return EFI_OUT_OF_RESOURCES;
394 }
395
396 Status = OcGetFileData (File, 0, ReadSize, FileBuffer);
397 if (EFI_ERROR (Status)) {
398 FreePool (FileBuffer);
399 return Status;
400 }
401
402 *Buffer = FileBuffer;
403 *BufferSize = ReadSize;
404 return EFI_SUCCESS;
405}
406
407VOID
409 IN OUT DIRECTORY_SEARCH_CONTEXT *Context
410 )
411{
412 ASSERT (Context != NULL);
413
414 ZeroMem (Context, sizeof (*Context));
415}
416
417EFI_STATUS
419 IN EFI_FILE_PROTOCOL *File,
420 IN BOOLEAN IsDirectory
421 )
422{
423 EFI_FILE_INFO *FileInfo;
424
425 //
426 // Ensure this is a directory/file.
427 //
428 FileInfo = OcGetFileInfo (File, &gEfiFileInfoGuid, 0, NULL);
429 if (FileInfo == NULL) {
430 return EFI_INVALID_PARAMETER;
431 }
432
433 if (((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) != IsDirectory) {
434 FreePool (FileInfo);
435 return EFI_INVALID_PARAMETER;
436 }
437
438 FreePool (FileInfo);
439
440 return EFI_SUCCESS;
441}
442
443EFI_STATUS
445 IN OUT DIRECTORY_SEARCH_CONTEXT *Context,
446 IN EFI_FILE_PROTOCOL *Directory,
447 IN CHAR16 *FileNameStartsWith OPTIONAL,
448 OUT EFI_FILE_INFO **FileInfo
449 )
450{
451 EFI_STATUS Status;
452 EFI_FILE_INFO *FileInfoCurrent;
453 EFI_FILE_INFO *FileInfoLatest;
454 UINTN FileInfoSize;
455 UINT32 EpochCurrent;
456 UINTN Index;
457
458 UINTN LatestIndex;
459 UINT32 LatestEpoch;
460
461 ASSERT (Context != NULL);
462 ASSERT (Directory != NULL);
463 ASSERT (FileInfo != NULL);
464
465 LatestIndex = 0;
466 LatestEpoch = 0;
467
468 Status = OcEnsureDirectoryFile (Directory, TRUE);
469 if (EFI_ERROR (Status)) {
470 return Status;
471 }
472
473 //
474 // Allocate two FILE_INFO structures.
475 // The first is used for all entries, and the second is used only for the
476 // latest, and eventually returned to the caller.
477 //
478 FileInfoCurrent = AllocatePool (SIZE_1KB);
479 if (FileInfoCurrent == NULL) {
480 return EFI_OUT_OF_RESOURCES;
481 }
482
483 FileInfoLatest = AllocateZeroPool (SIZE_1KB);
484 if (FileInfoLatest == NULL) {
485 FreePool (FileInfoCurrent);
486 return EFI_OUT_OF_RESOURCES;
487 }
488
489 Directory->SetPosition (Directory, 0);
490 Index = 0;
491
492 do {
493 //
494 // Apple's HFS+ driver does not adhere to the spec and will return zero for
495 // EFI_BUFFER_TOO_SMALL. EFI_FILE_INFO structures larger than 1KB are
496 // unrealistic as the filename is the only variable.
497 //
498 FileInfoSize = SIZE_1KB - sizeof (CHAR16);
499 Status = Directory->Read (Directory, &FileInfoSize, FileInfoCurrent);
500 if (EFI_ERROR (Status)) {
501 Directory->SetPosition (Directory, 0);
502 FreePool (FileInfoCurrent);
503 FreePool (FileInfoLatest);
504 return Status;
505 }
506
507 if (FileInfoSize > 0) {
508 //
509 // Skip any files that do not start with the desired filename.
510 //
511 if (FileNameStartsWith != NULL) {
512 if (StrnCmp (FileInfoCurrent->FileName, FileNameStartsWith, StrLen (FileNameStartsWith)) != 0) {
513 continue;
514 }
515 }
516
517 //
518 // Get time of current entry.
519 // We want to skip any entries that have been returned as "latest" in prior calls.
520 //
521 EpochCurrent = EfiTimeToEpoch (&FileInfoCurrent->ModificationTime);
522 DEBUG ((DEBUG_VERBOSE, "OCFS: Current file %s with time %u\n", FileInfoCurrent->FileName, EpochCurrent));
523
524 //
525 // Skip any entries that are newer than our previously matched entry.
526 //
527 if ((Context->PreviousTime > 0) && (EpochCurrent > Context->PreviousTime)) {
528 DEBUG ((DEBUG_VERBOSE, "OCFS: Skipping file %s due to time %u > %u\n", FileInfoCurrent->FileName, EpochCurrent, Context->PreviousTime));
529 continue;
530 }
531
532 //
533 // Skip any entries that have the same time as our previously
534 // matched entry and were found previously.
535 //
536 // ASSUMPTION: Entries are in the same order each time the directory is iterated.
537 //
538 if (EpochCurrent == Context->PreviousTime) {
539 if (Index <= Context->PreviousIndex) {
540 DEBUG ((DEBUG_VERBOSE, "OCFS: Skipping file %s with due to index %u <= %u\n", FileInfoCurrent->FileName, Index, Context->PreviousIndex));
541 Index++;
542 continue;
543 }
544 } else {
545 //
546 // Reset index counter if the time is different from the last.
547 //
548 Index = 0;
549 }
550
551 //
552 // Store latest entry.
553 //
554 if ((FileInfoLatest->FileName[0] == '\0') || (EpochCurrent > EfiTimeToEpoch (&FileInfoLatest->ModificationTime))) {
555 CopyMem (FileInfoLatest, FileInfoCurrent, FileInfoSize);
556 LatestIndex = Index;
557 LatestEpoch = EfiTimeToEpoch (&FileInfoLatest->ModificationTime);
558
559 DEBUG ((DEBUG_VERBOSE, "OCFS: Stored newest file %s\n", FileInfoCurrent->FileName));
560 }
561 }
562 } while (FileInfoSize > 0);
563
564 Directory->SetPosition (Directory, 0);
565 FreePool (FileInfoCurrent);
566
567 if (FileInfoLatest->FileName[0] == '\0') {
568 FreePool (FileInfoLatest);
569
570 DEBUG ((DEBUG_VERBOSE, "OCFS: No matching files found\n"));
571 return EFI_NOT_FOUND;
572 }
573
574 *FileInfo = FileInfoLatest;
575 Context->PreviousIndex = LatestIndex;
576 Context->PreviousTime = LatestEpoch;
577
578 return EFI_SUCCESS;
579}
580
581//
582// TODO: OcGetNewestFileFromDirectory above and ScanExtensions in CachelessContext.c could be redone using this.
583// TODO: I am unclear exactly what the Apple 32-bit HFS is being described as doing (see also OcGetFileInfo), so
584// have just copied the existing handling.
585//
586EFI_STATUS
588 IN EFI_FILE_HANDLE Directory,
589 IN OC_PROCESS_DIRECTORY_ENTRY ProcessEntry,
590 IN OUT VOID *Context OPTIONAL
591 )
592{
593 EFI_STATUS Status;
594 EFI_STATUS TempStatus;
595 EFI_FILE_INFO *FileInfo;
596 UINTN FileInfoSize;
597
598 ASSERT (Directory != NULL);
599 ASSERT (ProcessEntry != NULL);
600
601 Status = OcEnsureDirectoryFile (Directory, TRUE);
602 if (EFI_ERROR (Status)) {
603 return Status;
604 }
605
606 //
607 // Allocate FILE_INFO structure.
608 //
609 FileInfo = AllocatePool (SIZE_1KB);
610 if (FileInfo == NULL) {
611 return EFI_OUT_OF_RESOURCES;
612 }
613
614 Status = EFI_NOT_FOUND;
615 Directory->SetPosition (Directory, 0);
616
617 do {
618 //
619 // Apple's HFS+ driver does not adhere to the spec and will return zero for
620 // EFI_BUFFER_TOO_SMALL. EFI_FILE_INFO structures larger than 1KB are
621 // unrealistic as the filename is the only variable.
622 //
623 FileInfoSize = SIZE_1KB - sizeof (CHAR16);
624 TempStatus = Directory->Read (Directory, &FileInfoSize, FileInfo);
625 if (EFI_ERROR (TempStatus)) {
626 Status = TempStatus;
627 break;
628 }
629
630 if (FileInfoSize > 0) {
631 TempStatus = ProcessEntry (Directory, FileInfo, FileInfoSize, Context);
632
633 //
634 // Act as if no matching file was found.
635 //
636 if (TempStatus == EFI_NOT_FOUND) {
637 continue;
638 }
639
640 if (EFI_ERROR (TempStatus)) {
641 Status = TempStatus;
642 break;
643 }
644
645 //
646 // At least one file found.
647 //
648 Status = EFI_SUCCESS;
649 }
650 } while (FileInfoSize > 0);
651
652 Directory->SetPosition (Directory, 0);
653 FreePool (FileInfo);
654
655 return Status;
656}
UINT16 y
Definition BmfFile.h:84
EFI_STATUS OcEnsureDirectoryFile(IN EFI_FILE_PROTOCOL *File, IN BOOLEAN IsDirectory)
#define SEC_PER_HOUR
STATIC UINT32 EfiTimeToEpoch(IN EFI_TIME *Time)
EFI_STATUS OcGetFileSize(IN EFI_FILE_PROTOCOL *File, OUT UINT32 *Size)
#define SEC_PER_DAY
EFI_STATUS OcGetFileModificationTime(IN EFI_FILE_PROTOCOL *File, OUT EFI_TIME *Time)
#define EPOCH_JULIAN_DATE
BOOLEAN OcIsWritableFileSystem(IN EFI_FILE_PROTOCOL *Fs)
VOID OcDirectorySeachContextInit(IN OUT DIRECTORY_SEARCH_CONTEXT *Context)
EFI_STATUS OcGetFileData(IN EFI_FILE_PROTOCOL *File, IN UINT32 Position, IN UINT32 Size, OUT UINT8 *Buffer)
#define SEC_PER_MIN
EFI_STATUS OcGetNewestFileFromDirectory(IN OUT DIRECTORY_SEARCH_CONTEXT *Context, IN EFI_FILE_PROTOCOL *Directory, IN CHAR16 *FileNameStartsWith OPTIONAL, OUT EFI_FILE_INFO **FileInfo)
EFI_STATUS OcScanDirectory(IN EFI_FILE_HANDLE Directory, IN OC_PROCESS_DIRECTORY_ENTRY ProcessEntry, IN OUT VOID *Context OPTIONAL)
STATIC UINT32 EfiGetEpochDays(IN EFI_TIME *Time)
EFI_STATUS OcSetFileData(IN EFI_FILE_PROTOCOL *WritableFs OPTIONAL, IN CONST CHAR16 *FileName, IN CONST VOID *Buffer, IN UINT32 Size)
EFI_STATUS OcFindWritableOcFileSystem(OUT EFI_FILE_PROTOCOL **FileSystem)
EFI_STATUS OcAllocateCopyFileData(IN EFI_FILE_PROTOCOL *File, OUT UINT8 **Buffer, OUT UINT32 *BufferSize)
EFI_STATUS OcFindWritableFileSystem(IN OUT EFI_FILE_PROTOCOL **WritableFs)
DMG_SIZE_DEVICE_PATH Size
EFI_BOOT_SERVICES * gBS
#define OC_BOOTSTRAP_PROTOCOL_REVISION
Definition OcBootstrap.h:33
EFI_GUID gOcBootstrapProtocolGuid
VOID * OcGetFileInfo(IN EFI_FILE_PROTOCOL *File, IN EFI_GUID *InformationType, IN UINTN MinFileInfoSize, OUT UINTN *RealFileInfoSize OPTIONAL)
Definition GetFileInfo.c:33
EFI_FILE_PROTOCOL * OcLocateRootVolume(IN EFI_HANDLE DeviceHandle OPTIONAL, IN EFI_DEVICE_PATH_PROTOCOL *FilePath OPTIONAL)
EFI_STATUS OcSafeFileOpen(IN CONST EFI_FILE_PROTOCOL *Directory, OUT EFI_FILE_PROTOCOL **NewHandle, IN CONST CHAR16 *FileName, IN CONST UINT64 OpenMode, IN CONST UINT64 Attributes)
Definition OpenFile.c:29
EFI_STATUS(* OC_PROCESS_DIRECTORY_ENTRY)(EFI_FILE_HANDLE Directory, EFI_FILE_INFO *FileInfo, UINTN FileInfoSize, VOID *Context OPTIONAL)
Definition OcFileLib.h:331
OC_TYPING_BUFFER_ENTRY Buffer[OC_TYPING_BUFFER_SIZE]
Definition OcTypingLib.h:42
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_GUID gEfiFileInfoGuid
EFI_GUID gEfiSimpleFileSystemProtocolGuid
#define ASSERT(x)
Definition coder.h:55
#define MIN(a, b)
Definition deflate.c:1673
OC_GET_LOAD_HANDLE GetLoadHandle
Definition OcBootstrap.h:59