VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/FatPkg/FatPei/FatLiteApi.c@ 108794

Last change on this file since 108794 was 108794, checked in by vboxsync, 2 weeks ago

Devices/EFI/FirmwareNew: Merge edk2-stable202502 from the vendor branch and make it build for the important platforms, bugref:4643

  • Property svn:eol-style set to native
File size: 21.7 KB
Line 
1/** @file
2 FAT recovery PEIM entry point, Ppi Functions and FAT Api functions.
3
4Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
5
6SPDX-License-Identifier: BSD-2-Clause-Patent
7
8**/
9
10#include "FatLitePeim.h"
11
12PEI_FAT_PRIVATE_DATA *mPrivateData = NULL;
13
14/**
15 BlockIo installation notification function. Find out all the current BlockIO
16 PPIs in the system and add them into private data. Assume there is
17
18 @param PeiServices General purpose services available to every
19 PEIM.
20 @param NotifyDescriptor The typedef structure of the notification
21 descriptor. Not used in this function.
22 @param Ppi The typedef structure of the PPI descriptor.
23 Not used in this function.
24
25 @retval EFI_SUCCESS The function completed successfully.
26
27**/
28EFI_STATUS
29EFIAPI
30BlockIoNotifyEntry (
31 IN EFI_PEI_SERVICES **PeiServices,
32 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
33 IN VOID *Ppi
34 );
35
36/**
37 Discover all the block I/O devices to find the FAT volume.
38
39 @param PrivateData Global memory map for accessing global
40 variables.
41 @param BlockIo2 Boolean to show whether using BlockIo2 or BlockIo
42
43 @retval EFI_SUCCESS The function completed successfully.
44
45**/
46EFI_STATUS
47UpdateBlocksAndVolumes (
48 IN OUT PEI_FAT_PRIVATE_DATA *PrivateData,
49 IN BOOLEAN BlockIo2
50 )
51{
52 EFI_STATUS Status;
53 EFI_PEI_PPI_DESCRIPTOR *TempPpiDescriptor;
54 UINTN BlockIoPpiInstance;
55 EFI_PEI_RECOVERY_BLOCK_IO_PPI *BlockIoPpi;
56 EFI_PEI_RECOVERY_BLOCK_IO2_PPI *BlockIo2Ppi;
57 UINTN NumberBlockDevices;
58 UINTN Index;
59 EFI_PEI_BLOCK_IO_MEDIA Media;
60 EFI_PEI_BLOCK_IO2_MEDIA Media2;
61 PEI_FAT_VOLUME Volume;
62 EFI_PEI_SERVICES **PeiServices;
63
64 PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer ();
65 BlockIo2Ppi = NULL;
66 BlockIoPpi = NULL;
67 //
68 // Clean up caches
69 //
70 for (Index = 0; Index < PEI_FAT_CACHE_SIZE; Index++) {
71 PrivateData->CacheBuffer[Index].Valid = FALSE;
72 }
73
74 PrivateData->BlockDeviceCount = 0;
75
76 //
77 // Find out all Block Io Ppi instances within the system
78 // Assuming all device Block Io Peims are dispatched already
79 //
80 for (BlockIoPpiInstance = 0; BlockIoPpiInstance < PEI_FAT_MAX_BLOCK_IO_PPI; BlockIoPpiInstance++) {
81 if (BlockIo2) {
82 Status = PeiServicesLocatePpi (
83 &gEfiPeiVirtualBlockIo2PpiGuid,
84 BlockIoPpiInstance,
85 &TempPpiDescriptor,
86 (VOID **)&BlockIo2Ppi
87 );
88 } else {
89 Status = PeiServicesLocatePpi (
90 &gEfiPeiVirtualBlockIoPpiGuid,
91 BlockIoPpiInstance,
92 &TempPpiDescriptor,
93 (VOID **)&BlockIoPpi
94 );
95 }
96
97 if (EFI_ERROR (Status)) {
98 //
99 // Done with all Block Io Ppis
100 //
101 break;
102 }
103
104 if (BlockIo2) {
105 Status = BlockIo2Ppi->GetNumberOfBlockDevices (
106 PeiServices,
107 BlockIo2Ppi,
108 &NumberBlockDevices
109 );
110 } else {
111 Status = BlockIoPpi->GetNumberOfBlockDevices (
112 PeiServices,
113 BlockIoPpi,
114 &NumberBlockDevices
115 );
116 }
117
118 if (EFI_ERROR (Status)) {
119 continue;
120 }
121
122 for (Index = 1; Index <= NumberBlockDevices && PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE; Index++) {
123 if (BlockIo2) {
124 Status = BlockIo2Ppi->GetBlockDeviceMediaInfo (
125 PeiServices,
126 BlockIo2Ppi,
127 Index,
128 &Media2
129 );
130 if (EFI_ERROR (Status) || !Media2.MediaPresent) {
131 continue;
132 }
133
134 PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockIo2 = BlockIo2Ppi;
135 PrivateData->BlockDevice[PrivateData->BlockDeviceCount].InterfaceType = Media2.InterfaceType;
136 PrivateData->BlockDevice[PrivateData->BlockDeviceCount].LastBlock = Media2.LastBlock;
137 PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockSize = Media2.BlockSize;
138 } else {
139 Status = BlockIoPpi->GetBlockDeviceMediaInfo (
140 PeiServices,
141 BlockIoPpi,
142 Index,
143 &Media
144 );
145 if (EFI_ERROR (Status) || !Media.MediaPresent) {
146 continue;
147 }
148
149 PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockIo = BlockIoPpi;
150 PrivateData->BlockDevice[PrivateData->BlockDeviceCount].DevType = Media.DeviceType;
151 PrivateData->BlockDevice[PrivateData->BlockDeviceCount].LastBlock = Media.LastBlock;
152 PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockSize = (UINT32)Media.BlockSize;
153 }
154
155 PrivateData->BlockDevice[PrivateData->BlockDeviceCount].IoAlign = 0;
156 //
157 // Not used here
158 //
159 PrivateData->BlockDevice[PrivateData->BlockDeviceCount].Logical = FALSE;
160 PrivateData->BlockDevice[PrivateData->BlockDeviceCount].PartitionChecked = FALSE;
161
162 PrivateData->BlockDevice[PrivateData->BlockDeviceCount].PhysicalDevNo = (UINT8)Index;
163 PrivateData->BlockDeviceCount++;
164 }
165 }
166
167 //
168 // Find out all logical devices
169 //
170 FatFindPartitions (PrivateData);
171
172 //
173 // Build up file system volume array
174 //
175 PrivateData->VolumeCount = 0;
176 for (Index = 0; Index < PrivateData->BlockDeviceCount; Index++) {
177 Volume.BlockDeviceNo = Index;
178 Status = FatGetBpbInfo (PrivateData, &Volume);
179 if (Status == EFI_SUCCESS) {
180 //
181 // Add the detected volume to the volume array
182 //
183 CopyMem (
184 (UINT8 *)&(PrivateData->Volume[PrivateData->VolumeCount]),
185 (UINT8 *)&Volume,
186 sizeof (PEI_FAT_VOLUME)
187 );
188 PrivateData->VolumeCount += 1;
189 if (PrivateData->VolumeCount >= PEI_FAT_MAX_VOLUME) {
190 break;
191 }
192 }
193 }
194
195 return EFI_SUCCESS;
196}
197
198/**
199 BlockIo installation notification function. Find out all the current BlockIO
200 PPIs in the system and add them into private data. Assume there is
201
202 @param PeiServices General purpose services available to every
203 PEIM.
204 @param NotifyDescriptor The typedef structure of the notification
205 descriptor. Not used in this function.
206 @param Ppi The typedef structure of the PPI descriptor.
207 Not used in this function.
208
209 @retval EFI_SUCCESS The function completed successfully.
210
211**/
212EFI_STATUS
213EFIAPI
214BlockIoNotifyEntry (
215 IN EFI_PEI_SERVICES **PeiServices,
216 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
217 IN VOID *Ppi
218 )
219{
220 if (CompareGuid (NotifyDescriptor->Guid, &gEfiPeiVirtualBlockIo2PpiGuid)) {
221 UpdateBlocksAndVolumes (mPrivateData, TRUE);
222 } else {
223 UpdateBlocksAndVolumes (mPrivateData, FALSE);
224 }
225
226 return EFI_SUCCESS;
227}
228
229/**
230 Installs the Device Recovery Module PPI, Initialize BlockIo Ppi
231 installation notification
232
233 @param FileHandle Handle of the file being invoked. Type
234 EFI_PEI_FILE_HANDLE is defined in
235 FfsFindNextFile().
236 @param PeiServices Describes the list of possible PEI Services.
237
238 @retval EFI_SUCCESS The entry point was executed successfully.
239 @retval EFI_OUT_OF_RESOURCES There is no enough memory to complete the
240 operations.
241
242**/
243EFI_STATUS
244EFIAPI
245FatPeimEntry (
246 IN EFI_PEI_FILE_HANDLE FileHandle,
247 IN CONST EFI_PEI_SERVICES **PeiServices
248 )
249{
250 EFI_STATUS Status;
251 EFI_PHYSICAL_ADDRESS Address;
252 PEI_FAT_PRIVATE_DATA *PrivateData;
253
254 Status = PeiServicesRegisterForShadow (FileHandle);
255 if (!EFI_ERROR (Status)) {
256 return Status;
257 }
258
259 Status = PeiServicesAllocatePages (
260 EfiBootServicesCode,
261 (sizeof (PEI_FAT_PRIVATE_DATA) - 1) / PEI_FAT_MEMORY_PAGE_SIZE + 1,
262 &Address
263 );
264 if (EFI_ERROR (Status)) {
265 return EFI_OUT_OF_RESOURCES;
266 }
267
268 PrivateData = (PEI_FAT_PRIVATE_DATA *)(UINTN)Address;
269
270 //
271 // Initialize Private Data (to zero, as is required by subsequent operations)
272 //
273 ZeroMem ((UINT8 *)PrivateData, sizeof (PEI_FAT_PRIVATE_DATA));
274
275 PrivateData->Signature = PEI_FAT_PRIVATE_DATA_SIGNATURE;
276
277 //
278 // Installs Ppi
279 //
280 PrivateData->DeviceRecoveryPpi.GetNumberRecoveryCapsules = GetNumberRecoveryCapsules;
281 PrivateData->DeviceRecoveryPpi.GetRecoveryCapsuleInfo = GetRecoveryCapsuleInfo;
282 PrivateData->DeviceRecoveryPpi.LoadRecoveryCapsule = LoadRecoveryCapsule;
283
284 PrivateData->PpiDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
285 PrivateData->PpiDescriptor.Guid = &gEfiPeiDeviceRecoveryModulePpiGuid;
286 PrivateData->PpiDescriptor.Ppi = &PrivateData->DeviceRecoveryPpi;
287
288 Status = PeiServicesInstallPpi (&PrivateData->PpiDescriptor);
289 if (EFI_ERROR (Status)) {
290 return EFI_OUT_OF_RESOURCES;
291 }
292
293 //
294 // Other initializations
295 //
296 PrivateData->BlockDeviceCount = 0;
297
298 UpdateBlocksAndVolumes (PrivateData, TRUE);
299 UpdateBlocksAndVolumes (PrivateData, FALSE);
300
301 //
302 // PrivateData is allocated now, set it to the module variable
303 //
304 mPrivateData = PrivateData;
305
306 //
307 // Installs Block Io Ppi notification function
308 //
309 PrivateData->NotifyDescriptor[0].Flags =
310 (
311 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
312 );
313 PrivateData->NotifyDescriptor[0].Guid = &gEfiPeiVirtualBlockIoPpiGuid;
314 PrivateData->NotifyDescriptor[0].Notify = BlockIoNotifyEntry;
315 PrivateData->NotifyDescriptor[1].Flags =
316 (
317 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |
318 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
319 );
320 PrivateData->NotifyDescriptor[1].Guid = &gEfiPeiVirtualBlockIo2PpiGuid;
321 PrivateData->NotifyDescriptor[1].Notify = BlockIoNotifyEntry;
322 return PeiServicesNotifyPpi (&PrivateData->NotifyDescriptor[0]);
323}
324
325/**
326 Returns the number of DXE capsules residing on the device.
327
328 This function searches for DXE capsules from the associated device and returns
329 the number and maximum size in bytes of the capsules discovered. Entry 1 is
330 assumed to be the highest load priority and entry N is assumed to be the lowest
331 priority.
332
333 @param[in] PeiServices General-purpose services that are available
334 to every PEIM
335 @param[in] This Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI
336 instance.
337 @param[out] NumberRecoveryCapsules Pointer to a caller-allocated UINTN. On
338 output, *NumberRecoveryCapsules contains
339 the number of recovery capsule images
340 available for retrieval from this PEIM
341 instance.
342
343 @retval EFI_SUCCESS One or more capsules were discovered.
344 @retval EFI_DEVICE_ERROR A device error occurred.
345 @retval EFI_NOT_FOUND A recovery DXE capsule cannot be found.
346
347**/
348EFI_STATUS
349EFIAPI
350GetNumberRecoveryCapsules (
351 IN EFI_PEI_SERVICES **PeiServices,
352 IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This,
353 OUT UINTN *NumberRecoveryCapsules
354 )
355{
356 EFI_STATUS Status;
357 PEI_FAT_PRIVATE_DATA *PrivateData;
358 UINTN Index;
359 UINTN RecoveryCapsuleCount;
360 PEI_FILE_HANDLE Handle;
361
362 PrivateData = PEI_FAT_PRIVATE_DATA_FROM_THIS (This);
363
364 //
365 // Search each volume in the root directory for the Recovery capsule
366 //
367 RecoveryCapsuleCount = 0;
368 for (Index = 0; Index < PrivateData->VolumeCount; Index++) {
369 Status = FindRecoveryFile (PrivateData, Index, (CHAR16 *)PcdGetPtr (PcdRecoveryFileName), &Handle);
370 if (EFI_ERROR (Status)) {
371 continue;
372 }
373
374 RecoveryCapsuleCount++;
375 }
376
377 *NumberRecoveryCapsules = RecoveryCapsuleCount;
378
379 if (*NumberRecoveryCapsules == 0) {
380 return EFI_NOT_FOUND;
381 }
382
383 return EFI_SUCCESS;
384}
385
386/**
387 Returns the size and type of the requested recovery capsule.
388
389 This function gets the size and type of the capsule specified by CapsuleInstance.
390
391 @param[in] PeiServices General-purpose services that are available to every PEIM
392 @param[in] This Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI
393 instance.
394 @param[in] CapsuleInstance Specifies for which capsule instance to retrieve
395 the information. This parameter must be between
396 one and the value returned by GetNumberRecoveryCapsules()
397 in NumberRecoveryCapsules.
398 @param[out] Size A pointer to a caller-allocated UINTN in which
399 the size of the requested recovery module is
400 returned.
401 @param[out] CapsuleType A pointer to a caller-allocated EFI_GUID in which
402 the type of the requested recovery capsule is
403 returned. The semantic meaning of the value
404 returned is defined by the implementation.
405
406 @retval EFI_SUCCESS One or more capsules were discovered.
407 @retval EFI_DEVICE_ERROR A device error occurred.
408 @retval EFI_NOT_FOUND A recovery DXE capsule cannot be found.
409
410**/
411EFI_STATUS
412EFIAPI
413GetRecoveryCapsuleInfo (
414 IN EFI_PEI_SERVICES **PeiServices,
415 IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This,
416 IN UINTN CapsuleInstance,
417 OUT UINTN *Size,
418 OUT EFI_GUID *CapsuleType
419 )
420{
421 EFI_STATUS Status;
422 PEI_FAT_PRIVATE_DATA *PrivateData;
423 UINTN Index;
424 UINTN BlockDeviceNo;
425 UINTN RecoveryCapsuleCount;
426 PEI_FILE_HANDLE Handle;
427 UINTN NumberRecoveryCapsules;
428
429 Handle = NULL;
430
431 Status = GetNumberRecoveryCapsules (PeiServices, This, &NumberRecoveryCapsules);
432
433 if (EFI_ERROR (Status)) {
434 return Status;
435 }
436
437 if ((CapsuleInstance == 0) || (CapsuleInstance > NumberRecoveryCapsules)) {
438 return EFI_NOT_FOUND;
439 }
440
441 PrivateData = PEI_FAT_PRIVATE_DATA_FROM_THIS (This);
442
443 //
444 // Search each volume in the root directory for the Recovery capsule
445 //
446 RecoveryCapsuleCount = 0;
447 for (Index = 0; Index < PrivateData->VolumeCount; Index++) {
448 Status = FindRecoveryFile (PrivateData, Index, (CHAR16 *)PcdGetPtr (PcdRecoveryFileName), &Handle);
449
450 if (EFI_ERROR (Status)) {
451 continue;
452 }
453
454 if (CapsuleInstance - 1 == RecoveryCapsuleCount) {
455 //
456 // Get file size
457 //
458 *Size = (UINTN)(((PEI_FAT_FILE *)Handle)->FileSize);
459
460 //
461 // Find corresponding physical block device
462 //
463 BlockDeviceNo = PrivateData->Volume[Index].BlockDeviceNo;
464 while (BlockDeviceNo < PrivateData->BlockDeviceCount && PrivateData->BlockDevice[BlockDeviceNo].Logical) {
465 BlockDeviceNo = PrivateData->BlockDevice[BlockDeviceNo].ParentDevNo;
466 }
467
468 //
469 // Fill in the Capsule Type GUID according to the block device type
470 //
471 if (BlockDeviceNo < PrivateData->BlockDeviceCount) {
472 if (PrivateData->BlockDevice[BlockDeviceNo].BlockIo2 != NULL) {
473 switch (PrivateData->BlockDevice[BlockDeviceNo].InterfaceType) {
474 case MSG_ATAPI_DP:
475 CopyGuid (CapsuleType, &gRecoveryOnFatIdeDiskGuid);
476 break;
477
478 case MSG_USB_DP:
479 CopyGuid (CapsuleType, &gRecoveryOnFatUsbDiskGuid);
480 break;
481
482 case MSG_NVME_NAMESPACE_DP:
483 CopyGuid (CapsuleType, &gRecoveryOnFatNvmeDiskGuid);
484 break;
485
486 default:
487 break;
488 }
489 }
490
491 if (PrivateData->BlockDevice[BlockDeviceNo].BlockIo != NULL) {
492 switch (PrivateData->BlockDevice[BlockDeviceNo].DevType) {
493 case LegacyFloppy:
494 CopyGuid (CapsuleType, &gRecoveryOnFatFloppyDiskGuid);
495 break;
496
497 case IdeCDROM:
498 case IdeLS120:
499 CopyGuid (CapsuleType, &gRecoveryOnFatIdeDiskGuid);
500 break;
501
502 case UsbMassStorage:
503 CopyGuid (CapsuleType, &gRecoveryOnFatUsbDiskGuid);
504 break;
505
506 default:
507 break;
508 }
509 }
510 }
511
512 return EFI_SUCCESS;
513 }
514
515 RecoveryCapsuleCount++;
516 }
517
518 return EFI_NOT_FOUND;
519}
520
521/**
522 Loads a DXE capsule from some media into memory.
523
524 This function, by whatever mechanism, retrieves a DXE capsule from some device
525 and loads it into memory. Note that the published interface is device neutral.
526
527 @param[in] PeiServices General-purpose services that are available
528 to every PEIM
529 @param[in] This Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI
530 instance.
531 @param[in] CapsuleInstance Specifies which capsule instance to retrieve.
532 @param[out] Buffer Specifies a caller-allocated buffer in which
533 the requested recovery capsule will be returned.
534
535 @retval EFI_SUCCESS The capsule was loaded correctly.
536 @retval EFI_DEVICE_ERROR A device error occurred.
537 @retval EFI_NOT_FOUND A requested recovery DXE capsule cannot be found.
538
539**/
540EFI_STATUS
541EFIAPI
542LoadRecoveryCapsule (
543 IN EFI_PEI_SERVICES **PeiServices,
544 IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This,
545 IN UINTN CapsuleInstance,
546 OUT VOID *Buffer
547 )
548{
549 EFI_STATUS Status;
550 PEI_FAT_PRIVATE_DATA *PrivateData;
551 UINTN Index;
552 UINTN RecoveryCapsuleCount;
553 PEI_FILE_HANDLE Handle;
554 UINTN NumberRecoveryCapsules;
555
556 Handle = NULL;
557
558 Status = GetNumberRecoveryCapsules (PeiServices, This, &NumberRecoveryCapsules);
559
560 if (EFI_ERROR (Status)) {
561 return Status;
562 }
563
564 if ((CapsuleInstance == 0) || (CapsuleInstance > NumberRecoveryCapsules)) {
565 return EFI_NOT_FOUND;
566 }
567
568 PrivateData = PEI_FAT_PRIVATE_DATA_FROM_THIS (This);
569
570 //
571 // Search each volume in the root directory for the Recovery capsule
572 //
573 RecoveryCapsuleCount = 0;
574 for (Index = 0; Index < PrivateData->VolumeCount; Index++) {
575 Status = FindRecoveryFile (PrivateData, Index, (CHAR16 *)PcdGetPtr (PcdRecoveryFileName), &Handle);
576 if (EFI_ERROR (Status)) {
577 continue;
578 }
579
580 if (CapsuleInstance - 1 == RecoveryCapsuleCount) {
581 Status = FatReadFile (
582 PrivateData,
583 Handle,
584 (UINTN)(((PEI_FAT_FILE *)Handle)->FileSize),
585 Buffer
586 );
587 return Status;
588 }
589
590 RecoveryCapsuleCount++;
591 }
592
593 return EFI_NOT_FOUND;
594}
595
596/**
597 Finds the recovery file on a FAT volume.
598 This function finds the recovery file named FileName on a specified FAT volume and returns
599 its FileHandle pointer.
600
601 @param PrivateData Global memory map for accessing global
602 variables.
603 @param VolumeIndex The index of the volume.
604 @param FileName The recovery file name to find.
605 @param Handle The output file handle.
606
607 @retval EFI_DEVICE_ERROR Some error occurred when operating the FAT
608 volume.
609 @retval EFI_NOT_FOUND The recovery file was not found.
610 @retval EFI_SUCCESS The recovery file was successfully found on the
611 FAT volume.
612
613**/
614EFI_STATUS
615FindRecoveryFile (
616 IN PEI_FAT_PRIVATE_DATA *PrivateData,
617 IN UINTN VolumeIndex,
618 IN CHAR16 *FileName,
619 OUT PEI_FILE_HANDLE *Handle
620 )
621{
622 EFI_STATUS Status;
623 PEI_FAT_FILE Parent;
624 PEI_FAT_FILE *File;
625
626 File = &PrivateData->File;
627
628 //
629 // VolumeIndex must be less than PEI_FAT_MAX_VOLUME because PrivateData->VolumeCount
630 // cannot be larger than PEI_FAT_MAX_VOLUME when detecting recovery volume.
631 //
632 ASSERT (VolumeIndex < PEI_FAT_MAX_VOLUME);
633
634 //
635 // Construct root directory file
636 //
637 ZeroMem (&Parent, sizeof (PEI_FAT_FILE));
638 Parent.IsFixedRootDir = (BOOLEAN)((PrivateData->Volume[VolumeIndex].FatType == Fat32) ? FALSE : TRUE);
639 Parent.Attributes = FAT_ATTR_DIRECTORY;
640 Parent.CurrentPos = 0;
641 Parent.CurrentCluster = Parent.IsFixedRootDir ? 0 : PrivateData->Volume[VolumeIndex].RootDirCluster;
642 Parent.StartingCluster = Parent.CurrentCluster;
643 Parent.Volume = &PrivateData->Volume[VolumeIndex];
644
645 Status = FatSetFilePos (PrivateData, &Parent, 0);
646 if (EFI_ERROR (Status)) {
647 return EFI_DEVICE_ERROR;
648 }
649
650 //
651 // Search for recovery capsule in root directory
652 //
653 Status = FatReadNextDirectoryEntry (PrivateData, &Parent, File);
654 while (Status == EFI_SUCCESS) {
655 //
656 // Compare whether the file name is recovery file name.
657 //
658 if (EngStriColl (PrivateData, FileName, File->FileName)) {
659 break;
660 }
661
662 Status = FatReadNextDirectoryEntry (PrivateData, &Parent, File);
663 }
664
665 if (EFI_ERROR (Status)) {
666 return EFI_NOT_FOUND;
667 }
668
669 //
670 // Get the recovery file, set its file position to 0.
671 //
672 if (File->StartingCluster != 0) {
673 Status = FatSetFilePos (PrivateData, File, 0);
674 }
675
676 *Handle = File;
677
678 return EFI_SUCCESS;
679}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette