BOOLEAN BootMonFsImageInThisBlock ( IN VOID *Buf, IN UINTN Size, IN UINT32 Block, OUT HW_IMAGE_DESCRIPTION *Image ) { EFI_STATUS Status; HW_IMAGE_FOOTER *Ptr; HW_IMAGE_DESCRIPTION *Footer; UINT32 Checksum; // The footer is stored as the last thing in the block Ptr = (HW_IMAGE_FOOTER *)((UINT8 *)Buf + Size - sizeof (HW_IMAGE_FOOTER)); // Check that the verification bytes are present if ((Ptr->FooterSignature1 != HW_IMAGE_FOOTER_SIGNATURE_1) || (Ptr->FooterSignature2 != HW_IMAGE_FOOTER_SIGNATURE_2)) { return FALSE; } if (Ptr->Version == HW_IMAGE_FOOTER_VERSION) { if (Ptr->Offset != HW_IMAGE_FOOTER_OFFSET) { return FALSE; } } else if (Ptr->Version == HW_IMAGE_FOOTER_VERSION2) { if (Ptr->Offset != HW_IMAGE_FOOTER_OFFSET2) { return FALSE; } } else { return FALSE; } Footer = (HW_IMAGE_DESCRIPTION *)(((UINT8 *)Buf + Size - sizeof (HW_IMAGE_DESCRIPTION))); Checksum = Footer->FooterChecksum; Status = BootMonFsComputeFooterChecksum (Footer); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Warning: failed to compute checksum for image '%a'\n", Footer->Footer.Filename)); } if (Footer->FooterChecksum != Checksum) { DEBUG ((DEBUG_ERROR, "Warning: image '%a' checksum mismatch.\n", Footer->Footer.Filename)); } if ((Footer->BlockEnd != Block) || (Footer->BlockStart > Footer->BlockEnd)) { return FALSE; } // Copy the image out CopyMem (Image, Footer, sizeof (HW_IMAGE_DESCRIPTION)); return TRUE; }
// Flush file data that will extend the file's length. Update and, if necessary, // move the image description. // We need to pass the file's starting position on media (FileStart), because // if the file hasn't been flushed before its Description->BlockStart won't // have been initialised. // FileStart must be aligned to the media's block size. // Note that this function uses DiskIo to flush, so call BlockIo->FlushBlocks() // after calling it. STATIC EFI_STATUS FlushAppendRegion ( IN BOOTMON_FS_FILE *File, IN BOOTMON_FS_FILE_REGION *Region, IN UINT64 NewFileSize, IN UINT64 FileStart ) { EFI_STATUS Status; EFI_DISK_IO_PROTOCOL *DiskIo; UINTN BlockSize; HW_IMAGE_DESCRIPTION *Description; DiskIo = File->Instance->DiskIo; BlockSize = File->Instance->BlockIo->Media->BlockSize; ASSERT (FileStart % BlockSize == 0); // Only invalidate the Image Description of files that have already been // written in Flash if (File->HwDescription.RegionCount > 0) { Status = InvalidateImageDescription (File); ASSERT_EFI_ERROR (Status); } // // Update File Description // Description = &File->HwDescription; Description->Attributes = 1; Description->BlockStart = FileStart / BlockSize; Description->BlockEnd = Description->BlockStart + (NewFileSize / BlockSize); Description->Footer.FooterSignature1 = HW_IMAGE_FOOTER_SIGNATURE_1; Description->Footer.FooterSignature2 = HW_IMAGE_FOOTER_SIGNATURE_2; Description->Footer.Version = HW_IMAGE_FOOTER_VERSION; Description->Footer.Offset = HW_IMAGE_FOOTER_OFFSET; Description->RegionCount = 1; Description->Region[0].Checksum = 0; Description->Region[0].Offset = Description->BlockStart * BlockSize; Description->Region[0].Size = NewFileSize - sizeof (HW_IMAGE_DESCRIPTION); Status = BootMonFsComputeFooterChecksum (Description); if (EFI_ERROR (Status)) { return Status; } // Write the new file data Status = DiskIo->WriteDisk ( DiskIo, File->Instance->Media->MediaId, FileStart + Region->Offset, Region->Size, Region->Buffer ); ASSERT_EFI_ERROR (Status); // Round the file size up to the nearest block size if ((NewFileSize % BlockSize) > 0) { NewFileSize += BlockSize - (NewFileSize % BlockSize); } // Update the file description on the media Status = DiskIo->WriteDisk ( DiskIo, File->Instance->Media->MediaId, (FileStart + NewFileSize) - sizeof (HW_IMAGE_DESCRIPTION), sizeof (HW_IMAGE_DESCRIPTION), Description ); ASSERT_EFI_ERROR (Status); return Status; }