From 9d08253661b9e48c535048ffcdb8153d7a9724cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Mon, 6 Oct 2025 11:33:02 +0300 Subject: [PATCH] [Windows] Fix application manifest in exported projects with modified resources. (cherry picked from commit 91fc0c3756d196c41980e73a38b8b11af67945ed) --- platform/windows/export/template_modifier.cpp | 62 +++++++++++++++++-- platform/windows/export/template_modifier.h | 11 +++- 2 files changed, 66 insertions(+), 7 deletions(-) diff --git a/platform/windows/export/template_modifier.cpp b/platform/windows/export/template_modifier.cpp index 15bd6f7243a..c55d42e9ab6 100644 --- a/platform/windows/export/template_modifier.cpp +++ b/platform/windows/export/template_modifier.cpp @@ -217,6 +217,11 @@ TemplateModifier::VersionInfo::VersionInfo() { value_length = 52; } +Vector TemplateModifier::ManifestInfo::save() const { + Vector bytes = manifest.to_utf8_buffer(); + return bytes; +} + Vector TemplateModifier::IconEntry::save() const { Vector bytes; ByteStream::save(width, bytes); @@ -347,10 +352,10 @@ uint32_t TemplateModifier::_snap(uint32_t p_value, uint32_t p_size) const { return p_value + (p_value % p_size ? p_size - (p_value % p_size) : 0); } -Vector TemplateModifier::_create_resources(uint32_t p_virtual_address, const GroupIcon &p_group_icon, const VersionInfo &p_version_info) const { +Vector TemplateModifier::_create_resources(uint32_t p_virtual_address, const GroupIcon &p_group_icon, const VersionInfo &p_version_info, const ManifestInfo &p_manifest_info) const { // 0x04, 0x00 as string length ICON in UTF16 and padding to 32 bits const uint8_t ICON_DIRECTORY_STRING[] = { 0x04, 0x00, 0x49, 0x00, 0x43, 0x00, 0x4f, 0x00, 0x4e, 0x00, 0x00, 0x00 }; - const uint16_t RT_ENTRY_COUNT = 3; + const uint16_t RT_ENTRY_COUNT = 4; const uint32_t icon_count = p_group_icon.images.size(); ResourceDirectoryTable root_directory_table; @@ -376,6 +381,12 @@ Vector TemplateModifier::_create_resources(uint32_t p_virtual_address, rt_version_entry.subdirectory = true; resources.append_array(rt_version_entry.save()); + ResourceDirectoryEntry rt_manifest_entry; + rt_manifest_entry.id = ResourceDirectoryEntry::MANIFEST; + rt_manifest_entry.data_offset = (6 + icon_count) * ResourceDirectoryTable::SIZE + (RT_ENTRY_COUNT + 2 * icon_count + 4) * ResourceDirectoryEntry::SIZE; + rt_manifest_entry.subdirectory = true; + resources.append_array(rt_manifest_entry.save()); + ResourceDirectoryTable icon_table; icon_table.id_entry_count = icon_count; resources.append_array(icon_table.save()); @@ -395,7 +406,7 @@ Vector TemplateModifier::_create_resources(uint32_t p_virtual_address, ResourceDirectoryEntry language_icon_entry; language_icon_entry.id = ResourceDirectoryEntry::ENGLISH; - language_icon_entry.data_offset = (6 + icon_count) * ResourceDirectoryTable::SIZE + (RT_ENTRY_COUNT + icon_count * 2 + 4) * ResourceDirectoryEntry::SIZE + sizeof(ICON_DIRECTORY_STRING) + i * ResourceDataEntry::SIZE; + language_icon_entry.data_offset = (8 + icon_count) * ResourceDirectoryTable::SIZE + (RT_ENTRY_COUNT + icon_count * 2 + 6) * ResourceDirectoryEntry::SIZE + sizeof(ICON_DIRECTORY_STRING) + i * ResourceDataEntry::SIZE; resources.append_array(language_icon_entry.save()); } @@ -416,7 +427,7 @@ Vector TemplateModifier::_create_resources(uint32_t p_virtual_address, ResourceDirectoryEntry group_icon_language_entry; group_icon_language_entry.id = ResourceDirectoryEntry::ENGLISH; - group_icon_language_entry.data_offset = (6 + icon_count) * ResourceDirectoryTable::SIZE + (RT_ENTRY_COUNT + 2 * icon_count + 4) * ResourceDirectoryEntry::SIZE + sizeof(ICON_DIRECTORY_STRING) + icon_count * ResourceDataEntry::SIZE; + group_icon_language_entry.data_offset = (8 + icon_count) * ResourceDirectoryTable::SIZE + (RT_ENTRY_COUNT + 2 * icon_count + 6) * ResourceDirectoryEntry::SIZE + sizeof(ICON_DIRECTORY_STRING) + icon_count * ResourceDataEntry::SIZE; resources.append_array(group_icon_language_entry.save()); ResourceDirectoryTable version_table; @@ -435,9 +446,28 @@ Vector TemplateModifier::_create_resources(uint32_t p_virtual_address, ResourceDirectoryEntry version_language_entry; version_language_entry.id = ResourceDirectoryEntry::ENGLISH; - version_language_entry.data_offset = (6 + icon_count) * ResourceDirectoryTable::SIZE + (RT_ENTRY_COUNT + 2 * icon_count + 4) * ResourceDirectoryEntry::SIZE + sizeof(ICON_DIRECTORY_STRING) + (icon_count + 1) * ResourceDataEntry::SIZE; + version_language_entry.data_offset = (8 + icon_count) * ResourceDirectoryTable::SIZE + (RT_ENTRY_COUNT + 2 * icon_count + 6) * ResourceDirectoryEntry::SIZE + sizeof(ICON_DIRECTORY_STRING) + (icon_count + 1) * ResourceDataEntry::SIZE; resources.append_array(version_language_entry.save()); + ResourceDirectoryTable manifest_table; + manifest_table.id_entry_count = 1; + resources.append_array(manifest_table.save()); + + ResourceDirectoryEntry manifest_entry; + manifest_entry.id = 1; + manifest_entry.data_offset = (7 + icon_count) * ResourceDirectoryTable::SIZE + (RT_ENTRY_COUNT + 2 * icon_count + 5) * ResourceDirectoryEntry::SIZE; + manifest_entry.subdirectory = true; + resources.append_array(manifest_entry.save()); + + ResourceDirectoryTable manifest_language_table; + manifest_language_table.id_entry_count = 1; + resources.append_array(manifest_language_table.save()); + + ResourceDirectoryEntry manifest_language_entry; + manifest_language_entry.id = ResourceDirectoryEntry::ENGLISH; + manifest_language_entry.data_offset = (8 + icon_count) * ResourceDirectoryTable::SIZE + (RT_ENTRY_COUNT + 2 * icon_count + 6) * ResourceDirectoryEntry::SIZE + sizeof(ICON_DIRECTORY_STRING) + (icon_count + 2) * ResourceDataEntry::SIZE; + resources.append_array(manifest_language_entry.save()); + Vector icon_directory_string; icon_directory_string.resize(sizeof(ICON_DIRECTORY_STRING)); memcpy(icon_directory_string.ptrw(), ICON_DIRECTORY_STRING, sizeof(ICON_DIRECTORY_STRING)); @@ -449,6 +479,7 @@ Vector TemplateModifier::_create_resources(uint32_t p_virtual_address, } data_entries.append(p_group_icon.save()); data_entries.append(p_version_info.save()); + data_entries.append(p_manifest_info.save()); uint32_t offset = resources.size() + data_entries.size() * ResourceDataEntry::SIZE; @@ -497,6 +528,24 @@ TemplateModifier::VersionInfo TemplateModifier::_create_version_info(const HashM return version_info; } +TemplateModifier::ManifestInfo TemplateModifier::_create_manifest_info() const { + ManifestInfo manifest_info; + manifest_info.manifest = R"MANIFEST( + + + + true + + + + + + + +)MANIFEST"; + return manifest_info; +} + TemplateModifier::GroupIcon TemplateModifier::_create_group_icon(const String &p_icon_path) const { GroupIcon group_icon; @@ -594,10 +643,11 @@ Error TemplateModifier::_modify_template(const Ref &p_preset GroupIcon group_icon = _create_group_icon(p_icon_path); VersionInfo version_info = _create_version_info(_get_strings(p_preset)); + ManifestInfo manifest_info = _create_manifest_info(); SectionEntry &resources_section_entry = section_entries.write[resource_index]; uint32_t old_resources_size_of_raw_data = resources_section_entry.size_of_raw_data; - Vector resources = _create_resources(resources_section_entry.virtual_address, group_icon, version_info); + Vector resources = _create_resources(resources_section_entry.virtual_address, group_icon, version_info, manifest_info); resources_section_entry.virtual_size = resources.size(); resources.resize_initialized(_snap(resources.size(), BLOCK_SIZE)); resources_section_entry.size_of_raw_data = resources.size(); diff --git a/platform/windows/export/template_modifier.h b/platform/windows/export/template_modifier.h index 351cef0d02b..5608b1c8a3a 100644 --- a/platform/windows/export/template_modifier.h +++ b/platform/windows/export/template_modifier.h @@ -65,6 +65,7 @@ class TemplateModifier { static const uint16_t SIZE = 8; static const uint32_t ICON = 0x03; static const uint32_t GROUP_ICON = 0x0e; + static const uint32_t MANIFEST = 0x18; static const uint32_t VERSION = 0x10; static const uint32_t ENGLISH = 0x0409; static const uint32_t HIGH_BIT = 0x80000000; @@ -153,6 +154,13 @@ class TemplateModifier { VersionInfo(); }; + struct ManifestInfo : Structure { + String manifest; + + Vector save() const; + ManifestInfo() {} + }; + struct IconEntry : ByteStream { static const uint32_t SIZE = 16; @@ -215,8 +223,9 @@ class TemplateModifier { uint32_t _get_pe_header_offset(Ref p_executable) const; Vector _get_section_entries(Ref p_executable) const; GroupIcon _create_group_icon(const String &p_icon_path) const; + ManifestInfo _create_manifest_info() const; VersionInfo _create_version_info(const HashMap &p_strings) const; - Vector _create_resources(uint32_t p_virtual_address, const GroupIcon &p_group_icon, const VersionInfo &p_version_info) const; + Vector _create_resources(uint32_t p_virtual_address, const GroupIcon &p_group_icon, const VersionInfo &p_version_info, const ManifestInfo &p_manifest_info) const; Error _truncate(const String &p_executable_path, uint32_t p_size) const; HashMap _get_strings(const Ref &p_preset) const; Error _modify_template(const Ref &p_preset, const String &p_template_path, const String &p_icon_path) const;