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