diff --git a/core/relinker/main.cpp b/core/relinker/main.cpp index dfbbc5d77..824d8d656 100644 --- a/core/relinker/main.cpp +++ b/core/relinker/main.cpp @@ -131,18 +131,13 @@ int Run(const int argc, char* argv[]) { if (args.windowsDiagnostics) checkOutputInputs(std::filesystem::absolute("windows-diagnostics-imports.txt"), "Windows import diagnostics"); + std::vector registryPaths; if (args.writeRegistry) { const std::filesystem::path outFsPath = Io::NativePath(absPath); - std::vector registryPaths{ - outFsPath.parent_path() / Io::NativePath(Io::Utf8Path(outFsPath.stem()) + ".registry.json") - }; + registryPaths.push_back(outFsPath.parent_path() / Io::NativePath(Io::Utf8Path(outFsPath.stem()) + ".registry.json")); for (const auto& artifact : guestArtifacts) registryPaths.push_back(outFsPath.parent_path() / Io::NativePath(Io::Utf8Path(outFsPath.stem()) + "." + Io::Utf8Path(artifact.Path.filename()) + ".registry.json")); for (const auto& path : registryPaths) checkOutputInputs(path, "Registry"); - const auto registryWriter = std::make_shared(); - fileWriter.Write(Io::Utf8Path(registryPaths.front()), registryWriter->WriteCallRegistry(result.RegistryEntries)); - for (std::size_t index = 0; index < guestArtifacts.size(); ++index) - fileWriter.Write(Io::Utf8Path(registryPaths[index + 1]), registryWriter->WriteModuleImports(guestArtifacts[index].Imports)); } auto byteWriter = std::make_shared(); @@ -177,6 +172,12 @@ int Run(const int argc, char* argv[]) { std::cout << "Guest module: " << Io::Utf8Path(artifact.Path) << '\n'; } fileWriter.Write(absPath, executableBytes); + if (args.writeRegistry) { + const auto registryWriter = std::make_shared(); + fileWriter.Write(Io::Utf8Path(registryPaths.front()), registryWriter->WriteCallRegistry(result.RegistryEntries)); + for (std::size_t index = 0; index < guestArtifacts.size(); ++index) + fileWriter.Write(Io::Utf8Path(registryPaths[index + 1]), registryWriter->WriteModuleImports(guestArtifacts[index].Imports)); + } if (desktopEntry) std::cout << "Desktop entry: " << Io::Utf8Path(desktopEntryWriter.Write(*desktopEntry)) << '\n'; std::cout << "External prx references: " << result.RegistryEntries.size() << "\nOutput file: " << absPath << '\n'; std::cout << "Expected runtime layout (relative to the output executable):\n" diff --git a/core/relinker/relinker/tests/test_input_preservation.py b/core/relinker/relinker/tests/test_input_preservation.py index 7863f55a7..3ec4114b3 100644 --- a/core/relinker/relinker/tests/test_input_preservation.py +++ b/core/relinker/relinker/tests/test_input_preservation.py @@ -119,6 +119,29 @@ def check_registry_inputs(relinker, work, windows): assert not (case / "app0").exists() +def check_registry_after_failed_patch(relinker, work): + case = work / "registry-failed-patch" + (case / "sce_module").mkdir(parents=True) + (case / "sce_module" / "sample.prx").write_bytes(guest_fixture(PLAIN_SITE)) + (case / "sce_sys").mkdir() + (case / "sce_sys" / "icon0.png").write_bytes(b"\x89PNG\r\n\x1a\n" + bytes(40)) + source = case / "input.elf" + source.write_bytes(main_fixture()) + output = case / "output.exe" + previous_output = b"previous executable" + output.write_bytes(previous_output) + registries = [case / "output.registry.json", case / "output.sample.prx.guest.prx.registry.json"] + previous_registry = b"previous registry" + for registry in registries: + registry.write_bytes(previous_registry) + result = subprocess.run([str(relinker), "--windows", "--registry", str(source), str(output)], + capture_output=True, text=True, timeout=20) + assert result.returncode == 2 and "Invalid Windows icon PNG" in result.stderr, (result.stdout, result.stderr) + assert output.read_bytes() == previous_output + assert all(registry.read_bytes() == previous_registry for registry in registries) + assert not (case / "app0").exists() + + def check_desktop_inputs(relinker, work): for desktop in (False, True): for bundled in (False, True): @@ -180,6 +203,7 @@ def main(): work = Path(directory) check_diagnostic_inputs(relinker, work) check_desktop_inputs(relinker, work) + check_registry_after_failed_patch(relinker, work) for windows in (False, True): options = ["--windows"] if windows else [] check_registry_inputs(relinker, work, windows)