diff --git a/gui/gui_main.py b/gui/gui_main.py index f96591ec5..19a659a63 100644 --- a/gui/gui_main.py +++ b/gui/gui_main.py @@ -12,7 +12,7 @@ import wx.adv from wx.lib.agw import hyperlink import threading -from resources import constants, defaults, build, install, installer, utilities, sys_patch_detect, sys_patch, run, generate_smbios, updates +from resources import constants, defaults, build, install, installer, sys_patch_download, utilities, sys_patch_detect, sys_patch, run, generate_smbios, updates from data import model_array, os_data, smbios_data, sip_data from gui import menu_redirect @@ -103,8 +103,6 @@ class wx_python_gui: print("- Setting IgnoreAppUpdates to True") self.constants.ignore_updates = True subprocess.run(["defaults", "write", "com.dortania.opencore-legacy-patcher-wxpython", "IgnoreAppUpdates", "-bool", "TRUE"]) - else: - print("No updates available") else: self.constants.ignore_updates = True print("- Ignoring App Updates due to defaults") @@ -679,7 +677,7 @@ class wx_python_gui: self.subheader.Centre(wx.HORIZONTAL) patches = sys_patch_detect.detect_root_patch(self.computer.real_model, self.constants).detect_patch_set() - if not any(not patch.startswith("Settings") and patches[patch] is True for patch in patches): + if not any(not patch.startswith("Settings") and not patch.startswith("Validation") and patches[patch] is True for patch in patches): print("- No applicable patches available") patches = [] @@ -687,7 +685,7 @@ class wx_python_gui: if patches: for patch in patches: # Add Label for each patch - if (not patch.startswith("Settings") and patches[patch] is True): + if (not patch.startswith("Settings") and not patch.startswith("Validation") and patches[patch] is True): print(f"- Adding patch: {patch} - {patches[patch]}") self.patch_label = wx.StaticText(self.frame, label=f"- {patch}") self.patch_label.SetFont(wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)) @@ -698,6 +696,29 @@ class wx_python_gui: ) ) i = i + self.patch_label.GetSize().height + 3 + if patches["Validation: Patching Possible"] is False: + self.patch_label = wx.StaticText(self.frame, label="Cannot Patch due to following reasons:") + self.patch_label.SetFont(wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)) + self.patch_label.SetPosition( + wx.Point( + self.subheader.GetPosition().x, + self.subheader.GetPosition().y + self.subheader.GetSize().height + 3 + i + ) + ) + self.patch_label.Centre(wx.HORIZONTAL) + i = i + self.patch_label.GetSize().height + 3 + for patch in patches: + if patch.startswith("Validation") and patches[patch] is True: + print(f"- Adding check: {patch} - {patches[patch]}") + self.patch_label = wx.StaticText(self.frame, label=f"- {patch.lstrip('Validation: ')}") + self.patch_label.SetFont(wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)) + self.patch_label.SetPosition( + wx.Point( + self.subheader.GetPosition().x + 20, + self.subheader.GetPosition().y + self.subheader.GetSize().height + 3 + i + ) + ) + i = i + self.patch_label.GetSize().height + 3 else: # Prompt user with no patches found self.patch_label = wx.StaticText(self.frame, label="No patches found") @@ -718,12 +739,7 @@ class wx_python_gui: self.patch_label.GetPosition().y + self.patch_label.GetSize().height + 10 ) ) - uid = os.geteuid() - print(f"Effective UID: {uid}") - if uid == 0: - self.start_root_patching.Bind(wx.EVT_BUTTON, self.root_patch_start) - else: - self.start_root_patching.Bind(wx.EVT_BUTTON, self.relaunch_as_root) + self.start_root_patching.Centre(wx.HORIZONTAL) if not patches: self.start_root_patching.Disable() @@ -736,10 +752,7 @@ class wx_python_gui: self.start_root_patching.GetPosition().y + self.start_root_patching.GetSize().height + 3 ) ) - if uid == 0: - self.revert_root_patches.Bind(wx.EVT_BUTTON, self.root_patch_revert) - else: - self.revert_root_patches.Bind(wx.EVT_BUTTON, self.relaunch_as_root) + self.revert_root_patches.Centre(wx.HORIZONTAL) if self.constants.detected_os < os_data.os_data.big_sur: self.revert_root_patches.Disable() @@ -754,6 +767,19 @@ class wx_python_gui: self.return_to_main_menu.Bind(wx.EVT_BUTTON, self.main_menu) self.return_to_main_menu.Centre(wx.HORIZONTAL) + uid = os.geteuid() + if uid == 0: + self.start_root_patching.Bind(wx.EVT_BUTTON, self.root_patch_start) + self.revert_root_patches.Bind(wx.EVT_BUTTON, self.root_patch_revert) + else: + self.start_root_patching.Bind(wx.EVT_BUTTON, self.relaunch_as_root) + self.revert_root_patches.Bind(wx.EVT_BUTTON, self.relaunch_as_root) + + if patches: + if patches["Validation: Patching Possible"] is False: + self.start_root_patching.Disable() + self.revert_root_patches.Disable() + self.frame.SetSize(-1, self.return_to_main_menu.GetPosition().y + self.return_to_main_menu.GetSize().height + 40) def root_patch_start(self, event=None): @@ -767,7 +793,7 @@ class wx_python_gui: self.header.Centre(wx.HORIZONTAL) # Subheader - self.subheader = wx.StaticText(self.frame, label="Starting root volume patching") + self.subheader = wx.StaticText(self.frame, label="Preparing PatcherSupportPkg binaries") self.subheader.SetFont(wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)) self.subheader.SetPosition( wx.Point( @@ -786,6 +812,17 @@ class wx_python_gui: ) ) self.developer_note.Centre(wx.HORIZONTAL) + self.frame.SetSize(-1, self.developer_note.GetPosition().y + self.developer_note.GetSize().height + 80) + + # Download resources + sys.stdout=menu_redirect.RedirectLabel(self.developer_note) + sys_patch_download.grab_patcher_support_pkg(self.constants).download_files() + sys.stdout=sys.__stdout__ + + self.subheader.SetLabel("Starting root volume patching") + self.developer_note.SetLabel("Starting shortly") + self.subheader.Centre(wx.HORIZONTAL) + self.developer_note.Centre(wx.HORIZONTAL) # Text Box self.text_box = wx.TextCtrl(self.frame, style=wx.TE_MULTILINE | wx.TE_READONLY) diff --git a/resources/sys_patch.py b/resources/sys_patch.py index 74a950886..e0d43d4ec 100644 --- a/resources/sys_patch.py +++ b/resources/sys_patch.py @@ -12,8 +12,8 @@ import zipfile from pathlib import Path import sys -from resources import constants, device_probe, utilities, generate_smbios -from data import sip_data, sys_patch_data, model_array, os_data, smbios_data, cpu_data, dylib_data +from resources import constants, device_probe, utilities, generate_smbios, sys_patch_download +from data import sip_data, sys_patch_data, model_array, os_data, smbios_data, cpu_data class PatchSysVolume: @@ -639,7 +639,7 @@ set million colour before rebooting""" def check_files(self): if Path(self.constants.payload_apple_root_path).exists(): - print("- Found Apple Binaries") + print("- Found local Apple Binaries") if self.constants.gui_mode is False: patch_input = input("Would you like to redownload?(y/n): ") if patch_input in {"y", "Y", "yes", "Yes"}: @@ -648,38 +648,14 @@ set million colour before rebooting""" else: self.download_files() else: - print("- Apple binaries missing") self.download_files() def download_files(self): - if self.constants.detected_os == os_data.os_data.monterey: - os_ver = "12-Monterey" - elif self.constants.detected_os == os_data.os_data.big_sur: - os_ver = "11-Big-Sur" - elif self.constants.detected_os == os_data.os_data.catalina: - os_ver = "10.15-Catalina" - elif self.constants.detected_os == os_data.os_data.mojave: - os_ver = "10.14-Mojave" + if self.constants.gui_mode is False: + download_result, os_ver, link = sys_patch_download.grab_patcher_support_pkg(self.constants).download_files() else: - raise Exception(f"Unsupported OS: {self.constants.detected_os}") - link = f"{self.constants.url_patcher_support_pkg}{self.constants.patcher_support_pkg_version}/{os_ver}.zip" - - if Path(self.constants.payload_apple_root_path).exists(): - print("- Removing old Apple Binaries folder") - Path(self.constants.payload_apple_root_path).unlink() - if Path(self.constants.payload_apple_root_path_zip).exists(): - print("- Removing old Apple Binaries zip") - Path(self.constants.payload_apple_root_path_zip).unlink() - - download_result = None - local_zip = Path(self.constants.payload_path) / f"{os_ver}.zip" - if Path(local_zip).exists(): - print(f"- Found local {os_ver} zip, skipping download") - print(f"- Duplicating into Apple.zip") - shutil.copy(local_zip, self.constants.payload_apple_root_path_zip) download_result = True - else: - download_result = utilities.download_file(link, self.constants.payload_apple_root_path_zip) + os_ver, link = sys_patch_download.grab_patcher_support_pkg(self.constants).generate_pkg_link() if download_result and self.constants.payload_apple_root_path_zip.exists(): print("- Download completed") @@ -691,15 +667,17 @@ set million colour before rebooting""" Path(self.constants.payload_apple_root_path_zip).unlink() print("- Binaries downloaded to:") print(self.constants.payload_path) - # if self.constants.gui_mode is False: - # input("Press [ENTER] to continue") + return self.constants.payload_apple_root_path except zipfile.BadZipFile: print("- Couldn't unzip") - return + return None else: print("- Download failed, please verify the below link works:") print(link) - input("Press [ENTER] to continue") + if download_result is None and self.constants.gui_mode is False: + print("\nIf you continue to have issues, try using the Offline builds") + print("located on Github next to the other builds") + input("Press enter to exit") def detect_gpus(self): gpus = self.constants.computer.gpus diff --git a/resources/sys_patch_detect.py b/resources/sys_patch_detect.py index ede406305..9a8d8d854 100644 --- a/resources/sys_patch_detect.py +++ b/resources/sys_patch_detect.py @@ -1,5 +1,5 @@ -from resources import constants, device_probe, utilities -from data import model_array, os_data, smbios_data, cpu_data +from resources import constants, device_probe, utilities, generate_smbios +from data import model_array, os_data, smbios_data, cpu_data, sip_data class detect_root_patch: def __init__(self, model, versions): @@ -28,6 +28,14 @@ class detect_root_patch: self.check_board_id= False self.supports_metal= False + # Validation Checks + self.sip_enabled = False + self.sbm_enabled = False + self.amfi_enabled = False + self.fv_enabled = False + self.dosdude_patched = False + self.bad_board_id = False + def detect_gpus(self): gpus = self.constants.computer.gpus @@ -154,6 +162,7 @@ class detect_root_patch: "Graphics: Intel Ironlake": self.iron_gpu, "Graphics: Intel Sandy Bridge": self.sandy_gpu, "Graphics: Intel Ivy Bridge": self.ivy_gpu, + # "Graphics: Intel Ivy Bridge": True, "Brightness: Legacy Backlight Control": self.brightness_legacy, "Audio: Legacy Realtek": self.legacy_audio, "Networking: Legacy Wireless": self.legacy_wifi, @@ -161,6 +170,27 @@ class detect_root_patch: "Miscellaneous: Legacy Keyboard Backlight": self.legacy_keyboard_backlight, "Settings: Requires AMFI exemption": self.amfi_must_disable, "Settings: Requires Board ID validation": self.check_board_id, + "Validation: Patching Possible": self.verify_patch_allowed(), + "Validation: SIP is enabled": self.sip_enabled, + "Validation: SBM is enabled": self.sbm_enabled, + "Validation: AMFI is enabled": self.amfi_enabled, + "Validation: FileVault is enabled": self.fv_enabled, + "Validation: System is dosdude1 patched": self.dosdude_patched, + "Validation: Board ID is unsupported": self.bad_board_id, } - return self.root_patch_dict \ No newline at end of file + return self.root_patch_dict + + def verify_patch_allowed(self): + sip = sip_data.system_integrity_protection.root_patch_sip_big_sur if self.constants.detected_os > os_data.os_data.catalina else sip_data.system_integrity_protection.root_patch_sip_mojave + self.sip_enabled, self.sbm_enabled, self.amfi_enabled, self.fv_enabled, self.dosdude_patched = utilities.patching_status(sip, self.constants.detected_os) + + if self.check_board_id is True and (self.computer.reported_board_id not in self.constants.sandy_board_id and self.computer.reported_board_id not in self.constants.sandy_board_id_stock): + self.bad_board_id = True + + if any( + [self.sip_enabled, self.sbm_enabled, self.fv_enabled, self.dosdude_patched, self.amfi_enabled if self.amfi_must_disable else False, self.bad_board_id if self.check_board_id else False] + ): + return False + else: + return True \ No newline at end of file diff --git a/resources/sys_patch_download.py b/resources/sys_patch_download.py new file mode 100644 index 000000000..114cd3d73 --- /dev/null +++ b/resources/sys_patch_download.py @@ -0,0 +1,48 @@ +# Download PatcherSupportPkg for usage with Root Patching +# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk + +from data import os_data +from resources import utilities +from pathlib import Path +import shutil + +class grab_patcher_support_pkg: + + def __init__(self, constants): + self.constants = constants + + def generate_pkg_link(self): + if self.constants.detected_os == os_data.os_data.monterey: + os_ver = "12-Monterey" + elif self.constants.detected_os == os_data.os_data.big_sur: + os_ver = "11-Big-Sur" + elif self.constants.detected_os == os_data.os_data.catalina: + os_ver = "10.15-Catalina" + elif self.constants.detected_os == os_data.os_data.mojave: + os_ver = "10.14-Mojave" + else: + raise Exception(f"Unsupported OS: {self.constants.detected_os}") + link = f"{self.constants.url_patcher_support_pkg}{self.constants.patcher_support_pkg_version}/{os_ver}.zip" + return os_ver, link + + def download_files(self): + os_ver, link = self.generate_pkg_link() + if Path(self.constants.payload_apple_root_path).exists(): + print("- Removing old Apple Binaries folder") + # Delete folder + shutil.rmtree(self.constants.payload_apple_root_path) + if Path(self.constants.payload_apple_root_path_zip).exists(): + print("- Removing old Apple Binaries zip") + Path(self.constants.payload_apple_root_path_zip).unlink() + + download_result = None + local_zip = Path(self.constants.payload_path) / f"{os_ver}.zip" + if Path(local_zip).exists(): + print(f"- Found local {os_ver} zip, skipping download") + print(f"- Duplicating into Apple.zip") + shutil.copy(local_zip, self.constants.payload_apple_root_path_zip) + download_result = True + else: + download_result = utilities.download_file(link, self.constants.payload_apple_root_path_zip) + + return download_result, os_ver, link \ No newline at end of file diff --git a/resources/updates.py b/resources/updates.py index 62f3c18f8..cbf74f5f9 100644 --- a/resources/updates.py +++ b/resources/updates.py @@ -61,20 +61,20 @@ class check_binary_updates: return False def check_binary_updates(self): - print("- Checking for updates...") + # print("- Checking for updates...") if self.verify_network_connection(self.binary_url): - print("- Network connection functional") + # print("- Network connection functional") response = requests.get(self.binary_url) data_set = response.json() - print("- Retrived latest version data") + # print("- Retrived latest version data") self.remote_version = data_set["tag_name"] - print(f"- Latest version: {self.remote_version}") + # print(f"- Latest version: {self.remote_version}") self.remote_version_array = self.remote_version.split(".") self.remote_version_array = [ int(x) for x in self.remote_version_array ] if self.check_if_build_newer() is True: - print("- Remote version is newer") + # print("- Remote version is newer") for asset in data_set["assets"]: print(f"- Found asset: {asset['name']}") if self.determine_remote_type( @@ -82,7 +82,7 @@ class check_binary_updates: ) and self.determine_remote_offline_type( asset["name"] ) == self.determine_local_build_type_offline(): - print(f"- Found matching asset: {asset['name']}") + # print(f"- Found matching asset: {asset['name']}") self.available_binaries.update({ asset['name']: { "Name": @@ -104,8 +104,8 @@ class check_binary_updates: if self.available_binaries: return self.available_binaries else: - print("- No matching binaries available") + # print("- No matching binaries available") return None - else: - print("- Failed to connect to GitHub API") + # else: + # print("- Failed to connect to GitHub API") return None \ No newline at end of file