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