| 297 | } |
| 298 | |
| 299 | bool Updater::StageUpdate() |
| 300 | { |
| 301 | m_progress->SetProgressRange(static_cast<u32>(m_update_paths.size())); |
| 302 | m_progress->SetProgressValue(0); |
| 303 | |
| 304 | #ifdef _WIN32 |
| 305 | UInt32 block_index = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */ |
| 306 | Byte* out_buffer = 0; /* it must be 0 before first call for each new archive. */ |
| 307 | size_t out_buffer_size = 0; /* it can have any value before first call (if outBuffer = 0) */ |
| 308 | ScopedGuard out_buffer_guard([&out_buffer]() { |
| 309 | if (out_buffer) |
| 310 | ISzAlloc_Free(&g_Alloc, out_buffer); |
| 311 | }); |
| 312 | |
| 313 | for (const FileToUpdate& ftu : m_update_paths) |
| 314 | { |
| 315 | m_progress->SetFormattedStatusText("Extracting '%s'...", ftu.destination_filename.c_str()); |
| 316 | m_progress->DisplayFormattedInformation("Decompressing '%s'...", ftu.destination_filename.c_str()); |
| 317 | |
| 318 | size_t out_offset = 0; |
| 319 | size_t extracted_size = 0; |
| 320 | SRes res = SzArEx_Extract(&m_archive, &m_look_stream.vt, ftu.file_index, |
| 321 | &block_index, &out_buffer, &out_buffer_size, &out_offset, &extracted_size, &g_Alloc, &g_Alloc); |
| 322 | if (res != SZ_OK) |
| 323 | { |
| 324 | m_progress->DisplayFormattedModalError("Failed to decompress file '%s' from 7z (file index=%u, error=%s)", |
| 325 | ftu.destination_filename.c_str(), ftu.file_index, SZErrorToString(res)); |
| 326 | return false; |
| 327 | } |
| 328 | |
| 329 | m_progress->DisplayFormattedInformation("Writing '%s' to staging (%zu bytes)...", ftu.destination_filename.c_str(), extracted_size); |
| 330 | |
| 331 | const std::string destination_file = StringUtil::StdStringFromFormat( |
| 332 | "%s" FS_OSPATH_SEPARATOR_STR "%s", m_staging_directory.c_str(), ftu.destination_filename.c_str()); |
| 333 | std::FILE* fp = FileSystem::OpenCFile(destination_file.c_str(), "wb"); |
| 334 | if (!fp) |
| 335 | { |
| 336 | m_progress->DisplayFormattedModalError("Failed to open staging output file '%s'", destination_file.c_str()); |
| 337 | return false; |
| 338 | } |
| 339 | |
| 340 | const bool wrote_completely = std::fwrite(out_buffer + out_offset, extracted_size, 1, fp) == 1 && std::fflush(fp) == 0; |
| 341 | if (std::fclose(fp) != 0 || !wrote_completely) |
| 342 | { |
| 343 | m_progress->DisplayFormattedModalError("Failed to write output file '%s'", destination_file.c_str()); |
| 344 | FileSystem::DeleteFilePath(destination_file.c_str()); |
| 345 | return false; |
| 346 | } |
| 347 | |
| 348 | m_progress->IncrementProgressValue(); |
| 349 | } |
| 350 | |
| 351 | return true; |
| 352 | #else |
| 353 | return false; |
| 354 | #endif |
| 355 | } |
| 356 |
no test coverage detected