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