]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemEntryPoint.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / FvSimpleFileSystemDxe / FvSimpleFileSystemEntryPoint.c
CommitLineData
9da91aea
BJ
1/** @file\r
2 This driver uses the EFI_FIRMWARE_VOLUME2_PROTOCOL to expose files in firmware\r
3 volumes via the the EFI_SIMPLE_FILESYSTEM_PROTOCOL and EFI_FILE_PROTOCOL.\r
4\r
5 It will expose a single directory, containing one file for each file in the firmware\r
6 volume. If a file has a UI section, its contents will be used as a filename.\r
7 Otherwise, a string representation of the GUID will be used.\r
8 Files of an executable type (That is PEIM, DRIVER, COMBINED_PEIM_DRIVER and APPLICATION)\r
9 will have ".efi" added to their filename.\r
10\r
11 Its primary intended use is to be able to start EFI applications embedded in FVs\r
12 from the UEFI shell. It is entirely read-only.\r
13\r
14Copyright (c) 2014, ARM Limited. All rights reserved.\r
b07c9665 15Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>\r
9da91aea 16\r
9d510e61 17SPDX-License-Identifier: BSD-2-Clause-Patent\r
9da91aea
BJ
18\r
19**/\r
20\r
21#include "FvSimpleFileSystemInternal.h"\r
22\r
23EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollation = NULL;\r
24\r
25//\r
26// A Guid string is 32 hex characters with 4 hyphens and a NULL-terminated char: 37 characters total\r
27//\r
28#define GUID_STRING_SIZE (37 * sizeof (CHAR16))\r
29\r
30#define FVFS_VOLUME_LABEL_PREFIX L"Firmware Volume: "\r
31#define FVFS_VOLUME_LABEL_SIZE (sizeof (FVFS_VOLUME_LABEL_PREFIX) + GUID_STRING_SIZE - sizeof (CHAR16))\r
32#define FVFS_FALLBACK_VOLUME_LABEL L"Firmware Volume"\r
33\r
34//\r
35// Template for EFI_SIMPLE_FILE_SYSTEM_PROTOCOL data structure.\r
36//\r
37EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mSimpleFsTemplate = {\r
38 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,\r
39 FvSimpleFileSystemOpenVolume\r
40};\r
41\r
42//\r
43// Template for EFI_DRIVER_BINDING_PROTOCOL data structure.\r
44//\r
45EFI_DRIVER_BINDING_PROTOCOL mDriverBinding = {\r
46 FvSimpleFileSystemDriverSupported,\r
47 FvSimpleFileSystemDriverStart,\r
48 FvSimpleFileSystemDriverStop,\r
49 0,\r
50 NULL,\r
51 NULL\r
52};\r
53\r
54/**\r
55 Open the root directory on a volume.\r
56\r
57 @param This A pointer to the volume to open the root directory.\r
58 @param RootFile A pointer to the location to return the opened file handle for the\r
59 root directory.\r
60\r
61 @retval EFI_SUCCESS The device was opened.\r
62 @retval EFI_UNSUPPORTED This volume does not support the requested file system type.\r
63 @retval EFI_NO_MEDIA The device has no medium.\r
64 @retval EFI_DEVICE_ERROR The device reported an error.\r
65 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
66 @retval EFI_ACCESS_DENIED The service denied access to the file.\r
67 @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.\r
68 @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no\r
69 longer supported. Any existing file handles for this volume are\r
70 no longer valid. To access the files on the new medium, the\r
71 volume must be reopened with OpenVolume().\r
72\r
73**/\r
74EFI_STATUS\r
75EFIAPI\r
76FvSimpleFileSystemOpenVolume (\r
77 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,\r
78 OUT EFI_FILE_PROTOCOL **RootFile\r
79 )\r
80{\r
81 EFI_STATUS Status;\r
82 FV_FILESYSTEM_FILE *Root;\r
83 CHAR16 *UiSection;\r
84 EFI_GUID NameGuid;\r
85 EFI_FV_FILE_ATTRIBUTES Attributes;\r
86 UINT32 Authentication;\r
87 UINTN Key;\r
88 EFI_FV_FILETYPE FileType;\r
89 UINTN Size;\r
90 FV_FILESYSTEM_INSTANCE *Instance;\r
91 FV_FILESYSTEM_FILE_INFO *FvFileInfo;\r
92 EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;\r
93 CHAR16 *Name;\r
94 UINTN NameLen;\r
95 UINTN NumChars;\r
96 UINTN DestMax;\r
97\r
98 Instance = FVFS_INSTANCE_FROM_SIMPLE_FS_THIS (This);\r
99 Status = EFI_SUCCESS;\r
100\r
101 if (Instance->Root == NULL) {\r
102 //\r
103 // Allocate file structure for root file\r
104 //\r
105 Root = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE));\r
106 if (Root == NULL) {\r
107 return EFI_OUT_OF_RESOURCES;\r
108 }\r
109\r
110 Instance->Root = Root;\r
111 Root->Instance = Instance;\r
112 Root->Signature = FVFS_FILE_SIGNATURE;\r
113 CopyMem (&Root->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate));\r
114 Root->FvFileInfo = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE_INFO));\r
115 if (Root->FvFileInfo == NULL) {\r
116 return EFI_OUT_OF_RESOURCES;\r
117 }\r
118 Root->FvFileInfo->FileInfo.Size = sizeof (EFI_FILE_INFO);\r
119 Root->FvFileInfo->FileInfo.Attribute = EFI_FILE_DIRECTORY | EFI_FILE_READ_ONLY;\r
120\r
121 //\r
122 // Populate the instance's list of files. We consider anything a file that\r
123 // has a UI_SECTION, which we consider to be its filename.\r
124 //\r
125 FvProtocol = Instance->FvProtocol;\r
126 //\r
127 // Allocate Key\r
128 //\r
129 Key = 0;\r
130\r
131 do {\r
132 FileType = EFI_FV_FILETYPE_ALL;\r
133\r
134 Status = FvProtocol->GetNextFile (\r
135 FvProtocol,\r
136 &Key,\r
137 &FileType,\r
138 &NameGuid,\r
139 &Attributes,\r
140 &Size\r
141 );\r
142 if (EFI_ERROR (Status)) {\r
143 ASSERT (Status == EFI_NOT_FOUND);\r
144 break;\r
145 }\r
146\r
147 //\r
148 // Get a file's name: If it has a UI section, use that, otherwise use\r
149 // its NameGuid.\r
150 //\r
151 UiSection = NULL;\r
152 Status = FvProtocol->ReadSection (\r
153 FvProtocol,\r
154 &NameGuid,\r
155 EFI_SECTION_USER_INTERFACE,\r
156 0,\r
157 (VOID **)&UiSection,\r
158 &Size,\r
159 &Authentication\r
160 );\r
161 if (!EFI_ERROR (Status)) {\r
162 Name = UiSection;\r
163 } else {\r
164 Name = AllocateZeroPool (GUID_STRING_SIZE);\r
165 if (Name == NULL) {\r
166 return EFI_OUT_OF_RESOURCES;\r
167 }\r
168 NumChars = UnicodeSPrint (Name, GUID_STRING_SIZE, L"%g", &NameGuid);\r
169 ASSERT ((NumChars + 1) * sizeof (CHAR16) == GUID_STRING_SIZE);\r
170 }\r
171\r
172 //\r
173 // Found a file.\r
174 // Allocate a file structure and populate it.\r
175 //\r
176 NameLen = StrSize (Name);\r
177 if (FV_FILETYPE_IS_EXECUTABLE (FileType)) {\r
178 NameLen += StrSize (L".efi") - sizeof (CHAR16);\r
179 }\r
180\r
181 FvFileInfo = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE_INFO) + NameLen - sizeof (CHAR16));\r
182 if (FvFileInfo == NULL) {\r
183 return EFI_OUT_OF_RESOURCES;\r
184 }\r
185\r
186 FvFileInfo->Signature = FVFS_FILE_INFO_SIGNATURE;\r
187 InitializeListHead (&FvFileInfo->Link);\r
188 CopyMem (&FvFileInfo->NameGuid, &NameGuid, sizeof (EFI_GUID));\r
189 FvFileInfo->Type = FileType;\r
190\r
191 //\r
192 // Add ".efi" to filenames of drivers and applications.\r
193 //\r
194 DestMax = NameLen / sizeof (CHAR16);\r
195 Status = StrnCpyS (&FvFileInfo->FileInfo.FileName[0], DestMax, Name, StrLen (Name));\r
196 ASSERT_EFI_ERROR (Status);\r
197\r
198 if (FV_FILETYPE_IS_EXECUTABLE (FileType)) {\r
199 Status = StrnCatS (&FvFileInfo->FileInfo.FileName[0], DestMax, L".efi", StrLen (L".efi"));\r
200 ASSERT_EFI_ERROR (Status);\r
201 }\r
202\r
203 FvFileInfo->FileInfo.Size = sizeof (EFI_FILE_INFO) + NameLen - sizeof (CHAR16);\r
204 Status = FvFsGetFileSize (FvProtocol, FvFileInfo);\r
205 ASSERT_EFI_ERROR (Status);\r
206 FvFileInfo->FileInfo.PhysicalSize = FvFileInfo->FileInfo.FileSize;\r
207 FvFileInfo->FileInfo.Attribute = EFI_FILE_READ_ONLY;\r
208\r
209 InsertHeadList (&Instance->FileInfoHead, &FvFileInfo->Link);\r
210\r
211 FreePool (Name);\r
212\r
213 } while (TRUE);\r
214\r
215 if (Status == EFI_NOT_FOUND) {\r
216 Status = EFI_SUCCESS;\r
217 }\r
218 }\r
219\r
ebd2be68
FT
220 Instance->Root->DirReadNext = NULL;\r
221 if (!IsListEmpty (&Instance->FileInfoHead)) {\r
222 Instance->Root->DirReadNext = FVFS_GET_FIRST_FILE_INFO (Instance);\r
223 }\r
224\r
9da91aea
BJ
225 *RootFile = &Instance->Root->FileProtocol;\r
226 return Status;\r
227}\r
228\r
229/**\r
230 Worker function to initialize Unicode Collation support.\r
231\r
232 It tries to locate Unicode Collation (2) protocol and matches it with current\r
233 platform language code.\r
234\r
235 @param AgentHandle The handle used to open Unicode Collation (2) protocol.\r
236 @param ProtocolGuid The pointer to Unicode Collation (2) protocol GUID.\r
237 @param VariableName The name of the RFC 4646 or ISO 639-2 language variable.\r
238 @param DefaultLanguage The default language in case the RFC 4646 or ISO 639-2 language is absent.\r
239\r
240 @retval EFI_SUCCESS The Unicode Collation (2) protocol has been successfully located.\r
241 @retval Others The Unicode Collation (2) protocol has not been located.\r
242\r
243**/\r
244EFI_STATUS\r
245InitializeUnicodeCollationSupportWorker (\r
246 IN EFI_HANDLE AgentHandle,\r
247 IN EFI_GUID *ProtocolGuid,\r
248 IN CONST CHAR16 *VariableName,\r
249 IN CONST CHAR8 *DefaultLanguage\r
250 )\r
251{\r
252 EFI_STATUS ReturnStatus;\r
253 EFI_STATUS Status;\r
254 UINTN NumHandles;\r
255 UINTN Index;\r
256 EFI_HANDLE *Handles;\r
257 EFI_UNICODE_COLLATION_PROTOCOL *Uci;\r
258 BOOLEAN Iso639Language;\r
259 CHAR8 *Language;\r
260 CHAR8 *BestLanguage;\r
261\r
262 Status = gBS->LocateHandleBuffer (\r
263 ByProtocol,\r
264 ProtocolGuid,\r
265 NULL,\r
266 &NumHandles,\r
267 &Handles\r
268 );\r
269 if (EFI_ERROR (Status)) {\r
270 return Status;\r
271 }\r
272\r
273 Iso639Language = (BOOLEAN) (ProtocolGuid == &gEfiUnicodeCollationProtocolGuid);\r
274 GetEfiGlobalVariable2 (VariableName, (VOID**) &Language, NULL);\r
275\r
276 ReturnStatus = EFI_UNSUPPORTED;\r
277 for (Index = 0; Index < NumHandles; Index++) {\r
278 //\r
279 // Open Unicode Collation Protocol\r
280 //\r
281 Status = gBS->OpenProtocol (\r
282 Handles[Index],\r
283 ProtocolGuid,\r
284 (VOID **) &Uci,\r
285 AgentHandle,\r
286 NULL,\r
287 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
288 );\r
289 if (EFI_ERROR (Status)) {\r
290 continue;\r
291 }\r
292\r
293 //\r
294 // Find the best matching matching language from the supported languages\r
295 // of Unicode Collation (2) protocol.\r
296 //\r
297 BestLanguage = GetBestLanguage (\r
298 Uci->SupportedLanguages,\r
299 Iso639Language,\r
300 (Language == NULL) ? "" : Language,\r
301 DefaultLanguage,\r
302 NULL\r
303 );\r
304 if (BestLanguage != NULL) {\r
305 FreePool (BestLanguage);\r
306 mUnicodeCollation = Uci;\r
307 ReturnStatus = EFI_SUCCESS;\r
308 break;\r
309 }\r
310 }\r
311\r
312 if (Language != NULL) {\r
313 FreePool (Language);\r
314 }\r
315\r
316 FreePool (Handles);\r
317\r
318 return ReturnStatus;\r
319}\r
320\r
321/**\r
322 Initialize Unicode Collation support.\r
323\r
324 It tries to locate Unicode Collation 2 protocol and matches it with current\r
325 platform language code. If for any reason the first attempt fails, it then tries to\r
326 use Unicode Collation Protocol.\r
327\r
328 @param AgentHandle The handle used to open Unicode Collation (2) protocol.\r
329\r
330 @retval EFI_SUCCESS The Unicode Collation (2) protocol has been successfully located.\r
331 @retval Others The Unicode Collation (2) protocol has not been located.\r
332\r
333**/\r
334EFI_STATUS\r
335InitializeUnicodeCollationSupport (\r
336 IN EFI_HANDLE AgentHandle\r
337 )\r
338{\r
339\r
340 EFI_STATUS Status;\r
341\r
342 Status = EFI_UNSUPPORTED;\r
343\r
344 //\r
345 // First try to use RFC 4646 Unicode Collation 2 Protocol.\r
346 //\r
347 Status = InitializeUnicodeCollationSupportWorker (\r
348 AgentHandle,\r
349 &gEfiUnicodeCollation2ProtocolGuid,\r
350 L"PlatformLang",\r
351 (CONST CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang)\r
352 );\r
353 //\r
354 // If the attempt to use Unicode Collation 2 Protocol fails, then we fall back\r
355 // on the ISO 639-2 Unicode Collation Protocol.\r
356 //\r
357 if (EFI_ERROR (Status)) {\r
358 Status = InitializeUnicodeCollationSupportWorker (\r
359 AgentHandle,\r
360 &gEfiUnicodeCollationProtocolGuid,\r
361 L"Lang",\r
362 (CONST CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultLang)\r
363 );\r
364 }\r
365\r
366 return Status;\r
367}\r
368\r
369/**\r
370 Test to see if this driver supports ControllerHandle.\r
371\r
372 @param DriverBinding Protocol instance pointer.\r
373 @param ControllerHandle Handle of device to test\r
374 @param RemainingDevicePath Optional parameter use to pick a specific child\r
375 device to start.\r
376\r
377 @retval EFI_SUCCESS This driver supports this device\r
378 @retval EFI_ALREADY_STARTED This driver is already running on this device\r
379 @retval other This driver does not support this device\r
380\r
381**/\r
382EFI_STATUS\r
383EFIAPI\r
384FvSimpleFileSystemDriverSupported (\r
385 IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,\r
386 IN EFI_HANDLE ControllerHandle,\r
387 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
388 )\r
389{\r
390 return gBS->OpenProtocol (\r
391 ControllerHandle,\r
392 &gEfiFirmwareVolume2ProtocolGuid,\r
393 NULL,\r
394 gImageHandle,\r
395 ControllerHandle,\r
396 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
397 );\r
398}\r
399\r
400/**\r
401 Start this driver on ControllerHandle by opening a FV protocol and\r
402 installing a SimpleFileSystem protocol on ControllerHandle.\r
403\r
404 @param DriverBinding Protocol instance pointer.\r
405 @param ControllerHandle Handle of device to bind driver to\r
406 @param RemainingDevicePath Optional parameter use to pick a specific child\r
407 device to start.\r
408\r
409 @retval EFI_SUCCESS This driver is added to ControllerHandle\r
410 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle\r
411 @retval other This driver does not support this device\r
412\r
413**/\r
414EFI_STATUS\r
415EFIAPI\r
416FvSimpleFileSystemDriverStart (\r
417 IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,\r
418 IN EFI_HANDLE ControllerHandle,\r
419 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
420 )\r
421{\r
422 EFI_STATUS Status;\r
423 EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;\r
424 FV_FILESYSTEM_INSTANCE *Instance;\r
425 EFI_DEVICE_PATH_PROTOCOL *FvDevicePath;\r
426 EFI_GUID *FvGuid;\r
427 UINTN NumChars;\r
428\r
429 Status = InitializeUnicodeCollationSupport (DriverBinding->DriverBindingHandle);\r
430 if (EFI_ERROR (Status)) {\r
431 return Status;\r
432 }\r
433\r
434 //\r
435 // Open FV protocol\r
436 //\r
437 Status = gBS->OpenProtocol (\r
438 ControllerHandle,\r
439 &gEfiFirmwareVolume2ProtocolGuid,\r
440 (VOID **) &FvProtocol,\r
441 gImageHandle,\r
442 ControllerHandle,\r
443 EFI_OPEN_PROTOCOL_BY_DRIVER\r
444 );\r
445 if (EFI_ERROR (Status)) {\r
446 return Status;\r
447 }\r
448\r
449 //\r
450 // Create an instance\r
451 //\r
452 Instance = AllocateZeroPool (sizeof (FV_FILESYSTEM_INSTANCE));\r
b07c9665 453 ASSERT (Instance != NULL);\r
9da91aea
BJ
454\r
455 Instance->Root = NULL;\r
456 Instance->FvProtocol = FvProtocol;\r
457 Instance->Signature = FVFS_INSTANCE_SIGNATURE;\r
458 InitializeListHead (&Instance->FileInfoHead);\r
459 InitializeListHead (&Instance->FileHead);\r
460 CopyMem (&Instance->SimpleFs, &mSimpleFsTemplate, sizeof (mSimpleFsTemplate));\r
461\r
462 Status = gBS->InstallProtocolInterface(\r
463 &ControllerHandle,\r
464 &gEfiSimpleFileSystemProtocolGuid,\r
465 EFI_NATIVE_INTERFACE,\r
466 &Instance->SimpleFs\r
467 );\r
b07c9665 468 ASSERT_EFI_ERROR (Status);\r
9da91aea
BJ
469\r
470 //\r
471 // Decide on a filesystem volume label, which will include the FV's guid.\r
472 // Get the device path to find the FV's GUID\r
473 //\r
474 Instance->VolumeLabel = NULL;\r
475 Status = gBS->OpenProtocol (\r
476 ControllerHandle,\r
477 &gEfiDevicePathProtocolGuid,\r
478 (VOID **) &FvDevicePath,\r
479 gImageHandle,\r
480 ControllerHandle,\r
b07c9665 481 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
9da91aea
BJ
482 );\r
483 if (!EFI_ERROR (Status)) {\r
484 //\r
485 // Iterate over device path until we find a firmware volume node\r
486 //\r
487 while (!IsDevicePathEndType (FvDevicePath)) {\r
488 if (DevicePathType (FvDevicePath) == MEDIA_DEVICE_PATH &&\r
489 DevicePathSubType (FvDevicePath) == MEDIA_PIWG_FW_VOL_DP) {\r
490 //\r
491 // Allocate the volume label\r
492 //\r
493 Instance->VolumeLabel = AllocateZeroPool (FVFS_VOLUME_LABEL_SIZE);\r
494 //\r
495 // Check the allocation was successful\r
496 //\r
497 if (Instance->VolumeLabel != NULL) {\r
498 //\r
499 // Extract the FV's guid\r
500 //\r
501 FvGuid = &((MEDIA_FW_VOL_DEVICE_PATH *) FvDevicePath)->FvName;\r
502 //\r
503 // Build the volume label string\r
504 //\r
505 NumChars = UnicodeSPrint (\r
506 Instance->VolumeLabel,\r
507 FVFS_VOLUME_LABEL_SIZE,\r
508 FVFS_VOLUME_LABEL_PREFIX L"%g",\r
509 FvGuid\r
510 );\r
511 ASSERT ((NumChars + 1) * sizeof (CHAR16) == FVFS_VOLUME_LABEL_SIZE);\r
512 }\r
513 break;\r
514 }\r
515 FvDevicePath = NextDevicePathNode (FvDevicePath);\r
516 }\r
517 }\r
518 //\r
519 // If we didn't decide on a volume label, set a fallback one\r
520 //\r
521 if (Instance->VolumeLabel == NULL) {\r
522 Instance->VolumeLabel = AllocateCopyPool (\r
523 sizeof (FVFS_FALLBACK_VOLUME_LABEL),\r
524 FVFS_FALLBACK_VOLUME_LABEL\r
525 );\r
526 }\r
527\r
b07c9665 528 return EFI_SUCCESS;\r
9da91aea
BJ
529}\r
530\r
531/**\r
532 Stop this driver on ControllerHandle by removing SimpleFileSystem protocol and closing\r
533 the FV protocol on ControllerHandle.\r
534\r
535 @param DriverBinding Protocol instance pointer.\r
536 @param ControllerHandle Handle of device to stop driver on\r
537 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
538 children is zero stop the entire bus driver.\r
539 @param ChildHandleBuffer List of Child Handles to Stop.\r
540\r
541 @retval EFI_SUCCESS This driver is removed ControllerHandle\r
542 @retval other This driver was not removed from this device\r
543\r
544**/\r
545EFI_STATUS\r
546EFIAPI\r
547FvSimpleFileSystemDriverStop (\r
548 IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,\r
549 IN EFI_HANDLE ControllerHandle,\r
550 IN UINTN NumberOfChildren,\r
551 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL\r
552 )\r
553{\r
554 EFI_STATUS Status;\r
555 FV_FILESYSTEM_INSTANCE *Instance;\r
556 FV_FILESYSTEM_FILE_INFO *FvFileInfo;\r
557 LIST_ENTRY *Entry;\r
558 LIST_ENTRY *DelEntry;\r
559 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFile;\r
560\r
561 Status = gBS->OpenProtocol (\r
562 ControllerHandle,\r
563 &gEfiSimpleFileSystemProtocolGuid,\r
564 (VOID **) &SimpleFile,\r
565 DriverBinding->DriverBindingHandle,\r
566 ControllerHandle,\r
567 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
568 );\r
569 if (EFI_ERROR (Status)) {\r
570 return Status;\r
571 }\r
572\r
573 Instance = FVFS_INSTANCE_FROM_SIMPLE_FS_THIS (SimpleFile);\r
574\r
575 if (IsListEmpty (&Instance->FileHead) == FALSE) {\r
576 //\r
577 // Not all opened files are closed\r
578 //\r
579 return EFI_DEVICE_ERROR;\r
580 }\r
581\r
582 //\r
583 // Close and uninstall protocols.\r
584 //\r
585 Status = gBS->CloseProtocol (\r
586 ControllerHandle,\r
587 &gEfiFirmwareVolume2ProtocolGuid,\r
588 gImageHandle,\r
589 ControllerHandle\r
590 );\r
591 ASSERT_EFI_ERROR (Status);\r
592\r
593 Status = gBS->UninstallProtocolInterface (\r
594 ControllerHandle,\r
595 &gEfiSimpleFileSystemProtocolGuid,\r
596 &Instance->SimpleFs\r
597 );\r
598 ASSERT_EFI_ERROR (Status);\r
599\r
600 //\r
601 // Free file structures\r
602 //\r
603 if (!IsListEmpty (&Instance->FileInfoHead)) {\r
604 //\r
605 // Free the Subtask list.\r
606 //\r
607 for(Entry = Instance->FileInfoHead.ForwardLink;\r
608 Entry != (&Instance->FileInfoHead);\r
609 ) {\r
610 DelEntry = Entry;\r
611 Entry = Entry->ForwardLink;\r
612 FvFileInfo = FVFS_FILE_INFO_FROM_LINK (DelEntry);\r
613\r
614 RemoveEntryList (DelEntry);\r
615 FreePool (FvFileInfo);\r
616 }\r
617 }\r
618\r
619 if (Instance->Root != NULL) {\r
620 //\r
621 // Root->Name is statically allocated, no need to free.\r
622 //\r
623 if (Instance->Root->FvFileInfo != NULL) {\r
624 FreePool (Instance->Root->FvFileInfo);\r
625 }\r
626 FreePool (Instance->Root);\r
627 }\r
628\r
629 //\r
630 // Free Instance\r
631 //\r
632 if (Instance->VolumeLabel != NULL) {\r
633 FreePool (Instance->VolumeLabel);\r
634 }\r
635 FreePool (Instance);\r
636\r
637 return EFI_SUCCESS;\r
638}\r
639\r
640/**\r
641 The user Entry Point for module FvSimpleFileSystem. The user code starts with this function.\r
642\r
643 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
644 @param[in] SystemTable A pointer to the EFI System Table.\r
645\r
646 @retval EFI_SUCCESS The entry point is executed successfully.\r
647 @retval other Some error occurs when executing this entry point.\r
648\r
649**/\r
650EFI_STATUS\r
651EFIAPI\r
652FvSimpleFileSystemEntryPoint (\r
653 IN EFI_HANDLE ImageHandle,\r
654 IN EFI_SYSTEM_TABLE *SystemTable\r
655 )\r
656{\r
657 EFI_STATUS Status;\r
658\r
659 //\r
660 // Install driver model protocol(s).\r
661 //\r
662 Status = EfiLibInstallDriverBindingComponentName2 (\r
663 ImageHandle,\r
664 SystemTable,\r
665 &mDriverBinding,\r
666 ImageHandle,\r
667 &gFvSimpleFileSystemComponentName,\r
668 &gFvSimpleFileSystemComponentName2\r
669 );\r
670 ASSERT_EFI_ERROR (Status);\r
671\r
672 return Status;\r
673}\r