diff options
Diffstat (limited to 'core/io')
-rw-r--r-- | core/io/file_access_pack.cpp | 68 |
1 files changed, 53 insertions, 15 deletions
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index c6e14ffee7..ba120de68b 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -32,6 +32,7 @@ #include "core/io/file_access_encrypted.h" #include "core/object/script_language.h" +#include "core/os/os.h" #include "core/version.h" #include <stdio.h> @@ -131,32 +132,69 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, return false; } - f->seek(p_offset); + bool pck_header_found = false; + // Search for the header at the start offset - standalone PCK file. + f->seek(p_offset); uint32_t magic = f->get_32(); + if (magic == PACK_HEADER_MAGIC) { + pck_header_found = true; + } - if (magic != PACK_HEADER_MAGIC) { - // loading with offset feature not supported for self contained exe files - ERR_FAIL_COND_V_MSG(p_offset != 0, false, "Loading self-contained executable with offset not supported."); + // Search for the header in the executable "pck" section - self contained executable. + if (!pck_header_found) { + // Loading with offset feature not supported for self contained exe files. + if (p_offset != 0) { + ERR_FAIL_V_MSG(false, "Loading self-contained executable with offset not supported."); + } - //maybe at the end.... self contained exe - f->seek_end(); - f->seek(f->get_position() - 4); - magic = f->get_32(); - if (magic != PACK_HEADER_MAGIC) { - return false; + int64_t pck_off = OS::get_singleton()->get_embedded_pck_offset(); + if (pck_off != 0) { + // Search for the header, in case PCK start and section have different alignment. + for (int i = 0; i < 8; i++) { + f->seek(pck_off); + magic = f->get_32(); + if (magic == PACK_HEADER_MAGIC) { +#ifdef DEBUG_ENABLED + print_verbose("PCK header found in executable pck section, loading from offset 0x" + String::num_int64(pck_off - 4, 16)); +#endif + pck_header_found = true; + break; + } + pck_off++; + } } - f->seek(f->get_position() - 12); + } - uint64_t ds = f->get_64(); - f->seek(f->get_position() - ds - 8); + // Search for the header at the end of file - self contained executable. + if (!pck_header_found) { + // Loading with offset feature not supported for self contained exe files. + if (p_offset != 0) { + ERR_FAIL_V_MSG(false, "Loading self-contained executable with offset not supported."); + } + f->seek_end(); + f->seek(f->get_position() - 4); magic = f->get_32(); - if (magic != PACK_HEADER_MAGIC) { - return false; + + if (magic == PACK_HEADER_MAGIC) { + f->seek(f->get_position() - 12); + uint64_t ds = f->get_64(); + f->seek(f->get_position() - ds - 8); + magic = f->get_32(); + if (magic == PACK_HEADER_MAGIC) { +#ifdef DEBUG_ENABLED + print_verbose("PCK header found at the end of executable, loading from offset 0x" + String::num_int64(f->get_position() - 4, 16)); +#endif + pck_header_found = true; + } } } + if (!pck_header_found) { + return false; + } + uint32_t version = f->get_32(); uint32_t ver_major = f->get_32(); uint32_t ver_minor = f->get_32(); |