]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVol.c
Searching for files starts on an 8 byte aligned boundary after the end of the Extende...
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / FirmwareVolume / FwVolDxe / FwVol.c
1 /** @file
2
3 Firmware File System driver that produce full Firmware Volume2 protocol.
4 Layers on top of Firmware Block protocol to produce a file abstraction
5 of FV based files.
6
7 Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
8
9 This program and the accompanying materials
10 are licensed and made available under the terms and conditions
11 of the BSD License which accompanies this distribution. The
12 full text of the license may be found at
13 http://opensource.org/licenses/bsd-license.php
14
15 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
16 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17
18 **/
19
20 #include "FwVolDriver.h"
21
22 #define KEYSIZE sizeof (UINTN)
23
24 /**
25 Given the supplied FW_VOL_BLOCK_PROTOCOL, allocate a buffer for output and
26 copy the real length volume header into it.
27
28 @param Fvb The FW_VOL_BLOCK_PROTOCOL instance from which to
29 read the volume header
30 @param FwVolHeader Pointer to pointer to allocated buffer in which
31 the volume header is returned.
32
33 @retval EFI_OUT_OF_RESOURCES No enough buffer could be allocated.
34 @retval EFI_SUCCESS Successfully read volume header to the allocated
35 buffer.
36 @retval EFI_ACCESS_DENIED Read status of FV is not enabled.
37 **/
38 EFI_STATUS
39 GetFwVolHeader (
40 IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb,
41 OUT EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader
42 )
43 {
44 EFI_STATUS Status;
45 EFI_FIRMWARE_VOLUME_HEADER TempFvh;
46 EFI_FVB_ATTRIBUTES_2 FvbAttributes;
47 UINTN FvhLength;
48 EFI_PHYSICAL_ADDRESS BaseAddress;
49
50 //
51 // Determine the real length of FV header
52 //
53 Status = Fvb->GetAttributes (
54 Fvb,
55 &FvbAttributes
56 );
57 if (EFI_ERROR (Status)) {
58 return Status;
59 }
60
61 if ((FvbAttributes & EFI_FVB2_READ_STATUS) == 0) {
62 return EFI_ACCESS_DENIED;
63 }
64
65 //
66 // Just avoid compiling warning
67 //
68 BaseAddress = 0;
69 FvhLength = sizeof (EFI_FIRMWARE_VOLUME_HEADER);
70
71 //
72 // memory-mapped FV and non memory-mapped has different ways to read
73 //
74 if ((FvbAttributes & EFI_FVB2_MEMORY_MAPPED) != 0) {
75 Status = Fvb->GetPhysicalAddress (
76 Fvb,
77 &BaseAddress
78 );
79 if (EFI_ERROR (Status)) {
80 return Status;
81 }
82 CopyMem (&TempFvh, (VOID *) (UINTN) BaseAddress, FvhLength);
83 } else {
84 Status = Fvb->Read (
85 Fvb,
86 0,
87 0,
88 &FvhLength,
89 (UINT8 *) &TempFvh
90 );
91 }
92
93 *FwVolHeader = AllocatePool (TempFvh.HeaderLength);
94 if (*FwVolHeader == NULL) {
95 return EFI_OUT_OF_RESOURCES;
96 }
97 //
98 // Read the whole header
99 //
100 if ((FvbAttributes & EFI_FVB2_MEMORY_MAPPED) != 0) {
101 CopyMem (*FwVolHeader, (VOID *) (UINTN) BaseAddress, TempFvh.HeaderLength);
102 } else {
103 //
104 // Assumed the first block is bigger than the length of Fv headder
105 //
106 FvhLength = TempFvh.HeaderLength;
107 Status = Fvb->Read (
108 Fvb,
109 0,
110 0,
111 &FvhLength,
112 (UINT8 *) *FwVolHeader
113 );
114 //
115 // Check whether Read successes.
116 //
117 if (EFI_ERROR (Status)) {
118 FreePool (*FwVolHeader);
119 *FwVolHeader = NULL;
120 return Status;
121 }
122 }
123
124 return EFI_SUCCESS;
125 }
126
127 /**
128 Free FvDevice resource when error happens.
129
130 @param FvDevice Pointer to the FvDevice to be freed.
131 **/
132 VOID
133 FreeFvDeviceResource (
134 IN FV_DEVICE *FvDevice
135 )
136 {
137 LBA_ENTRY *LbaEntry;
138 FREE_SPACE_ENTRY *FreeSpaceEntry;
139 FFS_FILE_LIST_ENTRY *FfsFileEntry;
140 LIST_ENTRY *NextEntry;
141
142 //
143 // Free LAB Entry
144 //
145 LbaEntry = (LBA_ENTRY *) FvDevice->LbaHeader.ForwardLink;
146 while (&LbaEntry->Link != &FvDevice->LbaHeader) {
147 NextEntry = (&LbaEntry->Link)->ForwardLink;
148 FreePool (LbaEntry);
149 LbaEntry = (LBA_ENTRY *) NextEntry;
150 }
151 //
152 // Free File List Entry
153 //
154 FfsFileEntry = (FFS_FILE_LIST_ENTRY *) FvDevice->FfsFileListHeader.ForwardLink;
155 while (&FfsFileEntry->Link != &FvDevice->FfsFileListHeader) {
156 NextEntry = (&FfsFileEntry->Link)->ForwardLink;
157 FreePool (FfsFileEntry);
158 FfsFileEntry = (FFS_FILE_LIST_ENTRY *) NextEntry;
159 }
160 //
161 // Free Space Entry
162 //
163 FreeSpaceEntry = (FREE_SPACE_ENTRY *) FvDevice->FreeSpaceHeader.ForwardLink;
164 while (&FreeSpaceEntry->Link != &FvDevice->FreeSpaceHeader) {
165 NextEntry = (&FreeSpaceEntry->Link)->ForwardLink;
166 FreePool (FreeSpaceEntry);
167 FreeSpaceEntry = (FREE_SPACE_ENTRY *) NextEntry;
168 }
169 //
170 // Free the cache
171 //
172 FreePool ((UINT8 *) (UINTN) FvDevice->CachedFv);
173
174 return ;
175 }
176
177 /**
178 Check if an FV is consistent and allocate cache for it.
179
180 @param FvDevice A pointer to the FvDevice to be checked.
181
182 @retval EFI_OUT_OF_RESOURCES No enough buffer could be allocated.
183 @retval EFI_VOLUME_CORRUPTED File system is corrupted.
184 @retval EFI_SUCCESS FV is consistent and cache is allocated.
185
186 **/
187 EFI_STATUS
188 FvCheck (
189 IN FV_DEVICE *FvDevice
190 )
191 {
192 EFI_STATUS Status;
193 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
194 EFI_FVB_ATTRIBUTES_2 FvbAttributes;
195 EFI_FV_BLOCK_MAP_ENTRY *BlockMap;
196 EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
197 EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExtHeader;
198 UINT8 *FwCache;
199 LBA_ENTRY *LbaEntry;
200 FREE_SPACE_ENTRY *FreeSpaceEntry;
201 FFS_FILE_LIST_ENTRY *FfsFileEntry;
202 UINT8 *LbaStart;
203 UINTN Index;
204 EFI_LBA LbaIndex;
205 UINT8 *Ptr;
206 UINTN Size;
207 UINT8 *FreeStart;
208 UINTN FreeSize;
209 UINT8 ErasePolarity;
210 EFI_FFS_FILE_STATE FileState;
211 UINT8 *TopFvAddress;
212 UINTN TestLength;
213 EFI_PHYSICAL_ADDRESS BaseAddress;
214
215 Fvb = FvDevice->Fvb;
216
217 Status = Fvb->GetAttributes (Fvb, &FvbAttributes);
218 if (EFI_ERROR (Status)) {
219 return Status;
220 }
221
222 InitializeListHead (&FvDevice->LbaHeader);
223 InitializeListHead (&FvDevice->FreeSpaceHeader);
224 InitializeListHead (&FvDevice->FfsFileListHeader);
225
226 FwVolHeader = NULL;
227 Status = GetFwVolHeader (Fvb, &FwVolHeader);
228 if (EFI_ERROR (Status)) {
229 return Status;
230 }
231 ASSERT (FwVolHeader != NULL);
232
233 FvDevice->IsFfs3Fv = CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem3Guid);
234
235 //
236 // Double Check firmware volume header here
237 //
238 if (!VerifyFvHeaderChecksum (FwVolHeader)) {
239 FreePool (FwVolHeader);
240 return EFI_VOLUME_CORRUPTED;
241 }
242
243 BlockMap = FwVolHeader->BlockMap;
244
245 //
246 // FwVolHeader->FvLength is the whole FV length including FV header
247 //
248 FwCache = AllocateZeroPool ((UINTN) FwVolHeader->FvLength);
249 if (FwCache == NULL) {
250 FreePool (FwVolHeader);
251 return EFI_OUT_OF_RESOURCES;
252 }
253
254 FvDevice->CachedFv = (EFI_PHYSICAL_ADDRESS) (UINTN) FwCache;
255
256 //
257 // Copy to memory
258 //
259 LbaStart = FwCache;
260 LbaIndex = 0;
261 Ptr = NULL;
262
263 if ((FvbAttributes & EFI_FVB2_MEMORY_MAPPED) != 0) {
264 //
265 // Get volume base address
266 //
267 Status = Fvb->GetPhysicalAddress (Fvb, &BaseAddress);
268 if (EFI_ERROR (Status)) {
269 FreePool (FwVolHeader);
270 return Status;
271 }
272
273 Ptr = (UINT8 *) ((UINTN) BaseAddress);
274
275 DEBUG((EFI_D_INFO, "Fv Base Address is 0x%LX\n", BaseAddress));
276 }
277 //
278 // Copy whole FV into the memory
279 //
280 while ((BlockMap->NumBlocks != 0) || (BlockMap->Length != 0)) {
281
282 for (Index = 0; Index < BlockMap->NumBlocks; Index++) {
283 LbaEntry = AllocatePool (sizeof (LBA_ENTRY));
284 if (LbaEntry == NULL) {
285 FreePool (FwVolHeader);
286 FreeFvDeviceResource (FvDevice);
287 return EFI_OUT_OF_RESOURCES;
288 }
289
290 LbaEntry->LbaIndex = LbaIndex;
291 LbaEntry->StartingAddress = LbaStart;
292 LbaEntry->BlockLength = BlockMap->Length;
293
294 //
295 // Copy each LBA into memory
296 //
297 if ((FvbAttributes & EFI_FVB2_MEMORY_MAPPED) != 0) {
298
299 CopyMem (LbaStart, Ptr, BlockMap->Length);
300 Ptr += BlockMap->Length;
301
302 } else {
303
304 Size = BlockMap->Length;
305 Status = Fvb->Read (
306 Fvb,
307 LbaIndex,
308 0,
309 &Size,
310 LbaStart
311 );
312 //
313 // Not check EFI_BAD_BUFFER_SIZE, for Size = BlockMap->Length
314 //
315 if (EFI_ERROR (Status)) {
316 FreePool (FwVolHeader);
317 FreeFvDeviceResource (FvDevice);
318 return Status;
319 }
320
321 }
322
323 LbaIndex++;
324 LbaStart += BlockMap->Length;
325
326 InsertTailList (&FvDevice->LbaHeader, &LbaEntry->Link);
327 }
328
329 BlockMap++;
330 }
331
332 FvDevice->FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) FwCache;
333
334 //
335 // it is not used any more, so free FwVolHeader
336 //
337 FreePool (FwVolHeader);
338
339 //
340 // Scan to check the free space & File list
341 //
342 if ((FvbAttributes & EFI_FVB2_ERASE_POLARITY) != 0) {
343 ErasePolarity = 1;
344 } else {
345 ErasePolarity = 0;
346 }
347
348 FvDevice->ErasePolarity = ErasePolarity;
349
350 //
351 // go through the whole FV cache, check the consistence of the FV
352 //
353 if (FvDevice->FwVolHeader->ExtHeaderOffset != 0) {
354 //
355 // Searching for files starts on an 8 byte aligned boundary after the end of the Extended Header if it exists.
356 //
357 FwVolExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *) (UINTN) (FvDevice->CachedFv + FvDevice->FwVolHeader->ExtHeaderOffset);
358 Ptr = (UINT8 *) FwVolExtHeader + FwVolExtHeader->ExtHeaderSize;
359 Ptr = (UINT8 *) ALIGN_POINTER (Ptr, 8);
360 } else {
361 Ptr = (UINT8 *) (UINTN) (FvDevice->CachedFv + FvDevice->FwVolHeader->HeaderLength);
362 }
363 TopFvAddress = (UINT8 *) (UINTN) (FvDevice->CachedFv + FvDevice->FwVolHeader->FvLength);
364
365 //
366 // Build FFS list & Free Space List here
367 //
368 while (Ptr < TopFvAddress) {
369 TestLength = TopFvAddress - Ptr;
370
371 if (TestLength > sizeof (EFI_FFS_FILE_HEADER)) {
372 TestLength = sizeof (EFI_FFS_FILE_HEADER);
373 }
374
375 if (IsBufferErased (ErasePolarity, Ptr, TestLength)) {
376 //
377 // We found free space
378 //
379 FreeStart = Ptr;
380 FreeSize = 0;
381
382 do {
383 TestLength = TopFvAddress - Ptr;
384
385 if (TestLength > sizeof (EFI_FFS_FILE_HEADER)) {
386 TestLength = sizeof (EFI_FFS_FILE_HEADER);
387 }
388
389 if (!IsBufferErased (ErasePolarity, Ptr, TestLength)) {
390 break;
391 }
392
393 FreeSize += TestLength;
394 Ptr += TestLength;
395 } while (Ptr < TopFvAddress);
396
397 FreeSpaceEntry = AllocateZeroPool (sizeof (FREE_SPACE_ENTRY));
398 if (FreeSpaceEntry == NULL) {
399 FreeFvDeviceResource (FvDevice);
400 return EFI_OUT_OF_RESOURCES;
401 }
402 //
403 // Create a Free space entry
404 //
405 FreeSpaceEntry->StartingAddress = FreeStart;
406 FreeSpaceEntry->Length = FreeSize;
407 InsertTailList (&FvDevice->FreeSpaceHeader, &FreeSpaceEntry->Link);
408 continue;
409 }
410 //
411 // double check boundry
412 //
413 if (TestLength < sizeof (EFI_FFS_FILE_HEADER)) {
414 break;
415 }
416
417 if (!IsValidFFSHeader (
418 FvDevice->ErasePolarity,
419 (EFI_FFS_FILE_HEADER *) Ptr
420 )) {
421 FileState = GetFileState (
422 FvDevice->ErasePolarity,
423 (EFI_FFS_FILE_HEADER *) Ptr
424 );
425 if ((FileState == EFI_FILE_HEADER_INVALID) || (FileState == EFI_FILE_HEADER_CONSTRUCTION)) {
426 if (IS_FFS_FILE2 (Ptr)) {
427 if (!FvDevice->IsFfs3Fv) {
428 DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &((EFI_FFS_FILE_HEADER *) Ptr)->Name));
429 }
430 Ptr = Ptr + sizeof (EFI_FFS_FILE_HEADER2);
431 } else {
432 Ptr = Ptr + sizeof (EFI_FFS_FILE_HEADER);
433 }
434
435 continue;
436
437 } else {
438 //
439 // File system is corrputed, return
440 //
441 FreeFvDeviceResource (FvDevice);
442 return EFI_VOLUME_CORRUPTED;
443 }
444 }
445
446 if (IS_FFS_FILE2 (Ptr)) {
447 ASSERT (FFS_FILE2_SIZE (Ptr) > 0x00FFFFFF);
448 if (!FvDevice->IsFfs3Fv) {
449 DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &((EFI_FFS_FILE_HEADER *) Ptr)->Name));
450 Ptr = Ptr + FFS_FILE2_SIZE (Ptr);
451 //
452 // Adjust Ptr to the next 8-byte aligned boundry.
453 //
454 while (((UINTN) Ptr & 0x07) != 0) {
455 Ptr++;
456 }
457 continue;
458 }
459 }
460
461 if (IsValidFFSFile (FvDevice, (EFI_FFS_FILE_HEADER *) Ptr)) {
462 FileState = GetFileState (
463 FvDevice->ErasePolarity,
464 (EFI_FFS_FILE_HEADER *) Ptr
465 );
466
467 //
468 // check for non-deleted file
469 //
470 if (FileState != EFI_FILE_DELETED) {
471 //
472 // Create a FFS list entry for each non-deleted file
473 //
474 FfsFileEntry = AllocateZeroPool (sizeof (FFS_FILE_LIST_ENTRY));
475 if (FfsFileEntry == NULL) {
476 FreeFvDeviceResource (FvDevice);
477 return EFI_OUT_OF_RESOURCES;
478 }
479
480 FfsFileEntry->FfsHeader = Ptr;
481 InsertTailList (&FvDevice->FfsFileListHeader, &FfsFileEntry->Link);
482 }
483
484 if (IS_FFS_FILE2 (Ptr)) {
485 Ptr = Ptr + FFS_FILE2_SIZE (Ptr);
486 } else {
487 Ptr = Ptr + FFS_FILE_SIZE (Ptr);
488 }
489
490 //
491 // Adjust Ptr to the next 8-byte aligned boundry.
492 //
493 while (((UINTN) Ptr & 0x07) != 0) {
494 Ptr++;
495 }
496 } else {
497 //
498 // File system is corrupted, return
499 //
500 FreeFvDeviceResource (FvDevice);
501 return EFI_VOLUME_CORRUPTED;
502 }
503 }
504
505 FvDevice->CurrentFfsFile = NULL;
506
507 return EFI_SUCCESS;
508 }
509
510 /**
511 Entry point function does install/reinstall FV2 protocol with full functionality.
512
513 @param ImageHandle A handle for the image that is initializing this driver
514 @param SystemTable A pointer to the EFI system table
515
516 @retval EFI_SUCCESS At least one Fv protocol install/reinstall successfully.
517 @retval EFI_NOT_FOUND No FV protocol install/reinstall successfully.
518 **/
519 EFI_STATUS
520 EFIAPI
521 FwVolDriverInit (
522 IN EFI_HANDLE ImageHandle,
523 IN EFI_SYSTEM_TABLE *SystemTable
524 )
525 {
526 EFI_STATUS Status;
527 EFI_HANDLE *HandleBuffer;
528 UINTN HandleCount;
529 UINTN Index;
530 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
531 EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
532 FV_DEVICE *FvDevice;
533 EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
534 BOOLEAN Reinstall;
535 BOOLEAN InstallFlag;
536
537 DEBUG ((EFI_D_INFO, "=========FwVol writable driver installed\n"));
538 InstallFlag = FALSE;
539 //
540 // Locate all handles of Fvb protocol
541 //
542 Status = gBS->LocateHandleBuffer (
543 ByProtocol,
544 &gEfiFirmwareVolumeBlockProtocolGuid,
545 NULL,
546 &HandleCount,
547 &HandleBuffer
548 );
549 if (EFI_ERROR (Status)) {
550 return EFI_NOT_FOUND;
551 }
552
553 for (Index = 0; Index < HandleCount; Index += 1) {
554 Status = gBS->HandleProtocol (
555 HandleBuffer[Index],
556 &gEfiFirmwareVolumeBlockProtocolGuid,
557 (VOID **) &Fvb
558 );
559 if (EFI_ERROR (Status)) {
560 continue;
561 }
562
563 FwVolHeader = NULL;
564 Status = GetFwVolHeader (Fvb, &FwVolHeader);
565 if (EFI_ERROR (Status)) {
566 continue;
567 }
568 ASSERT (FwVolHeader != NULL);
569 //
570 // Check to see that the file system is indeed formatted in a way we can
571 // understand it...
572 //
573 if ((!CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem2Guid)) &&
574 (!CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem3Guid))) {
575 FreePool (FwVolHeader);
576 continue;
577 }
578 FreePool (FwVolHeader);
579
580 Reinstall = FALSE;
581 //
582 // Check if there is an FV protocol already installed in that handle
583 //
584 Status = gBS->HandleProtocol (
585 HandleBuffer[Index],
586 &gEfiFirmwareVolume2ProtocolGuid,
587 (VOID **) &Fv
588 );
589 if (!EFI_ERROR (Status)) {
590 Reinstall = TRUE;
591 }
592 //
593 // FwVol protocol on the handle so create a new one
594 //
595 FvDevice = AllocateZeroPool (sizeof (FV_DEVICE));
596 if (FvDevice == NULL) {
597 goto Done;
598 }
599
600 FvDevice->Signature = FV_DEVICE_SIGNATURE;
601 FvDevice->Fvb = Fvb;
602
603 //
604 // Firmware Volume Protocol interface
605 //
606 FvDevice->Fv.GetVolumeAttributes = FvGetVolumeAttributes;
607 FvDevice->Fv.SetVolumeAttributes = FvSetVolumeAttributes;
608 FvDevice->Fv.ReadFile = FvReadFile;
609 FvDevice->Fv.ReadSection = FvReadFileSection;
610 FvDevice->Fv.WriteFile = FvWriteFile;
611 FvDevice->Fv.GetNextFile = FvGetNextFile;
612 FvDevice->Fv.KeySize = KEYSIZE;
613 FvDevice->Fv.GetInfo = FvGetVolumeInfo;
614 FvDevice->Fv.SetInfo = FvSetVolumeInfo;
615
616 Status = FvCheck (FvDevice);
617 if (EFI_ERROR (Status)) {
618 //
619 // The file system is not consistence
620 //
621 FreePool (FvDevice);
622 continue;
623 }
624
625 if (Reinstall) {
626 //
627 // Reinstall an New FV protocol
628 //
629 // FvDevice = FV_DEVICE_FROM_THIS (Fv);
630 // FvDevice->Fvb = Fvb;
631 // FreeFvDeviceResource (FvDevice);
632 //
633 Status = gBS->ReinstallProtocolInterface (
634 HandleBuffer[Index],
635 &gEfiFirmwareVolume2ProtocolGuid,
636 Fv,
637 &FvDevice->Fv
638 );
639 if (!EFI_ERROR (Status)) {
640 InstallFlag = TRUE;
641 } else {
642 FreePool (FvDevice);
643 }
644
645 DEBUG ((EFI_D_INFO, "Reinstall FV protocol as writable - %r\n", Status));
646 ASSERT_EFI_ERROR (Status);
647 } else {
648 //
649 // Install an New FV protocol
650 //
651 Status = gBS->InstallProtocolInterface (
652 &FvDevice->Handle,
653 &gEfiFirmwareVolume2ProtocolGuid,
654 EFI_NATIVE_INTERFACE,
655 &FvDevice->Fv
656 );
657 if (!EFI_ERROR (Status)) {
658 InstallFlag = TRUE;
659 } else {
660 FreePool (FvDevice);
661 }
662
663 DEBUG ((EFI_D_INFO, "Install FV protocol as writable - %r\n", Status));
664 ASSERT_EFI_ERROR (Status);
665 }
666 }
667
668 Done:
669 //
670 // As long as one Fv protocol install/reinstall successfully,
671 // success should return to ensure this image will be not unloaded.
672 // Otherwise, new Fv protocols are corrupted by other loaded driver.
673 //
674 if (InstallFlag) {
675 return EFI_SUCCESS;
676 }
677
678 //
679 // No FV protocol install/reinstall successfully.
680 // EFI_NOT_FOUND should return to ensure this image will be unloaded.
681 //
682 return EFI_NOT_FOUND;
683 }