/** 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; }
/** 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 (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) { CapsuleInstance = CapsuleInstance + 1; } 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].CapsuleSize, Buffer ); } else { Status = BlockIoPpi->ReadBlocks ( PeiServices, BlockIoPpi, PrivateData->CapsuleData[CapsuleInstance - 1].IndexBlock, PrivateData->CapsuleData[CapsuleInstance - 1].CapsuleStartLBA, PrivateData->CapsuleData[CapsuleInstance - 1].CapsuleSize, Buffer ); } return Status; }
/** 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 (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) { CapsuleInstance = CapsuleInstance + 1; } 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; }
/** 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) { 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; 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; }