123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675 |
- /** @file
- FAT recovery PEIM entry point, Ppi Functions and FAT Api functions.
- Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "FatLitePeim.h"
- PEI_FAT_PRIVATE_DATA *mPrivateData = NULL;
- /**
- BlockIo installation notification function. Find out all the current BlockIO
- PPIs in the system and add them into private data. Assume there is
- @param PeiServices General purpose services available to every
- PEIM.
- @param NotifyDescriptor The typedef structure of the notification
- descriptor. Not used in this function.
- @param Ppi The typedef structure of the PPI descriptor.
- Not used in this function.
- @retval EFI_SUCCESS The function completed successfully.
- **/
- EFI_STATUS
- EFIAPI
- BlockIoNotifyEntry (
- IN EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
- IN VOID *Ppi
- );
- /**
- Discover all the block I/O devices to find the FAT volume.
- @param PrivateData Global memory map for accessing global
- variables.
- @param BlockIo2 Boolean to show whether using BlockIo2 or BlockIo
- @retval EFI_SUCCESS The function completed successfully.
- **/
- EFI_STATUS
- UpdateBlocksAndVolumes (
- IN OUT PEI_FAT_PRIVATE_DATA *PrivateData,
- IN BOOLEAN BlockIo2
- )
- {
- EFI_STATUS Status;
- EFI_PEI_PPI_DESCRIPTOR *TempPpiDescriptor;
- UINTN BlockIoPpiInstance;
- EFI_PEI_RECOVERY_BLOCK_IO_PPI *BlockIoPpi;
- EFI_PEI_RECOVERY_BLOCK_IO2_PPI *BlockIo2Ppi;
- UINTN NumberBlockDevices;
- UINTN Index;
- EFI_PEI_BLOCK_IO_MEDIA Media;
- EFI_PEI_BLOCK_IO2_MEDIA Media2;
- PEI_FAT_VOLUME Volume;
- EFI_PEI_SERVICES **PeiServices;
- PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer ();
- BlockIo2Ppi = NULL;
- BlockIoPpi = NULL;
- //
- // Clean up caches
- //
- for (Index = 0; Index < PEI_FAT_CACHE_SIZE; Index++) {
- PrivateData->CacheBuffer[Index].Valid = FALSE;
- }
- PrivateData->BlockDeviceCount = 0;
- //
- // Find out all Block Io Ppi instances within the system
- // Assuming all device Block Io Peims are dispatched already
- //
- for (BlockIoPpiInstance = 0; BlockIoPpiInstance < PEI_FAT_MAX_BLOCK_IO_PPI; BlockIoPpiInstance++) {
- if (BlockIo2) {
- Status = PeiServicesLocatePpi (
- &gEfiPeiVirtualBlockIo2PpiGuid,
- BlockIoPpiInstance,
- &TempPpiDescriptor,
- (VOID **)&BlockIo2Ppi
- );
- } else {
- Status = PeiServicesLocatePpi (
- &gEfiPeiVirtualBlockIoPpiGuid,
- BlockIoPpiInstance,
- &TempPpiDescriptor,
- (VOID **)&BlockIoPpi
- );
- }
- if (EFI_ERROR (Status)) {
- //
- // Done with all Block Io Ppis
- //
- break;
- }
- if (BlockIo2) {
- Status = BlockIo2Ppi->GetNumberOfBlockDevices (
- PeiServices,
- BlockIo2Ppi,
- &NumberBlockDevices
- );
- } else {
- Status = BlockIoPpi->GetNumberOfBlockDevices (
- PeiServices,
- BlockIoPpi,
- &NumberBlockDevices
- );
- }
- if (EFI_ERROR (Status)) {
- continue;
- }
- for (Index = 1; Index <= NumberBlockDevices && PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE; Index++) {
- if (BlockIo2) {
- Status = BlockIo2Ppi->GetBlockDeviceMediaInfo (
- PeiServices,
- BlockIo2Ppi,
- Index,
- &Media2
- );
- if (EFI_ERROR (Status) || !Media2.MediaPresent) {
- continue;
- }
- PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockIo2 = BlockIo2Ppi;
- PrivateData->BlockDevice[PrivateData->BlockDeviceCount].InterfaceType = Media2.InterfaceType;
- PrivateData->BlockDevice[PrivateData->BlockDeviceCount].LastBlock = Media2.LastBlock;
- PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockSize = Media2.BlockSize;
- } else {
- Status = BlockIoPpi->GetBlockDeviceMediaInfo (
- PeiServices,
- BlockIoPpi,
- Index,
- &Media
- );
- if (EFI_ERROR (Status) || !Media.MediaPresent) {
- continue;
- }
- PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockIo = BlockIoPpi;
- PrivateData->BlockDevice[PrivateData->BlockDeviceCount].DevType = Media.DeviceType;
- PrivateData->BlockDevice[PrivateData->BlockDeviceCount].LastBlock = Media.LastBlock;
- PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockSize = (UINT32)Media.BlockSize;
- }
- PrivateData->BlockDevice[PrivateData->BlockDeviceCount].IoAlign = 0;
- //
- // Not used here
- //
- PrivateData->BlockDevice[PrivateData->BlockDeviceCount].Logical = FALSE;
- PrivateData->BlockDevice[PrivateData->BlockDeviceCount].PartitionChecked = FALSE;
- PrivateData->BlockDevice[PrivateData->BlockDeviceCount].PhysicalDevNo = (UINT8)Index;
- PrivateData->BlockDeviceCount++;
- }
- }
- //
- // Find out all logical devices
- //
- FatFindPartitions (PrivateData);
- //
- // Build up file system volume array
- //
- PrivateData->VolumeCount = 0;
- for (Index = 0; Index < PrivateData->BlockDeviceCount; Index++) {
- Volume.BlockDeviceNo = Index;
- Status = FatGetBpbInfo (PrivateData, &Volume);
- if (Status == EFI_SUCCESS) {
- //
- // Add the detected volume to the volume array
- //
- CopyMem (
- (UINT8 *)&(PrivateData->Volume[PrivateData->VolumeCount]),
- (UINT8 *)&Volume,
- sizeof (PEI_FAT_VOLUME)
- );
- PrivateData->VolumeCount += 1;
- if (PrivateData->VolumeCount >= PEI_FAT_MAX_VOLUME) {
- break;
- }
- }
- }
- return EFI_SUCCESS;
- }
- /**
- BlockIo installation notification function. Find out all the current BlockIO
- PPIs in the system and add them into private data. Assume there is
- @param PeiServices General purpose services available to every
- PEIM.
- @param NotifyDescriptor The typedef structure of the notification
- descriptor. Not used in this function.
- @param Ppi The typedef structure of the PPI descriptor.
- Not used in this function.
- @retval EFI_SUCCESS The function completed successfully.
- **/
- EFI_STATUS
- EFIAPI
- BlockIoNotifyEntry (
- IN EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
- IN VOID *Ppi
- )
- {
- if (CompareGuid (NotifyDescriptor->Guid, &gEfiPeiVirtualBlockIo2PpiGuid)) {
- UpdateBlocksAndVolumes (mPrivateData, TRUE);
- } else {
- UpdateBlocksAndVolumes (mPrivateData, FALSE);
- }
- return EFI_SUCCESS;
- }
- /**
- Installs the Device Recovery Module PPI, Initialize BlockIo Ppi
- installation notification
- @param FileHandle Handle of the file being invoked. Type
- EFI_PEI_FILE_HANDLE is defined in
- FfsFindNextFile().
- @param PeiServices Describes the list of possible PEI Services.
- @retval EFI_SUCCESS The entry point was executed successfully.
- @retval EFI_OUT_OF_RESOURCES There is no enough memory to complete the
- operations.
- **/
- EFI_STATUS
- EFIAPI
- FatPeimEntry (
- IN EFI_PEI_FILE_HANDLE FileHandle,
- IN CONST EFI_PEI_SERVICES **PeiServices
- )
- {
- EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS Address;
- PEI_FAT_PRIVATE_DATA *PrivateData;
- Status = PeiServicesRegisterForShadow (FileHandle);
- if (!EFI_ERROR (Status)) {
- return Status;
- }
- Status = PeiServicesAllocatePages (
- EfiBootServicesCode,
- (sizeof (PEI_FAT_PRIVATE_DATA) - 1) / PEI_FAT_MEMORY_PAGE_SIZE + 1,
- &Address
- );
- if (EFI_ERROR (Status)) {
- return EFI_OUT_OF_RESOURCES;
- }
- PrivateData = (PEI_FAT_PRIVATE_DATA *)(UINTN)Address;
- //
- // Initialize Private Data (to zero, as is required by subsequent operations)
- //
- ZeroMem ((UINT8 *)PrivateData, sizeof (PEI_FAT_PRIVATE_DATA));
- PrivateData->Signature = PEI_FAT_PRIVATE_DATA_SIGNATURE;
- //
- // Installs Ppi
- //
- PrivateData->DeviceRecoveryPpi.GetNumberRecoveryCapsules = GetNumberRecoveryCapsules;
- PrivateData->DeviceRecoveryPpi.GetRecoveryCapsuleInfo = GetRecoveryCapsuleInfo;
- PrivateData->DeviceRecoveryPpi.LoadRecoveryCapsule = LoadRecoveryCapsule;
- PrivateData->PpiDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
- PrivateData->PpiDescriptor.Guid = &gEfiPeiDeviceRecoveryModulePpiGuid;
- PrivateData->PpiDescriptor.Ppi = &PrivateData->DeviceRecoveryPpi;
- Status = PeiServicesInstallPpi (&PrivateData->PpiDescriptor);
- if (EFI_ERROR (Status)) {
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // Other initializations
- //
- PrivateData->BlockDeviceCount = 0;
- UpdateBlocksAndVolumes (PrivateData, TRUE);
- UpdateBlocksAndVolumes (PrivateData, FALSE);
- //
- // PrivateData is allocated now, set it to the module variable
- //
- mPrivateData = PrivateData;
- //
- // Installs Block Io Ppi notification function
- //
- PrivateData->NotifyDescriptor[0].Flags =
- (
- EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
- );
- PrivateData->NotifyDescriptor[0].Guid = &gEfiPeiVirtualBlockIoPpiGuid;
- PrivateData->NotifyDescriptor[0].Notify = BlockIoNotifyEntry;
- PrivateData->NotifyDescriptor[1].Flags =
- (
- EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |
- EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
- );
- PrivateData->NotifyDescriptor[1].Guid = &gEfiPeiVirtualBlockIo2PpiGuid;
- PrivateData->NotifyDescriptor[1].Notify = BlockIoNotifyEntry;
- return PeiServicesNotifyPpi (&PrivateData->NotifyDescriptor[0]);
- }
- /**
- Returns the number of DXE capsules residing on the device.
- This function searches for DXE capsules from the associated device and returns
- the number and maximum size in bytes of the capsules discovered. Entry 1 is
- assumed to be the highest load priority and entry N is assumed to be the lowest
- priority.
- @param[in] PeiServices General-purpose services that are available
- to every PEIM
- @param[in] This Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI
- instance.
- @param[out] NumberRecoveryCapsules Pointer to a caller-allocated UINTN. On
- output, *NumberRecoveryCapsules contains
- the number of recovery capsule images
- available for retrieval from this PEIM
- instance.
- @retval EFI_SUCCESS One or more capsules were discovered.
- @retval EFI_DEVICE_ERROR A device error occurred.
- @retval EFI_NOT_FOUND A recovery DXE capsule cannot be found.
- **/
- EFI_STATUS
- EFIAPI
- GetNumberRecoveryCapsules (
- IN EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This,
- OUT UINTN *NumberRecoveryCapsules
- )
- {
- EFI_STATUS Status;
- PEI_FAT_PRIVATE_DATA *PrivateData;
- UINTN Index;
- UINTN RecoveryCapsuleCount;
- PEI_FILE_HANDLE Handle;
- PrivateData = PEI_FAT_PRIVATE_DATA_FROM_THIS (This);
- //
- // Search each volume in the root directory for the Recovery capsule
- //
- RecoveryCapsuleCount = 0;
- for (Index = 0; Index < PrivateData->VolumeCount; Index++) {
- Status = FindRecoveryFile (PrivateData, Index, (CHAR16 *)PcdGetPtr (PcdRecoveryFileName), &Handle);
- if (EFI_ERROR (Status)) {
- continue;
- }
- RecoveryCapsuleCount++;
- }
- *NumberRecoveryCapsules = RecoveryCapsuleCount;
- if (*NumberRecoveryCapsules == 0) {
- return EFI_NOT_FOUND;
- }
- return EFI_SUCCESS;
- }
- /**
- Returns the size and type of the requested recovery capsule.
- This function gets the size and type of the capsule specified by CapsuleInstance.
- @param[in] PeiServices General-purpose services that are available to every PEIM
- @param[in] This Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI
- instance.
- @param[in] CapsuleInstance Specifies for which capsule instance to retrieve
- the information. This parameter must be between
- one and the value returned by GetNumberRecoveryCapsules()
- in NumberRecoveryCapsules.
- @param[out] Size A pointer to a caller-allocated UINTN in which
- the size of the requested recovery module is
- returned.
- @param[out] CapsuleType A pointer to a caller-allocated EFI_GUID in which
- the type of the requested recovery capsule is
- returned. The semantic meaning of the value
- returned is defined by the implementation.
- @retval EFI_SUCCESS One or more capsules were discovered.
- @retval EFI_DEVICE_ERROR A device error occurred.
- @retval EFI_NOT_FOUND A recovery DXE capsule cannot be found.
- **/
- EFI_STATUS
- EFIAPI
- GetRecoveryCapsuleInfo (
- IN EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This,
- IN UINTN CapsuleInstance,
- OUT UINTN *Size,
- OUT EFI_GUID *CapsuleType
- )
- {
- EFI_STATUS Status;
- PEI_FAT_PRIVATE_DATA *PrivateData;
- UINTN Index;
- UINTN BlockDeviceNo;
- UINTN RecoveryCapsuleCount;
- PEI_FILE_HANDLE Handle;
- UINTN NumberRecoveryCapsules;
- Status = GetNumberRecoveryCapsules (PeiServices, This, &NumberRecoveryCapsules);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- if ((CapsuleInstance == 0) || (CapsuleInstance > NumberRecoveryCapsules)) {
- return EFI_NOT_FOUND;
- }
- PrivateData = PEI_FAT_PRIVATE_DATA_FROM_THIS (This);
- //
- // Search each volume in the root directory for the Recovery capsule
- //
- RecoveryCapsuleCount = 0;
- for (Index = 0; Index < PrivateData->VolumeCount; Index++) {
- Status = FindRecoveryFile (PrivateData, Index, (CHAR16 *)PcdGetPtr (PcdRecoveryFileName), &Handle);
- if (EFI_ERROR (Status)) {
- continue;
- }
- if (CapsuleInstance - 1 == RecoveryCapsuleCount) {
- //
- // Get file size
- //
- *Size = (UINTN)(((PEI_FAT_FILE *)Handle)->FileSize);
- //
- // Find corresponding physical block device
- //
- BlockDeviceNo = PrivateData->Volume[Index].BlockDeviceNo;
- while (PrivateData->BlockDevice[BlockDeviceNo].Logical && BlockDeviceNo < PrivateData->BlockDeviceCount) {
- BlockDeviceNo = PrivateData->BlockDevice[BlockDeviceNo].ParentDevNo;
- }
- //
- // Fill in the Capsule Type GUID according to the block device type
- //
- if (BlockDeviceNo < PrivateData->BlockDeviceCount) {
- if (PrivateData->BlockDevice[BlockDeviceNo].BlockIo2 != NULL) {
- switch (PrivateData->BlockDevice[BlockDeviceNo].InterfaceType) {
- case MSG_ATAPI_DP:
- CopyGuid (CapsuleType, &gRecoveryOnFatIdeDiskGuid);
- break;
- case MSG_USB_DP:
- CopyGuid (CapsuleType, &gRecoveryOnFatUsbDiskGuid);
- break;
- case MSG_NVME_NAMESPACE_DP:
- CopyGuid (CapsuleType, &gRecoveryOnFatNvmeDiskGuid);
- break;
- default:
- break;
- }
- }
- if (PrivateData->BlockDevice[BlockDeviceNo].BlockIo != NULL) {
- switch (PrivateData->BlockDevice[BlockDeviceNo].DevType) {
- case LegacyFloppy:
- CopyGuid (CapsuleType, &gRecoveryOnFatFloppyDiskGuid);
- break;
- case IdeCDROM:
- case IdeLS120:
- CopyGuid (CapsuleType, &gRecoveryOnFatIdeDiskGuid);
- break;
- case UsbMassStorage:
- CopyGuid (CapsuleType, &gRecoveryOnFatUsbDiskGuid);
- break;
- default:
- break;
- }
- }
- }
- return EFI_SUCCESS;
- }
- RecoveryCapsuleCount++;
- }
- return EFI_NOT_FOUND;
- }
- /**
- Loads a DXE capsule from some media into memory.
- This function, by whatever mechanism, retrieves a DXE capsule from some device
- and loads it into memory. Note that the published interface is device neutral.
- @param[in] PeiServices General-purpose services that are available
- to every PEIM
- @param[in] This Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI
- instance.
- @param[in] CapsuleInstance Specifies which capsule instance to retrieve.
- @param[out] Buffer Specifies a caller-allocated buffer in which
- the requested recovery capsule will be returned.
- @retval EFI_SUCCESS The capsule was loaded correctly.
- @retval EFI_DEVICE_ERROR A device error occurred.
- @retval EFI_NOT_FOUND A requested recovery DXE capsule cannot be found.
- **/
- EFI_STATUS
- EFIAPI
- LoadRecoveryCapsule (
- IN EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This,
- IN UINTN CapsuleInstance,
- OUT VOID *Buffer
- )
- {
- EFI_STATUS Status;
- PEI_FAT_PRIVATE_DATA *PrivateData;
- UINTN Index;
- UINTN RecoveryCapsuleCount;
- PEI_FILE_HANDLE Handle;
- UINTN NumberRecoveryCapsules;
- Status = GetNumberRecoveryCapsules (PeiServices, This, &NumberRecoveryCapsules);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- if ((CapsuleInstance == 0) || (CapsuleInstance > NumberRecoveryCapsules)) {
- return EFI_NOT_FOUND;
- }
- PrivateData = PEI_FAT_PRIVATE_DATA_FROM_THIS (This);
- //
- // Search each volume in the root directory for the Recovery capsule
- //
- RecoveryCapsuleCount = 0;
- for (Index = 0; Index < PrivateData->VolumeCount; Index++) {
- Status = FindRecoveryFile (PrivateData, Index, (CHAR16 *)PcdGetPtr (PcdRecoveryFileName), &Handle);
- if (EFI_ERROR (Status)) {
- continue;
- }
- if (CapsuleInstance - 1 == RecoveryCapsuleCount) {
- Status = FatReadFile (
- PrivateData,
- Handle,
- (UINTN)(((PEI_FAT_FILE *)Handle)->FileSize),
- Buffer
- );
- return Status;
- }
- RecoveryCapsuleCount++;
- }
- return EFI_NOT_FOUND;
- }
- /**
- Finds the recovery file on a FAT volume.
- This function finds the recovery file named FileName on a specified FAT volume and returns
- its FileHandle pointer.
- @param PrivateData Global memory map for accessing global
- variables.
- @param VolumeIndex The index of the volume.
- @param FileName The recovery file name to find.
- @param Handle The output file handle.
- @retval EFI_DEVICE_ERROR Some error occurred when operating the FAT
- volume.
- @retval EFI_NOT_FOUND The recovery file was not found.
- @retval EFI_SUCCESS The recovery file was successfully found on the
- FAT volume.
- **/
- EFI_STATUS
- FindRecoveryFile (
- IN PEI_FAT_PRIVATE_DATA *PrivateData,
- IN UINTN VolumeIndex,
- IN CHAR16 *FileName,
- OUT PEI_FILE_HANDLE *Handle
- )
- {
- EFI_STATUS Status;
- PEI_FAT_FILE Parent;
- PEI_FAT_FILE *File;
- File = &PrivateData->File;
- //
- // VolumeIndex must be less than PEI_FAT_MAX_VOLUME because PrivateData->VolumeCount
- // cannot be larger than PEI_FAT_MAX_VOLUME when detecting recovery volume.
- //
- ASSERT (VolumeIndex < PEI_FAT_MAX_VOLUME);
- //
- // Construct root directory file
- //
- ZeroMem (&Parent, sizeof (PEI_FAT_FILE));
- Parent.IsFixedRootDir = (BOOLEAN)((PrivateData->Volume[VolumeIndex].FatType == Fat32) ? FALSE : TRUE);
- Parent.Attributes = FAT_ATTR_DIRECTORY;
- Parent.CurrentPos = 0;
- Parent.CurrentCluster = Parent.IsFixedRootDir ? 0 : PrivateData->Volume[VolumeIndex].RootDirCluster;
- Parent.StartingCluster = Parent.CurrentCluster;
- Parent.Volume = &PrivateData->Volume[VolumeIndex];
- Status = FatSetFilePos (PrivateData, &Parent, 0);
- if (EFI_ERROR (Status)) {
- return EFI_DEVICE_ERROR;
- }
- //
- // Search for recovery capsule in root directory
- //
- Status = FatReadNextDirectoryEntry (PrivateData, &Parent, File);
- while (Status == EFI_SUCCESS) {
- //
- // Compare whether the file name is recovery file name.
- //
- if (EngStriColl (PrivateData, FileName, File->FileName)) {
- break;
- }
- Status = FatReadNextDirectoryEntry (PrivateData, &Parent, File);
- }
- if (EFI_ERROR (Status)) {
- return EFI_NOT_FOUND;
- }
- //
- // Get the recovery file, set its file position to 0.
- //
- if (File->StartingCluster != 0) {
- Status = FatSetFilePos (PrivateData, File, 0);
- }
- *Handle = File;
- return EFI_SUCCESS;
- }
|