From 2f1da04cc340c74d194335c286e14e0428496d21 Mon Sep 17 00:00:00 2001 From: Amaury Pouly Date: Wed, 27 Jun 2012 14:51:56 +0200 Subject: [PATCH] zenutils/update_extract: make sure the archive is valid The update_extract tool works by finding the compressed size and the compressed data in the updater. This is problematic since without the uncompressed size, inflate can produce extra bytes at end. This is not a problem for our tools but the device will plain reject it if sent by MTP/sendfirm for example. Workaround this issue by reading and rewriting the archive after decompression so that only the meaningfull data is written. Change-Id: I117f434b92a56d93d269af49c3e426cd8cc0c7e4 --- utils/zenutils/source/update_extract/main.cpp | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/utils/zenutils/source/update_extract/main.cpp b/utils/zenutils/source/update_extract/main.cpp index 6c7b5b1a4c..d04a7134fb 100644 --- a/utils/zenutils/source/update_extract/main.cpp +++ b/utils/zenutils/source/update_extract/main.cpp @@ -23,6 +23,7 @@ #include #include #include +#include static const char VERSION[] = "0.1"; @@ -225,6 +226,38 @@ int process_arguments(int argc, char* argv[]) return 10; } + if (verbose) + std::cout << "[*] Normalizing firmware archive..." << std::endl; + + /* We only know the compressed size of the archive, not the uncompressed one. + * In some cases (like in some Zen X-Fi updater), the uncompressed archive + * has extraneous zero bytes at the end which will make the device reject + * the firmware. To normalize the archives, we simply read it and write it + * again, so that it will remove all useless extra bytes */ + zen::firmware_archive archive(false); + std::ifstream ifs; + ifs.open(firmarename.c_str(), std::ios::binary); + if (!ifs) + { + std::cerr << "Failed to open the firmware archive." << std::endl; + return 11; + } + + if (!archive.read(ifs)) + { + std::cerr << "Failed to read the firmware archive." << std::endl; + return 12; + } + ifs.close(); + + std::ofstream ofs; + ofs.open(firmarename.c_str(), std::ios::binary); + if (!archive.write(ofs)) + { + std::cerr << "Failed to write the firmware archive." << std::endl; + return 13; + } + ofs.close(); //-------------------------------------------------------------------- // Generate an options file for the extracted firmware archive. @@ -237,7 +270,6 @@ int process_arguments(int argc, char* argv[]) std::cout << "[*] Producing options file..." << std::endl; // Produce options file for the given input file. - std::ofstream ofs; ofs.open(optionsname.c_str(), std::ios::binary); if (!ofs) {