mirror of
https://github.com/dortania/OpenCore-Legacy-Patcher.git
synced 2026-04-15 13:18:56 +10:00
Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e494906f22 | ||
|
|
cdb40d8201 | ||
|
|
b42eb6e395 | ||
|
|
20bb0cd6d8 | ||
|
|
c6688ea922 | ||
|
|
0e490e5ae9 | ||
|
|
e58a671136 | ||
|
|
5d142fd19f | ||
|
|
f55598dac8 | ||
|
|
321cc8dd68 | ||
|
|
9070f5af8d | ||
|
|
a8c080042a | ||
|
|
5788e067b3 | ||
|
|
90d7e9715d | ||
|
|
f8a3d5716c | ||
|
|
82084c84e3 | ||
|
|
f29c629165 | ||
|
|
54b3e17d93 | ||
|
|
2bc843dd2f | ||
|
|
55eeec790f | ||
|
|
8db6c5607d | ||
|
|
2df8dc9caf | ||
|
|
99f48b1e87 | ||
|
|
0dfcf03c0c | ||
|
|
b46e55d3f6 | ||
|
|
62fd543623 | ||
|
|
ec46221c30 | ||
|
|
e57247a233 | ||
|
|
6aa0ab2161 | ||
|
|
f1210def89 | ||
|
|
03842d4e77 | ||
|
|
34676702f4 | ||
|
|
352d917a7d | ||
|
|
f1b47f6a78 | ||
|
|
15d58966f6 | ||
|
|
49cb9ccb66 | ||
|
|
6841fa6f0a | ||
|
|
5e77d7dba1 | ||
|
|
fbedb6f0d2 | ||
|
|
974a560cde |
@@ -8,7 +8,6 @@ import sys
|
||||
import time
|
||||
import argparse
|
||||
import plistlib
|
||||
import platform
|
||||
import subprocess
|
||||
|
||||
from pathlib import Path
|
||||
@@ -127,7 +126,7 @@ class CreateBinary:
|
||||
if Path(f"./dist/OpenCore-Patcher.app").exists():
|
||||
print("Found OpenCore-Patcher.app, removing...")
|
||||
rm_output = subprocess.run(
|
||||
["rm", "-rf", "./dist/OpenCore-Patcher.app"],
|
||||
["/bin/rm", "-rf", "./dist/OpenCore-Patcher.app"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
if rm_output.returncode != 0:
|
||||
@@ -153,13 +152,11 @@ class CreateBinary:
|
||||
print("Embedding icns...")
|
||||
for file in Path("payloads/Icon/AppIcons").glob("*.icns"):
|
||||
subprocess.run(
|
||||
["cp", str(file), "./dist/OpenCore-Patcher.app/Contents/Resources/"],
|
||||
["/bin/cp", str(file), "./dist/OpenCore-Patcher.app/Contents/Resources/"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
def _embed_key(self):
|
||||
"""
|
||||
Embed developer key into binary
|
||||
@@ -253,12 +250,12 @@ class CreateBinary:
|
||||
if file.name in whitelist_folders:
|
||||
continue
|
||||
print(f"- Deleting {file.name}")
|
||||
subprocess.run(["rm", "-rf", file])
|
||||
subprocess.run(["/bin/rm", "-rf", file])
|
||||
else:
|
||||
if file.name in whitelist_files:
|
||||
continue
|
||||
print(f"- Deleting {file.name}")
|
||||
subprocess.run(["rm", "-f", file])
|
||||
subprocess.run(["/bin/rm", "-f", file])
|
||||
|
||||
|
||||
def _download_resources(self):
|
||||
@@ -280,7 +277,7 @@ class CreateBinary:
|
||||
assert resource, "Resource cannot be empty"
|
||||
assert resource not in ("/", "."), "Resource cannot be root"
|
||||
rm_output = subprocess.run(
|
||||
["rm", "-rf", f"./{resource}"],
|
||||
["/bin/rm", "-rf", f"./{resource}"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
if rm_output.returncode != 0:
|
||||
@@ -294,7 +291,7 @@ class CreateBinary:
|
||||
|
||||
download_result = subprocess.run(
|
||||
[
|
||||
"curl", "-LO",
|
||||
"/usr/bin/curl", "-LO",
|
||||
f"https://github.com/dortania/PatcherSupportPkg/releases/download/{patcher_support_pkg_version}/{resource}"
|
||||
],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
@@ -323,7 +320,7 @@ class CreateBinary:
|
||||
|
||||
print("- Removing old payloads.dmg")
|
||||
rm_output = subprocess.run(
|
||||
["rm", "-rf", "./payloads.dmg"],
|
||||
["/bin/rm", "-rf", "./payloads.dmg"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
if rm_output.returncode != 0:
|
||||
@@ -333,7 +330,7 @@ class CreateBinary:
|
||||
|
||||
print("- Generating DMG...")
|
||||
dmg_output = subprocess.run([
|
||||
'hdiutil', 'create', './payloads.dmg',
|
||||
'/usr/bin/hdiutil', 'create', './payloads.dmg',
|
||||
'-megabytes', '32000', # Overlays can only be as large as the disk image allows
|
||||
'-format', 'UDZO', '-ov',
|
||||
'-volname', 'OpenCore Patcher Resources (Base)',
|
||||
@@ -411,7 +408,7 @@ class CreateBinary:
|
||||
path = "./dist/OpenCore-Patcher"
|
||||
print(f"- Removing {path}")
|
||||
rm_output = subprocess.run(
|
||||
["rm", "-rf", path],
|
||||
["/bin/rm", "-rf", path],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
if rm_output.returncode != 0:
|
||||
|
||||
56
CHANGELOG.md
56
CHANGELOG.md
@@ -1,5 +1,61 @@
|
||||
# OpenCore Legacy Patcher changelog
|
||||
|
||||
## 1.4.2
|
||||
- Resolve Auto-Join support for Modern Wireless on macOS 14.4
|
||||
- Applicable for BCM94360, 4360, 4350, 4331 and 43224 chipsets
|
||||
- Resolve WiFi support for Legacy Wireless on macOS 12.7.4 and 13.6.5
|
||||
- Applicable for BCM94328, BCM94322 and Atheros chipsets
|
||||
- Resolve USB 1.1 on macOS Ventura regression from OCLP 1.4.0
|
||||
- Increment Binaries:
|
||||
- PatcherSupportPkg 1.4.8 - release
|
||||
|
||||
## 1.4.1
|
||||
- Update updater implementation
|
||||
- Resolve Keyboard/Trackpad support for MacBookAir6,x running macOS 14.4 and newer
|
||||
- Expands SPI Keyboard and Trackpad patch to include MacBookAir6,x
|
||||
- Publish Bluetooth NVRAM variables for BCM2046 and BCM2070 chipsets
|
||||
- Reduces need for NVRAM reset to restore Bluetooth support in newer OSes (Thanks @ausdauersportler)
|
||||
|
||||
## 1.4.0
|
||||
- Refactor subprocess invocations
|
||||
- Resolve RecoveryOS support (Regression resolved in OpenCorePkg)
|
||||
- Restore SPI Keyboard and Trackpad support for macOS 14.4 and newer
|
||||
- Applicable for MacBook8,1, MacBookAir7,x and MacBookPro12,1-14,x
|
||||
- Restore support for T1 on macOS 14.4 and newer
|
||||
- Applicable for MacBookPro13,2, MacBookPro13,3, MacBookPro14,2, MacBookPro14,3
|
||||
- Restore support for legacy Metal GPUs on macOS 14.4 and newer
|
||||
- Applicable for:
|
||||
- Intel Ivy Bridge through Skylake
|
||||
- Nvidia Kepler
|
||||
- AMD legacy GCN
|
||||
- Restore support for USB 1.1 on macOS 14.4 and newer
|
||||
- Applicable for Penryn Macs, Xserve3,1 and MacPro4,1/5,1
|
||||
- Resolve support for legacy and modern WiFi on macOS 14.4 and newer
|
||||
- Applicable for all WiFi-equipped Macs
|
||||
- Note with 14.4: Auto-Join may not work until you forget and rejoin the network
|
||||
- Increment binaries:
|
||||
- OpenCorePkg 0.9.7 - release
|
||||
|
||||
## 1.3.0
|
||||
- Resolve mismatched `CFBundleExecutable` and binary name for kexts.
|
||||
- Resolves ProperTree binary detection (Thanks @CorpNewt).
|
||||
- Applicable extensions:
|
||||
- corecrypto_T1.kext
|
||||
- corecaptureElCap.kext
|
||||
- IO80211ElCap.kext
|
||||
- Resolve 3802-GPU support for macOS 14.2 Beta 2 and newer.
|
||||
- Applicable GPUs:
|
||||
- Intel Ivy Bridge and Haswell iGPUs
|
||||
- Nvidia Kepler dGPUs
|
||||
- Increment Binaries:
|
||||
- PatcherSupportPkg 1.4.6 - release
|
||||
|
||||
## 1.2.1
|
||||
- Resolve `TeraScale 2 Acceleration` checkbox in Settings not being saved
|
||||
- Thanks @rtd1250
|
||||
- Resolve Auto Patcher failing to launch after updating macOS
|
||||
- Regression from 1.2.0
|
||||
|
||||
## 1.2.0
|
||||
- Resolve application not existing if user dismisses an update instead of installing
|
||||
- Resolve lldb crashes on extracted binaries
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Copyright (c) 2020-2023, Dhinak G
|
||||
Copyright (c) 2020-2023, Mykola Grymalyuk
|
||||
Copyright (c) 2020-2024, Dhinak G
|
||||
Copyright (c) 2020-2024, Mykola Grymalyuk
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
||||
@@ -1,16 +1,28 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
import sys, os, time, subprocess, pathlib
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import subprocess
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from PyInstaller.building.api import PYZ, EXE, COLLECT
|
||||
from PyInstaller.building.osx import BUNDLE
|
||||
from PyInstaller.building.build_main import Analysis
|
||||
|
||||
sys.path.append(os.path.abspath(os.getcwd()))
|
||||
|
||||
from resources import constants
|
||||
|
||||
block_cipher = None
|
||||
|
||||
datas = [
|
||||
('payloads.dmg', '.'),
|
||||
('Universal-Binaries.dmg', '.'),
|
||||
|
||||
]
|
||||
if pathlib.Path("DortaniaInternalResources.dmg").exists():
|
||||
|
||||
if Path("DortaniaInternalResources.dmg").exists():
|
||||
datas.append(('DortaniaInternalResources.dmg', '.'))
|
||||
|
||||
|
||||
@@ -27,8 +39,10 @@ a = Analysis(['OpenCore-Patcher-GUI.command'],
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher,
|
||||
noarchive=False)
|
||||
pyz = PYZ(a.pure, a.zipped_data,
|
||||
cipher=block_cipher)
|
||||
|
||||
pyz = PYZ(a.pure,
|
||||
a.zipped_data,
|
||||
cipher=block_cipher)
|
||||
|
||||
exe = EXE(pyz,
|
||||
a.scripts,
|
||||
@@ -43,7 +57,8 @@ exe = EXE(pyz,
|
||||
disable_windowed_traceback=False,
|
||||
target_arch="universal2",
|
||||
codesign_identity=None,
|
||||
entitlements_file=None )
|
||||
entitlements_file=None)
|
||||
|
||||
coll = COLLECT(exe,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
@@ -52,6 +67,7 @@ coll = COLLECT(exe,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
name='OpenCore-Patcher')
|
||||
|
||||
app = BUNDLE(coll,
|
||||
name='OpenCore-Patcher.app',
|
||||
icon="payloads/OC-Patcher.icns",
|
||||
@@ -64,6 +80,6 @@ app = BUNDLE(coll,
|
||||
"NSRequiresAquaSystemAppearance": False,
|
||||
"NSHighResolutionCapable": True,
|
||||
"Build Date": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
|
||||
"BuildMachineOSBuild": subprocess.run("sw_vers -buildVersion".split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.decode().strip(),
|
||||
"BuildMachineOSBuild": subprocess.run(["/usr/bin/sw_vers", "-buildVersion"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.decode().strip(),
|
||||
"NSPrincipalClass": "NSApplication",
|
||||
})
|
||||
|
||||
1210
data/css_data.py
Normal file
1210
data/css_data.py
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,8 @@
|
||||
# Dictionary defining patch sets used during Root Volume patching (sys_patch.py)
|
||||
# Copyright (C) 2022-2023, Mykola Grymalyuk
|
||||
|
||||
import packaging.version
|
||||
|
||||
from data import os_data
|
||||
|
||||
|
||||
@@ -9,7 +11,7 @@ class SystemPatchDictionary():
|
||||
Library for generating patch sets for sys_patch.py and supporting modules
|
||||
|
||||
Usage:
|
||||
>>> patchsets = SystemPatchDictionary(22, 0, [20, 21, 22]).patchset_dict
|
||||
>>> patchsets = SystemPatchDictionary(22, 0, [20, 21, 22], "13.0").patchset_dict
|
||||
|
||||
|
||||
Patchset Schema:
|
||||
@@ -49,12 +51,13 @@ class SystemPatchDictionary():
|
||||
Note: Stubbed binaries are OS specific, thus use the 'self.os_major' variable to denounce which folder variant to use
|
||||
"""
|
||||
|
||||
def __init__(self, os_major: int, os_minor: int, non_metal_os_support: list) -> None:
|
||||
def __init__(self, os_major: int, os_minor: int, non_metal_os_support: list, marketing_version: str) -> None:
|
||||
"""
|
||||
Parameters:
|
||||
os_major (int): Major XNU Kernel version
|
||||
os_minor (int): Minor XNU Kernel version
|
||||
non_metal_os_support (list): List of supported non-metal OSes (XNU Major Versions)
|
||||
marketing_version (str): Marketing version of the OS
|
||||
|
||||
'non_metal_os_support' is assumed to be sorted from oldest to newest
|
||||
"""
|
||||
@@ -64,6 +67,9 @@ class SystemPatchDictionary():
|
||||
self.os_float: float = float(f"{self.os_major}.{self.os_minor}")
|
||||
self.non_metal_os_support: list = non_metal_os_support
|
||||
self.patchset_dict: dict = {}
|
||||
self.marketing_version: str = marketing_version
|
||||
|
||||
self.affected_by_cve_2024_23227: bool = self.__is_affect_by_cve_2024_23227()
|
||||
|
||||
# XNU Kernel versions
|
||||
self.macOS_12_0_B7: float = 21.1
|
||||
@@ -71,10 +77,76 @@ class SystemPatchDictionary():
|
||||
self.macOS_12_5: float = 21.6
|
||||
self.macOS_13_3: float = 22.4
|
||||
self.macOS_14_1: float = 23.1
|
||||
self.macOS_14_2: float = 23.2
|
||||
self.macOS_14_4: float = 23.4
|
||||
|
||||
self._generate_sys_patch_dict()
|
||||
|
||||
|
||||
def __resolve_ivy_bridge_framebuffers(self) -> str:
|
||||
"""
|
||||
Resolve patchset directory for Ivy Bridge framebuffers:
|
||||
- AppleIntelFramebufferCapri.kext
|
||||
- AppleIntelHD4000Graphics.kext
|
||||
"""
|
||||
if self.os_major < os_data.os_data.sonoma:
|
||||
return "11.4"
|
||||
if self.os_float < self.macOS_14_4:
|
||||
return "11.4-23"
|
||||
return "11.4-23.4"
|
||||
|
||||
|
||||
def __resolve_kepler_geforce_framebuffers(self) -> str:
|
||||
"""
|
||||
Resolve patchset directory for GeForce.kext
|
||||
"""
|
||||
if self.os_major < os_data.os_data.sonoma:
|
||||
return "12.0 Beta 6"
|
||||
if self.os_float < self.macOS_14_4:
|
||||
return "12.0 Beta 6-23"
|
||||
return "12.0 Beta 6-23.4"
|
||||
|
||||
|
||||
def __resolve_monterey_framebuffers(self) -> str:
|
||||
"""
|
||||
Resolve patchset directory for framebuffers last supported in Monterey:
|
||||
- AppleIntelBDWGraphics.kext
|
||||
- AppleIntelBDWGraphicsFramebuffer.kext
|
||||
- AppleIntelFramebufferAzul.kext
|
||||
- AppleIntelHD5000Graphics.kext
|
||||
- AppleIntelSKLGraphics.kext
|
||||
- AppleIntelSKLGraphicsFramebuffer.kext
|
||||
- AMDRadeonX4000.kext
|
||||
- AMDRadeonX5000.kext
|
||||
"""
|
||||
if self.os_major < os_data.os_data.sonoma:
|
||||
return "12.5"
|
||||
if self.os_float < self.macOS_14_4:
|
||||
return "12.5-23"
|
||||
return "12.5-23.4"
|
||||
|
||||
|
||||
def __is_affect_by_cve_2024_23227(self) -> bool:
|
||||
"""
|
||||
CVE-2024-23227 broke our airportd patches for 12.7.4, 13.6.5 and 14.4
|
||||
|
||||
Note that since the XNU version's security patch level is not increment
|
||||
"""
|
||||
|
||||
if self.os_major > os_data.os_data.sonoma:
|
||||
return True
|
||||
|
||||
parsed_version = packaging.version.parse(self.marketing_version)
|
||||
if self.marketing_version.startswith("12"):
|
||||
return parsed_version >= packaging.version.parse("12.7.4")
|
||||
if self.marketing_version.startswith("13"):
|
||||
return parsed_version >= packaging.version.parse("13.6.5")
|
||||
if self.marketing_version.startswith("14"):
|
||||
return parsed_version >= packaging.version.parse("14.4")
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def _generate_sys_patch_dict(self):
|
||||
"""
|
||||
Generates the sys_patch_dict dictionary
|
||||
@@ -388,6 +460,11 @@ class SystemPatchDictionary():
|
||||
**({ "MTLCompiler.framework": "13.2.1" } if self.os_major == os_data.os_data.ventura else {}),
|
||||
**({ "GPUCompiler.framework": "13.2.1" } if self.os_major == os_data.os_data.ventura else {}),
|
||||
"RenderBox.framework": "13.2.1-3802" if self.os_major == os_data.os_data.ventura else "14.0-3802",
|
||||
|
||||
# More issues for 3802, now with 14.2 Beta 2+...
|
||||
# If there is a god, they clearly despise us and legacy Macs.
|
||||
**({ "MTLCompiler.framework": "14.2 Beta 1" } if self.os_float >= self.macOS_14_2 else {}),
|
||||
**({ "GPUCompiler.framework": "14.2 Beta 1" } if self.os_float >= self.macOS_14_2 else {}),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -578,7 +655,7 @@ class SystemPatchDictionary():
|
||||
},
|
||||
"Install": {
|
||||
"/System/Library/Extensions": {
|
||||
"GeForce.kext": "12.0 Beta 6" if self.os_major < os_data.os_data.sonoma else "12.0 Beta 6-23",
|
||||
"GeForce.kext": self.__resolve_kepler_geforce_framebuffers(),
|
||||
"NVDAGF100Hal.kext": "12.0 Beta 6",
|
||||
"NVDAGK100Hal.kext": "12.0 Beta 6",
|
||||
"NVDAResman.kext": "12.0 Beta 6",
|
||||
@@ -775,7 +852,7 @@ class SystemPatchDictionary():
|
||||
"AMD9000Controller.kext": "12.5",
|
||||
"AMD9500Controller.kext": "12.5",
|
||||
"AMD10000Controller.kext": "12.5",
|
||||
"AMDRadeonX4000.kext": "12.5" if self.os_major < os_data.os_data.sonoma else "12.5-23",
|
||||
"AMDRadeonX4000.kext": self.__resolve_monterey_framebuffers(),
|
||||
"AMDRadeonX4000HWServices.kext": "12.5",
|
||||
"AMDFramebuffer.kext": "12.5" if self.os_float < self.macOS_13_3 else "12.5-GCN",
|
||||
"AMDSupport.kext": "12.5",
|
||||
@@ -838,7 +915,7 @@ class SystemPatchDictionary():
|
||||
},
|
||||
"Install": {
|
||||
"/System/Library/Extensions": {
|
||||
"AMDRadeonX4000.kext": "12.5" if self.os_major < os_data.os_data.sonoma else "12.5-23",
|
||||
"AMDRadeonX4000.kext": self.__resolve_monterey_framebuffers(),
|
||||
"AMDRadeonX4000HWServices.kext": "12.5",
|
||||
|
||||
"AMDRadeonVADriver2.bundle": "12.5",
|
||||
@@ -862,7 +939,7 @@ class SystemPatchDictionary():
|
||||
},
|
||||
"Install": {
|
||||
"/System/Library/Extensions": {
|
||||
"AMDRadeonX5000.kext": "12.5" if self.os_major < os_data.os_data.sonoma else "12.5-23",
|
||||
"AMDRadeonX5000.kext": self.__resolve_monterey_framebuffers(),
|
||||
|
||||
"AMDRadeonVADriver2.bundle": "12.5",
|
||||
"AMDRadeonX5000GLDriver.bundle": "12.5",
|
||||
@@ -956,8 +1033,8 @@ class SystemPatchDictionary():
|
||||
"AppleIntelHD4000GraphicsGLDriver.bundle": "11.0 Beta 6",
|
||||
"AppleIntelHD4000GraphicsMTLDriver.bundle": "11.0 Beta 6" if self.os_major < os_data.os_data.ventura else "11.0-beta 6-22",
|
||||
"AppleIntelHD4000GraphicsVADriver.bundle": "11.3 Beta 1",
|
||||
"AppleIntelFramebufferCapri.kext": "11.4" if self.os_major < os_data.os_data.sonoma else "11.4-23",
|
||||
"AppleIntelHD4000Graphics.kext": "11.4" if self.os_major < os_data.os_data.sonoma else "11.4-23",
|
||||
"AppleIntelFramebufferCapri.kext": self.__resolve_ivy_bridge_framebuffers(),
|
||||
"AppleIntelHD4000Graphics.kext": self.__resolve_ivy_bridge_framebuffers(),
|
||||
"AppleIntelIVBVA.bundle": "11.4",
|
||||
"AppleIntelGraphicsShared.bundle": "11.4", # libIGIL-Metal.dylib pulled from 11.0 Beta 6
|
||||
},
|
||||
@@ -977,8 +1054,8 @@ class SystemPatchDictionary():
|
||||
},
|
||||
"Install": {
|
||||
"/System/Library/Extensions": {
|
||||
"AppleIntelFramebufferAzul.kext": "12.5" if self.os_major < os_data.os_data.sonoma else "12.5-23",
|
||||
"AppleIntelHD5000Graphics.kext": "12.5" if self.os_major < os_data.os_data.sonoma else "12.5-23",
|
||||
"AppleIntelFramebufferAzul.kext": self.__resolve_monterey_framebuffers(),
|
||||
"AppleIntelHD5000Graphics.kext": self.__resolve_monterey_framebuffers(),
|
||||
"AppleIntelHD5000GraphicsGLDriver.bundle": "12.5",
|
||||
"AppleIntelHD5000GraphicsMTLDriver.bundle": "12.5",
|
||||
"AppleIntelHD5000GraphicsVADriver.bundle": "12.5",
|
||||
@@ -1001,10 +1078,10 @@ class SystemPatchDictionary():
|
||||
},
|
||||
"Install": {
|
||||
"/System/Library/Extensions": {
|
||||
"AppleIntelBDWGraphics.kext": "12.5" if self.os_major < os_data.os_data.sonoma else "12.5-23",
|
||||
"AppleIntelBDWGraphicsFramebuffer.kext": "12.5" if self.os_major < os_data.os_data.sonoma else "12.5-23",
|
||||
"AppleIntelBDWGraphics.kext": self.__resolve_monterey_framebuffers(),
|
||||
"AppleIntelBDWGraphicsFramebuffer.kext": self.__resolve_monterey_framebuffers(),
|
||||
"AppleIntelBDWGraphicsGLDriver.bundle": "12.5",
|
||||
"AppleIntelBDWGraphicsMTLDriver.bundle": "12.5" if self.os_major < os_data.os_data.ventura else "12.5-22",
|
||||
"AppleIntelBDWGraphicsMTLDriver.bundle": "12.5-22",
|
||||
"AppleIntelBDWGraphicsVADriver.bundle": "12.5",
|
||||
"AppleIntelBDWGraphicsVAME.bundle": "12.5",
|
||||
"AppleIntelGraphicsShared.bundle": "12.5",
|
||||
@@ -1025,8 +1102,8 @@ class SystemPatchDictionary():
|
||||
},
|
||||
"Install": {
|
||||
"/System/Library/Extensions": {
|
||||
"AppleIntelSKLGraphics.kext": "12.5" if self.os_major < os_data.os_data.sonoma else "12.5-23",
|
||||
"AppleIntelSKLGraphicsFramebuffer.kext": "12.5" if self.os_major < os_data.os_data.sonoma else "12.5-23",
|
||||
"AppleIntelSKLGraphics.kext": self.__resolve_monterey_framebuffers(),
|
||||
"AppleIntelSKLGraphicsFramebuffer.kext": self.__resolve_monterey_framebuffers(),
|
||||
"AppleIntelSKLGraphicsGLDriver.bundle": "12.5",
|
||||
"AppleIntelSKLGraphicsMTLDriver.bundle": "12.5",
|
||||
"AppleIntelSKLGraphicsVADriver.bundle": "12.5",
|
||||
@@ -1101,10 +1178,10 @@ class SystemPatchDictionary():
|
||||
},
|
||||
"Install": {
|
||||
"/usr/libexec": {
|
||||
"airportd": "11.7.1",
|
||||
"airportd": "11.7.10" if self.affected_by_cve_2024_23227 is False else "11.7.10-Sandbox",
|
||||
},
|
||||
"/System/Library/CoreServices": {
|
||||
"WiFiAgent.app": "11.7.1",
|
||||
"WiFiAgent.app": "11.7.10",
|
||||
},
|
||||
},
|
||||
"Install Non-Root": {
|
||||
@@ -1128,19 +1205,16 @@ class SystemPatchDictionary():
|
||||
},
|
||||
"Install": {
|
||||
"/usr/libexec": {
|
||||
"wps": "12.6.2",
|
||||
"wifip2pd": "12.6.2",
|
||||
"wifianalyticsd": "13.5",
|
||||
"wps": "12.7.2",
|
||||
"wifip2pd": "12.7.2",
|
||||
},
|
||||
"/System/Library/Frameworks": {
|
||||
"CoreWLAN.framework": "12.6.2",
|
||||
"CoreWLAN.framework": "12.7.2",
|
||||
},
|
||||
"/System/Library/PrivateFrameworks": {
|
||||
"CoreWiFi.framework": "12.6.2",
|
||||
"IO80211.framework": "12.6.2",
|
||||
"WiFiPeerToPeer.framework": "12.6.2",
|
||||
**({ "CoreAnalytics.framework": "13.5"} if self.os_major >= os_data.os_data.sonoma else {}),
|
||||
**({ "WiFiAnalytics.framework": "13.5"} if self.os_major >= os_data.os_data.sonoma else {}),
|
||||
"CoreWiFi.framework": "12.7.2",
|
||||
"IO80211.framework": "12.7.2",
|
||||
"WiFiPeerToPeer.framework": "12.7.2",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1160,20 +1234,16 @@ class SystemPatchDictionary():
|
||||
},
|
||||
"Install": {
|
||||
"/usr/libexec": {
|
||||
"airportd": "13.5",
|
||||
"wifianalyticsd": "13.5",
|
||||
"wifip2pd": "13.5",
|
||||
"airportd": "13.6.5",
|
||||
"wifip2pd": "13.6.5",
|
||||
},
|
||||
"/System/Library/Frameworks": {
|
||||
"CoreWLAN.framework": "13.5",
|
||||
"CoreWLAN.framework": "13.6.5",
|
||||
},
|
||||
"/System/Library/PrivateFrameworks": {
|
||||
"CoreAnalytics.framework": "13.5",
|
||||
"CoreWiFi.framework": "13.5",
|
||||
"IO80211.framework": "13.5",
|
||||
"WiFiAnalytics.framework": "13.5",
|
||||
"WiFiPolicy.framework": "13.5",
|
||||
"WiFiPeerToPeer.framework": "13.5",
|
||||
"CoreWiFi.framework": "13.6.5",
|
||||
"IO80211.framework": "13.6.5",
|
||||
"WiFiPeerToPeer.framework": "13.6.5",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1265,7 +1335,7 @@ class SystemPatchDictionary():
|
||||
},
|
||||
"Install": {
|
||||
"/System/Library/Extensions": {
|
||||
"IOUSBHostFamily.kext": "12.6.2",
|
||||
"IOUSBHostFamily.kext": "12.6.2" if self.os_float < self.macOS_14_4 else "12.6.2-23.4",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -70,7 +70,7 @@ This issue is fully resolved for 13.2.1 and lower starting from 0.2.5.
|
||||
|
||||
::: details Workaround for 0.2.4, Ventura 13.3+
|
||||
|
||||
Due to the usage of amfi_get_out_of_my_way=1, macOS will fail to prompt users for special permissions upon application start as well as omit the entires in System Preferences. To work around this, we recommend users install tccplus to manage permissions.
|
||||
Due to the usage of amfi_get_out_of_my_way=1, macOS will fail to prompt users for special permissions upon application start as well as omit the entries in System Preferences. To work around this, we recommend users install tccplus to manage permissions.
|
||||
|
||||
[Download TCCPlus](https://github.com/jslegendre/tccplus)
|
||||
|
||||
|
||||
@@ -1,18 +1,7 @@
|
||||
# Supporting the patcher
|
||||
|
||||
OpenCore Legacy Patcher is a hobby project for us developers, and while we love helping out the community, it's very difficult for us to troubleshoot issues remotely. The best way for us to get to work on the patcher, fix issues and add enhancements is having the hardware in-hand. As a hobby project, neither of the main developers can afford to buy every legacy Mac to test on.
|
||||
We have opened OpenCollective in order to manage donations as well as be transparent about where the donated money is going. If you want to support the patcher with money donation, you can do so below.
|
||||
|
||||
The best way to support us in all honesty is to donate any old hardware you no longer need, as this allows us to have machines to test locally and push fixes much faster. While we appreciate cash donations, this makes it much more difficult for us to handle as an organization.
|
||||
[OpenCollective](https://opencollective.com/opencore-legacy-patcher)
|
||||
|
||||
Main sections of help we'd appreciate:
|
||||
|
||||
* Donating any Mac you own
|
||||
* Does require SSE4,1 CPU to test on Sierra and newer however
|
||||
|
||||
Additionally, hardware info dumps are greatly beneficial for us to determine what patches a machine might need:
|
||||
|
||||
* [IORegistryExplorer](https://github.com/khronokernel/IORegistryClone/blob/master/ioreg-210.zip?raw=true)
|
||||
* `File -> SaveAs` and open an issue on Github
|
||||
* Note: We want IOReg dumps of hardware not running on OpenCore, instead running a clean, officially supported OS by the machine
|
||||
|
||||
If you have any legacy hardware you're willing to donate or want to buy us hardware, please reach out on our Discord server.
|
||||
If you wish, you can also donate legacy hardware you don't need anymore as long as it makes sense logistically. In this case, reach out on the Discord server.
|
||||
|
||||
@@ -26,7 +26,7 @@ For this example, we'll assume you'll need an installer. Selecting this option w
|
||||
| :--- | :--- | :--- |
|
||||
|  |  | 
|
||||
|
||||
Since the patcher officially supports Big Sur and newer for patching, only those entires will be shown. For ourselves, we'll select macOS 12 as that's the latest public release at the time of writing. This will download and install the macOS installer to your applications folder.
|
||||
Since the patcher officially supports Big Sur and newer for patching, only those entries will be shown. For ourselves, we'll select macOS 12 as that's the latest public release at the time of writing. This will download and install the macOS installer to your applications folder.
|
||||
|
||||
* Note that some machines (namely 2012 and older) may not be currently supported on macOS Ventura. If you see this prompt, you'll need to use an older version of macOS.
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ meta:
|
||||
content: Experience macOS just like before
|
||||
|
||||
features:
|
||||
- title: Built with security in mind
|
||||
details: Supporting System Integrity Protection(SIP), FileVault 2, .im4m Secure Boot and Vaulting. For many machines, you're just as secure as a supported Mac.
|
||||
# - title: Built with security in mind
|
||||
# details: Supporting System Integrity Protection(SIP), FileVault 2, .im4m Secure Boot and Vaulting. We make an effort to ensure your system is as secure as possible.
|
||||
- title: Native OTA updates
|
||||
details: Install updates the moment they come out, with native System Preferences support, just like a supported Mac.
|
||||
- title: Zero firmware patching
|
||||
@@ -22,5 +22,5 @@ features:
|
||||
details: Unlock Sidecar, AirPlay to Mac, Night Shift, and Universal Control, even on natively supported models!
|
||||
- title: A helpful community
|
||||
details: Whether it's getting started or learning the specifics, you can always find answers with our amazing community of tinkerers, developers, and dreamers.
|
||||
footer: Copyright © Dortania 2020-2022
|
||||
footer: Copyright © Dortania 2020-2024
|
||||
---
|
||||
@@ -66,13 +66,13 @@ Then revert the snapshot
|
||||
```sh
|
||||
bless --mount "/Volumes/Macintosh HD" --bootefi --last-sealed-snapshot
|
||||
```
|
||||
After that, type the following
|
||||
```sh
|
||||
cd "/Volumes/Macintosh HD/Library/Extensions" && ls
|
||||
```
|
||||
You should now see bunch of .kexts. If you only see .kexts starting with "HighPoint" and "SoftRAID", you can ignore this and just restart the system. If other kexts are found, continue.
|
||||
Now we're going to clean the /Library/Extensions folder from offending kexts while keeping needed ones.
|
||||
|
||||
Delete everything **except** for the ones that start with HighPoint and SoftRAID, by using `rm -rf "kextname"`
|
||||
Run the following and **make sure to type it carefully**
|
||||
|
||||
```sh
|
||||
cd "/Volumes/Macintosh HD/Library/Extensions" && ls | grep -v "HighPoint*\|SoftRAID*" | xargs rm -rf
|
||||
```
|
||||
|
||||
Then restart and now your system should be restored to the unpatched snapshot and should be able to boot again.
|
||||
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
|
||||
:::warning
|
||||
|
||||
Note that after you remove OpenCore, your Mac will no longer boot and show the "prohibited" symbol. Be ready to install an natively-supported version of macOS before you uninstall OpenCore.
|
||||
Note that after you remove OpenCore, your Mac will no longer boot and show the "prohibited" symbol. Be ready to install a natively-supported version of macOS before you uninstall OpenCore.
|
||||
|
||||
* This does not apply to native Macs just using OpenCore to achieve features like AirPlay to Mac and Sidecar, but it is still recommended to reinstall macOS after removing OpenCore, if using SMBIOS spoofing to enable Univeral Control.
|
||||
* This does not apply to native Macs just using OpenCore to achieve features like AirPlay to Mac and Sidecar, but it is still recommended to reinstall macOS after removing OpenCore, if using SMBIOS spoofing to enable Universal Control and other features.
|
||||
:::
|
||||
|
||||
## Uninstalling the application
|
||||
|
||||
17636
docs/package-lock.json
generated
17636
docs/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -33,19 +33,19 @@
|
||||
},
|
||||
"license": "CC-BY-NC-SA-4.0",
|
||||
"devDependencies": {
|
||||
"@vuepress/plugin-back-to-top": "^1.7.1",
|
||||
"markdown-it-multimd-table": "^4.0.3",
|
||||
"markdown-link-check": "^3.8.5",
|
||||
"markdownlint-cli": "^0.26.0",
|
||||
"run-script-os": "^1.1.4",
|
||||
"spellchecker-cli": "^4.4.0",
|
||||
"vuepress": "^1.7.1",
|
||||
"@vuepress/plugin-back-to-top": "^1.9.10",
|
||||
"markdown-it-multimd-table": "^4.2.3",
|
||||
"markdown-link-check": "^3.11.2",
|
||||
"markdownlint-cli": "^0.37.0",
|
||||
"run-script-os": "^1.1.6",
|
||||
"spellchecker-cli": "^6.1.1",
|
||||
"vuepress": "^1.9.10",
|
||||
"vuepress-plugin-medium-zoom": "^1.1.9",
|
||||
"vuepress-plugin-zooming": "^1.1.8",
|
||||
"vuepress-theme-book": "0.0.5",
|
||||
"vuepress-theme-book": "0.0.9",
|
||||
"vuepress-theme-dark-new": "^0.1.2",
|
||||
"vuepress-theme-succinct": "^1.6.4",
|
||||
"vuepress-theme-yuu": "^2.3.0"
|
||||
"vuepress-theme-succinct": "^1.7.2",
|
||||
"vuepress-theme-yuu": "^3.1.1"
|
||||
},
|
||||
"homepage": "https://dortania.github.io/OpenCore-Legacy-Patcher/"
|
||||
}
|
||||
|
||||
@@ -1745,6 +1745,24 @@
|
||||
<key>PlistPath</key>
|
||||
<string>Contents/Info.plist</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Arch</key>
|
||||
<string>x86_64</string>
|
||||
<key>Comment</key>
|
||||
<string>AppleCredentialManager - T1</string>
|
||||
<key>Enabled</key>
|
||||
<false/>
|
||||
<key>MaxKernel</key>
|
||||
<string></string>
|
||||
<key>MinKernel</key>
|
||||
<string>23.4.0</string>
|
||||
<key>BundlePath</key>
|
||||
<string>AppleCredentialManager.kext</string>
|
||||
<key>ExecutablePath</key>
|
||||
<string>Contents/MacOS/AppleCredentialManager</string>
|
||||
<key>PlistPath</key>
|
||||
<string>Contents/Info.plist</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Arch</key>
|
||||
<string>x86_64</string>
|
||||
@@ -1763,24 +1781,6 @@
|
||||
<key>PlistPath</key>
|
||||
<string>Contents/Info.plist</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Arch</key>
|
||||
<string>x86_64</string>
|
||||
<key>Comment</key>
|
||||
<string>AppleCredentialManager - T1</string>
|
||||
<key>Enabled</key>
|
||||
<false/>
|
||||
<key>MaxKernel</key>
|
||||
<string></string>
|
||||
<key>MinKernel</key>
|
||||
<string>23.0.0</string>
|
||||
<key>BundlePath</key>
|
||||
<string>AppleCredentialManager.kext</string>
|
||||
<key>ExecutablePath</key>
|
||||
<string>Contents/MacOS/AppleCredentialManager</string>
|
||||
<key>PlistPath</key>
|
||||
<string>Contents/Info.plist</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Arch</key>
|
||||
<string>x86_64</string>
|
||||
@@ -1799,6 +1799,42 @@
|
||||
<key>PlistPath</key>
|
||||
<string>Contents/Info.plist</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Arch</key>
|
||||
<string>x86_64</string>
|
||||
<key>Comment</key>
|
||||
<string>AppleHSSPISupport - SPI Top Case Support</string>
|
||||
<key>Enabled</key>
|
||||
<false/>
|
||||
<key>MaxKernel</key>
|
||||
<string></string>
|
||||
<key>MinKernel</key>
|
||||
<string>23.4.0</string>
|
||||
<key>BundlePath</key>
|
||||
<string>AppleHSSPISupport.kext</string>
|
||||
<key>ExecutablePath</key>
|
||||
<string>Contents/MacOS/AppleHSSPISupport</string>
|
||||
<key>PlistPath</key>
|
||||
<string>Contents/Info.plist</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Arch</key>
|
||||
<string>x86_64</string>
|
||||
<key>Comment</key>
|
||||
<string>AppleHSSPIHIDDriver - SPI Top Case Support</string>
|
||||
<key>Enabled</key>
|
||||
<false/>
|
||||
<key>MaxKernel</key>
|
||||
<string></string>
|
||||
<key>MinKernel</key>
|
||||
<string>23.4.0</string>
|
||||
<key>BundlePath</key>
|
||||
<string>AppleHSSPIHIDDriver.kext</string>
|
||||
<key>ExecutablePath</key>
|
||||
<string>Contents/MacOS/AppleHSSPIHIDDriver</string>
|
||||
<key>PlistPath</key>
|
||||
<string>Contents/Info.plist</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Block</key>
|
||||
<array>
|
||||
@@ -1846,7 +1882,7 @@
|
||||
<key>MaxKernel</key>
|
||||
<string></string>
|
||||
<key>MinKernel</key>
|
||||
<string>23.0.0</string>
|
||||
<string>23.4.0</string>
|
||||
<key>Strategy</key>
|
||||
<string>Exclude</string>
|
||||
</dict>
|
||||
|
||||
BIN
payloads/Kexts/Misc/AppleHSSPIHIDDriver-v1.0.0.zip
Normal file
BIN
payloads/Kexts/Misc/AppleHSSPIHIDDriver-v1.0.0.zip
Normal file
Binary file not shown.
BIN
payloads/Kexts/Misc/AppleHSSPISupport-v1.0.0.zip
Normal file
BIN
payloads/Kexts/Misc/AppleHSSPISupport-v1.0.0.zip
Normal file
Binary file not shown.
Binary file not shown.
@@ -108,36 +108,36 @@ class GenerateKexts:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
# Download source
|
||||
weg_source_zip = f"{temp_dir}/WhateverGreen-{self.weg_version}.zip"
|
||||
subprocess.run(["curl", "-L", weg_source_url, "-o", weg_source_zip], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
subprocess.run(["/usr/bin/curl", "--location", weg_source_url, "--output", weg_source_zip], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
|
||||
# Unzip source
|
||||
subprocess.run(["unzip", weg_source_zip, "-d", temp_dir], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
subprocess.run(["/usr/bin/unzip", weg_source_zip, "-d", temp_dir], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
|
||||
# Git clone MacKernelSDK into source
|
||||
subprocess.run(["git", "clone", "https://github.com/acidanthera/MacKernelSDK", f"{temp_dir}/WhateverGreen-{self.weg_version}/MacKernelSDK"], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
subprocess.run(["/usr/bin/git", "clone", "https://github.com/acidanthera/MacKernelSDK", f"{temp_dir}/WhateverGreen-{self.weg_version}/MacKernelSDK"], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
|
||||
# Grab latest Lilu release, debug version
|
||||
lilu_zip = f"{temp_dir}/Lilu-{self.lilu_version}-DEBUG.zip"
|
||||
subprocess.run(["curl", "-L", lilu_url, "-o", lilu_zip], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
subprocess.run(["/usr/bin/curl", "--location", lilu_url, "--output", lilu_zip], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
|
||||
# Unzip Lilu into WEG source
|
||||
subprocess.run(["unzip", lilu_zip, "-d", f"{temp_dir}/WhateverGreen-{self.weg_version}"], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
subprocess.run(["/usr/bin/unzip", lilu_zip, "-d", f"{temp_dir}/WhateverGreen-{self.weg_version}"], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
|
||||
# Apply patch
|
||||
patch_path = Path("./Acidanthera/WhateverGreen-Navi-Backlight.patch").absolute()
|
||||
subprocess.run(["git", "apply", patch_path], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, cwd=f"{temp_dir}/WhateverGreen-{self.weg_version}")
|
||||
subprocess.run(["/usr/bin/git", "apply", patch_path], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, cwd=f"{temp_dir}/WhateverGreen-{self.weg_version}")
|
||||
|
||||
# Build WEG
|
||||
for variant in ["Release", "Debug"]:
|
||||
subprocess.run(["xcodebuild", "-configuration", variant], cwd=f"{temp_dir}/WhateverGreen-{self.weg_version}", check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
subprocess.run(["/usr/bin/xcodebuild", "-configuration", variant], cwd=f"{temp_dir}/WhateverGreen-{self.weg_version}", check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
|
||||
|
||||
# Zip Release
|
||||
for variant in ["RELEASE", "DEBUG"]:
|
||||
dst_path = Path(f"./Acidanthera/WhateverGreen-v{self.weg_version}-Navi-{variant}.zip").absolute()
|
||||
subprocess.run(["zip", "-r", dst_path, "WhateverGreen.kext"], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, cwd=f"{temp_dir}/WhateverGreen-{self.weg_version}/build/{'Release' if variant == 'RELEASE' else 'Debug'}")
|
||||
subprocess.run(["/usr/bin/zip", "-r", dst_path, "WhateverGreen.kext"], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, cwd=f"{temp_dir}/WhateverGreen-{self.weg_version}/build/{'Release' if variant == 'RELEASE' else 'Debug'}")
|
||||
if Path(f"./Acidanthera/WhateverGreen-v{self.weg_old}-Navi-{variant}.zip").exists():
|
||||
subprocess.run(["rm", f"./Acidanthera/WhateverGreen-v{self.weg_old}-Navi-{variant}.zip"], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
subprocess.run(["/bin/rm", f"./Acidanthera/WhateverGreen-v{self.weg_old}-Navi-{variant}.zip"], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
|
||||
self._update_constants_file("self.whatevergreen_navi_version", f"{self.weg_old}-Navi", f"{self.weg_version}-Navi")
|
||||
|
||||
@@ -212,14 +212,14 @@ class GenerateKexts:
|
||||
zip_name = f"{override_kext_zip_name}-v{remote_version}-{variant}.zip" if override_kext_zip_name else f"{kext_name}-v{remote_version}-{variant}.zip"
|
||||
|
||||
if Path(f"./{kext_folder}/{zip_name.replace(f'v{remote_version}', f'v{local_version}')}").exists():
|
||||
subprocess.run(["rm", "-rf", f"./{kext_folder}/{zip_name.replace(f'v{remote_version}', f'v{local_version}')}"])
|
||||
subprocess.run(["/bin/rm", "-rf", f"./{kext_folder}/{zip_name.replace(f'v{remote_version}', f'v{local_version}')}"])
|
||||
self._download_file(asset["browser_download_url"], f"./{kext_folder}/{zip_name}", f"{kext_name}.kext")
|
||||
self._update_constants_file(KEXT_DICTIONARY[kext_folder][kext_name]["Constants Variable"], local_version, remote_version)
|
||||
|
||||
if override_kext_zip_name:
|
||||
# rename zip file
|
||||
os.rename(f"./{kext_folder}/{zip_name}", f"./{kext_folder}/{kext_name}-v{remote_version}-{variant}.zip")
|
||||
subprocess.run(["rm", "-rf", f"./{kext_folder}/{kext_name}-v{local_version}-{variant}.zip"])
|
||||
subprocess.run(["/bin/rm", "-rf", f"./{kext_folder}/{kext_name}-v{local_version}-{variant}.zip"])
|
||||
|
||||
|
||||
def _get_local_version(self, kext_folder, kext_name, variant):
|
||||
@@ -247,14 +247,14 @@ class GenerateKexts:
|
||||
f.write(download.content)
|
||||
|
||||
# Unzip file
|
||||
subprocess.run(["unzip", "-q", f"{temp_dir}/temp.zip", "-d", f"{temp_dir}"], check=True)
|
||||
subprocess.run(["/usr/bin/unzip", "-q", f"{temp_dir}/temp.zip", "-d", f"{temp_dir}"], check=True)
|
||||
|
||||
print(f" Moving {file} to {file_path}...")
|
||||
# Zip file
|
||||
subprocess.run(["zip", "-q", "-r", Path(file_path).name, file], cwd=f"{temp_dir}", check=True)
|
||||
subprocess.run(["/usr/bin/zip", "-q", "-r", Path(file_path).name, file], cwd=f"{temp_dir}", check=True)
|
||||
|
||||
# Move file
|
||||
subprocess.run(["mv", f"{temp_dir}/{Path(file_path).name}", file_path], check=True)
|
||||
subprocess.run(["/bin/mv", f"{temp_dir}/{Path(file_path).name}", file_path], check=True)
|
||||
|
||||
|
||||
def _update_constants_file(self, variable_name, old_version, new_version):
|
||||
|
||||
Binary file not shown.
Binary file not shown.
BIN
payloads/Kexts/Wifi/IOSkywalkFamily-v1.1.0.zip
Normal file
BIN
payloads/Kexts/Wifi/IOSkywalkFamily-v1.1.0.zip
Normal file
Binary file not shown.
Binary file not shown.
@@ -13,9 +13,5 @@
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>/var/log/OpenCore-Patcher.log</string>
|
||||
<key>StandardOutPath</key>
|
||||
<string>/var/log/OpenCore-Patcher.log</string>
|
||||
</dict>
|
||||
</plist>
|
||||
</plist>
|
||||
Binary file not shown.
Binary file not shown.
@@ -128,24 +128,24 @@ class GenerateOpenCore:
|
||||
for variant in BUILD_VARIANTS:
|
||||
print(f"Moving {variant} folder...")
|
||||
subprocess.run (
|
||||
["mv", f"{self.working_dir}/OpenCore-{variant}-ROOT/X64", f"{self.working_dir}/OpenCore-{variant}"],
|
||||
["/bin/mv", f"{self.working_dir}/OpenCore-{variant}-ROOT/X64", f"{self.working_dir}/OpenCore-{variant}"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
if variant == "DEBUG":
|
||||
for utility in IMPORTANT_UTILITIES:
|
||||
print(f"Moving {utility} from {variant} variant...")
|
||||
subprocess.run (
|
||||
["rm", "-rf", f"{self.working_dir}/{utility}"],
|
||||
["/bin/rm", "-rf", f"{self.working_dir}/{utility}"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
subprocess.run (
|
||||
["mv", f"{self.working_dir}/OpenCore-{variant}-ROOT/Utilities/{utility}/{utility}", f"{self.working_dir}/{utility}"],
|
||||
["/bin/mv", f"{self.working_dir}/OpenCore-{variant}-ROOT/Utilities/{utility}/{utility}", f"{self.working_dir}/{utility}"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
# Remove root folder
|
||||
subprocess.run (
|
||||
["rm", "-rf", f"{self.working_dir}/OpenCore-{variant}-ROOT"],
|
||||
["/bin/rm", "-rf", f"{self.working_dir}/OpenCore-{variant}-ROOT"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
@@ -153,12 +153,12 @@ class GenerateOpenCore:
|
||||
print("Removing zip files...")
|
||||
# remove debug_zip
|
||||
subprocess.run (
|
||||
["rm", "-rf", self.debug_zip],
|
||||
["/bin/rm", "-rf", self.debug_zip],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
# remove release_zip
|
||||
subprocess.run (
|
||||
["rm", "-rf", self.release_zip],
|
||||
["/bin/rm", "-rf", self.release_zip],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
@@ -194,7 +194,7 @@ class GenerateOpenCore:
|
||||
if (self.working_dir / f"OpenCore-{variant}").exists():
|
||||
print(f" Deleting old {variant} variant...")
|
||||
subprocess.run (
|
||||
["rm", "-rf", f"{self.working_dir}/OpenCore-{variant}"],
|
||||
["/bin/rm", "-rf", f"{self.working_dir}/OpenCore-{variant}"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
@@ -212,7 +212,7 @@ class GenerateOpenCore:
|
||||
# Create S/L/C
|
||||
print(" Creating SLC folder")
|
||||
subprocess.run (
|
||||
["mkdir", "-p", f"{self.working_dir}/OpenCore-{variant}/System/Library/CoreServices"],
|
||||
["/bin/mkdir", "-p", f"{self.working_dir}/OpenCore-{variant}/System/Library/CoreServices"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
@@ -220,21 +220,21 @@ class GenerateOpenCore:
|
||||
print(" Relocating BOOT folder to SLC")
|
||||
for file in (self.working_dir / f"OpenCore-{variant}/EFI/BOOT").iterdir():
|
||||
subprocess.run (
|
||||
["mv", f"{file}", f"{self.working_dir}/OpenCore-{variant}/System/Library/CoreServices"],
|
||||
["/bin/mv", f"{file}", f"{self.working_dir}/OpenCore-{variant}/System/Library/CoreServices"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
# Rename BOOTx64.efi to boot.efi
|
||||
print(" Renaming BOOTx64.efi to boot.efi")
|
||||
subprocess.run (
|
||||
["mv", f"{self.working_dir}/OpenCore-{variant}/System/Library/CoreServices/BOOTx64.efi", f"{self.working_dir}/OpenCore-{variant}/System/Library/CoreServices/boot.efi"],
|
||||
["/bin/mv", f"{self.working_dir}/OpenCore-{variant}/System/Library/CoreServices/BOOTx64.efi", f"{self.working_dir}/OpenCore-{variant}/System/Library/CoreServices/boot.efi"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
# Delete BOOT folder
|
||||
print(" Deleting BOOT folder")
|
||||
subprocess.run (
|
||||
["rm", "-rf", f"{self.working_dir}/OpenCore-{variant}/EFI/BOOT"],
|
||||
["/bin/rm", "-rf", f"{self.working_dir}/OpenCore-{variant}/EFI/BOOT"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
@@ -244,7 +244,7 @@ class GenerateOpenCore:
|
||||
if Path(f"{self.working_dir}/OpenCore-{variant}/EFI/OC/Drivers/{driver}").exists():
|
||||
print(f" Deleting {driver}")
|
||||
subprocess.run (
|
||||
["rm", f"{self.working_dir}/OpenCore-{variant}/EFI/OC/Drivers/{driver}"],
|
||||
["/bin/rm", f"{self.working_dir}/OpenCore-{variant}/EFI/OC/Drivers/{driver}"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
else:
|
||||
@@ -256,7 +256,7 @@ class GenerateOpenCore:
|
||||
if Path(f"{self.working_dir}/OpenCore-{variant}/EFI/OC/Tools/{tool}").exists():
|
||||
print(f" Deleting {tool}")
|
||||
subprocess.run (
|
||||
["rm", f"{self.working_dir}/OpenCore-{variant}/EFI/OC/Tools/{tool}"],
|
||||
["/bin/rm", f"{self.working_dir}/OpenCore-{variant}/EFI/OC/Tools/{tool}"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
else:
|
||||
@@ -265,21 +265,21 @@ class GenerateOpenCore:
|
||||
# Rename OpenCore-<variant> to OpenCore-Build
|
||||
print(" Renaming OpenCore folder")
|
||||
subprocess.run (
|
||||
["mv", f"{self.working_dir}/OpenCore-{variant}", f"{self.working_dir}/OpenCore-Build"],
|
||||
["/bin/mv", f"{self.working_dir}/OpenCore-{variant}", f"{self.working_dir}/OpenCore-Build"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
# Create OpenCore-<variant>.zip
|
||||
print(" Creating OpenCore.zip")
|
||||
subprocess.run (
|
||||
["ditto", "-c", "-k", "--sequesterRsrc", "--keepParent", f"{self.working_dir}/OpenCore-Build", f"{self.working_dir}/OpenCore-{variant}.zip"],
|
||||
["/usr/bin/ditto", "-c", "-k", "--sequesterRsrc", "--keepParent", f"{self.working_dir}/OpenCore-Build", f"{self.working_dir}/OpenCore-{variant}.zip"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
# Delete OpenCore-Build
|
||||
print(" Deleting OpenCore-Build")
|
||||
subprocess.run (
|
||||
["rm", "-rf", f"{self.working_dir}/OpenCore-Build"],
|
||||
["/bin/rm", "-rf", f"{self.working_dir}/OpenCore-Build"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
|
||||
Binary file not shown.
@@ -124,7 +124,7 @@ class arguments:
|
||||
"""
|
||||
Fetch KDK for incoming OS
|
||||
"""
|
||||
results = subprocess.run(["ps", "-ax"], stdout=subprocess.PIPE)
|
||||
results = subprocess.run(["/bin/ps", "-ax"], stdout=subprocess.PIPE)
|
||||
if results.stdout.decode("utf-8").count("OpenCore-Patcher --cache_os") > 1:
|
||||
logging.info("Another instance of OS caching is running, exiting")
|
||||
return
|
||||
@@ -154,7 +154,7 @@ class arguments:
|
||||
if "GPUCompanionBundles" not in kext_plist:
|
||||
continue
|
||||
logging.info(f" - Removing {kext.name}")
|
||||
subprocess.run(["rm", "-rf", kext])
|
||||
subprocess.run(["/bin/rm", "-rf", kext])
|
||||
|
||||
|
||||
def _build_handler(self) -> None:
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
# Copyright (C) 2020-2023, Dhinak G, Mykola Grymalyuk
|
||||
|
||||
import logging
|
||||
import binascii
|
||||
|
||||
from resources import constants, device_probe
|
||||
from resources.build import support
|
||||
@@ -45,6 +46,9 @@ class BuildBluetooth:
|
||||
support.BuildSupport(self.model, self.constants, self.config).enable_kext("BlueToolFixup.kext", self.constants.bluetool_version, self.constants.bluetool_path)
|
||||
support.BuildSupport(self.model, self.constants, self.config).enable_kext("Bluetooth-Spoof.kext", self.constants.btspoof_version, self.constants.btspoof_path)
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -btlfxallowanyaddr"
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["bluetoothInternalControllerInfo"] = binascii.unhexlify("0000000000000000000000000000")
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["bluetoothExternalDongleFailed"] = binascii.unhexlify("00")
|
||||
self.config["NVRAM"]["Delete"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"] += ["bluetoothInternalControllerInfo", "bluetoothExternalDongleFailed"]
|
||||
elif self.computer.bluetooth_chipset == "BRCM20702 Hub":
|
||||
# BCM94331 can include either BCM2070 or BRCM20702 v1 Bluetooth chipsets
|
||||
# Note Monterey only natively supports BRCM20702 v2 (found with BCM94360)
|
||||
@@ -75,4 +79,7 @@ class BuildBluetooth:
|
||||
support.BuildSupport(self.model, self.constants, self.config).enable_kext("BlueToolFixup.kext", self.constants.bluetool_version, self.constants.bluetool_path)
|
||||
if smbios_data.smbios_dictionary[self.model]["Bluetooth Model"] <= bluetooth_data.bluetooth_data.BRCM2070.value:
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -btlfxallowanyaddr"
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["bluetoothInternalControllerInfo"] = binascii.unhexlify("0000000000000000000000000000")
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["bluetoothExternalDongleFailed"] = binascii.unhexlify("00")
|
||||
self.config["NVRAM"]["Delete"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"] += ["bluetoothInternalControllerInfo", "bluetoothExternalDongleFailed"]
|
||||
support.BuildSupport(self.model, self.constants, self.config).enable_kext("Bluetooth-Spoof.kext", self.constants.btspoof_version, self.constants.btspoof_path)
|
||||
@@ -180,9 +180,17 @@ class BuildMiscellaneous:
|
||||
|
||||
def _topcase_handling(self) -> None:
|
||||
"""
|
||||
USB Top Case Handler
|
||||
USB/SPI Top Case Handler
|
||||
"""
|
||||
|
||||
# macOS 14.4 Beta 1 strips SPI-based top case support for Broadwell through Kaby Lake MacBooks (and MacBookAir6,x)
|
||||
if self.model.startswith("MacBook") and self.model in smbios_data.smbios_dictionary:
|
||||
if self.model.startswith("MacBookAir6") or (cpu_data.CPUGen.broadwell <= smbios_data.smbios_dictionary[self.model]["CPU Generation"] <= cpu_data.CPUGen.kaby_lake):
|
||||
logging.info("- Enabling SPI-based top case support")
|
||||
support.BuildSupport(self.model, self.constants, self.config).enable_kext("AppleHSSPISupport.kext", self.constants.apple_spi_version, self.constants.apple_spi_path)
|
||||
support.BuildSupport(self.model, self.constants, self.config).enable_kext("AppleHSSPIHIDDriver.kext", self.constants.apple_spi_hid_version, self.constants.apple_spi_hid_path)
|
||||
|
||||
|
||||
#On-device probing
|
||||
if not self.constants.custom_model and self.computer.internal_keyboard_type and self.computer.trackpad_type:
|
||||
|
||||
@@ -357,7 +365,9 @@ class BuildMiscellaneous:
|
||||
|
||||
support.BuildSupport(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Block"], "Identifier", "com.apple.driver.AppleSSE")["Enabled"] = True
|
||||
support.BuildSupport(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Block"], "Identifier", "com.apple.driver.AppleKeyStore")["Enabled"] = True
|
||||
support.BuildSupport(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Block"], "Identifier", "com.apple.driver.AppleCredentialManager")["Enabled"] = True
|
||||
|
||||
support.BuildSupport(self.model, self.constants, self.config).enable_kext("corecrypto_T1.kext", self.constants.t1_corecrypto_version, self.constants.t1_corecrypto_path)
|
||||
support.BuildSupport(self.model, self.constants, self.config).enable_kext("AppleSSE.kext", self.constants.t1_sse_version, self.constants.t1_sse_path)
|
||||
support.BuildSupport(self.model, self.constants, self.config).enable_kext("AppleKeyStore.kext", self.constants.t1_key_store_version, self.constants.t1_key_store_path)
|
||||
support.BuildSupport(self.model, self.constants, self.config).enable_kext("AppleKeyStore.kext", self.constants.t1_key_store_version, self.constants.t1_key_store_path)
|
||||
support.BuildSupport(self.model, self.constants, self.config).enable_kext("AppleCredentialManager.kext", self.constants.t1_credential_version, self.constants.t1_credential_path)
|
||||
@@ -288,7 +288,7 @@ class BuildSMBIOS:
|
||||
"""
|
||||
|
||||
if self.constants.custom_serial_number == "" or self.constants.custom_board_serial_number == "":
|
||||
macserial_output = subprocess.run([self.constants.macserial_path] + f"-g -m {self.spoofed_model} -n 1".split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
macserial_output = subprocess.run([self.constants.macserial_path, "--generate", "--model", self.spoofed_model, "--num", "1"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
macserial_output = macserial_output.stdout.decode().strip().split(" | ")
|
||||
sn = macserial_output[0]
|
||||
mlb = macserial_output[1]
|
||||
|
||||
@@ -169,6 +169,27 @@ class BuildSupport:
|
||||
logging.info(f"- Found extra driver: {driver_file.name}")
|
||||
raise Exception(f"Found extra driver: {driver_file.name}")
|
||||
|
||||
self._validate_malformed_kexts(self.constants.opencore_release_folder / Path("EFI/OC/Kexts"))
|
||||
|
||||
|
||||
def _validate_malformed_kexts(self, directory: str | Path) -> None:
|
||||
"""
|
||||
Validate Info.plist and executable pathing for kexts
|
||||
"""
|
||||
for kext_folder in Path(directory).glob("*.kext"):
|
||||
if not Path(kext_folder / Path("Contents/Info.plist")).exists():
|
||||
continue
|
||||
|
||||
kext_data = plistlib.load(Path(kext_folder / Path("Contents/Info.plist")).open("rb"))
|
||||
if "CFBundleExecutable" in kext_data:
|
||||
expected_executable = Path(kext_folder / Path("Contents/MacOS") / Path(kext_data["CFBundleExecutable"]))
|
||||
if not expected_executable.exists():
|
||||
logging.info(f"- Missing executable for {kext_folder.name}: Contents/MacOS/{expected_executable.name}")
|
||||
raise Exception(f" - Missing executable for {kext_folder.name}: Contents/MacOS/{expected_executable.name}")
|
||||
|
||||
if Path(kext_folder / Path("Contents/PlugIns")).exists():
|
||||
self._validate_malformed_kexts(kext_folder / Path("Contents/PlugIns"))
|
||||
|
||||
|
||||
def cleanup(self) -> None:
|
||||
"""
|
||||
|
||||
@@ -13,9 +13,9 @@ from data import os_data
|
||||
class Constants:
|
||||
def __init__(self) -> None:
|
||||
# Patcher Versioning
|
||||
self.patcher_version: str = "1.2.0" # OpenCore-Legacy-Patcher
|
||||
self.patcher_support_pkg_version: str = "1.4.5" # PatcherSupportPkg
|
||||
self.copyright_date: str = "Copyright © 2020-2023 Dortania"
|
||||
self.patcher_version: str = "1.4.2" # OpenCore-Legacy-Patcher
|
||||
self.patcher_support_pkg_version: str = "1.4.8" # PatcherSupportPkg
|
||||
self.copyright_date: str = "Copyright © 2020-2024 Dortania"
|
||||
self.patcher_name: str = "OpenCore Legacy Patcher"
|
||||
|
||||
# URLs
|
||||
@@ -28,7 +28,7 @@ class Constants:
|
||||
|
||||
# OpenCore Versioning
|
||||
# https://github.com/acidanthera/OpenCorePkg
|
||||
self.opencore_version: str = "0.9.6"
|
||||
self.opencore_version: str = "0.9.7"
|
||||
|
||||
# Kext Versioning
|
||||
## Acidanthera
|
||||
@@ -69,15 +69,18 @@ class Constants:
|
||||
self.apple_camera_version: str = "1.0.0" # AppleCameraInterface (14.0 Beta 1)
|
||||
self.t1_sse_version: str = "1.1.0" # AppleSSE (13.6 - T1 support)
|
||||
self.t1_key_store_version: str = "1.1.0" # AppleKeyStore (13.6 - T1 support)
|
||||
self.t1_corecrypto_version: str = "1.0.0" # corecrypto (13.6 - T1 support)
|
||||
self.t1_credential_version: str = "1.0.0" # AppleCredentialManager (13.6 - T1 support)
|
||||
self.t1_corecrypto_version: str = "1.0.1" # corecrypto (13.6 - T1 support)
|
||||
self.apple_spi_version: str = "1.0.0" # AppleHSSPISupport (14.4 Beta 1)
|
||||
self.apple_spi_hid_version: str = "1.0.0" # AppleHSSPIHIDDriver (14.4 Beta 1)
|
||||
|
||||
## Apple - Dortania Modified
|
||||
self.bcm570_version: str = "1.0.2" # CatalinaBCM5701Ethernet
|
||||
self.i210_version: str = "1.0.0" # CatalinaIntelI210Ethernet
|
||||
self.corecaptureelcap_version: str = "1.0.1" # corecaptureElCap
|
||||
self.io80211elcap_version: str = "2.0.0" # IO80211ElCap
|
||||
self.corecaptureelcap_version: str = "1.0.2" # corecaptureElCap
|
||||
self.io80211elcap_version: str = "2.0.1" # IO80211ElCap
|
||||
self.io80211legacy_version: str = "1.0.0" # IO80211FamilyLegacy (Ventura)
|
||||
self.ioskywalk_version: str = "1.0.0" # IOSkywalkFamily (Ventura)
|
||||
self.ioskywalk_version: str = "1.1.0" # IOSkywalkFamily (Ventura)
|
||||
self.bigsursdxc_version: str = "1.0.0" # BigSurSDXC
|
||||
self.monterey_ahci_version: str = "1.0.0" # CatalinaAHCI
|
||||
|
||||
@@ -451,6 +454,10 @@ class Constants:
|
||||
def t1_key_store_path(self):
|
||||
return self.payload_kexts_path / Path(f"Misc/AppleKeyStore-v{self.t1_key_store_version}.zip")
|
||||
|
||||
@property
|
||||
def t1_credential_path(self):
|
||||
return self.payload_kexts_path / Path(f"Misc/AppleCredentialManager-v{self.t1_credential_version}.zip")
|
||||
|
||||
@property
|
||||
def t1_sse_path(self):
|
||||
return self.payload_kexts_path / Path(f"Misc/AppleSSE-v{self.t1_sse_version}.zip")
|
||||
@@ -459,6 +466,14 @@ class Constants:
|
||||
def t1_corecrypto_path(self):
|
||||
return self.payload_kexts_path / Path(f"Misc/corecrypto_T1-v{self.t1_corecrypto_version}.zip")
|
||||
|
||||
@property
|
||||
def apple_spi_path(self):
|
||||
return self.payload_kexts_path / Path(f"Misc/AppleHSSPISupport-v{self.apple_spi_version}.zip")
|
||||
|
||||
@property
|
||||
def apple_spi_hid_path(self):
|
||||
return self.payload_kexts_path / Path(f"Misc/AppleHSSPIHIDDriver-v{self.apple_spi_hid_version}.zip")
|
||||
|
||||
@property
|
||||
def mousse_path(self):
|
||||
return self.payload_kexts_path / Path(f"SSE/AAAMouSSE-v{self.mousse_version}.zip")
|
||||
|
||||
@@ -329,9 +329,9 @@ class GenerateDefaults:
|
||||
|
||||
for key in ["Moraea_BlurBeta"]:
|
||||
# Enable BetaBlur if user hasn't disabled it
|
||||
is_key_enabled = subprocess.run(["defaults", "read", "-g", key], stdout=subprocess.PIPE).stdout.decode("utf-8").strip()
|
||||
is_key_enabled = subprocess.run(["/usr/bin/defaults", "read", "-globalDomain", key], stdout=subprocess.PIPE).stdout.decode("utf-8").strip()
|
||||
if is_key_enabled not in ["false", "0"]:
|
||||
subprocess.run(["defaults", "write", "-g", key, "-bool", "true"])
|
||||
subprocess.run(["/usr/bin/defaults", "write", "-globalDomain", key, "-bool", "true"])
|
||||
|
||||
def _check_amfipass_supported(self) -> None:
|
||||
"""
|
||||
|
||||
@@ -862,7 +862,7 @@ class Computer:
|
||||
# Reported model
|
||||
entry = next(ioreg.ioiterator_to_list(ioreg.IOServiceGetMatchingServices(ioreg.kIOMasterPortDefault, ioreg.IOServiceMatching("IOPlatformExpertDevice".encode()), None)[1]))
|
||||
self.reported_model = ioreg.corefoundation_to_native(ioreg.IORegistryEntryCreateCFProperty(entry, "model", ioreg.kCFAllocatorDefault, ioreg.kNilOptions)).strip(b"\0").decode() # type: ignore
|
||||
translated = subprocess.run("sysctl -in sysctl.proc_translated".split(), stdout=subprocess.PIPE).stdout.decode()
|
||||
translated = subprocess.run(["/usr/sbin/sysctl", "-in", "sysctl.proc_translated"], stdout=subprocess.PIPE).stdout.decode()
|
||||
if translated:
|
||||
board = "target-type"
|
||||
else:
|
||||
@@ -894,14 +894,14 @@ class Computer:
|
||||
|
||||
def cpu_probe(self):
|
||||
self.cpu = CPU(
|
||||
subprocess.run("sysctl machdep.cpu.brand_string".split(), stdout=subprocess.PIPE).stdout.decode().partition(": ")[2].strip(),
|
||||
subprocess.run("sysctl machdep.cpu.features".split(), stdout=subprocess.PIPE).stdout.decode().partition(": ")[2].strip().split(" "),
|
||||
subprocess.run(["/usr/sbin/sysctl", "machdep.cpu.brand_string"], stdout=subprocess.PIPE).stdout.decode().partition(": ")[2].strip(),
|
||||
subprocess.run(["/usr/sbin/sysctl", "machdep.cpu.features"], stdout=subprocess.PIPE).stdout.decode().partition(": ")[2].strip().split(" "),
|
||||
self.cpu_get_leafs(),
|
||||
)
|
||||
|
||||
def cpu_get_leafs(self):
|
||||
leafs = []
|
||||
result = subprocess.run("sysctl machdep.cpu.leaf7_features".split(), stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
|
||||
result = subprocess.run(["/usr/sbin/sysctl", "machdep.cpu.leaf7_features"], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
|
||||
if result.returncode == 0:
|
||||
return result.stdout.decode().partition(": ")[2].strip().split(" ")
|
||||
return leafs
|
||||
@@ -979,7 +979,7 @@ class Computer:
|
||||
def sata_disk_probe(self):
|
||||
# Get all SATA Controllers/Disks from 'system_profiler SPSerialATADataType'
|
||||
# Determine whether SATA SSD is present and Apple-made
|
||||
sp_sata_data = plistlib.loads(subprocess.run(f"system_profiler SPSerialATADataType -xml".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
sp_sata_data = plistlib.loads(subprocess.run(["/usr/sbin/system_profiler", "SPSerialATADataType", "-xml"], stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
for root in sp_sata_data:
|
||||
for ahci_controller in root["_items"]:
|
||||
# Each AHCI controller will have its own entry
|
||||
@@ -1015,7 +1015,7 @@ class Computer:
|
||||
self.oclp_sys_signed = sys_plist["Custom Signature"]
|
||||
|
||||
def check_rosetta(self):
|
||||
result = subprocess.run("sysctl -in sysctl.proc_translated".split(), stdout=subprocess.PIPE).stdout.decode()
|
||||
result = subprocess.run(["/usr/sbin/sysctl", "-in", "sysctl.proc_translated"], stdout=subprocess.PIPE).stdout.decode()
|
||||
if "1" in result:
|
||||
self.rosetta_active = True
|
||||
else:
|
||||
|
||||
@@ -114,7 +114,7 @@ class GlobalEnviromentSettings:
|
||||
return
|
||||
|
||||
# Set file permission to allow any user to write to log file
|
||||
result = subprocess.run(["chmod", "777", self.global_settings_plist], capture_output=True)
|
||||
result = subprocess.run(["/bin/chmod", "777", self.global_settings_plist], capture_output=True)
|
||||
if result.returncode != 0:
|
||||
logging.warning("Failed to fix settings file permissions:")
|
||||
if result.stderr:
|
||||
|
||||
@@ -22,16 +22,16 @@ class tui_disk_installation:
|
||||
# TODO: AllDisksAndPartitions is not supported in Snow Leopard and older
|
||||
try:
|
||||
# High Sierra and newer
|
||||
disks = plistlib.loads(subprocess.run("diskutil list -plist physical".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
disks = plistlib.loads(subprocess.run(["/usr/sbin/diskutil", "list", "-plist", "physical"], stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
except ValueError:
|
||||
# Sierra and older
|
||||
disks = plistlib.loads(subprocess.run("diskutil list -plist".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
disks = plistlib.loads(subprocess.run(["/usr/sbin/diskutil", "list", "-plist"], stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
for disk in disks["AllDisksAndPartitions"]:
|
||||
disk_info = plistlib.loads(subprocess.run(f"diskutil info -plist {disk['DeviceIdentifier']}".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
disk_info = plistlib.loads(subprocess.run(["/usr/sbin/diskutil", "info", "-plist", disk["DeviceIdentifier"]], stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
try:
|
||||
all_disks[disk["DeviceIdentifier"]] = {"identifier": disk_info["DeviceNode"], "name": disk_info["MediaName"], "size": disk_info["TotalSize"], "partitions": {}}
|
||||
for partition in disk["Partitions"]:
|
||||
partition_info = plistlib.loads(subprocess.run(f"diskutil info -plist {partition['DeviceIdentifier']}".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
partition_info = plistlib.loads(subprocess.run(["/usr/sbin/diskutil", "info", "-plist", partition["DeviceIdentifier"]], stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
all_disks[disk["DeviceIdentifier"]]["partitions"][partition["DeviceIdentifier"]] = {
|
||||
"fs": partition_info.get("FilesystemType", partition_info["Content"]),
|
||||
"type": partition_info["Content"],
|
||||
@@ -102,15 +102,15 @@ class tui_disk_installation:
|
||||
logging.info("Please disable Safe Mode and try again.")
|
||||
return
|
||||
else:
|
||||
result = subprocess.run(f"diskutil mount {full_disk_identifier}".split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
result = subprocess.run(["/usr/sbin/diskutil", "mount", full_disk_identifier], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
if result.returncode != 0:
|
||||
logging.info("Mount failed")
|
||||
logging.info(result.stderr.decode())
|
||||
return
|
||||
|
||||
partition_info = plistlib.loads(subprocess.run(f"diskutil info -plist {full_disk_identifier}".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
partition_info = plistlib.loads(subprocess.run(["/usr/sbin/diskutil", "info", "-plist", full_disk_identifier], stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
parent_disk = partition_info["ParentWholeDisk"]
|
||||
drive_host_info = plistlib.loads(subprocess.run(f"diskutil info -plist {parent_disk}".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
drive_host_info = plistlib.loads(subprocess.run(["/usr/sbin/diskutil", "info", "-plist", parent_disk], stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
sd_type = drive_host_info["MediaName"]
|
||||
try:
|
||||
ssd_type = drive_host_info["SolidState"]
|
||||
@@ -125,49 +125,49 @@ class tui_disk_installation:
|
||||
|
||||
if (mount_path / Path("EFI/OC")).exists():
|
||||
logging.info("Removing preexisting EFI/OC folder")
|
||||
subprocess.run(["rm", "-rf", mount_path / Path("EFI/OC")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
subprocess.run(["/bin/rm", "-rf", mount_path / Path("EFI/OC")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
|
||||
if (mount_path / Path("System")).exists():
|
||||
logging.info("Removing preexisting System folder")
|
||||
subprocess.run(["rm", "-rf", mount_path / Path("System")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
subprocess.run(["/bin/rm", "-rf", mount_path / Path("System")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
|
||||
if (mount_path / Path("boot.efi")).exists():
|
||||
logging.info("Removing preexisting boot.efi")
|
||||
subprocess.run(["rm", mount_path / Path("boot.efi")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
subprocess.run(["/bin/rm", mount_path / Path("boot.efi")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
|
||||
logging.info("Copying OpenCore onto EFI partition")
|
||||
subprocess.run(["mkdir", "-p", mount_path / Path("EFI")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
subprocess.run(["cp", "-r", self.constants.opencore_release_folder / Path("EFI/OC"), mount_path / Path("EFI/OC")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
subprocess.run(["cp", "-r", self.constants.opencore_release_folder / Path("System"), mount_path / Path("System")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
subprocess.run(["/bin/mkdir", "-p", mount_path / Path("EFI")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
subprocess.run(["/bin/cp", "-r", self.constants.opencore_release_folder / Path("EFI/OC"), mount_path / Path("EFI/OC")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
subprocess.run(["/bin/cp", "-r", self.constants.opencore_release_folder / Path("System"), mount_path / Path("System")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
|
||||
if Path(self.constants.opencore_release_folder / Path("boot.efi")).exists():
|
||||
subprocess.run(["cp", self.constants.opencore_release_folder / Path("boot.efi"), mount_path / Path("boot.efi")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
subprocess.run(["/bin/cp", self.constants.opencore_release_folder / Path("boot.efi"), mount_path / Path("boot.efi")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
|
||||
if self.constants.boot_efi is True:
|
||||
logging.info("Converting Bootstrap to BOOTx64.efi")
|
||||
if (mount_path / Path("EFI/BOOT")).exists():
|
||||
subprocess.run(["rm", "-rf", mount_path / Path("EFI/BOOT")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
subprocess.run(["/bin/rm", "-rf", mount_path / Path("EFI/BOOT")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
Path(mount_path / Path("EFI/BOOT")).mkdir()
|
||||
subprocess.run(["mv", mount_path / Path("System/Library/CoreServices/boot.efi"), mount_path / Path("EFI/BOOT/BOOTx64.efi")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
subprocess.run(["rm", "-rf", mount_path / Path("System")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
subprocess.run(["/bin/mv", mount_path / Path("System/Library/CoreServices/boot.efi"), mount_path / Path("EFI/BOOT/BOOTx64.efi")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
subprocess.run(["/bin/rm", "-rf", mount_path / Path("System")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
|
||||
if self._determine_sd_card(sd_type) is True:
|
||||
logging.info("Adding SD Card icon")
|
||||
subprocess.run(["cp", self.constants.icon_path_sd, mount_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
subprocess.run(["/bin/cp", self.constants.icon_path_sd, mount_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
elif ssd_type is True:
|
||||
logging.info("Adding SSD icon")
|
||||
subprocess.run(["cp", self.constants.icon_path_ssd, mount_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
subprocess.run(["/bin/cp", self.constants.icon_path_ssd, mount_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
elif disk_type == "USB":
|
||||
logging.info("Adding External USB Drive icon")
|
||||
subprocess.run(["cp", self.constants.icon_path_external, mount_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
subprocess.run(["/bin/cp", self.constants.icon_path_external, mount_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
else:
|
||||
logging.info("Adding Internal Drive icon")
|
||||
subprocess.run(["cp", self.constants.icon_path_internal, mount_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
subprocess.run(["/bin/cp", self.constants.icon_path_internal, mount_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
|
||||
logging.info("Cleaning install location")
|
||||
if not self.constants.recovery_status:
|
||||
logging.info("Unmounting EFI partition")
|
||||
subprocess.run(["diskutil", "umount", mount_path], stdout=subprocess.PIPE).stdout.decode().strip().encode()
|
||||
subprocess.run(["/usr/sbin/diskutil", "umount", mount_path], stdout=subprocess.PIPE).stdout.decode().strip().encode()
|
||||
|
||||
logging.info("OpenCore transfer complete")
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ class KernelDebugKitObject:
|
||||
logging.info("Could not fetch KDK list")
|
||||
return None
|
||||
|
||||
KDK_ASSET_LIST = sorted(results.json(), key=lambda x: (packaging.version.parse(x["version"]), datetime.datetime.fromisoformat(x["date"])), reverse=True)
|
||||
KDK_ASSET_LIST = results.json()
|
||||
|
||||
return KDK_ASSET_LIST
|
||||
|
||||
@@ -334,7 +334,7 @@ class KernelDebugKitObject:
|
||||
kdk_build = kdk_plist_data["ProductBuildVersion"]
|
||||
|
||||
# Check pkg receipts for this build, will give a canonical list if all files that should be present
|
||||
result = subprocess.run(["pkgutil", "--files", f"com.apple.pkg.KDK.{kdk_build}"], capture_output=True)
|
||||
result = subprocess.run(["/usr/sbin/pkgutil", "--files", f"com.apple.pkg.KDK.{kdk_build}"], capture_output=True)
|
||||
if result.returncode != 0:
|
||||
# If pkg receipt is missing, we'll fallback to legacy validation
|
||||
logging.info(f"pkg receipt missing for {kdk_path.name}, falling back to legacy validation")
|
||||
@@ -468,7 +468,7 @@ class KernelDebugKitObject:
|
||||
logging.warning(f"KDK does not exist: {kdk_path}")
|
||||
return
|
||||
|
||||
rm_args = ["rm", "-rf" if Path(kdk_path).is_dir() else "-f", kdk_path]
|
||||
rm_args = ["/bin/rm", "-rf" if Path(kdk_path).is_dir() else "-f", kdk_path]
|
||||
|
||||
result = utilities.elevated(rm_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
if result.returncode != 0:
|
||||
@@ -538,7 +538,7 @@ class KernelDebugKitObject:
|
||||
return False
|
||||
|
||||
# TODO: should we use the checksum from the API?
|
||||
result = subprocess.run(["hdiutil", "verify", self.constants.kdk_download_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
result = subprocess.run(["/usr/bin/hdiutil", "verify", self.constants.kdk_download_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
if result.returncode != 0:
|
||||
logging.info("Error: Kernel Debug Kit checksum verification failed!")
|
||||
logging.info(f"Output: {result.stderr.decode('utf-8')}")
|
||||
@@ -612,7 +612,7 @@ class KernelDebugKitUtilities:
|
||||
|
||||
logging.info(f"Extracting downloaded KDK disk image")
|
||||
with tempfile.TemporaryDirectory() as mount_point:
|
||||
result = subprocess.run(["hdiutil", "attach", kdk_path, "-mountpoint", mount_point, "-nobrowse"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
result = subprocess.run(["/usr/bin/hdiutil", "attach", kdk_path, "-mountpoint", mount_point, "-nobrowse"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
if result.returncode != 0:
|
||||
logging.info("Failed to mount KDK:")
|
||||
logging.info(result.stdout.decode('utf-8'))
|
||||
@@ -644,7 +644,7 @@ class KernelDebugKitUtilities:
|
||||
Parameters:
|
||||
mount_point (Path): Path to mount point
|
||||
"""
|
||||
subprocess.run(["hdiutil", "detach", mount_point], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
subprocess.run(["/usr/bin/hdiutil", "detach", mount_point], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
|
||||
|
||||
def _create_backup(self, kdk_path: Path, kdk_info_plist: Path) -> None:
|
||||
@@ -674,7 +674,7 @@ class KernelDebugKitUtilities:
|
||||
return
|
||||
|
||||
if not Path(KDK_INSTALL_PATH).exists():
|
||||
subprocess.run(["mkdir", "-p", KDK_INSTALL_PATH], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
subprocess.run(["/bin/mkdir", "-p", KDK_INSTALL_PATH], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
|
||||
kdk_dst_name = f"KDK_{kdk_info_dict['version']}_{kdk_info_dict['build']}.pkg"
|
||||
kdk_dst_path = Path(f"{KDK_INSTALL_PATH}/{kdk_dst_name}")
|
||||
@@ -684,7 +684,7 @@ class KernelDebugKitUtilities:
|
||||
logging.info("Backup already exists, skipping")
|
||||
return
|
||||
|
||||
result = utilities.elevated(["cp", "-R", kdk_path, kdk_dst_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
result = utilities.elevated(["/bin/cp", "-R", kdk_path, kdk_dst_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
if result.returncode != 0:
|
||||
logging.info("Failed to create KDK backup:")
|
||||
logging.info(result.stdout.decode('utf-8'))
|
||||
@@ -130,7 +130,7 @@ class InitializeLoggingSupport:
|
||||
]
|
||||
|
||||
for path in paths:
|
||||
result = subprocess.run(["chmod", "777", path], capture_output=True)
|
||||
result = subprocess.run(["/bin/chmod", "777", path], capture_output=True)
|
||||
if result.returncode != 0:
|
||||
logging.error(f"Failed to fix log file permissions")
|
||||
if result.stdout:
|
||||
@@ -251,7 +251,7 @@ class InitializeLoggingSupport:
|
||||
return
|
||||
|
||||
if cant_log is True:
|
||||
subprocess.run(["open", "--reveal", self.log_filepath])
|
||||
subprocess.run(["/usr/bin/open", "--reveal", self.log_filepath])
|
||||
return
|
||||
|
||||
threading.Thread(target=analytics_handler.Analytics(self.constants).send_crash_report, args=(self.log_filepath,)).start()
|
||||
|
||||
@@ -108,10 +108,10 @@ class InstallerCreation():
|
||||
logging.info(f"Creating temporary directory at {ia_tmp}")
|
||||
# Delete all files in tmp_dir
|
||||
for file in Path(ia_tmp).glob("*"):
|
||||
subprocess.run(["rm", "-rf", str(file)])
|
||||
subprocess.run(["/bin/rm", "-rf", str(file)])
|
||||
|
||||
# Copy installer to tmp (use CoW to avoid extra disk writes)
|
||||
args = ["cp", "-cR", installer_path, ia_tmp]
|
||||
args = ["/bin/cp", "-cR", installer_path, ia_tmp]
|
||||
if utilities.check_filesystem_type() != "apfs":
|
||||
# HFS+ disks do not support CoW
|
||||
args[1] = "-R"
|
||||
@@ -179,13 +179,13 @@ fi
|
||||
# TODO: AllDisksAndPartitions is not supported in Snow Leopard and older
|
||||
try:
|
||||
# High Sierra and newer
|
||||
disks = plistlib.loads(subprocess.run("diskutil list -plist physical".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
disks = plistlib.loads(subprocess.run(["/usr/sbin/diskutil", "list", "-plist", "physical"], stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
except ValueError:
|
||||
# Sierra and older
|
||||
disks = plistlib.loads(subprocess.run("diskutil list -plist".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
disks = plistlib.loads(subprocess.run(["/usr/sbin/diskutil", "list", "-plist"], stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
|
||||
for disk in disks["AllDisksAndPartitions"]:
|
||||
disk_info = plistlib.loads(subprocess.run(f"diskutil info -plist {disk['DeviceIdentifier']}".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
disk_info = plistlib.loads(subprocess.run(["/usr/sbin/diskutil", "info", "-plist", disk["DeviceIdentifier"]], stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
try:
|
||||
all_disks[disk["DeviceIdentifier"]] = {"identifier": disk_info["DeviceNode"], "name": disk_info["MediaName"], "size": disk_info["TotalSize"], "removable": disk_info["Internal"], "partitions": {}}
|
||||
except KeyError:
|
||||
@@ -407,7 +407,7 @@ class RemoteInstallerCatalog:
|
||||
})
|
||||
|
||||
available_apps = {k: v for k, v in sorted(available_apps.items(), key=lambda x: x[1]['Version'])}
|
||||
|
||||
|
||||
return available_apps
|
||||
|
||||
|
||||
@@ -623,7 +623,7 @@ class LocalInstallerCatalog:
|
||||
|
||||
output = subprocess.run(
|
||||
[
|
||||
"hdiutil", "attach", "-noverify", sharedsupport_path,
|
||||
"/usr/bin/hdiutil", "attach", "-noverify", sharedsupport_path,
|
||||
"-mountpoint", tmpdir,
|
||||
"-nobrowse",
|
||||
],
|
||||
@@ -644,6 +644,6 @@ class LocalInstallerCatalog:
|
||||
detected_os = plist["Assets"][0]["OSVersion"]
|
||||
|
||||
# Unmount SharedSupport.dmg
|
||||
subprocess.run(["hdiutil", "detach", tmpdir], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
subprocess.run(["/usr/bin/hdiutil", "detach", tmpdir], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
|
||||
return (detected_build, detected_os)
|
||||
@@ -44,7 +44,7 @@ class OSProbe:
|
||||
str: OS version (ex. 12.0)
|
||||
"""
|
||||
|
||||
result = subprocess.run(["sw_vers", "-productVersion"], stdout=subprocess.PIPE)
|
||||
result = subprocess.run(["/usr/bin/sw_vers", "-productVersion"], stdout=subprocess.PIPE)
|
||||
if result.returncode != 0:
|
||||
raise RuntimeError("Failed to detect OS version")
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ class RoutePayloadDiskImage:
|
||||
self._unmount_active_dmgs(unmount_all_active=False)
|
||||
output = subprocess.run(
|
||||
[
|
||||
"hdiutil", "attach", "-noverify", f"{self.constants.payload_path_dmg}",
|
||||
"/usr/bin/hdiutil", "attach", "-noverify", f"{self.constants.payload_path_dmg}",
|
||||
"-mountpoint", Path(self.temp_dir.name / Path("payloads")),
|
||||
"-nobrowse",
|
||||
"-shadow", Path(self.temp_dir.name / Path("payloads_overlay")),
|
||||
@@ -67,7 +67,7 @@ class RoutePayloadDiskImage:
|
||||
unmount_all_active (bool): If True, unmount all active DMGs, otherwise only unmount our own DMG
|
||||
"""
|
||||
|
||||
dmg_info = subprocess.run(["hdiutil", "info", "-plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
dmg_info = subprocess.run(["/usr/bin/hdiutil", "info", "-plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
dmg_info = plistlib.loads(dmg_info.stdout)
|
||||
|
||||
|
||||
@@ -80,12 +80,12 @@ class RoutePayloadDiskImage:
|
||||
if self.temp_dir.name in image["shadow-path"]:
|
||||
logging.info(f"Unmounting personal {variant}")
|
||||
subprocess.run(
|
||||
["hdiutil", "detach", image["system-entities"][0]["dev-entry"], "-force"],
|
||||
["/usr/bin/hdiutil", "detach", image["system-entities"][0]["dev-entry"], "-force"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT
|
||||
)
|
||||
else:
|
||||
logging.info(f"Unmounting {variant} at: {image['system-entities'][0]['dev-entry']}")
|
||||
subprocess.run(
|
||||
["hdiutil", "detach", image["system-entities"][0]["dev-entry"], "-force"],
|
||||
["/usr/bin/hdiutil", "detach", image["system-entities"][0]["dev-entry"], "-force"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT
|
||||
)
|
||||
@@ -209,7 +209,7 @@ class PatchSysVolume:
|
||||
if save_hid_cs is True and cs_path.exists():
|
||||
logging.info("- Backing up IOHIDEventDriver CodeSignature")
|
||||
# Note it's a folder, not a file
|
||||
utilities.elevated(["cp", "-r", cs_path, f"{self.constants.payload_path}/IOHIDEventDriver_CodeSignature.bak"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
utilities.elevated(["/bin/cp", "-r", cs_path, f"{self.constants.payload_path}/IOHIDEventDriver_CodeSignature.bak"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
|
||||
logging.info(f"- Merging KDK with Root Volume: {kdk_path.name}")
|
||||
utilities.elevated(
|
||||
@@ -230,9 +230,9 @@ class PatchSysVolume:
|
||||
logging.info("- Restoring IOHIDEventDriver CodeSignature")
|
||||
if not cs_path.exists():
|
||||
logging.info(" - CodeSignature folder missing, creating")
|
||||
utilities.elevated(["mkdir", "-p", cs_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
utilities.elevated(["cp", "-r", f"{self.constants.payload_path}/IOHIDEventDriver_CodeSignature.bak", cs_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
utilities.elevated(["rm", "-rf", f"{self.constants.payload_path}/IOHIDEventDriver_CodeSignature.bak"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
utilities.elevated(["/bin/mkdir", "-p", cs_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
utilities.elevated(["/bin/cp", "-r", f"{self.constants.payload_path}/IOHIDEventDriver_CodeSignature.bak", cs_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
utilities.elevated(["/bin/rm", "-rf", f"{self.constants.payload_path}/IOHIDEventDriver_CodeSignature.bak"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
|
||||
|
||||
def _unpatch_root_vol(self):
|
||||
@@ -369,7 +369,7 @@ class PatchSysVolume:
|
||||
|
||||
if self.skip_root_kmutil_requirement is True:
|
||||
# Force rebuild the Auxiliary KC
|
||||
result = utilities.elevated(["killall", "syspolicyd", "kernelmanagerd"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
result = utilities.elevated(["/usr/bin/killall", "syspolicyd", "kernelmanagerd"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
if result.returncode != 0:
|
||||
logging.info("- Unable to remove kernel extension policy files")
|
||||
logging.info(f"\nReason for Patch Failure ({result.returncode}):")
|
||||
@@ -422,7 +422,7 @@ class PatchSysVolume:
|
||||
"""
|
||||
if self.root_mount_path:
|
||||
logging.info("- Unmounting Root Volume (Don't worry if this fails)")
|
||||
utilities.elevated(["diskutil", "unmount", self.root_mount_path], stdout=subprocess.PIPE).stdout.decode().strip().encode()
|
||||
utilities.elevated(["/usr/sbin/diskutil", "unmount", self.root_mount_path], stdout=subprocess.PIPE).stdout.decode().strip().encode()
|
||||
else:
|
||||
logging.info("- Skipping Root Volume unmount")
|
||||
|
||||
@@ -457,11 +457,11 @@ class PatchSysVolume:
|
||||
|
||||
if (Path(self.mount_application_support) / Path("SkyLightPlugins/")).exists():
|
||||
logging.info("- 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))
|
||||
utilities.process_status(utilities.elevated(["/bin/rm", "-Rf", f"{self.mount_application_support}/SkyLightPlugins"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
utilities.process_status(utilities.elevated(["/bin/mkdir", f"{self.mount_application_support}/SkyLightPlugins"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
else:
|
||||
logging.info("- Creating SkylightPlugins folder")
|
||||
utilities.process_status(utilities.elevated(["mkdir", "-p", f"{self.mount_application_support}/SkyLightPlugins/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
utilities.process_status(utilities.elevated(["/bin/mkdir", "-p", f"{self.mount_application_support}/SkyLightPlugins/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
|
||||
def _delete_nonmetal_enforcement(self) -> None:
|
||||
@@ -471,10 +471,10 @@ class PatchSysVolume:
|
||||
"""
|
||||
|
||||
for arg in ["useMetal", "useIOP"]:
|
||||
result = subprocess.run(["defaults", "read", "/Library/Preferences/com.apple.CoreDisplay", arg], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout.decode("utf-8").strip()
|
||||
result = subprocess.run(["/usr/bin/defaults", "read", "/Library/Preferences/com.apple.CoreDisplay", arg], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout.decode("utf-8").strip()
|
||||
if result in ["0", "false", "1", "true"]:
|
||||
logging.info(f"- Removing non-Metal Enforcement Preference: {arg}")
|
||||
utilities.elevated(["defaults", "delete", "/Library/Preferences/com.apple.CoreDisplay", arg])
|
||||
utilities.elevated(["/usr/bin/defaults", "delete", "/Library/Preferences/com.apple.CoreDisplay", arg])
|
||||
|
||||
|
||||
def _clean_auxiliary_kc(self) -> None:
|
||||
@@ -516,15 +516,15 @@ class PatchSysVolume:
|
||||
|
||||
relocation_path = "/Library/Relocated Extensions"
|
||||
if not Path(relocation_path).exists():
|
||||
utilities.elevated(["mkdir", relocation_path])
|
||||
utilities.elevated(["/bin/mkdir", relocation_path])
|
||||
|
||||
for file in Path("/Library/Extensions").glob("*.kext"):
|
||||
try:
|
||||
if datetime.fromtimestamp(file.stat().st_mtime) < datetime(2021, 10, 1):
|
||||
logging.info(f" - Relocating {file.name} kext to {relocation_path}")
|
||||
if Path(relocation_path) / Path(file.name).exists():
|
||||
utilities.elevated(["rm", "-Rf", relocation_path / Path(file.name)])
|
||||
utilities.elevated(["mv", file, relocation_path])
|
||||
utilities.elevated(["/bin/rm", "-Rf", relocation_path / Path(file.name)])
|
||||
utilities.elevated(["/bin/mv", file, relocation_path])
|
||||
except:
|
||||
# Some users have the most cursed /L*/E* folders
|
||||
# ex. Symlinks pointing to symlinks pointing to dead files
|
||||
@@ -545,8 +545,8 @@ class PatchSysVolume:
|
||||
if sys_patch_helpers.SysPatchHelpers(self.constants).generate_patchset_plist(patchset, file_name, self.kdk_path):
|
||||
logging.info("- Writing patchset information to Root Volume")
|
||||
if Path(destination_path_file).exists():
|
||||
utilities.process_status(utilities.elevated(["rm", destination_path_file], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
utilities.process_status(utilities.elevated(["cp", f"{self.constants.payload_path}/{file_name}", destination_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
utilities.process_status(utilities.elevated(["/bin/rm", destination_path_file], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
utilities.process_status(utilities.elevated(["/bin/cp", f"{self.constants.payload_path}/{file_name}", destination_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
|
||||
def _add_auxkc_support(self, install_file: str, source_folder_path: str, install_patch_directory: str, destination_folder_path: str) -> str:
|
||||
@@ -792,19 +792,19 @@ class PatchSysVolume:
|
||||
# Applicable for .kext, .app, .plugin, .bundle, all of which are directories
|
||||
if Path(destination_folder + "/" + file_name).exists():
|
||||
logging.info(f" - Found existing {file_name}, overwriting...")
|
||||
utilities.process_status(utilities.elevated(["rm", "-R", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
utilities.process_status(utilities.elevated(["/bin/rm", "-R", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
else:
|
||||
logging.info(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(["/bin/cp", "-R", f"{source_folder}/{file_name}", destination_folder], 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():
|
||||
logging.info(f" - Found existing {file_name}, overwriting...")
|
||||
utilities.process_status(utilities.elevated(["rm", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
utilities.process_status(utilities.elevated(["/bin/rm", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
else:
|
||||
logging.info(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(["/bin/cp", f"{source_folder}/{file_name}", destination_folder], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
self._fix_permissions(destination_folder + "/" + file_name)
|
||||
|
||||
|
||||
@@ -820,9 +820,9 @@ class PatchSysVolume:
|
||||
if Path(destination_folder + "/" + file_name).exists():
|
||||
logging.info(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))
|
||||
utilities.process_status(utilities.elevated(["/bin/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))
|
||||
utilities.process_status(utilities.elevated(["/bin/rm", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
|
||||
def _fix_permissions(self, destination_file: Path) -> None:
|
||||
@@ -857,7 +857,7 @@ class PatchSysVolume:
|
||||
|
||||
output = subprocess.run(
|
||||
[
|
||||
"hdiutil", "attach", "-noverify", f"{self.constants.payload_local_binaries_root_path_dmg}",
|
||||
"/usr/bin/hdiutil", "attach", "-noverify", f"{self.constants.payload_local_binaries_root_path_dmg}",
|
||||
"-mountpoint", Path(self.constants.payload_path / Path("Universal-Binaries")),
|
||||
"-nobrowse",
|
||||
"-shadow", Path(self.constants.payload_path / Path("Universal-Binaries_overlay")),
|
||||
@@ -890,7 +890,7 @@ class PatchSysVolume:
|
||||
|
||||
result = subprocess.run(
|
||||
[
|
||||
"hdiutil", "attach", "-noverify", f"{self.constants.overlay_psp_path_dmg}",
|
||||
"/usr/bin/hdiutil", "attach", "-noverify", f"{self.constants.overlay_psp_path_dmg}",
|
||||
"-mountpoint", Path(self.constants.payload_path / Path("DortaniaInternal")),
|
||||
"-nobrowse",
|
||||
"-passphrase", password
|
||||
@@ -901,7 +901,7 @@ class PatchSysVolume:
|
||||
logging.info("- Mounted DortaniaInternal resources")
|
||||
result = subprocess.run(
|
||||
[
|
||||
"ditto", f"{self.constants.payload_path / Path('DortaniaInternal')}", f"{self.constants.payload_path / Path('Universal-Binaries')}"
|
||||
"/usr/bin/ditto", f"{self.constants.payload_path / Path('DortaniaInternal')}", f"{self.constants.payload_path / Path('Universal-Binaries')}"
|
||||
],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT
|
||||
)
|
||||
|
||||
@@ -17,6 +17,7 @@ from pathlib import Path
|
||||
from resources import utilities, updates, global_settings, network_handler, constants
|
||||
from resources.sys_patch import sys_patch_detect
|
||||
from resources.wx_gui import gui_entry, gui_support
|
||||
from data import css_data
|
||||
|
||||
|
||||
class AutomaticSysPatch:
|
||||
@@ -70,32 +71,8 @@ class AutomaticSysPatch:
|
||||
|
||||
Please check the Github page for more information about this release."""
|
||||
|
||||
html_markdown = markdown2.markdown(changelog)
|
||||
html_css = """
|
||||
<style>
|
||||
body {
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-size: 13px;
|
||||
margin-top: 20px;
|
||||
background-color: rgb(238,238,238);
|
||||
}
|
||||
h2 {
|
||||
line-height: 0.5;
|
||||
padding-left: 10px;
|
||||
}
|
||||
a {
|
||||
color: -apple-system-control-accent;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
color: #fff;
|
||||
background-color: rgb(47,47,47);
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
"""
|
||||
html_markdown = markdown2.markdown(changelog, extras=["tables"])
|
||||
html_css = css_data.updater_css
|
||||
frame = wx.Dialog(None, -1, title="", size=(650, 500))
|
||||
frame.SetMinSize((650, 500))
|
||||
frame.SetWindowStyle(wx.STAY_ON_TOP)
|
||||
@@ -107,7 +84,18 @@ Please check the Github page for more information about this release."""
|
||||
self.title_text.SetFont(gui_support.font_factory(19, wx.FONTWEIGHT_BOLD))
|
||||
self.description.SetFont(gui_support.font_factory(13, wx.FONTWEIGHT_NORMAL))
|
||||
self.web_view = wx.html2.WebView.New(panel, style=wx.BORDER_SUNKEN)
|
||||
html_code = html_css+html_markdown.replace("<a href=", "<a target='_blank' href=")
|
||||
html_code = f'''
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
{html_css}
|
||||
</style>
|
||||
</head>
|
||||
<body class="markdown-body">
|
||||
{html_markdown.replace("<a href=", "<a target='_blank' href=")}
|
||||
</body>
|
||||
</html>
|
||||
'''
|
||||
self.web_view.SetPage(html_code, "")
|
||||
self.web_view.Bind(wx.html2.EVT_WEBVIEW_NEWWINDOW, self._onWebviewNav)
|
||||
self.web_view.EnableContextMenu(False)
|
||||
@@ -170,7 +158,7 @@ Please check the Github page for more information about this release."""
|
||||
warning_str = f"""\n\nWARNING: We're unable to verify whether there are any new releases of OpenCore Legacy Patcher on Github. Be aware that you may be using an outdated version for this OS. If you're unsure, verify on Github that OpenCore Legacy Patcher {self.constants.patcher_version} is the latest official release"""
|
||||
|
||||
args = [
|
||||
"osascript",
|
||||
"/usr/bin/osascript",
|
||||
"-e",
|
||||
f"""display dialog "OpenCore Legacy Patcher has detected you're running without Root Patches, and would like to install them.\n\nmacOS wipes all root patches during OS installs and updates, so they need to be reinstalled.\n\nFollowing Patches have been detected for your system: \n{patch_string}\nWould you like to apply these patches?{warning_str}" """
|
||||
f'with icon POSIX file "{self.constants.app_icon_path}"',
|
||||
@@ -182,7 +170,7 @@ Please check the Github page for more information about this release."""
|
||||
)
|
||||
if output.returncode == 0:
|
||||
args = [
|
||||
"osascript",
|
||||
"/usr/bin/osascript",
|
||||
"-e",
|
||||
f'''do shell script "{args_string}"'''
|
||||
f' with prompt "OpenCore Legacy Patcher would like to patch your root volume"'
|
||||
@@ -238,7 +226,7 @@ Please check the Github page for more information about this release."""
|
||||
return True
|
||||
|
||||
args = [
|
||||
"osascript",
|
||||
"/usr/bin/osascript",
|
||||
"-e",
|
||||
f"""display dialog "OpenCore Legacy Patcher has detected that you are booting {'a different' if self.constants.special_build else 'an outdated'} OpenCore build\n- Booted: {self.constants.computer.oclp_version}\n- Installed: {self.constants.patcher_version}\n\nWould you like to update the OpenCore bootloader?" """
|
||||
f'with icon POSIX file "{self.constants.app_icon_path}"',
|
||||
@@ -304,7 +292,7 @@ Please check the Github page for more information about this release."""
|
||||
# Check if OpenCore is on a USB drive
|
||||
logging.info("- Boot Drive does not match macOS drive, checking if OpenCore is on a USB drive")
|
||||
|
||||
disk_info = plistlib.loads(subprocess.run(["diskutil", "info", "-plist", root_disk], stdout=subprocess.PIPE).stdout)
|
||||
disk_info = plistlib.loads(subprocess.run(["/usr/sbin/diskutil", "info", "-plist", root_disk], stdout=subprocess.PIPE).stdout)
|
||||
try:
|
||||
if disk_info["Ejectable"] is False:
|
||||
logging.info("- Boot Disk is not removable, skipping prompt")
|
||||
@@ -313,7 +301,7 @@ Please check the Github page for more information about this release."""
|
||||
logging.info("- Boot Disk is ejectable, prompting user to install to internal")
|
||||
|
||||
args = [
|
||||
"osascript",
|
||||
"/usr/bin/osascript",
|
||||
"-e",
|
||||
f"""display dialog "OpenCore Legacy Patcher has detected that you are booting OpenCore from an USB or External drive.\n\nIf you would like to boot your Mac normally without a USB drive plugged in, you can install OpenCore to the internal hard drive.\n\nWould you like to launch OpenCore Legacy Patcher and install to disk?" """
|
||||
f'with icon POSIX file "{self.constants.app_icon_path}"',
|
||||
@@ -362,12 +350,12 @@ Please check the Github page for more information about this release."""
|
||||
logging.info(f" - {name} checksums match, skipping")
|
||||
continue
|
||||
logging.info(f" - Existing service found, removing")
|
||||
utilities.process_status(utilities.elevated(["rm", services[service]], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
utilities.process_status(utilities.elevated(["/bin/rm", services[service]], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
# Create parent directories
|
||||
if not Path(services[service]).parent.exists():
|
||||
logging.info(f" - Creating {Path(services[service]).parent} directory")
|
||||
utilities.process_status(utilities.elevated(["mkdir", "-p", Path(services[service]).parent], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
utilities.process_status(utilities.elevated(["cp", service, services[service]], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
utilities.process_status(utilities.elevated(["/bin/mkdir", "-p", Path(services[service]).parent], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
utilities.process_status(utilities.elevated(["/bin/cp", service, services[service]], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
# Set the permissions on the service
|
||||
utilities.process_status(utilities.elevated(["chmod", "644", services[service]], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
@@ -383,33 +371,33 @@ Please check the Github page for more information about this release."""
|
||||
|
||||
if not Path("Library/Application Support/Dortania").exists():
|
||||
logging.info("- Creating /Library/Application Support/Dortania/")
|
||||
utilities.process_status(utilities.elevated(["mkdir", "-p", "/Library/Application Support/Dortania"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
utilities.process_status(utilities.elevated(["/bin/mkdir", "-p", "/Library/Application Support/Dortania"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
logging.info("- Copying OpenCore Patcher to /Library/Application Support/Dortania/")
|
||||
if Path("/Library/Application Support/Dortania/OpenCore-Patcher.app").exists():
|
||||
logging.info("- Deleting existing OpenCore-Patcher")
|
||||
utilities.process_status(utilities.elevated(["rm", "-R", "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
utilities.process_status(utilities.elevated(["/bin/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]
|
||||
logging.info(f"- Copying {path} to /Library/Application Support/Dortania/")
|
||||
utilities.process_status(utilities.elevated(["ditto", path, "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
utilities.process_status(utilities.elevated(["/usr/bin/ditto", path, "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
if not Path("/Library/Application Support/Dortania/OpenCore-Patcher.app").exists():
|
||||
# Sometimes the binary the user launches may have a suffix (ie. OpenCore-Patcher 3.app)
|
||||
# We'll want to rename it to OpenCore-Patcher.app
|
||||
path = path.split("/")[-1]
|
||||
logging.info(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))
|
||||
utilities.process_status(utilities.elevated(["/bin/mv", f"/Library/Application Support/Dortania/{path}", "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
subprocess.run(["xattr", "-cr", "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
subprocess.run(["/usr/bin/xattr", "-cr", "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
|
||||
# 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():
|
||||
logging.info("- 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))
|
||||
utilities.process_status(utilities.elevated(["/bin/ln", "-s", "/Library/Application Support/Dortania/OpenCore-Patcher.app", "/Applications/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
|
||||
def _create_rsr_monitor_daemon(self) -> bool:
|
||||
@@ -444,7 +432,7 @@ Please check the Github page for more information about this release."""
|
||||
# Load the RSRMonitor plist
|
||||
rsr_monitor_plist = plistlib.load(open(self.constants.rsr_monitor_launch_daemon_path, "rb"))
|
||||
|
||||
arguments = ["rm", "-Rfv"]
|
||||
arguments = ["/bin/rm", "-Rfv"]
|
||||
arguments += [f"/Library/Extensions/{kext}" for kext in kexts]
|
||||
|
||||
# Add the arguments to the RSRMonitor plist
|
||||
|
||||
@@ -35,7 +35,7 @@ class GenerateRootPatchSets:
|
||||
dict: Dictionary of patches to be applied from sys_patch_dict.py
|
||||
"""
|
||||
|
||||
all_hardware_patchset: dict = sys_patch_dict.SystemPatchDictionary(self.constants.detected_os, self.constants.detected_os_minor, self.constants.legacy_accel_support).patchset_dict
|
||||
all_hardware_patchset: dict = sys_patch_dict.SystemPatchDictionary(self.constants.detected_os, self.constants.detected_os_minor, self.constants.legacy_accel_support, self.constants.detected_os_version).patchset_dict
|
||||
required_patches: dict = {}
|
||||
|
||||
utilities.cls()
|
||||
|
||||
@@ -185,7 +185,7 @@ class SysPatchHelpers:
|
||||
if did_find:
|
||||
with open(file_path, "wb") as f:
|
||||
plistlib.dump(data, f, sort_keys=False)
|
||||
subprocess.run(["killall", "NotificationCenter"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
subprocess.run(["/usr/bin/killall", "NotificationCenter"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
|
||||
|
||||
def install_rsr_repair_binary(self):
|
||||
@@ -235,23 +235,30 @@ class SysPatchHelpers:
|
||||
- lib (entire directory)
|
||||
|
||||
Note: With macOS Sonoma, 32023 compiler is used instead and so this patch is not needed
|
||||
until macOS 14.2 Beta 2 with version '32023.26'.
|
||||
|
||||
Parameters:
|
||||
mount_point: The mount point of the target volume
|
||||
"""
|
||||
|
||||
if self.constants.detected_os != os_data.os_data.ventura:
|
||||
return
|
||||
if self.constants.detected_os_minor < 4:
|
||||
if os_data.os_data.sonoma < self.constants.detected_os < os_data.os_data.ventura:
|
||||
return
|
||||
|
||||
LIBRARY_DIR = f"{mount_point}/System/Library/PrivateFrameworks/GPUCompiler.framework/Versions/31001/Libraries/lib/clang"
|
||||
GPU_VERSION = "31001.669"
|
||||
if self.constants.detected_os == os_data.os_data.ventura:
|
||||
if self.constants.detected_os_minor < 4: # 13.3
|
||||
return
|
||||
BASE_VERSION = "31001"
|
||||
GPU_VERSION = f"{BASE_VERSION}.669"
|
||||
elif self.constants.detected_os == os_data.os_data.sonoma:
|
||||
if self.constants.detected_os_minor < 2: # 14.2 Beta 2
|
||||
return
|
||||
BASE_VERSION = "32023"
|
||||
GPU_VERSION = f"{BASE_VERSION}.26"
|
||||
|
||||
LIBRARY_DIR = f"{mount_point}/System/Library/PrivateFrameworks/GPUCompiler.framework/Versions/{BASE_VERSION}/Libraries/lib/clang"
|
||||
DEST_DIR = f"{LIBRARY_DIR}/{GPU_VERSION}"
|
||||
|
||||
if not Path(DEST_DIR).exists():
|
||||
return
|
||||
raise Exception(f"Failed to find GPUCompiler libraries at {DEST_DIR}")
|
||||
|
||||
for file in Path(LIBRARY_DIR).iterdir():
|
||||
if file.is_file():
|
||||
@@ -260,13 +267,13 @@ class SysPatchHelpers:
|
||||
continue
|
||||
|
||||
# Partial match as each OS can increment the version
|
||||
if not file.name.startswith("31001."):
|
||||
if not file.name.startswith(f"{BASE_VERSION}."):
|
||||
continue
|
||||
|
||||
logging.info(f"Merging GPUCompiler.framework libraries to match binary")
|
||||
|
||||
src_dir = f"{LIBRARY_DIR}/{file.name}"
|
||||
if not Path(f"{DEST_DIR}/lib").exists():
|
||||
utilities.process_status(utilities.elevated(["cp", "-cR", f"{src_dir}/lib", f"{DEST_DIR}/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
utilities.process_status(utilities.elevated(["/bin/cp", "-cR", f"{src_dir}/lib", f"{DEST_DIR}/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
break
|
||||
@@ -108,13 +108,14 @@ def check_recovery():
|
||||
|
||||
|
||||
def get_disk_path():
|
||||
root_partition_info = plistlib.loads(subprocess.run("diskutil info -plist /".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
root_partition_info = plistlib.loads(subprocess.run(["/usr/sbin/diskutil", "info", "-plist", "/"], stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
root_mount_path = root_partition_info["DeviceIdentifier"]
|
||||
root_mount_path = root_mount_path[:-2] if root_mount_path.count("s") > 1 else root_mount_path
|
||||
return root_mount_path
|
||||
|
||||
|
||||
def check_if_root_is_apfs_snapshot():
|
||||
root_partition_info = plistlib.loads(subprocess.run("diskutil info -plist /".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
root_partition_info = plistlib.loads(subprocess.run(["/usr/sbin/diskutil", "info", "-plist", "/"], stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
try:
|
||||
is_snapshotted = root_partition_info["APFSSnapshot"]
|
||||
except KeyError:
|
||||
@@ -124,7 +125,7 @@ def check_if_root_is_apfs_snapshot():
|
||||
|
||||
def check_seal():
|
||||
# 'Snapshot Sealed' property is only listed on booted snapshots
|
||||
sealed = subprocess.run(["diskutil", "apfs", "list"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
sealed = subprocess.run(["/usr/sbin/diskutil", "apfs", "list"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
if "Snapshot Sealed: Yes" in sealed.stdout.decode():
|
||||
return True
|
||||
else:
|
||||
@@ -132,7 +133,7 @@ def check_seal():
|
||||
|
||||
def check_filesystem_type():
|
||||
# Expected to return 'apfs' or 'hfs'
|
||||
filesystem_type = plistlib.loads(subprocess.run(["diskutil", "info", "-plist", "/"], stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
filesystem_type = plistlib.loads(subprocess.run(["/usr/sbin/diskutil", "info", "-plist", "/"], stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
return filesystem_type["FilesystemType"]
|
||||
|
||||
|
||||
@@ -186,10 +187,10 @@ def check_kext_loaded(bundle_id: str) -> str:
|
||||
# no UUID for kextstat
|
||||
pattern = re.compile(re.escape(bundle_id) + r"\s+\((?P<version>.+)\)")
|
||||
|
||||
args = ["kextstat", "-l", "-b", bundle_id]
|
||||
args = ["/usr/sbin/kextstat", "-list-only", "-bundle-id", bundle_id]
|
||||
|
||||
if Path("/usr/bin/kmutil").exists():
|
||||
args = ["kmutil", "showloaded", "--list-only", "--variant-suffix", "release", "--optional-identifier", bundle_id]
|
||||
args = ["/usr/bin/kmutil", "showloaded", "--list-only", "--variant-suffix", "release", "--optional-identifier", bundle_id]
|
||||
|
||||
kext_loaded = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
if kext_loaded.returncode != 0:
|
||||
@@ -213,7 +214,7 @@ def check_oclp_boot():
|
||||
def check_monterey_wifi():
|
||||
IO80211ElCap = "com.apple.iokit.IO80211ElCap"
|
||||
CoreCaptureElCap = "com.apple.driver.corecaptureElCap"
|
||||
loaded_kexts: str = subprocess.run("kextcache".split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.decode()
|
||||
loaded_kexts: str = subprocess.run(["/usr/sbin/kextcache"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.decode()
|
||||
if IO80211ElCap in loaded_kexts and CoreCaptureElCap in loaded_kexts:
|
||||
return True
|
||||
else:
|
||||
@@ -307,7 +308,7 @@ def patching_status(os_sip, os):
|
||||
|
||||
if os > os_data.os_data.catalina and not check_filevault_skip():
|
||||
# Assume non-OCLP Macs do not have our APFS seal patch
|
||||
fv_status: str = subprocess.run("fdesetup status".split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.decode()
|
||||
fv_status: str = subprocess.run(["/usr/bin/fdesetup", "status"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.decode()
|
||||
if "FileVault is Off" in fv_status:
|
||||
fv_enabled = False
|
||||
else:
|
||||
@@ -340,8 +341,7 @@ def cls():
|
||||
|
||||
def check_command_line_tools():
|
||||
# Determine whether Command Line Tools exist
|
||||
# xcode-select -p
|
||||
xcode_select = subprocess.run("xcode-select -p".split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
xcode_select = subprocess.run(["/usr/bin/xcode-select", "--print-path"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
if xcode_select.returncode == 0:
|
||||
return True
|
||||
else:
|
||||
@@ -420,7 +420,7 @@ def find_apfs_physical_volume(device):
|
||||
disk_list = None
|
||||
physical_disks = []
|
||||
try:
|
||||
disk_list = plistlib.loads(subprocess.run(["diskutil", "info", "-plist", device], stdout=subprocess.PIPE).stdout)
|
||||
disk_list = plistlib.loads(subprocess.run(["/usr/sbin/diskutil", "info", "-plist", device], stdout=subprocess.PIPE).stdout)
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
@@ -465,7 +465,7 @@ def find_disk_off_uuid(uuid):
|
||||
# Find disk by UUID
|
||||
disk_list = None
|
||||
try:
|
||||
disk_list = plistlib.loads(subprocess.run(["diskutil", "info", "-plist", uuid], stdout=subprocess.PIPE).stdout)
|
||||
disk_list = plistlib.loads(subprocess.run(["/usr/sbin/diskutil", "info", "-plist", uuid], stdout=subprocess.PIPE).stdout)
|
||||
except TypeError:
|
||||
pass
|
||||
if disk_list:
|
||||
@@ -492,12 +492,12 @@ def get_free_space(disk=None):
|
||||
return free
|
||||
|
||||
def grab_mount_point_from_disk(disk):
|
||||
data = plistlib.loads(subprocess.run(f"diskutil info -plist {disk}".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
data = plistlib.loads(subprocess.run(["/usr/sbin/diskutil", "info", "-plist", disk], stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
return data["MountPoint"]
|
||||
|
||||
def monitor_disk_output(disk):
|
||||
# Returns MB written on drive
|
||||
output = subprocess.check_output(["iostat", "-Id", disk])
|
||||
output = subprocess.check_output(["/usr/sbin/iostat", "-Id", disk])
|
||||
output = output.decode("utf-8")
|
||||
# Grab second last entry (last is \n)
|
||||
output = output.split(" ")
|
||||
@@ -509,7 +509,7 @@ def get_preboot_uuid() -> str:
|
||||
"""
|
||||
Get the UUID of the Preboot volume
|
||||
"""
|
||||
args = ["ioreg", "-a", "-n", "chosen", "-p", "IODeviceTree", "-r"]
|
||||
args = ["/usr/sbin/ioreg", "-a", "-n", "chosen", "-p", "IODeviceTree", "-r"]
|
||||
output = plistlib.loads(subprocess.run(args, stdout=subprocess.PIPE).stdout)
|
||||
return output[0]["apfs-preboot-uuid"].strip(b"\0").decode()
|
||||
|
||||
@@ -533,13 +533,13 @@ def block_os_updaters():
|
||||
if bad_process in current_process:
|
||||
if pid != "":
|
||||
logging.info(f"Killing Process: {pid} - {current_process.split('/')[-1]}")
|
||||
subprocess.run(["kill", "-9", pid])
|
||||
subprocess.run(["/bin/kill", "-9", pid])
|
||||
break
|
||||
|
||||
def check_boot_mode():
|
||||
# Check whether we're in Safe Mode or not
|
||||
try:
|
||||
sys_plist = plistlib.loads(subprocess.run(["system_profiler", "SPSoftwareDataType"], stdout=subprocess.PIPE).stdout)
|
||||
sys_plist = plistlib.loads(subprocess.run(["/usr/sbin/system_profiler", "SPSoftwareDataType"], stdout=subprocess.PIPE).stdout)
|
||||
return sys_plist[0]["_items"][0]["boot_mode"]
|
||||
except (KeyError, TypeError, plistlib.InvalidFileException):
|
||||
return None
|
||||
@@ -550,7 +550,7 @@ def elevated(*args, **kwargs) -> subprocess.CompletedProcess:
|
||||
if os.getuid() == 0 or check_cli_args() is not None:
|
||||
return subprocess.run(*args, **kwargs)
|
||||
else:
|
||||
return subprocess.run(["sudo"] + [args[0][0]] + args[0][1:], **kwargs)
|
||||
return subprocess.run(["/usr/bin/sudo"] + [args[0][0]] + args[0][1:], **kwargs)
|
||||
|
||||
|
||||
def fetch_staged_update(variant: str = "Update") -> (str, str):
|
||||
|
||||
@@ -15,8 +15,10 @@ class PatcherValidation:
|
||||
Primarily for Continuous Integration
|
||||
"""
|
||||
|
||||
def __init__(self, global_constants: constants.Constants) -> None:
|
||||
def __init__(self, global_constants: constants.Constants, verify_unused_files: bool = False) -> None:
|
||||
self.constants: constants.Constants = global_constants
|
||||
self.verify_unused_files = verify_unused_files
|
||||
self.active_patchset_files = []
|
||||
|
||||
self.constants.validate = True
|
||||
|
||||
@@ -102,7 +104,7 @@ class PatcherValidation:
|
||||
minor_kernel (int): Minor kernel version
|
||||
"""
|
||||
|
||||
patchset = sys_patch_dict.SystemPatchDictionary(major_kernel, minor_kernel, self.constants.legacy_accel_support).patchset_dict
|
||||
patchset = sys_patch_dict.SystemPatchDictionary(major_kernel, minor_kernel, self.constants.legacy_accel_support, self.constants.detected_os_version).patchset_dict
|
||||
host_os_float = float(f"{major_kernel}.{minor_kernel}")
|
||||
|
||||
for patch_subject in patchset:
|
||||
@@ -119,6 +121,8 @@ class PatcherValidation:
|
||||
if not Path(source_file).exists():
|
||||
logging.info(f"File not found: {source_file}")
|
||||
raise Exception(f"Failed to find {source_file}")
|
||||
if self.verify_unused_files is True:
|
||||
self.active_patchset_files.append(source_file)
|
||||
|
||||
logging.info(f"Validating against Darwin {major_kernel}.{minor_kernel}")
|
||||
if not sys_patch_helpers.SysPatchHelpers(self.constants).generate_patchset_plist(patchset, f"OpenCore-Legacy-Patcher-{major_kernel}.{minor_kernel}.plist", None):
|
||||
@@ -141,9 +145,33 @@ class PatcherValidation:
|
||||
raise Exception("Failed to download Universal-Binaries.dmg")
|
||||
|
||||
logging.info("Validating Root Patch File integrity")
|
||||
|
||||
if Path(self.constants.payload_path / Path("Universal-Binaries_overlay")).exists():
|
||||
subprocess.run(
|
||||
[
|
||||
"/bin/rm", "-f", Path(self.constants.payload_path / Path("Universal-Binaries_overlay"))
|
||||
],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT
|
||||
)
|
||||
if Path(self.constants.payload_path / Path("Universal-Binaries")).exists():
|
||||
output = subprocess.run(
|
||||
[
|
||||
"/usr/bin/hdiutil", "detach", Path(self.constants.payload_path / Path("Universal-Binaries")),
|
||||
"-force"
|
||||
],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT
|
||||
)
|
||||
|
||||
if output.returncode != 0:
|
||||
logging.info("Failed to unmount Universal-Binaries.dmg")
|
||||
logging.info(f"Output: {output.stdout.decode()}")
|
||||
logging.info(f"Return Code: {output.returncode}")
|
||||
|
||||
raise Exception("Failed to unmount Universal-Binaries.dmg")
|
||||
|
||||
output = subprocess.run(
|
||||
[
|
||||
"hdiutil", "attach", "-noverify", f"{self.constants.payload_local_binaries_root_path_dmg}",
|
||||
"/usr/bin/hdiutil", "attach", "-noverify", f"{self.constants.payload_local_binaries_root_path_dmg}",
|
||||
"-mountpoint", Path(self.constants.payload_path / Path("Universal-Binaries")),
|
||||
"-nobrowse",
|
||||
"-shadow", Path(self.constants.payload_path / Path("Universal-Binaries_overlay")),
|
||||
@@ -165,14 +193,18 @@ class PatcherValidation:
|
||||
for supported_os in [os_data.os_data.big_sur, os_data.os_data.monterey, os_data.os_data.ventura, os_data.os_data.sonoma]:
|
||||
for i in range(0, 10):
|
||||
self._validate_root_patch_files(supported_os, i)
|
||||
|
||||
logging.info("Validating SNB Board ID patcher")
|
||||
self.constants.computer.reported_board_id = "Mac-7BA5B2DFE22DDD8C"
|
||||
sys_patch_helpers.SysPatchHelpers(self.constants).snb_board_id_patch(self.constants.payload_local_binaries_root_path)
|
||||
|
||||
if self.verify_unused_files is True:
|
||||
self._find_unused_files()
|
||||
|
||||
# unmount the dmg
|
||||
output = subprocess.run(
|
||||
[
|
||||
"hdiutil", "detach", Path(self.constants.payload_path / Path("Universal-Binaries")),
|
||||
"/usr/bin/hdiutil", "detach", Path(self.constants.payload_path / Path("Universal-Binaries")),
|
||||
"-force"
|
||||
],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT
|
||||
@@ -187,12 +219,56 @@ class PatcherValidation:
|
||||
|
||||
subprocess.run(
|
||||
[
|
||||
"rm", "-f", Path(self.constants.payload_path / Path("Universal-Binaries_overlay"))
|
||||
"/bin/rm", "-f", Path(self.constants.payload_path / Path("Universal-Binaries_overlay"))
|
||||
],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT
|
||||
)
|
||||
|
||||
|
||||
def _find_unused_files(self) -> None:
|
||||
"""
|
||||
Find PatcherSupportPkg files that are unused by the patcher
|
||||
|
||||
Note this function is extremely slow, so only manually run when needed
|
||||
"""
|
||||
if self.active_patchset_files == []:
|
||||
return
|
||||
|
||||
unused_files = []
|
||||
|
||||
for file in Path(self.constants.payload_local_binaries_root_path).rglob("*"):
|
||||
if file.is_dir():
|
||||
continue
|
||||
|
||||
relative_path = Path(file).relative_to(self.constants.payload_local_binaries_root_path)
|
||||
|
||||
if relative_path.name == ".DS_Store":
|
||||
continue
|
||||
|
||||
if str(relative_path) in [".fseventsd/fseventsd-uuid", ".signed"]:
|
||||
continue
|
||||
|
||||
is_used = False
|
||||
for used_file in self.active_patchset_files:
|
||||
used_relative_path = Path(used_file).relative_to(self.constants.payload_local_binaries_root_path)
|
||||
if str(relative_path) in str(used_relative_path):
|
||||
is_used = True
|
||||
break
|
||||
if str(used_relative_path) in str(relative_path):
|
||||
is_used = True
|
||||
break
|
||||
|
||||
if is_used:
|
||||
continue
|
||||
|
||||
unused_files.append(relative_path)
|
||||
|
||||
if len(unused_files) > 0:
|
||||
logging.info("Unused files found:")
|
||||
for file in unused_files:
|
||||
logging.info(f" {file}")
|
||||
|
||||
|
||||
def _validate_configs(self) -> None:
|
||||
"""
|
||||
Validates build modules
|
||||
@@ -222,4 +298,4 @@ class PatcherValidation:
|
||||
self._build_prebuilt()
|
||||
self._build_dumps()
|
||||
|
||||
subprocess.run(["rm", "-rf", self.constants.build_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
subprocess.run(["/bin/rm", "-rf", self.constants.build_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
@@ -428,8 +428,8 @@ class macOSInstallerFlashFrame(wx.Frame):
|
||||
if not str(path).endswith(".zip"):
|
||||
return
|
||||
if Path(self.constants.installer_pkg_path).exists():
|
||||
subprocess.run(["rm", self.constants.installer_pkg_path])
|
||||
subprocess.run(["ditto", "-V", "-x", "-k", "--sequesterRsrc", "--rsrc", self.constants.installer_pkg_zip_path, self.constants.payload_path])
|
||||
subprocess.run(["/bin/rm", self.constants.installer_pkg_path])
|
||||
subprocess.run(["/usr/bin/ditto", "-V", "-x", "-k", "--sequesterRsrc", "--rsrc", self.constants.installer_pkg_zip_path, self.constants.payload_path])
|
||||
|
||||
|
||||
def _install_installer_pkg(self, disk):
|
||||
@@ -448,8 +448,8 @@ class macOSInstallerFlashFrame(wx.Frame):
|
||||
logging.info("Installer unsupported, requires Big Sur or newer")
|
||||
return
|
||||
|
||||
subprocess.run(["mkdir", "-p", f"{path}/Library/Packages/"])
|
||||
subprocess.run(["cp", "-r", self.constants.installer_pkg_path, f"{path}/Library/Packages/"])
|
||||
subprocess.run(["/bin/mkdir", "-p", f"{path}/Library/Packages/"])
|
||||
subprocess.run(["/bin/cp", "-r", self.constants.installer_pkg_path, f"{path}/Library/Packages/"])
|
||||
|
||||
self._kdk_chainload(os_version["ProductBuildVersion"], os_version["ProductVersion"], Path(path + "/Library/Packages/"))
|
||||
|
||||
@@ -512,17 +512,17 @@ class macOSInstallerFlashFrame(wx.Frame):
|
||||
# Now that we have a KDK, extract it to get the pkg
|
||||
with tempfile.TemporaryDirectory() as mount_point:
|
||||
logging.info("Mounting KDK")
|
||||
result = subprocess.run(["hdiutil", "attach", kdk_dmg_path, "-mountpoint", mount_point, "-nobrowse"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
result = subprocess.run(["/usr/bin/hdiutil", "attach", kdk_dmg_path, "-mountpoint", mount_point, "-nobrowse"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
if result.returncode != 0:
|
||||
logging.info("Failed to mount KDK")
|
||||
logging.info(result.stdout.decode("utf-8"))
|
||||
return
|
||||
|
||||
logging.info("Copying KDK")
|
||||
subprocess.run(["cp", "-r", f"{mount_point}/KernelDebugKit.pkg", kdk_pkg_path])
|
||||
subprocess.run(["/bin/cp", "-r", f"{mount_point}/KernelDebugKit.pkg", kdk_pkg_path])
|
||||
|
||||
logging.info("Unmounting KDK")
|
||||
result = subprocess.run(["hdiutil", "detach", mount_point], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
result = subprocess.run(["/usr/bin/hdiutil", "detach", mount_point], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
if result.returncode != 0:
|
||||
logging.info("Failed to unmount KDK")
|
||||
logging.info(result.stdout.decode("utf-8"))
|
||||
@@ -545,7 +545,7 @@ class macOSInstallerFlashFrame(wx.Frame):
|
||||
logging.error(f"Failed to find {dmg_path}")
|
||||
error_message = f"Failed to find {dmg_path}"
|
||||
return error_message
|
||||
result = subprocess.run(["hdiutil", "verify", dmg_path],stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
result = subprocess.run(["/usr/bin/hdiutil", "verify", dmg_path],stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
if result.returncode != 0:
|
||||
if result.stdout:
|
||||
logging.error(result.stdout.decode("utf-8"))
|
||||
|
||||
@@ -27,7 +27,7 @@ from resources import (
|
||||
global_settings,
|
||||
updates
|
||||
)
|
||||
from data import os_data
|
||||
from data import os_data, css_data
|
||||
|
||||
|
||||
class MainFrame(wx.Frame):
|
||||
@@ -261,13 +261,13 @@ class MainFrame(wx.Frame):
|
||||
if Path("/Applications/OpenCore-Patcher.app").exists() and Path("/Applications/OpenCore-Patcher.app").is_symlink() is False:
|
||||
logging.info("Found user-installed app in /Applications, replacing with symlink")
|
||||
# Delete app
|
||||
result = subprocess.run(["rm", "-rf", "/Applications/OpenCore-Patcher.app"], capture_output=True)
|
||||
result = subprocess.run(["/bin/rm", "-rf", "/Applications/OpenCore-Patcher.app"], capture_output=True)
|
||||
if result.returncode != 0:
|
||||
logging.info("Failed to delete app from /Applications")
|
||||
return
|
||||
|
||||
# Create symlink
|
||||
result = subprocess.run(["ln", "-s", "/Library/Application Support/Dortania/OpenCore-Patcher.app", "/Applications/OpenCore-Patcher.app"], capture_output=True)
|
||||
result = subprocess.run(["/bin/ln", "-s", "/Library/Application Support/Dortania/OpenCore-Patcher.app", "/Applications/OpenCore-Patcher.app"], capture_output=True)
|
||||
if result.returncode != 0:
|
||||
logging.info("Failed to create symlink to /Applications")
|
||||
return
|
||||
@@ -352,31 +352,8 @@ class MainFrame(wx.Frame):
|
||||
|
||||
Please check the Github page for more information about this release."""
|
||||
|
||||
html_markdown = markdown2.markdown(changelog)
|
||||
html_css = """
|
||||
<style>
|
||||
body {
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-size: 13px;
|
||||
margin-top: 20px;
|
||||
background-color: rgb(238,238,238);
|
||||
}
|
||||
h2 {
|
||||
line-height: 0.5;
|
||||
}
|
||||
a {
|
||||
color: -apple-system-control-accent;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
color: #fff;
|
||||
background-color: rgb(47,47,47);
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
"""
|
||||
html_markdown = markdown2.markdown(changelog, extras=["tables"])
|
||||
html_css = css_data.updater_css
|
||||
frame = wx.Dialog(None, -1, title="", size=(650, 500))
|
||||
frame.SetMinSize((650, 500))
|
||||
frame.SetWindowStyle(wx.STAY_ON_TOP)
|
||||
@@ -388,7 +365,18 @@ Please check the Github page for more information about this release."""
|
||||
self.title_text.SetFont(gui_support.font_factory(19, wx.FONTWEIGHT_BOLD))
|
||||
self.description.SetFont(gui_support.font_factory(13, wx.FONTWEIGHT_NORMAL))
|
||||
self.web_view = wx.html2.WebView.New(panel, style=wx.BORDER_SUNKEN)
|
||||
html_code = html_css+html_markdown.replace("<a href=", "<a target='_blank' href=")
|
||||
html_code = f'''
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
{html_css}
|
||||
</style>
|
||||
</head>
|
||||
<body class="markdown-body">
|
||||
{html_markdown.replace("<a href=", "<a target='_blank' href=")}
|
||||
</body>
|
||||
</html>
|
||||
'''
|
||||
self.web_view.SetPage(html_code, "")
|
||||
self.web_view.Bind(wx.html2.EVT_WEBVIEW_NEWWINDOW, self._onWebviewNav)
|
||||
self.web_view.EnableContextMenu(False)
|
||||
|
||||
@@ -286,7 +286,7 @@ class SettingsFrame(wx.Frame):
|
||||
"tampering or corruption."
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
"Show OpenCore Boot Picker": {
|
||||
"type": "checkbox",
|
||||
"value": self.constants.showpicker,
|
||||
@@ -685,6 +685,7 @@ class SettingsFrame(wx.Frame):
|
||||
"By default this is disabled due to",
|
||||
"common GPU failures on these models.",
|
||||
],
|
||||
"override_function": self._update_global_settings,
|
||||
"condition": not bool(self.constants.computer.real_model not in ["MacBookPro8,2", "MacBookPro8,3"])
|
||||
},
|
||||
"wrap_around 1": {
|
||||
@@ -856,7 +857,7 @@ class SettingsFrame(wx.Frame):
|
||||
"Export constants.py values to a txt file.",
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
"Developer Root Volume Patching": {
|
||||
"type": "title",
|
||||
},
|
||||
@@ -1109,7 +1110,7 @@ Hardware Information:
|
||||
value_type = "-bool"
|
||||
|
||||
logging.info(f"Updating System Defaults: {variable} = {value} ({value_type})")
|
||||
subprocess.run(["defaults", "write", "-g", variable, value_type, str(value)])
|
||||
subprocess.run(["/usr/bin/defaults", "write", "-globalDomain", variable, value_type, str(value)])
|
||||
|
||||
|
||||
def _find_parent_for_key(self, key: str) -> str:
|
||||
@@ -1151,7 +1152,7 @@ Hardware Information:
|
||||
if dlg.ShowModal() != wx.ID_YES:
|
||||
return
|
||||
|
||||
macserial_output = subprocess.run([self.constants.macserial_path] + f"-g -m {self.constants.custom_model or self.constants.computer.real_model} -n 1".split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
macserial_output = subprocess.run([self.constants.macserial_path, "--generate", "--model", self.constants.custom_model or self.constants.computer.real_model, "--num", "1"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
macserial_output = macserial_output.stdout.decode().strip().split(" | ")
|
||||
if len(macserial_output) == 2:
|
||||
self.custom_serial_number_textbox.SetValue(macserial_output[0])
|
||||
@@ -1255,7 +1256,7 @@ Hardware Information:
|
||||
|
||||
|
||||
def _get_system_settings(self, variable) -> bool:
|
||||
result = subprocess.run(["defaults", "read", "-g", variable], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
result = subprocess.run(["/usr/bin/defaults", "read", "-globalDomain", variable], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
if result.returncode == 0:
|
||||
try:
|
||||
return bool(int(result.stdout.decode().strip()))
|
||||
@@ -1315,7 +1316,7 @@ Hardware Information:
|
||||
|
||||
def on_test_exception(self, event: wx.Event) -> None:
|
||||
raise Exception("Test Exception")
|
||||
|
||||
|
||||
def on_mount_root_vol(self, event: wx.Event) -> None:
|
||||
if os.geteuid() != 0:
|
||||
wx.MessageDialog(self.parent, "Please relaunch as Root to mount the Root Volume", "Error", wx.OK | wx.ICON_ERROR).ShowModal()
|
||||
|
||||
@@ -64,7 +64,7 @@ class GenerateMenubar:
|
||||
|
||||
self.frame.Bind(wx.EVT_MENU, lambda event: gui_about.AboutFrame(self.constants), aboutItem)
|
||||
self.frame.Bind(wx.EVT_MENU, lambda event: RelaunchApplicationAsRoot(self.frame, self.constants).relaunch(None), relaunchItem)
|
||||
self.frame.Bind(wx.EVT_MENU, lambda event: subprocess.run(["open", "-R", self.constants.log_filepath]), revealLogItem)
|
||||
self.frame.Bind(wx.EVT_MENU, lambda event: subprocess.run(["/usr/bin/open", "--reveal", self.constants.log_filepath]), revealLogItem)
|
||||
|
||||
if os.geteuid() == 0:
|
||||
relaunchItem.Enable(False)
|
||||
@@ -329,7 +329,7 @@ class RelaunchApplicationAsRoot:
|
||||
|
||||
# Relaunch as root
|
||||
args = [
|
||||
"osascript",
|
||||
"/usr/bin/osascript",
|
||||
"-e",
|
||||
f'''do shell script "{program_arguments}"'''
|
||||
' with prompt "OpenCore Legacy Patcher needs administrator privileges to relaunch as admin."'
|
||||
|
||||
@@ -318,7 +318,7 @@ class SysPatchStartFrame(wx.Frame):
|
||||
if answer == wx.ID_YES:
|
||||
output =subprocess.run(
|
||||
[
|
||||
"osascript", "-e",
|
||||
"/usr/bin/osascript", "-e",
|
||||
'tell app "System Preferences" to activate',
|
||||
"-e", 'tell app "System Preferences" to reveal anchor "General" of pane id "com.apple.preference.security"',
|
||||
],
|
||||
@@ -327,7 +327,7 @@ class SysPatchStartFrame(wx.Frame):
|
||||
)
|
||||
if output.returncode != 0:
|
||||
# Some form of fallback if unaccelerated state errors out
|
||||
subprocess.run(["open", "-a", "System Preferences"])
|
||||
subprocess.run(["/usr/bin/open", "-a", "System Preferences"])
|
||||
time.sleep(5)
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
@@ -184,13 +184,13 @@ class UpdateFrame(wx.Frame):
|
||||
"""
|
||||
logging.info("Extracting update")
|
||||
if Path(self.application_path).exists():
|
||||
subprocess.run(["rm", "-rf", str(self.application_path)])
|
||||
subprocess.run(["/bin/rm", "-rf", str(self.application_path)])
|
||||
|
||||
# Some hell spawn at Github decided to double zip our Github Actions artifacts
|
||||
# So we need to unzip it twice
|
||||
for i in range(2):
|
||||
result = subprocess.run(
|
||||
["ditto", "-xk", str(self.constants.payload_path / "OpenCore-Patcher-GUI.app.zip"), str(self.constants.payload_path)], capture_output=True
|
||||
["/usr/bin/ditto", "-xk", str(self.constants.payload_path / "OpenCore-Patcher-GUI.app.zip"), str(self.constants.payload_path)], capture_output=True
|
||||
)
|
||||
if result.returncode != 0:
|
||||
logging.error(f"Failed to extract update. Error: {result.stderr.decode('utf-8')}")
|
||||
|
||||
Reference in New Issue
Block a user