TianoCore EDK2 master
Loading...
Searching...
No Matches
PosixFileSystem.c
1/*++ @file
2 POSIX Pthreads to emulate APs and implement threads
3
4Copyright (c) 2011, Apple Inc. All rights reserved.
5Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
6SPDX-License-Identifier: BSD-2-Clause-Patent
7
8
9**/
10
11#include "Host.h"
12
13#define EMU_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE SIGNATURE_32 ('E', 'P', 'f', 's')
14
15typedef struct {
16 UINTN Signature;
18 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFileSystem;
19 CHAR8 *FilePath;
20 CHAR16 *VolumeLabel;
21 BOOLEAN FileHandlesOpen;
23
24#define EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS(a) \
25 CR (a, \
26 EMU_SIMPLE_FILE_SYSTEM_PRIVATE, \
27 SimpleFileSystem, \
28 EMU_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE \
29 )
30
31#define EMU_EFI_FILE_PRIVATE_SIGNATURE SIGNATURE_32 ('E', 'P', 'f', 'i')
32
33typedef struct {
34 UINTN Signature;
36 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;
37 EFI_FILE_PROTOCOL EfiFile;
38 int fd;
39 DIR *Dir;
40 BOOLEAN IsRootDirectory;
41 BOOLEAN IsDirectoryPath;
42 BOOLEAN IsOpenedByRead;
43 char *FileName;
44 struct dirent *Dirent;
46
47#define EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS(a) \
48 CR (a, \
49 EMU_EFI_FILE_PRIVATE, \
50 EfiFile, \
51 EMU_EFI_FILE_PRIVATE_SIGNATURE \
52 )
53
55PosixFileGetInfo (
57 IN EFI_GUID *InformationType,
58 IN OUT UINTN *BufferSize,
59 OUT VOID *Buffer
60 );
61
63PosixFileSetInfo (
65 IN EFI_GUID *InformationType,
66 IN UINTN BufferSize,
67 IN VOID *Buffer
68 );
69
70EFI_FILE_PROTOCOL gPosixFileProtocol = {
71 EFI_FILE_REVISION,
72 GasketPosixFileOpen,
73 GasketPosixFileCLose,
74 GasketPosixFileDelete,
75 GasketPosixFileRead,
76 GasketPosixFileWrite,
77 GasketPosixFileGetPossition,
78 GasketPosixFileSetPossition,
79 GasketPosixFileGetInfo,
80 GasketPosixFileSetInfo,
81 GasketPosixFileFlush
82};
83
84EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gPosixFileSystemProtocol = {
85 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
86 GasketPosixOpenVolume,
87};
88
105PosixOpenVolume (
108 )
109{
110 EFI_STATUS Status;
112 EMU_EFI_FILE_PRIVATE *PrivateFile;
113
114 Private = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This);
115
116 Status = EFI_OUT_OF_RESOURCES;
117 PrivateFile = malloc (sizeof (EMU_EFI_FILE_PRIVATE));
118 if (PrivateFile == NULL) {
119 goto Done;
120 }
121
122 PrivateFile->FileName = malloc (AsciiStrSize (Private->FilePath));
123 if (PrivateFile->FileName == NULL) {
124 goto Done;
125 }
126
128 PrivateFile->FileName,
129 AsciiStrSize (Private->FilePath),
130 Private->FilePath
131 );
132
133 PrivateFile->Signature = EMU_EFI_FILE_PRIVATE_SIGNATURE;
134 PrivateFile->Thunk = Private->Thunk;
135 PrivateFile->SimpleFileSystem = This;
136 PrivateFile->IsRootDirectory = TRUE;
137 PrivateFile->IsDirectoryPath = TRUE;
138 PrivateFile->IsOpenedByRead = TRUE;
139
140 CopyMem (&PrivateFile->EfiFile, &gPosixFileProtocol, sizeof (EFI_FILE_PROTOCOL));
141
142 PrivateFile->fd = -1;
143 PrivateFile->Dir = NULL;
144 PrivateFile->Dirent = NULL;
145
146 *Root = &PrivateFile->EfiFile;
147
148 PrivateFile->Dir = opendir (PrivateFile->FileName);
149 if (PrivateFile->Dir == NULL) {
150 Status = EFI_ACCESS_DENIED;
151 } else {
152 Status = EFI_SUCCESS;
153 }
154
155Done:
156 if (EFI_ERROR (Status)) {
157 if (PrivateFile != NULL) {
158 if (PrivateFile->FileName != NULL) {
159 free (PrivateFile->FileName);
160 }
161
162 free (PrivateFile);
163 }
164
165 *Root = NULL;
166 }
167
168 return Status;
169}
170
172ErrnoToEfiStatus (
173 )
174{
175 switch (errno) {
176 case EACCES:
177 return EFI_ACCESS_DENIED;
178
179 case EDQUOT:
180 case ENOSPC:
181 return EFI_VOLUME_FULL;
182
183 default:
184 return EFI_DEVICE_ERROR;
185 }
186}
187
188VOID
189CutPrefix (
190 IN CHAR8 *Str,
191 IN UINTN Count
192 )
193{
194 CHAR8 *Pointer;
195
196 if (AsciiStrLen (Str) < Count) {
197 ASSERT (0);
198 }
199
200 for (Pointer = Str; *(Pointer + Count); Pointer++) {
201 *Pointer = *(Pointer + Count);
202 }
203
204 *Pointer = *(Pointer + Count);
205}
206
207VOID
208PosixSystemTimeToEfiTime (
209 IN time_t SystemTime,
210 OUT EFI_TIME *Time
211 )
212{
213 struct tm *tm;
214
215 tm = gmtime (&SystemTime);
216 Time->Year = tm->tm_year;
217 Time->Month = tm->tm_mon + 1;
218 Time->Day = tm->tm_mday;
219 Time->Hour = tm->tm_hour;
220 Time->Minute = tm->tm_min;
221 Time->Second = tm->tm_sec;
222 Time->Nanosecond = 0;
223
224 Time->TimeZone = timezone / 60;
225 Time->Daylight = (daylight ? EFI_TIME_ADJUST_DAYLIGHT : 0) | (tm->tm_isdst > 0 ? EFI_TIME_IN_DAYLIGHT : 0);
226}
227
229UnixSimpleFileSystemFileInfo (
230 EMU_EFI_FILE_PRIVATE *PrivateFile,
231 IN CHAR8 *FileName,
232 IN OUT UINTN *BufferSize,
233 OUT VOID *Buffer
234 )
235{
236 EFI_STATUS Status;
237 UINTN Size;
238 UINTN NameSize;
239 UINTN ResultSize;
240 EFI_FILE_INFO *Info;
241 CHAR8 *RealFileName;
242 CHAR8 *TempPointer;
243 CHAR16 *BufferFileName;
244 struct stat buf;
245
246 if (FileName != NULL) {
247 RealFileName = FileName;
248 } else if (PrivateFile->IsRootDirectory) {
249 RealFileName = "";
250 } else {
251 RealFileName = PrivateFile->FileName;
252 }
253
254 TempPointer = RealFileName;
255 while (*TempPointer) {
256 if (*TempPointer == '/') {
257 RealFileName = TempPointer + 1;
258 }
259
260 TempPointer++;
261 }
262
264 NameSize = AsciiStrSize (RealFileName) * 2;
265 ResultSize = Size + NameSize;
266
267 if (*BufferSize < ResultSize) {
268 *BufferSize = ResultSize;
269 return EFI_BUFFER_TOO_SMALL;
270 }
271
272 if (stat ((FileName == NULL) ? PrivateFile->FileName : FileName, &buf) < 0) {
273 return EFI_DEVICE_ERROR;
274 }
275
276 Status = EFI_SUCCESS;
277
278 Info = Buffer;
279 ZeroMem (Info, ResultSize);
280
281 Info->Size = ResultSize;
282 Info->FileSize = buf.st_size;
283 Info->PhysicalSize = MultU64x32 (buf.st_blocks, buf.st_blksize);
284
285 PosixSystemTimeToEfiTime (buf.st_ctime, &Info->CreateTime);
286 PosixSystemTimeToEfiTime (buf.st_atime, &Info->LastAccessTime);
287 PosixSystemTimeToEfiTime (buf.st_mtime, &Info->ModificationTime);
288
289 if (!(buf.st_mode & S_IWUSR)) {
290 Info->Attribute |= EFI_FILE_READ_ONLY;
291 }
292
293 if (S_ISDIR (buf.st_mode)) {
294 Info->Attribute |= EFI_FILE_DIRECTORY;
295 }
296
297 BufferFileName = (CHAR16 *)((CHAR8 *)Buffer + Size);
298 while (*RealFileName) {
299 *BufferFileName++ = *RealFileName++;
300 }
301
302 *BufferFileName = 0;
303
304 *BufferSize = ResultSize;
305 return Status;
306}
307
308BOOLEAN
309IsZero (
310 IN VOID *Buffer,
311 IN UINTN Length
312 )
313{
314 if ((Buffer == NULL) || (Length == 0)) {
315 return FALSE;
316 }
317
318 if (*(UINT8 *)Buffer != 0) {
319 return FALSE;
320 }
321
322 if (Length > 1) {
323 if (!CompareMem (Buffer, (UINT8 *)Buffer + 1, Length - 1)) {
324 return FALSE;
325 }
326 }
327
328 return TRUE;
329}
330
352PosixFileOpen (
353 IN EFI_FILE_PROTOCOL *This,
354 OUT EFI_FILE_PROTOCOL **NewHandle,
355 IN CHAR16 *FileName,
356 IN UINT64 OpenMode,
357 IN UINT64 Attributes
358 )
359{
360 EFI_FILE_PROTOCOL *Root;
361 EMU_EFI_FILE_PRIVATE *PrivateFile;
362 EMU_EFI_FILE_PRIVATE *NewPrivateFile;
364 EFI_STATUS Status;
365 CHAR16 *Src;
366 char *Dst;
367 CHAR8 *RealFileName;
368 char *ParseFileName;
369 char *GuardPointer;
370 CHAR8 TempChar;
371 UINTN Count;
372 BOOLEAN TrailingDash;
373 BOOLEAN LoopFinish;
374 UINTN InfoSize;
375 EFI_FILE_INFO *Info;
376 struct stat finfo;
377 int res;
378 UINTN Size;
379
380 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
381 PrivateRoot = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);
382 NewPrivateFile = NULL;
383 Status = EFI_OUT_OF_RESOURCES;
384
385 //
386 // BUGBUG: assume an open of root
387 // if current location, return current data
388 //
389 TrailingDash = FALSE;
390 if ((StrCmp (FileName, L"\\") == 0) ||
391 ((StrCmp (FileName, L".") == 0) && PrivateFile->IsRootDirectory))
392 {
393OpenRoot:
394 Status = PosixOpenVolume (PrivateFile->SimpleFileSystem, &Root);
395 NewPrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (Root);
396 goto Done;
397 }
398
399 if (FileName[StrLen (FileName) - 1] == L'\\') {
400 TrailingDash = TRUE;
401 FileName[StrLen (FileName) - 1] = 0;
402 }
403
404 //
405 // Attempt to open the file
406 //
407 NewPrivateFile = malloc (sizeof (EMU_EFI_FILE_PRIVATE));
408 if (NewPrivateFile == NULL) {
409 goto Done;
410 }
411
412 CopyMem (NewPrivateFile, PrivateFile, sizeof (EMU_EFI_FILE_PRIVATE));
413
414 Size = AsciiStrSize (PrivateFile->FileName) + 1 + StrLen (FileName) + 1;
415 NewPrivateFile->FileName = malloc (Size);
416 if (NewPrivateFile->FileName == NULL) {
417 goto Done;
418 }
419
420 if (*FileName == L'\\') {
421 AsciiStrCpyS (NewPrivateFile->FileName, Size, PrivateRoot->FilePath);
422 // Skip first '\'.
423 Src = FileName + 1;
424 } else {
425 AsciiStrCpyS (NewPrivateFile->FileName, Size, PrivateFile->FileName);
426 Src = FileName;
427 }
428
429 Dst = NewPrivateFile->FileName + AsciiStrLen (NewPrivateFile->FileName);
430 GuardPointer = NewPrivateFile->FileName + AsciiStrLen (PrivateRoot->FilePath);
431 *Dst++ = '/';
432 // Convert unicode to ascii and '\' to '/'
433 while (*Src) {
434 if (*Src == '\\') {
435 *Dst++ = '/';
436 } else {
437 *Dst++ = *Src;
438 }
439
440 Src++;
441 }
442
443 *Dst = 0;
444
445 //
446 // Get rid of . and .., except leading . or ..
447 //
448
449 //
450 // GuardPointer protect simplefilesystem root path not be destroyed
451 //
452
453 LoopFinish = FALSE;
454 while (!LoopFinish) {
455 LoopFinish = TRUE;
456
457 for (ParseFileName = GuardPointer; *ParseFileName; ParseFileName++) {
458 if ((*ParseFileName == '.') &&
459 ((*(ParseFileName + 1) == 0) || (*(ParseFileName + 1) == '/')) &&
460 (*(ParseFileName - 1) == '/')
461 )
462 {
463 //
464 // cut /.
465 //
466 CutPrefix (ParseFileName - 1, 2);
467 LoopFinish = FALSE;
468 break;
469 }
470
471 if ((*ParseFileName == '.') &&
472 (*(ParseFileName + 1) == '.') &&
473 ((*(ParseFileName + 2) == 0) || (*(ParseFileName + 2) == '/')) &&
474 (*(ParseFileName - 1) == '/')
475 )
476 {
477 ParseFileName--;
478 Count = 3;
479
480 while (ParseFileName != GuardPointer) {
481 ParseFileName--;
482 Count++;
483 if (*ParseFileName == '/') {
484 break;
485 }
486 }
487
488 //
489 // cut /.. and its left directory
490 //
491 CutPrefix (ParseFileName, Count);
492 LoopFinish = FALSE;
493 break;
494 }
495 }
496 }
497
498 if (AsciiStrCmp (NewPrivateFile->FileName, PrivateRoot->FilePath) == 0) {
499 NewPrivateFile->IsRootDirectory = TRUE;
500 free (NewPrivateFile->FileName);
501 free (NewPrivateFile);
502 goto OpenRoot;
503 }
504
505 RealFileName = NewPrivateFile->FileName + AsciiStrLen (NewPrivateFile->FileName) - 1;
506 while (RealFileName > NewPrivateFile->FileName && *RealFileName != '/') {
507 RealFileName--;
508 }
509
510 TempChar = *(RealFileName - 1);
511 *(RealFileName - 1) = 0;
512 *(RealFileName - 1) = TempChar;
513
514 //
515 // Test whether file or directory
516 //
517 NewPrivateFile->IsRootDirectory = FALSE;
518 NewPrivateFile->fd = -1;
519 NewPrivateFile->Dir = NULL;
520 if (OpenMode & EFI_FILE_MODE_CREATE) {
521 if (Attributes & EFI_FILE_DIRECTORY) {
522 NewPrivateFile->IsDirectoryPath = TRUE;
523 } else {
524 NewPrivateFile->IsDirectoryPath = FALSE;
525 }
526 } else {
527 res = stat (NewPrivateFile->FileName, &finfo);
528 if ((res == 0) && S_ISDIR (finfo.st_mode)) {
529 NewPrivateFile->IsDirectoryPath = TRUE;
530 } else {
531 NewPrivateFile->IsDirectoryPath = FALSE;
532 }
533 }
534
535 if (OpenMode & EFI_FILE_MODE_WRITE) {
536 NewPrivateFile->IsOpenedByRead = FALSE;
537 } else {
538 NewPrivateFile->IsOpenedByRead = TRUE;
539 }
540
541 Status = EFI_SUCCESS;
542
543 //
544 // deal with directory
545 //
546 if (NewPrivateFile->IsDirectoryPath) {
547 if ((OpenMode & EFI_FILE_MODE_CREATE)) {
548 //
549 // Create a directory
550 //
551 if (mkdir (NewPrivateFile->FileName, 0777) != 0) {
552 if (errno != EEXIST) {
553 // free (TempFileName);
554 Status = EFI_ACCESS_DENIED;
555 goto Done;
556 }
557 }
558 }
559
560 NewPrivateFile->Dir = opendir (NewPrivateFile->FileName);
561 if (NewPrivateFile->Dir == NULL) {
562 if (errno == EACCES) {
563 Status = EFI_ACCESS_DENIED;
564 } else {
565 Status = EFI_NOT_FOUND;
566 }
567
568 goto Done;
569 }
570 } else {
571 //
572 // deal with file
573 //
574 NewPrivateFile->fd = open (
575 NewPrivateFile->FileName,
576 ((OpenMode & EFI_FILE_MODE_CREATE) ? O_CREAT : 0) | (NewPrivateFile->IsOpenedByRead ? O_RDONLY : O_RDWR),
577 0666
578 );
579 if (NewPrivateFile->fd < 0) {
580 if (errno == ENOENT) {
581 Status = EFI_NOT_FOUND;
582 } else {
583 Status = EFI_ACCESS_DENIED;
584 }
585 }
586 }
587
588 if ((OpenMode & EFI_FILE_MODE_CREATE) && (Status == EFI_SUCCESS)) {
589 //
590 // Set the attribute
591 //
592 InfoSize = 0;
593 Info = NULL;
594 Status = PosixFileGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info);
595 if (Status != EFI_BUFFER_TOO_SMALL) {
596 Status = EFI_DEVICE_ERROR;
597 goto Done;
598 }
599
600 Info = malloc (InfoSize);
601 if (Info == NULL) {
602 goto Done;
603 }
604
605 Status = PosixFileGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info);
606 if (EFI_ERROR (Status)) {
607 goto Done;
608 }
609
610 Info->Attribute = Attributes;
611 PosixFileSetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, InfoSize, Info);
612
613 free (Info);
614 }
615
616Done:;
617 if (TrailingDash) {
618 FileName[StrLen (FileName) + 1] = 0;
619 FileName[StrLen (FileName)] = L'\\';
620 }
621
622 if (EFI_ERROR (Status)) {
623 if (NewPrivateFile) {
624 if (NewPrivateFile->FileName) {
625 free (NewPrivateFile->FileName);
626 }
627
628 free (NewPrivateFile);
629 }
630 } else {
631 *NewHandle = &NewPrivateFile->EfiFile;
632 }
633
634 return Status;
635}
636
646PosixFileCLose (
648 )
649{
650 EMU_EFI_FILE_PRIVATE *PrivateFile;
651
652 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
653
654 if (PrivateFile->fd >= 0) {
655 close (PrivateFile->fd);
656 }
657
658 if (PrivateFile->Dir != NULL) {
659 closedir (PrivateFile->Dir);
660 }
661
662 PrivateFile->fd = -1;
663 PrivateFile->Dir = NULL;
664
665 if (PrivateFile->FileName) {
666 free (PrivateFile->FileName);
667 }
668
669 free (PrivateFile);
670
671 return EFI_SUCCESS;
672}
673
684PosixFileDelete (
686 )
687{
688 EFI_STATUS Status;
689 EMU_EFI_FILE_PRIVATE *PrivateFile;
690
691 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
692 Status = EFI_WARN_DELETE_FAILURE;
693
694 if (PrivateFile->IsDirectoryPath) {
695 if (PrivateFile->Dir != NULL) {
696 closedir (PrivateFile->Dir);
697 PrivateFile->Dir = NULL;
698 }
699
700 if (rmdir (PrivateFile->FileName) == 0) {
701 Status = EFI_SUCCESS;
702 }
703 } else {
704 close (PrivateFile->fd);
705 PrivateFile->fd = -1;
706
707 if (!PrivateFile->IsOpenedByRead) {
708 if (!unlink (PrivateFile->FileName)) {
709 Status = EFI_SUCCESS;
710 }
711 }
712 }
713
714 free (PrivateFile->FileName);
715 free (PrivateFile);
716
717 return Status;
718}
719
735PosixFileRead (
736 IN EFI_FILE_PROTOCOL *This,
737 IN OUT UINTN *BufferSize,
738 OUT VOID *Buffer
739 )
740{
741 EMU_EFI_FILE_PRIVATE *PrivateFile;
742 EFI_STATUS Status;
743 int Res;
744 UINTN Size;
745 UINTN NameSize;
746 UINTN ResultSize;
747 CHAR8 *FullFileName;
748 UINTN FullFileNameSize;
749
750 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
751
752 if (!PrivateFile->IsDirectoryPath) {
753 if (PrivateFile->fd < 0) {
754 Status = EFI_DEVICE_ERROR;
755 goto Done;
756 }
757
758 Res = read (PrivateFile->fd, Buffer, *BufferSize);
759 if (Res < 0) {
760 Status = EFI_DEVICE_ERROR;
761 goto Done;
762 }
763
764 *BufferSize = Res;
765 Status = EFI_SUCCESS;
766 goto Done;
767 }
768
769 //
770 // Read on a directory.
771 //
772 if (PrivateFile->Dir == NULL) {
773 Status = EFI_DEVICE_ERROR;
774 goto Done;
775 }
776
777 if (PrivateFile->Dirent == NULL) {
778 PrivateFile->Dirent = readdir (PrivateFile->Dir);
779 if (PrivateFile->Dirent == NULL) {
780 *BufferSize = 0;
781 Status = EFI_SUCCESS;
782 goto Done;
783 }
784 }
785
787 NameSize = AsciiStrLen (PrivateFile->Dirent->d_name) + 1;
788 ResultSize = Size + 2 * NameSize;
789
790 if (*BufferSize < ResultSize) {
791 *BufferSize = ResultSize;
792 Status = EFI_BUFFER_TOO_SMALL;
793 goto Done;
794 }
795
796 Status = EFI_SUCCESS;
797
798 *BufferSize = ResultSize;
799
800 FullFileNameSize = AsciiStrLen (PrivateFile->FileName) + 1 + NameSize;
801 FullFileName = malloc (FullFileNameSize);
802 if (FullFileName == NULL) {
803 Status = EFI_OUT_OF_RESOURCES;
804 goto Done;
805 }
806
807 AsciiStrCpyS (FullFileName, FullFileNameSize, PrivateFile->FileName);
808 AsciiStrCatS (FullFileName, FullFileNameSize, "/");
809 AsciiStrCatS (FullFileName, FullFileNameSize, PrivateFile->Dirent->d_name);
810 Status = UnixSimpleFileSystemFileInfo (
811 PrivateFile,
812 FullFileName,
813 BufferSize,
814 Buffer
815 );
816 free (FullFileName);
817
818 PrivateFile->Dirent = NULL;
819
820Done:
821 return Status;
822}
823
843PosixFileWrite (
844 IN EFI_FILE_PROTOCOL *This,
845 IN OUT UINTN *BufferSize,
846 IN VOID *Buffer
847 )
848{
849 EMU_EFI_FILE_PRIVATE *PrivateFile;
850 int Res;
851
852 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
853
854 if (PrivateFile->fd < 0) {
855 return EFI_DEVICE_ERROR;
856 }
857
858 if (PrivateFile->IsDirectoryPath) {
859 return EFI_UNSUPPORTED;
860 }
861
862 if (PrivateFile->IsOpenedByRead) {
863 return EFI_ACCESS_DENIED;
864 }
865
866 Res = write (PrivateFile->fd, Buffer, *BufferSize);
867 if (Res == (UINTN)-1) {
868 return ErrnoToEfiStatus ();
869 }
870
871 *BufferSize = Res;
872 return EFI_SUCCESS;
873}
874
886PosixFileSetPossition (
887 IN EFI_FILE_PROTOCOL *This,
888 IN UINT64 Position
889 )
890{
891 EMU_EFI_FILE_PRIVATE *PrivateFile;
892 off_t Pos;
893
894 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
895
896 if (PrivateFile->IsDirectoryPath) {
897 if (Position != 0) {
898 return EFI_UNSUPPORTED;
899 }
900
901 if (PrivateFile->Dir == NULL) {
902 return EFI_DEVICE_ERROR;
903 }
904
905 rewinddir (PrivateFile->Dir);
906 return EFI_SUCCESS;
907 } else {
908 if (Position == (UINT64)-1) {
909 Pos = lseek (PrivateFile->fd, 0, SEEK_END);
910 } else {
911 Pos = lseek (PrivateFile->fd, Position, SEEK_SET);
912 }
913
914 if (Pos == (off_t)-1) {
915 return ErrnoToEfiStatus ();
916 }
917
918 return EFI_SUCCESS;
919 }
920}
921
933PosixFileGetPossition (
934 IN EFI_FILE_PROTOCOL *This,
935 OUT UINT64 *Position
936 )
937{
938 EFI_STATUS Status;
939 EMU_EFI_FILE_PRIVATE *PrivateFile;
940
941 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
942
943 if (PrivateFile->IsDirectoryPath) {
944 Status = EFI_UNSUPPORTED;
945 } else {
946 *Position = (UINT64)lseek (PrivateFile->fd, 0, SEEK_CUR);
947 Status = (*Position == (UINT64)-1) ? ErrnoToEfiStatus () : EFI_SUCCESS;
948 }
949
950 return Status;
951}
952
972PosixFileGetInfo (
973 IN EFI_FILE_PROTOCOL *This,
974 IN EFI_GUID *InformationType,
975 IN OUT UINTN *BufferSize,
976 OUT VOID *Buffer
977 )
978{
979 EFI_STATUS Status;
980 EMU_EFI_FILE_PRIVATE *PrivateFile;
981 EFI_FILE_SYSTEM_INFO *FileSystemInfoBuffer;
982 int UnixStatus;
984 struct statfs buf;
985
986 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
987 PrivateRoot = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);
988
989 Status = EFI_SUCCESS;
990 if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {
991 Status = UnixSimpleFileSystemFileInfo (PrivateFile, NULL, BufferSize, Buffer);
992 } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
993 if (*BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel)) {
994 *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);
995 return EFI_BUFFER_TOO_SMALL;
996 }
997
998 UnixStatus = statfs (PrivateFile->FileName, &buf);
999 if (UnixStatus < 0) {
1000 return EFI_DEVICE_ERROR;
1001 }
1002
1003 FileSystemInfoBuffer = (EFI_FILE_SYSTEM_INFO *)Buffer;
1004 FileSystemInfoBuffer->Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);
1005 FileSystemInfoBuffer->ReadOnly = FALSE;
1006
1007 //
1008 // Succeeded
1009 //
1010 FileSystemInfoBuffer->VolumeSize = MultU64x32 (buf.f_blocks, buf.f_bsize);
1011 FileSystemInfoBuffer->FreeSpace = MultU64x32 (buf.f_bavail, buf.f_bsize);
1012 FileSystemInfoBuffer->BlockSize = buf.f_bsize;
1013
1014 StrCpyS (
1015 (CHAR16 *)FileSystemInfoBuffer->VolumeLabel,
1016 (*BufferSize - SIZE_OF_EFI_FILE_SYSTEM_INFO) / sizeof (CHAR16),
1017 PrivateRoot->VolumeLabel
1018 );
1019 *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel);
1020 } else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
1021 if (*BufferSize < StrSize (PrivateRoot->VolumeLabel)) {
1022 *BufferSize = StrSize (PrivateRoot->VolumeLabel);
1023 return EFI_BUFFER_TOO_SMALL;
1024 }
1025
1026 StrCpyS (
1027 (CHAR16 *)Buffer,
1028 *BufferSize / sizeof (CHAR16),
1029 PrivateRoot->VolumeLabel
1030 );
1031 *BufferSize = StrSize (PrivateRoot->VolumeLabel);
1032 }
1033
1034 return Status;
1035}
1036
1055PosixFileSetInfo (
1056 IN EFI_FILE_PROTOCOL *This,
1057 IN EFI_GUID *InformationType,
1058 IN UINTN BufferSize,
1059 IN VOID *Buffer
1060 )
1061{
1062 EMU_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot;
1063 EMU_EFI_FILE_PRIVATE *PrivateFile;
1064 EFI_FILE_INFO *OldFileInfo;
1065 EFI_FILE_INFO *NewFileInfo;
1066 EFI_STATUS Status;
1067 UINTN OldInfoSize;
1068 mode_t NewAttr;
1069 struct stat OldAttr;
1070 CHAR8 *OldFileName;
1071 CHAR8 *NewFileName;
1072 CHAR8 *CharPointer;
1073 BOOLEAN AttrChangeFlag;
1074 BOOLEAN NameChangeFlag;
1075 BOOLEAN SizeChangeFlag;
1076 BOOLEAN TimeChangeFlag;
1077 struct tm NewLastAccessSystemTime;
1078 struct tm NewLastWriteSystemTime;
1079 EFI_FILE_SYSTEM_INFO *NewFileSystemInfo;
1080 CHAR8 *AsciiFilePtr;
1081 CHAR16 *UnicodeFilePtr;
1082 int UnixStatus;
1083 struct utimbuf Utime;
1084 UINTN Size;
1085
1086 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
1087 PrivateRoot = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem);
1088 errno = 0;
1089 Status = EFI_UNSUPPORTED;
1090 OldFileInfo = NewFileInfo = NULL;
1091 OldFileName = NewFileName = NULL;
1092 AttrChangeFlag = NameChangeFlag = SizeChangeFlag = TimeChangeFlag = FALSE;
1093
1094 //
1095 // Set file system information.
1096 //
1097 if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
1098 if (BufferSize < (SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel))) {
1099 Status = EFI_BAD_BUFFER_SIZE;
1100 goto Done;
1101 }
1102
1103 NewFileSystemInfo = (EFI_FILE_SYSTEM_INFO *)Buffer;
1104
1105 free (PrivateRoot->VolumeLabel);
1106
1107 PrivateRoot->VolumeLabel = malloc (StrSize (NewFileSystemInfo->VolumeLabel));
1108 if (PrivateRoot->VolumeLabel == NULL) {
1109 goto Done;
1110 }
1111
1112 StrCpyS (
1113 PrivateRoot->VolumeLabel,
1114 StrSize (NewFileSystemInfo->VolumeLabel) / sizeof (CHAR16),
1115 NewFileSystemInfo->VolumeLabel
1116 );
1117
1118 Status = EFI_SUCCESS;
1119 goto Done;
1120 }
1121
1122 //
1123 // Set volume label information.
1124 //
1125 if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
1126 if (BufferSize < StrSize (PrivateRoot->VolumeLabel)) {
1127 Status = EFI_BAD_BUFFER_SIZE;
1128 goto Done;
1129 }
1130
1131 StrCpyS (
1132 PrivateRoot->VolumeLabel,
1133 StrSize (PrivateRoot->VolumeLabel) / sizeof (CHAR16),
1134 (CHAR16 *)Buffer
1135 );
1136
1137 Status = EFI_SUCCESS;
1138 goto Done;
1139 }
1140
1141 if (!CompareGuid (InformationType, &gEfiFileInfoGuid)) {
1142 Status = EFI_UNSUPPORTED;
1143 goto Done;
1144 }
1145
1146 if (BufferSize < SIZE_OF_EFI_FILE_INFO) {
1147 Status = EFI_BAD_BUFFER_SIZE;
1148 goto Done;
1149 }
1150
1151 //
1152 // Set file/directory information.
1153 //
1154
1155 //
1156 // Check for invalid set file information parameters.
1157 //
1158 NewFileInfo = (EFI_FILE_INFO *)Buffer;
1159 if ((NewFileInfo->Size <= sizeof (EFI_FILE_INFO)) ||
1160 (NewFileInfo->Attribute &~(EFI_FILE_VALID_ATTR)) ||
1161 ((sizeof (UINTN) == 4) && (NewFileInfo->Size > 0xFFFFFFFF))
1162 )
1163 {
1164 Status = EFI_INVALID_PARAMETER;
1165 goto Done;
1166 }
1167
1168 //
1169 // Get current file information so we can determine what kind
1170 // of change request this is.
1171 //
1172 OldInfoSize = 0;
1173 Status = UnixSimpleFileSystemFileInfo (PrivateFile, NULL, &OldInfoSize, NULL);
1174 if (Status != EFI_BUFFER_TOO_SMALL) {
1175 Status = EFI_DEVICE_ERROR;
1176 goto Done;
1177 }
1178
1179 OldFileInfo = malloc (OldInfoSize);
1180 if (OldFileInfo == NULL) {
1181 goto Done;
1182 }
1183
1184 Status = UnixSimpleFileSystemFileInfo (PrivateFile, NULL, &OldInfoSize, OldFileInfo);
1185 if (EFI_ERROR (Status)) {
1186 goto Done;
1187 }
1188
1189 OldFileName = malloc (AsciiStrSize (PrivateFile->FileName));
1190 if (OldFileName == NULL) {
1191 goto Done;
1192 }
1193
1194 AsciiStrCpyS (
1195 OldFileName,
1196 AsciiStrSize (PrivateFile->FileName),
1197 PrivateFile->FileName
1198 );
1199
1200 //
1201 // Make full pathname from new filename and rootpath.
1202 //
1203 if (NewFileInfo->FileName[0] == '\\') {
1204 Size = AsciiStrLen (PrivateRoot->FilePath) + 1 + StrLen (NewFileInfo->FileName) + 1;
1205 NewFileName = malloc (Size);
1206 if (NewFileName == NULL) {
1207 goto Done;
1208 }
1209
1210 AsciiStrCpyS (NewFileName, Size, PrivateRoot->FilePath);
1211 AsciiFilePtr = NewFileName + AsciiStrLen (NewFileName);
1212 UnicodeFilePtr = NewFileInfo->FileName + 1;
1213 *AsciiFilePtr++ = '/';
1214 } else {
1215 Size = AsciiStrLen (PrivateFile->FileName) + 2 + StrLen (NewFileInfo->FileName) + 1;
1216 NewFileName = malloc (Size);
1217 if (NewFileName == NULL) {
1218 goto Done;
1219 }
1220
1221 AsciiStrCpyS (NewFileName, Size, PrivateRoot->FilePath);
1222 AsciiFilePtr = NewFileName + AsciiStrLen (NewFileName);
1223 if ((AsciiFilePtr[-1] != '/') && (NewFileInfo->FileName[0] != '/')) {
1224 // make sure there is a / between Root FilePath and NewFileInfo Filename
1225 AsciiFilePtr[0] = '/';
1226 AsciiFilePtr[1] = '\0';
1227 AsciiFilePtr++;
1228 }
1229
1230 UnicodeFilePtr = NewFileInfo->FileName;
1231 }
1232
1233 // Convert to ascii.
1234 while (*UnicodeFilePtr) {
1235 *AsciiFilePtr++ = *UnicodeFilePtr++;
1236 }
1237
1238 *AsciiFilePtr = 0;
1239
1240 //
1241 // Is there an attribute change request?
1242 //
1243 if (NewFileInfo->Attribute != OldFileInfo->Attribute) {
1244 if ((NewFileInfo->Attribute & EFI_FILE_DIRECTORY) != (OldFileInfo->Attribute & EFI_FILE_DIRECTORY)) {
1245 Status = EFI_INVALID_PARAMETER;
1246 goto Done;
1247 }
1248
1249 AttrChangeFlag = TRUE;
1250 }
1251
1252 //
1253 // Is there a name change request?
1254 // bugbug: - Should really use EFI_UNICODE_COLLATION_PROTOCOL
1255 //
1256 if (StrCmp (NewFileInfo->FileName, OldFileInfo->FileName)) {
1257 NameChangeFlag = TRUE;
1258 }
1259
1260 //
1261 // Is there a size change request?
1262 //
1263 if (NewFileInfo->FileSize != OldFileInfo->FileSize) {
1264 SizeChangeFlag = TRUE;
1265 }
1266
1267 //
1268 // Is there a time stamp change request?
1269 //
1270 if (!IsZero (&NewFileInfo->CreateTime, sizeof (EFI_TIME)) &&
1271 CompareMem (&NewFileInfo->CreateTime, &OldFileInfo->CreateTime, sizeof (EFI_TIME))
1272 )
1273 {
1274 TimeChangeFlag = TRUE;
1275 } else if (!IsZero (&NewFileInfo->LastAccessTime, sizeof (EFI_TIME)) &&
1276 CompareMem (&NewFileInfo->LastAccessTime, &OldFileInfo->LastAccessTime, sizeof (EFI_TIME))
1277 )
1278 {
1279 TimeChangeFlag = TRUE;
1280 } else if (!IsZero (&NewFileInfo->ModificationTime, sizeof (EFI_TIME)) &&
1281 CompareMem (&NewFileInfo->ModificationTime, &OldFileInfo->ModificationTime, sizeof (EFI_TIME))
1282 )
1283 {
1284 TimeChangeFlag = TRUE;
1285 }
1286
1287 //
1288 // All done if there are no change requests being made.
1289 //
1290 if (!(AttrChangeFlag || NameChangeFlag || SizeChangeFlag || TimeChangeFlag)) {
1291 Status = EFI_SUCCESS;
1292 goto Done;
1293 }
1294
1295 //
1296 // Set file or directory information.
1297 //
1298 if (stat (OldFileName, &OldAttr) != 0) {
1299 Status = ErrnoToEfiStatus ();
1300 goto Done;
1301 }
1302
1303 //
1304 // Name change.
1305 //
1306 if (NameChangeFlag) {
1307 //
1308 // Close the handles first
1309 //
1310 if (PrivateFile->IsOpenedByRead) {
1311 Status = EFI_ACCESS_DENIED;
1312 goto Done;
1313 }
1314
1315 for (CharPointer = NewFileName; *CharPointer != 0 && *CharPointer != L'/'; CharPointer++) {
1316 }
1317
1318 if (*CharPointer != 0) {
1319 Status = EFI_ACCESS_DENIED;
1320 goto Done;
1321 }
1322
1323 UnixStatus = rename (OldFileName, NewFileName);
1324 if (UnixStatus == 0) {
1325 //
1326 // modify file name
1327 //
1328 free (PrivateFile->FileName);
1329
1330 PrivateFile->FileName = malloc (AsciiStrSize (NewFileName));
1331 if (PrivateFile->FileName == NULL) {
1332 goto Done;
1333 }
1334
1335 AsciiStrCpyS (
1336 PrivateFile->FileName,
1337 AsciiStrSize (NewFileName),
1338 NewFileName
1339 );
1340 } else {
1341 Status = EFI_DEVICE_ERROR;
1342 goto Done;
1343 }
1344 }
1345
1346 //
1347 // Size change
1348 //
1349 if (SizeChangeFlag) {
1350 if (PrivateFile->IsDirectoryPath) {
1351 Status = EFI_UNSUPPORTED;
1352 goto Done;
1353 }
1354
1355 if (PrivateFile->IsOpenedByRead || OldFileInfo->Attribute & EFI_FILE_READ_ONLY) {
1356 Status = EFI_ACCESS_DENIED;
1357 goto Done;
1358 }
1359
1360 if (ftruncate (PrivateFile->fd, NewFileInfo->FileSize) != 0) {
1361 Status = ErrnoToEfiStatus ();
1362 goto Done;
1363 }
1364 }
1365
1366 //
1367 // Time change
1368 //
1369 if (TimeChangeFlag) {
1370 NewLastAccessSystemTime.tm_year = NewFileInfo->LastAccessTime.Year;
1371 NewLastAccessSystemTime.tm_mon = NewFileInfo->LastAccessTime.Month;
1372 NewLastAccessSystemTime.tm_mday = NewFileInfo->LastAccessTime.Day;
1373 NewLastAccessSystemTime.tm_hour = NewFileInfo->LastAccessTime.Hour;
1374 NewLastAccessSystemTime.tm_min = NewFileInfo->LastAccessTime.Minute;
1375 NewLastAccessSystemTime.tm_sec = NewFileInfo->LastAccessTime.Second;
1376 NewLastAccessSystemTime.tm_isdst = 0;
1377
1378 Utime.actime = mktime (&NewLastAccessSystemTime);
1379
1380 NewLastWriteSystemTime.tm_year = NewFileInfo->ModificationTime.Year;
1381 NewLastWriteSystemTime.tm_mon = NewFileInfo->ModificationTime.Month;
1382 NewLastWriteSystemTime.tm_mday = NewFileInfo->ModificationTime.Day;
1383 NewLastWriteSystemTime.tm_hour = NewFileInfo->ModificationTime.Hour;
1384 NewLastWriteSystemTime.tm_min = NewFileInfo->ModificationTime.Minute;
1385 NewLastWriteSystemTime.tm_sec = NewFileInfo->ModificationTime.Second;
1386 NewLastWriteSystemTime.tm_isdst = 0;
1387
1388 Utime.modtime = mktime (&NewLastWriteSystemTime);
1389
1390 if ((Utime.actime == (time_t)-1) || (Utime.modtime == (time_t)-1)) {
1391 goto Done;
1392 }
1393
1394 if (utime (PrivateFile->FileName, &Utime) == -1) {
1395 Status = ErrnoToEfiStatus ();
1396 goto Done;
1397 }
1398 }
1399
1400 //
1401 // No matter about AttrChangeFlag, Attribute must be set.
1402 // Because operation before may cause attribute change.
1403 //
1404 NewAttr = OldAttr.st_mode;
1405
1406 if (NewFileInfo->Attribute & EFI_FILE_READ_ONLY) {
1407 NewAttr &= ~(S_IRUSR | S_IRGRP | S_IROTH);
1408 } else {
1409 NewAttr |= S_IRUSR;
1410 }
1411
1412 if (chmod (NewFileName, NewAttr) != 0) {
1413 Status = ErrnoToEfiStatus ();
1414 }
1415
1416Done:
1417 if (OldFileInfo != NULL) {
1418 free (OldFileInfo);
1419 }
1420
1421 if (OldFileName != NULL) {
1422 free (OldFileName);
1423 }
1424
1425 if (NewFileName != NULL) {
1426 free (NewFileName);
1427 }
1428
1429 return Status;
1430}
1431
1448PosixFileFlush (
1449 IN EFI_FILE_PROTOCOL *This
1450 )
1451{
1452 EMU_EFI_FILE_PRIVATE *PrivateFile;
1453
1454 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
1455
1456 if (PrivateFile->IsDirectoryPath) {
1457 return EFI_UNSUPPORTED;
1458 }
1459
1460 if (PrivateFile->IsOpenedByRead) {
1461 return EFI_ACCESS_DENIED;
1462 }
1463
1464 if (PrivateFile->fd < 0) {
1465 return EFI_DEVICE_ERROR;
1466 }
1467
1468 if (fsync (PrivateFile->fd) != 0) {
1469 return ErrnoToEfiStatus ();
1470 }
1471
1472 return EFI_SUCCESS;
1473}
1474
1476PosixFileSystmeThunkOpen (
1478 )
1479{
1481 UINTN i;
1482
1483 if (This->Private != NULL) {
1484 return EFI_ALREADY_STARTED;
1485 }
1486
1487 if (!CompareGuid (This->Protocol, &gEfiSimpleFileSystemProtocolGuid)) {
1488 return EFI_UNSUPPORTED;
1489 }
1490
1491 Private = malloc (sizeof (EMU_SIMPLE_FILE_SYSTEM_PRIVATE));
1492 if (Private == NULL) {
1493 return EFI_OUT_OF_RESOURCES;
1494 }
1495
1496 Private->FilePath = malloc (StrLen (This->ConfigString) + 1);
1497 if (Private->FilePath == NULL) {
1498 free (Private);
1499 return EFI_OUT_OF_RESOURCES;
1500 }
1501
1502 // Convert Unicode to Ascii
1503 for (i = 0; This->ConfigString[i] != 0; i++) {
1504 Private->FilePath[i] = This->ConfigString[i];
1505 }
1506
1507 Private->FilePath[i] = 0;
1508
1509 Private->VolumeLabel = malloc (StrSize (L"EFI_EMULATED"));
1510 if (Private->VolumeLabel == NULL) {
1511 free (Private->FilePath);
1512 free (Private);
1513 return EFI_OUT_OF_RESOURCES;
1514 }
1515
1516 StrCpyS (
1517 Private->VolumeLabel,
1518 StrSize (L"EFI_EMULATED") / sizeof (CHAR16),
1519 L"EFI_EMULATED"
1520 );
1521
1522 Private->Signature = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE;
1523 Private->Thunk = This;
1524 CopyMem (&Private->SimpleFileSystem, &gPosixFileSystemProtocol, sizeof (Private->SimpleFileSystem));
1525 Private->FileHandlesOpen = FALSE;
1526
1527 This->Interface = &Private->SimpleFileSystem;
1528 This->Private = Private;
1529 return EFI_SUCCESS;
1530}
1531
1533PosixFileSystmeThunkClose (
1535 )
1536{
1538
1539 if (!CompareGuid (This->Protocol, &gEfiSimpleFileSystemProtocolGuid)) {
1540 return EFI_UNSUPPORTED;
1541 }
1542
1543 Private = This->Private;
1544
1545 if (Private->FileHandlesOpen) {
1546 //
1547 // Close only supported if all the EFI_FILE_HANDLEs have been closed.
1548 //
1549 return EFI_NOT_READY;
1550 }
1551
1552 if (This->Private != NULL) {
1553 if (Private->VolumeLabel != NULL) {
1554 free (Private->VolumeLabel);
1555 }
1556
1557 free (This->Private);
1558 This->Private = NULL;
1559 }
1560
1561 return EFI_SUCCESS;
1562}
1563
1564EMU_IO_THUNK_PROTOCOL gPosixFileSystemThunkIo = {
1565 &gEfiSimpleFileSystemProtocolGuid,
1566 NULL,
1567 NULL,
1568 0,
1569 GasketPosixFileSystmeThunkOpen,
1570 GasketPosixFileSystmeThunkClose,
1571 NULL
1572};
UINT64 UINTN
UINTN EFIAPI StrSize(IN CONST CHAR16 *String)
Definition: String.c:72
RETURN_STATUS EFIAPI StrCpyS(OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source)
Definition: SafeString.c:226
INTN EFIAPI StrCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString)
Definition: String.c:109
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
Definition: String.c:641
RETURN_STATUS EFIAPI AsciiStrCatS(IN OUT CHAR8 *Destination, IN UINTN DestMax, IN CONST CHAR8 *Source)
Definition: SafeString.c:1964
INTN EFIAPI AsciiStrCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString)
Definition: String.c:716
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
Definition: MultU64x32.c:27
UINTN EFIAPI AsciiStrSize(IN CONST CHAR8 *String)
Definition: String.c:681
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
RETURN_STATUS EFIAPI AsciiStrCpyS(OUT CHAR8 *Destination, IN UINTN DestMax, IN CONST CHAR8 *Source)
Definition: SafeString.c:1797
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
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)
struct tm * gmtime(const time_t *)
#define SIZE_OF_EFI_FILE_INFO
Definition: FileInfo.h:62
#define SIZE_OF_EFI_FILE_SYSTEM_INFO
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_TIME ModificationTime
Definition: FileInfo.h:43
UINT64 PhysicalSize
Definition: FileInfo.h:31
EFI_TIME CreateTime
Definition: FileInfo.h:35
UINT64 Size
Definition: FileInfo.h:23
UINT64 Attribute
Definition: FileInfo.h:47
CHAR16 FileName[1]
Definition: FileInfo.h:52
EFI_TIME LastAccessTime
Definition: FileInfo.h:39
UINT64 FileSize
Definition: FileInfo.h:27
Definition: Base.h:213