TianoCore EDK2 master
Loading...
Searching...
No Matches
EmuSimpleFileSystem.c
1/*++ @file
2 Produce Simple File System abstractions for directories on your PC using Posix APIs.
3 The configuration of what devices to mount or emulate comes from UNIX
4 environment variables. The variables must be visible to the Microsoft*
5 Developer Studio for them to work.
6
7Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
8Portions copyright (c) 2011, Apple Inc. All rights reserved.
9SPDX-License-Identifier: BSD-2-Clause-Patent
10
11**/
12
13#include "EmuSimpleFileSystem.h"
14
36EFIAPI
37EmuSimpleFileSystemOpen (
39 OUT EFI_FILE_PROTOCOL **NewHandle,
40 IN CHAR16 *FileName,
41 IN UINT64 OpenMode,
42 IN UINT64 Attributes
43 )
44{
45 EFI_STATUS Status;
46 EFI_TPL OldTpl;
47 EMU_EFI_FILE_PRIVATE *PrivateFile;
48 EMU_EFI_FILE_PRIVATE *NewPrivateFile;
49
50 //
51 // Check for obvious invalid parameters.
52 //
53 if ((This == NULL) || (NewHandle == NULL) || (FileName == NULL)) {
54 return EFI_INVALID_PARAMETER;
55 }
56
57 switch (OpenMode) {
58 case EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:
59 if (Attributes &~EFI_FILE_VALID_ATTR) {
60 return EFI_INVALID_PARAMETER;
61 }
62
63 if (Attributes & EFI_FILE_READ_ONLY) {
64 return EFI_INVALID_PARAMETER;
65 }
66
67 //
68 // fall through
69 //
70 case EFI_FILE_MODE_READ:
71 case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:
72 break;
73
74 default:
75 return EFI_INVALID_PARAMETER;
76 }
77
78 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
79
80 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
81
82 NewPrivateFile = AllocateCopyPool (sizeof (EMU_EFI_FILE_PRIVATE), PrivateFile);
83 if (NewPrivateFile == NULL) {
84 Status = EFI_OUT_OF_RESOURCES;
85 goto Done;
86 }
87
88 Status = PrivateFile->Io->Open (PrivateFile->Io, &NewPrivateFile->Io, FileName, OpenMode, Attributes);
89 if (!EFI_ERROR (Status)) {
90 *NewHandle = &NewPrivateFile->EfiFile;
91 } else {
92 *NewHandle = NULL;
93 FreePool (NewPrivateFile);
94 }
95
96Done:
97 gBS->RestoreTPL (OldTpl);
98
99 return Status;
100}
101
111EFIAPI
112EmuSimpleFileSystemClose (
114 )
115{
116 EFI_STATUS Status;
117 EMU_EFI_FILE_PRIVATE *PrivateFile;
118 EFI_TPL OldTpl;
119
120 if (This == NULL) {
121 return EFI_INVALID_PARAMETER;
122 }
123
124 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
125
126 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
127
128 Status = PrivateFile->Io->Close (PrivateFile->Io);
129 if (!EFI_ERROR (Status)) {
130 gBS->FreePool (PrivateFile);
131 }
132
133 gBS->RestoreTPL (OldTpl);
134
135 return Status;
136}
137
148EFIAPI
149EmuSimpleFileSystemDelete (
151 )
152{
153 EFI_STATUS Status;
154 EMU_EFI_FILE_PRIVATE *PrivateFile;
155 EFI_TPL OldTpl;
156
157 if (This == NULL) {
158 return EFI_INVALID_PARAMETER;
159 }
160
161 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
162
163 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
164
165 Status = PrivateFile->Io->Delete (PrivateFile->Io);
166 if (!EFI_ERROR (Status)) {
167 gBS->FreePool (PrivateFile);
168 }
169
170 gBS->RestoreTPL (OldTpl);
171
172 return Status;
173}
174
190EFIAPI
191EmuSimpleFileSystemRead (
192 IN EFI_FILE_PROTOCOL *This,
193 IN OUT UINTN *BufferSize,
194 OUT VOID *Buffer
195 )
196{
197 EFI_STATUS Status;
198 EMU_EFI_FILE_PRIVATE *PrivateFile;
199 EFI_TPL OldTpl;
200
201 if ((This == NULL) || (BufferSize == NULL)) {
202 return EFI_INVALID_PARAMETER;
203 }
204
205 if ((*BufferSize != 0) && (Buffer == NULL)) {
206 // Buffer can be NULL if *BufferSize is zero
207 return EFI_INVALID_PARAMETER;
208 }
209
210 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
211
212 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
213
214 Status = PrivateFile->Io->Read (PrivateFile->Io, BufferSize, Buffer);
215
216 gBS->RestoreTPL (OldTpl);
217 return Status;
218}
219
239EFIAPI
240EmuSimpleFileSystemWrite (
241 IN EFI_FILE_PROTOCOL *This,
242 IN OUT UINTN *BufferSize,
243 IN VOID *Buffer
244 )
245{
246 EFI_STATUS Status;
247 EMU_EFI_FILE_PRIVATE *PrivateFile;
248 EFI_TPL OldTpl;
249
250 if ((This == NULL) || (BufferSize == NULL) || (Buffer == NULL)) {
251 return EFI_INVALID_PARAMETER;
252 }
253
254 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
255
256 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
257
258 Status = PrivateFile->Io->Write (PrivateFile->Io, BufferSize, Buffer);
259
260 gBS->RestoreTPL (OldTpl);
261 return Status;
262}
263
275EFIAPI
276EmuSimpleFileSystemGetPosition (
277 IN EFI_FILE_PROTOCOL *This,
278 OUT UINT64 *Position
279 )
280{
281 EFI_STATUS Status;
282 EMU_EFI_FILE_PRIVATE *PrivateFile;
283 EFI_TPL OldTpl;
284
285 if ((This == NULL) || (Position == NULL)) {
286 return EFI_INVALID_PARAMETER;
287 }
288
289 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
290
291 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
292
293 Status = PrivateFile->Io->GetPosition (PrivateFile->Io, Position);
294
295 gBS->RestoreTPL (OldTpl);
296 return Status;
297}
298
310EFIAPI
311EmuSimpleFileSystemSetPosition (
312 IN EFI_FILE_PROTOCOL *This,
313 IN UINT64 Position
314 )
315{
316 EFI_STATUS Status;
317 EMU_EFI_FILE_PRIVATE *PrivateFile;
318 EFI_TPL OldTpl;
319
320 if (This == NULL) {
321 return EFI_INVALID_PARAMETER;
322 }
323
324 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
325
326 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
327
328 Status = PrivateFile->Io->SetPosition (PrivateFile->Io, Position);
329
330 gBS->RestoreTPL (OldTpl);
331 return Status;
332}
333
353EFIAPI
354EmuSimpleFileSystemGetInfo (
355 IN EFI_FILE_PROTOCOL *This,
356 IN EFI_GUID *InformationType,
357 IN OUT UINTN *BufferSize,
358 OUT VOID *Buffer
359 )
360{
361 EFI_STATUS Status;
362 EMU_EFI_FILE_PRIVATE *PrivateFile;
363 EFI_TPL OldTpl;
364
365 if ((This == NULL) || (InformationType == NULL) || (BufferSize == NULL)) {
366 return EFI_INVALID_PARAMETER;
367 }
368
369 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
370
371 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
372
373 Status = PrivateFile->Io->GetInfo (PrivateFile->Io, InformationType, BufferSize, Buffer);
374
375 gBS->RestoreTPL (OldTpl);
376 return Status;
377}
378
397EFIAPI
398EmuSimpleFileSystemSetInfo (
399 IN EFI_FILE_PROTOCOL *This,
400 IN EFI_GUID *InformationType,
401 IN UINTN BufferSize,
402 IN VOID *Buffer
403 )
404{
405 EFI_STATUS Status;
406 EMU_EFI_FILE_PRIVATE *PrivateFile;
407 EFI_TPL OldTpl;
408
409 //
410 // Check for invalid parameters.
411 //
412 if ((This == NULL) || (InformationType == NULL) || (BufferSize == 0) || (Buffer == NULL)) {
413 return EFI_INVALID_PARAMETER;
414 }
415
416 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
417
418 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
419
420 Status = PrivateFile->Io->SetInfo (PrivateFile->Io, InformationType, BufferSize, Buffer);
421
422 gBS->RestoreTPL (OldTpl);
423 return Status;
424}
425
442EFIAPI
443EmuSimpleFileSystemFlush (
445 )
446{
447 EFI_STATUS Status;
448 EMU_EFI_FILE_PRIVATE *PrivateFile;
449 EFI_TPL OldTpl;
450
451 if (This == NULL) {
452 return EFI_INVALID_PARAMETER;
453 }
454
455 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
456
457 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
458
459 Status = PrivateFile->Io->Flush (PrivateFile->Io);
460
461 gBS->RestoreTPL (OldTpl);
462 return Status;
463}
464
481EFIAPI
482EmuSimpleFileSystemOpenVolume (
485 )
486{
487 EFI_STATUS Status;
489 EMU_EFI_FILE_PRIVATE *PrivateFile;
490 EFI_TPL OldTpl;
491
492 Status = EFI_UNSUPPORTED;
493
494 if ((This == NULL) || (Root == NULL)) {
495 return EFI_INVALID_PARAMETER;
496 }
497
498 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
499
500 Private = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This);
501
502 PrivateFile = AllocatePool (sizeof (EMU_EFI_FILE_PRIVATE));
503 if (PrivateFile == NULL) {
504 Status = EFI_OUT_OF_RESOURCES;
505 goto Done;
506 }
507
508 PrivateFile->Signature = EMU_EFI_FILE_PRIVATE_SIGNATURE;
509 PrivateFile->IoThunk = Private->IoThunk;
510 PrivateFile->SimpleFileSystem = This;
511
512 ZeroMem (&PrivateFile->EfiFile, sizeof (PrivateFile->EfiFile));
513 PrivateFile->EfiFile.Revision = EFI_FILE_PROTOCOL_REVISION;
514 PrivateFile->EfiFile.Open = EmuSimpleFileSystemOpen;
515 PrivateFile->EfiFile.Close = EmuSimpleFileSystemClose;
516 PrivateFile->EfiFile.Delete = EmuSimpleFileSystemDelete;
517 PrivateFile->EfiFile.Read = EmuSimpleFileSystemRead;
518 PrivateFile->EfiFile.Write = EmuSimpleFileSystemWrite;
519 PrivateFile->EfiFile.GetPosition = EmuSimpleFileSystemGetPosition;
520 PrivateFile->EfiFile.SetPosition = EmuSimpleFileSystemSetPosition;
521 PrivateFile->EfiFile.GetInfo = EmuSimpleFileSystemGetInfo;
522 PrivateFile->EfiFile.SetInfo = EmuSimpleFileSystemSetInfo;
523 PrivateFile->EfiFile.Flush = EmuSimpleFileSystemFlush;
524
525 *Root = &PrivateFile->EfiFile;
526
527 Status = Private->Io->OpenVolume (Private->Io, &PrivateFile->Io);
528 if (EFI_ERROR (Status)) {
529 goto Done;
530 }
531
533 "eng",
534 gEmuSimpleFileSystemComponentName.SupportedLanguages,
535 &Private->ControllerNameTable,
536 Private->IoThunk->ConfigString,
537 TRUE
538 );
539
541 "en",
542 gEmuSimpleFileSystemComponentName.SupportedLanguages,
543 &Private->ControllerNameTable,
544 Private->IoThunk->ConfigString,
545 FALSE
546 );
547
548Done:
549 if (EFI_ERROR (Status)) {
550 if (PrivateFile) {
551 gBS->FreePool (PrivateFile);
552 }
553
554 *Root = NULL;
555 }
556
557 gBS->RestoreTPL (OldTpl);
558
559 return Status;
560}
561
605EFIAPI
606EmuSimpleFileSystemDriverBindingSupported (
608 IN EFI_HANDLE ControllerHandle,
609 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
610 )
611{
612 EFI_STATUS Status;
613 EMU_IO_THUNK_PROTOCOL *EmuIoThunk;
614
615 //
616 // Open the IO Abstraction(s) needed to perform the supported test
617 //
618 Status = gBS->OpenProtocol (
619 ControllerHandle,
620 &gEmuIoThunkProtocolGuid,
621 (VOID **)&EmuIoThunk,
622 This->DriverBindingHandle,
623 ControllerHandle,
624 EFI_OPEN_PROTOCOL_BY_DRIVER
625 );
626 if (EFI_ERROR (Status)) {
627 return Status;
628 }
629
630 //
631 // Make sure GUID is for a File System handle.
632 //
633 Status = EFI_UNSUPPORTED;
634 if (CompareGuid (EmuIoThunk->Protocol, &gEfiSimpleFileSystemProtocolGuid)) {
635 Status = EFI_SUCCESS;
636 }
637
638 //
639 // Close the I/O Abstraction(s) used to perform the supported test
640 //
641 gBS->CloseProtocol (
642 ControllerHandle,
643 &gEmuIoThunkProtocolGuid,
644 This->DriverBindingHandle,
645 ControllerHandle
646 );
647
648 return Status;
649}
650
687EFIAPI
688EmuSimpleFileSystemDriverBindingStart (
690 IN EFI_HANDLE ControllerHandle,
691 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
692 )
693{
694 EFI_STATUS Status;
695 EMU_IO_THUNK_PROTOCOL *EmuIoThunk;
697
698 Private = NULL;
699
700 //
701 // Open the IO Abstraction(s) needed
702 //
703 Status = gBS->OpenProtocol (
704 ControllerHandle,
705 &gEmuIoThunkProtocolGuid,
706 (VOID **)&EmuIoThunk,
707 This->DriverBindingHandle,
708 ControllerHandle,
709 EFI_OPEN_PROTOCOL_BY_DRIVER
710 );
711 if (EFI_ERROR (Status)) {
712 return Status;
713 }
714
715 //
716 // Validate GUID
717 //
718 if (!CompareGuid (EmuIoThunk->Protocol, &gEfiSimpleFileSystemProtocolGuid)) {
719 Status = EFI_UNSUPPORTED;
720 goto Done;
721 }
722
724 if (Private == NULL) {
725 Status = EFI_OUT_OF_RESOURCES;
726 goto Done;
727 }
728
729 Status = EmuIoThunk->Open (EmuIoThunk);
730 if (EFI_ERROR (Status)) {
731 goto Done;
732 }
733
734 Private->Signature = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE;
735 Private->IoThunk = EmuIoThunk;
736 Private->Io = EmuIoThunk->Interface;
737
738 Private->SimpleFileSystem.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;
739 Private->SimpleFileSystem.OpenVolume = EmuSimpleFileSystemOpenVolume;
740
741 Private->ControllerNameTable = NULL;
742
744 "eng",
745 gEmuSimpleFileSystemComponentName.SupportedLanguages,
746 &Private->ControllerNameTable,
747 EmuIoThunk->ConfigString,
748 TRUE
749 );
750
752 "en",
753 gEmuSimpleFileSystemComponentName2.SupportedLanguages,
754 &Private->ControllerNameTable,
755 EmuIoThunk->ConfigString,
756 FALSE
757 );
758
759 Status = gBS->InstallMultipleProtocolInterfaces (
760 &ControllerHandle,
761 &gEfiSimpleFileSystemProtocolGuid,
762 &Private->SimpleFileSystem,
763 NULL
764 );
765
766Done:
767 if (EFI_ERROR (Status)) {
768 if (Private != NULL) {
769 if (Private->ControllerNameTable != NULL) {
770 FreeUnicodeStringTable (Private->ControllerNameTable);
771 }
772
773 gBS->FreePool (Private);
774 }
775
776 gBS->CloseProtocol (
777 ControllerHandle,
778 &gEmuIoThunkProtocolGuid,
779 This->DriverBindingHandle,
780 ControllerHandle
781 );
782 }
783
784 return Status;
785}
786
814EFIAPI
815EmuSimpleFileSystemDriverBindingStop (
817 IN EFI_HANDLE ControllerHandle,
818 IN UINTN NumberOfChildren,
819 IN EFI_HANDLE *ChildHandleBuffer
820 )
821{
822 EFI_STATUS Status;
823 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;
825
826 //
827 // Get our context back
828 //
829 Status = gBS->OpenProtocol (
830 ControllerHandle,
831 &gEfiSimpleFileSystemProtocolGuid,
832 (VOID **)&SimpleFileSystem,
833 This->DriverBindingHandle,
834 ControllerHandle,
835 EFI_OPEN_PROTOCOL_GET_PROTOCOL
836 );
837 if (EFI_ERROR (Status)) {
838 return EFI_UNSUPPORTED;
839 }
840
841 Private = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (SimpleFileSystem);
842
843 //
844 // Uninstall the Simple File System Protocol from ControllerHandle
845 //
846 Status = gBS->UninstallMultipleProtocolInterfaces (
847 ControllerHandle,
848 &gEfiSimpleFileSystemProtocolGuid,
849 &Private->SimpleFileSystem,
850 NULL
851 );
852 if (!EFI_ERROR (Status)) {
853 Status = gBS->CloseProtocol (
854 ControllerHandle,
855 &gEmuIoThunkProtocolGuid,
856 This->DriverBindingHandle,
857 ControllerHandle
858 );
859 ASSERT_EFI_ERROR (Status);
860 //
861 // Destroy the IO interface.
862 //
863 Status = Private->IoThunk->Close (Private->IoThunk);
864 ASSERT_EFI_ERROR (Status);
865 //
866 // Free our instance data
867 //
868 FreeUnicodeStringTable (Private->ControllerNameTable);
869 gBS->FreePool (Private);
870 }
871
872 return Status;
873}
874
875EFI_DRIVER_BINDING_PROTOCOL gEmuSimpleFileSystemDriverBinding = {
876 EmuSimpleFileSystemDriverBindingSupported,
877 EmuSimpleFileSystemDriverBindingStart,
878 EmuSimpleFileSystemDriverBindingStop,
879 0xa,
880 NULL,
881 NULL
882};
883
895EFIAPI
896InitializeEmuSimpleFileSystem (
897 IN EFI_HANDLE ImageHandle,
898 IN EFI_SYSTEM_TABLE *SystemTable
899 )
900{
901 EFI_STATUS Status;
902
904 ImageHandle,
905 SystemTable,
906 &gEmuSimpleFileSystemDriverBinding,
907 ImageHandle,
908 &gEmuSimpleFileSystemComponentName,
909 &gEmuSimpleFileSystemComponentName2
910 );
911 ASSERT_EFI_ERROR (Status);
912
913 return Status;
914}
UINT64 UINTN
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
#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
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
UINTN EFI_TPL
Definition: UefiBaseType.h:41
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
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 EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
EFI_STATUS EFIAPI FreeUnicodeStringTable(IN EFI_UNICODE_STRING_TABLE *UnicodeStringTable)
Definition: UefiLib.c:1257
CHAR16 * ConfigString
Only be valid after Open() is called.
Definition: EmuIoThunk.h:33
Definition: Base.h:213