diff options
Diffstat (limited to 'platform/uwp/export/export.cpp')
-rw-r--r-- | platform/uwp/export/export.cpp | 213 |
1 files changed, 106 insertions, 107 deletions
diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp index 6a7284f770..fefad3584b 100644 --- a/platform/uwp/export/export.cpp +++ b/platform/uwp/export/export.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,9 +30,11 @@ #include "export.h" #include "core/bind/core_bind.h" +#include "core/crypto/crypto_core.h" #include "core/io/marshalls.h" #include "core/io/zip_io.h" #include "core/object.h" +#include "core/os/dir_access.h" #include "core/os/file_access.h" #include "core/project_settings.h" #include "core/version.h" @@ -42,8 +44,6 @@ #include "thirdparty/minizip/unzip.h" #include "thirdparty/minizip/zip.h" -#include "thirdparty/misc/base64.h" -#include "thirdparty/misc/sha256.h" #include <zlib.h> @@ -73,7 +73,7 @@ static const char *uwp_uap_capabilities[] = { "voipCall", NULL }; -static const char *uwp_device_capabilites[] = { +static const char *uwp_device_capabilities[] = { "bluetooth", "location", "microphone", @@ -134,8 +134,6 @@ class AppxPackager { String progress_task; FileAccess *package; - String tmp_blockmap_file_path; - String tmp_content_types_file_path; Set<String> mime_types; @@ -147,8 +145,8 @@ class AppxPackager { String hash_block(const uint8_t *p_block_data, size_t p_block_len); - void make_block_map(); - void make_content_types(); + void make_block_map(const String &p_path); + void make_content_types(const String &p_path); _FORCE_INLINE_ unsigned int buf_put_int16(uint16_t p_val, uint8_t *p_buf) { for (int i = 0; i < 2; i++) { @@ -187,7 +185,7 @@ class AppxPackager { public: void set_progress_task(String p_task) { progress_task = p_task; } void init(FileAccess *p_fa); - void add_file(String p_file_name, const uint8_t *p_buffer, size_t p_len, int p_file_no, int p_total_files, bool p_compress = false); + Error add_file(String p_file_name, const uint8_t *p_buffer, size_t p_len, int p_file_no, int p_total_files, bool p_compress = false); void finish(); AppxPackager(); @@ -198,23 +196,20 @@ public: String AppxPackager::hash_block(const uint8_t *p_block_data, size_t p_block_len) { - char hash[32]; + unsigned char hash[32]; char base64[45]; - sha256_context ctx; - sha256_init(&ctx); - sha256_hash(&ctx, (uint8_t *)p_block_data, p_block_len); - sha256_done(&ctx, (uint8_t *)hash); - - base64_encode(base64, hash, 32); + CryptoCore::sha256(p_block_data, p_block_len, hash); + size_t len = 0; + CryptoCore::b64_encode((unsigned char *)base64, 45, &len, (unsigned char *)hash, 32); base64[44] = '\0'; return String(base64); } -void AppxPackager::make_block_map() { +void AppxPackager::make_block_map(const String &p_path) { - FileAccess *tmp_file = FileAccess::open(tmp_blockmap_file_path, FileAccess::WRITE); + FileAccess *tmp_file = FileAccess::open(p_path, FileAccess::WRITE); tmp_file->store_string("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"); tmp_file->store_string("<BlockMap xmlns=\"http://schemas.microsoft.com/appx/2010/blockmap\" HashMethod=\"http://www.w3.org/2001/04/xmlenc#sha256\">"); @@ -241,7 +236,6 @@ void AppxPackager::make_block_map() { tmp_file->close(); memdelete(tmp_file); - tmp_file = NULL; } String AppxPackager::content_type(String p_extension) { @@ -258,9 +252,9 @@ String AppxPackager::content_type(String p_extension) { return "application/octet-stream"; } -void AppxPackager::make_content_types() { +void AppxPackager::make_content_types(const String &p_path) { - FileAccess *tmp_file = FileAccess::open(tmp_content_types_file_path, FileAccess::WRITE); + FileAccess *tmp_file = FileAccess::open(p_path, FileAccess::WRITE); tmp_file->store_string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); tmp_file->store_string("<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">"); @@ -291,7 +285,6 @@ void AppxPackager::make_content_types() { tmp_file->close(); memdelete(tmp_file); - tmp_file = NULL; } Vector<uint8_t> AppxPackager::make_file_header(FileMeta p_file_meta) { @@ -464,14 +457,14 @@ void AppxPackager::init(FileAccess *p_fa) { package = p_fa; central_dir_offset = 0; end_of_central_dir_offset = 0; - tmp_blockmap_file_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpblockmap.xml"); - tmp_content_types_file_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpcontenttypes.xml"); } -void AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t p_len, int p_file_no, int p_total_files, bool p_compress) { +Error AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t p_len, int p_file_no, int p_total_files, bool p_compress) { if (p_file_no >= 1 && p_total_files >= 1) { - EditorNode::progress_task_step(progress_task, "File: " + p_file_name, (p_file_no * 100) / p_total_files); + if (EditorNode::progress_task_step(progress_task, "File: " + p_file_name, (p_file_no * 100) / p_total_files)) { + return ERR_SKIP; + } } FileMeta meta; @@ -505,9 +498,9 @@ void AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t while (p_len - step > 0) { - size_t block_size = (p_len - step) > BLOCK_SIZE ? BLOCK_SIZE : (p_len - step); + size_t block_size = (p_len - step) > BLOCK_SIZE ? (size_t)BLOCK_SIZE : (p_len - step); - for (uint32_t i = 0; i < block_size; i++) { + for (uint64_t i = 0; i < block_size; i++) { strm_in.write[i] = p_buffer[step + i]; } @@ -523,20 +516,22 @@ void AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t int total_out_before = strm.total_out; - deflate(&strm, Z_FULL_FLUSH); + int err = deflate(&strm, Z_FULL_FLUSH); + ERR_FAIL_COND_V(err >= 0, ERR_BUG); // Negative means bug + bh.compressed_size = strm.total_out - total_out_before; //package->store_buffer(strm_out.ptr(), strm.total_out - total_out_before); int start = file_buffer.size(); file_buffer.resize(file_buffer.size() + bh.compressed_size); - for (uint32_t i = 0; i < bh.compressed_size; i++) + for (uint64_t i = 0; i < bh.compressed_size; i++) file_buffer.write[start + i] = strm_out[i]; } else { bh.compressed_size = block_size; //package->store_buffer(strm_in.ptr(), block_size); int start = file_buffer.size(); file_buffer.resize(file_buffer.size() + block_size); - for (uint32_t i = 0; i < bh.compressed_size; i++) + for (uint64_t i = 0; i < bh.compressed_size; i++) file_buffer.write[start + i] = strm_in[i]; } @@ -559,7 +554,7 @@ void AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t //package->store_buffer(strm_out.ptr(), strm.total_out - total_out_before); int start = file_buffer.size(); file_buffer.resize(file_buffer.size() + (strm.total_out - total_out_before)); - for (uint32_t i = 0; i < (strm.total_out - total_out_before); i++) + for (uint64_t i = 0; i < (strm.total_out - total_out_before); i++) file_buffer.write[start + i] = strm_out[i]; deflateEnd(&strm); @@ -584,6 +579,8 @@ void AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t package->store_buffer(file_buffer.ptr(), file_buffer.size()); file_metadata.push_back(meta); + + return OK; } void AppxPackager::finish() { @@ -591,7 +588,9 @@ void AppxPackager::finish() { // Create and add block map file EditorNode::progress_task_step("export", "Creating block map...", 4); - make_block_map(); + const String &tmp_blockmap_file_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpblockmap.xml"); + make_block_map(tmp_blockmap_file_path); + FileAccess *blockmap_file = FileAccess::open(tmp_blockmap_file_path, FileAccess::READ); Vector<uint8_t> blockmap_buffer; blockmap_buffer.resize(blockmap_file->get_len()); @@ -602,11 +601,13 @@ void AppxPackager::finish() { blockmap_file->close(); memdelete(blockmap_file); - blockmap_file = NULL; // Add content types + EditorNode::progress_task_step("export", "Setting content types...", 5); - make_content_types(); + + const String &tmp_content_types_file_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpcontenttypes.xml"); + make_content_types(tmp_content_types_file_path); FileAccess *types_file = FileAccess::open(tmp_content_types_file_path, FileAccess::READ); Vector<uint8_t> types_buffer; @@ -618,7 +619,10 @@ void AppxPackager::finish() { types_file->close(); memdelete(types_file); - types_file = NULL; + + // Cleanup generated files. + DirAccess::remove_file_or_error(tmp_blockmap_file_path); + DirAccess::remove_file_or_error(tmp_content_types_file_path); // Pre-process central directory before signing for (int i = 0; i < file_metadata.size(); i++) { @@ -646,9 +650,9 @@ AppxPackager::~AppxPackager() {} //////////////////////////////////////////////////////////////////// -class EditorExportUWP : public EditorExportPlatform { +class EditorExportPlatformUWP : public EditorExportPlatform { - GDCLASS(EditorExportUWP, EditorExportPlatform); + GDCLASS(EditorExportPlatformUWP, EditorExportPlatform); Ref<ImageTexture> logo; @@ -841,7 +845,7 @@ class EditorExportUWP : public EditorExportPlatform { } uap++; } - const char **device = uwp_device_capabilites; + const char **device = uwp_device_capabilities; while (*device) { if ((bool)p_preset->get("capabilities/" + String(*device))) { capabilities_elements += " <DeviceCapability Name=\"" + String(*device) + "\" />\n"; @@ -903,8 +907,7 @@ class EditorExportUWP : public EditorExportPlatform { String err_string = "Couldn't save temp logo file."; EditorNode::add_io_error(err_string); - ERR_EXPLAIN(err_string); - ERR_FAIL_V(data); + ERR_FAIL_V_MSG(data, err_string); } FileAccess *f = FileAccess::open(tmp_path, FileAccess::READ, &err); @@ -912,10 +915,10 @@ class EditorExportUWP : public EditorExportPlatform { if (err != OK) { String err_string = "Couldn't open temp logo file."; - + // Cleanup generated file. + DirAccess::remove_file_or_error(tmp_path); EditorNode::add_io_error(err_string); - ERR_EXPLAIN(err_string); - ERR_FAIL_V(data); + ERR_FAIL_V_MSG(data, err_string); } data.resize(f->get_len()); @@ -923,31 +926,7 @@ class EditorExportUWP : public EditorExportPlatform { f->close(); memdelete(f); - - // Delete temp file - DirAccess *dir = DirAccess::open(tmp_path.get_base_dir(), &err); - - if (err != OK) { - - String err_string = "Couldn't open temp path to remove temp logo file."; - - EditorNode::add_io_error(err_string); - ERR_EXPLAIN(err_string); - ERR_FAIL_V(data); - } - - err = dir->remove(tmp_path); - - memdelete(dir); - - if (err != OK) { - - String err_string = "Couldn't remove temp logo file."; - - EditorNode::add_io_error(err_string); - ERR_EXPLAIN(err_string); - ERR_FAIL_V(data); - } + DirAccess::remove_file_or_error(tmp_path); return data; } @@ -1008,9 +987,7 @@ class EditorExportUWP : public EditorExportPlatform { AppxPackager *packager = (AppxPackager *)p_userdata; String dst_path = p_path.replace_first("res://", "game/"); - packager->add_file(dst_path, p_data.ptr(), p_data.size(), p_file, p_total, _should_compress_asset(p_path, p_data)); - - return OK; + return packager->add_file(dst_path, p_data.ptr(), p_data.size(), p_file, p_total, _should_compress_asset(p_path, p_data)); } public: @@ -1021,8 +998,10 @@ public: return "UWP"; } - virtual String get_binary_extension(const Ref<EditorExportPreset> &p_preset) const { - return "appx"; + virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const { + List<String> list; + list.push_back("appx"); + return list; } virtual Ref<Texture> get_logo() const { @@ -1033,13 +1012,13 @@ public: r_features->push_back("s3tc"); r_features->push_back("etc"); switch ((int)p_preset->get("architecture/target")) { - case EditorExportUWP::ARM: { + case EditorExportPlatformUWP::ARM: { r_features->push_back("arm"); } break; - case EditorExportUWP::X86: { + case EditorExportPlatformUWP::X86: { r_features->push_back("32"); } break; - case EditorExportUWP::X64: { + case EditorExportPlatformUWP::X64: { r_features->push_back("64"); } break; } @@ -1103,7 +1082,7 @@ public: uap++; } - const char **device = uwp_device_capabilites; + const char **device = uwp_device_capabilities; while (*device) { r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/" + String(*device).camelcase_to_underscore(false)), false)); device++; @@ -1121,18 +1100,18 @@ public: String platform_infix; switch (arch) { - case EditorExportUWP::ARM: { + case EditorExportPlatformUWP::ARM: { platform_infix = "arm"; } break; - case EditorExportUWP::X86: { + case EditorExportPlatformUWP::X86: { platform_infix = "x86"; } break; - case EditorExportUWP::X64: { + case EditorExportPlatformUWP::X64: { platform_infix = "x64"; } break; } - if (!exists_export_template("uwp_" + platform_infix + "_debug.zip", &err) || !exists_export_template("uwp_" + platform_infix + "_debug.zip", &err)) { + if (!exists_export_template("uwp_" + platform_infix + "_debug.zip", &err) || !exists_export_template("uwp_" + platform_infix + "_release.zip", &err)) { valid = false; r_missing_templates = true; } @@ -1149,12 +1128,12 @@ public: if (!FileAccess::exists(custom_debug_binary)) { dvalid = false; - err = "\nCustom debug binary not found."; + err += TTR("Custom debug template not found.") + "\n"; } if (!FileAccess::exists(custom_release_binary)) { rvalid = false; - err += "\nCustom release binary not found."; + err += TTR("Custom release template not found.") + "\n"; } if (dvalid || rvalid) @@ -1167,57 +1146,57 @@ public: if (!_valid_resource_name(p_preset->get("package/unique_name"))) { valid = false; - err += "\nInvalid unique name."; + err += TTR("Invalid package unique name.") + "\n"; } if (!_valid_guid(p_preset->get("identity/product_guid"))) { valid = false; - err += "\nInvalid product GUID."; + err += TTR("Invalid product GUID.") + "\n"; } if (!_valid_guid(p_preset->get("identity/publisher_guid"))) { valid = false; - err += "\nInvalid publisher GUID."; + err += TTR("Invalid publisher GUID.") + "\n"; } if (!_valid_bgcolor(p_preset->get("images/background_color"))) { valid = false; - err += "\nInvalid background color."; + err += TTR("Invalid background color.") + "\n"; } if (!p_preset->get("images/store_logo").is_zero() && !_valid_image((Object::cast_to<StreamTexture>((Object *)p_preset->get("images/store_logo"))), 50, 50)) { valid = false; - err += "\nInvalid Store Logo image dimensions (should be 50x50)."; + err += TTR("Invalid Store Logo image dimensions (should be 50x50).") + "\n"; } if (!p_preset->get("images/square44x44_logo").is_zero() && !_valid_image((Object::cast_to<StreamTexture>((Object *)p_preset->get("images/square44x44_logo"))), 44, 44)) { valid = false; - err += "\nInvalid square 44x44 logo image dimensions (should be 44x44)."; + err += TTR("Invalid square 44x44 logo image dimensions (should be 44x44).") + "\n"; } if (!p_preset->get("images/square71x71_logo").is_zero() && !_valid_image((Object::cast_to<StreamTexture>((Object *)p_preset->get("images/square71x71_logo"))), 71, 71)) { valid = false; - err += "\nInvalid square 71x71 logo image dimensions (should be 71x71)."; + err += TTR("Invalid square 71x71 logo image dimensions (should be 71x71).") + "\n"; } if (!p_preset->get("images/square150x150_logo").is_zero() && !_valid_image((Object::cast_to<StreamTexture>((Object *)p_preset->get("images/square150x150_logo"))), 150, 0)) { valid = false; - err += "\nInvalid square 150x150 logo image dimensions (should be 150x150)."; + err += TTR("Invalid square 150x150 logo image dimensions (should be 150x150).") + "\n"; } if (!p_preset->get("images/square310x310_logo").is_zero() && !_valid_image((Object::cast_to<StreamTexture>((Object *)p_preset->get("images/square310x310_logo"))), 310, 310)) { valid = false; - err += "\nInvalid square 310x310 logo image dimensions (should be 310x310)."; + err += TTR("Invalid square 310x310 logo image dimensions (should be 310x310).") + "\n"; } if (!p_preset->get("images/wide310x150_logo").is_zero() && !_valid_image((Object::cast_to<StreamTexture>((Object *)p_preset->get("images/wide310x150_logo"))), 310, 150)) { valid = false; - err += "\nInvalid wide 310x150 logo image dimensions (should be 310x150)."; + err += TTR("Invalid wide 310x150 logo image dimensions (should be 310x150).") + "\n"; } if (!p_preset->get("images/splash_screen").is_zero() && !_valid_image((Object::cast_to<StreamTexture>((Object *)p_preset->get("images/splash_screen"))), 620, 300)) { valid = false; - err += "\nInvalid splash screen image dimensions (should be 620x300)."; + err += TTR("Invalid splash screen image dimensions (should be 620x300).") + "\n"; } r_error = err; @@ -1228,7 +1207,7 @@ public: String src_appx; - EditorProgress ep("export", "Exporting for Windows Universal", 7); + EditorProgress ep("export", "Exporting for Windows Universal", 7, true); if (p_debug) src_appx = p_preset->get("custom_template/debug"); @@ -1263,10 +1242,14 @@ public: } } + if (!DirAccess::exists(p_path.get_base_dir())) { + return ERR_FILE_BAD_PATH; + } + Error err = OK; FileAccess *fa_pack = FileAccess::open(p_path, FileAccess::WRITE, &err); - ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE); + ERR_FAIL_COND_V_MSG(err != OK, ERR_CANT_CREATE, "Cannot create file '" + p_path + "'."); AppxPackager packager; packager.init(fa_pack); @@ -1274,7 +1257,9 @@ public: FileAccess *src_f = NULL; zlib_filefunc_def io = zipio_create_io_from_file(&src_f); - ep.step("Creating package...", 0); + if (ep.step("Creating package...", 0)) { + return ERR_SKIP; + } unzFile pkg = unzOpen2(src_appx.utf8().get_data(), &io); @@ -1286,7 +1271,9 @@ public: int ret = unzGoToFirstFile(pkg); - ep.step("Copying template files...", 1); + if (ep.step("Copying template files...", 1)) { + return ERR_SKIP; + } EditorNode::progress_add_task("template_files", "Template files", 100); packager.set_progress_task("template_files"); @@ -1335,14 +1322,19 @@ public: print_line("ADDING: " + path); - packager.add_file(path, data.ptr(), data.size(), template_file_no++, template_files_amount, _should_compress_asset(path, data)); + err = packager.add_file(path, data.ptr(), data.size(), template_file_no++, template_files_amount, _should_compress_asset(path, data)); + if (err != OK) { + return err; + } ret = unzGoToNextFile(pkg); } EditorNode::progress_end_task("template_files"); - ep.step("Creating command line...", 2); + if (ep.step("Creating command line...", 2)) { + return ERR_SKIP; + } Vector<String> cl = ((String)p_preset->get("command_line/extra_args")).strip_edges().split(" "); for (int i = 0; i < cl.size(); i++) { @@ -1376,9 +1368,14 @@ public: print_line(itos(i) + " param: " + cl[i]); } - packager.add_file("__cl__.cl", clf.ptr(), clf.size(), -1, -1, false); + err = packager.add_file("__cl__.cl", clf.ptr(), clf.size(), -1, -1, false); + if (err != OK) { + return err; + } - ep.step("Adding project files...", 3); + if (ep.step("Adding project files...", 3)) { + return ERR_SKIP; + } EditorNode::progress_add_task("project_files", "Project Files", 100); packager.set_progress_task("project_files"); @@ -1387,7 +1384,9 @@ public: EditorNode::progress_end_task("project_files"); - ep.step("Closing package...", 7); + if (ep.step("Closing package...", 7)) { + return ERR_SKIP; + } unzClose(pkg); @@ -1457,7 +1456,7 @@ public: virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, Set<String> &p_features) { } - EditorExportUWP() { + EditorExportPlatformUWP() { Ref<Image> img = memnew(Image(_uwp_logo)); logo.instance(); logo->create_from_image(img); @@ -1476,7 +1475,7 @@ void register_uwp_exporter() { EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "export/uwp/debug_algorithm", PROPERTY_HINT_ENUM, "MD5,SHA1,SHA256")); #endif // WINDOWS_ENABLED - Ref<EditorExportUWP> exporter; + Ref<EditorExportPlatformUWP> exporter; exporter.instance(); EditorExport::get_singleton()->add_export_platform(exporter); } |