FatPkg: Add FAT PEIM
Signed-off-by: jljusten Reviewed-by: mdkinney (based on FatPkg commit bead7f219277e063ed28589de8ddd01cf180c1a8) [jordan.l.justen@intel.com: Use script to relicense to 2-clause BSD] Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jordan Justen <jordan.l.justen@intel.com> Acked-by: Mark Doran <mark.doran@intel.com> Acked-by: Laszlo Ersek <lersek@redhat.com>
This commit is contained in:
611
FatPkg/FatPei/FatLiteApi.c
Normal file
611
FatPkg/FatPei/FatLiteApi.c
Normal file
@@ -0,0 +1,611 @@
|
||||
/** @file
|
||||
FAT recovery PEIM entry point, Ppi Functions and FAT Api functions.
|
||||
|
||||
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials are licensed and made available
|
||||
under the terms and conditions of the BSD License which accompanies this
|
||||
distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include "FatLitePeim.h"
|
||||
|
||||
PEI_FAT_PRIVATE_DATA *mPrivateData = NULL;
|
||||
|
||||
/**
|
||||
BlockIo installation nofication 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.
|
||||
|
||||
@retval EFI_SUCCESS The function completed successfully.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
UpdateBlocksAndVolumes (
|
||||
IN OUT PEI_FAT_PRIVATE_DATA *PrivateData
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PEI_PPI_DESCRIPTOR *TempPpiDescriptor;
|
||||
UINTN BlockIoPpiInstance;
|
||||
EFI_PEI_RECOVERY_BLOCK_IO_PPI *BlockIoPpi;
|
||||
UINTN NumberBlockDevices;
|
||||
UINTN Index;
|
||||
EFI_PEI_BLOCK_IO_MEDIA Media;
|
||||
PEI_FAT_VOLUME Volume;
|
||||
EFI_PEI_SERVICES **PeiServices;
|
||||
|
||||
PeiServices = (EFI_PEI_SERVICES **) GetPeiServicesTablePointer ();
|
||||
|
||||
//
|
||||
// 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++) {
|
||||
Status = PeiServicesLocatePpi (
|
||||
&gEfiPeiVirtualBlockIoPpiGuid,
|
||||
BlockIoPpiInstance,
|
||||
&TempPpiDescriptor,
|
||||
(VOID **) &BlockIoPpi
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// Done with all Block Io Ppis
|
||||
//
|
||||
break;
|
||||
}
|
||||
|
||||
Status = BlockIoPpi->GetNumberOfBlockDevices (
|
||||
PeiServices,
|
||||
BlockIoPpi,
|
||||
&NumberBlockDevices
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (Index = 1; Index <= NumberBlockDevices && PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE; Index++) {
|
||||
|
||||
Status = BlockIoPpi->GetBlockDeviceMediaInfo (
|
||||
PeiServices,
|
||||
BlockIoPpi,
|
||||
Index,
|
||||
&Media
|
||||
);
|
||||
if (EFI_ERROR (Status) || !Media.MediaPresent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockSize = (UINT32) Media.BlockSize;
|
||||
PrivateData->BlockDevice[PrivateData->BlockDeviceCount].LastBlock = Media.LastBlock;
|
||||
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].BlockIo = BlockIoPpi;
|
||||
PrivateData->BlockDevice[PrivateData->BlockDeviceCount].PhysicalDevNo = (UINT8) Index;
|
||||
PrivateData->BlockDevice[PrivateData->BlockDeviceCount].DevType = Media.DeviceType;
|
||||
|
||||
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
|
||||
)
|
||||
{
|
||||
UpdateBlocksAndVolumes (mPrivateData);
|
||||
|
||||
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_MEMMORY_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);
|
||||
|
||||
//
|
||||
// PrivateData is allocated now, set it to the module variable
|
||||
//
|
||||
mPrivateData = PrivateData;
|
||||
|
||||
//
|
||||
// Installs Block Io Ppi notification function
|
||||
//
|
||||
PrivateData->NotifyDescriptor.Flags =
|
||||
(
|
||||
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |
|
||||
EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
|
||||
);
|
||||
PrivateData->NotifyDescriptor.Guid = &gEfiPeiVirtualBlockIoPpiGuid;
|
||||
PrivateData->NotifyDescriptor.Notify = BlockIoNotifyEntry;
|
||||
return PeiServicesNotifyPpi (&PrivateData->NotifyDescriptor);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
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, PEI_FAT_RECOVERY_CAPSULE_WITHOUT_NT_EMULATOR, &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 (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {
|
||||
CapsuleInstance = CapsuleInstance + 1;
|
||||
}
|
||||
|
||||
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, PEI_FAT_RECOVERY_CAPSULE_WITHOUT_NT_EMULATOR, &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) {
|
||||
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 (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {
|
||||
CapsuleInstance = CapsuleInstance + 1;
|
||||
}
|
||||
|
||||
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, PEI_FAT_RECOVERY_CAPSULE_WITHOUT_NT_EMULATOR, &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 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 occured 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
|
||||
//
|
||||
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) {
|
||||
if (EngStriColl (PrivateData, FileName, File->FileName)) {
|
||||
break;
|
||||
}
|
||||
|
||||
Status = FatReadNextDirectoryEntry (PrivateData, &Parent, File);
|
||||
}
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
*Handle = File;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
}
|
Reference in New Issue
Block a user