]> git.proxmox.com Git - mirror_edk2.git/blob - EmulatorPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystem.c
28abfd6beff74de78b7807a86a200efb0a0a846c
[mirror_edk2.git] / EmulatorPkg / EmuSimpleFileSystemDxe / 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
7 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
8 Portions copyright (c) 2011, Apple Inc. All rights reserved.
9 This program and the accompanying materials
10 are licensed and made available under the terms and conditions of the BSD License
11 which accompanies this distribution. The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php
13
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16
17 **/
18
19 #include "EmuSimpleFileSystem.h"
20
21
22
23
24 /**
25 Opens a new file relative to the source file's location.
26
27 @param This The protocol instance pointer.
28 @param NewHandle Returns File Handle for FileName.
29 @param FileName Null terminated string. "\", ".", and ".." are supported.
30 @param OpenMode Open mode for file.
31 @param Attributes Only used for EFI_FILE_MODE_CREATE.
32
33 @retval EFI_SUCCESS The device was opened.
34 @retval EFI_NOT_FOUND The specified file could not be found on the device.
35 @retval EFI_NO_MEDIA The device has no media.
36 @retval EFI_MEDIA_CHANGED The media has changed.
37 @retval EFI_DEVICE_ERROR The device reported an error.
38 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
39 @retval EFI_ACCESS_DENIED The service denied access to the file.
40 @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.
41 @retval EFI_VOLUME_FULL The volume is full.
42
43 **/
44 EFI_STATUS
45 EFIAPI
46 EmuSimpleFileSystemOpen (
47 IN EFI_FILE_PROTOCOL *This,
48 OUT EFI_FILE_PROTOCOL **NewHandle,
49 IN CHAR16 *FileName,
50 IN UINT64 OpenMode,
51 IN UINT64 Attributes
52 )
53 {
54 EFI_STATUS Status;
55 EFI_TPL OldTpl;
56 EMU_EFI_FILE_PRIVATE *PrivateFile;
57 EMU_EFI_FILE_PRIVATE *NewPrivateFile;
58
59 //
60 // Check for obvious invalid parameters.
61 //
62 if (This == NULL || NewHandle == NULL || FileName == NULL) {
63 return EFI_INVALID_PARAMETER;
64 }
65
66 switch (OpenMode) {
67 case EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:
68 if (Attributes &~EFI_FILE_VALID_ATTR) {
69 return EFI_INVALID_PARAMETER;
70 }
71
72 if (Attributes & EFI_FILE_READ_ONLY) {
73 return EFI_INVALID_PARAMETER;
74 }
75
76 //
77 // fall through
78 //
79 case EFI_FILE_MODE_READ:
80 case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:
81 break;
82
83 default:
84 return EFI_INVALID_PARAMETER;
85 }
86
87 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
88
89 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
90
91 NewPrivateFile = AllocateCopyPool (sizeof (EMU_EFI_FILE_PRIVATE), PrivateFile);
92 if (NewPrivateFile == NULL) {
93 Status = EFI_OUT_OF_RESOURCES;
94 goto Done;
95 }
96
97
98 Status = PrivateFile->Io->Open (PrivateFile->Io, &NewPrivateFile->Io, FileName, OpenMode, Attributes);
99 if (!EFI_ERROR (Status)) {
100 *NewHandle = &NewPrivateFile->EfiFile;
101 } else {
102 *NewHandle = NULL;
103 FreePool (NewPrivateFile);
104 }
105
106 Done:
107 gBS->RestoreTPL (OldTpl);
108
109 return Status;
110 }
111
112
113
114 /**
115 Close the file handle
116
117 @param This Protocol instance pointer.
118
119 @retval EFI_SUCCESS The file was closed.
120
121 **/
122 EFI_STATUS
123 EFIAPI
124 EmuSimpleFileSystemClose (
125 IN EFI_FILE_PROTOCOL *This
126 )
127 {
128 EFI_STATUS Status;
129 EMU_EFI_FILE_PRIVATE *PrivateFile;
130 EFI_TPL OldTpl;
131
132 if (This == NULL) {
133 return EFI_INVALID_PARAMETER;
134 }
135
136 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
137
138 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
139
140 Status = PrivateFile->Io->Close (PrivateFile->Io);
141 if (!EFI_ERROR (Status)) {
142 gBS->FreePool (PrivateFile);
143 }
144
145 gBS->RestoreTPL (OldTpl);
146
147 return Status;
148 }
149
150
151 /**
152 Close and delete the file handle.
153
154 @param This Protocol instance pointer.
155
156 @retval EFI_SUCCESS The file was closed and deleted.
157 @retval EFI_WARN_DELETE_FAILURE The handle was closed but the file was not deleted.
158
159 **/
160 EFI_STATUS
161 EFIAPI
162 EmuSimpleFileSystemDelete (
163 IN EFI_FILE_PROTOCOL *This
164 )
165 {
166 EFI_STATUS Status;
167 EMU_EFI_FILE_PRIVATE *PrivateFile;
168 EFI_TPL OldTpl;
169
170 if (This == NULL) {
171 return EFI_INVALID_PARAMETER;
172 }
173
174 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
175
176 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
177
178 Status = PrivateFile->Io->Delete (PrivateFile->Io);
179 if (!EFI_ERROR (Status)) {
180 gBS->FreePool (PrivateFile);
181 }
182
183 gBS->RestoreTPL (OldTpl);
184
185 return Status;
186 }
187
188
189 /**
190 Read data from the file.
191
192 @param This Protocol instance pointer.
193 @param BufferSize On input size of buffer, on output amount of data in buffer.
194 @param Buffer The buffer in which data is read.
195
196 @retval EFI_SUCCESS Data was read.
197 @retval EFI_NO_MEDIA The device has no media.
198 @retval EFI_DEVICE_ERROR The device reported an error.
199 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
200 @retval EFI_BUFFER_TO_SMALL BufferSize is too small. BufferSize contains required size.
201
202 **/
203 EFI_STATUS
204 EFIAPI
205 EmuSimpleFileSystemRead (
206 IN EFI_FILE_PROTOCOL *This,
207 IN OUT UINTN *BufferSize,
208 OUT VOID *Buffer
209 )
210 {
211 EFI_STATUS Status;
212 EMU_EFI_FILE_PRIVATE *PrivateFile;
213 EFI_TPL OldTpl;
214
215 if (This == NULL || BufferSize == NULL) {
216 return EFI_INVALID_PARAMETER;
217 }
218
219 if ((*BufferSize != 0) && (Buffer == NULL)) {
220 // Buffer can be NULL if *BufferSize is zero
221 return EFI_INVALID_PARAMETER;
222 }
223
224 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
225
226 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
227
228 Status = PrivateFile->Io->Read (PrivateFile->Io, BufferSize, Buffer);
229
230 gBS->RestoreTPL (OldTpl);
231 return Status;
232 }
233
234
235 /**
236 Write data to a file.
237
238 @param This Protocol instance pointer.
239 @param BufferSize On input size of buffer, on output amount of data in buffer.
240 @param Buffer The buffer in which data to write.
241
242 @retval EFI_SUCCESS Data was written.
243 @retval EFI_UNSUPPORTED Writes to Open directory are not supported.
244 @retval EFI_NO_MEDIA The device has no media.
245 @retval EFI_DEVICE_ERROR The device reported an error.
246 @retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file.
247 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
248 @retval EFI_WRITE_PROTECTED The device is write protected.
249 @retval EFI_ACCESS_DENIED The file was open for read only.
250 @retval EFI_VOLUME_FULL The volume is full.
251
252 **/
253 EFI_STATUS
254 EFIAPI
255 EmuSimpleFileSystemWrite (
256 IN EFI_FILE_PROTOCOL *This,
257 IN OUT UINTN *BufferSize,
258 IN VOID *Buffer
259 )
260 {
261 EFI_STATUS Status;
262 EMU_EFI_FILE_PRIVATE *PrivateFile;
263 EFI_TPL OldTpl;
264
265 if (This == NULL || BufferSize == NULL || Buffer == NULL) {
266 return EFI_INVALID_PARAMETER;
267 }
268
269 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
270
271 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
272
273 Status = PrivateFile->Io->Write (PrivateFile->Io, BufferSize, Buffer);
274
275 gBS->RestoreTPL (OldTpl);
276 return Status;
277 }
278
279
280 /**
281 Get a file's current position
282
283 @param This Protocol instance pointer.
284 @param Position Byte position from the start of the file.
285
286 @retval EFI_SUCCESS Position was updated.
287 @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open.
288
289 **/
290 EFI_STATUS
291 EFIAPI
292 EmuSimpleFileSystemGetPosition (
293 IN EFI_FILE_PROTOCOL *This,
294 OUT UINT64 *Position
295 )
296 {
297 EFI_STATUS Status;
298 EMU_EFI_FILE_PRIVATE *PrivateFile;
299 EFI_TPL OldTpl;
300
301 if (This == NULL || Position == NULL) {
302 return EFI_INVALID_PARAMETER;
303 }
304
305 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
306
307 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
308
309 Status = PrivateFile->Io->GetPosition (PrivateFile->Io, Position);
310
311 gBS->RestoreTPL (OldTpl);
312 return Status;
313 }
314
315
316
317 /**
318 Set file's current position
319
320 @param This Protocol instance pointer.
321 @param Position Byte position from the start of the file.
322
323 @retval EFI_SUCCESS Position was updated.
324 @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open..
325
326 **/
327 EFI_STATUS
328 EFIAPI
329 EmuSimpleFileSystemSetPosition (
330 IN EFI_FILE_PROTOCOL *This,
331 IN UINT64 Position
332 )
333 {
334 EFI_STATUS Status;
335 EMU_EFI_FILE_PRIVATE *PrivateFile;
336 EFI_TPL OldTpl;
337
338 if (This == NULL) {
339 return EFI_INVALID_PARAMETER;
340 }
341
342 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
343
344 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
345
346 Status = PrivateFile->Io->SetPosition (PrivateFile->Io, Position);
347
348 gBS->RestoreTPL (OldTpl);
349 return Status;
350 }
351
352
353 /**
354 Get information about a file.
355
356 @param This Protocol instance pointer.
357 @param InformationType Type of information to return in Buffer.
358 @param BufferSize On input size of buffer, on output amount of data in buffer.
359 @param Buffer The buffer to return data.
360
361 @retval EFI_SUCCESS Data was returned.
362 @retval EFI_UNSUPPORTED InformationType is not supported.
363 @retval EFI_NO_MEDIA The device has no media.
364 @retval EFI_DEVICE_ERROR The device reported an error.
365 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
366 @retval EFI_WRITE_PROTECTED The device is write protected.
367 @retval EFI_ACCESS_DENIED The file was open for read only.
368 @retval EFI_BUFFER_TOO_SMALL Buffer was too small; required size returned in BufferSize.
369
370 **/
371 EFI_STATUS
372 EFIAPI
373 EmuSimpleFileSystemGetInfo (
374 IN EFI_FILE_PROTOCOL *This,
375 IN EFI_GUID *InformationType,
376 IN OUT UINTN *BufferSize,
377 OUT VOID *Buffer
378 )
379 {
380 EFI_STATUS Status;
381 EMU_EFI_FILE_PRIVATE *PrivateFile;
382 EFI_TPL OldTpl;
383
384 if (This == NULL || InformationType == NULL || BufferSize == NULL) {
385 return EFI_INVALID_PARAMETER;
386 }
387
388 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
389
390 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
391
392 Status = PrivateFile->Io->GetInfo (PrivateFile->Io, InformationType, BufferSize, Buffer);
393
394 gBS->RestoreTPL (OldTpl);
395 return Status;
396 }
397
398
399 /**
400 Set information about a file
401
402 @param File Protocol instance pointer.
403 @param InformationType Type of information in Buffer.
404 @param BufferSize Size of buffer.
405 @param Buffer The data to write.
406
407 @retval EFI_SUCCESS Data was set.
408 @retval EFI_UNSUPPORTED InformationType is not supported.
409 @retval EFI_NO_MEDIA The device has no media.
410 @retval EFI_DEVICE_ERROR The device reported an error.
411 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
412 @retval EFI_WRITE_PROTECTED The device is write protected.
413 @retval EFI_ACCESS_DENIED The file was open for read only.
414
415 **/
416 EFI_STATUS
417 EFIAPI
418 EmuSimpleFileSystemSetInfo (
419 IN EFI_FILE_PROTOCOL*This,
420 IN EFI_GUID *InformationType,
421 IN UINTN BufferSize,
422 IN VOID *Buffer
423 )
424 {
425 EFI_STATUS Status;
426 EMU_EFI_FILE_PRIVATE *PrivateFile;
427 EFI_TPL OldTpl;
428
429 //
430 // Check for invalid parameters.
431 //
432 if (This == NULL || InformationType == NULL || BufferSize == 0 || Buffer == NULL) {
433 return EFI_INVALID_PARAMETER;
434 }
435
436 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
437
438 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
439
440 Status = PrivateFile->Io->SetInfo (PrivateFile->Io, InformationType, BufferSize, Buffer);
441
442 gBS->RestoreTPL (OldTpl);
443 return Status;
444 }
445
446
447 /**
448 Flush data back for the file handle.
449
450 @param This Protocol instance pointer.
451
452 @retval EFI_SUCCESS Data was flushed.
453 @retval EFI_UNSUPPORTED Writes to Open directory are not supported.
454 @retval EFI_NO_MEDIA The device has no media.
455 @retval EFI_DEVICE_ERROR The device reported an error.
456 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
457 @retval EFI_WRITE_PROTECTED The device is write protected.
458 @retval EFI_ACCESS_DENIED The file was open for read only.
459 @retval EFI_VOLUME_FULL The volume is full.
460
461 **/
462 EFI_STATUS
463 EFIAPI
464 EmuSimpleFileSystemFlush (
465 IN EFI_FILE_PROTOCOL *This
466 )
467 {
468 EFI_STATUS Status;
469 EMU_EFI_FILE_PRIVATE *PrivateFile;
470 EFI_TPL OldTpl;
471
472 if (This == NULL) {
473 return EFI_INVALID_PARAMETER;
474 }
475
476 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
477
478 PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
479
480 Status = PrivateFile->Io->Flush (PrivateFile->Io);
481
482 gBS->RestoreTPL (OldTpl);
483 return Status;
484 }
485
486
487
488 /**
489 Open the root directory on a volume.
490
491 @param This Protocol instance pointer.
492 @param Root Returns an Open file handle for the root directory
493
494 @retval EFI_SUCCESS The device was opened.
495 @retval EFI_UNSUPPORTED This volume does not support the file system.
496 @retval EFI_NO_MEDIA The device has no media.
497 @retval EFI_DEVICE_ERROR The device reported an error.
498 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
499 @retval EFI_ACCESS_DENIED The service denied access to the file.
500 @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.
501
502 **/
503 EFI_STATUS
504 EFIAPI
505 EmuSimpleFileSystemOpenVolume (
506 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
507 OUT EFI_FILE_PROTOCOL **Root
508 )
509 {
510 EFI_STATUS Status;
511 EMU_SIMPLE_FILE_SYSTEM_PRIVATE *Private;
512 EMU_EFI_FILE_PRIVATE *PrivateFile;
513 EFI_TPL OldTpl;
514
515 Status = EFI_UNSUPPORTED;
516
517 if (This == NULL || Root == NULL) {
518 return EFI_INVALID_PARAMETER;
519 }
520
521 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
522
523 Private = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This);
524
525 PrivateFile = AllocatePool (sizeof (EMU_EFI_FILE_PRIVATE));
526 if (PrivateFile == NULL) {
527 Status = EFI_OUT_OF_RESOURCES;
528 goto Done;
529 }
530
531 PrivateFile->Signature = EMU_EFI_FILE_PRIVATE_SIGNATURE;
532 PrivateFile->IoThunk = Private->IoThunk;
533 PrivateFile->SimpleFileSystem = This;
534
535 ZeroMem (&PrivateFile->EfiFile, sizeof (PrivateFile->EfiFile));
536 PrivateFile->EfiFile.Revision = EFI_FILE_PROTOCOL_REVISION;
537 PrivateFile->EfiFile.Open = EmuSimpleFileSystemOpen;
538 PrivateFile->EfiFile.Close = EmuSimpleFileSystemClose;
539 PrivateFile->EfiFile.Delete = EmuSimpleFileSystemDelete;
540 PrivateFile->EfiFile.Read = EmuSimpleFileSystemRead;
541 PrivateFile->EfiFile.Write = EmuSimpleFileSystemWrite;
542 PrivateFile->EfiFile.GetPosition = EmuSimpleFileSystemGetPosition;
543 PrivateFile->EfiFile.SetPosition = EmuSimpleFileSystemSetPosition;
544 PrivateFile->EfiFile.GetInfo = EmuSimpleFileSystemGetInfo;
545 PrivateFile->EfiFile.SetInfo = EmuSimpleFileSystemSetInfo;
546 PrivateFile->EfiFile.Flush = EmuSimpleFileSystemFlush;
547
548 *Root = &PrivateFile->EfiFile;
549
550 Status = Private->Io->OpenVolume (Private->Io, &PrivateFile->Io);
551 if (EFI_ERROR (Status)) {
552 goto Done;
553 }
554
555 AddUnicodeString2 (
556 "eng",
557 gEmuSimpleFileSystemComponentName.SupportedLanguages,
558 &Private->ControllerNameTable,
559 Private->IoThunk->ConfigString,
560 TRUE
561 );
562
563 AddUnicodeString2 (
564 "en",
565 gEmuSimpleFileSystemComponentName.SupportedLanguages,
566 &Private->ControllerNameTable,
567 Private->IoThunk->ConfigString,
568 FALSE
569 );
570
571
572 Done:
573 if (EFI_ERROR (Status)) {
574 if (PrivateFile) {
575 gBS->FreePool (PrivateFile);
576 }
577
578 *Root = NULL;
579 }
580
581 gBS->RestoreTPL (OldTpl);
582
583 return Status;
584 }
585
586 /**
587 Tests to see if this driver supports a given controller. If a child device is provided,
588 it further tests to see if this driver supports creating a handle for the specified child device.
589
590 This function checks to see if the driver specified by This supports the device specified by
591 ControllerHandle. Drivers will typically use the device path attached to
592 ControllerHandle and/or the services from the bus I/O abstraction attached to
593 ControllerHandle to determine if the driver supports ControllerHandle. This function
594 may be called many times during platform initialization. In order to reduce boot times, the tests
595 performed by this function must be very small, and take as little time as possible to execute. This
596 function must not change the state of any hardware devices, and this function must be aware that the
597 device specified by ControllerHandle may already be managed by the same driver or a
598 different driver. This function must match its calls to AllocatePages() with FreePages(),
599 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
600 Because ControllerHandle may have been previously started by the same driver, if a protocol is
601 already in the opened state, then it must not be closed with CloseProtocol(). This is required
602 to guarantee the state of ControllerHandle is not modified by this function.
603
604 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
605 @param[in] ControllerHandle The handle of the controller to test. This handle
606 must support a protocol interface that supplies
607 an I/O abstraction to the driver.
608 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
609 parameter is ignored by device drivers, and is optional for bus
610 drivers. For bus drivers, if this parameter is not NULL, then
611 the bus driver must determine if the bus controller specified
612 by ControllerHandle and the child controller specified
613 by RemainingDevicePath are both supported by this
614 bus driver.
615
616 @retval EFI_SUCCESS The device specified by ControllerHandle and
617 RemainingDevicePath is supported by the driver specified by This.
618 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
619 RemainingDevicePath is already being managed by the driver
620 specified by This.
621 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
622 RemainingDevicePath is already being managed by a different
623 driver or an application that requires exclusive access.
624 Currently not implemented.
625 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
626 RemainingDevicePath is not supported by the driver specified by This.
627 **/
628 EFI_STATUS
629 EFIAPI
630 EmuSimpleFileSystemDriverBindingSupported (
631 IN EFI_DRIVER_BINDING_PROTOCOL *This,
632 IN EFI_HANDLE ControllerHandle,
633 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
634 )
635 {
636 EFI_STATUS Status;
637 EMU_IO_THUNK_PROTOCOL *EmuIoThunk;
638
639 //
640 // Open the IO Abstraction(s) needed to perform the supported test
641 //
642 Status = gBS->OpenProtocol (
643 ControllerHandle,
644 &gEmuIoThunkProtocolGuid,
645 (VOID **)&EmuIoThunk,
646 This->DriverBindingHandle,
647 ControllerHandle,
648 EFI_OPEN_PROTOCOL_BY_DRIVER
649 );
650 if (EFI_ERROR (Status)) {
651 return Status;
652 }
653
654 //
655 // Make sure GUID is for a File System handle.
656 //
657 Status = EFI_UNSUPPORTED;
658 if (CompareGuid (EmuIoThunk->Protocol, &gEfiSimpleFileSystemProtocolGuid)) {
659 Status = EFI_SUCCESS;
660 }
661
662 //
663 // Close the I/O Abstraction(s) used to perform the supported test
664 //
665 gBS->CloseProtocol (
666 ControllerHandle,
667 &gEmuIoThunkProtocolGuid,
668 This->DriverBindingHandle,
669 ControllerHandle
670 );
671
672 return Status;
673 }
674
675
676
677 /**
678 Starts a device controller or a bus controller.
679
680 The Start() function is designed to be invoked from the EFI boot service ConnectController().
681 As a result, much of the error checking on the parameters to Start() has been moved into this
682 common boot service. It is legal to call Start() from other locations,
683 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
684 1. ControllerHandle must be a valid EFI_HANDLE.
685 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
686 EFI_DEVICE_PATH_PROTOCOL.
687 3. Prior to calling Start(), the Supported() function for the driver specified by This must
688 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
689
690 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
691 @param[in] ControllerHandle The handle of the controller to start. This handle
692 must support a protocol interface that supplies
693 an I/O abstraction to the driver.
694 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
695 parameter is ignored by device drivers, and is optional for bus
696 drivers. For a bus driver, if this parameter is NULL, then handles
697 for all the children of Controller are created by this driver.
698 If this parameter is not NULL and the first Device Path Node is
699 not the End of Device Path Node, then only the handle for the
700 child device specified by the first Device Path Node of
701 RemainingDevicePath is created by this driver.
702 If the first Device Path Node of RemainingDevicePath is
703 the End of Device Path Node, no child handle is created by this
704 driver.
705
706 @retval EFI_SUCCESS The device was started.
707 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
708 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
709 @retval Others The driver failded to start the device.
710
711 **/
712 EFI_STATUS
713 EFIAPI
714 EmuSimpleFileSystemDriverBindingStart (
715 IN EFI_DRIVER_BINDING_PROTOCOL *This,
716 IN EFI_HANDLE ControllerHandle,
717 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
718 )
719 {
720 EFI_STATUS Status;
721 EMU_IO_THUNK_PROTOCOL *EmuIoThunk;
722 EMU_SIMPLE_FILE_SYSTEM_PRIVATE *Private;
723
724 Private = NULL;
725
726 //
727 // Open the IO Abstraction(s) needed
728 //
729 Status = gBS->OpenProtocol (
730 ControllerHandle,
731 &gEmuIoThunkProtocolGuid,
732 (VOID **)&EmuIoThunk,
733 This->DriverBindingHandle,
734 ControllerHandle,
735 EFI_OPEN_PROTOCOL_BY_DRIVER
736 );
737 if (EFI_ERROR (Status)) {
738 return Status;
739 }
740
741 //
742 // Validate GUID
743 //
744 if (!CompareGuid (EmuIoThunk->Protocol, &gEfiSimpleFileSystemProtocolGuid)) {
745 Status = EFI_UNSUPPORTED;
746 goto Done;
747 }
748
749 Private = AllocateZeroPool (sizeof (EMU_SIMPLE_FILE_SYSTEM_PRIVATE));
750 if (Private == NULL) {
751 Status = EFI_OUT_OF_RESOURCES;
752 goto Done;
753 }
754
755 Status = EmuIoThunk->Open (EmuIoThunk);
756 if (EFI_ERROR (Status)) {
757 goto Done;
758 }
759
760 Private->Signature = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE;
761 Private->IoThunk = EmuIoThunk;
762 Private->Io = EmuIoThunk->Interface;
763
764 Private->SimpleFileSystem.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;
765 Private->SimpleFileSystem.OpenVolume = EmuSimpleFileSystemOpenVolume;
766
767 Private->ControllerNameTable = NULL;
768
769 AddUnicodeString2 (
770 "eng",
771 gEmuSimpleFileSystemComponentName.SupportedLanguages,
772 &Private->ControllerNameTable,
773 EmuIoThunk->ConfigString,
774 TRUE
775 );
776
777 AddUnicodeString2 (
778 "en",
779 gEmuSimpleFileSystemComponentName2.SupportedLanguages,
780 &Private->ControllerNameTable,
781 EmuIoThunk->ConfigString,
782 FALSE
783 );
784
785 Status = gBS->InstallMultipleProtocolInterfaces (
786 &ControllerHandle,
787 &gEfiSimpleFileSystemProtocolGuid, &Private->SimpleFileSystem,
788 NULL
789 );
790
791 Done:
792 if (EFI_ERROR (Status)) {
793 if (Private != NULL) {
794 if (Private->ControllerNameTable != NULL) {
795 FreeUnicodeStringTable (Private->ControllerNameTable);
796 }
797
798 gBS->FreePool (Private);
799
800 }
801
802 gBS->CloseProtocol (
803 ControllerHandle,
804 &gEmuIoThunkProtocolGuid,
805 This->DriverBindingHandle,
806 ControllerHandle
807 );
808 }
809
810 return Status;
811 }
812
813
814 /**
815 Stops a device controller or a bus controller.
816
817 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
818 As a result, much of the error checking on the parameters to Stop() has been moved
819 into this common boot service. It is legal to call Stop() from other locations,
820 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
821 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
822 same driver's Start() function.
823 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
824 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
825 Start() function, and the Start() function must have called OpenProtocol() on
826 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
827
828 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
829 @param[in] ControllerHandle A handle to the device being stopped. The handle must
830 support a bus specific I/O protocol for the driver
831 to use to stop the device.
832 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
833 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
834 if NumberOfChildren is 0.
835
836 @retval EFI_SUCCESS The device was stopped.
837 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
838
839 **/
840 EFI_STATUS
841 EFIAPI
842 EmuSimpleFileSystemDriverBindingStop (
843 IN EFI_DRIVER_BINDING_PROTOCOL *This,
844 IN EFI_HANDLE ControllerHandle,
845 IN UINTN NumberOfChildren,
846 IN EFI_HANDLE *ChildHandleBuffer
847 )
848 {
849 EFI_STATUS Status;
850 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;
851 EMU_SIMPLE_FILE_SYSTEM_PRIVATE *Private;
852
853 //
854 // Get our context back
855 //
856 Status = gBS->OpenProtocol (
857 ControllerHandle,
858 &gEfiSimpleFileSystemProtocolGuid,
859 (VOID **)&SimpleFileSystem,
860 This->DriverBindingHandle,
861 ControllerHandle,
862 EFI_OPEN_PROTOCOL_GET_PROTOCOL
863 );
864 if (EFI_ERROR (Status)) {
865 return EFI_UNSUPPORTED;
866 }
867
868 Private = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (SimpleFileSystem);
869
870 //
871 // Uninstall the Simple File System Protocol from ControllerHandle
872 //
873 Status = gBS->UninstallMultipleProtocolInterfaces (
874 ControllerHandle,
875 &gEfiSimpleFileSystemProtocolGuid, &Private->SimpleFileSystem,
876 NULL
877 );
878 if (!EFI_ERROR (Status)) {
879 Status = gBS->CloseProtocol (
880 ControllerHandle,
881 &gEmuIoThunkProtocolGuid,
882 This->DriverBindingHandle,
883 ControllerHandle
884 );
885 ASSERT_EFI_ERROR (Status);
886 //
887 // Destroy the IO interface.
888 //
889 Status = Private->IoThunk->Close (Private->IoThunk);
890 ASSERT_EFI_ERROR (Status);
891 //
892 // Free our instance data
893 //
894 FreeUnicodeStringTable (Private->ControllerNameTable);
895 gBS->FreePool (Private);
896 }
897
898 return Status;
899 }
900
901
902 EFI_DRIVER_BINDING_PROTOCOL gEmuSimpleFileSystemDriverBinding = {
903 EmuSimpleFileSystemDriverBindingSupported,
904 EmuSimpleFileSystemDriverBindingStart,
905 EmuSimpleFileSystemDriverBindingStop,
906 0xa,
907 NULL,
908 NULL
909 };
910
911
912
913
914 /**
915 The user Entry Point for module EmuSimpleFileSystem. The user code starts with this function.
916
917 @param[in] ImageHandle The firmware allocated handle for the EFI image.
918 @param[in] SystemTable A pointer to the EFI System Table.
919
920 @retval EFI_SUCCESS The entry point is executed successfully.
921 @retval other Some error occurs when executing this entry point.
922
923 **/
924 EFI_STATUS
925 EFIAPI
926 InitializeEmuSimpleFileSystem(
927 IN EFI_HANDLE ImageHandle,
928 IN EFI_SYSTEM_TABLE *SystemTable
929 )
930 {
931 EFI_STATUS Status;
932
933 Status = EfiLibInstallDriverBindingComponentName2 (
934 ImageHandle,
935 SystemTable,
936 &gEmuSimpleFileSystemDriverBinding,
937 ImageHandle,
938 &gEmuSimpleFileSystemComponentName,
939 &gEmuSimpleFileSystemComponentName2
940 );
941 ASSERT_EFI_ERROR (Status);
942
943 return Status;
944 }