diff options
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Disk/CdExpressPei/PeiCdExpress.c')
-rw-r--r-- | src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Disk/CdExpressPei/PeiCdExpress.c | 715 |
1 files changed, 715 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Disk/CdExpressPei/PeiCdExpress.c b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Disk/CdExpressPei/PeiCdExpress.c new file mode 100644 index 00000000..a3a0be4d --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Disk/CdExpressPei/PeiCdExpress.c @@ -0,0 +1,715 @@ +/** @file + Source file for CD recovery PEIM + +Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR> + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PeiCdExpress.h" + +PEI_CD_EXPRESS_PRIVATE_DATA *mPrivateData = NULL; +CHAR8 *mRecoveryFileName; +UINTN mRecoveryFileNameSize; + +/** + Installs the Device Recovery Module PPI, Initialize BlockIo Ppi + installation notification + + @param FileHandle The file handle of the image. + @param PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory. + +**/ +EFI_STATUS +EFIAPI +CdExpressPeimEntry ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + PEI_CD_EXPRESS_PRIVATE_DATA *PrivateData; + + if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) { + return EFI_SUCCESS; + } + + PrivateData = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (*PrivateData))); + if (PrivateData == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + mRecoveryFileNameSize = PcdGetSize(PcdRecoveryFileName) / sizeof(CHAR16); + mRecoveryFileName = AllocatePool(mRecoveryFileNameSize); + if (mRecoveryFileName == NULL) { + return EFI_OUT_OF_RESOURCES; + } + Status = UnicodeStrToAsciiStrS(PcdGetPtr(PcdRecoveryFileName), mRecoveryFileName, mRecoveryFileNameSize); + if (EFI_ERROR(Status)) { + return Status; + } + + // + // Initialize Private Data (to zero, as is required by subsequent operations) + // + ZeroMem (PrivateData, sizeof (*PrivateData)); + PrivateData->Signature = PEI_CD_EXPRESS_PRIVATE_DATA_SIGNATURE; + + PrivateData->BlockBuffer = AllocatePages (EFI_SIZE_TO_PAGES (PEI_CD_BLOCK_SIZE)); + if (PrivateData->BlockBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + PrivateData->CapsuleCount = 0; + Status = UpdateBlocksAndVolumes (PrivateData, TRUE); + Status = UpdateBlocksAndVolumes (PrivateData, FALSE); + + // + // 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; + } + // + // 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 + ); + PrivateData->NotifyDescriptor.Guid = &gEfiPeiVirtualBlockIoPpiGuid; + PrivateData->NotifyDescriptor.Notify = BlockIoNotifyEntry; + + PrivateData->NotifyDescriptor2.Flags = + ( + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST + ); + PrivateData->NotifyDescriptor2.Guid = &gEfiPeiVirtualBlockIo2PpiGuid; + PrivateData->NotifyDescriptor2.Notify = BlockIoNotifyEntry; + + return PeiServicesNotifyPpi (&PrivateData->NotifyDescriptor); + +} + +/** + BlockIo installation notification function. + + This function finds out all the current Block IO PPIs in the system and add them + into private data. + + @param PeiServices Indirect reference to the PEI Services Table. + @param NotifyDescriptor Address of the notification descriptor data structure. + @param Ppi Address of the PPI that was installed. + + @retval EFI_SUCCESS The function completes 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; +} + +/** + Finds out all the current Block IO PPIs in the system and add them into private data. + + @param PrivateData The private data structure that contains recovery module information. + @param BlockIo2 Boolean to show whether using BlockIo2 or BlockIo. + + @retval EFI_SUCCESS The blocks and volumes are updated successfully. + +**/ +EFI_STATUS +UpdateBlocksAndVolumes ( + IN OUT PEI_CD_EXPRESS_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 IndexBlockDevice; + EFI_PEI_BLOCK_IO_MEDIA Media; + EFI_PEI_BLOCK_IO2_MEDIA Media2; + EFI_PEI_SERVICES **PeiServices; + + IndexBlockDevice = 0; + BlockIo2Ppi = NULL; + BlockIoPpi = NULL; + // + // Find out all Block Io Ppi instances within the system + // Assuming all device Block Io Peims are dispatched already + // + for (BlockIoPpiInstance = 0; BlockIoPpiInstance < PEI_CD_EXPRESS_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; + } + + PeiServices = (EFI_PEI_SERVICES **) GetPeiServicesTablePointer (); + if (BlockIo2) { + Status = BlockIo2Ppi->GetNumberOfBlockDevices ( + PeiServices, + BlockIo2Ppi, + &NumberBlockDevices + ); + } else { + Status = BlockIoPpi->GetNumberOfBlockDevices ( + PeiServices, + BlockIoPpi, + &NumberBlockDevices + ); + } + if (EFI_ERROR (Status) || (NumberBlockDevices == 0)) { + continue; + } + // + // Just retrieve the first block, should emulate all blocks. + // + for (IndexBlockDevice = 1; IndexBlockDevice <= NumberBlockDevices && PrivateData->CapsuleCount < PEI_CD_EXPRESS_MAX_CAPSULE_NUMBER; IndexBlockDevice ++) { + if (BlockIo2) { + Status = BlockIo2Ppi->GetBlockDeviceMediaInfo ( + PeiServices, + BlockIo2Ppi, + IndexBlockDevice, + &Media2 + ); + if (EFI_ERROR (Status) || + !Media2.MediaPresent || + ((Media2.InterfaceType != MSG_ATAPI_DP) && (Media2.InterfaceType != MSG_USB_DP)) || + (Media2.BlockSize != PEI_CD_BLOCK_SIZE) + ) { + continue; + } + DEBUG ((EFI_D_INFO, "PeiCdExpress InterfaceType is %d\n", Media2.InterfaceType)); + DEBUG ((EFI_D_INFO, "PeiCdExpress MediaPresent is %d\n", Media2.MediaPresent)); + DEBUG ((EFI_D_INFO, "PeiCdExpress BlockSize is 0x%x\n", Media2.BlockSize)); + } else { + Status = BlockIoPpi->GetBlockDeviceMediaInfo ( + PeiServices, + BlockIoPpi, + IndexBlockDevice, + &Media + ); + if (EFI_ERROR (Status) || + !Media.MediaPresent || + ((Media.DeviceType != IdeCDROM) && (Media.DeviceType != UsbMassStorage)) || + (Media.BlockSize != PEI_CD_BLOCK_SIZE) + ) { + continue; + } + DEBUG ((EFI_D_INFO, "PeiCdExpress DeviceType is %d\n", Media.DeviceType)); + DEBUG ((EFI_D_INFO, "PeiCdExpress MediaPresent is %d\n", Media.MediaPresent)); + DEBUG ((EFI_D_INFO, "PeiCdExpress BlockSize is 0x%x\n", Media.BlockSize)); + } + + DEBUG ((EFI_D_INFO, "PeiCdExpress Status is %d\n", Status)); + + DEBUG ((EFI_D_INFO, "IndexBlockDevice is %d\n", IndexBlockDevice)); + PrivateData->CapsuleData[PrivateData->CapsuleCount].IndexBlock = IndexBlockDevice; + if (BlockIo2) { + PrivateData->CapsuleData[PrivateData->CapsuleCount].BlockIo2 = BlockIo2Ppi; + } else { + PrivateData->CapsuleData[PrivateData->CapsuleCount].BlockIo = BlockIoPpi; + } + Status = FindRecoveryCapsules (PrivateData); + DEBUG ((EFI_D_INFO, "Status is %d\n", Status)); + + if (EFI_ERROR (Status)) { + continue; + } + + PrivateData->CapsuleCount++; + } + + } + + return EFI_SUCCESS; +} + +/** + Finds out the recovery capsule in the current volume. + + @param PrivateData The private data structure that contains recovery module information. + + @retval EFI_SUCCESS The recovery capsule is successfully found in the volume. + @retval EFI_NOT_FOUND The recovery capsule is not found in the volume. + +**/ +EFI_STATUS +EFIAPI +FindRecoveryCapsules ( + IN OUT PEI_CD_EXPRESS_PRIVATE_DATA *PrivateData + ) +{ + EFI_STATUS Status; + UINTN Lba; + EFI_PEI_RECOVERY_BLOCK_IO_PPI *BlockIoPpi; + EFI_PEI_RECOVERY_BLOCK_IO2_PPI *BlockIo2Ppi; + UINTN BufferSize; + UINT8 *Buffer; + UINT8 Type; + UINT8 *StandardID; + UINT32 RootDirLBA; + PEI_CD_EXPRESS_DIR_FILE_RECORD *RoorDirRecord; + UINTN VolumeSpaceSize; + BOOLEAN StartOfVolume; + UINTN OriginalLBA; + UINTN IndexBlockDevice; + + Buffer = PrivateData->BlockBuffer; + BufferSize = PEI_CD_BLOCK_SIZE; + + Lba = 16; + // + // The volume descriptor starts on Lba 16 + // + IndexBlockDevice = PrivateData->CapsuleData[PrivateData->CapsuleCount].IndexBlock; + BlockIoPpi = PrivateData->CapsuleData[PrivateData->CapsuleCount].BlockIo; + BlockIo2Ppi = PrivateData->CapsuleData[PrivateData->CapsuleCount].BlockIo2; + + VolumeSpaceSize = 0; + StartOfVolume = TRUE; + OriginalLBA = 16; + + while (TRUE) { + SetMem (Buffer, BufferSize, 0); + if (BlockIo2Ppi != NULL) { + Status = BlockIo2Ppi->ReadBlocks ( + (EFI_PEI_SERVICES **) GetPeiServicesTablePointer (), + BlockIo2Ppi, + IndexBlockDevice, + Lba, + BufferSize, + Buffer + ); + } else { + Status = BlockIoPpi->ReadBlocks ( + (EFI_PEI_SERVICES **) GetPeiServicesTablePointer (), + BlockIoPpi, + IndexBlockDevice, + Lba, + BufferSize, + Buffer + ); + } + if (EFI_ERROR (Status)) { + return Status; + } + + StandardID = (UINT8 *) (Buffer + PEI_CD_EXPRESS_STANDARD_ID_OFFSET); + if (!StringCmp (StandardID, (UINT8 *) PEI_CD_STANDARD_ID, PEI_CD_EXPRESS_STANDARD_ID_SIZE, TRUE)) { + break; + } + + if (StartOfVolume) { + OriginalLBA = Lba; + StartOfVolume = FALSE; + } + + Type = *(UINT8 *) (Buffer + PEI_CD_EXPRESS_VOLUME_TYPE_OFFSET); + if (Type == PEI_CD_EXPRESS_VOLUME_TYPE_TERMINATOR) { + if (VolumeSpaceSize == 0) { + break; + } else { + Lba = (OriginalLBA + VolumeSpaceSize); + VolumeSpaceSize = 0; + StartOfVolume = TRUE; + continue; + } + } + + if (Type != PEI_CD_EXPRESS_VOLUME_TYPE_PRIMARY) { + Lba++; + continue; + } + + VolumeSpaceSize = *(UINT32 *) (Buffer + PEI_CD_EXPRESS_VOLUME_SPACE_OFFSET); + + RoorDirRecord = (PEI_CD_EXPRESS_DIR_FILE_RECORD *) (Buffer + PEI_CD_EXPRESS_ROOT_DIR_RECORD_OFFSET); + RootDirLBA = RoorDirRecord->LocationOfExtent[0]; + + Status = RetrieveCapsuleFileFromRoot (PrivateData, BlockIoPpi, BlockIo2Ppi, IndexBlockDevice, RootDirLBA); + if (!EFI_ERROR (Status)) { + // + // Just look for the first primary descriptor + // + return EFI_SUCCESS; + } + + Lba++; + } + + return EFI_NOT_FOUND; +} + +/** + Retrieves the recovery capsule in root directory of the current volume. + + @param PrivateData The private data structure that contains recovery module information. + @param BlockIoPpi The Block IO PPI used to access the volume. + @param BlockIo2Ppi The Block IO 2 PPI used to access the volume. + @param IndexBlockDevice The index of current block device. + @param Lba The starting logic block address to retrieve capsule. + + @retval EFI_SUCCESS The recovery capsule is successfully found in the volume. + @retval EFI_NOT_FOUND The recovery capsule is not found in the volume. + @retval Others + +**/ +EFI_STATUS +EFIAPI +RetrieveCapsuleFileFromRoot ( + IN OUT PEI_CD_EXPRESS_PRIVATE_DATA *PrivateData, + IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *BlockIoPpi, + IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *BlockIo2Ppi, + IN UINTN IndexBlockDevice, + IN UINT32 Lba + ) +{ + EFI_STATUS Status; + UINTN BufferSize; + UINT8 *Buffer; + PEI_CD_EXPRESS_DIR_FILE_RECORD *FileRecord; + UINTN Index; + + Buffer = PrivateData->BlockBuffer; + BufferSize = PEI_CD_BLOCK_SIZE; + + SetMem (Buffer, BufferSize, 0); + + if (BlockIo2Ppi != NULL) { + Status = BlockIo2Ppi->ReadBlocks ( + (EFI_PEI_SERVICES **) GetPeiServicesTablePointer (), + BlockIo2Ppi, + IndexBlockDevice, + Lba, + BufferSize, + Buffer + ); + } else { + Status = BlockIoPpi->ReadBlocks ( + (EFI_PEI_SERVICES **) GetPeiServicesTablePointer (), + BlockIoPpi, + IndexBlockDevice, + Lba, + BufferSize, + Buffer + ); + } + if (EFI_ERROR (Status)) { + return Status; + } + + while (1) { + FileRecord = (PEI_CD_EXPRESS_DIR_FILE_RECORD *) Buffer; + + if (FileRecord->Length == 0) { + break; + } + // + // Not intend to check other flag now + // + if ((FileRecord->Flag & PEI_CD_EXPRESS_DIR_FILE_REC_FLAG_ISDIR) != 0) { + Buffer += FileRecord->Length; + continue; + } + + for (Index = 0; Index < FileRecord->FileIDLength; Index++) { + if (FileRecord->FileID[Index] == ';') { + break; + } + } + + if (Index != mRecoveryFileNameSize - 1) { + Buffer += FileRecord->Length; + continue; + } + + if (!StringCmp (FileRecord->FileID, (UINT8 *)mRecoveryFileName, mRecoveryFileNameSize - 1, FALSE)) { + Buffer += FileRecord->Length; + continue; + } + + PrivateData->CapsuleData[PrivateData->CapsuleCount].CapsuleStartLBA = FileRecord->LocationOfExtent[0]; + PrivateData->CapsuleData[PrivateData->CapsuleCount].CapsuleBlockAlignedSize = + ( + FileRecord->DataLength[0] / + PEI_CD_BLOCK_SIZE + + 1 + ) * + PEI_CD_BLOCK_SIZE; + PrivateData->CapsuleData[PrivateData->CapsuleCount].CapsuleSize = FileRecord->DataLength[0]; + + return EFI_SUCCESS; + } + + return EFI_NOT_FOUND; +} + +/** + 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 + ) +{ + PEI_CD_EXPRESS_PRIVATE_DATA *PrivateData; + + PrivateData = PEI_CD_EXPRESS_PRIVATE_DATA_FROM_THIS (This); + UpdateBlocksAndVolumes (PrivateData, TRUE); + UpdateBlocksAndVolumes (PrivateData, FALSE); + *NumberRecoveryCapsules = PrivateData->CapsuleCount; + + 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 + ) +{ + PEI_CD_EXPRESS_PRIVATE_DATA *PrivateData; + UINTN NumberRecoveryCapsules; + EFI_STATUS Status; + + Status = GetNumberRecoveryCapsules (PeiServices, This, &NumberRecoveryCapsules); + + if (EFI_ERROR (Status)) { + return Status; + } + + if ((CapsuleInstance == 0) || (CapsuleInstance > NumberRecoveryCapsules)) { + return EFI_NOT_FOUND; + } + + PrivateData = PEI_CD_EXPRESS_PRIVATE_DATA_FROM_THIS (This); + + *Size = PrivateData->CapsuleData[CapsuleInstance - 1].CapsuleSize; + CopyMem ( + CapsuleType, + &gRecoveryOnDataCdGuid, + sizeof (EFI_GUID) + ); + + return EFI_SUCCESS; +} + +/** + 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_CD_EXPRESS_PRIVATE_DATA *PrivateData; + EFI_PEI_RECOVERY_BLOCK_IO_PPI *BlockIoPpi; + EFI_PEI_RECOVERY_BLOCK_IO2_PPI *BlockIo2Ppi; + UINTN NumberRecoveryCapsules; + + Status = GetNumberRecoveryCapsules (PeiServices, This, &NumberRecoveryCapsules); + + if (EFI_ERROR (Status)) { + return Status; + } + + if ((CapsuleInstance == 0) || (CapsuleInstance > NumberRecoveryCapsules)) { + return EFI_NOT_FOUND; + } + + PrivateData = PEI_CD_EXPRESS_PRIVATE_DATA_FROM_THIS (This); + BlockIoPpi = PrivateData->CapsuleData[CapsuleInstance - 1].BlockIo; + BlockIo2Ppi = PrivateData->CapsuleData[CapsuleInstance - 1].BlockIo2; + + if (BlockIo2Ppi != NULL) { + Status = BlockIo2Ppi->ReadBlocks ( + PeiServices, + BlockIo2Ppi, + PrivateData->CapsuleData[CapsuleInstance - 1].IndexBlock, + PrivateData->CapsuleData[CapsuleInstance - 1].CapsuleStartLBA, + PrivateData->CapsuleData[CapsuleInstance - 1].CapsuleBlockAlignedSize, + Buffer + ); + } else { + Status = BlockIoPpi->ReadBlocks ( + PeiServices, + BlockIoPpi, + PrivateData->CapsuleData[CapsuleInstance - 1].IndexBlock, + PrivateData->CapsuleData[CapsuleInstance - 1].CapsuleStartLBA, + PrivateData->CapsuleData[CapsuleInstance - 1].CapsuleBlockAlignedSize, + Buffer + ); + } + return Status; +} + +/** + This function compares two ASCII strings in case sensitive/insensitive way. + + @param Source1 The first string. + @param Source2 The second string. + @param Size The maximum comparison length. + @param CaseSensitive Flag to indicate whether the comparison is case sensitive. + + @retval TRUE The two strings are the same. + @retval FALSE The two string are not the same. + +**/ +BOOLEAN +StringCmp ( + IN UINT8 *Source1, + IN UINT8 *Source2, + IN UINTN Size, + IN BOOLEAN CaseSensitive + ) +{ + UINTN Index; + UINT8 Dif; + + for (Index = 0; Index < Size; Index++) { + if (Source1[Index] == Source2[Index]) { + continue; + } + + if (!CaseSensitive) { + Dif = (UINT8) ((Source1[Index] > Source2[Index]) ? (Source1[Index] - Source2[Index]) : (Source2[Index] - Source1[Index])); + if (Dif == ('a' - 'A')) { + continue; + } + } + + return FALSE; + } + + return TRUE; +} |