Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit 230bb60

Browse files
committed
[[ Deploy ]] Handle payload and project out of order on windows
This patch allows deploy to handle installer standalones that have the payload and project sections out of order. Previously it was assumed that the last three sections of the installer were `.payload`, `.project` and `.rsrc`. This patch allows for the section order to also be `.project`, `.payload`, `.rsrc`, however, it is still assumed that they are the last three sections and `.rsrc` is the last section.
1 parent c1c059a commit 230bb60

1 file changed

Lines changed: 99 additions & 41 deletions

File tree

engine/src/deploy_windows.cpp

Lines changed: 99 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1681,34 +1681,69 @@ Exec_stat MCDeployToWindows(const MCDeployParameters& p_params)
16811681

16821682
IMAGE_SECTION_HEADER *t_payload_section, *t_project_section, *t_resource_section;
16831683
t_payload_section = t_project_section = t_resource_section = nil;
1684+
1685+
16841686
uint32_t t_section_count;
1685-
if (t_success)
1687+
1688+
uint32_t t_output_offset = 0;
1689+
uint32_t t_base_address = 0;
1690+
1691+
bool t_swap_payload = false;
1692+
if (t_success)
16861693
{
16871694
t_section_count = t_nt_header . FileHeader . NumberOfSections;
1688-
if (!MCStringIsEmpty(p_params . payload))
1689-
t_payload_section = &t_section_headers[t_section_count - 3];
1690-
else
1691-
t_payload_section = nil;
1692-
1693-
if (!t_icons_only)
1694-
t_project_section = &t_section_headers[t_section_count - 2];
16951695

1696-
t_resource_section = &t_section_headers[t_section_count - 1];
1697-
}
1698-
1696+
IMAGE_SECTION_HEADER *t_temp_section;
1697+
for (uint32_t t_index = 0; t_index < t_section_count; t_index++)
1698+
{
1699+
t_temp_section = &t_section_headers[t_index];
1700+
1701+
if (memcmp(t_temp_section -> Name, ".payload", 8) == 0)
1702+
{
1703+
t_payload_section = t_temp_section;
1704+
if (t_output_offset == 0)
1705+
{
1706+
t_output_offset = t_temp_section -> PointerToRawData;
1707+
t_base_address = t_temp_section -> VirtualAddress;
1708+
}
1709+
else
1710+
{
1711+
// payload is should be third last
1712+
t_swap_payload = true;
1713+
}
1714+
}
1715+
else if (memcmp(t_temp_section -> Name, ".project", 8) == 0)
1716+
{
1717+
t_project_section = t_temp_section;
1718+
if (t_output_offset == 0)
1719+
{
1720+
t_output_offset = t_temp_section -> PointerToRawData;
1721+
t_base_address = t_temp_section -> VirtualAddress;
1722+
}
1723+
}
1724+
else if (memcmp(t_temp_section -> Name, ".rsrc", 5) == 0)
1725+
{
1726+
t_resource_section = t_temp_section;
1727+
if (t_output_offset == 0)
1728+
{
1729+
t_output_offset = t_temp_section -> PointerToRawData;
1730+
t_base_address = t_temp_section -> VirtualAddress;
1731+
}
1732+
}
1733+
}
1734+
}
1735+
16991736
// Next we check that there are at least two sections, and they are the
17001737
// right ones.
1701-
if (t_success &&
1702-
((MCStringIsEmpty(p_params . payload) && t_section_count < 2) ||
1703-
(!MCStringIsEmpty(p_params . payload) && t_section_count < 3)))
1738+
if (t_success && t_section_count < 2)
17041739
t_success = MCDeployThrow(kMCDeployErrorWindowsMissingSections);
1705-
if (t_success && memcmp(t_resource_section -> Name, ".rsrc", 6) != 0)
1740+
if (t_success && t_resource_section == nil)
17061741
t_success = MCDeployThrow(kMCDeployErrorWindowsNoResourceSection);
1707-
if (t_success && !t_icons_only && memcmp(t_project_section -> Name, ".project", 8) != 0)
1742+
if (t_success && !t_icons_only && t_project_section == nil)
17081743
t_success = MCDeployThrow(kMCDeployErrorWindowsNoProjectSection);
1709-
if (t_success && t_payload_section != nil && memcmp(t_payload_section -> Name, ".payload", 8) != 0)
1744+
if (t_success && !MCStringIsEmpty(p_params . payload) && t_payload_section == nil)
17101745
t_success = MCDeployThrow(kMCDeployErrorWindowsNoPayloadSection);
1711-
1746+
17121747
// Read in the resources
17131748
MCWindowsResources t_resources;
17141749
MCWindowsResourcesInitialize(t_resources);
@@ -1755,35 +1790,49 @@ Exec_stat MCDeployToWindows(const MCDeployParameters& p_params)
17551790

