| 3337 | } |
| 3338 | |
| 3339 | UINT8 FfsEngine::reconstructVolume(const QModelIndex & index, QByteArray & reconstructed) |
| 3340 | { |
| 3341 | if (!index.isValid()) |
| 3342 | return ERR_SUCCESS; |
| 3343 | |
| 3344 | UINT8 result; |
| 3345 | |
| 3346 | // No action |
| 3347 | if (model->action(index) == Actions::NoAction || model->action(index) == Actions::DoNotRebuild) { |
| 3348 | reconstructed = model->header(index).append(model->body(index)); |
| 3349 | return ERR_SUCCESS; |
| 3350 | } |
| 3351 | else if (model->action(index) == Actions::Remove) { |
| 3352 | reconstructed.clear(); |
| 3353 | return ERR_SUCCESS; |
| 3354 | } |
| 3355 | else if (model->action(index) == Actions::Replace || |
| 3356 | model->action(index) == Actions::Rebuild) { |
| 3357 | QByteArray header = model->header(index); |
| 3358 | QByteArray body = model->body(index); |
| 3359 | EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)header.data(); |
| 3360 | |
| 3361 | // Check sanity of HeaderLength |
| 3362 | if (volumeHeader->HeaderLength > header.size()) { |
| 3363 | msg(tr("reconstructVolume: invalid volume header length, reconstruction is not possible"), index); |
| 3364 | return ERR_INVALID_VOLUME; |
| 3365 | } |
| 3366 | |
| 3367 | // Recalculate volume header checksum |
| 3368 | volumeHeader->Checksum = 0; |
| 3369 | volumeHeader->Checksum = calculateChecksum16((const UINT16*)volumeHeader, volumeHeader->HeaderLength); |
| 3370 | |
| 3371 | // Get volume size |
| 3372 | UINT32 volumeSize = header.size() + body.size(); |
| 3373 | |
| 3374 | // Reconstruct volume body |
| 3375 | UINT32 freeSpaceOffset = 0; |
| 3376 | if (model->rowCount(index)) { |
| 3377 | reconstructed.clear(); |
| 3378 | UINT8 polarity = volumeHeader->Attributes & EFI_FVB_ERASE_POLARITY ? ERASE_POLARITY_TRUE : ERASE_POLARITY_FALSE; |
| 3379 | char empty = volumeHeader->Attributes & EFI_FVB_ERASE_POLARITY ? '\xFF' : '\x00'; |
| 3380 | |
| 3381 | // Calculate volume base for volume |
| 3382 | UINT32 volumeBase; |
| 3383 | QByteArray file; |
| 3384 | bool baseFound = false; |
| 3385 | |
| 3386 | // Search for VTF |
| 3387 | for (int i = 0; i < model->rowCount(index); i++) { |
| 3388 | file = model->header(index.child(i, 0)); |
| 3389 | // VTF found |
| 3390 | if (file.left(sizeof(EFI_GUID)) == EFI_FFS_VOLUME_TOP_FILE_GUID) { |
| 3391 | baseFound = true; |
| 3392 | volumeBase = (UINT32)(0x100000000 - volumeSize); |
| 3393 | break; |
| 3394 | } |
| 3395 | } |
| 3396 |
nothing calls this directly
no test coverage detected