| 3711 | } |
| 3712 | |
| 3713 | UINT8 FfsEngine::reconstructFile(const QModelIndex& index, const UINT8 revision, const UINT8 erasePolarity, const UINT32 base, QByteArray& reconstructed) |
| 3714 | { |
| 3715 | if (!index.isValid()) |
| 3716 | return ERR_SUCCESS; |
| 3717 | |
| 3718 | UINT8 result; |
| 3719 | |
| 3720 | // No action |
| 3721 | if (model->action(index) == Actions::NoAction || model->action(index) == Actions::DoNotRebuild) { |
| 3722 | reconstructed = model->header(index).append(model->body(index)); |
| 3723 | const EFI_FFS_FILE_HEADER* fileHeader = (const EFI_FFS_FILE_HEADER*)model->header(index).constData(); |
| 3724 | // Append tail, if needed |
| 3725 | if (fileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) { |
| 3726 | UINT8 ht = ~fileHeader->IntegrityCheck.Checksum.Header; |
| 3727 | UINT8 ft = ~fileHeader->IntegrityCheck.Checksum.File; |
| 3728 | reconstructed.append(ht).append(ft); |
| 3729 | } |
| 3730 | return ERR_SUCCESS; |
| 3731 | } |
| 3732 | else if (model->action(index) == Actions::Remove) { |
| 3733 | reconstructed.clear(); |
| 3734 | return ERR_SUCCESS; |
| 3735 | } |
| 3736 | else if (model->action(index) == Actions::Insert || |
| 3737 | model->action(index) == Actions::Replace || |
| 3738 | model->action(index) == Actions::Rebuild) { |
| 3739 | QByteArray header = model->header(index); |
| 3740 | EFI_FFS_FILE_HEADER* fileHeader = (EFI_FFS_FILE_HEADER*)header.data(); |
| 3741 | |
| 3742 | // Check erase polarity |
| 3743 | if (erasePolarity == ERASE_POLARITY_UNKNOWN) { |
| 3744 | msg(tr("reconstructFile: unknown erase polarity"), index); |
| 3745 | return ERR_INVALID_PARAMETER; |
| 3746 | } |
| 3747 | |
| 3748 | // Check file state |
| 3749 | // Check top reserved bit of file state to determine it's original erase polarity |
| 3750 | UINT8 state = fileHeader->State; |
| 3751 | if (state & EFI_FILE_ERASE_POLARITY) |
| 3752 | state = ~state; |
| 3753 | |
| 3754 | // Order of this checks must be preserved |
| 3755 | // Check file to have valid state, or delete it otherwise |
| 3756 | if (state & EFI_FILE_HEADER_INVALID) { |
| 3757 | // File marked to have invalid header and must be deleted |
| 3758 | // Do not add anything to queue |
| 3759 | msg(tr("reconstructFile: file is HEADER_INVALID state, and will be removed from reconstructed image"), index); |
| 3760 | return ERR_SUCCESS; |
| 3761 | } |
| 3762 | else if (state & EFI_FILE_DELETED) { |
| 3763 | // File marked to have been deleted form and must be deleted |
| 3764 | // Do not add anything to queue |
| 3765 | msg(tr("reconstructFile: file is in DELETED state, and will be removed from reconstructed image"), index); |
| 3766 | return ERR_SUCCESS; |
| 3767 | } |
| 3768 | else if (state & EFI_FILE_MARKED_FOR_UPDATE) { |
| 3769 | // File is marked for update, the mark must be removed |
| 3770 | msg(tr("reconstructFile: file's MARKED_FOR_UPDATE state cleared"), index); |
nothing calls this directly
no test coverage detected