From c308bcb993d8d4bbbf48d707658b8ccc44d7f25d Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Thu, 4 May 2023 12:43:06 -0600 Subject: [PATCH 1/2] payloads: USe variable name for mounting --- resources/constants.py | 10 +++++++-- resources/reroute_payloads.py | 40 ++++++++++++++++++----------------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/resources/constants.py b/resources/constants.py index 23cec43fe..131b851fd 100644 --- a/resources/constants.py +++ b/resources/constants.py @@ -106,8 +106,9 @@ class Constants: self.kdkless_version: str = "1.0.0" # Get resource path - self.current_path: Path = Path(__file__).parent.parent.resolve() - self.payload_path: Path = self.current_path / Path("payloads") + self.current_path: Path = Path(__file__).parent.parent.resolve() + self.original_path: Path = Path(__file__).parent.parent.resolve() + self.payload_path: Path = self.current_path / Path("payloads") # Patcher Settings ## Internal settings @@ -225,6 +226,11 @@ class Constants: ] # Payload Location + + # Support Disk Images + @property + def payload_path_dmg(self): + return self.original_path / Path("payloads.dmg") # OpenCore @property def opencore_zip_source(self): diff --git a/resources/reroute_payloads.py b/resources/reroute_payloads.py index 9877e341f..760e359fb 100644 --- a/resources/reroute_payloads.py +++ b/resources/reroute_payloads.py @@ -36,7 +36,7 @@ class RoutePayloadDiskImage: self._unmount_active_dmgs(unmount_all_active=False) output = subprocess.run( [ - "hdiutil", "attach", "-noverify", f"{self.constants.payload_path}.dmg", + "hdiutil", "attach", "-noverify", f"{self.constants.payload_path_dmg}", "-mountpoint", Path(self.temp_dir.name / Path("payloads")), "-nobrowse", "-shadow", Path(self.temp_dir.name / Path("payloads_overlay")), @@ -55,7 +55,7 @@ class RoutePayloadDiskImage: logging.info(f"Return Code: {output.returncode}") - def _unmount_active_dmgs(self, unmount_all_active=True) -> None: + def _unmount_active_dmgs(self, unmount_all_active: bool = True) -> None: """ Unmounts disk images associated with OCLP @@ -70,20 +70,22 @@ class RoutePayloadDiskImage: dmg_info = subprocess.run(["hdiutil", "info", "-plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) dmg_info = plistlib.loads(dmg_info.stdout) - for image in dmg_info["images"]: - if image["image-path"].endswith("payloads.dmg"): - if unmount_all_active is False: - # Check that only our personal payloads.dmg is unmounted - if "shadow-path" in image: - if self.temp_dir.name in image["shadow-path"]: - logging.info("- Unmounting personal payloads.dmg") - subprocess.run( - ["hdiutil", "detach", image["system-entities"][0]["dev-entry"], "-force"], - stdout=subprocess.PIPE, stderr=subprocess.STDOUT - ) - else: - logging.info(f"- Unmounting payloads.dmg at: {image['system-entities'][0]['dev-entry']}") - subprocess.run( - ["hdiutil", "detach", image["system-entities"][0]["dev-entry"], "-force"], - stdout=subprocess.PIPE, stderr=subprocess.STDOUT - ) \ No newline at end of file + + for variant in ["Universal-Binaries.dmg", "payloads.dmg"]: + for image in dmg_info["images"]: + if image["image-path"].endswith(variant): + if unmount_all_active is False: + # Check that only our personal payloads.dmg is unmounted + if "shadow-path" in image: + if self.temp_dir.name in image["shadow-path"]: + logging.info(f"- Unmounting personal {variant}") + subprocess.run( + ["hdiutil", "detach", image["system-entities"][0]["dev-entry"], "-force"], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT + ) + else: + logging.info(f"- Unmounting {variant} at: {image['system-entities'][0]['dev-entry']}") + subprocess.run( + ["hdiutil", "detach", image["system-entities"][0]["dev-entry"], "-force"], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT + ) \ No newline at end of file From d21b984918ff212b769ced44cca356352df39536 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Thu, 4 May 2023 15:02:41 -0600 Subject: [PATCH 2/2] Implement DMG-based PatcherSupportPkg --- .gitignore | 1 + Build-Binary.command | 18 +++------- OpenCore-Patcher-GUI.spec | 2 +- resources/constants.py | 12 ++++--- resources/sys_patch/sys_patch.py | 32 +++++++++++------ resources/validation.py | 61 +++++++++++++++++--------------- 6 files changed, 68 insertions(+), 58 deletions(-) diff --git a/.gitignore b/.gitignore index acf45a709..cd8243a95 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ __pycache__/ /payloads/OpenCore-Legacy-Patcher-*.plist /payloads/KDK.dmg *.log +/Universal-Binaries.dmg diff --git a/Build-Binary.command b/Build-Binary.command index 8cc39219b..83721de0d 100755 --- a/Build-Binary.command +++ b/Build-Binary.command @@ -236,7 +236,6 @@ class CreateBinary: "launcher.sh", "OC-Patcher-TUI.icns", "OC-Patcher.icns", - "Universal-Binaries.zip", ] @@ -261,16 +260,16 @@ class CreateBinary: patcher_support_pkg_version = constants.Constants().patcher_support_pkg_version required_resources = [ - "Universal-Binaries.zip" + "Universal-Binaries.dmg" ] print("- Downloading required resources...") for resource in required_resources: - if Path(f"./payloads/{resource}").exists(): + if Path(f"./{resource}").exists(): if self.args.reset_binaries: print(f" - Removing old {resource}") rm_output = subprocess.run( - ["rm", "-rf", f"./payloads/{resource}"], + ["rm", "-rf", f"./{resource}"], stdout=subprocess.PIPE, stderr=subprocess.PIPE ) if rm_output.returncode != 0: @@ -298,13 +297,6 @@ class CreateBinary: print(f" - {resource} not found") raise Exception(f"{resource} not found") - print(" - Moving into payloads") - mv_output = subprocess.run(["mv", resource, "./payloads/"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - if mv_output.returncode != 0: - print(" - Move failed") - print(mv_output.stderr.decode('utf-8')) - raise Exception("Move failed") - def _generate_payloads_dmg(self): """ @@ -331,9 +323,9 @@ class CreateBinary: print(" - Generating DMG...") dmg_output = subprocess.run([ 'hdiutil', 'create', './payloads.dmg', - '-megabytes', '32000', + '-megabytes', '32000', # Overlays can only be as large as the disk image allows '-format', 'UDZO', '-ov', - '-volname', 'OpenCore Patcher Resources', + '-volname', 'OpenCore Patcher Resources (Base)', '-fs', 'HFS+', '-srcfolder', './payloads', '-passphrase', 'password', '-encryption' diff --git a/OpenCore-Patcher-GUI.spec b/OpenCore-Patcher-GUI.spec index 3db1fe908..a89ec2a1e 100644 --- a/OpenCore-Patcher-GUI.spec +++ b/OpenCore-Patcher-GUI.spec @@ -9,7 +9,7 @@ block_cipher = None a = Analysis(['OpenCore-Patcher-GUI.command'], pathex=[], binaries=[], - datas=[('payloads.dmg', '.')], + datas=[('payloads.dmg', '.'), ('Universal-Binaries.dmg', '.')], hiddenimports=[], hookspath=[], hooksconfig={}, diff --git a/resources/constants.py b/resources/constants.py index 131b851fd..642fbee5d 100644 --- a/resources/constants.py +++ b/resources/constants.py @@ -13,7 +13,7 @@ class Constants: def __init__(self) -> None: # Patcher Versioning self.patcher_version: str = "0.6.6" # OpenCore-Legacy-Patcher - self.patcher_support_pkg_version: str = "0.9.7" # PatcherSupportPkg + self.patcher_support_pkg_version: str = "1.0.0" # PatcherSupportPkg self.copyright_date: str = "Copyright © 2020-2023 Dortania" # URLs @@ -231,6 +231,12 @@ class Constants: @property def payload_path_dmg(self): return self.original_path / Path("payloads.dmg") + + @property + def payload_local_binaries_root_path_dmg(self): + return self.original_path / Path("Universal-Binaries.dmg") + + # OpenCore @property def opencore_zip_source(self): @@ -656,10 +662,6 @@ class Constants: def payload_local_binaries_root_path(self): return self.payload_path / Path("Universal-Binaries") - @property - def payload_local_binaries_root_path_zip(self): - return self.payload_path / Path("Universal-Binaries.zip") - @property def kdk_download_path(self): return self.payload_path / Path("KDK.dmg") diff --git a/resources/sys_patch/sys_patch.py b/resources/sys_patch/sys_patch.py index 769c167f4..4e04bf531 100644 --- a/resources/sys_patch/sys_patch.py +++ b/resources/sys_patch/sys_patch.py @@ -67,13 +67,6 @@ class PatchSysVolume: self.skip_root_kmutil_requirement = self.hardware_details["Settings: Supports Auxiliary Cache"] - def __del__(self) -> None: - """ - Ensures that each time we're patching, we're using a clean PatcherSupportPkg folder - """ - - if Path(self.constants.payload_local_binaries_root_path).exists(): - shutil.rmtree(self.constants.payload_local_binaries_root_path) def _init_pathing(self, custom_root_mount_path: Path = None, custom_data_mount_path: Path = None) -> None: """ @@ -854,10 +847,27 @@ class PatchSysVolume: logging.info("- Local PatcherSupportPkg resources available, continuing...") return True - if Path(self.constants.payload_local_binaries_root_path_zip).exists(): - logging.info("- Local PatcherSupportPkg resources available, unzipping...") - logging.info("- Unzipping binaries...") - utilities.process_status(subprocess.run(["ditto", "-V", "-x", "-k", "--sequesterRsrc", "--rsrc", self.constants.payload_local_binaries_root_path_zip, self.constants.payload_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + if Path(self.constants.payload_local_binaries_root_path_dmg).exists(): + logging.info("- Local PatcherSupportPkg resources available, mounting...") + + output = subprocess.run( + [ + "hdiutil", "attach", "-noverify", f"{self.constants.payload_local_binaries_root_path_dmg}", + "-mountpoint", Path(self.constants.payload_path / Path("Universal-Binaries")), + "-nobrowse", + "-shadow", Path(self.constants.payload_path / Path("Universal-Binaries_overlay")), + "-passphrase", "password" + ], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT + ) + + if output.returncode != 0: + logging.info("- Failed to mount Universal-Binaries.dmg") + logging.info(f"Output: {output.stdout.decode()}") + logging.info(f"Return Code: {output.returncode}") + return False + + logging.info("- Mounted Universal-Binaries.dmg") return True logging.info("- PatcherSupportPkg resources missing, Patcher likely corrupted!!!") diff --git a/resources/validation.py b/resources/validation.py index 7f5c729b9..9468682c4 100644 --- a/resources/validation.py +++ b/resources/validation.py @@ -133,35 +133,40 @@ class PatcherValidation: Validates sys_patch modules """ - if Path(self.constants.payload_local_binaries_root_path_zip).exists(): - logging.info("Validating Root Patch File integrity") - if not Path(self.constants.payload_local_binaries_root_path).exists(): - subprocess.run( - [ - "ditto", "-V", "-x", "-k", "--sequesterRsrc", "--rsrc", - self.constants.payload_local_binaries_root_path_zip, - self.constants.payload_path - ], - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT - ) - for supported_os in [os_data.os_data.big_sur, os_data.os_data.monterey, os_data.os_data.ventura]: - for i in range(0, 10): - self._validate_root_patch_files(supported_os, i) - logging.info("Validating SNB Board ID patcher") - self.constants.computer.reported_board_id = "Mac-7BA5B2DFE22DDD8C" - sys_patch_helpers.SysPatchHelpers(self.constants).snb_board_id_patch(self.constants.payload_local_binaries_root_path) - - # Clean up - subprocess.run( - [ - "rm", "-rf", self.constants.payload_local_binaries_root_path - ], - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT - ) - else: + if not Path(self.constants.payload_local_binaries_root_path_dmg).exists(): logging.info("- Skipping Root Patch File integrity validation") + return + + logging.info("Validating Root Patch File integrity") + output = subprocess.run( + [ + "hdiutil", "attach", "-noverify", f"{self.constants.payload_local_binaries_root_path_dmg}", + "-mountpoint", Path(self.constants.payload_path / Path("Universal-Binaries")), + "-nobrowse", + "-shadow", Path(self.constants.payload_path / Path("Universal-Binaries_overlay")), + "-passphrase", "password" + ], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT + ) + + if output.returncode != 0: + logging.info("- Failed to mount Universal-Binaries.dmg") + logging.info(f"Output: {output.stdout.decode()}") + logging.info(f"Return Code: {output.returncode}") + + print(self.constants.payload_local_binaries_root_path_dmg) + + raise Exception("Failed to mount Universal-Binaries.dmg") + + logging.info("- Mounted Universal-Binaries.dmg") + + + for supported_os in [os_data.os_data.big_sur, os_data.os_data.monterey, os_data.os_data.ventura]: + for i in range(0, 10): + self._validate_root_patch_files(supported_os, i) + logging.info("Validating SNB Board ID patcher") + self.constants.computer.reported_board_id = "Mac-7BA5B2DFE22DDD8C" + sys_patch_helpers.SysPatchHelpers(self.constants).snb_board_id_patch(self.constants.payload_local_binaries_root_path) def _validate_configs(self) -> None: