From 4e1254c31e3560ee63758dc96704db6324175318 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Mon, 2 May 2022 13:19:36 -0600 Subject: [PATCH 01/14] Initial Commit --- data/sys_patch_data.py | 287 --------------- data/sys_patch_dict.py | 305 ++++++++++++++++ gui/gui_main.py | 2 +- resources/constants.py | 163 +-------- resources/generate_smbios.py | 59 ++- resources/sys_patch.py | 623 ++++++++++---------------------- resources/sys_patch_detect.py | 45 ++- resources/sys_patch_download.py | 30 +- 8 files changed, 608 insertions(+), 906 deletions(-) delete mode 100644 data/sys_patch_data.py create mode 100644 data/sys_patch_dict.py diff --git a/data/sys_patch_data.py b/data/sys_patch_data.py deleted file mode 100644 index eb234852a..000000000 --- a/data/sys_patch_data.py +++ /dev/null @@ -1,287 +0,0 @@ -# Lists Root patches used by sys_patch.py -# Copyright (C) 2020-2021, Dhinak G, Mykola Grymalyuk -DeleteNvidiaAccel11 = [ - "AMDRadeonX4000.kext", - "AMDRadeonX4000HWServices.kext", - "AMDRadeonX5000.kext", - "AMDRadeonX5000HWServices.kext", - "AMDRadeonX6000.kext", - "AMDRadeonX6000Framebuffer.kext", - "AMDRadeonX6000HWServices.kext", - "AppleIntelBDWGraphics.kext", - "AppleIntelBDWGraphicsFramebuffer.kext", - "AppleIntelCFLGraphicsFramebuffer.kext", - "AppleIntelHD4000Graphics.kext", - "AppleIntelHD5000Graphics.kext", - "AppleIntelICLGraphics.kext", - "AppleIntelICLLPGraphicsFramebuffer.kext", - "AppleIntelKBLGraphics.kext", - "AppleIntelKBLGraphicsFramebuffer.kext", - "AppleIntelSKLGraphics.kext", - "AppleIntelSKLGraphicsFramebuffer.kext", - "AppleIntelFramebufferAzul.kext", - "AppleIntelFramebufferCapri.kext", - "AppleParavirtGPU.kext", - "GeForce.kext", - "IOAcceleratorFamily2.kext", - "IOGPUFamily.kext", -] - -DeleteAMDAccel11 = [ - "AMDRadeonX4000.kext", - "AMDRadeonX4000HWServices.kext", - "AMDRadeonX5000.kext", - "AMDRadeonX5000HWServices.kext", - "AMDRadeonX6000.kext", - "AMDRadeonX6000Framebuffer.kext", - "AMDRadeonX6000HWServices.kext", - "AMD7000Controller.kext", # AMDSupport Dependency - "AMD8000Controller.kext", # AMDSupport Dependency - "AMD9000Controller.kext", # AMDSupport Dependency - "AMD9500Controller.kext", # AMDSupport Dependency - "AMD10000Controller.kext", # AMDSupport Dependency - "AppleIntelBDWGraphics.kext", - "AppleIntelBDWGraphicsFramebuffer.kext", - "AppleIntelCFLGraphicsFramebuffer.kext", - "AppleIntelHD4000Graphics.kext", - "AppleIntelHD5000Graphics.kext", - "AppleIntelICLGraphics.kext", - "AppleIntelICLLPGraphicsFramebuffer.kext", - "AppleIntelKBLGraphics.kext", - "AppleIntelKBLGraphicsFramebuffer.kext", - "AppleIntelSKLGraphics.kext", - "AppleIntelSKLGraphicsFramebuffer.kext", - "AppleIntelFramebufferAzul.kext", - "AppleIntelFramebufferCapri.kext", - "AppleParavirtGPU.kext", - "GeForce.kext", - "IOGPUFamily.kext", -] - -DeleteAMDAccel11TS2 = [ - "AppleCameraInterface.kext", -] - -AddNvidiaAccel11 = [ - "GeForceGA.bundle", - "GeForceTesla.kext", - "GeForceTeslaGLDriver.bundle", - "GeForceTeslaVADriver.bundle", - "NVDANV50HalTesla.kext", - "NVDAResmanTesla.kext", - "IOSurface.kext", -] - -AddNvidiaBrightness = [ - "GeForceGA.bundle", - "GeForceTesla.kext", - "GeForceTeslaGLDriver.bundle", - "GeForceTeslaVADriver.bundle", - "NVDANV50HalTesla.kext", - "NVDAResmanTesla.kext", -] - -AddNvidiaKeplerAccel11 = [ - "GeForce.kext", - "GeForceAIRPlugin.bundle", - "GeForceGLDriver.bundle", - "GeForceMTLDriver.bundle", - "GeForceVADriver.bundle", - "NVDAGF100Hal.kext", - "NVDAGK100Hal.kext", - "NVDAResman.kext", - "NVDAStartup.kext", -] - -AddNvidiaTeslaAccel12 = [ - "NVDAStartup.kext", -] - -AddAMDAccel11 = [ - "AMD2400Controller.kext", - "AMD2600Controller.kext", - "AMD3800Controller.kext", - "AMD4600Controller.kext", - "AMD4800Controller.kext", - "AMD5000Controller.kext", - "AMD6000Controller.kext", - "AMDFramebuffer.kext", - "AMDLegacyFramebuffer.kext", - "AMDLegacySupport.kext", - "AMDRadeonVADriver.bundle", - "AMDRadeonVADriver2.bundle", - "AMDRadeonX3000.kext", - "AMDRadeonX3000GLDriver.bundle", - "AMDShared.bundle", - "AMDSupport.kext", - "ATIRadeonX2000.kext", - "ATIRadeonX2000GA.plugin", - "ATIRadeonX2000GLDriver.bundle", - "ATIRadeonX2000VADriver.bundle", -] - -AddAMDBrightness = [ - "AMD2400Controller.kext", - "AMD2600Controller.kext", - "AMD3800Controller.kext", - "AMD4600Controller.kext", - "AMD4800Controller.kext", - "AMD5000Controller.kext", - "AMD6000Controller.kext", - "AMDLegacyFramebuffer.kext", - "AMDLegacySupport.kext", - "AMDRadeonVADriver.bundle", - "AMDRadeonVADriver2.bundle", - # "AMDRadeonX3000.kext", - # "AMDRadeonX3000GLDriver.bundle", - "AMDShared.bundle", - "ATIRadeonX2000.kext", - "ATIRadeonX2000GA.plugin", - "ATIRadeonX2000GLDriver.bundle", - "ATIRadeonX2000VADriver.bundle", -] - -AddAMDAccel11TS2 = [ - "IOSurface.kext", - "IOAcceleratorFamily2.kext", -] - -AddIntelGen1Accel = [ - "AppleIntelHDGraphics.kext", - "AppleIntelHDGraphicsFB.kext", - "AppleIntelHDGraphicsGA.plugin", - "AppleIntelHDGraphicsGLDriver.bundle", - "AppleIntelHDGraphicsVADriver.bundle", -] - -AddIntelGen2Accel = [ - "AppleIntelHD3000Graphics.kext", - "AppleIntelHD3000GraphicsGA.plugin", - "AppleIntelHD3000GraphicsGLDriver.bundle", - "AppleIntelHD3000GraphicsVADriver.bundle", - # "AppleIntelSNBGraphicsFB.kext", - "AppleIntelSNBVA.bundle", -] - -AddIntelGen2AccelStock = [ - "AppleIntelSNBGraphicsFB-Clean.kext", -] - -AddIntelGen2AccelPatched = [ - "AppleIntelSNBGraphicsFB.kext", -] - -AddIntelGen3Accel = [ - "AppleIntelFramebufferCapri.kext", - "AppleIntelHD4000Graphics.kext", - "AppleIntelHD4000GraphicsGLDriver.bundle", - "AppleIntelHD4000GraphicsMTLDriver.bundle", - "AppleIntelHD4000GraphicsVADriver.bundle", - "AppleIntelIVBVA.bundle", - "AppleIntelGraphicsShared.bundle", -] - -AddGeneralAccel = ["IOAcceleratorFamily2.kext", "IOSurface.kext"] - -DeleteBrightness = ["AppleGraphicsControl.kext/Contents/PlugIns/AGDCBacklightControl.kext"] - -DeleteDemux = [ - "AppleGraphicsControl.kext/Contents/PlugIns/AGDCBacklightControl.kext", - "AppleGraphicsControl.kext/Contents/PlugIns/AppleMuxControl.kext", - "AppleBacklight.kext", -] - -AddDemux = [ - "AppleMuxControl.kext", -] - -AddBrightness = [ - "AppleBacklight.kext", - "AppleBacklightExpert.kext", -] - -AddVolumeControl = [ - "AppleHDA.kext", - "IOAudioFamily.kext", -] - -AddVolumeControlv2 = [ - "AppleHDA.kext", -] - -DeleteVolumeControl = [ - "AppleVirtIO.kext", - "AppleVirtualGraphics.kext", - "AppleVirtualPlatform.kext", - "ApplePVPanic.kext", - "AppleVirtIOStorage.kext", -] - -AddNvidiaAccelLegacy = [ - # "GeForceGA.bundle", - "GeForceTesla.kext", - "GeForceTeslaGLDriver.bundle", - "GeForceTeslaVADriver.bundle", - "NVDANV50HalTesla.kext", - "NVDAResmanTesla.kext", -] - -AddAMDAccelLegacy = [ - "AMD2400Controller.kext", - "AMD2600Controller.kext", - "AMD3800Controller.kext", - "AMD4600Controller.kext", - "AMD4800Controller.kext", - "AMD5000Controller.kext", - "AMD6000Controller.kext", - "AMDFramebuffer.kext", - "AMDLegacyFramebuffer.kext", - "AMDLegacySupport.kext", - "AMDRadeonVADriver.bundle", - "AMDRadeonVADriver2.bundle", - "AMDRadeonX3000.kext", - "AMDRadeonX3000GLDriver.bundle", - "AMDRadeonX4000HWServices.kext", - "AMDRadeonX4000.kext", - "AMDRadeonX4000GLDriver.bundle", - "AMDShared.bundle", - "AMDSupport.kext", - "ATIRadeonX2000.kext", - "ATIRadeonX2000GA.plugin", - "ATIRadeonX2000GLDriver.bundle", - "ATIRadeonX2000VADriver.bundle", -] - -AddGeneralAccelCatalina = [ - "AppleGraphicsControl.kext", - "AppleGraphicsPowerManagement.kext", - "AppleMCCSControl.kext", - "IOGraphicsFamily.kext", - "IONDRVSupport.kext", - "IOSurface.kext", -] - -AddGeneralAccelMojave = [ - "IONDRVSupport.kext", - "AppleGraphicsControl.kext", - "AppleGraphicsPowerManagement.kext", - "AppleMCCSControl.kext", - "IOAccelerator2D.plugin", - "IOAcceleratorFamily2.kext", - "IOGraphicsFamily.kext", -] - -BackupLocations = [ - "System/Library/Extensions", - "System/Library/Frameworks/CoreDisplay.framework", - "System/Library/Frameworks/IOSurface.framework", - "System/Library/Frameworks/OpenGL.framework", - "System/Library/Frameworks/WebKit.framework", - "System/Library/LaunchDaemons", - "System/Library/PrivateFrameworks/DisplayServices.framework", - "System/Library/PrivateFrameworks/GPUSupport.framework", - "System/Library/PrivateFrameworks/SkyLight.framework", - "System/Library/PrivateFrameworks/IOAccelerator.framework", - "System/Library/PrivateFrameworks/AppleGVA.framework", - "System/Library/PrivateFrameworks/AppleGVACore.framework", -] diff --git a/data/sys_patch_dict.py b/data/sys_patch_dict.py new file mode 100644 index 000000000..352a9bc6c --- /dev/null +++ b/data/sys_patch_dict.py @@ -0,0 +1,305 @@ +from data import os_data + +def SystemPatchDictionary(os): + sys_patch_dict = { + "Graphics": { + "Non-Metal Common": { + "Install": { + "/System/Library/Extensions": { + "IOSurface.kext": "10.15.7", + }, + "/System/Library/Frameworks": { + "OpenGL.framework": "10.14.3", + "CoreDisplay.framework": f"10.14.4-{os}", + "IOSurface.framework": f"10.15.7-{os}", + "QuartzCore.framework": f"10.15.7-{os}", + }, + "/System/Library/PrivateFrameworks": { + "GPUSupport.framework": "10.14.3", + "SkyLight.framework": f"10.14.6-{os}", + }, + }, + "Remove": { + "/System/Library/Extensions": [ + "AMDRadeonX4000.kext", + "AMDRadeonX4000HWServices.kext", + "AMDRadeonX5000.kext", + "AMDRadeonX5000HWServices.kext", + "AMDRadeonX6000.kext", + "AMDRadeonX6000Framebuffer.kext", + "AMDRadeonX6000HWServices.kext", + "AppleIntelBDWGraphics.kext", + "AppleIntelBDWGraphicsFramebuffer.kext", + "AppleIntelCFLGraphicsFramebuffer.kext", + "AppleIntelHD4000Graphics.kext", + "AppleIntelHD5000Graphics.kext", + "AppleIntelICLGraphics.kext", + "AppleIntelICLLPGraphicsFramebuffer.kext", + "AppleIntelKBLGraphics.kext", + "AppleIntelKBLGraphicsFramebuffer.kext", + "AppleIntelSKLGraphics.kext", + "AppleIntelSKLGraphicsFramebuffer.kext", + "AppleIntelFramebufferAzul.kext", + "AppleIntelFramebufferCapri.kext", + "AppleParavirtGPU.kext", + "GeForce.kext", + "IOAcceleratorFamily2.kext", + "IOGPUFamily.kext", + ], + }, + "Install Non-Root": { + "/Library/Application Support/SkyLightPlugins": { + **({ "DropboxHack.dylib": "SkyLightPlugins" } if os >= os_data.os_data.monterey else {}), + **({ "DropboxHack.txt": "SkyLightPlugins" } if os >= os_data.os_data.monterey else {}), + }, + }, + }, + "Metal Common": { + "Install": { + "/System/Library/Frameworks": { + "OpenCL.framework": "11.6", + "WebKit.framework": "11.6", + }, + "/System/Library/PrivateFrameworks": { + "AppleGVA.framework": "10.15.7", + "AppleGVACore.framework": "10.15.7", + }, + }, + }, + + "Legacy GVA": { + "Install": { + "/System/Library/PrivateFrameworks": { + "AppleGVA.framework": "10.13.6", + "AppleGVACore.framework": "10.15.7", + }, + }, + }, + + "Nvidia Tesla": { + "Install": { + "/System/Library/Extensions": { + "GeForceGA.bundle": "10.13.6", + "GeForceTesla.kext": "10.13.6", + "GeForceTeslaGLDriver.bundle": "10.13.6", + "GeForceTeslaVADriver.bundle": "10.13.6", + "NVDANV50HalTesla.kext": "10.13.6", + "NVDAResmanTesla.kext": "10.13.6", + **({ "NVDAStartup.kext": "12.0 Beta 6" } if os >= os_data.os_data.monterey else {}) + }, + }, + }, + "Nvidia Kepler": { + "Install": { + "/System/Library/Extensions": { + "GeForceAIRPlugin.bundle": "11.0 Beta 3", + "GeForceGLDriver.bundle": "11.0 Beta 3", + "GeForceMTLDriver.bundle": "11.0 Beta 3", + "GeForce.kext": "12.0 Beta 6", + "GeForceVADriver.bundle": "12.0 Beta 6", + "NVDAGF100Hal.kext": "12.0 Beta 6", + "NVDAGK100Hal.kext": "12.0 Beta 6", + "NVDAResman.kext": "12.0 Beta 6", + "NVDAStartup.kext": "12.0 Beta 6", + }, + }, + }, + "AMD TeraScale 1": { + "Install": { + "/System/Library/Extensions": { + "AMD2400Controller.kext": "10.13.6", + "AMD2600Controller.kext": "10.13.6", + "AMD3800Controller.kext": "10.13.6", + "AMD4600Controller.kext": "10.13.6", + "AMD4800Controller.kext": "10.13.6", + "AMDFramebuffer.kext": "10.13.6", + "AMDLegacyFramebuffer.kext": "10.13.6", + "AMDLegacySupport.kext": "10.13.6", + "AMDShared.bundle": "10.13.6", + "AMDSupport.kext": "10.13.6", + "ATIRadeonX2000.kext": "10.13.6", + "ATIRadeonX2000GA.plugin": "10.13.6", + "ATIRadeonX2000GLDriver.bundle": "10.13.6", + "ATIRadeonX2000VADriver.bundle": "10.13.6", + }, + }, + "Remove": { + "/System/Library/Extensions": [ + "AMD7000Controller.kext", + "AMD8000Controller.kext", + "AMD9000Controller.kext", + "AMD9500Controller.kext", + "AMD10000Controller.kext", + ], + }, + }, + "AMD TeraScale 2": { + "Processes": { + "defaults write com.apple.cmio CMIO_Unit_Input_ASC.DoNotUseOpenCL -bool true": False, + }, + "Install": { + "/System/Library/Extensions": { + "AMD5000Controller.kext": "10.13.6", + "AMD6000Controller.kext": "10.13.6", + "AMDFramebuffer.kext": "10.13.6", + "AMDLegacyFramebuffer.kext": "10.13.6", + "AMDLegacySupport.kext": "10.13.6", + "AMDRadeonVADriver.bundle": "10.13.6", + "AMDRadeonVADriver2.bundle": "10.13.6", + "AMDRadeonX3000.kext": "10.13.6", + "AMDRadeonX3000GLDriver.bundle": "10.13.6", + "AMDShared.bundle": "10.13.6", + "AMDSupport.kext": "10.13.6", + "IOAcceleratorFamily2.kext": "10.13.6", + "IOSurface.kext": "10.14.6", + }, + "/System/Library/Frameworks": { + "OpenCL.framework": "10.13.6", + "IOSurface.framework": f"10.14.6-{os}", + }, + "/System/Library/PrivateFrameworks": { + "GPUSupport.framework": "10.13.6", + "IOAccelerator.framework": f"10.13.6-{os}", + }, + }, + "Remove": { + "/System/Library/Extensions": { + "AppleCameraInterface.kext", # Specific to IOAccelerator downgrade + "AMD7000Controller.kext", + "AMD8000Controller.kext", + "AMD9000Controller.kext", + "AMD9500Controller.kext", + "AMD10000Controller.kext", + }, + }, + }, + "Intel Ironlake": { + "Install": { + "/System/Library/Extensions": { + "AppleIntelHDGraphics.kext": "10.13.6", + "AppleIntelHDGraphicsFB.kext": "10.13.6", + "AppleIntelHDGraphicsGA.plugin": "10.13.6", + "AppleIntelHDGraphicsGLDriver.bundle": "10.13.6", + "AppleIntelHDGraphicsVADriver.bundle": "10.13.6", + }, + }, + }, + "Intel Sandy Bridge": { + "Install": { + "/System/Library/Extensions": { + "AppleIntelHD3000Graphics.kext": "10.13.6", + "AppleIntelHD3000GraphicsGA.plugin": "10.13.6", + "AppleIntelHD3000GraphicsGLDriver.bundle": "10.13.6", + "AppleIntelHD3000GraphicsVADriver.bundle": "10.13.6", + "AppleIntelSNBGraphicsFB.kext": "10.13.6", # Add check for Board ID patched kext + "AppleIntelSNBVA.bundle": "10.13.6", + }, + }, + }, + "Intel Ivy Bridge": { + "Processes": { + "defaults write com.apple.coremedia hardwareVideoDecoder -string enable": False, + }, + "Install": { + "/System/Library/Extensions": { + "AppleIntelHD4000GraphicsGLDriver.bundle": "11.0 Beta 6", + "AppleIntelHD4000GraphicsMTLDriver.bundle": "11.0 Beta 6", + "AppleIntelHD4000GraphicsVADriver.bundle": "11.3 Beta 1", + "AppleIntelFramebufferCapri.kext": "11.4", + "AppleIntelHD4000Graphics.kext": "11.4", + "AppleIntelIVBVA.bundle": "11.4", + "AppleIntelGraphicsShared.bundle": "11.4", # libIGIL-Metal.dylib pulled from 11.0 Beta 6 + }, + }, + }, + }, + "Audio": { + "Legacy Realtek": { + # For iMac7,1 and iMac8,1 units with legacy Realtek HD Audio + "Install": { + "/System/Library/Extensions": { + "AppleHDA.kext": "10.11.6", + "IOAudioFamily.kext": "10.11.6", + }, + }, + "Remove": { + "/System/Library/Extensions": [ + "AppleVirtIO.kext", + "AppleVirtualGraphics.kext", + "AppleVirtualPlatform.kext", + "ApplePVPanic.kext", + "AppleVirtIOStorage.kext", + ], + }, + }, + # For Mac Pros with non-UGA/GOP GPUs + "Legacy Non-GOP": { + "Install": { + "/System/Library/Extensions": { + "AppleHDA.kext": "10.13.6", + }, + }, + }, + }, + "Networking": { + "Legacy WiFi": { + "Install": { + "/usr/libexec": { + "airportd": "11.5.2", + }, + "/System/Library/CoreServices": { + "WiFiAgent.app": "11.5.2", + }, + }, + "Install Non-Root": { + "/Library/Application Support/SkyLightPlugins": { + **({ "CoreWLAN.dylib": "SkyLightPlugins" } if os >= os_data.os_data.monterey else {}), + **({ "CoreWLAN.txt": "SkyLightPlugins" } if os >= os_data.os_data.monterey else {}), + }, + }, + }, + }, + "Brightness": { + "Legacy Brightness": { + "Install": { + "/System/Library/Extensions": { + "AppleBacklight.kext": "10.12.6", + "AppleBacklightExpert.kext": "10.12.6", + }, + "/System/Library/PrivateFrameworks": { + "DisplayServices.framework": "10.12.6", + }, + }, + "Remove": { + "/System/Library/Extensions/AppleGraphicsControl.kext/Contents/PlugIns": [ + "AGDCBacklightControl.kext", + ], + }, + }, + }, + "Miscellaneous": { + "Legacy GMUX": { + "Install": { + "/System/Library/Extensions/AppleGraphicsControl.kext/Contents/PlugIns": { + "AppleMuxControl.kext": "10.12.6", + }, + }, + "Remove": { + "/System/Library/Extensions": [ + "AppleBacklight.kext", + ], + "/System/Library/Extensions/AppleGraphicsControl.kext/Contents/PlugIns": [ + "AGDCBacklightControl.kext", + "AppleMuxControl.kext", + ], + }, + }, + "Legacy Keyboard Backlight": { + "Processes": { + "defaults write /Library/Preferences/.GlobalPreferences.plist Moraea_BacklightHack -bool true": True, + }, + }, + }, + } + + return sys_patch_dict \ No newline at end of file diff --git a/gui/gui_main.py b/gui/gui_main.py index c2790e01b..6ac81056f 100644 --- a/gui/gui_main.py +++ b/gui/gui_main.py @@ -899,7 +899,7 @@ class wx_python_gui: # Download resources sys.stdout=menu_redirect.RedirectLabel(self.developer_note) - download_result, os_ver, extensions_link, framework_link = sys_patch_download.grab_patcher_support_pkg(self.constants).download_files() + download_result, os_ver, link = sys_patch_download.grab_patcher_support_pkg(self.constants).download_files() sys.stdout=sys.__stdout__ if download_result is None: diff --git a/resources/constants.py b/resources/constants.py index 80f71b765..1b7e2e515 100644 --- a/resources/constants.py +++ b/resources/constants.py @@ -15,7 +15,7 @@ class Constants: def __init__(self): # Patcher Versioning self.patcher_version = "0.4.5" # OpenCore-Legacy-Patcher - self.patcher_support_pkg_version = "0.3.9" # PatcherSupportPkg + self.patcher_support_pkg_version = "0.4.0" # PatcherSupportPkg self.url_patcher_support_pkg = "https://github.com/dortania/PatcherSupportPkg/releases/download/" self.nightly_url_patcher_support_pkg = "https://nightly.link/dortania/PatcherSupportPkg/workflows/build/master/" self.discord_link = "https://discord.gg/rqdPgH8xSN" @@ -571,167 +571,14 @@ class Constants: return self.payload_path / Path("AutoPkg-Assets.pkg.zip") # Apple Payloads Paths - @property - def payload_apple_root_path_zip(self): - return self.payload_path / Path("Apple.zip") + def payload_local_binaries_root_path(self): + return self.payload_path / Path("Universal-Binaries") @property - def payload_universal_extensions_zip_path(self): - return self.payload_path / Path("Universal-Extensions.zip") + def payload_local_binaries_root_path_zip(self): + return self.payload_path / Path("Universal-Binaries.zip") - @property - def payload_apple_root_path(self): - return self.payload_path / Path("Apple") - - @property - def payload_apple_kexts_path(self): - return self.payload_path / Path("Universal-Extensions") - - @property - def payload_apple_coreservices_path(self): - return self.payload_apple_root_path / Path("CoreServices") - - @property - def payload_apple_usr_path(self): - return self.payload_apple_root_path / Path("usr") - - @property - def payload_apple_libexec_path(self): - return self.payload_apple_usr_path / Path("libexec") - - @property - def payload_apple_application_support(self): - return self.payload_apple_root_path / Path("Application Support") - - @property - def payload_apple_private_path(self): - return self.payload_apple_root_path / Path("private") - - @property - def payload_apple_etc_path(self): - return self.payload_apple_private_path / Path("etc") - - @property - def payload_apple_frameworks_path(self): - return self.payload_apple_root_path / Path("Frameworks") - - @property - def payload_apple_frameworks_path_accel(self): - return self.payload_apple_frameworks_path / Path("Graphics-Acceleration-Non-Metal") - - @property - def payload_apple_frameworks_path_accel_ts2(self): - return self.payload_apple_frameworks_path / Path("Graphics-Acceleration-TeraScale-2") - - @property - def payload_apple_frameworks_path_accel_ivy(self): - return self.payload_apple_frameworks_path / Path("Graphics-Acceleration-Ivy-Bridge") - - @property - def payload_apple_frameworks_path_accel_kepler(self): - return self.payload_apple_frameworks_path / Path("Graphics-Acceleration-Kepler") - - @property - def payload_apple_lauchd_path(self): - return self.payload_apple_root_path / Path("LaunchDaemons") - - @property - def payload_apple_private_frameworks_path(self): - return self.payload_apple_root_path / Path("PrivateFrameworks") - - @property - def payload_apple_private_frameworks_path_accel(self): - return self.payload_apple_private_frameworks_path / Path("Graphics-Acceleration-Non-Metal") - - @property - def payload_apple_private_frameworks_path_accel_ts2(self): - return self.payload_apple_private_frameworks_path / Path("Graphics-Acceleration-TeraScale-2") - - @property - def payload_apple_private_frameworks_path_accel_ivy(self): - return self.payload_apple_private_frameworks_path / Path("Graphics-Acceleration-Ivy-Bridge") - - @property - def payload_apple_private_frameworks_path_brightness(self): - return self.payload_apple_private_frameworks_path / Path("Brightness-Control") - - @property - def payload_apple_private_frameworks_path_legacy_drm(self): - return self.payload_apple_private_frameworks_path / Path("Legacy-GVA") - - # Apple Extensions - # El Capitan Extensions - @property - def audio_path(self): - return self.payload_apple_kexts_path / Path("Audio") - - # High Sierra Extensions - @property - def audio_v2_path(self): - return self.payload_apple_kexts_path / Path("Audio-v2") - - # GPU Kexts and Bundles - - @property - def legacy_graphics(self): - return self.payload_apple_kexts_path / Path("Graphics-Acceleration") - - @property - def legacy_nvidia_path(self): - return self.legacy_graphics / Path("Nvidia-Tesla") - - @property - def legacy_nvidia_kepler_path(self): - return self.legacy_graphics / Path("Nvidia-Kepler") - - @property - def legacy_amd_path(self): - return self.legacy_graphics / Path("AMD-TeraScale") - - @property - def legacy_amd_path_ts2(self): - return self.legacy_graphics / Path("AMD-TeraScale-2") - - @property - def legacy_intel_gen1_path(self): - return self.legacy_graphics / Path("Intel-Gen5-Ironlake") - - @property - def legacy_intel_gen2_path(self): - return self.legacy_graphics / Path("Intel-Gen6-SandyBridge") - - @property - def legacy_intel_gen3_path(self): - return self.legacy_graphics / Path("Intel-Gen7-IvyBridge") - - @property - def legacy_general_path(self): - return self.legacy_graphics / Path("General-Patches") - - @property - def legacy_brightness(self): - return self.payload_apple_kexts_path / Path("Brightness-Control") - - @property - def legacy_mux_path(self): - return self.payload_apple_kexts_path / Path("Legacy-Mux") - - @property - def legacy_wifi_coreservices(self): - return self.payload_apple_coreservices_path / Path("Legacy-Wifi") - - @property - def legacy_wifi_libexec(self): - return self.payload_apple_libexec_path / Path("Legacy-Wifi") - - @property - def legacy_wifi_support(self): - return self.payload_apple_application_support / Path("Legacy-Wifi") - - @property - def legacy_dropbox_support(self): - return self.payload_apple_application_support / Path("Dropbox") sbm_values = [ "j137ap", # iMacPro1,1 diff --git a/resources/generate_smbios.py b/resources/generate_smbios.py index 188bd67a5..5377ebb7b 100644 --- a/resources/generate_smbios.py +++ b/resources/generate_smbios.py @@ -105,6 +105,13 @@ def find_model_off_board(board): return key return None +def find_board_off_model(model): + if model in smbios_data.smbios_dictionary: + return smbios_data.smbios_dictionary[model]["Board ID"] + else: + return None + + def check_firewire(model): # MacBooks never supported FireWire # Pre-Thunderbolt MacBook Airs as well @@ -116,4 +123,54 @@ def check_firewire(model): elif model.startswith("MacBook"): return False else: - return True \ No newline at end of file + return True + +def determine_best_board_id_for_sandy(current_board_id, gpus): + # This function is mainly for users who are either spoofing or using hackintoshes + # Generally hackintosh will use whatever the latest SMBIOS is, so we need to determine + # the best Board ID to patch inside of AppleIntelSNBGraphicsFB + + # Currently the kext supports the following models: + # MacBookPro8,1 - Mac-94245B3640C91C81 (13") + # MacBookPro8,2 - Mac-94245A3940C91C80 (15") + # MacBookPro8,3 - Mac-942459F5819B171B (17") + # MacBookAir4,1 - Mac-C08A6BB70A942AC2 (11") + # MacBookAir4,2 - Mac-742912EFDBEE19B3 (13") + # Macmini5,1 - Mac-8ED6AF5B48C039E1 + # Macmini5,2 - Mac-4BC72D62AD45599E (headless) + # Macmini5,3 - Mac-7BA5B2794B2CDB12 + # iMac12,1 - Mac-942B5BF58194151B (headless) + # iMac12,2 - Mac-942B59F58194171B (headless) + # Unknown(MBP) - Mac-94245AF5819B141B + # Unknown(iMac) - Mac-942B5B3A40C91381 (headless) + if current_board_id: + model = find_model_off_board(current_board_id) + if model: + if model.startswith("MacBook"): + try: + size = int(smbios_data.smbios_dictionary[model]["Screen Size"]) + except KeyError: + size = 13 # Assume 13 if it's missing + if model.startswith("MacBookPro"): + if size >= 17: + return find_board_off_model("MacBookPro8,3") + elif size >= 15: + return find_board_off_model("MacBookPro8,2") + else: + return find_board_off_model("MacBookPro8,1") + else: # MacBook and MacBookAir + if size >= 13: + return find_board_off_model("MacBookAir4,2") + else: + return find_board_off_model("MacBookAir4,1") + else: + # We're working with a desktop, so need to figure out whether the unit is running headless or not + if len(gpus) > 1: + # More than 1 GPU detected, assume headless + if model.startswith("Macmini"): + return find_board_off_model("Macmini5,2") + else: + return find_board_off_model("iMac12,2") + else: + return find_board_off_model("Macmini5,1") + return find_board_off_model("Macmini5,1") # Safest bet if we somehow don't know the model \ No newline at end of file diff --git a/resources/sys_patch.py b/resources/sys_patch.py index c3e95ff09..e8d86559f 100644 --- a/resources/sys_patch.py +++ b/resources/sys_patch.py @@ -11,8 +11,8 @@ import subprocess import zipfile from pathlib import Path -from resources import constants, utilities, generate_smbios, sys_patch_download, sys_patch_detect -from data import sip_data, sys_patch_data, os_data +from resources import constants, generate_smbios, utilities, sys_patch_download, sys_patch_detect +from data import os_data, sys_patch_dict class PatchSysVolume: @@ -26,7 +26,7 @@ class PatchSysVolume: self.root_supports_snapshot = utilities.check_if_root_is_apfs_snapshot() self.constants.root_patcher_succeded = False # Reset Variable each time we start - # GUI will detect hardware patches betfore starting PatchSysVolume() + # GUI will detect hardware patches before starting PatchSysVolume() # However the TUI will not, so allow for data to be passed in manually avoiding multiple calls if hardware_details is None: hardware_details = sys_patch_detect.detect_root_patch(self.computer.real_model, self.constants).detect_patch_set() @@ -68,14 +68,7 @@ class PatchSysVolume: else: self.mount_location = "" self.mount_location_data = "" - self.mount_coreservices = f"{self.mount_location}/System/Library/CoreServices" self.mount_extensions = f"{self.mount_location}/System/Library/Extensions" - self.mount_frameworks = f"{self.mount_location}/System/Library/Frameworks" - self.mount_lauchd = f"{self.mount_location}/System/Library/LaunchDaemons" - self.mount_private_frameworks = f"{self.mount_location}/System/Library/PrivateFrameworks" - self.mount_libexec = f"{self.mount_location}/usr/libexec" - self.mount_extensions_mux = f"{self.mount_location}/System/Library/Extensions/AppleGraphicsControl.kext/Contents/PlugIns/" - self.mount_private_etc = f"{self.mount_location_data}/private/etc" self.mount_application_support = f"{self.mount_location_data}/Library/Application Support" def find_mount_root_vol(self, patch): @@ -147,6 +140,7 @@ class PatchSysVolume: # - Check the output for 'KernelCache ID' to see if the cache was successfully rebuilt # kmutil notes: # - will return 71 on failure to build KCs + # - will return 31 on 'No binaries or codeless kexts were provided' # - will return -10 if the volume is missing (ie. unmounted by another process) if result.returncode != 0 or (self.constants.detected_os < os_data.os_data.catalina and "KernelCache ID" not in result.stdout.decode()): self.success_status = False @@ -191,26 +185,7 @@ class PatchSysVolume: print("- Unmounting Root Volume (Don't worry if this fails)") utilities.elevated(["diskutil", "unmount", self.root_mount_path], stdout=subprocess.PIPE).stdout.decode().strip().encode() - def delete_old_binaries(self, vendor_patch): - for delete_current_kext in vendor_patch: - delete_path = Path(self.mount_extensions) / Path(delete_current_kext) - if Path(delete_path).exists(): - print(f"- Deleting {delete_current_kext}") - utilities.process_status(utilities.elevated(["rm", "-R", delete_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - else: - print(f"- Couldn't find {delete_current_kext}, skipping") - def add_new_binaries(self, vendor_patch, vendor_location): - for add_current_kext in vendor_patch: - existing_path = Path(self.mount_extensions) / Path(add_current_kext) - if Path(existing_path).exists(): - print(f"- Found conflicting kext, Deleting Root Volume's {add_current_kext}") - utilities.process_status(utilities.elevated(["rm", "-R", existing_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - print(f"- Adding {add_current_kext}") - utilities.process_status(utilities.elevated(["cp", "-R", f"{vendor_location}/{add_current_kext}", self.mount_extensions], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - utilities.process_status(utilities.elevated(["chmod", "-Rf", "755", f"{self.mount_extensions}/{add_current_kext}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - utilities.process_status(utilities.elevated(["chown", "-Rf", "root:wheel", f"{self.mount_extensions}/{add_current_kext}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - def install_auto_patcher_launch_agent(self): # Installs the following: # - OpenCore-Patcher.app in /Library/Application Support/Dortania/ @@ -265,360 +240,192 @@ class PatchSysVolume: def clean_skylight_plugins(self): if (Path(self.mount_application_support) / Path("SkyLightPlugins/")).exists(): - print("- Found SkylightPlugins folder, removing") - utilities.process_status(utilities.elevated(["rm", "-rf", f"{self.mount_application_support}/SkyLightPlugins"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - - def add_brightness_patch(self): - self.delete_old_binaries(sys_patch_data.DeleteBrightness) - self.add_new_binaries(sys_patch_data.AddBrightness, self.constants.legacy_brightness) - utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.payload_apple_private_frameworks_path_brightness}/", self.mount_private_frameworks], stdout=subprocess.PIPE) - utilities.process_status(utilities.elevated(["chmod", "-Rf", "755", f"{self.mount_private_frameworks}/DisplayServices.framework"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - utilities.process_status(utilities.elevated(["chown", "-Rf", "root:wheel", f"{self.mount_private_frameworks}/DisplayServices.framework"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - - def add_audio_patch(self): - if self.model in ["iMac7,1", "iMac8,1"]: - self.delete_old_binaries(sys_patch_data.DeleteVolumeControl) - self.add_new_binaries(sys_patch_data.AddVolumeControl, self.constants.audio_path) + print("- Found SkylightPlugins folder, removing old plugins") + utilities.process_status(utilities.elevated(["rm", "-Rf", f"{self.mount_application_support}/SkyLightPlugins"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + utilities.process_status(utilities.elevated(["mkdir", f"{self.mount_application_support}/SkyLightPlugins"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) else: - self.add_new_binaries(sys_patch_data.AddVolumeControlv2, self.constants.audio_v2_path) - - def add_wifi_patch(self): - print("- Merging Wireless CoreSerices patches") - utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.legacy_wifi_coreservices}/", self.mount_coreservices], stdout=subprocess.PIPE) - utilities.process_status(utilities.elevated(["chmod", "-Rf", "755", f"{self.mount_coreservices}/WiFiAgent.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - utilities.process_status(utilities.elevated(["chown", "-Rf", "root:wheel", f"{self.mount_coreservices}/WiFiAgent.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - print("- Merging Wireless usr/libexec patches") - utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.legacy_wifi_libexec}/", self.mount_libexec], stdout=subprocess.PIPE) - utilities.process_status(utilities.elevated(["chmod", "755", f"{self.mount_libexec}/airportd"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - utilities.process_status(utilities.elevated(["chown", "root:wheel", f"{self.mount_libexec}/airportd"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - - # dylib patch to resolve password crash prompt - # Note requires ASentientBot's SkyLight to function - # Thus Metal machines do not benefit from this patch, however install anyways as harmless - print("- Merging Wireless SkyLightPlugins") - utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.legacy_wifi_support}/", self.mount_application_support], stdout=subprocess.PIPE) - - def add_legacy_mux_patch(self): - self.delete_old_binaries(sys_patch_data.DeleteDemux) - print("- Merging Legacy Mux Kext patches") - utilities.process_status( - utilities.elevated(["cp", "-R", f"{self.constants.legacy_mux_path}/AppleMuxControl.kext", self.mount_extensions_mux], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - ) - - def add_legacy_keyboard_backlight_patch(self): - print("- Enabling Keyboard Backlight delay") - utilities.process_status( - utilities.elevated(["defaults", "write", "/Library/Preferences/.GlobalPreferences.plist", "Moraea_BacklightHack", "-bool", "true"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - ) - - def add_legacy_dropbox_patch(self): - print("- Merging DropboxHack SkyLightPlugins") - utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.legacy_dropbox_support}/", self.mount_application_support], stdout=subprocess.PIPE) - - def gpu_accel_legacy(self): - if self.constants.detected_os == os_data.os_data.mojave: - print("- Installing General Acceleration Kext patches for Mojave") - self.add_new_binaries(sys_patch_data.AddGeneralAccelMojave, self.constants.legacy_general_path) - elif self.constants.detected_os == os_data.os_data.catalina: - print("- Installing General Acceleration Kext patches for Catalina") - self.add_new_binaries(sys_patch_data.AddGeneralAccelCatalina, self.constants.legacy_general_path) - elif self.constants.detected_os in [os_data.os_data.big_sur, os_data.os_data.monterey]: - print("- Installing General Acceleration Kext patches for Big Sur/Monterey") - self.add_new_binaries(sys_patch_data.AddGeneralAccel, self.constants.legacy_general_path) - - # Nvidia - def gpu_accel_legacy_nvidia_master(self): - if self.constants.detected_os in [os_data.os_data.mojave, os_data.os_data.catalina]: - print("- Installing Nvidia Acceleration Kext patches for Mojave/Catalina") - self.gpu_accel_legacy() - self.add_new_binaries(sys_patch_data.AddNvidiaAccelLegacy, self.constants.legacy_nvidia_path) - elif self.constants.detected_os in [os_data.os_data.big_sur, os_data.os_data.monterey]: - print("- Installing Nvidia Acceleration Kext patches for Big Sur/Monterey") - self.delete_old_binaries(sys_patch_data.DeleteNvidiaAccel11) - self.gpu_accel_legacy() - self.add_new_binaries(sys_patch_data.AddNvidiaAccel11, self.constants.legacy_nvidia_path) - if self.constants.detected_os == os_data.os_data.monterey and self.constants.detected_os_minor > 0: - # Beta 7+ removes NVDAStartup - self.add_new_binaries(sys_patch_data.AddNvidiaTeslaAccel12, self.constants.legacy_nvidia_kepler_path) - else: - print("- Installing basic Nvidia Framebuffer Kext patches for generic OS") - self.add_new_binaries(sys_patch_data.AddNvidiaBrightness, self.constants.legacy_nvidia_path) - - # AMD/ATI - def gpu_accel_legacy_ts1_master(self): - if self.constants.detected_os in [os_data.os_data.mojave, os_data.os_data.catalina]: - print("- Installing TeraScale 1 Acceleration Kext patches for Mojave/Catalina") - self.gpu_accel_legacy() - self.add_new_binaries(sys_patch_data.AddAMDAccelLegacy, self.constants.legacy_amd_path) - elif self.constants.detected_os in [os_data.os_data.big_sur, os_data.os_data.monterey]: - print("- Installing TeraScale 1 Acceleration Kext patches for Big Sur/Monterey") - self.delete_old_binaries(sys_patch_data.DeleteAMDAccel11) - self.gpu_accel_legacy() - self.add_new_binaries(sys_patch_data.AddAMDAccel11, self.constants.legacy_amd_path) - else: - print("- Installing basic TeraScale 1 Framebuffer Kext patches for generic OS") - self.add_new_binaries(sys_patch_data.AddAMDBrightness, self.constants.legacy_amd_path) - - def gpu_accel_legacy_ts2_master(self): - if self.constants.detected_os in [os_data.os_data.mojave, os_data.os_data.catalina] and self.constants.allow_ts2_accel is True: - print("- Installing TeraScale 2 Acceleration Kext patches for Mojave/Catalina") - self.gpu_accel_legacy() - self.add_new_binaries(sys_patch_data.AddAMDAccelLegacy, self.constants.legacy_amd_path) - elif self.constants.detected_os in [os_data.os_data.big_sur, os_data.os_data.monterey] and self.constants.allow_ts2_accel is True: - print("- Installing TeraScale 2 Acceleration Kext patches for Big Sur") - self.delete_old_binaries(sys_patch_data.DeleteAMDAccel11) - self.delete_old_binaries(sys_patch_data.DeleteAMDAccel11TS2) - self.gpu_accel_legacy() - self.add_new_binaries(sys_patch_data.AddAMDAccel11, self.constants.legacy_amd_path) - else: - print("- Installing basic TeraScale 2 Framebuffer Kext patches for generic OS") - self.add_new_binaries(sys_patch_data.AddAMDBrightness, self.constants.legacy_amd_path) - - # Intel - def gpu_accel_legacy_ironlake_master(self): - if self.constants.detected_os in [os_data.os_data.mojave, os_data.os_data.catalina]: - print("- Installing Ironlake Acceleration Kext patches for Mojave/Catalina") - self.gpu_accel_legacy() - self.add_new_binaries(sys_patch_data.AddIntelGen1Accel, self.constants.legacy_intel_gen1_path) - elif self.constants.detected_os in [os_data.os_data.big_sur, os_data.os_data.monterey]: - print("- Installing Ironlake Acceleration Kext patches for Big Sur/Monterey") - self.delete_old_binaries(sys_patch_data.DeleteNvidiaAccel11) - self.gpu_accel_legacy() - self.add_new_binaries(sys_patch_data.AddIntelGen1Accel, self.constants.legacy_intel_gen1_path) - else: - print("- Installing basic Ironlake Framebuffer Kext patches for generic OS") - self.add_new_binaries(sys_patch_data.AddIntelGen1Accel, self.constants.legacy_intel_gen1_path) - - def gpu_accel_legacy_sandybridge_master(self): - if self.constants.detected_os in [os_data.os_data.mojave, os_data.os_data.catalina]: - print("- Installing Sandy Bridge Acceleration Kext patches for Mojave/Catalina") - self.gpu_accel_legacy() - self.add_new_binaries(sys_patch_data.AddIntelGen2Accel, self.constants.legacy_intel_gen2_path) - self.gpu_accel_legacy_sandybridge_board_id() - elif self.constants.detected_os in [os_data.os_data.big_sur, os_data.os_data.monterey]: - print("- Installing Sandy Bridge Acceleration Kext patches for Big Sur/Monterey") - self.delete_old_binaries(sys_patch_data.DeleteNvidiaAccel11) - self.gpu_accel_legacy() - self.add_new_binaries(sys_patch_data.AddIntelGen2Accel, self.constants.legacy_intel_gen2_path) - self.gpu_accel_legacy_sandybridge_board_id() - self.gpu_accel_legacy_gva() - else: - print("- Installing basic Sandy Bridge Framebuffer Kext patches for generic OS") - self.add_new_binaries(sys_patch_data.AddIntelGen2Accel, self.constants.legacy_intel_gen2_path) - self.gpu_accel_legacy_sandybridge_board_id() - - def gpu_accel_legacy_sandybridge_board_id(self): - if self.constants.computer.reported_board_id in self.constants.sandy_board_id_stock: - print("- Using stock AppleIntelSNBGraphicsFB") - # TODO: Clean this function up - # add_new_binaries() and delete_old_binaries() have a bug when the passed array has a single element - # 'TypeError: expected str, bytes or os.PathLike object, not list' - # This is a temporary workaround to fix that - utilities.elevated(["rm", "-r", f"{self.mount_extensions}/AppleIntelSNBGraphicsFB-Clean.kext"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - utilities.elevated(["rm", "-r", f"{self.mount_extensions}/AppleIntelSNBGraphicsFB.kext"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - # Add kext - print("- Adding AppleIntelSNBGraphicsFB.kext") - utilities.elevated( - ["cp", "-r", f"{self.constants.legacy_intel_gen2_path}/AppleIntelSNBGraphicsFB-Clean.kext", f"{self.mount_extensions}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT - ) - # Rename kext - utilities.elevated( - ["mv", f"{self.mount_extensions}/AppleIntelSNBGraphicsFB-Clean.kext", f"{self.mount_extensions}/AppleIntelSNBGraphicsFB.kext"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT - ) - # Fix permissions - utilities.elevated(["chown", "-Rf", "root:wheel", f"{self.mount_extensions}/AppleIntelSNBGraphicsFB.kext"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - utilities.elevated(["chmod", "-Rf", "755", f"{self.mount_extensions}/AppleIntelSNBGraphicsFB.kext"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - - else: - # Adjust board ID for spoofs - print("- Using Board ID patched AppleIntelSNBGraphicsFB") - utilities.elevated(["rm", "-r", f"{self.mount_extensions}/AppleIntelSNBGraphicsFB-Clean.kext"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - utilities.elevated(["rm", "-r", f"{self.mount_extensions}/AppleIntelSNBGraphicsFB.kext"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - # Add kext - print("- Adding AppleIntelSNBGraphicsFB.kext") - utilities.elevated(["cp", "-r", f"{self.constants.legacy_intel_gen2_path}/AppleIntelSNBGraphicsFB.kext", f"{self.mount_extensions}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - # Fix permissions - utilities.elevated(["chown", "-Rf", "root:wheel", f"{self.mount_extensions}/AppleIntelSNBGraphicsFB.kext"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - utilities.elevated(["chmod", "-Rf", "755", f"{self.mount_extensions}/AppleIntelSNBGraphicsFB.kext"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - - def gpu_framebuffer_ivybridge_master(self): - if self.constants.detected_os == os_data.os_data.monterey: - print("- Installing IvyBridge Acceleration Kext patches for Monterey") - self.add_new_binaries(sys_patch_data.AddIntelGen3Accel, self.constants.legacy_intel_gen3_path) - if self.validate is False: - print("- Fixing Acceleration in CoreMedia") - utilities.process_status(subprocess.run(["defaults", "write", "com.apple.coremedia", "hardwareVideoDecoder", "-string", "enable"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - print("- Merging Ivy Bridge Frameworks") - utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.payload_apple_frameworks_path_accel_ivy}/", self.mount_frameworks], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - print("- Merging Ivy Bridge PrivateFrameworks") - utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.payload_apple_private_frameworks_path_accel_ivy}/", self.mount_private_frameworks], stdout=subprocess.PIPE) - else: - print("- Installing basic Ivy Bridge Kext patches for generic OS") - self.add_new_binaries(sys_patch_data.AddIntelGen3Accel, self.constants.legacy_intel_gen3_path) - - def gpu_framebuffer_kepler_master(self): - if self.constants.detected_os == os_data.os_data.monterey: - print("- Installing Kepler Acceleration Kext patches for Monterey") - self.add_new_binaries(sys_patch_data.AddNvidiaKeplerAccel11, self.constants.legacy_nvidia_kepler_path) - print("- Merging Kepler Frameworks") - utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.payload_apple_frameworks_path_accel_kepler}/", self.mount_frameworks], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - else: - print("- Installing Kepler Kext patches for generic OS") - self.add_new_binaries(sys_patch_data.AddNvidiaKeplerAccel11, self.constants.legacy_nvidia_kepler_path) - - def gpu_accel_legacy_gva(self): - print("- Merging AppleGVA Hardware Accel patches for non-Metal") - utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.payload_apple_private_frameworks_path_legacy_drm}/", self.mount_private_frameworks], stdout=subprocess.PIPE) - - def gpu_accel_legacy_extended(self): - if self.constants.detected_os == os_data.os_data.monterey: - self.add_legacy_dropbox_patch() - - if self.legacy_keyboard_backlight is True: - self.add_legacy_keyboard_backlight_patch() - - print("- Merging general legacy Frameworks") - utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.payload_apple_frameworks_path_accel}/", self.mount_frameworks], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - if self.constants.detected_os > os_data.os_data.big_sur: - print("- Merging Monterey WebKit patch") - utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.payload_apple_frameworks_path_accel_ivy}/", self.mount_frameworks], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - - print("- Merging general legacy PrivateFrameworks") - utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.payload_apple_private_frameworks_path_accel}/", self.mount_private_frameworks], stdout=subprocess.PIPE) - if self.constants.detected_os > os_data.os_data.catalina: - # With PatcherSupportPkg v0.2.0, IOHID-Fixup.plist is deprecated and integrated into SkyLight patch set - if (Path(self.mount_lauchd) / Path("IOHID-Fixup.plist")).exists(): - print("- Stripping legacy IOHID-Fixup.plist") - utilities.process_status( - utilities.elevated(["rm", "-f", f"{self.mount_lauchd}/IOHID-Fixup.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - ) - else: - print("- Disabling Library Validation") - utilities.process_status( - utilities.elevated( - ["defaults", "write", "/Library/Preferences/com.apple.security.libraryvalidation.plist", "DisableLibraryValidation", "-bool", "true"], - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - ) - ) - - def gpu_accel_legacy_extended_ts2(self): - print("- Merging TeraScale 2 legacy Frameworks") - utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.payload_apple_frameworks_path_accel_ts2}/", self.mount_frameworks], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - - print("- Merging TeraScale 2 PrivateFrameworks") - utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.payload_apple_private_frameworks_path_accel_ts2}/", self.mount_private_frameworks], stdout=subprocess.PIPE) - if self.validate is False: - print("- Fixing Acceleration in CMIO") - utilities.process_status(subprocess.run(["defaults", "write", "com.apple.cmio", "CMIO_Unit_Input_ASC.DoNotUseOpenCL", "-bool", "true"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + print("- Creating SkylightPlugins folder") + utilities.process_status(utilities.elevated(["mkdir", f"{self.mount_application_support}/SkyLightPlugins/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + def patch_root_vol(self): print(f"- Running patches for {self.model}") - - # Before starting, clean out old plugins - self.clean_skylight_plugins() - - # Graphics patches - if self.nvidia_legacy is True: - print("- Installing legacy Nvidia Patches") - if self.constants.detected_os in self.constants.legacy_accel_support: - print("- Detected supported OS, installing Acceleration Patches") - self.added_legacy_kexts = True - else: - print("- Detected unsupported OS, installing Basic Framebuffer") - self.gpu_accel_legacy_nvidia_master() - - elif self.kepler_gpu is True: - print("- Installing Kepler Patches") - if self.constants.detected_os == os_data.os_data.monterey: - print("- Detected supported OS, installing Acceleration Patches") - else: - print("- Detected unsupported OS, installing Basic Framebuffer") - self.gpu_framebuffer_kepler_master() - - elif self.amd_ts1 is True: - print("- Installing legacy TeraScale 1 Patches") - if self.constants.detected_os in self.constants.legacy_accel_support: - print("- Detected supported OS, installing Acceleration Patches") - self.added_legacy_kexts = True - else: - print("- Detected unsupported OS, installing Basic Framebuffer") - self.gpu_accel_legacy_ts1_master() - - elif self.amd_ts2 is True: - print("- Installing legacy TeraScale 2 Patches") - if self.constants.detected_os in self.constants.legacy_accel_support: - print("- Detected supported OS, installing Acceleration Patches") - self.added_legacy_kexts = True - else: - print("- Detected unsupported OS, installing Basic Framebuffer") - self.gpu_accel_legacy_ts2_master() - - if self.iron_gpu is True: - print("- Installing legacy Ironlake Patches") - if self.constants.detected_os in self.constants.legacy_accel_support: - print("- Detected supported OS, installing Acceleration Patches") - self.added_legacy_kexts = True - else: - print("- Detected unsupported OS, installing Basic Framebuffer") - self.gpu_accel_legacy_ironlake_master() - - elif self.sandy_gpu is True: - print("- Installing legacy Sandy Bridge Patches") - if self.constants.detected_os in self.constants.legacy_accel_support: - print("- Detected supported OS, installing Acceleration Patches") - self.added_legacy_kexts = True - else: - print("- Detected unsupported OS, installing Basic Framebuffer") - self.gpu_accel_legacy_sandybridge_master() - - elif self.ivy_gpu is True: - print("- Installing Ivy Bridge Patches") - if self.constants.detected_os == os_data.os_data.monterey: - print("- Detected supported OS, installing Acceleration Patches") - else: - print("- Detected unsupported OS, installing Basic Framebuffer") - self.gpu_framebuffer_ivybridge_master() - - if self.amd_ts2 is True and self.constants.detected_os in self.constants.legacy_accel_support and self.constants.allow_ts2_accel is True: - # TeraScale 2 patches must be installed after Intel HD3000 - self.add_new_binaries(sys_patch_data.AddAMDAccel11TS2, self.constants.legacy_amd_path_ts2) - - if self.added_legacy_kexts is True and self.constants.detected_os in self.constants.legacy_accel_support: - self.gpu_accel_legacy_extended() - if self.amd_ts2 is True and self.constants.allow_ts2_accel is True: - self.gpu_accel_legacy_extended_ts2() - - # Misc patches - if self.brightness_legacy is True: - print("- Installing legacy Brightness Control") - self.add_brightness_patch() - - if self.legacy_audio is True: - print("- Fixing Volume Control Support") - self.add_audio_patch() - - if self.legacy_wifi is True: - print("- Installing legacy Wireless support") - self.add_wifi_patch() - - if self.legacy_gmux is True: - print("- Installing Legacy Mux Brightness support") - self.add_legacy_mux_patch() + + self.execute_patchset(self.generate_patchset()) if self.constants.wxpython_variant is True and self.constants.detected_os >= os_data.os_data.big_sur: self.install_auto_patcher_launch_agent() - if self.validate is False: - self.rebuild_snapshot() + self.rebuild_snapshot() + + def generate_patchset(self): + all_hardware_patchset = sys_patch_dict.SystemPatchDictionary(self.constants.detected_os) + required_patches = {} + + print("- Creating Patch Set for Booted Hardware:") + if self.iron_gpu is True: + print(" - Adding Intel Ironlake Graphics Patchset") + required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]}) + required_patches.update({"Intel Ironlake": all_hardware_patchset["Graphics"]["Intel Ironlake"]}) + if self.sandy_gpu is True: + print(" - Adding Intel Sandy Bridge Graphics Patchset") + required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]}) + required_patches.update({"Legacy GVA": all_hardware_patchset["Graphics"]["Legacy GVA"]}) + required_patches.update({"Intel Sandy Bridge": all_hardware_patchset["Graphics"]["Intel Sandy Bridge"]}) + if self.ivy_gpu is True: + print(" - Adding Intel Ivy Bridge Graphics Patchset") + required_patches.update({"Metal Common": all_hardware_patchset["Graphics"]["Metal Common"]}) + required_patches.update({"Intel Ivy Bridge": all_hardware_patchset["Graphics"]["Intel Ivy Bridge"]}) + if self.nvidia_legacy is True: + print(" - Adding Nvidia Tesla Graphics Patchset") + required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]}) + required_patches.update({"Nvidia Tesla": all_hardware_patchset["Graphics"]["Nvidia Tesla"]}) + if self.kepler_gpu is True: + print(" - Adding Nvidia Kepler Graphics Patchset") + required_patches.update({"Metal Common": all_hardware_patchset["Graphics"]["Metal Common"]}) + required_patches.update({"Nvidia Kepler": all_hardware_patchset["Graphics"]["Nvidia Kepler"]}) + if self.amd_ts1 is True: + print(" - Adding AMD TeraScale 1 Graphics Patchset") + required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]}) + required_patches.update({"AMD TeraScale 1": all_hardware_patchset["Graphics"]["AMD TeraScale 1"]}) + if self.amd_ts2 is True: + print(" - Adding AMD TeraScale 2 Graphics Patchset") + required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]}) + required_patches.update({"AMD TeraScale 2": all_hardware_patchset["Graphics"]["AMD TeraScale 2"]}) + if self.brightness_legacy is True: + print(" - Adding Legacy Brightness Patchset") + required_patches.update({"Legacy Brightness": all_hardware_patchset["Brightness"]["Legacy Brightness"]}) + if self.legacy_audio is True: + print(" - Adding Legacy Audio Patchset") + if self.model in ["iMac7,1", "iMac8,1"]: + required_patches.update({"Legacy Realtek": all_hardware_patchset["Audio"]["Legacy Realtek"]}) + else: + required_patches.update({"Legacy Non-GOP": all_hardware_patchset["Audio"]["Legacy Non-GOP"]}) + if self.legacy_wifi is True: + print(" - Adding Legacy WiFi Patchset") + required_patches.update({"Legacy WiFi": all_hardware_patchset["Networking"]["Legacy WiFi"]}) + if self.legacy_gmux is True: + print(" - Adding Legacy GMUX Patchset") + required_patches.update({"Legacy GMUX": all_hardware_patchset["Miscellaneous"]["Legacy GMUX"]}) + if self.legacy_keyboard_backlight: + print(" - Adding Legacy Keyboard Backlight Patchset") + required_patches.update({"Legacy Keyboard Backlight": all_hardware_patchset["Miscellaneous"]["Legacy Keyboard Backlight"]}) + + return required_patches + + + def execute_patchset(self, required_patches): + source_files_path = str(self.constants.payload_local_binaries_root_path) + print("- Running Preflight Checks before patching") + # Make sure old SkyLight plugins aren't being used + self.clean_skylight_plugins() + # Make sure SNB kexts are compatible with the host + if "Intel Sandy Bridge" in required_patches: + if self.computer.reported_board_id not in self.constants.sandy_board_id_stock: + print(f"- Found unspported Board ID {self.computer.reported_board_id}, performing AppleIntelSNBGraphicsFB bin patching") + board_to_patch = generate_smbios.determine_best_board_id_for_sandy(self.computer.reported_board_id, self.computer.gpus) + print(f"- Replacing {board_to_patch} with {self.computer.reported_board_id}") + + board_to_patch_hex = bytes.fromhex(board_to_patch.encode('utf-8').hex()) + reported_board_hex = bytes.fromhex(self.computer.reported_board_id.encode('utf-8').hex()) + + if len(board_to_patch_hex) != len(reported_board_hex): + print(f"- Error: Board ID {self.computer.reported_board_id} is not the same length as {board_to_patch}") + raise Exception("Host's Board ID is not the same length as the kext's Board ID, cannot patch!!!") + else: + path = source_files_path + "10.13.6/System/Library/Extensions/AppleIntelSNBGraphicsFB.kext/Contents/MacOS/AppleIntelSNBGraphicsFB" + if Path(path).exists: + with open(path, 'rb') as f: + data = f.read() + data = data.replace(board_to_patch_hex, reported_board_hex) + with open(path, 'wb') as f: + f.write(data) + else: + raise Exception("Failed to find AppleIntelSNBGraphicsFB.kext, cannot patch!!!") + + print("- Finished Preflight, starting patching") + for patch in required_patches: + print("- Installing Patchset: " + patch) + if "Remove" in required_patches[patch]: + for remove_patch_directory in required_patches[patch]["Remove"]: + print("- Remove Files at: " + remove_patch_directory) + for remove_patch_file in required_patches[patch]["Remove"][remove_patch_directory]: + destination_folder_path = str(self.mount_location) + remove_patch_directory + self.remove_file(destination_folder_path, remove_patch_file) + + if "Install" in required_patches[patch]: + for install_patch_directory in required_patches[patch]["Install"]: + print(f"- Handling Installs in: {install_patch_directory}") + for install_file in required_patches[patch]["Install"][install_patch_directory]: + source_folder_path = source_files_path + "/" + required_patches[patch]['Install'][install_patch_directory][install_file] + install_patch_directory + destination_folder_path = str(self.mount_location) + install_patch_directory + self.install_new_file(source_folder_path, destination_folder_path, install_file) + + if "Install Non-Root" in required_patches[patch]: + for install_patch_directory in required_patches[patch]["Install Non-Root"]: + print(f"- Handling Non-Root Installs in: {install_patch_directory}") + for install_file in required_patches[patch]["Install Non-Root"][install_patch_directory]: + source_folder_path = source_files_path + "/" + required_patches[patch]['Install Non-Root'][install_patch_directory][install_file] + install_patch_directory + destination_folder_path = str(self.mount_location_data) + install_patch_directory + self.install_new_file(source_folder_path, destination_folder_path, install_file) + + if "Processes" in required_patches[patch]: + for process in required_patches[patch]["Processes"]: + # Some processes need sudo, however we cannot directly call sudo in some scenarios + # Instead, call elevated funtion and strip sudo from argument + process_array = process.split(" ") + if required_patches[patch]["Processes"][process] is True: + utilities.process_status(utilities.elevated(process_array, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + else: + utilities.process_status(subprocess.run(process_array, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + + def install_new_file(self, source_folder, destination_folder, file_name): + # .frameworks are merged + # .kexts and .apps are deleted and replaced + file_name_str = str(file_name) + if file_name_str.endswith(".kext") or file_name_str.endswith(".app") or file_name_str.endswith(".bundle") or file_name_str.endswith(".plugin"): + if Path(destination_folder + "/" + file_name).exists(): + print(f" - Found existing {file_name}, overwritting...") + utilities.process_status(utilities.elevated(["rm", "-R", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + else: + print(" - Installing: " + file_name) + utilities.process_status(utilities.elevated(["cp", "-R", f"{source_folder}/{file_name}", destination_folder], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + utilities.process_status(utilities.elevated(["chmod", "-Rf", "755", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + utilities.process_status(utilities.elevated(["chown", "-Rf", "root:wheel", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + + elif file_name_str.endswith(".framework"): + # merge with rsync + print(" - Installing: " + file_name) + utilities.elevated(["rsync", "-r", "-i", "-a", f"{source_folder}/{file_name}", f"{destination_folder}/"], stdout=subprocess.PIPE) + utilities.process_status(utilities.elevated(["chmod", "-Rf", "755", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + utilities.process_status(utilities.elevated(["chown", "-Rf", "root:wheel", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + else: + # Assume it's an individual file, replace as normal + if Path(destination_folder + "/" + file_name).exists(): + print(f" - Found existing {file_name}, overwritting...") + utilities.process_status(utilities.elevated(["rm", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + else: + print(" - Installing: " + file_name) + utilities.process_status(utilities.elevated(["cp", f"{source_folder}/{file_name}", destination_folder], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + utilities.process_status(utilities.elevated(["chmod", "755", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + utilities.process_status(utilities.elevated(["chown", "root:wheel", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + + def remove_file(self, destination_folder, file_name): + if Path(destination_folder + "/" + file_name).exists(): + print(" - Removing: " + file_name) + if Path(destination_folder + "/" + file_name).is_dir(): + utilities.process_status(utilities.elevated(["rm", "-R", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + else: + utilities.process_status(utilities.elevated(["rm", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + def check_files(self): - if Path(self.constants.payload_apple_root_path).exists(): + if Path(self.constants.payload_local_binaries_root_path).exists(): 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"}: - shutil.rmtree(Path(self.constants.payload_apple_root_path)) + shutil.rmtree(Path(self.constants.payload_local_binaries_root_path)) output = self.download_files() else: output = self.download_files() @@ -628,32 +435,26 @@ class PatchSysVolume: def download_files(self): if self.constants.gui_mode is False or "Library/InstallerSandboxes/" in str(self.constants.payload_path): - download_result, os_ver, extensions_link, framework_link = sys_patch_download.grab_patcher_support_pkg(self.constants).download_files() + download_result, os_ver, link = sys_patch_download.grab_patcher_support_pkg(self.constants).download_files() else: download_result = True - os_ver, extensions_link, framework_link = sys_patch_download.grab_patcher_support_pkg(self.constants).generate_pkg_link() + 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() and self.constants.payload_universal_extensions_zip_path.exists(): - print("- Download completed") - print("- Unzipping download...") + if download_result and self.constants.payload_local_binaries_root_path_zip.exists(): + print("- Unzipping binaries...") try: - utilities.process_status(subprocess.run(["unzip", self.constants.payload_apple_root_path_zip], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=self.constants.payload_path)) - utilities.process_status(subprocess.run(["unzip", self.constants.payload_universal_extensions_zip_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=self.constants.payload_path)) + utilities.process_status(subprocess.run(["ditto", "-V", "-x", "-k", "--sequesterRsrc", "--rsrc", self.constants.payload_local_binaries_root_path_zip, self.constants.payload_path])) print("- Renaming folder") - os.rename(self.constants.payload_path / Path(os_ver), self.constants.payload_apple_root_path) - Path(self.constants.payload_apple_root_path_zip).unlink() - Path(self.constants.payload_universal_extensions_zip_path).unlink() print("- Binaries downloaded to:") print(self.constants.payload_path) - return self.constants.payload_apple_root_path + return self.constants.payload_local_binaries_root_path except zipfile.BadZipFile: print("- Couldn't unzip") return None else: if self.constants.gui_mode is True: - print("- Download failed, please verify the below links work:") - print(framework_link) - print(extensions_link) + print("- Download failed, please verify the below link work:") + print(link) print("\nIf you continue to have issues, try using the Offline builds") print("located on Github next to the other builds") else: @@ -705,57 +506,6 @@ class PatchSysVolume: ] ) - 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 - if sip == sip_data.system_integrity_protection.root_patch_sip_mojave: - sip_value = "For Hackintoshes, please set csr-active-config to '03060000' (0x603)\nFor non-OpenCore Macs, please run 'csrutil disable' in RecoveryOS" - else: - sip_value = ( - "For Hackintoshes, please set csr-active-config to '02080000' (0x802)\nFor non-OpenCore Macs, please run 'csrutil disable' and \n'csrutil authenticated-root disable' in RecoveryOS" - ) - if self.sip_enabled is True: - print("\nCannot patch! Please disable System Integrity Protection (SIP).") - print("Disable SIP in Patcher Settings and Rebuild OpenCore\n") - print("Ensure the following bits are set for csr-active-config:") - print("\n".join(sip)) - print(sip_value) - - if self.sbm_enabled is True: - print("\nCannot patch! Please disable Apple Secure Boot.") - print("Disable SecureBootModel in Patcher Settings and Rebuild OpenCore") - print("For Hackintoshes, set SecureBootModel to Disabled") - - if self.fv_enabled is True: - print("\nCannot patch! Please disable FileVault.") - print("For OCLP Macs, please rebuild your config with 0.2.5 or newer") - print("For others, Go to System Preferences -> Security and disable FileVault") - - if self.amfi_enabled is True and self.amfi_must_disable is True: - print("\nCannot patch! Please disable AMFI.") - print("For Hackintoshes, please add amfi_get_out_of_my_way=1 to boot-args") - - 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): - print("\nCannot patch! Board ID not supported by AppleIntelSNBGraphicsFB") - print(f"Detected Board ID: {self.computer.reported_board_id}") - print("Please ensure your Board ID is listed below:") - for board in self.constants.sandy_board_id: - print(f"- {board} ({generate_smbios.find_model_off_board(board)})") - for board in self.constants.sandy_board_id_stock: - print(f"- {board} ({generate_smbios.find_model_off_board(board)})") - - self.bad_board_id = True - - if self.dosdude_patched is True: - print("\nCannot patch! Detected machine has already been patched by another patcher") - print("Please ensure your install is either clean or patched with OpenCore Legacy Patcher") - - 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 - # Entry Function def start_patch(self): print("- Starting Patch Process") @@ -772,9 +522,8 @@ class PatchSysVolume: change_menu = "y" print("- Continuing root patching") if change_menu in ["y", "Y"]: - print("- Continuing with Patching") print("- Verifying whether Root Patching possible") - if self.verify_patch_allowed() is True: + if sys_patch_detect.detect_root_patch(self.computer.real_model, self.constants).verify_patch_allowed(print_errors=not self.constants.wxpython_variant) is True: print("- Patcher is capable of patching") if self.check_files(): self.find_mount_root_vol(True) @@ -786,7 +535,7 @@ class PatchSysVolume: def start_unpatch(self): print("- Starting Unpatch Process") - if self.verify_patch_allowed() is True: + if sys_patch_detect.detect_root_patch(self.computer.real_model, self.constants).verify_patch_allowed(print_errors=not self.constants.wxpython_variant) is True: self.find_mount_root_vol(False) if self.constants.gui_mode is False: input("\nPress [ENTER] to return to the main menu") diff --git a/resources/sys_patch_detect.py b/resources/sys_patch_detect.py index dc4b4e04a..2689a9f7e 100644 --- a/resources/sys_patch_detect.py +++ b/resources/sys_patch_detect.py @@ -3,7 +3,7 @@ # Used when supplying data to sys_patch.py # Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk -from resources import constants, device_probe, utilities +from resources import constants, device_probe, utilities, generate_smbios from data import model_array, os_data, sip_data class detect_root_patch: @@ -182,13 +182,52 @@ class detect_root_patch: return self.root_patch_dict - def verify_patch_allowed(self): + def verify_patch_allowed(self, print_errors=False): 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 sip == sip_data.system_integrity_protection.root_patch_sip_mojave: + sip_value = "For Hackintoshes, please set csr-active-config to '03060000' (0x603)\nFor non-OpenCore Macs, please run 'csrutil disable' in RecoveryOS" + else: + sip_value = ( + "For Hackintoshes, please set csr-active-config to '02080000' (0x802)\nFor non-OpenCore Macs, please run 'csrutil disable' and \n'csrutil authenticated-root disable' in RecoveryOS" + ) + if print_errors is True: + if self.sip_enabled is True: + print("\nCannot patch! Please disable System Integrity Protection (SIP).") + print("Disable SIP in Patcher Settings and Rebuild OpenCore\n") + print("Ensure the following bits are set for csr-active-config:") + print("\n".join(sip)) + print(sip_value) + + if self.sbm_enabled is True: + print("\nCannot patch! Please disable Apple Secure Boot.") + print("Disable SecureBootModel in Patcher Settings and Rebuild OpenCore") + print("For Hackintoshes, set SecureBootModel to Disabled") + + if self.fv_enabled is True: + print("\nCannot patch! Please disable FileVault.") + print("For OCLP Macs, please rebuild your config with 0.2.5 or newer") + print("For others, Go to System Preferences -> Security and disable FileVault") + + if self.amfi_enabled is True and self.amfi_must_disable is True: + print("\nCannot patch! Please disable AMFI.") + print("For Hackintoshes, please add amfi_get_out_of_my_way=1 to boot-args") + + if self.dosdude_patched is True: + print("\nCannot patch! Detected machine has already been patched by another patcher") + print("Please ensure your install is either clean or patched with OpenCore Legacy Patcher") 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 print_errors is True: + print("\nCannot patch! Board ID not supported by AppleIntelSNBGraphicsFB") + print(f"Detected Board ID: {self.computer.reported_board_id}") + print("Please ensure your Board ID is listed below:") + for board in self.constants.sandy_board_id: + print(f"- {board} ({generate_smbios.find_model_off_board(board)})") + for board in self.constants.sandy_board_id_stock: + print(f"- {board} ({generate_smbios.find_model_off_board(board)})") + 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] ): diff --git a/resources/sys_patch_download.py b/resources/sys_patch_download.py index 0577c1bac..5e3189d18 100644 --- a/resources/sys_patch_download.py +++ b/resources/sys_patch_download.py @@ -22,31 +22,23 @@ class grab_patcher_support_pkg: os_ver = "10.14-Mojave" else: raise Exception(f"Unsupported OS: {self.constants.detected_os}") - framework_link = f"{self.constants.url_patcher_support_pkg}{self.constants.patcher_support_pkg_version}/{os_ver}.zip" - extensions_link = f"{self.constants.url_patcher_support_pkg}{self.constants.patcher_support_pkg_version}/Universal-Extensions.zip" - return os_ver, extensions_link, framework_link + link = f"{self.constants.url_patcher_support_pkg}{self.constants.patcher_support_pkg_version}/Universal-Binaries.zip" + return os_ver, link def download_files(self): - os_ver, extensions_link, framework_link = self.generate_pkg_link() - if Path(self.constants.payload_apple_root_path).exists(): + os_ver, link = self.generate_pkg_link() + if Path(self.constants.payload_local_binaries_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() + shutil.rmtree(self.constants.payload_local_binaries_root_path) download_result = None - local_framework_zip = Path(self.constants.payload_path) / f"{os_ver}.zip" - local_extensions_zip = Path(self.constants.payload_path) / f"Universal-Extensions.zip" - if Path(local_framework_zip).exists() and Path(local_extensions_zip).exists(): - print(f"- Found local {os_ver} zip, skipping download") - print(f"- Duplicating into Apple.zip") - shutil.copy(local_framework_zip, self.constants.payload_apple_root_path_zip) + local_zip = Path(self.constants.payload_path) / f"Universal-Binaries.zip" + if Path(local_zip).exists(): + print(f"- Found local {local_zip} zip, skipping download") download_result = True else: - print(f"- No local version found, donwloading...") - if utilities.download_file(extensions_link, self.constants.payload_universal_extensions_zip_path): - download_result = utilities.download_file(framework_link, self.constants.payload_apple_root_path_zip) + print(f"- No local version found, downloading...") + download_result = utilities.download_file(link, self.constants.payload_local_binaries_root_path_zip) - return download_result, os_ver, extensions_link, framework_link \ No newline at end of file + return download_result, os_ver, link \ No newline at end of file From 48bf23325094a75c2b600ad9906ebafadf0990ec Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Mon, 2 May 2022 13:29:53 -0600 Subject: [PATCH 02/14] create_offline_build.py: Update binary selection --- create_offline_build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/create_offline_build.py b/create_offline_build.py index 2bf4e8472..88e6175c0 100644 --- a/create_offline_build.py +++ b/create_offline_build.py @@ -2,7 +2,7 @@ import subprocess from resources import constants patcher_support_pkg_version = constants.Constants().patcher_support_pkg_version -binary_packages = ["11-Big-Sur", "12-Monterey", "Universal-Extensions"] +binary_packages = ["Universal-Binaries"] for binary_package in binary_packages: print(f"- Downloading {binary_package}...") From 3cd270593f99d5743056f9344784d3b5c2ee0b5f Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Mon, 2 May 2022 13:50:55 -0600 Subject: [PATCH 03/14] sys_patch_dict.py: Remove OpenCL defaults for TS2 --- data/sys_patch_dict.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/data/sys_patch_dict.py b/data/sys_patch_dict.py index 352a9bc6c..3f9500b7b 100644 --- a/data/sys_patch_dict.py +++ b/data/sys_patch_dict.py @@ -134,9 +134,6 @@ def SystemPatchDictionary(os): }, }, "AMD TeraScale 2": { - "Processes": { - "defaults write com.apple.cmio CMIO_Unit_Input_ASC.DoNotUseOpenCL -bool true": False, - }, "Install": { "/System/Library/Extensions": { "AMD5000Controller.kext": "10.13.6", @@ -191,7 +188,7 @@ def SystemPatchDictionary(os): "AppleIntelHD3000GraphicsGA.plugin": "10.13.6", "AppleIntelHD3000GraphicsGLDriver.bundle": "10.13.6", "AppleIntelHD3000GraphicsVADriver.bundle": "10.13.6", - "AppleIntelSNBGraphicsFB.kext": "10.13.6", # Add check for Board ID patched kext + "AppleIntelSNBGraphicsFB.kext": "10.13.6", "AppleIntelSNBVA.bundle": "10.13.6", }, }, From 3940b5ee3f295f52c007c913a4a3011e59b75da0 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Mon, 2 May 2022 14:19:38 -0600 Subject: [PATCH 04/14] Test --- .github/workflows/build-app-wxpython.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-app-wxpython.yml b/.github/workflows/build-app-wxpython.yml index 8f3dc2acf..687217c55 100644 --- a/.github/workflows/build-app-wxpython.yml +++ b/.github/workflows/build-app-wxpython.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v3 - run: python3 create_offline_build.py - run: /Library/Frameworks/Python.framework/Versions/3.9/bin/pyinstaller OpenCore-Patcher-GUI.spec - - run: python3 ./payloads/binary.py $branch $commiturl $commitdate + - run: 'codesign -s "Developer ID Application: Mykola Grymalyuk (S74BDJXQMD)" -v --force --deep --timestamp --entitlements ./payloads/entitlements.plist -o runtime "dist/OpenCore-Patcher.app"' - run: cd dist; zip -r ../OpenCore-Patcher-wxPython.app.zip OpenCore-Patcher.app - run: ./../sign-wxpython.sh From e7defde42f54b0cb9cad4e2ad01ccd7f1dc49877 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Mon, 2 May 2022 14:23:37 -0600 Subject: [PATCH 05/14] CI: Strip commit info --- .github/workflows/build-app-wxpython.yml | 1 - .github/workflows/build-app.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/build-app-wxpython.yml b/.github/workflows/build-app-wxpython.yml index 687217c55..87ade3834 100644 --- a/.github/workflows/build-app-wxpython.yml +++ b/.github/workflows/build-app-wxpython.yml @@ -18,7 +18,6 @@ jobs: - uses: actions/checkout@v3 - run: python3 create_offline_build.py - run: /Library/Frameworks/Python.framework/Versions/3.9/bin/pyinstaller OpenCore-Patcher-GUI.spec - - run: 'codesign -s "Developer ID Application: Mykola Grymalyuk (S74BDJXQMD)" -v --force --deep --timestamp --entitlements ./payloads/entitlements.plist -o runtime "dist/OpenCore-Patcher.app"' - run: cd dist; zip -r ../OpenCore-Patcher-wxPython.app.zip OpenCore-Patcher.app - run: ./../sign-wxpython.sh diff --git a/.github/workflows/build-app.yml b/.github/workflows/build-app.yml index 226203808..34dcc5bef 100644 --- a/.github/workflows/build-app.yml +++ b/.github/workflows/build-app.yml @@ -18,7 +18,6 @@ jobs: - uses: actions/checkout@v3 - run: python3 create_offline_build.py - run: /Library/Frameworks/Python.framework/Versions/3.9/bin/pyinstaller OpenCore-Patcher.spec - - run: python3 ./payloads/binary.py $branch $commiturl $commitdate - run: ./after_pyinstaller.sh - run: 'codesign -s "Developer ID Application: Mykola Grymalyuk (S74BDJXQMD)" -v --force --deep --timestamp --entitlements ./payloads/entitlements.plist -o runtime "dist/OpenCore-Patcher.app"' - run: cd dist; zip -r ../OpenCore-Patcher-TUI.app.zip OpenCore-Patcher.app From b4bfd827ce54a7513477038632506fab53996718 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Mon, 2 May 2022 16:53:23 -0600 Subject: [PATCH 06/14] Remove unused variables --- resources/constants.py | 14 -------------- resources/sys_patch.py | 16 ++-------------- resources/sys_patch_detect.py | 18 +----------------- 3 files changed, 3 insertions(+), 45 deletions(-) diff --git a/resources/constants.py b/resources/constants.py index 1b7e2e515..fbcffbe11 100644 --- a/resources/constants.py +++ b/resources/constants.py @@ -209,11 +209,6 @@ class Constants: @property def plist_template(self): return self.payload_path / Path("Config/config.plist") - - # Mount Location - @property - def payload_mnt1_path(self): - return self.payload_path / Path("mnt1") # Launch Agent @property @@ -600,15 +595,6 @@ class Constants: # "x86legacy", # non-T2 Macs/VMs, Monterey's boot.efi enforces this on all Macs ] - sandy_board_id = [ - "Mac-E43C1C25D4880AD6", # MacBookPro12,1 - "Mac-06F11F11946D27C5", # MacBookPro11,5 - "Mac-9F18E312C5C2BF0B", # MacBookAir7,1 - "Mac-937CB26E2E02BB01", # MacBookAir7,2 - "Mac-35C5E08120C7EEAF", # Macmini7,1 - "Mac-7BA5B2D9E42DDD94", # iMacPro1,1 - ] - sandy_board_id_stock = [ "Mac-94245B3640C91C81", # MacBookPro8,1 "Mac-94245A3940C91C80", # MacBookPro8,2 diff --git a/resources/sys_patch.py b/resources/sys_patch.py index e8d86559f..c97591744 100644 --- a/resources/sys_patch.py +++ b/resources/sys_patch.py @@ -21,8 +21,6 @@ class PatchSysVolume: self.constants: constants.Constants() = versions self.computer = self.constants.computer self.root_mount_path = None - self.validate = False - self.added_legacy_kexts = False self.root_supports_snapshot = utilities.check_if_root_is_apfs_snapshot() self.constants.root_patcher_succeded = False # Reset Variable each time we start @@ -34,16 +32,6 @@ class PatchSysVolume: self.init_pathing(custom_root_mount_path=None, custom_data_mount_path=None) def init_hardware_patches(self, hardware_details): - - self.amfi_must_disable = hardware_details["Settings: Requires AMFI exemption"] - self.check_board_id = hardware_details["Settings: Requires Board ID validation"] - self.sip_enabled = hardware_details["Validation: SIP is enabled"] - self.sbm_enabled = hardware_details["Validation: SBM is enabled"] - self.amfi_enabled = hardware_details["Validation: AMFI is enabled"] - self.fv_enabled = hardware_details["Validation: FileVault is enabled"] - self.dosdude_patched = hardware_details["Validation: System is dosdude1 patched"] - self.bad_board_id = hardware_details[f"Validation: Board ID is unsupported \n({self.computer.reported_board_id})"] - self.nvidia_legacy = hardware_details["Graphics: Nvidia Tesla"] self.kepler_gpu = hardware_details["Graphics: Nvidia Kepler"] self.amd_ts1 = hardware_details["Graphics: AMD TeraScale 1"] @@ -312,7 +300,7 @@ class PatchSysVolume: required_patches.update({"Legacy Keyboard Backlight": all_hardware_patchset["Miscellaneous"]["Legacy Keyboard Backlight"]}) return required_patches - + def execute_patchset(self, required_patches): source_files_path = str(self.constants.payload_local_binaries_root_path) @@ -535,7 +523,7 @@ class PatchSysVolume: def start_unpatch(self): print("- Starting Unpatch Process") - if sys_patch_detect.detect_root_patch(self.computer.real_model, self.constants).verify_patch_allowed(print_errors=not self.constants.wxpython_variant) is True: + if sys_patch_detect.detect_root_patch(self.computer.real_model, self.constants).verify_patch_allowed(print_errors=True) is True: self.find_mount_root_vol(False) if self.constants.gui_mode is False: input("\nPress [ENTER] to return to the main menu") diff --git a/resources/sys_patch_detect.py b/resources/sys_patch_detect.py index 2689a9f7e..0fecd8f6a 100644 --- a/resources/sys_patch_detect.py +++ b/resources/sys_patch_detect.py @@ -30,7 +30,6 @@ class detect_root_patch: # Patch Requirements self.amfi_must_disable= False - self.check_board_id= False self.supports_metal= False # Validation Checks @@ -39,7 +38,6 @@ class detect_root_patch: self.amfi_enabled = False self.fv_enabled = False self.dosdude_patched = False - self.bad_board_id = False def detect_gpus(self): @@ -80,7 +78,6 @@ class detect_root_patch: if self.constants.detected_os > non_metal_os: self.sandy_gpu = True self.amfi_must_disable = True - self.check_board_id = True self.legacy_keyboard_backlight = self.check_legacy_keyboard_backlight() elif gpu.arch == device_probe.Intel.Archs.Ivy_Bridge: if self.constants.detected_os > os_data.os_data.big_sur: @@ -170,14 +167,12 @@ class detect_root_patch: "Miscellaneous: Legacy GMUX": self.legacy_gmux, "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 if self.amfi_must_disable else False, "Validation: FileVault is enabled": self.fv_enabled, "Validation: System is dosdude1 patched": self.dosdude_patched, - f"Validation: Board ID is unsupported \n({self.computer.reported_board_id})": self.bad_board_id, } return self.root_patch_dict @@ -216,20 +211,9 @@ class detect_root_patch: if self.dosdude_patched is True: print("\nCannot patch! Detected machine has already been patched by another patcher") print("Please ensure your install is either clean or patched with OpenCore Legacy Patcher") - - 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 print_errors is True: - print("\nCannot patch! Board ID not supported by AppleIntelSNBGraphicsFB") - print(f"Detected Board ID: {self.computer.reported_board_id}") - print("Please ensure your Board ID is listed below:") - for board in self.constants.sandy_board_id: - print(f"- {board} ({generate_smbios.find_model_off_board(board)})") - for board in self.constants.sandy_board_id_stock: - print(f"- {board} ({generate_smbios.find_model_off_board(board)})") 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] + [self.sip_enabled, self.sbm_enabled, self.fv_enabled, self.dosdude_patched, self.amfi_enabled if self.amfi_must_disable else False] ): return False else: From 8489823f8bc718e6c42797526c73dd17baabd877 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Mon, 2 May 2022 22:09:22 -0600 Subject: [PATCH 07/14] Remove more unneeded code --- data/sys_patch_dict.py | 60 ++++++++++++++---- gui/gui_main.py | 2 +- resources/cli_menu.py | 24 ++++---- resources/install.py | 12 ++-- resources/installer.py | 4 +- resources/main.py | 4 +- resources/sys_patch.py | 99 +++++++++++++++++------------- resources/sys_patch_download.py | 16 +---- resources/tui_helpers.py | 78 ++++++++++++++++++++++++ resources/utilities.py | 105 -------------------------------- 10 files changed, 210 insertions(+), 194 deletions(-) create mode 100644 resources/tui_helpers.py diff --git a/data/sys_patch_dict.py b/data/sys_patch_dict.py index 3f9500b7b..b484ae4aa 100644 --- a/data/sys_patch_dict.py +++ b/data/sys_patch_dict.py @@ -1,6 +1,19 @@ +# Dictionary defining patch sets used during Root Volume patching (sys_patch.py) +# Copyright (C) 2022, Mykola Grymalyuk + +# Schema for sys_patch_dict.py: +# Supports 3 types of higher level keys: +# - Install: Install to root volume - Dictionary of strings with value of source +# - Install Non-Root: Install to data partition - Dictionary of strings with value of source +# - Remove: Files to remove - Array of strings +# - Processes: Additional processes to run - Array of strings + +# File Storage is based off the origin, ie. '10.13.6/System/Library/Extensions/IOSurface.kext' +# Stubbed binaries are OS specific, this use the 'os' variable to denounce which folder to use + from data import os_data -def SystemPatchDictionary(os): +def SystemPatchDictionary(os_major): sys_patch_dict = { "Graphics": { "Non-Metal Common": { @@ -10,13 +23,13 @@ def SystemPatchDictionary(os): }, "/System/Library/Frameworks": { "OpenGL.framework": "10.14.3", - "CoreDisplay.framework": f"10.14.4-{os}", - "IOSurface.framework": f"10.15.7-{os}", - "QuartzCore.framework": f"10.15.7-{os}", + "CoreDisplay.framework": f"10.14.4-{os_major}", + "IOSurface.framework": f"10.15.7-{os_major}", + "QuartzCore.framework": f"10.15.7-{os_major}", }, "/System/Library/PrivateFrameworks": { "GPUSupport.framework": "10.14.3", - "SkyLight.framework": f"10.14.6-{os}", + "SkyLight.framework": f"10.14.6-{os_major}", }, }, "Remove": { @@ -49,8 +62,8 @@ def SystemPatchDictionary(os): }, "Install Non-Root": { "/Library/Application Support/SkyLightPlugins": { - **({ "DropboxHack.dylib": "SkyLightPlugins" } if os >= os_data.os_data.monterey else {}), - **({ "DropboxHack.txt": "SkyLightPlugins" } if os >= os_data.os_data.monterey else {}), + **({ "DropboxHack.dylib": "SkyLightPlugins" } if os_major >= os_data.os_data.monterey else {}), + **({ "DropboxHack.txt": "SkyLightPlugins" } if os_major >= os_data.os_data.monterey else {}), }, }, }, @@ -85,7 +98,7 @@ def SystemPatchDictionary(os): "GeForceTeslaVADriver.bundle": "10.13.6", "NVDANV50HalTesla.kext": "10.13.6", "NVDAResmanTesla.kext": "10.13.6", - **({ "NVDAStartup.kext": "12.0 Beta 6" } if os >= os_data.os_data.monterey else {}) + **({ "NVDAStartup.kext": "12.0 Beta 6" } if os_major >= os_data.os_data.monterey else {}) }, }, }, @@ -104,6 +117,29 @@ def SystemPatchDictionary(os): }, }, }, + "Nvidia Web Drivers": { + "Install": { + "/System/Library/Extensions": { + "NVDAStartupWeb.kext": "10.13.6", + "GeForceTeslaWeb.kext": "10.13.6", + "GeForceWeb.kext": "10.13.6", + "NVDAGF100HalWeb.kext": "10.13.6", + "NVDAGK100HalWeb.kext": "10.13.6", + "NVDAGM100HalWeb.kext": "10.13.6", + "NVDAGP100HalWeb.kext": "10.13.6", + "NVDANV50HalTeslaWeb.kext": "10.13.6", + "NVDAResmanTeslaWeb.kext": "10.13.6", + "NVDAResmanWeb.kext": "10.13.6", + "GeForceVADriverWeb.bundle": "10.13.6", + "GeForceAIRPluginWeb.bundle": "10.13.6", + "GeForceGLDriverWeb.bundle": "10.13.6", + "GeForceMTLDriverWeb.bundle": "10.13.6", + "GeForceTeslaGAWeb.bundle": "10.13.6", + "GeForceTeslaGLDriverWeb.bundle": "10.13.6", + "GeForceTeslaVADriverWeb.bundle": "10.13.6", + }, + }, + }, "AMD TeraScale 1": { "Install": { "/System/Library/Extensions": { @@ -152,11 +188,11 @@ def SystemPatchDictionary(os): }, "/System/Library/Frameworks": { "OpenCL.framework": "10.13.6", - "IOSurface.framework": f"10.14.6-{os}", + "IOSurface.framework": f"10.14.6-{os_major}", }, "/System/Library/PrivateFrameworks": { "GPUSupport.framework": "10.13.6", - "IOAccelerator.framework": f"10.13.6-{os}", + "IOAccelerator.framework": f"10.13.6-{os_major}", }, }, "Remove": { @@ -250,8 +286,8 @@ def SystemPatchDictionary(os): }, "Install Non-Root": { "/Library/Application Support/SkyLightPlugins": { - **({ "CoreWLAN.dylib": "SkyLightPlugins" } if os >= os_data.os_data.monterey else {}), - **({ "CoreWLAN.txt": "SkyLightPlugins" } if os >= os_data.os_data.monterey else {}), + **({ "CoreWLAN.dylib": "SkyLightPlugins" } if os_major >= os_data.os_data.monterey else {}), + **({ "CoreWLAN.txt": "SkyLightPlugins" } if os_major >= os_data.os_data.monterey else {}), }, }, }, diff --git a/gui/gui_main.py b/gui/gui_main.py index 6ac81056f..865119407 100644 --- a/gui/gui_main.py +++ b/gui/gui_main.py @@ -899,7 +899,7 @@ class wx_python_gui: # Download resources sys.stdout=menu_redirect.RedirectLabel(self.developer_note) - download_result, os_ver, link = sys_patch_download.grab_patcher_support_pkg(self.constants).download_files() + download_result, link = sys_patch_download.grab_patcher_support_pkg(self.constants).download_files() sys.stdout=sys.__stdout__ if download_result is None: diff --git a/resources/cli_menu.py b/resources/cli_menu.py index d0b6c26c5..136bc2866 100644 --- a/resources/cli_menu.py +++ b/resources/cli_menu.py @@ -3,7 +3,7 @@ import sys import subprocess -from resources import constants, install, utilities, defaults, sys_patch, installer +from resources import constants, install, utilities, defaults, sys_patch, installer, tui_helpers from data import cpu_data, smbios_data, model_array, os_data, mirror_data @@ -1014,7 +1014,7 @@ AssetCache. self.set_cc_support() def credits(self): - utilities.TUIOnlyPrint( + tui_helpers.TUIOnlyPrint( ["Credits"], "Press [Enter] to go back.\n", [ @@ -1085,7 +1085,7 @@ system_profiler SPHardwareDataType | grep 'Model Identifier' response = None while not (response and response == -1): title = ["Adjust Advanced Patcher Settings, for developers ONLY"] - menu = utilities.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) + menu = tui_helpers.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) options = [ [f"Set Metal GPU Status:\t\tCurrently {self.constants.imac_vendor}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).change_metal], [f"Set DRM Preferences:\t\tCurrently {self.constants.drm_support}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).drm_setting], @@ -1105,7 +1105,7 @@ system_profiler SPHardwareDataType | grep 'Model Identifier' response = None while not (response and response == -1): title = ["Adjust Patcher Settings"] - menu = utilities.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) + menu = tui_helpers.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) options = [ ["Debug Settings", self.patcher_setting_debug], ["Security Settings", self.patcher_settings_security], @@ -1129,7 +1129,7 @@ system_profiler SPHardwareDataType | grep 'Model Identifier' response = None while not (response and response == -1): title = ["Adjust Debug Settings"] - menu = utilities.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) + menu = tui_helpers.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) options = [ [f"Enable Verbose Mode:\tCurrently {self.constants.verbose_debug}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).change_verbose], [f"Enable OpenCore DEBUG:\tCurrently {self.constants.opencore_debug}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).change_oc], @@ -1149,7 +1149,7 @@ system_profiler SPHardwareDataType | grep 'Model Identifier' response = None while not (response and response == -1): title = ["Adjust Security Settings"] - menu = utilities.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) + menu = tui_helpers.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) options = [ # [ # f"Set Apple Mobile File Integrity (AMFI):\tCurrently {self.constants.amfi_status}", @@ -1175,7 +1175,7 @@ system_profiler SPHardwareDataType | grep 'Model Identifier' response = None while not (response and response == -1): title = ["Adjust SMBIOS Settings"] - menu = utilities.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) + menu = tui_helpers.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) options = [ [f"Set SMBIOS Spoof Level:\tCurrently {self.constants.serial_settings}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).change_serial], [f"Set SMBIOS Spoof Model:\tCurrently {self.constants.override_smbios}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).set_smbios], @@ -1192,7 +1192,7 @@ system_profiler SPHardwareDataType | grep 'Model Identifier' response = None while not (response and response == -1): title = ["Adjust Bootable Volume Settings"] - menu = utilities.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) + menu = tui_helpers.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) options = [ [f"Set FireWire Boot:\t\tCurrently {self.constants.firewire_boot}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).allow_firewire], [f"Set XHCI Boot:\t\tCurrently {self.constants.xhci_boot}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).allow_xhci], @@ -1209,7 +1209,7 @@ system_profiler SPHardwareDataType | grep 'Model Identifier' response = None while not (response and response == -1): title = ["Adjust Miscellaneous Settings"] - menu = utilities.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) + menu = tui_helpers.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) options = [ [f"Set ShowPicker Mode:\tCurrently {self.constants.showpicker}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).change_showpicker], [f"Set Wake on WLAN:\t\tCurrently {self.constants.enable_wake_on_wlan}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).allow_wowl], @@ -1246,7 +1246,7 @@ system_profiler SPHardwareDataType | grep 'Model Identifier' response = None while not (response and response == -1): title = ["Adjust Advanced Patcher Settings, for developers ONLY"] - menu = utilities.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) + menu = tui_helpers.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) options = [ [f"Set Metal GPU Status:\t\tCurrently {self.constants.imac_vendor}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).change_metal], [f"Set DRM Preferences:\t\tCurrently {self.constants.drm_support}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).drm_setting], @@ -1301,7 +1301,7 @@ B. Exit while not (response and response == -1): options = [] title = ["Select the macOS Installer you wish to download"] - menu = utilities.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) + menu = tui_helpers.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) available_installers = installer.list_downloadable_macOS_installers(self.constants.payload_path, "DeveloperSeed") if available_installers: # Add mirror of 11.2.3 for users who want it @@ -1321,7 +1321,7 @@ B. Exit while not (response and response == -1): options = [] title = ["Select the macOS Installer you wish to use"] - menu = utilities.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) + menu = tui_helpers.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) available_installers = installer.list_local_macOS_installers() if available_installers: for app in available_installers: diff --git a/resources/install.py b/resources/install.py index 1d07a81db..3adcf789a 100644 --- a/resources/install.py +++ b/resources/install.py @@ -7,7 +7,7 @@ import subprocess import shutil import os from pathlib import Path -from resources import utilities, constants +from resources import utilities, constants, tui_helpers from data import os_data class tui_disk_installation: @@ -79,7 +79,7 @@ class tui_disk_installation: utilities.header(["Installing OpenCore to Drive"]) if not self.constants.opencore_release_folder.exists(): - utilities.TUIOnlyPrint( + tui_helpers.TUIOnlyPrint( ["Installing OpenCore to Drive"], "Press [Enter] to go back.\n", [ @@ -92,7 +92,7 @@ Please build OpenCore first!""" print("\nDisk picker is loading...") all_disks = self.list_disks() - menu = utilities.TUIMenu( + menu = tui_helpers.TUIMenu( ["Select Disk"], "Please select the disk you would like to install OpenCore to: ", in_between=["Missing disks? Ensure they have an EFI or FAT32 partition."], @@ -110,7 +110,7 @@ Please build OpenCore first!""" disk_identifier = "disk" + response selected_disk = all_disks[disk_identifier] - menu = utilities.TUIMenu( + menu = tui_helpers.TUIMenu( ["Select Partition"], "Please select the partition you would like to install OpenCore to: ", return_number_instead_of_direct_call=True, @@ -169,7 +169,7 @@ Please build OpenCore first!""" return else: if self.constants.gui_mode is False: - utilities.TUIOnlyPrint( + tui_helpers.TUIOnlyPrint( ["Copying OpenCore"], "Press [Enter] to go back.\n", ["An error occurred!"] + result.stderr.decode().split("\n") + [""] ).start() else: @@ -252,7 +252,7 @@ Please build OpenCore first!""" input() else: if self.constants.gui_mode is False: - utilities.TUIOnlyPrint(["Copying OpenCore"], "Press [Enter] to go back.\n", ["EFI failed to mount!"]).start() + tui_helpers.TUIOnlyPrint(["Copying OpenCore"], "Press [Enter] to go back.\n", ["EFI failed to mount!"]).start() else: print("EFI failed to mount!") diff --git a/resources/installer.py b/resources/installer.py index 8da2e8f7c..fadaeb91d 100644 --- a/resources/installer.py +++ b/resources/installer.py @@ -3,7 +3,7 @@ from pathlib import Path import plistlib import subprocess import requests -from resources import utilities +from resources import utilities, tui_helpers def list_local_macOS_installers(): # Finds all applicable macOS installers @@ -264,7 +264,7 @@ def select_disk_to_format(): except KeyError: # Avoid crashing with CDs installed continue - menu = utilities.TUIMenu( + menu = tui_helpers.TUIMenu( ["Select Disk to write the macOS Installer onto"], "Please select the disk you would like to install OpenCore to: ", in_between=["Missing drives? Verify they are 14GB+ and external (ie. USB)", "", "Ensure all data is backed up on selected drive, entire drive will be erased!"], diff --git a/resources/main.py b/resources/main.py index 79c7599af..2a5362072 100644 --- a/resources/main.py +++ b/resources/main.py @@ -6,7 +6,7 @@ import subprocess import sys from pathlib import Path -from resources import build, cli_menu, constants, utilities, device_probe, os_probe, defaults, arguments, install +from resources import build, cli_menu, constants, utilities, device_probe, os_probe, defaults, arguments, install, tui_helpers from data import model_array class OpenCoreLegacyPatcher: @@ -79,7 +79,7 @@ class OpenCoreLegacyPatcher: else: in_between = ["This model is supported"] - menu = utilities.TUIMenu(title, "Please select an option: ", in_between=in_between, auto_number=True, top_level=True) + menu = tui_helpers.TUIMenu(title, "Please select an option: ", in_between=in_between, auto_number=True, top_level=True) options = ( [["Build OpenCore", build.BuildOpenCore(self.constants.custom_model or self.constants.computer.real_model, self.constants).build_opencore]] diff --git a/resources/sys_patch.py b/resources/sys_patch.py index c97591744..c076e87ba 100644 --- a/resources/sys_patch.py +++ b/resources/sys_patch.py @@ -5,10 +5,8 @@ # - Temporary Work-around: sudo bless --mount /System/Volumes/Update/mnt1 --bootefi --last-sealed-snapshot # - Work-around battery throttling on laptops with no battery (IOPlatformPluginFamily.kext/Contents/PlugIns/ACPI_SMC_PlatformPlugin.kext/Contents/Resources/) -import os import shutil import subprocess -import zipfile from pathlib import Path from resources import constants, generate_smbios, utilities, sys_patch_download, sys_patch_detect @@ -268,6 +266,7 @@ class PatchSysVolume: print(" - Adding Nvidia Tesla Graphics Patchset") required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]}) required_patches.update({"Nvidia Tesla": all_hardware_patchset["Graphics"]["Nvidia Tesla"]}) + required_patches.update({"Nvidia Web Drivers": all_hardware_patchset["Graphics"]["Nvidia Web Drivers"]}) if self.kepler_gpu is True: print(" - Adding Nvidia Kepler Graphics Patchset") required_patches.update({"Metal Common": all_hardware_patchset["Graphics"]["Metal Common"]}) @@ -304,34 +303,7 @@ class PatchSysVolume: def execute_patchset(self, required_patches): source_files_path = str(self.constants.payload_local_binaries_root_path) - print("- Running Preflight Checks before patching") - # Make sure old SkyLight plugins aren't being used - self.clean_skylight_plugins() - # Make sure SNB kexts are compatible with the host - if "Intel Sandy Bridge" in required_patches: - if self.computer.reported_board_id not in self.constants.sandy_board_id_stock: - print(f"- Found unspported Board ID {self.computer.reported_board_id}, performing AppleIntelSNBGraphicsFB bin patching") - board_to_patch = generate_smbios.determine_best_board_id_for_sandy(self.computer.reported_board_id, self.computer.gpus) - print(f"- Replacing {board_to_patch} with {self.computer.reported_board_id}") - - board_to_patch_hex = bytes.fromhex(board_to_patch.encode('utf-8').hex()) - reported_board_hex = bytes.fromhex(self.computer.reported_board_id.encode('utf-8').hex()) - - if len(board_to_patch_hex) != len(reported_board_hex): - print(f"- Error: Board ID {self.computer.reported_board_id} is not the same length as {board_to_patch}") - raise Exception("Host's Board ID is not the same length as the kext's Board ID, cannot patch!!!") - else: - path = source_files_path + "10.13.6/System/Library/Extensions/AppleIntelSNBGraphicsFB.kext/Contents/MacOS/AppleIntelSNBGraphicsFB" - if Path(path).exists: - with open(path, 'rb') as f: - data = f.read() - data = data.replace(board_to_patch_hex, reported_board_hex) - with open(path, 'wb') as f: - f.write(data) - else: - raise Exception("Failed to find AppleIntelSNBGraphicsFB.kext, cannot patch!!!") - - print("- Finished Preflight, starting patching") + self.preflight_checks(required_patches, source_files_path) for patch in required_patches: print("- Installing Patchset: " + patch) if "Remove" in required_patches[patch]: @@ -367,6 +339,55 @@ class PatchSysVolume: else: utilities.process_status(subprocess.run(process_array, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + def preflight_checks(self, required_patches, source_files_path): + print("- Running Preflight Checks before patching") + + # Make sure old SkyLight plugins aren't being used + self.clean_skylight_plugins() + + # Make sure SNB kexts are compatible with the host + if "Intel Sandy Bridge" in required_patches: + if self.computer.reported_board_id not in self.constants.sandy_board_id_stock: + print(f"- Found unspported Board ID {self.computer.reported_board_id}, performing AppleIntelSNBGraphicsFB bin patching") + board_to_patch = generate_smbios.determine_best_board_id_for_sandy(self.computer.reported_board_id, self.computer.gpus) + print(f"- Replacing {board_to_patch} with {self.computer.reported_board_id}") + + board_to_patch_hex = bytes.fromhex(board_to_patch.encode('utf-8').hex()) + reported_board_hex = bytes.fromhex(self.computer.reported_board_id.encode('utf-8').hex()) + + if len(board_to_patch_hex) != len(reported_board_hex): + print(f"- Error: Board ID {self.computer.reported_board_id} is not the same length as {board_to_patch}") + raise Exception("Host's Board ID is not the same length as the kext's Board ID, cannot patch!!!") + else: + path = source_files_path + "10.13.6/System/Library/Extensions/AppleIntelSNBGraphicsFB.kext/Contents/MacOS/AppleIntelSNBGraphicsFB" + if Path(path).exists: + with open(path, 'rb') as f: + data = f.read() + data = data.replace(board_to_patch_hex, reported_board_hex) + with open(path, 'wb') as f: + f.write(data) + else: + raise Exception("Failed to find AppleIntelSNBGraphicsFB.kext, cannot patch!!!") + + # Check all the files are present + for patch in required_patches: + if "Install" in required_patches[patch]: + for install_patch_directory in required_patches[patch]["Install"]: + for install_file in required_patches[patch]["Install"][install_patch_directory]: + source_file = source_files_path + "/" + required_patches[patch]['Install'][install_patch_directory][install_file] + install_patch_directory + "/" + install_file + if not Path(source_file).exists: + raise Exception(f"Failed to find {source_file}") + + if "Install Non-Root" in required_patches[patch]: + for install_patch_directory in required_patches[patch]["Install Non-Root"]: + print(f"- Handling Non-Root Installs in: {install_patch_directory}") + for install_file in required_patches[patch]["Install Non-Root"][install_patch_directory]: + source_file = source_files_path + "/" + required_patches[patch]['Install Non-Root'][install_patch_directory][install_file] + install_patch_directory + "/" + install_file + if not Path(source_file).exists: + raise Exception(f"Failed to find {source_file}") + + print("- Finished Preflight, starting patching") + def install_new_file(self, source_folder, destination_folder, file_name): # .frameworks are merged # .kexts and .apps are deleted and replaced @@ -423,22 +444,18 @@ class PatchSysVolume: def download_files(self): if self.constants.gui_mode is False or "Library/InstallerSandboxes/" in str(self.constants.payload_path): - download_result, os_ver, link = sys_patch_download.grab_patcher_support_pkg(self.constants).download_files() + download_result, link = sys_patch_download.grab_patcher_support_pkg(self.constants).download_files() else: download_result = True - os_ver, link = sys_patch_download.grab_patcher_support_pkg(self.constants).generate_pkg_link() + link = sys_patch_download.grab_patcher_support_pkg(self.constants).generate_pkg_link() if download_result and self.constants.payload_local_binaries_root_path_zip.exists(): print("- Unzipping binaries...") - try: - utilities.process_status(subprocess.run(["ditto", "-V", "-x", "-k", "--sequesterRsrc", "--rsrc", self.constants.payload_local_binaries_root_path_zip, self.constants.payload_path])) - print("- Renaming folder") - print("- Binaries downloaded to:") - print(self.constants.payload_path) - return self.constants.payload_local_binaries_root_path - except zipfile.BadZipFile: - print("- Couldn't unzip") - return None + utilities.process_status(subprocess.run(["ditto", "-V", "-x", "-k", "--sequesterRsrc", "--rsrc", self.constants.payload_local_binaries_root_path_zip, self.constants.payload_path])) + print("- Renaming folder") + print("- Binaries downloaded to:") + print(self.constants.payload_path) + return self.constants.payload_local_binaries_root_path else: if self.constants.gui_mode is True: print("- Download failed, please verify the below link work:") diff --git a/resources/sys_patch_download.py b/resources/sys_patch_download.py index 5e3189d18..23d1746c6 100644 --- a/resources/sys_patch_download.py +++ b/resources/sys_patch_download.py @@ -12,21 +12,11 @@ class grab_patcher_support_pkg: 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}/Universal-Binaries.zip" - return os_ver, link + return link def download_files(self): - os_ver, link = self.generate_pkg_link() + link = self.generate_pkg_link() if Path(self.constants.payload_local_binaries_root_path).exists(): print("- Removing old Apple Binaries folder") # Delete folder @@ -41,4 +31,4 @@ class grab_patcher_support_pkg: print(f"- No local version found, downloading...") download_result = utilities.download_file(link, self.constants.payload_local_binaries_root_path_zip) - return download_result, os_ver, link \ No newline at end of file + return download_result, link \ No newline at end of file diff --git a/resources/tui_helpers.py b/resources/tui_helpers.py new file mode 100644 index 000000000..92b24602a --- /dev/null +++ b/resources/tui_helpers.py @@ -0,0 +1,78 @@ +# Copyright (C) 2020-2022, Dhinak G, Mykola Grymaluk +from resources import utilities + +class TUIMenu: + def __init__(self, title, prompt, options=None, return_number_instead_of_direct_call=False, add_quit=True, auto_number=False, in_between=None, top_level=False, loop=False): + self.title = title + self.prompt = prompt + self.in_between = in_between or [] + self.options = options or [] + self.return_number_instead_of_direct_call = return_number_instead_of_direct_call + self.auto_number = auto_number + self.add_quit = add_quit + self.top_level = top_level + self.loop = loop + self.added_quit = False + + def add_menu_option(self, name, description="", function=None, key=""): + self.options.append([key, name, description, function]) + + def start(self): + return_option = ["Q", "Quit"] if self.top_level else ["B", "Back"] + if self.add_quit and not self.added_quit: + self.add_menu_option(return_option[1], function=None, key=return_option[0]) + self.added_quit = True + + while True: + utilities.cls() + utilities.header(self.title) + print() + + for i in self.in_between: + print(i) + if self.in_between: + print() + + for index, option in enumerate(self.options): + if self.auto_number and not (index == (len(self.options) - 1) and self.add_quit): + option[0] = str((index + 1)) + print(option[0] + ". " + option[1]) + for i in option[2]: + print("\t" + i) + + print() + selected = input(self.prompt) + + keys = [option[0].upper() for option in self.options] + if not selected or selected.upper() not in keys: + if self.loop: + continue + else: + return + if self.add_quit and selected.upper() == return_option[0]: + return -1 + elif self.return_number_instead_of_direct_call: + return self.options[keys.index(selected.upper())][0] + else: + self.options[keys.index(selected.upper())][3]() if self.options[keys.index(selected.upper())][3] else None + if not self.loop: + return + + +class TUIOnlyPrint: + def __init__(self, title, prompt, in_between=None): + self.title = title + self.prompt = prompt + self.in_between = in_between or [] + + def start(self): + utilities.cls() + utilities.header(self.title) + print() + + for i in self.in_between: + print(i) + if self.in_between: + print() + + return input(self.prompt) \ No newline at end of file diff --git a/resources/utilities.py b/resources/utilities.py index b33197b70..a126592d3 100644 --- a/resources/utilities.py +++ b/resources/utilities.py @@ -567,108 +567,3 @@ def check_cli_args(): return None else: return args - - -# def menu(title, prompt, menu_options, add_quit=True, auto_number=False, in_between=[], top_level=False): -# return_option = ["Q", "Quit", None] if top_level else ["B", "Back", None] -# if add_quit: menu_options.append(return_option) - -# cls() -# header(title) -# print() - -# for i in in_between: print(i) -# if in_between: print() - -# for index, option in enumerate(menu_options): -# if auto_number and not (index == (len(menu_options) - 1) and add_quit): -# option[0] = str((index + 1)) -# print(option[0] + ". " + option[1]) - -# print() -# selected = input(prompt) - -# keys = [option[0].upper() for option in menu_options] -# if not selected or selected.upper() not in keys: -# return -# if selected.upper() == return_option[0]: -# return -1 -# else: -# menu_options[keys.index(selected.upper())][2]() if menu_options[keys.index(selected.upper())][2] else None - - -class TUIMenu: - def __init__(self, title, prompt, options=None, return_number_instead_of_direct_call=False, add_quit=True, auto_number=False, in_between=None, top_level=False, loop=False): - self.title = title - self.prompt = prompt - self.in_between = in_between or [] - self.options = options or [] - self.return_number_instead_of_direct_call = return_number_instead_of_direct_call - self.auto_number = auto_number - self.add_quit = add_quit - self.top_level = top_level - self.loop = loop - self.added_quit = False - - def add_menu_option(self, name, description="", function=None, key=""): - self.options.append([key, name, description, function]) - - def start(self): - return_option = ["Q", "Quit"] if self.top_level else ["B", "Back"] - if self.add_quit and not self.added_quit: - self.add_menu_option(return_option[1], function=None, key=return_option[0]) - self.added_quit = True - - while True: - cls() - header(self.title) - print() - - for i in self.in_between: - print(i) - if self.in_between: - print() - - for index, option in enumerate(self.options): - if self.auto_number and not (index == (len(self.options) - 1) and self.add_quit): - option[0] = str((index + 1)) - print(option[0] + ". " + option[1]) - for i in option[2]: - print("\t" + i) - - print() - selected = input(self.prompt) - - keys = [option[0].upper() for option in self.options] - if not selected or selected.upper() not in keys: - if self.loop: - continue - else: - return - if self.add_quit and selected.upper() == return_option[0]: - return -1 - elif self.return_number_instead_of_direct_call: - return self.options[keys.index(selected.upper())][0] - else: - self.options[keys.index(selected.upper())][3]() if self.options[keys.index(selected.upper())][3] else None - if not self.loop: - return - - -class TUIOnlyPrint: - def __init__(self, title, prompt, in_between=None): - self.title = title - self.prompt = prompt - self.in_between = in_between or [] - - def start(self): - cls() - header(self.title) - print() - - for i in self.in_between: - print(i) - if self.in_between: - print() - - return input(self.prompt) From c23e39199034506be0e6855b0006dcdc916ec2f4 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Mon, 2 May 2022 22:14:31 -0600 Subject: [PATCH 08/14] sys_patch.py: Fix indentation --- resources/sys_patch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/sys_patch.py b/resources/sys_patch.py index c076e87ba..a5b19b7a8 100644 --- a/resources/sys_patch.py +++ b/resources/sys_patch.py @@ -370,7 +370,7 @@ class PatchSysVolume: raise Exception("Failed to find AppleIntelSNBGraphicsFB.kext, cannot patch!!!") # Check all the files are present - for patch in required_patches: + for patch in required_patches: if "Install" in required_patches[patch]: for install_patch_directory in required_patches[patch]["Install"]: for install_file in required_patches[patch]["Install"][install_patch_directory]: From 35031d8fa256ea31471ae6548b7dc8cafaed1f03 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Tue, 3 May 2022 20:12:41 -0600 Subject: [PATCH 09/14] sys_patch_dict.py: Deduplicate TS1/TS2 patch sets --- data/sys_patch_dict.py | 41 +++++++++++++++----------------- resources/sys_patch.py | 54 ++++++++++++++++++------------------------ 2 files changed, 42 insertions(+), 53 deletions(-) diff --git a/data/sys_patch_dict.py b/data/sys_patch_dict.py index b484ae4aa..79669449a 100644 --- a/data/sys_patch_dict.py +++ b/data/sys_patch_dict.py @@ -9,7 +9,7 @@ # - Processes: Additional processes to run - Array of strings # File Storage is based off the origin, ie. '10.13.6/System/Library/Extensions/IOSurface.kext' -# Stubbed binaries are OS specific, this use the 'os' variable to denounce which folder to use +# Stubbed binaries are OS specific, this use the 'os_major' variable to denounce which folder to use from data import os_data @@ -140,23 +140,14 @@ def SystemPatchDictionary(os_major): }, }, }, - "AMD TeraScale 1": { + "AMD Non-Metal Common": { "Install": { "/System/Library/Extensions": { - "AMD2400Controller.kext": "10.13.6", - "AMD2600Controller.kext": "10.13.6", - "AMD3800Controller.kext": "10.13.6", - "AMD4600Controller.kext": "10.13.6", - "AMD4800Controller.kext": "10.13.6", "AMDFramebuffer.kext": "10.13.6", "AMDLegacyFramebuffer.kext": "10.13.6", "AMDLegacySupport.kext": "10.13.6", "AMDShared.bundle": "10.13.6", "AMDSupport.kext": "10.13.6", - "ATIRadeonX2000.kext": "10.13.6", - "ATIRadeonX2000GA.plugin": "10.13.6", - "ATIRadeonX2000GLDriver.bundle": "10.13.6", - "ATIRadeonX2000VADriver.bundle": "10.13.6", }, }, "Remove": { @@ -169,20 +160,31 @@ def SystemPatchDictionary(os_major): ], }, }, + + "AMD TeraScale 1": { + "Install": { + "/System/Library/Extensions": { + "AMD2400Controller.kext": "10.13.6", + "AMD2600Controller.kext": "10.13.6", + "AMD3800Controller.kext": "10.13.6", + "AMD4600Controller.kext": "10.13.6", + "AMD4800Controller.kext": "10.13.6", + "ATIRadeonX2000.kext": "10.13.6", + "ATIRadeonX2000GA.plugin": "10.13.6", + "ATIRadeonX2000GLDriver.bundle": "10.13.6", + "ATIRadeonX2000VADriver.bundle": "10.13.6", + }, + }, + }, "AMD TeraScale 2": { "Install": { "/System/Library/Extensions": { "AMD5000Controller.kext": "10.13.6", "AMD6000Controller.kext": "10.13.6", - "AMDFramebuffer.kext": "10.13.6", - "AMDLegacyFramebuffer.kext": "10.13.6", - "AMDLegacySupport.kext": "10.13.6", "AMDRadeonVADriver.bundle": "10.13.6", "AMDRadeonVADriver2.bundle": "10.13.6", "AMDRadeonX3000.kext": "10.13.6", "AMDRadeonX3000GLDriver.bundle": "10.13.6", - "AMDShared.bundle": "10.13.6", - "AMDSupport.kext": "10.13.6", "IOAcceleratorFamily2.kext": "10.13.6", "IOSurface.kext": "10.14.6", }, @@ -197,12 +199,7 @@ def SystemPatchDictionary(os_major): }, "Remove": { "/System/Library/Extensions": { - "AppleCameraInterface.kext", # Specific to IOAccelerator downgrade - "AMD7000Controller.kext", - "AMD8000Controller.kext", - "AMD9000Controller.kext", - "AMD9500Controller.kext", - "AMD10000Controller.kext", + "AppleCameraInterface.kext", }, }, }, diff --git a/resources/sys_patch.py b/resources/sys_patch.py index a5b19b7a8..dd582e8f4 100644 --- a/resources/sys_patch.py +++ b/resources/sys_patch.py @@ -274,10 +274,12 @@ class PatchSysVolume: if self.amd_ts1 is True: print(" - Adding AMD TeraScale 1 Graphics Patchset") required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]}) + required_patches.update({"AMD Non-Metal Common": all_hardware_patchset["Graphics"]["AMD Non-Metal Common"]}) required_patches.update({"AMD TeraScale 1": all_hardware_patchset["Graphics"]["AMD TeraScale 1"]}) if self.amd_ts2 is True: print(" - Adding AMD TeraScale 2 Graphics Patchset") required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]}) + required_patches.update({"AMD Non-Metal Common": all_hardware_patchset["Graphics"]["AMD Non-Metal Common"]}) required_patches.update({"AMD TeraScale 2": all_hardware_patchset["Graphics"]["AMD TeraScale 2"]}) if self.brightness_legacy is True: print(" - Adding Legacy Brightness Patchset") @@ -313,21 +315,18 @@ class PatchSysVolume: destination_folder_path = str(self.mount_location) + remove_patch_directory self.remove_file(destination_folder_path, remove_patch_file) - if "Install" in required_patches[patch]: - for install_patch_directory in required_patches[patch]["Install"]: - print(f"- Handling Installs in: {install_patch_directory}") - for install_file in required_patches[patch]["Install"][install_patch_directory]: - source_folder_path = source_files_path + "/" + required_patches[patch]['Install'][install_patch_directory][install_file] + install_patch_directory - destination_folder_path = str(self.mount_location) + install_patch_directory - self.install_new_file(source_folder_path, destination_folder_path, install_file) - - if "Install Non-Root" in required_patches[patch]: - for install_patch_directory in required_patches[patch]["Install Non-Root"]: - print(f"- Handling Non-Root Installs in: {install_patch_directory}") - for install_file in required_patches[patch]["Install Non-Root"][install_patch_directory]: - source_folder_path = source_files_path + "/" + required_patches[patch]['Install Non-Root'][install_patch_directory][install_file] + install_patch_directory - destination_folder_path = str(self.mount_location_data) + install_patch_directory - self.install_new_file(source_folder_path, destination_folder_path, install_file) + + for method_install in ["Install", "Install Non-Root"]: + if method_install in required_patches[patch]: + for install_patch_directory in required_patches[patch][method_install]: + print(f"- Handling Installs in: {install_patch_directory}") + for install_file in required_patches[patch][method_install][install_patch_directory]: + source_folder_path = source_files_path + "/" + required_patches[patch][method_install][install_patch_directory][install_file] + install_patch_directory + if method_install == "Install": + destination_folder_path = str(self.mount_location) + install_patch_directory + else: + destination_folder_path = str(self.mount_location_data) + install_patch_directory + self.install_new_file(source_folder_path, destination_folder_path, install_file) if "Processes" in required_patches[patch]: for process in required_patches[patch]["Processes"]: @@ -370,22 +369,15 @@ class PatchSysVolume: raise Exception("Failed to find AppleIntelSNBGraphicsFB.kext, cannot patch!!!") # Check all the files are present - for patch in required_patches: - if "Install" in required_patches[patch]: - for install_patch_directory in required_patches[patch]["Install"]: - for install_file in required_patches[patch]["Install"][install_patch_directory]: - source_file = source_files_path + "/" + required_patches[patch]['Install'][install_patch_directory][install_file] + install_patch_directory + "/" + install_file - if not Path(source_file).exists: - raise Exception(f"Failed to find {source_file}") - - if "Install Non-Root" in required_patches[patch]: - for install_patch_directory in required_patches[patch]["Install Non-Root"]: - print(f"- Handling Non-Root Installs in: {install_patch_directory}") - for install_file in required_patches[patch]["Install Non-Root"][install_patch_directory]: - source_file = source_files_path + "/" + required_patches[patch]['Install Non-Root'][install_patch_directory][install_file] + install_patch_directory + "/" + install_file - if not Path(source_file).exists: - raise Exception(f"Failed to find {source_file}") - + for patch in required_patches: + for method_type in ["Install", "Install Non-Root"]: + if method_type in required_patches[patch]: + for install_patch_directory in required_patches[patch][method_type]: + for install_file in required_patches[patch][method_type][install_patch_directory]: + source_file = source_files_path + "/" + required_patches[patch][method_type][install_patch_directory][install_file] + install_patch_directory + "/" + install_file + if not Path(source_file).exists: + raise Exception(f"Failed to find {source_file}") + print("- Finished Preflight, starting patching") def install_new_file(self, source_folder, destination_folder, file_name): From 776be570fa8181dd6d57875c2a85945b044e0cdb Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Tue, 3 May 2022 21:30:50 -0600 Subject: [PATCH 10/14] Remove more duplicate functions --- resources/sys_patch.py | 152 ++++------------------------------ resources/sys_patch_detect.py | 68 ++++++++++++++- 2 files changed, 79 insertions(+), 141 deletions(-) diff --git a/resources/sys_patch.py b/resources/sys_patch.py index dd582e8f4..367c2236d 100644 --- a/resources/sys_patch.py +++ b/resources/sys_patch.py @@ -21,28 +21,15 @@ class PatchSysVolume: self.root_mount_path = None self.root_supports_snapshot = utilities.check_if_root_is_apfs_snapshot() self.constants.root_patcher_succeded = False # Reset Variable each time we start + self.patch_set_dictionary = {} # GUI will detect hardware patches before starting PatchSysVolume() # However the TUI will not, so allow for data to be passed in manually avoiding multiple calls if hardware_details is None: hardware_details = sys_patch_detect.detect_root_patch(self.computer.real_model, self.constants).detect_patch_set() - self.init_hardware_patches(hardware_details) + self.hardware_details = hardware_details self.init_pathing(custom_root_mount_path=None, custom_data_mount_path=None) - def init_hardware_patches(self, hardware_details): - self.nvidia_legacy = hardware_details["Graphics: Nvidia Tesla"] - self.kepler_gpu = hardware_details["Graphics: Nvidia Kepler"] - self.amd_ts1 = hardware_details["Graphics: AMD TeraScale 1"] - self.amd_ts2 = hardware_details["Graphics: AMD TeraScale 2"] - self.iron_gpu = hardware_details["Graphics: Intel Ironlake"] - self.sandy_gpu = hardware_details["Graphics: Intel Sandy Bridge"] - self.ivy_gpu = hardware_details["Graphics: Intel Ivy Bridge"] - self.brightness_legacy = hardware_details["Brightness: Legacy Backlight Control"] - self.legacy_audio = hardware_details["Audio: Legacy Realtek"] - self.legacy_wifi = hardware_details["Networking: Legacy Wireless"] - self.legacy_gmux = hardware_details["Miscellaneous: Legacy GMUX"] - self.legacy_keyboard_backlight = hardware_details["Miscellaneous: Legacy Keyboard Backlight"] - def init_pathing(self, custom_root_mount_path=None, custom_data_mount_path=None): if custom_root_mount_path and custom_data_mount_path: self.mount_location = custom_root_mount_path @@ -129,16 +116,14 @@ class PatchSysVolume: # - will return 31 on 'No binaries or codeless kexts were provided' # - will return -10 if the volume is missing (ie. unmounted by another process) if result.returncode != 0 or (self.constants.detected_os < os_data.os_data.catalina and "KernelCache ID" not in result.stdout.decode()): - self.success_status = False print("- Unable to build new kernel cache") - print(f"\nReason for Patch Failure({result.returncode}):") + print(f"\nReason for Patch Failure ({result.returncode}):") print(result.stdout.decode()) print("") print("\nPlease reboot the machine to avoid potential issues rerunning the patcher") if self.constants.gui_mode is False: input("Press [ENTER] to continue") else: - self.success_status = True print("- Successfully built new kernel cache") if self.root_supports_snapshot is True: print("- Creating new APFS snapshot") @@ -154,13 +139,6 @@ class PatchSysVolume: return else: self.unmount_drive() - else: - if self.constants.detected_os == os_data.os_data.catalina: - print("- Merging kernel cache") - utilities.process_status(utilities.elevated(["kcditto"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - if self.constants.detected_os in [os_data.os_data.mojave, os_data.os_data.catalina]: - print("- Merging dyld cache") - utilities.process_status(utilities.elevated(["update_dyld_shared_cache", "-root", f"{self.mount_location}/"])) print("- Patching complete") print("\nPlease reboot the machine for patches to take effect") self.constants.root_patcher_succeded = True @@ -236,73 +214,16 @@ class PatchSysVolume: def patch_root_vol(self): print(f"- Running patches for {self.model}") - - self.execute_patchset(self.generate_patchset()) + if self.patch_set_dictionary != {}: + self.execute_patchset(self.patch_set_dictionary) + else: + self.execute_patchset(sys_patch_detect.detect_root_patch(self.computer.real_model, self.constants).generate_patchset(self.hardware_details)) if self.constants.wxpython_variant is True and self.constants.detected_os >= os_data.os_data.big_sur: self.install_auto_patcher_launch_agent() self.rebuild_snapshot() - def generate_patchset(self): - all_hardware_patchset = sys_patch_dict.SystemPatchDictionary(self.constants.detected_os) - required_patches = {} - - print("- Creating Patch Set for Booted Hardware:") - if self.iron_gpu is True: - print(" - Adding Intel Ironlake Graphics Patchset") - required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]}) - required_patches.update({"Intel Ironlake": all_hardware_patchset["Graphics"]["Intel Ironlake"]}) - if self.sandy_gpu is True: - print(" - Adding Intel Sandy Bridge Graphics Patchset") - required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]}) - required_patches.update({"Legacy GVA": all_hardware_patchset["Graphics"]["Legacy GVA"]}) - required_patches.update({"Intel Sandy Bridge": all_hardware_patchset["Graphics"]["Intel Sandy Bridge"]}) - if self.ivy_gpu is True: - print(" - Adding Intel Ivy Bridge Graphics Patchset") - required_patches.update({"Metal Common": all_hardware_patchset["Graphics"]["Metal Common"]}) - required_patches.update({"Intel Ivy Bridge": all_hardware_patchset["Graphics"]["Intel Ivy Bridge"]}) - if self.nvidia_legacy is True: - print(" - Adding Nvidia Tesla Graphics Patchset") - required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]}) - required_patches.update({"Nvidia Tesla": all_hardware_patchset["Graphics"]["Nvidia Tesla"]}) - required_patches.update({"Nvidia Web Drivers": all_hardware_patchset["Graphics"]["Nvidia Web Drivers"]}) - if self.kepler_gpu is True: - print(" - Adding Nvidia Kepler Graphics Patchset") - required_patches.update({"Metal Common": all_hardware_patchset["Graphics"]["Metal Common"]}) - required_patches.update({"Nvidia Kepler": all_hardware_patchset["Graphics"]["Nvidia Kepler"]}) - if self.amd_ts1 is True: - print(" - Adding AMD TeraScale 1 Graphics Patchset") - required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]}) - required_patches.update({"AMD Non-Metal Common": all_hardware_patchset["Graphics"]["AMD Non-Metal Common"]}) - required_patches.update({"AMD TeraScale 1": all_hardware_patchset["Graphics"]["AMD TeraScale 1"]}) - if self.amd_ts2 is True: - print(" - Adding AMD TeraScale 2 Graphics Patchset") - required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]}) - required_patches.update({"AMD Non-Metal Common": all_hardware_patchset["Graphics"]["AMD Non-Metal Common"]}) - required_patches.update({"AMD TeraScale 2": all_hardware_patchset["Graphics"]["AMD TeraScale 2"]}) - if self.brightness_legacy is True: - print(" - Adding Legacy Brightness Patchset") - required_patches.update({"Legacy Brightness": all_hardware_patchset["Brightness"]["Legacy Brightness"]}) - if self.legacy_audio is True: - print(" - Adding Legacy Audio Patchset") - if self.model in ["iMac7,1", "iMac8,1"]: - required_patches.update({"Legacy Realtek": all_hardware_patchset["Audio"]["Legacy Realtek"]}) - else: - required_patches.update({"Legacy Non-GOP": all_hardware_patchset["Audio"]["Legacy Non-GOP"]}) - if self.legacy_wifi is True: - print(" - Adding Legacy WiFi Patchset") - required_patches.update({"Legacy WiFi": all_hardware_patchset["Networking"]["Legacy WiFi"]}) - if self.legacy_gmux is True: - print(" - Adding Legacy GMUX Patchset") - required_patches.update({"Legacy GMUX": all_hardware_patchset["Miscellaneous"]["Legacy GMUX"]}) - if self.legacy_keyboard_backlight: - print(" - Adding Legacy Keyboard Backlight Patchset") - required_patches.update({"Legacy Keyboard Backlight": all_hardware_patchset["Miscellaneous"]["Legacy Keyboard Backlight"]}) - - return required_patches - - def execute_patchset(self, required_patches): source_files_path = str(self.constants.payload_local_binaries_root_path) self.preflight_checks(required_patches, source_files_path) @@ -389,14 +310,14 @@ class PatchSysVolume: print(f" - Found existing {file_name}, overwritting...") utilities.process_status(utilities.elevated(["rm", "-R", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) else: - print(" - Installing: " + file_name) + print(f" - Installing: {file_name}") utilities.process_status(utilities.elevated(["cp", "-R", f"{source_folder}/{file_name}", destination_folder], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) utilities.process_status(utilities.elevated(["chmod", "-Rf", "755", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) utilities.process_status(utilities.elevated(["chown", "-Rf", "root:wheel", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) elif file_name_str.endswith(".framework"): # merge with rsync - print(" - Installing: " + file_name) + print(f" - Installing: {file_name}") utilities.elevated(["rsync", "-r", "-i", "-a", f"{source_folder}/{file_name}", f"{destination_folder}/"], stdout=subprocess.PIPE) utilities.process_status(utilities.elevated(["chmod", "-Rf", "755", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) utilities.process_status(utilities.elevated(["chown", "-Rf", "root:wheel", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) @@ -406,14 +327,14 @@ class PatchSysVolume: print(f" - Found existing {file_name}, overwritting...") utilities.process_status(utilities.elevated(["rm", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) else: - print(" - Installing: " + file_name) + print(f" - Installing: {file_name}") utilities.process_status(utilities.elevated(["cp", f"{source_folder}/{file_name}", destination_folder], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) utilities.process_status(utilities.elevated(["chmod", "755", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) utilities.process_status(utilities.elevated(["chown", "root:wheel", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) def remove_file(self, destination_folder, file_name): if Path(destination_folder + "/" + file_name).exists(): - print(" - Removing: " + file_name) + print(f" - Removing: {file_name}") if Path(destination_folder + "/" + file_name).is_dir(): utilities.process_status(utilities.elevated(["rm", "-R", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) else: @@ -444,7 +365,6 @@ class PatchSysVolume: if download_result and self.constants.payload_local_binaries_root_path_zip.exists(): print("- 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])) - print("- Renaming folder") print("- Binaries downloaded to:") print(self.constants.payload_path) return self.constants.payload_local_binaries_root_path @@ -458,57 +378,13 @@ class PatchSysVolume: input("\nPress enter to continue") return None - - def detect_patch_set(self): - utilities.cls() - print("The following patches will be applied:") - if self.nvidia_legacy is True: - print("- Add Legacy Nvidia Tesla Graphics Patch") - elif self.kepler_gpu is True: - print("- Add Legacy Nvidia Kepler Graphics Patch") - elif self.amd_ts1 is True: - print("- Add Legacy ATI TeraScale 1 Graphics Patch") - elif self.amd_ts2 is True: - print("- Add Legacy ATI TeraScale 2 Graphics Patch") - if self.iron_gpu is True: - print("- Add Legacy Intel IronLake Graphics Patch") - elif self.sandy_gpu is True: - print("- Add Legacy Intel Sandy Bridge Graphics Patch") - elif self.ivy_gpu is True: - print("- Add Legacy Intel Ivy Bridge Graphics Patch") - if self.brightness_legacy is True: - print("- Add Legacy Brightness Control") - if self.legacy_audio is True: - print("- Add legacy Audio Control") - if self.legacy_wifi is True: - print("- Add legacy WiFi Control") - if self.legacy_gmux is True: - print("- Add Legacy Mux Brightness Control") - if self.legacy_keyboard_backlight is True: - print("- Add Legacy Keyboard Backlight Control") - - self.no_patch = not any( - [ - self.nvidia_legacy, - self.kepler_gpu, - self.amd_ts1, - self.amd_ts2, - self.iron_gpu, - self.sandy_gpu, - self.ivy_gpu, - self.brightness_legacy, - self.legacy_audio, - self.legacy_wifi, - self.legacy_gmux, - ] - ) - # Entry Function def start_patch(self): print("- Starting Patch Process") print(f"- Determining Required Patch set for Darwin {self.constants.detected_os}") - self.detect_patch_set() - if self.no_patch is True: + self.patch_set_dictionary = sys_patch_detect.detect_root_patch(self.computer.real_model, self.constants).generate_patchset(self.hardware_details) + + if self.patch_set_dictionary == {}: change_menu = None print("- No Root Patches required for your machine!") if self.constants.gui_mode is False: diff --git a/resources/sys_patch_detect.py b/resources/sys_patch_detect.py index 0fecd8f6a..6cbd6ea3b 100644 --- a/resources/sys_patch_detect.py +++ b/resources/sys_patch_detect.py @@ -3,8 +3,8 @@ # Used when supplying data to sys_patch.py # Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk -from resources import constants, device_probe, utilities, generate_smbios -from data import model_array, os_data, sip_data +from resources import constants, device_probe, utilities +from data import model_array, os_data, sip_data, sys_patch_dict class detect_root_patch: def __init__(self, model, versions): @@ -217,4 +217,66 @@ class detect_root_patch: ): return False else: - return True \ No newline at end of file + return True + + def generate_patchset(self, hardware_details): + all_hardware_patchset = sys_patch_dict.SystemPatchDictionary(self.constants.detected_os) + required_patches = {} + utilities.cls() + print("- The following patches will be applied:") + if hardware_details["Graphics: Intel Ironlake"] is True: + print(" - Graphics: Intel Ironlake") + required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]}) + required_patches.update({"Intel Ironlake": all_hardware_patchset["Graphics"]["Intel Ironlake"]}) + if hardware_details["Graphics: Intel Sandy Bridge"] is True: + print(" - Graphics: Intel Sandy Bridge") + required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]}) + required_patches.update({"Legacy GVA": all_hardware_patchset["Graphics"]["Legacy GVA"]}) + required_patches.update({"Intel Sandy Bridge": all_hardware_patchset["Graphics"]["Intel Sandy Bridge"]}) + if hardware_details["Graphics: Intel Ivy Bridge"] is True: + print(" - Graphics: Intel Ivy Bridge") + required_patches.update({"Metal Common": all_hardware_patchset["Graphics"]["Metal Common"]}) + required_patches.update({"Intel Ivy Bridge": all_hardware_patchset["Graphics"]["Intel Ivy Bridge"]}) + if hardware_details["Graphics: Nvidia Tesla"] is True: + print(" - Graphics: Nvidia Tesla") + required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]}) + required_patches.update({"Nvidia Tesla": all_hardware_patchset["Graphics"]["Nvidia Tesla"]}) + required_patches.update({"Nvidia Web Drivers": all_hardware_patchset["Graphics"]["Nvidia Web Drivers"]}) + if hardware_details["Graphics: Nvidia Kepler"] is True: + print(" - Graphics: Nvidia Kepler") + required_patches.update({"Metal Common": all_hardware_patchset["Graphics"]["Metal Common"]}) + required_patches.update({"Nvidia Kepler": all_hardware_patchset["Graphics"]["Nvidia Kepler"]}) + if hardware_details["Graphics: AMD TeraScale 1"] is True: + print(" - Graphics: AMD TeraScale 1") + required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]}) + required_patches.update({"AMD Non-Metal Common": all_hardware_patchset["Graphics"]["AMD Non-Metal Common"]}) + required_patches.update({"AMD TeraScale 1": all_hardware_patchset["Graphics"]["AMD TeraScale 1"]}) + if hardware_details["Graphics: AMD TeraScale 2"] is True: + print(" - Graphics: AMD TeraScale 2") + required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]}) + required_patches.update({"AMD Non-Metal Common": all_hardware_patchset["Graphics"]["AMD Non-Metal Common"]}) + required_patches.update({"AMD TeraScale 2": all_hardware_patchset["Graphics"]["AMD TeraScale 2"]}) + if hardware_details["Brightness: Legacy Backlight Control"] is True: + print(" - Brightness: Legacy Brightness") + required_patches.update({"Legacy Brightness": all_hardware_patchset["Brightness"]["Legacy Brightness"]}) + if hardware_details["Audio: Legacy Realtek"] is True: + if self.model in ["iMac7,1", "iMac8,1"]: + print(" - Audio: Legacy Realtek Audio") + required_patches.update({"Legacy Realtek": all_hardware_patchset["Audio"]["Legacy Realtek"]}) + else: + print(" - Audio: Legacy non-GOP Audio") + required_patches.update({"Legacy Non-GOP": all_hardware_patchset["Audio"]["Legacy Non-GOP"]}) + if hardware_details["Networking: Legacy Wireless"] is True: + print(" - Networking: Legacy WiFi") + required_patches.update({"Legacy WiFi": all_hardware_patchset["Networking"]["Legacy WiFi"]}) + if hardware_details["Miscellaneous: Legacy GMUX"] is True: + print(" - Miscellaneous: Legacy GMUX") + required_patches.update({"Legacy GMUX": all_hardware_patchset["Miscellaneous"]["Legacy GMUX"]}) + if hardware_details["Miscellaneous: Legacy Keyboard Backlight"]: + print(" - Miscellaneous: Legacy Keyboard Backlight") + required_patches.update({"Legacy Keyboard Backlight": all_hardware_patchset["Miscellaneous"]["Legacy Keyboard Backlight"]}) + + if not required_patches: + print(" - No patch sets found for booted model") + + return required_patches \ No newline at end of file From 738d030e3a06edb2037276b44c484d824c4f5b4a Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Tue, 3 May 2022 22:07:56 -0600 Subject: [PATCH 11/14] sys_patch.py: Remove unused import --- resources/sys_patch.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/resources/sys_patch.py b/resources/sys_patch.py index 367c2236d..5798b422e 100644 --- a/resources/sys_patch.py +++ b/resources/sys_patch.py @@ -10,7 +10,7 @@ import subprocess from pathlib import Path from resources import constants, generate_smbios, utilities, sys_patch_download, sys_patch_detect -from data import os_data, sys_patch_dict +from data import os_data class PatchSysVolume: @@ -47,12 +47,6 @@ class PatchSysVolume: def find_mount_root_vol(self, patch): self.root_mount_path = utilities.get_disk_path() if self.root_mount_path.startswith("disk"): - if ( - self.constants.detected_os == os_data.os_data.catalina or - (self.constants.detected_os > os_data.os_data.catalina and self.root_supports_snapshot is False) - ): - print("- Mounting Dedicated Root Volume as writable") - utilities.elevated(["mount", "-uw", f"{self.mount_location}/"], stdout=subprocess.PIPE).stdout.decode().strip().encode() print(f"- Found Root Volume at: {self.root_mount_path}") if Path(self.mount_extensions).exists(): print("- Root Volume is already mounted") From 837bb692bf31f048e469efce1f6bde3f05a138fc Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Wed, 4 May 2022 11:30:38 -0600 Subject: [PATCH 12/14] sys_patch: Move launch_agent function --- resources/sys_patch.py | 96 ++++++++++--------------------------- resources/sys_patch_auto.py | 56 +++++++++++++++++++++- 2 files changed, 80 insertions(+), 72 deletions(-) diff --git a/resources/sys_patch.py b/resources/sys_patch.py index 5798b422e..69c899635 100644 --- a/resources/sys_patch.py +++ b/resources/sys_patch.py @@ -9,7 +9,7 @@ import shutil import subprocess from pathlib import Path -from resources import constants, generate_smbios, utilities, sys_patch_download, sys_patch_detect +from resources import constants, generate_smbios, utilities, sys_patch_download, sys_patch_detect, sys_patch_auto from data import os_data @@ -97,10 +97,7 @@ class PatchSysVolume: def rebuild_snapshot(self): print("- Rebuilding Kernel Cache (This may take some time)") - if self.constants.detected_os > os_data.os_data.catalina: - result = utilities.elevated(["kmutil", "install", "--volume-root", self.mount_location, "--update-all"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - else: - result = utilities.elevated(["kextcache", "-i", f"{self.mount_location}/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + result = utilities.elevated(["kmutil", "install", "--volume-root", self.mount_location, "--update-all"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) # kextcache notes: # - kextcache always returns 0, even if it fails @@ -109,7 +106,7 @@ class PatchSysVolume: # - will return 71 on failure to build KCs # - will return 31 on 'No binaries or codeless kexts were provided' # - will return -10 if the volume is missing (ie. unmounted by another process) - if result.returncode != 0 or (self.constants.detected_os < os_data.os_data.catalina and "KernelCache ID" not in result.stdout.decode()): + if result.returncode != 0: print("- Unable to build new kernel cache") print(f"\nReason for Patch Failure ({result.returncode}):") print(result.stdout.decode()) @@ -144,58 +141,6 @@ class PatchSysVolume: utilities.elevated(["diskutil", "unmount", self.root_mount_path], stdout=subprocess.PIPE).stdout.decode().strip().encode() - def install_auto_patcher_launch_agent(self): - # Installs the following: - # - OpenCore-Patcher.app in /Library/Application Support/Dortania/ - # - com.dortania.opencore-legacy-patcher.auto-patch.plist in /Library/LaunchAgents/ - if self.constants.launcher_script is None: - # Verify our binary isn't located in '/Library/Application Support/Dortania/' - # As we'd simply be duplicating ourselves - if not self.constants.launcher_binary.startswith("/Library/Application Support/Dortania/"): - print("- Installing Auto Patcher Launch Agent") - - if not Path("Library/Application Support/Dortania").exists(): - print("- Creating /Library/Application Support/Dortania/") - utilities.process_status(utilities.elevated(["mkdir", "-p", "/Library/Application Support/Dortania"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - - print("- Copying OpenCore Patcher to /Library/Application Support/Dortania/") - if Path("/Library/Application Support/Dortania/OpenCore-Patcher.app").exists(): - print("- Deleting existing OpenCore-Patcher") - utilities.process_status(utilities.elevated(["rm", "-R", "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - - # Strip everything after OpenCore-Patcher.app - path = str(self.constants.launcher_binary).split("/Contents/MacOS/OpenCore-Patcher")[0] - print(f"- Copying {path} to /Library/Application Support/Dortania/") - utilities.process_status(utilities.elevated(["cp", "-R", path, "/Library/Application Support/Dortania/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - - if not Path("/Library/Application Support/Dortania/OpenCore-Patcher.app").exists(): - # Sometimes the binary the user launches maye have a suffix (ie. OpenCore-Patcher 3.app) - # We'll want to rename it to OpenCore-Patcher.app - path = path.split("/")[-1] - print(f"- Renaming {path} to OpenCore-Patcher.app") - utilities.process_status(utilities.elevated(["mv", f"/Library/Application Support/Dortania/{path}", "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - - # Copy over our launch agent - print("- Copying auto-patch.plist Launch Agent to /Library/LaunchAgents/") - if Path("/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist").exists(): - print("- Deleting existing auto-patch.plist") - utilities.process_status(utilities.elevated(["rm", "/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - utilities.process_status(utilities.elevated(["cp", self.constants.auto_patch_launch_agent_path, "/Library/LaunchAgents/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - - # Set the permissions on the com.dortania.opencore-legacy-patcher.auto-patch.plist - print("- Setting permissions on auto-patch.plist") - utilities.process_status(utilities.elevated(["chmod", "644", "/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - utilities.process_status(utilities.elevated(["chown", "root:wheel", "/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - - # Making app alias - # Simply an easy way for users to notice the app - # If there's already an alias or exiting app, skip - if not Path("/Applications/OpenCore-Patcher.app").exists(): - print("- Making app alias") - utilities.process_status(utilities.elevated(["ln", "-s", "/Library/Application Support/Dortania/OpenCore-Patcher.app", "/Applications/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - else: - print("- Skipping Auto Patcher Launch Agent, not supported when running from source") - def clean_skylight_plugins(self): if (Path(self.mount_application_support) / Path("SkyLightPlugins/")).exists(): print("- Found SkylightPlugins folder, removing old plugins") @@ -214,7 +159,7 @@ class PatchSysVolume: self.execute_patchset(sys_patch_detect.detect_root_patch(self.computer.real_model, self.constants).generate_patchset(self.hardware_details)) if self.constants.wxpython_variant is True and self.constants.detected_os >= os_data.os_data.big_sur: - self.install_auto_patcher_launch_agent() + sys_patch_auto.AutomaticSysPatch.install_auto_patcher_launch_agent(self.constants) self.rebuild_snapshot() @@ -299,22 +244,21 @@ class PatchSysVolume: # .frameworks are merged # .kexts and .apps are deleted and replaced file_name_str = str(file_name) - if file_name_str.endswith(".kext") or file_name_str.endswith(".app") or file_name_str.endswith(".bundle") or file_name_str.endswith(".plugin"): + + if file_name_str.endswith(".framework"): + # merge with rsync + print(f" - Installing: {file_name}") + utilities.elevated(["rsync", "-r", "-i", "-a", f"{source_folder}/{file_name}", f"{destination_folder}/"], stdout=subprocess.PIPE) + self.fix_permissions(destination_folder + "/" + file_name) + elif Path(source_folder + "/" + file_name_str).is_dir(): + # Applicable for .kext, .app, .plugin, .bundle, all of which are directories if Path(destination_folder + "/" + file_name).exists(): print(f" - Found existing {file_name}, overwritting...") utilities.process_status(utilities.elevated(["rm", "-R", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) else: print(f" - Installing: {file_name}") utilities.process_status(utilities.elevated(["cp", "-R", f"{source_folder}/{file_name}", destination_folder], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - utilities.process_status(utilities.elevated(["chmod", "-Rf", "755", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - utilities.process_status(utilities.elevated(["chown", "-Rf", "root:wheel", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - - elif file_name_str.endswith(".framework"): - # merge with rsync - print(f" - Installing: {file_name}") - utilities.elevated(["rsync", "-r", "-i", "-a", f"{source_folder}/{file_name}", f"{destination_folder}/"], stdout=subprocess.PIPE) - utilities.process_status(utilities.elevated(["chmod", "-Rf", "755", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - utilities.process_status(utilities.elevated(["chown", "-Rf", "root:wheel", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + self.fix_permissions(destination_folder + "/" + file_name) else: # Assume it's an individual file, replace as normal if Path(destination_folder + "/" + file_name).exists(): @@ -323,8 +267,7 @@ class PatchSysVolume: else: print(f" - Installing: {file_name}") utilities.process_status(utilities.elevated(["cp", f"{source_folder}/{file_name}", destination_folder], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - utilities.process_status(utilities.elevated(["chmod", "755", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) - utilities.process_status(utilities.elevated(["chown", "root:wheel", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + self.fix_permissions(destination_folder + "/" + file_name) def remove_file(self, destination_folder, file_name): if Path(destination_folder + "/" + file_name).exists(): @@ -335,6 +278,17 @@ class PatchSysVolume: utilities.process_status(utilities.elevated(["rm", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + def fix_permissions(self, destination_file): + chmod_args = ["chmod", "-Rf", "755", destination_file] + chown_args = ["chown", "-Rf", "root:wheel", destination_file] + if not Path(destination_file).is_dir(): + # Strip recursive arguments + chmod_args.pop(1) + chown_args.pop(1) + utilities.process_status(utilities.elevated(chmod_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + utilities.process_status(utilities.elevated(chown_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + + def check_files(self): if Path(self.constants.payload_local_binaries_root_path).exists(): print("- Found local Apple Binaries") diff --git a/resources/sys_patch_auto.py b/resources/sys_patch_auto.py index 65bd532b2..84889d32a 100644 --- a/resources/sys_patch_auto.py +++ b/resources/sys_patch_auto.py @@ -8,6 +8,7 @@ # If all these tests pass, start Root Patcher # Copyright (C) 2022, Mykola Grymalyuk +from pathlib import Path import plistlib import subprocess import webbrowser @@ -162,4 +163,57 @@ class AutomaticSysPatch: print("- Unable to determine if boot disk is removable, skipping prompt") else: - print("- Failed to find disk OpenCore launched from") \ No newline at end of file + print("- Failed to find disk OpenCore launched from") + + + def install_auto_patcher_launch_agent(settings): + # Installs the following: + # - OpenCore-Patcher.app in /Library/Application Support/Dortania/ + # - com.dortania.opencore-legacy-patcher.auto-patch.plist in /Library/LaunchAgents/ + if settings.launcher_script is None: + # Verify our binary isn't located in '/Library/Application Support/Dortania/' + # As we'd simply be duplicating ourselves + if not settings.launcher_binary.startswith("/Library/Application Support/Dortania/"): + print("- Installing Auto Patcher Launch Agent") + + if not Path("Library/Application Support/Dortania").exists(): + print("- Creating /Library/Application Support/Dortania/") + utilities.process_status(utilities.elevated(["mkdir", "-p", "/Library/Application Support/Dortania"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + + print("- Copying OpenCore Patcher to /Library/Application Support/Dortania/") + if Path("/Library/Application Support/Dortania/OpenCore-Patcher.app").exists(): + print("- Deleting existing OpenCore-Patcher") + utilities.process_status(utilities.elevated(["rm", "-R", "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + + # Strip everything after OpenCore-Patcher.app + path = str(settings.launcher_binary).split("/Contents/MacOS/OpenCore-Patcher")[0] + print(f"- Copying {path} to /Library/Application Support/Dortania/") + utilities.process_status(utilities.elevated(["cp", "-R", path, "/Library/Application Support/Dortania/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + + if not Path("/Library/Application Support/Dortania/OpenCore-Patcher.app").exists(): + # Sometimes the binary the user launches maye have a suffix (ie. OpenCore-Patcher 3.app) + # We'll want to rename it to OpenCore-Patcher.app + path = path.split("/")[-1] + print(f"- Renaming {path} to OpenCore-Patcher.app") + utilities.process_status(utilities.elevated(["mv", f"/Library/Application Support/Dortania/{path}", "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + + # Copy over our launch agent + print("- Copying auto-patch.plist Launch Agent to /Library/LaunchAgents/") + if Path("/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist").exists(): + print("- Deleting existing auto-patch.plist") + utilities.process_status(utilities.elevated(["rm", "/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + utilities.process_status(utilities.elevated(["cp", settings.auto_patch_launch_agent_path, "/Library/LaunchAgents/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + + # Set the permissions on the com.dortania.opencore-legacy-patcher.auto-patch.plist + print("- Setting permissions on auto-patch.plist") + utilities.process_status(utilities.elevated(["chmod", "644", "/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + utilities.process_status(utilities.elevated(["chown", "root:wheel", "/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + + # Making app alias + # Simply an easy way for users to notice the app + # If there's already an alias or exiting app, skip + if not Path("/Applications/OpenCore-Patcher.app").exists(): + print("- Making app alias") + utilities.process_status(utilities.elevated(["ln", "-s", "/Library/Application Support/Dortania/OpenCore-Patcher.app", "/Applications/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) + else: + print("- Skipping Auto Patcher Launch Agent, not supported when running from source") \ No newline at end of file From 62291089fc03c5804d48a43d0545196208495659 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Wed, 4 May 2022 14:27:43 -0600 Subject: [PATCH 13/14] sys_patch.py: Add better documentation --- CHANGELOG.md | 1 + resources/sys_patch.py | 25 +++++++++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c2cb57a7..5688151ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # OpenCore Legacy Patcher changelog ## 0.4.5 +- Refactor Root Patching System ## 0.4.4 - Lower SIP requirement for Root Patching diff --git a/resources/sys_patch.py b/resources/sys_patch.py index 69c899635..94eebae2e 100644 --- a/resources/sys_patch.py +++ b/resources/sys_patch.py @@ -1,9 +1,26 @@ # Framework for mounting and patching macOS root volume # Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk -# Missing Features: -# - Full System/Library Snapshotting (need to research how Apple achieves this) -# - Temporary Work-around: sudo bless --mount /System/Volumes/Update/mnt1 --bootefi --last-sealed-snapshot -# - Work-around battery throttling on laptops with no battery (IOPlatformPluginFamily.kext/Contents/PlugIns/ACPI_SMC_PlatformPlugin.kext/Contents/Resources/) + +# System based off of Apple's Kernel Development Kit (KDK) +# - https://developer.apple.com/download/all/ + +# The system relies on mounting the APFS volume as a live read/write volume +# We perform our required edits, then create a new snapshot for the system boot + +# The manual process is as follows: +# 1. Mount the APFS volume as a read/write volume +# 'sudo mount -o nobrowse -t apfs /dev/disk5s5 /System/Volumes/Update/mnt1' +# 2. Perform edits to the system (ie. create new KernelCollection) +# 'sudo kmutil install --volume-root /System/Volumes/Update/mnt1/ --update-all' +# 3. Create a new snapshot for the system boot +# 'sudo bless --folder /System/Volumes/Update/mnt1/System/Library/CoreServices --bootefi --create-snapshot' + +# Additionally Apple's APFS snapshot system supports system rollbacks: +# 'sudo bless --mount /System/Volumes/Update/mnt1 --bootefi --last-sealed-snapshot' +# Note: root volume rollbacks are unstable in Big Sur due to quickly discarding the original snapshot +# - Generally within 2~ boots, the original snapshot is discarded +# - Monterey always preserves the original snapshot allowing for reliable rollbacks + import shutil import subprocess From f2a6d8c181b30e160c3686d341f5ead90888033a Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Wed, 4 May 2022 14:35:02 -0600 Subject: [PATCH 14/14] sys_patch_detect.py: Rename Tesla variable --- resources/sys_patch_detect.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/sys_patch_detect.py b/resources/sys_patch_detect.py index 6cbd6ea3b..54499e8f1 100644 --- a/resources/sys_patch_detect.py +++ b/resources/sys_patch_detect.py @@ -13,7 +13,7 @@ class detect_root_patch: self.computer = self.constants.computer # GPU Patch Detection - self.nvidia_legacy= False + self.nvidia_tesla= False self.kepler_gpu= False self.amd_ts1= False self.amd_ts2= False @@ -48,7 +48,7 @@ class detect_root_patch: print(f"- Found GPU ({i}): {utilities.friendly_hex(gpu.vendor_id)}:{utilities.friendly_hex(gpu.device_id)}") if gpu.arch in [device_probe.NVIDIA.Archs.Tesla, device_probe.NVIDIA.Archs.Fermi]: if self.constants.detected_os > non_metal_os: - self.nvidia_legacy = True + self.nvidia_tesla = True self.amfi_must_disable = True self.legacy_keyboard_backlight = self.check_legacy_keyboard_backlight() elif gpu.arch == device_probe.NVIDIA.Archs.Kepler: @@ -86,7 +86,7 @@ class detect_root_patch: if self.supports_metal is True: # Avoid patching Metal and non-Metal GPUs if both present, prioritize Metal GPU # Main concerns are for iMac12,x with Sandy iGPU and Kepler dGPU - self.nvidia_legacy = False + self.nvidia_tesla = False self.amd_ts1 = False self.amd_ts2 = False self.iron_gpu = False @@ -153,7 +153,7 @@ class detect_root_patch: self.legacy_gmux = True self.root_patch_dict = { - "Graphics: Nvidia Tesla": self.nvidia_legacy, + "Graphics: Nvidia Tesla": self.nvidia_tesla, "Graphics: Nvidia Kepler": self.kepler_gpu, "Graphics: AMD TeraScale 1": self.amd_ts1, "Graphics: AMD TeraScale 2": self.amd_ts2,