17561791
// Write out everything up to the beginning of the payload (if present) else
17571792
// the project section.
1758-
uint32_t t_output_offset;
1759-
t_output_offset = 0;
17601793
if (t_success)
17611794
{
1762-
if (t_icons_only)
1763-
t_output_offset = t_resource_section -> PointerToRawData;
1764-
else if (t_payload_section == nil)
1765-
t_output_offset = t_project_section -> PointerToRawData;
1766-
else
1767-
t_output_offset = t_payload_section -> PointerToRawData;
1768-
17691795
t_success = MCDeployFileCopy(t_output, 0, t_engine, 0, t_output_offset);
17701796
}
1771-
1772-
// Write out the payload capsule struct (if needed)
1773-
uint32_t t_payload_size;
1774-
t_payload_size = 0;
1775-
if (t_success && t_payload_section != nil)
1797+
1798+
uint32_t t_base_offset = t_output_offset;
1799+
1800+
// Write out the payload capsule struct (if needed)
1801+
uint32_t t_payload_size = 0;
1802+
if (t_success && t_payload_section != nil)
17761803
{
1777-
t_success = MCDeployWritePayload(p_params, false, t_output, t_output_offset, t_payload_size);
1778-
if (t_success)
1779-
t_output_offset += (t_payload_size + 4095) & ~4095;
1780-
}
1804+
if (!MCStringIsEmpty(p_params . payload))
1805+
{
1806+
t_success = MCDeployWritePayload(p_params, false, t_output, t_output_offset, t_payload_size);
1807+
if (t_success)
1808+
t_output_offset += (t_payload_size + 4095) & ~4095;
1809+
}
1810+
else
1811+
{
1812+
t_success = MCDeployFileCopy(t_output, t_output_offset, t_engine, t_payload_section -> PointerToRawData, t_payload_section -> SizeOfRawData);
1813+
if (t_success)
1814+
{
1815+
t_payload_size = t_payload_section -> SizeOfRawData;
1816+
t_output_offset += (t_payload_section -> SizeOfRawData + 4095) & ~4095;
1817+
}
1818+
}
1819+
}
17811820

17821821
// Write out the project capsule struct
17831822
uint32_t t_project_size;
17841823
t_project_size = 0;
1785-
if (t_success && !t_icons_only)
1786-
t_success = MCDeployWriteProject(p_params, false, t_output, t_output_offset, t_project_size);
1824+
if (t_success && t_project_section != nil)
1825+
{
1826+
if (!t_icons_only)
1827+
{
1828+
t_success = MCDeployWriteProject(p_params, false, t_output, t_output_offset, t_project_size);
1829+
}
1830+
else
1831+
{
1832+
t_project_size = t_project_section -> SizeOfRawData;
1833+
t_success = MCDeployFileCopy(t_output, t_output_offset, t_engine, t_project_section -> PointerToRawData, t_project_size);
1834+
}
1835+
}
17871836

17881837
// Next use the project size to compute the updated header values we need.
17891838
uint32_t t_optional_header_size, t_optional_header_offset, t_section_headers_offset;
@@ -1813,11 +1862,13 @@ Exec_stat MCDeployToWindows(const MCDeployParameters& p_params)
18131862
{
18141863
t_payload_section -> SizeOfRawData = t_payload_section_size;
18151864
t_payload_section -> Misc . VirtualSize = t_payload_section_size;
1865+
t_payload_section -> PointerToRawData = t_base_offset;
1866+
t_payload_section -> VirtualAddress = t_base_address;
18161867

18171868
t_project_section -> VirtualAddress = t_payload_section -> VirtualAddress + t_payload_section_size;
18181869
t_project_section -> PointerToRawData = t_payload_section -> PointerToRawData + t_payload_section_size;
18191870
}
1820-
1871+
18211872
// Resize and shift up the project section (if present)
18221873
if (t_project_section != nil)
18231874
{
@@ -1836,11 +1887,18 @@ Exec_stat MCDeployToWindows(const MCDeployParameters& p_params)
18361887

18371888
t_resource_section_offset = t_resource_section -> PointerToRawData;
18381889
t_resource_section_address = t_resource_section -> VirtualAddress;
1890+
1891+
if (t_swap_payload)
1892+
{
1893+
IMAGE_SECTION_HEADER t_swap_header = *t_payload_section;
1894+
t_section_headers[t_section_count - 2] = *t_project_section;
1895+
t_section_headers[t_section_count - 3] = t_swap_header;
1896+
}
18391897

18401898
// Update the resource data directory entry and the size of image/initialized data
18411899
t_nt_header . OptionalHeader . SizeOfImage = t_resource_section_address + t_resource_section_size;
1842-
1843-
t_nt_header . OptionalHeader . SizeOfInitializedData = 0;
1900+
1901+
t_nt_header . OptionalHeader . SizeOfInitializedData = 0;
18441902
for(uint32_t i = 0; i < t_section_count; i++)
18451903
if (t_section_headers[i] . Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
18461904
t_nt_header . OptionalHeader . SizeOfInitializedData += MCU_max((unsigned)t_section_headers[i] . SizeOfRawData, (unsigned)(t_section_headers[i] . Misc . VirtualSize + 4095) & ~4095);

0 commit comments

Comments
 (0)