mirror of
https://github.com/dortania/OpenCore-Legacy-Patcher.git
synced 2026-04-23 19:40:15 +10:00
Compare commits
75 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 | ||
|
|
5db862d38b | ||
|
|
139f94aae1 | ||
|
|
432736eb98 | ||
|
|
6e40a80650 | ||
|
|
21e1b73a4e | ||
|
|
d9676afe43 | ||
|
|
525c7c3173 | ||
|
|
51ef3fe719 | ||
|
|
c6f5ceacfd | ||
|
|
55801e80bd | ||
|
|
4196a7b5f2 | ||
|
|
f0d6faab9a | ||
|
|
6b00caf883 | ||
|
|
d98a653082 | ||
|
|
6d026290ac | ||
|
|
39e58b3927 | ||
|
|
8cfc33e704 | ||
|
|
2b1beff6dc | ||
|
|
d23e483542 | ||
|
|
d57a758c73 | ||
|
|
16b2f1ff55 | ||
|
|
ba0a676ca0 | ||
|
|
2ff132cb04 | ||
|
|
613748488c | ||
|
|
f23c9268f9 | ||
|
|
7160f34a85 | ||
|
|
6767f58047 | ||
|
|
1e781dccb3 | ||
|
|
7e7a5d0f35 | ||
|
|
f91c817fce | ||
|
|
173f77cc31 | ||
|
|
94f870ef5b | ||
|
|
1641e2522b | ||
|
|
de7d024c8f | ||
|
|
253b8b40a0 |
@@ -8,7 +8,6 @@ import sys
|
|||||||
import time
|
import time
|
||||||
import argparse
|
import argparse
|
||||||
import plistlib
|
import plistlib
|
||||||
import platform
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -127,7 +126,7 @@ class CreateBinary:
|
|||||||
if Path(f"./dist/OpenCore-Patcher.app").exists():
|
if Path(f"./dist/OpenCore-Patcher.app").exists():
|
||||||
print("Found OpenCore-Patcher.app, removing...")
|
print("Found OpenCore-Patcher.app, removing...")
|
||||||
rm_output = subprocess.run(
|
rm_output = subprocess.run(
|
||||||
["rm", "-rf", "./dist/OpenCore-Patcher.app"],
|
["/bin/rm", "-rf", "./dist/OpenCore-Patcher.app"],
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
)
|
)
|
||||||
if rm_output.returncode != 0:
|
if rm_output.returncode != 0:
|
||||||
@@ -153,13 +152,11 @@ class CreateBinary:
|
|||||||
print("Embedding icns...")
|
print("Embedding icns...")
|
||||||
for file in Path("payloads/Icon/AppIcons").glob("*.icns"):
|
for file in Path("payloads/Icon/AppIcons").glob("*.icns"):
|
||||||
subprocess.run(
|
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
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _embed_key(self):
|
def _embed_key(self):
|
||||||
"""
|
"""
|
||||||
Embed developer key into binary
|
Embed developer key into binary
|
||||||
@@ -236,11 +233,10 @@ class CreateBinary:
|
|||||||
"Kexts",
|
"Kexts",
|
||||||
"OpenCore",
|
"OpenCore",
|
||||||
"Tools",
|
"Tools",
|
||||||
|
"Launch Services",
|
||||||
]
|
]
|
||||||
|
|
||||||
whitelist_files = [
|
whitelist_files = [
|
||||||
"com.dortania.opencore-legacy-patcher.auto-patch.plist",
|
|
||||||
"com.dortania.opencore-legacy-patcher.rsr-monitor.plist",
|
|
||||||
"entitlements.plist",
|
"entitlements.plist",
|
||||||
"launcher.sh",
|
"launcher.sh",
|
||||||
"OC-Patcher-TUI.icns",
|
"OC-Patcher-TUI.icns",
|
||||||
@@ -254,12 +250,12 @@ class CreateBinary:
|
|||||||
if file.name in whitelist_folders:
|
if file.name in whitelist_folders:
|
||||||
continue
|
continue
|
||||||
print(f"- Deleting {file.name}")
|
print(f"- Deleting {file.name}")
|
||||||
subprocess.run(["rm", "-rf", file])
|
subprocess.run(["/bin/rm", "-rf", file])
|
||||||
else:
|
else:
|
||||||
if file.name in whitelist_files:
|
if file.name in whitelist_files:
|
||||||
continue
|
continue
|
||||||
print(f"- Deleting {file.name}")
|
print(f"- Deleting {file.name}")
|
||||||
subprocess.run(["rm", "-f", file])
|
subprocess.run(["/bin/rm", "-f", file])
|
||||||
|
|
||||||
|
|
||||||
def _download_resources(self):
|
def _download_resources(self):
|
||||||
@@ -281,7 +277,7 @@ class CreateBinary:
|
|||||||
assert resource, "Resource cannot be empty"
|
assert resource, "Resource cannot be empty"
|
||||||
assert resource not in ("/", "."), "Resource cannot be root"
|
assert resource not in ("/", "."), "Resource cannot be root"
|
||||||
rm_output = subprocess.run(
|
rm_output = subprocess.run(
|
||||||
["rm", "-rf", f"./{resource}"],
|
["/bin/rm", "-rf", f"./{resource}"],
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
)
|
)
|
||||||
if rm_output.returncode != 0:
|
if rm_output.returncode != 0:
|
||||||
@@ -295,7 +291,7 @@ class CreateBinary:
|
|||||||
|
|
||||||
download_result = subprocess.run(
|
download_result = subprocess.run(
|
||||||
[
|
[
|
||||||
"curl", "-LO",
|
"/usr/bin/curl", "-LO",
|
||||||
f"https://github.com/dortania/PatcherSupportPkg/releases/download/{patcher_support_pkg_version}/{resource}"
|
f"https://github.com/dortania/PatcherSupportPkg/releases/download/{patcher_support_pkg_version}/{resource}"
|
||||||
],
|
],
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
@@ -324,7 +320,7 @@ class CreateBinary:
|
|||||||
|
|
||||||
print("- Removing old payloads.dmg")
|
print("- Removing old payloads.dmg")
|
||||||
rm_output = subprocess.run(
|
rm_output = subprocess.run(
|
||||||
["rm", "-rf", "./payloads.dmg"],
|
["/bin/rm", "-rf", "./payloads.dmg"],
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
)
|
)
|
||||||
if rm_output.returncode != 0:
|
if rm_output.returncode != 0:
|
||||||
@@ -334,7 +330,7 @@ class CreateBinary:
|
|||||||
|
|
||||||
print("- Generating DMG...")
|
print("- Generating DMG...")
|
||||||
dmg_output = subprocess.run([
|
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
|
'-megabytes', '32000', # Overlays can only be as large as the disk image allows
|
||||||
'-format', 'UDZO', '-ov',
|
'-format', 'UDZO', '-ov',
|
||||||
'-volname', 'OpenCore Patcher Resources (Base)',
|
'-volname', 'OpenCore Patcher Resources (Base)',
|
||||||
@@ -412,7 +408,7 @@ class CreateBinary:
|
|||||||
path = "./dist/OpenCore-Patcher"
|
path = "./dist/OpenCore-Patcher"
|
||||||
print(f"- Removing {path}")
|
print(f"- Removing {path}")
|
||||||
rm_output = subprocess.run(
|
rm_output = subprocess.run(
|
||||||
["rm", "-rf", path],
|
["/bin/rm", "-rf", path],
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
)
|
)
|
||||||
if rm_output.returncode != 0:
|
if rm_output.returncode != 0:
|
||||||
|
|||||||
91
CHANGELOG.md
91
CHANGELOG.md
@@ -1,5 +1,96 @@
|
|||||||
# OpenCore Legacy Patcher changelog
|
# 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
|
||||||
|
- Remove MH_DYLIB_IN_CACHE flag from binaries extracted with DSCE
|
||||||
|
- Add support for detecting T1 Security Chips in DFU mode
|
||||||
|
- Resolve macOS 14.2 coreauthd crashes on T1 Macs
|
||||||
|
- Resolve missing NFC firmware on T1 Macs
|
||||||
|
- Update non-Metal Binaries for macOS Sonoma:
|
||||||
|
- Resolve Photos app crash
|
||||||
|
- Resolve loginwindow crashes
|
||||||
|
- Workaround tile window popup freezing apps by disabling the feature
|
||||||
|
- Workaround monochrome desktop widgets rendering issues by enforcing full color (can be disabled in OCLP settings)
|
||||||
|
- Add new arguments:
|
||||||
|
- `--cache_os`: Cache necessary patcher files for OS to be installed (ex. KDKs)
|
||||||
|
- `--prepare_for_update`: Clean up patcher files for OS to be installed (ex. /Library/Extensions)
|
||||||
|
- Add new Launch Daemons for handling macOS updates:
|
||||||
|
- `macos-update.plist`:
|
||||||
|
- Resolves KDKless Macs failing to boot after updating from 14.0 to 14.x
|
||||||
|
- Adds support for KDK caching for OS to be installed
|
||||||
|
- Invoked when update is staged
|
||||||
|
- `/Library/LaunchDaemons/com.dortania.opencore-legacy-patcher.macos-update.plist`
|
||||||
|
- `os-caching.plist`
|
||||||
|
- Resolves unsupported/old KDKs from being used post-update
|
||||||
|
- Invoked when update is downloading
|
||||||
|
- `/Library/LaunchDaemons/com.dortania.opencore-legacy-patcher.os-caching.plist`
|
||||||
|
- Load UI icons from local path
|
||||||
|
- Resolves macOS downloader crash on slower machines
|
||||||
|
- Resolve iMac18,2 internal 4K display support
|
||||||
|
- Remove News Widget removal from Control Centre
|
||||||
|
- News Widget no longer crashes on 3802-based GPUs
|
||||||
|
- Resolve i210 NIC support for macOS Sonoma
|
||||||
|
- Increment Binaries:
|
||||||
|
- PatcherSupportPkg 1.4.5 - release
|
||||||
|
- OpenCorePkg 0.9.6 - release
|
||||||
|
|
||||||
## 1.1.0
|
## 1.1.0
|
||||||
- Resolve rendering issues on Intel Broadwell iGPUs
|
- Resolve rendering issues on Intel Broadwell iGPUs
|
||||||
- Update non-Metal Binaries for macOS Sonoma:
|
- Update non-Metal Binaries for macOS Sonoma:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
Copyright (c) 2020-2023, Dhinak G
|
Copyright (c) 2020-2024, Dhinak G
|
||||||
Copyright (c) 2020-2023, Mykola Grymalyuk
|
Copyright (c) 2020-2024, Mykola Grymalyuk
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,28 @@
|
|||||||
# -*- mode: python ; coding: utf-8 -*-
|
# -*- 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()))
|
sys.path.append(os.path.abspath(os.getcwd()))
|
||||||
|
|
||||||
from resources import constants
|
from resources import constants
|
||||||
|
|
||||||
block_cipher = None
|
block_cipher = None
|
||||||
|
|
||||||
datas = [
|
datas = [
|
||||||
('payloads.dmg', '.'),
|
('payloads.dmg', '.'),
|
||||||
('Universal-Binaries.dmg', '.'),
|
('Universal-Binaries.dmg', '.'),
|
||||||
|
|
||||||
]
|
]
|
||||||
if pathlib.Path("DortaniaInternalResources.dmg").exists():
|
|
||||||
|
if Path("DortaniaInternalResources.dmg").exists():
|
||||||
datas.append(('DortaniaInternalResources.dmg', '.'))
|
datas.append(('DortaniaInternalResources.dmg', '.'))
|
||||||
|
|
||||||
|
|
||||||
@@ -27,8 +39,10 @@ a = Analysis(['OpenCore-Patcher-GUI.command'],
|
|||||||
win_private_assemblies=False,
|
win_private_assemblies=False,
|
||||||
cipher=block_cipher,
|
cipher=block_cipher,
|
||||||
noarchive=False)
|
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,
|
exe = EXE(pyz,
|
||||||
a.scripts,
|
a.scripts,
|
||||||
@@ -43,7 +57,8 @@ exe = EXE(pyz,
|
|||||||
disable_windowed_traceback=False,
|
disable_windowed_traceback=False,
|
||||||
target_arch="universal2",
|
target_arch="universal2",
|
||||||
codesign_identity=None,
|
codesign_identity=None,
|
||||||
entitlements_file=None )
|
entitlements_file=None)
|
||||||
|
|
||||||
coll = COLLECT(exe,
|
coll = COLLECT(exe,
|
||||||
a.binaries,
|
a.binaries,
|
||||||
a.zipfiles,
|
a.zipfiles,
|
||||||
@@ -52,6 +67,7 @@ coll = COLLECT(exe,
|
|||||||
upx=True,
|
upx=True,
|
||||||
upx_exclude=[],
|
upx_exclude=[],
|
||||||
name='OpenCore-Patcher')
|
name='OpenCore-Patcher')
|
||||||
|
|
||||||
app = BUNDLE(coll,
|
app = BUNDLE(coll,
|
||||||
name='OpenCore-Patcher.app',
|
name='OpenCore-Patcher.app',
|
||||||
icon="payloads/OC-Patcher.icns",
|
icon="payloads/OC-Patcher.icns",
|
||||||
@@ -64,6 +80,6 @@ app = BUNDLE(coll,
|
|||||||
"NSRequiresAquaSystemAppearance": False,
|
"NSRequiresAquaSystemAppearance": False,
|
||||||
"NSHighResolutionCapable": True,
|
"NSHighResolutionCapable": True,
|
||||||
"Build Date": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
|
"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",
|
"NSPrincipalClass": "NSApplication",
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ Our project's main goal is to breathe new life into Macs no longer supported by
|
|||||||
|
|
||||||
Noteworthy features of OpenCore Legacy Patcher:
|
Noteworthy features of OpenCore Legacy Patcher:
|
||||||
|
|
||||||
* Support for macOS Big Sur, Monterey and Ventura
|
* Support for macOS Big Sur, Monterey, Ventura, and Sonoma
|
||||||
* Native Over the Air (OTA) System Updates
|
* Native Over the Air (OTA) System Updates
|
||||||
* Supports Penryn and newer Macs
|
* Supports Penryn and newer Macs
|
||||||
* Full support for WPA Wi-Fi and Personal Hotspot on BCM943224 and newer wireless chipsets
|
* Full support for WPA Wi-Fi and Personal Hotspot on BCM943224 and newer wireless chipsets
|
||||||
@@ -32,7 +32,7 @@ Note: Only clean-installs and upgrades are supported. macOS Big Sur installs alr
|
|||||||
|
|
||||||
* You can, however, reinstall macOS with this patcher and retain your original data
|
* You can, however, reinstall macOS with this patcher and retain your original data
|
||||||
|
|
||||||
Note 2: Currently, OpenCore Legacy Patcher officially supports patching to run macOS Big Sur through Ventura installs. For older OSes, OpenCore may function; however, support is currently not provided from Dortania.
|
Note 2: Currently, OpenCore Legacy Patcher officially supports patching to run macOS Big Sur through Sonoma installs. For older OSes, OpenCore may function; however, support is currently not provided from Dortania.
|
||||||
|
|
||||||
* For macOS Mojave and Catalina support, we recommend the use of [dosdude1's patchers](http://dosdude1.com)
|
* For macOS Mojave and Catalina support, we recommend the use of [dosdude1's patchers](http://dosdude1.com)
|
||||||
|
|
||||||
|
|||||||
1210
data/css_data.py
Normal file
1210
data/css_data.py
Normal file
File diff suppressed because it is too large
Load Diff
@@ -2363,7 +2363,7 @@ smbios_dictionary = {
|
|||||||
"Wireless Model": device_probe.Broadcom.Chipsets.AirportBrcmNIC,
|
"Wireless Model": device_probe.Broadcom.Chipsets.AirportBrcmNIC,
|
||||||
"Bluetooth Model": bluetooth_data.bluetooth_data.BRCM20702_v2,
|
"Bluetooth Model": bluetooth_data.bluetooth_data.BRCM20702_v2,
|
||||||
"Ethernet Chipset": "Broadcom",
|
"Ethernet Chipset": "Broadcom",
|
||||||
"5K Display": True,
|
"Dual DisplayPort Display": True,
|
||||||
"Stock GPUs": [
|
"Stock GPUs": [
|
||||||
device_probe.Intel.Archs.Haswell,
|
device_probe.Intel.Archs.Haswell,
|
||||||
device_probe.AMD.Archs.Legacy_GCN_7000,
|
device_probe.AMD.Archs.Legacy_GCN_7000,
|
||||||
@@ -2382,7 +2382,7 @@ smbios_dictionary = {
|
|||||||
"Wireless Model": device_probe.Broadcom.Chipsets.AirportBrcmNIC,
|
"Wireless Model": device_probe.Broadcom.Chipsets.AirportBrcmNIC,
|
||||||
"Bluetooth Model": bluetooth_data.bluetooth_data.BRCM20702_v2,
|
"Bluetooth Model": bluetooth_data.bluetooth_data.BRCM20702_v2,
|
||||||
"Ethernet Chipset": "Broadcom",
|
"Ethernet Chipset": "Broadcom",
|
||||||
"5K Display": True,
|
"Dual DisplayPort Display": True,
|
||||||
"Stock GPUs": [
|
"Stock GPUs": [
|
||||||
device_probe.Intel.Archs.Haswell,
|
device_probe.Intel.Archs.Haswell,
|
||||||
device_probe.AMD.Archs.Legacy_GCN_7000,
|
device_probe.AMD.Archs.Legacy_GCN_7000,
|
||||||
@@ -2438,7 +2438,7 @@ smbios_dictionary = {
|
|||||||
"Wireless Model": device_probe.Broadcom.Chipsets.AirportBrcmNIC,
|
"Wireless Model": device_probe.Broadcom.Chipsets.AirportBrcmNIC,
|
||||||
"Bluetooth Model": bluetooth_data.bluetooth_data.BRCM20702_v2,
|
"Bluetooth Model": bluetooth_data.bluetooth_data.BRCM20702_v2,
|
||||||
"Ethernet Chipset": "Broadcom",
|
"Ethernet Chipset": "Broadcom",
|
||||||
"5K Display": True,
|
"Dual DisplayPort Display": True,
|
||||||
"Stock GPUs": [
|
"Stock GPUs": [
|
||||||
device_probe.Intel.Archs.Skylake,
|
device_probe.Intel.Archs.Skylake,
|
||||||
device_probe.AMD.Archs.Legacy_GCN_8000,
|
device_probe.AMD.Archs.Legacy_GCN_8000,
|
||||||
@@ -2458,7 +2458,7 @@ smbios_dictionary = {
|
|||||||
"Wireless Model": device_probe.Broadcom.Chipsets.AirportBrcmNIC,
|
"Wireless Model": device_probe.Broadcom.Chipsets.AirportBrcmNIC,
|
||||||
"Bluetooth Model": bluetooth_data.bluetooth_data.BRCM20702_v2,
|
"Bluetooth Model": bluetooth_data.bluetooth_data.BRCM20702_v2,
|
||||||
"Ethernet Chipset": "Broadcom",
|
"Ethernet Chipset": "Broadcom",
|
||||||
"5K Display": True,
|
"Dual DisplayPort Display": True,
|
||||||
"Stock GPUs": [
|
"Stock GPUs": [
|
||||||
device_probe.Intel.Archs.Skylake,
|
device_probe.Intel.Archs.Skylake,
|
||||||
device_probe.AMD.Archs.Legacy_GCN_8000,
|
device_probe.AMD.Archs.Legacy_GCN_8000,
|
||||||
@@ -2478,7 +2478,7 @@ smbios_dictionary = {
|
|||||||
"Wireless Model": device_probe.Broadcom.Chipsets.AirportBrcmNIC,
|
"Wireless Model": device_probe.Broadcom.Chipsets.AirportBrcmNIC,
|
||||||
"Bluetooth Model": bluetooth_data.bluetooth_data.BRCM20702_v2,
|
"Bluetooth Model": bluetooth_data.bluetooth_data.BRCM20702_v2,
|
||||||
"Ethernet Chipset": "Broadcom",
|
"Ethernet Chipset": "Broadcom",
|
||||||
"5K Display": True,
|
"Dual DisplayPort Display": True,
|
||||||
"Stock GPUs": [
|
"Stock GPUs": [
|
||||||
device_probe.Intel.Archs.Skylake,
|
device_probe.Intel.Archs.Skylake,
|
||||||
device_probe.AMD.Archs.Legacy_GCN_8000,
|
device_probe.AMD.Archs.Legacy_GCN_8000,
|
||||||
@@ -2517,6 +2517,7 @@ smbios_dictionary = {
|
|||||||
"Wireless Model": device_probe.Broadcom.Chipsets.AirportBrcmNIC,
|
"Wireless Model": device_probe.Broadcom.Chipsets.AirportBrcmNIC,
|
||||||
"Bluetooth Model": bluetooth_data.bluetooth_data.BRCM20703,
|
"Bluetooth Model": bluetooth_data.bluetooth_data.BRCM20703,
|
||||||
"Ethernet Chipset": "Broadcom",
|
"Ethernet Chipset": "Broadcom",
|
||||||
|
"Dual DisplayPort Display": True,
|
||||||
"Stock GPUs": [
|
"Stock GPUs": [
|
||||||
device_probe.Intel.Archs.Kaby_Lake,
|
device_probe.Intel.Archs.Kaby_Lake,
|
||||||
device_probe.AMD.Archs.Polaris,
|
device_probe.AMD.Archs.Polaris,
|
||||||
@@ -2536,7 +2537,7 @@ smbios_dictionary = {
|
|||||||
"Wireless Model": device_probe.Broadcom.Chipsets.AirportBrcmNIC,
|
"Wireless Model": device_probe.Broadcom.Chipsets.AirportBrcmNIC,
|
||||||
"Bluetooth Model": bluetooth_data.bluetooth_data.BRCM20703,
|
"Bluetooth Model": bluetooth_data.bluetooth_data.BRCM20703,
|
||||||
"Ethernet Chipset": "Broadcom",
|
"Ethernet Chipset": "Broadcom",
|
||||||
"5K Display": True,
|
"Dual DisplayPort Display": True,
|
||||||
"Stock GPUs": [
|
"Stock GPUs": [
|
||||||
device_probe.Intel.Archs.Kaby_Lake,
|
device_probe.Intel.Archs.Kaby_Lake,
|
||||||
device_probe.AMD.Archs.Polaris,
|
device_probe.AMD.Archs.Polaris,
|
||||||
@@ -2556,7 +2557,7 @@ smbios_dictionary = {
|
|||||||
"Wireless Model": device_probe.Broadcom.Chipsets.AppleBCMWLANBusInterfacePCIe,
|
"Wireless Model": device_probe.Broadcom.Chipsets.AppleBCMWLANBusInterfacePCIe,
|
||||||
"Bluetooth Model": bluetooth_data.bluetooth_data.UART,
|
"Bluetooth Model": bluetooth_data.bluetooth_data.UART,
|
||||||
"Ethernet Chipset": "Broadcom",
|
"Ethernet Chipset": "Broadcom",
|
||||||
"5K Display": True,
|
"Dual DisplayPort Display": True,
|
||||||
"Stock GPUs": [
|
"Stock GPUs": [
|
||||||
device_probe.Intel.Archs.Coffee_Lake,
|
device_probe.Intel.Archs.Coffee_Lake,
|
||||||
device_probe.AMD.Archs.Polaris,
|
device_probe.AMD.Archs.Polaris,
|
||||||
@@ -2577,7 +2578,7 @@ smbios_dictionary = {
|
|||||||
"Wireless Model": device_probe.Broadcom.Chipsets.AppleBCMWLANBusInterfacePCIe,
|
"Wireless Model": device_probe.Broadcom.Chipsets.AppleBCMWLANBusInterfacePCIe,
|
||||||
"Bluetooth Model": bluetooth_data.bluetooth_data.UART,
|
"Bluetooth Model": bluetooth_data.bluetooth_data.UART,
|
||||||
"Ethernet Chipset": "Broadcom",
|
"Ethernet Chipset": "Broadcom",
|
||||||
"5K Display": True,
|
"Dual DisplayPort Display": True,
|
||||||
"Stock GPUs": [
|
"Stock GPUs": [
|
||||||
device_probe.Intel.Archs.Coffee_Lake,
|
device_probe.Intel.Archs.Coffee_Lake,
|
||||||
device_probe.AMD.Archs.Polaris,
|
device_probe.AMD.Archs.Polaris,
|
||||||
@@ -2598,6 +2599,7 @@ smbios_dictionary = {
|
|||||||
"Wireless Model": device_probe.Broadcom.Chipsets.AppleBCMWLANBusInterfacePCIe,
|
"Wireless Model": device_probe.Broadcom.Chipsets.AppleBCMWLANBusInterfacePCIe,
|
||||||
"Bluetooth Model": bluetooth_data.bluetooth_data.UART,
|
"Bluetooth Model": bluetooth_data.bluetooth_data.UART,
|
||||||
"Ethernet Chipset": "Broadcom",
|
"Ethernet Chipset": "Broadcom",
|
||||||
|
"Dual DisplayPort Display": True,
|
||||||
"Stock GPUs": [
|
"Stock GPUs": [
|
||||||
device_probe.Intel.Archs.Coffee_Lake,
|
device_probe.Intel.Archs.Coffee_Lake,
|
||||||
device_probe.AMD.Archs.Polaris,
|
device_probe.AMD.Archs.Polaris,
|
||||||
@@ -2618,7 +2620,7 @@ smbios_dictionary = {
|
|||||||
"Wireless Model": device_probe.Broadcom.Chipsets.AppleBCMWLANBusInterfacePCIe,
|
"Wireless Model": device_probe.Broadcom.Chipsets.AppleBCMWLANBusInterfacePCIe,
|
||||||
"Bluetooth Model": bluetooth_data.bluetooth_data.UART,
|
"Bluetooth Model": bluetooth_data.bluetooth_data.UART,
|
||||||
"Ethernet Chipset": "Broadcom",
|
"Ethernet Chipset": "Broadcom",
|
||||||
"5K Display": True,
|
"Dual DisplayPort Display": True,
|
||||||
"Stock GPUs": [
|
"Stock GPUs": [
|
||||||
device_probe.Intel.Archs.Comet_Lake,
|
device_probe.Intel.Archs.Comet_Lake,
|
||||||
device_probe.AMD.Archs.Navi,
|
device_probe.AMD.Archs.Navi,
|
||||||
@@ -2637,7 +2639,7 @@ smbios_dictionary = {
|
|||||||
"Wireless Model": device_probe.Broadcom.Chipsets.AppleBCMWLANBusInterfacePCIe,
|
"Wireless Model": device_probe.Broadcom.Chipsets.AppleBCMWLANBusInterfacePCIe,
|
||||||
"Bluetooth Model": bluetooth_data.bluetooth_data.UART,
|
"Bluetooth Model": bluetooth_data.bluetooth_data.UART,
|
||||||
"Ethernet Chipset": "Broadcom",
|
"Ethernet Chipset": "Broadcom",
|
||||||
"5K Display": True,
|
"Dual DisplayPort Display": True,
|
||||||
"Stock GPUs": [
|
"Stock GPUs": [
|
||||||
device_probe.Intel.Archs.Comet_Lake,
|
device_probe.Intel.Archs.Comet_Lake,
|
||||||
device_probe.AMD.Archs.Navi,
|
device_probe.AMD.Archs.Navi,
|
||||||
@@ -2684,7 +2686,7 @@ smbios_dictionary = {
|
|||||||
"Wireless Model": device_probe.Broadcom.Chipsets.AppleBCMWLANBusInterfacePCIe,
|
"Wireless Model": device_probe.Broadcom.Chipsets.AppleBCMWLANBusInterfacePCIe,
|
||||||
"Bluetooth Model": bluetooth_data.bluetooth_data.UART,
|
"Bluetooth Model": bluetooth_data.bluetooth_data.UART,
|
||||||
"Ethernet Chipset": "Aquantia",
|
"Ethernet Chipset": "Aquantia",
|
||||||
"5K Display": True,
|
"Dual DisplayPort Display": True,
|
||||||
"Stock GPUs": [
|
"Stock GPUs": [
|
||||||
device_probe.AMD.Archs.Vega,
|
device_probe.AMD.Archs.Vega,
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Dictionary defining patch sets used during Root Volume patching (sys_patch.py)
|
# Dictionary defining patch sets used during Root Volume patching (sys_patch.py)
|
||||||
# Copyright (C) 2022-2023, Mykola Grymalyuk
|
# Copyright (C) 2022-2023, Mykola Grymalyuk
|
||||||
|
|
||||||
|
import packaging.version
|
||||||
|
|
||||||
from data import os_data
|
from data import os_data
|
||||||
|
|
||||||
|
|
||||||
@@ -9,7 +11,7 @@ class SystemPatchDictionary():
|
|||||||
Library for generating patch sets for sys_patch.py and supporting modules
|
Library for generating patch sets for sys_patch.py and supporting modules
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
>>> patchsets = SystemPatchDictionary(22, 0, [20, 21, 22]).patchset_dict
|
>>> patchsets = SystemPatchDictionary(22, 0, [20, 21, 22], "13.0").patchset_dict
|
||||||
|
|
||||||
|
|
||||||
Patchset Schema:
|
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
|
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:
|
Parameters:
|
||||||
os_major (int): Major XNU Kernel version
|
os_major (int): Major XNU Kernel version
|
||||||
os_minor (int): Minor XNU Kernel version
|
os_minor (int): Minor XNU Kernel version
|
||||||
non_metal_os_support (list): List of supported non-metal OSes (XNU Major Versions)
|
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
|
'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.os_float: float = float(f"{self.os_major}.{self.os_minor}")
|
||||||
self.non_metal_os_support: list = non_metal_os_support
|
self.non_metal_os_support: list = non_metal_os_support
|
||||||
self.patchset_dict: dict = {}
|
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
|
# XNU Kernel versions
|
||||||
self.macOS_12_0_B7: float = 21.1
|
self.macOS_12_0_B7: float = 21.1
|
||||||
@@ -71,10 +77,76 @@ class SystemPatchDictionary():
|
|||||||
self.macOS_12_5: float = 21.6
|
self.macOS_12_5: float = 21.6
|
||||||
self.macOS_13_3: float = 22.4
|
self.macOS_13_3: float = 22.4
|
||||||
self.macOS_14_1: float = 23.1
|
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()
|
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):
|
def _generate_sys_patch_dict(self):
|
||||||
"""
|
"""
|
||||||
Generates the sys_patch_dict dictionary
|
Generates the sys_patch_dict dictionary
|
||||||
@@ -155,6 +227,7 @@ class SystemPatchDictionary():
|
|||||||
"defaults write /Library/Preferences/.GlobalPreferences.plist WebKitExperimentalUseGPUProcessForCanvasRenderingEnabled -bool false": True,
|
"defaults write /Library/Preferences/.GlobalPreferences.plist WebKitExperimentalUseGPUProcessForCanvasRenderingEnabled -bool false": True,
|
||||||
**({"defaults write /Library/Preferences/.GlobalPreferences.plist WebKitPreferences.acceleratedDrawingEnabled -bool false": True} if self.os_major >= os_data.os_data.sonoma else {}),
|
**({"defaults write /Library/Preferences/.GlobalPreferences.plist WebKitPreferences.acceleratedDrawingEnabled -bool false": True} if self.os_major >= os_data.os_data.sonoma else {}),
|
||||||
**({"defaults write /Library/Preferences/.GlobalPreferences.plist NSEnableAppKitMenus -bool false": True} if self.os_major >= os_data.os_data.sonoma else {}),
|
**({"defaults write /Library/Preferences/.GlobalPreferences.plist NSEnableAppKitMenus -bool false": True} if self.os_major >= os_data.os_data.sonoma else {}),
|
||||||
|
**({"defaults write /Library/Preferences/.GlobalPreferences.plist NSZoomButtonShowMenu -bool false": True} if self.os_major >= os_data.os_data.sonoma else {}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"Non-Metal IOAccelerator Common": {
|
"Non-Metal IOAccelerator Common": {
|
||||||
@@ -387,6 +460,11 @@ class SystemPatchDictionary():
|
|||||||
**({ "MTLCompiler.framework": "13.2.1" } if self.os_major == os_data.os_data.ventura else {}),
|
**({ "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 {}),
|
**({ "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",
|
"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 {}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -577,7 +655,7 @@ class SystemPatchDictionary():
|
|||||||
},
|
},
|
||||||
"Install": {
|
"Install": {
|
||||||
"/System/Library/Extensions": {
|
"/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",
|
"NVDAGF100Hal.kext": "12.0 Beta 6",
|
||||||
"NVDAGK100Hal.kext": "12.0 Beta 6",
|
"NVDAGK100Hal.kext": "12.0 Beta 6",
|
||||||
"NVDAResman.kext": "12.0 Beta 6",
|
"NVDAResman.kext": "12.0 Beta 6",
|
||||||
@@ -774,7 +852,7 @@ class SystemPatchDictionary():
|
|||||||
"AMD9000Controller.kext": "12.5",
|
"AMD9000Controller.kext": "12.5",
|
||||||
"AMD9500Controller.kext": "12.5",
|
"AMD9500Controller.kext": "12.5",
|
||||||
"AMD10000Controller.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",
|
"AMDRadeonX4000HWServices.kext": "12.5",
|
||||||
"AMDFramebuffer.kext": "12.5" if self.os_float < self.macOS_13_3 else "12.5-GCN",
|
"AMDFramebuffer.kext": "12.5" if self.os_float < self.macOS_13_3 else "12.5-GCN",
|
||||||
"AMDSupport.kext": "12.5",
|
"AMDSupport.kext": "12.5",
|
||||||
@@ -837,7 +915,7 @@ class SystemPatchDictionary():
|
|||||||
},
|
},
|
||||||
"Install": {
|
"Install": {
|
||||||
"/System/Library/Extensions": {
|
"/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",
|
"AMDRadeonX4000HWServices.kext": "12.5",
|
||||||
|
|
||||||
"AMDRadeonVADriver2.bundle": "12.5",
|
"AMDRadeonVADriver2.bundle": "12.5",
|
||||||
@@ -861,7 +939,7 @@ class SystemPatchDictionary():
|
|||||||
},
|
},
|
||||||
"Install": {
|
"Install": {
|
||||||
"/System/Library/Extensions": {
|
"/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",
|
"AMDRadeonVADriver2.bundle": "12.5",
|
||||||
"AMDRadeonX5000GLDriver.bundle": "12.5",
|
"AMDRadeonX5000GLDriver.bundle": "12.5",
|
||||||
@@ -955,8 +1033,8 @@ class SystemPatchDictionary():
|
|||||||
"AppleIntelHD4000GraphicsGLDriver.bundle": "11.0 Beta 6",
|
"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",
|
"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",
|
"AppleIntelHD4000GraphicsVADriver.bundle": "11.3 Beta 1",
|
||||||
"AppleIntelFramebufferCapri.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": "11.4" if self.os_major < os_data.os_data.sonoma else "11.4-23",
|
"AppleIntelHD4000Graphics.kext": self.__resolve_ivy_bridge_framebuffers(),
|
||||||
"AppleIntelIVBVA.bundle": "11.4",
|
"AppleIntelIVBVA.bundle": "11.4",
|
||||||
"AppleIntelGraphicsShared.bundle": "11.4", # libIGIL-Metal.dylib pulled from 11.0 Beta 6
|
"AppleIntelGraphicsShared.bundle": "11.4", # libIGIL-Metal.dylib pulled from 11.0 Beta 6
|
||||||
},
|
},
|
||||||
@@ -976,8 +1054,8 @@ class SystemPatchDictionary():
|
|||||||
},
|
},
|
||||||
"Install": {
|
"Install": {
|
||||||
"/System/Library/Extensions": {
|
"/System/Library/Extensions": {
|
||||||
"AppleIntelFramebufferAzul.kext": "12.5" if self.os_major < os_data.os_data.sonoma else "12.5-23",
|
"AppleIntelFramebufferAzul.kext": self.__resolve_monterey_framebuffers(),
|
||||||
"AppleIntelHD5000Graphics.kext": "12.5" if self.os_major < os_data.os_data.sonoma else "12.5-23",
|
"AppleIntelHD5000Graphics.kext": self.__resolve_monterey_framebuffers(),
|
||||||
"AppleIntelHD5000GraphicsGLDriver.bundle": "12.5",
|
"AppleIntelHD5000GraphicsGLDriver.bundle": "12.5",
|
||||||
"AppleIntelHD5000GraphicsMTLDriver.bundle": "12.5",
|
"AppleIntelHD5000GraphicsMTLDriver.bundle": "12.5",
|
||||||
"AppleIntelHD5000GraphicsVADriver.bundle": "12.5",
|
"AppleIntelHD5000GraphicsVADriver.bundle": "12.5",
|
||||||
@@ -1000,10 +1078,10 @@ class SystemPatchDictionary():
|
|||||||
},
|
},
|
||||||
"Install": {
|
"Install": {
|
||||||
"/System/Library/Extensions": {
|
"/System/Library/Extensions": {
|
||||||
"AppleIntelBDWGraphics.kext": "12.5" if self.os_major < os_data.os_data.sonoma else "12.5-23",
|
"AppleIntelBDWGraphics.kext": self.__resolve_monterey_framebuffers(),
|
||||||
"AppleIntelBDWGraphicsFramebuffer.kext": "12.5" if self.os_major < os_data.os_data.sonoma else "12.5-23",
|
"AppleIntelBDWGraphicsFramebuffer.kext": self.__resolve_monterey_framebuffers(),
|
||||||
"AppleIntelBDWGraphicsGLDriver.bundle": "12.5",
|
"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",
|
"AppleIntelBDWGraphicsVADriver.bundle": "12.5",
|
||||||
"AppleIntelBDWGraphicsVAME.bundle": "12.5",
|
"AppleIntelBDWGraphicsVAME.bundle": "12.5",
|
||||||
"AppleIntelGraphicsShared.bundle": "12.5",
|
"AppleIntelGraphicsShared.bundle": "12.5",
|
||||||
@@ -1024,8 +1102,8 @@ class SystemPatchDictionary():
|
|||||||
},
|
},
|
||||||
"Install": {
|
"Install": {
|
||||||
"/System/Library/Extensions": {
|
"/System/Library/Extensions": {
|
||||||
"AppleIntelSKLGraphics.kext": "12.5" if self.os_major < os_data.os_data.sonoma else "12.5-23",
|
"AppleIntelSKLGraphics.kext": self.__resolve_monterey_framebuffers(),
|
||||||
"AppleIntelSKLGraphicsFramebuffer.kext": "12.5" if self.os_major < os_data.os_data.sonoma else "12.5-23",
|
"AppleIntelSKLGraphicsFramebuffer.kext": self.__resolve_monterey_framebuffers(),
|
||||||
"AppleIntelSKLGraphicsGLDriver.bundle": "12.5",
|
"AppleIntelSKLGraphicsGLDriver.bundle": "12.5",
|
||||||
"AppleIntelSKLGraphicsMTLDriver.bundle": "12.5",
|
"AppleIntelSKLGraphicsMTLDriver.bundle": "12.5",
|
||||||
"AppleIntelSKLGraphicsVADriver.bundle": "12.5",
|
"AppleIntelSKLGraphicsVADriver.bundle": "12.5",
|
||||||
@@ -1100,10 +1178,10 @@ class SystemPatchDictionary():
|
|||||||
},
|
},
|
||||||
"Install": {
|
"Install": {
|
||||||
"/usr/libexec": {
|
"/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": {
|
"/System/Library/CoreServices": {
|
||||||
"WiFiAgent.app": "11.7.1",
|
"WiFiAgent.app": "11.7.10",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"Install Non-Root": {
|
"Install Non-Root": {
|
||||||
@@ -1127,19 +1205,16 @@ class SystemPatchDictionary():
|
|||||||
},
|
},
|
||||||
"Install": {
|
"Install": {
|
||||||
"/usr/libexec": {
|
"/usr/libexec": {
|
||||||
"wps": "12.6.2",
|
"wps": "12.7.2",
|
||||||
"wifip2pd": "12.6.2",
|
"wifip2pd": "12.7.2",
|
||||||
"wifianalyticsd": "13.5",
|
|
||||||
},
|
},
|
||||||
"/System/Library/Frameworks": {
|
"/System/Library/Frameworks": {
|
||||||
"CoreWLAN.framework": "12.6.2",
|
"CoreWLAN.framework": "12.7.2",
|
||||||
},
|
},
|
||||||
"/System/Library/PrivateFrameworks": {
|
"/System/Library/PrivateFrameworks": {
|
||||||
"CoreWiFi.framework": "12.6.2",
|
"CoreWiFi.framework": "12.7.2",
|
||||||
"IO80211.framework": "12.6.2",
|
"IO80211.framework": "12.7.2",
|
||||||
"WiFiPeerToPeer.framework": "12.6.2",
|
"WiFiPeerToPeer.framework": "12.7.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 {}),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -1159,20 +1234,16 @@ class SystemPatchDictionary():
|
|||||||
},
|
},
|
||||||
"Install": {
|
"Install": {
|
||||||
"/usr/libexec": {
|
"/usr/libexec": {
|
||||||
"airportd": "13.5",
|
"airportd": "13.6.5",
|
||||||
"wifianalyticsd": "13.5",
|
"wifip2pd": "13.6.5",
|
||||||
"wifip2pd": "13.5",
|
|
||||||
},
|
},
|
||||||
"/System/Library/Frameworks": {
|
"/System/Library/Frameworks": {
|
||||||
"CoreWLAN.framework": "13.5",
|
"CoreWLAN.framework": "13.6.5",
|
||||||
},
|
},
|
||||||
"/System/Library/PrivateFrameworks": {
|
"/System/Library/PrivateFrameworks": {
|
||||||
"CoreAnalytics.framework": "13.5",
|
"CoreWiFi.framework": "13.6.5",
|
||||||
"CoreWiFi.framework": "13.5",
|
"IO80211.framework": "13.6.5",
|
||||||
"IO80211.framework": "13.5",
|
"WiFiPeerToPeer.framework": "13.6.5",
|
||||||
"WiFiAnalytics.framework": "13.5",
|
|
||||||
"WiFiPolicy.framework": "13.5",
|
|
||||||
"WiFiPeerToPeer.framework": "13.5",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -1264,7 +1335,7 @@ class SystemPatchDictionary():
|
|||||||
},
|
},
|
||||||
"Install": {
|
"Install": {
|
||||||
"/System/Library/Extensions": {
|
"/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",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -1347,13 +1418,21 @@ class SystemPatchDictionary():
|
|||||||
"libnfshared.dylib": "13.6",
|
"libnfshared.dylib": "13.6",
|
||||||
"libnfshared.dylibOld.dylib": "13.6",
|
"libnfshared.dylibOld.dylib": "13.6",
|
||||||
"libnfstorage.dylib": "13.6",
|
"libnfstorage.dylib": "13.6",
|
||||||
|
"libnfrestore.dylib": "13.6",
|
||||||
|
|
||||||
"libPN548_API.dylib": "13.6"
|
"libPN548_API.dylib": "13.6"
|
||||||
},
|
},
|
||||||
"/usr/libexec": {
|
"/usr/libexec": {
|
||||||
"biometrickitd": "13.6", # Required for Touch ID
|
"biometrickitd": "13.6", # Required for Touch ID
|
||||||
"nfcd": "13.6", # Required for Apple Pay
|
"nfcd": "13.6", # Required for Apple Pay
|
||||||
|
"nfrestore_service": "13.6", # Required for Apple Pay
|
||||||
},
|
},
|
||||||
|
"/usr/standalone/firmware/nfrestore/firmware/fw": {
|
||||||
|
"PN549_FW_02_01_5A_rev88207.bin": "13.6",
|
||||||
|
"SN100V_FW_A3_01_01_81_rev127208.bin": "13.6",
|
||||||
|
"SN200V_FW_B1_02_01_86_rev127266.bin": "13.6",
|
||||||
|
"SN300V_FW_B0_02_01_22_rev129172.bin": "13.6",
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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+
|
::: 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)
|
[Download TCCPlus](https://github.com/jslegendre/tccplus)
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,7 @@
|
|||||||
# Supporting the patcher
|
# 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:
|
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.
|
||||||
|
|
||||||
* 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.
|
|
||||||
|
|||||||
@@ -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.
|
* 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.
|
||||||
|
|
||||||
|
|||||||
126
docs/MODELS.md
126
docs/MODELS.md
@@ -24,85 +24,85 @@ The patcher is designed to target **macOS Big Sur 11.x to macOS Sonoma 14.x**.
|
|||||||
|
|
||||||
### MacBook
|
### MacBook
|
||||||
|
|
||||||
| Model Name | Identifier | Tagged Issues |
|
| Model Name | Identifier | Tagged Issues |
|
||||||
| :--- | :--- | :--- |
|
| :--- | :--- | :--- |
|
||||||
| MacBook (13-inch, Late 2008) | `MacBook5,1` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021)|
|
| MacBook (13-inch, Aluminum, Late 2008) | `MacBook5,1` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021)|
|
||||||
| MacBook (13-inch, Early 2009)<br>MacBook (13-inch, Mid 2009) | `MacBook5,2` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021)<br>- Trackpad gestures are partially broken |
|
| MacBook (13-inch, Early 2009)<br>MacBook (13-inch, Mid 2009) | `MacBook5,2` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021)<br>- Trackpad gestures are partially broken |
|
||||||
| MacBook (13-inch, Late 2009) | `MacBook6,1` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021) |
|
| MacBook (13-inch, Late 2009) | `MacBook6,1` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021) |
|
||||||
| MacBook (13-inch, Mid 2010) | `MacBook7,1` | ^^ |
|
| MacBook (13-inch, Mid 2010) | `MacBook7,1` | ^^ |
|
||||||
| MacBook (Retina, 12-inch, Early 2015) | `MacBook8,1` | - [Legacy Metal (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1008) |
|
| MacBook (Retina, 12-inch, Early 2015) | `MacBook8,1` | - [Legacy Metal (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1008) |
|
||||||
| MacBook (Retina, 12-inch, Early 2016) | `MacBook9,1` | ^^ |
|
| MacBook (Retina, 12-inch, Early 2016) | `MacBook9,1` | ^^ |
|
||||||
| MacBook (Retina, 12-inch, 2017) | `MacBook10,1` | - Supported by OpenCore Legacy Patcher |
|
| MacBook (Retina, 12-inch, 2017) | `MacBook10,1` | - Supported by OpenCore Legacy Patcher |
|
||||||
|
|
||||||
### MacBook Air
|
### MacBook Air
|
||||||
|
|
||||||
| Model Name | Identifier | Tagged Issues |
|
| Model Name | Identifier | Tagged Issues |
|
||||||
| :--- | :--- | :--- |
|
| :--- | :--- | :--- |
|
||||||
| MacBook Air (13-inch, Late 2008)<br>MacBook Air (13-inch, Mid 2009) | `MacBookAir2,1` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021)|
|
| MacBook Air (13-inch, Late 2008)<br>MacBook Air (13-inch, Mid 2009) | `MacBookAir2,1` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021)|
|
||||||
| MacBook Air (11-inch, Late 2010) | `MacBookAir3,1` | ^^ |
|
| MacBook Air (11-inch, Late 2010) | `MacBookAir3,1` | ^^ |
|
||||||
| MacBook Air (13-inch, Late 2010) | `MacBookAir3,2` | ^^ |
|
| MacBook Air (13-inch, Late 2010) | `MacBookAir3,2` | ^^ |
|
||||||
| MacBook Air (11-inch, Mid 2011) | `MacBookAir4,1` | ^^ |
|
| MacBook Air (11-inch, Mid 2011) | `MacBookAir4,1` | ^^ |
|
||||||
| MacBook Air (13-inch, Mid 2011) | `MacBookAir4,2` | ^^ |
|
| MacBook Air (13-inch, Mid 2011) | `MacBookAir4,2` | ^^ |
|
||||||
| MacBook Air (11-inch, Mid 2012) | `MacBookAir5,1` | - [Legacy Metal (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1008) |
|
| MacBook Air (11-inch, Mid 2012) | `MacBookAir5,1` | - [Legacy Metal (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1008) |
|
||||||
| MacBook Air (13-inch, Mid 2012) | `MacBookAir5,2` | ^^ |
|
| MacBook Air (13-inch, Mid 2012) | `MacBookAir5,2` | ^^ |
|
||||||
| MacBook Air (11-inch, Mid 2013)<br>MacBook Air (11-inch, Early 2014) | `MacBookAir6,1` | ^^ |
|
| MacBook Air (11-inch, Mid 2013)<br>MacBook Air (11-inch, Early 2014) | `MacBookAir6,1` | ^^ |
|
||||||
| MacBook Air (13-inch, Mid 2013)<br>MacBook Air (13-inch, Early 2014) | `MacBookAir6,2` | ^^ |
|
| MacBook Air (13-inch, Mid 2013)<br>MacBook Air (13-inch, Early 2014) | `MacBookAir6,2` | ^^ |
|
||||||
| MacBook Air (11-inch, Early 2015) | `MacBookAir7,1` | ^^ |
|
| MacBook Air (11-inch, Early 2015) | `MacBookAir7,1` | ^^ |
|
||||||
| MacBook Air (13-inch, Early 2015)<br>MacBook Air (13-inch, 2017) | `MacBookAir7,2` | ^^ |
|
| MacBook Air (13-inch, Early 2015)<br>MacBook Air (13-inch, 2017) | `MacBookAir7,2` | ^^ |
|
||||||
| MacBook Air (Retina, 13-inch, 2018) | `MacBookAir8,1` | - Supported by Apple |
|
| MacBook Air (Retina, 13-inch, 2018) | `MacBookAir8,1` | - Supported by Apple |
|
||||||
| MacBook Air (Retina, 13-inch, 2019) | `MacBookAir9,1` | ^^ |
|
| MacBook Air (Retina, 13-inch, 2019) | `MacBookAir9,1` | ^^ |
|
||||||
| MacBook Air (Retina, 13-inch, 2020) | `MacBookAir10,1` | ^^ |
|
| MacBook Air (Retina, 13-inch, 2020) | `MacBookAir10,1` | ^^ |
|
||||||
|
|
||||||
### MacBook Pro
|
### MacBook Pro
|
||||||
|
|
||||||
| Model Name | Identifier | Tagged Issues |
|
| Model Name | Identifier | Tagged Issues |
|
||||||
| :--- | :--- | :--- |
|
| :--- | :--- | :--- |
|
||||||
| MacBook Pro (15-inch, Early 2008)<br>MacBook Pro (17-inch, Early 2008) | `MacBookPro4,1` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021)|
|
| MacBook Pro (15-inch, Early 2008)<br>MacBook Pro (17-inch, Early 2008) | `MacBookPro4,1` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021)|
|
||||||
| MacBook Pro (15-inch, Late 2008) | `MacBookPro5,1` | ^^ |
|
| MacBook Pro (15-inch, Late 2008) | `MacBookPro5,1` | ^^ |
|
||||||
| MacBook Pro (17-inch, Early 2009)<br>MacBook Pro (17-inch, Mid 2009) | `MacBookPro5,2` | ^^ |
|
| MacBook Pro (17-inch, Early 2009)<br>MacBook Pro (17-inch, Mid 2009) | `MacBookPro5,2` | ^^ |
|
||||||
| MacBook Pro (15-inch, Mid 2009) | `MacBookPro5,3` | ^^ |
|
| MacBook Pro (15-inch, Mid 2009) | `MacBookPro5,3` | ^^ |
|
||||||
| MacBook Pro (13-inch, Mid 2009) | `MacBookPro5,5` | ^^ |
|
| MacBook Pro (13-inch, Mid 2009) | `MacBookPro5,5` | ^^ |
|
||||||
| MacBook Pro (17-inch, Mid 2010) | `MacBookPro6,1` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108) |
|
| MacBook Pro (17-inch, Mid 2010) | `MacBookPro6,1` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108) |
|
||||||
| MacBook Pro (15-inch, Mid 2010) | `MacBookPro6,2` | ^^ |
|
| MacBook Pro (15-inch, Mid 2010) | `MacBookPro6,2` | ^^ |
|
||||||
| MacBook Pro (13-inch, Mid 2010) | `MacBookPro7,1` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021) |
|
| MacBook Pro (13-inch, Mid 2010) | `MacBookPro7,1` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021) |
|
||||||
| MacBook Pro (13-inch, Early 2011)<br>MacBook Pro (13-inch, Late 2011) | `MacBookPro8,1` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108) |
|
| MacBook Pro (13-inch, Early 2011)<br>MacBook Pro (13-inch, Late 2011) | `MacBookPro8,1` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108) |
|
||||||
| MacBook Pro (15-inch, Early 2011)<br>MacBook Pro (15-inch, Late 2011) | `MacBookPro8,2` | ^^ |
|
| MacBook Pro (15-inch, Early 2011)<br>MacBook Pro (15-inch, Late 2011) | `MacBookPro8,2` | ^^ |
|
||||||
| MacBook Pro (17-inch, Early 2011)<br> | `MacBookPro8,3` | ^^ |
|
| MacBook Pro (17-inch, Early 2011)<br> | `MacBookPro8,3` | ^^ |
|
||||||
| MacBook Pro (15-inch, Mid 2012) | `MacBookPro9,1` | - [Legacy Metal (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1008) |
|
| MacBook Pro (15-inch, Mid 2012) | `MacBookPro9,1` | - [Legacy Metal (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1008) |
|
||||||
| MacBook Pro (13-inch, Mid 2012) | `MacBookPro9,2` | ^^ |
|
| MacBook Pro (13-inch, Mid 2012) | `MacBookPro9,2` | ^^ |
|
||||||
| MacBook Pro (Retina, 15-inch, Mid 2012)<br>MacBook Pro (Retina, 15-inch, Early 2013) | `MacBookPro10,1` | ^^ |
|
| MacBook Pro (Retina, 15-inch, Mid 2012)<br>MacBook Pro (Retina, 15-inch, Early 2013) | `MacBookPro10,1` | ^^ |
|
||||||
| MacBook Pro (Retina, 13-inch, Late 2012)<br>MacBook Pro (Retina, 13-inch, Early 2013) | `MacBookPro10,2` | ^^ |
|
| MacBook Pro (Retina, 13-inch, Late 2012)<br>MacBook Pro (Retina, 13-inch, Early 2013) | `MacBookPro10,2` | ^^ |
|
||||||
| MacBook Pro (Retina, 13-inch, Late 2013)<br>MacBook Pro (Retina, 13-inch, Mid 2014) | `MacBookPro11,1` | ^^ |
|
| MacBook Pro (Retina, 13-inch, Late 2013)<br>MacBook Pro (Retina, 13-inch, Mid 2014) | `MacBookPro11,1` | ^^ |
|
||||||
| MacBook Pro (Retina, 15-inch, Late 2013)<br>MacBook Pro (Retina, 15-inch, Mid 2014) | `MacBookPro11,2`<br>`MacBookPro11,3` | ^^ |
|
| MacBook Pro (Retina, 15-inch, Late 2013)<br>MacBook Pro (Retina, 15-inch, Mid 2014) | `MacBookPro11,2`<br>`MacBookPro11,3` | ^^ |
|
||||||
| MacBook Pro (Retina, 15-inch, Mid 2015) | `MacBookPro11,4`<br>`MacBookPro11,5` | ^^ |
|
| MacBook Pro (Retina, 15-inch, Mid 2015) | `MacBookPro11,4`<br>`MacBookPro11,5` | ^^ |
|
||||||
| MacBook Pro (Retina, 13-inch, Early 2015) | `MacBookPro12,1` | ^^ |
|
| MacBook Pro (Retina, 13-inch, Early 2015) | `MacBookPro12,1` | ^^ |
|
||||||
| MacBook Pro (13-inch, 2016, 2 Thunderbolt 3 ports) | `MacBookPro13,1` | ^^ |
|
| MacBook Pro (13-inch, 2016, 2 Thunderbolt 3 ports) | `MacBookPro13,1` | ^^ |
|
||||||
| MacBook Pro (13-inch, 2016, 4 Thunderbolt 3 ports) | `MacBookPro13,2` | - [Legacy Metal (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1008)<br>- [T1 Support (macOS 14+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1103) |
|
| MacBook Pro (13-inch, 2016, 4 Thunderbolt 3 ports) | `MacBookPro13,2` | ^^ |
|
||||||
| MacBook Pro (15-inch, 2016) | `MacBookPro13,3` | ^^ |
|
| MacBook Pro (15-inch, 2016) | `MacBookPro13,3` | ^^ |
|
||||||
| MacBook Pro (13-inch, 2017, 2 Thunderbolt 3 ports) | `MacBookPro14,1` | - Supported by OpenCore Legacy Patcher |
|
| MacBook Pro (13-inch, 2017, 2 Thunderbolt 3 ports) | `MacBookPro14,1` | - Supported by OpenCore Legacy Patcher |
|
||||||
| MacBook Pro (13-inch, 2017, 4 Thunderbolt 3 ports) | `MacBookPro14,2` | - [T1 Support (macOS 14+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1103) |
|
| MacBook Pro (13-inch, 2017, 4 Thunderbolt 3 ports) | `MacBookPro14,2` | ^^ |
|
||||||
| MacBook Pro (15-inch, 2017) | `MacBookPro14,3` | - [Legacy Metal (macOS 14+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1008)<br>- [T1 Support (macOS 14+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1103) |
|
| MacBook Pro (15-inch, 2017) | `MacBookPro14,3` | - [Legacy Metal (macOS 14+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1008) |
|
||||||
| MacBook Pro (13-inch, 2018, 4 Thunderbolt 3 ports)<br>MacBook Pro (13-inch, 2019, 4 Thunderbolt 3 ports) | `MacBookPro15,2` | - Supported by Apple |
|
| MacBook Pro (13-inch, 2018, 4 Thunderbolt 3 ports)<br>MacBook Pro (13-inch, 2019, 4 Thunderbolt 3 ports) | `MacBookPro15,2` | - Supported by Apple |
|
||||||
| MacBook Pro (15-inch, 2018)<br>MacBook Pro (15-inch, 2019) | `MacBookPro15,1` | ^^ |
|
| MacBook Pro (15-inch, 2018)<br>MacBook Pro (15-inch, 2019) | `MacBookPro15,1` | ^^ |
|
||||||
| MacBook Pro (13-inch, 2019, 2 Thunderbolt 3 ports) | `MacBookPro15,4` | ^^ |
|
| MacBook Pro (13-inch, 2019, 2 Thunderbolt 3 ports) | `MacBookPro15,4` | ^^ |
|
||||||
| MacBook Pro (16-inch, 2019) | `MacBookPro16,1`<br>`MacBookPro16,4` | ^^ |
|
| MacBook Pro (16-inch, 2019) | `MacBookPro16,1`<br>`MacBookPro16,4` | ^^ |
|
||||||
| MacBook Pro (13-inch, 2020, 4 Thunderbolt 3 ports) | `MacBookPro16,2` | ^^ |
|
| MacBook Pro (13-inch, 2020, 4 Thunderbolt 3 ports) | `MacBookPro16,2` | ^^ |
|
||||||
| MacBook Pro (13-inch, 2020, 2 Thunderbolt 3 ports) | `MacBookPro16,3` | ^^ |
|
| MacBook Pro (13-inch, 2020, 2 Thunderbolt 3 ports) | `MacBookPro16,3` | ^^ |
|
||||||
|
|
||||||
### Mac mini
|
### Mac mini
|
||||||
|
|
||||||
| Model Name | Identifier | Tagged Issues |
|
| Model Name | Identifier | Tagged Issues |
|
||||||
| :--- | :--- | :--- |
|
| :--- | :--- | :--- |
|
||||||
| Mac mini (Early 2009) | `Macmini3,1` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021) |
|
| Mac mini (Early 2009) | `Macmini3,1` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021) |
|
||||||
| Mac mini (Mid 2010) | `Macmini4,1` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108) |
|
| Mac mini (Mid 2010) | `Macmini4,1` | ^^ |
|
||||||
| Mac mini (Mid 2011) | `Macmini5,1`<br>`Macmini5,2`<br>`Macmini5,3` | ^^ |
|
| Mac mini (Mid 2011) | `Macmini5,1`<br>`Macmini5,2`<br>`Macmini5,3` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108) |
|
||||||
| Mac mini (Late 2012) | `Macmini6,1`<br>`Macmini6,2` | - [Legacy Metal (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1008) |
|
| Mac mini (Late 2012) | `Macmini6,1`<br>`Macmini6,2` | - [Legacy Metal (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1008) |
|
||||||
| Mac mini (Late 2014) | `Macmini7,1` | ^^ |
|
| Mac mini (Late 2014) | `Macmini7,1` | ^^ |
|
||||||
| Mac mini (Late 2018) | `Macmini8,1` | - Supported by Apple |
|
| Mac mini (Late 2018) | `Macmini8,1` | - Supported by Apple |
|
||||||
|
|
||||||
### iMac
|
### iMac
|
||||||
| Model Name | Identifier | Tagged Issues |
|
| Model Name | Identifier | Tagged Issues |
|
||||||
| :--- | :--- | :--- |
|
| :--- | :--- | :--- |
|
||||||
| iMac (20-inch, Mid 2007)<br>iMac (24-inch, Mid 2007) | `iMac7,1` | - [Requires SSE4.1 CPU](https://lowendmac.com/2018/penryn-t9300-9500-cpu-upgrades-for-the-2007-imac/)<br>- [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021)<br>- Remove stock Bluetooth to prevent panics |
|
| iMac (20-inch, Mid 2007)<br>iMac (24-inch, Mid 2007) | `iMac7,1` | - [Requires SSE4.1 CPU](https://lowendmac.com/2018/penryn-t9300-9500-cpu-upgrades-for-the-2007-imac/)<br>- [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021)<br>- Remove stock Bluetooth to prevent panics |
|
||||||
| iMac (20-inch, Early 2008)<br>iMac (24-inch, Early 2008) | `iMac8,1` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021) |
|
| iMac (20-inch, Early 2008)<br>iMac (24-inch, Early 2008) | `iMac8,1` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021) |
|
||||||
| iMac (20-inch, Early 2009)<br>iMac (24-inch, Early 2009)<br>iMac (20-inch, Mid 2009) | `iMac9,1` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021)<br>- [Recommend upgrading to Metal GPU](https://forums.macrumors.com/threads/2011-imac-graphics-card-upgrade.1596614/?post=17425857#post-17425857) |
|
| iMac (20-inch, Early 2009)<br>iMac (24-inch, Early 2009)<br>iMac (20-inch, Mid 2009) | `iMac9,1` | - [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021)<br>- [Recommend upgrading to Metal GPU](https://forums.macrumors.com/threads/2011-imac-graphics-card-upgrade.1596614/?post=17425857#post-17425857) |
|
||||||
@@ -133,7 +133,7 @@ The patcher is designed to target **macOS Big Sur 11.x to macOS Sonoma 14.x**.
|
|||||||
### Mac Pro
|
### Mac Pro
|
||||||
|
|
||||||
| Model Name | Identifier | Tagged Issues |
|
| Model Name | Identifier | Tagged Issues |
|
||||||
| :--- | :--- | :--- |
|
| :--- | :--- | :--- |
|
||||||
| Mac Pro (Early 2008) | `MacPro3,1` | - [Recommend upgrade to Metal GPU](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1008)<br>- [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021)<br>- Remove stock Bluetooth to prevent panics |
|
| Mac Pro (Early 2008) | `MacPro3,1` | - [Recommend upgrade to Metal GPU](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1008)<br>- [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021)<br>- Remove stock Bluetooth to prevent panics |
|
||||||
| Mac Pro (Early 2009) | `MacPro4,1` | - [Recommend upgrade to Metal GPU](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1008)<br>- [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021) |
|
| Mac Pro (Early 2009) | `MacPro4,1` | - [Recommend upgrade to Metal GPU](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1008)<br>- [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021) |
|
||||||
| Mac Pro (Mid 2010)<br>Mac Pro (Mid 2012) | `MacPro5,1` | ^^ |
|
| Mac Pro (Mid 2010)<br>Mac Pro (Mid 2012) | `MacPro5,1` | ^^ |
|
||||||
@@ -143,8 +143,8 @@ The patcher is designed to target **macOS Big Sur 11.x to macOS Sonoma 14.x**.
|
|||||||
### Xserve
|
### Xserve
|
||||||
|
|
||||||
| Model Name | Identifier | Tagged Issues |
|
| Model Name | Identifier | Tagged Issues |
|
||||||
| :--- | :--- | :--- |
|
| :--- | :--- | :--- |
|
||||||
| Xserve (Early 2008) | `Xserve2,1` | - Recommend upgrade to Metal GPU<br>- [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021)
|
| Xserve (Early 2008) | `Xserve2,1` | - Recommend upgrade to Metal GPU<br>- [non-Metal GPU (macOS 11+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)<br>- [USB 1.1 (macOS 13+)](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021)
|
||||||
| Xserve (Early 2009) | `Xserve3,1` | ^^ |
|
| Xserve (Early 2009) | `Xserve3,1` | ^^ |
|
||||||
|
|
||||||
# Once you've verified your hardware is supported, head to [Download and build macOS Installers](./INSTALLER.md)
|
# Once you've verified your hardware is supported, head to [Download and build macOS Installers](./INSTALLER.md)
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ meta:
|
|||||||
content: Experience macOS just like before
|
content: Experience macOS just like before
|
||||||
|
|
||||||
features:
|
features:
|
||||||
- title: Built with security in mind
|
# - 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.
|
# 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
|
- title: Native OTA updates
|
||||||
details: Install updates the moment they come out, with native System Preferences support, just like a supported Mac.
|
details: Install updates the moment they come out, with native System Preferences support, just like a supported Mac.
|
||||||
- title: Zero firmware patching
|
- 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!
|
details: Unlock Sidecar, AirPlay to Mac, Night Shift, and Universal Control, even on natively supported models!
|
||||||
- title: A helpful community
|
- 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.
|
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
|
||||||
---
|
---
|
||||||
@@ -1,12 +1,12 @@
|
|||||||

|

|
||||||
|
|
||||||
*Well here we are again, it's always such a pleasure~*
|
*Well here we are again, it's always such a pleasure~*
|
||||||
|
|
||||||
Apple has yet again dropped a bunch of models, continuing their journey on discontinuing Intel Macs. With the release of OpenCore Legacy Patcher v1.0.0, early support for macOS Sonoma has been implemented.
|
Apple has yet again dropped a bunch of models, continuing their journey on discontinuing Intel Macs. With the release of OpenCore Legacy Patcher 1.0.0, early support for macOS Sonoma has been implemented.
|
||||||
|
|
||||||
## Versioning
|
## Versioning
|
||||||
|
|
||||||
With v1.0.0, we'll be switching to a proper major, minor and bug fix system ([Semantic Versioning](https://semver.org/)). This means the coming release will be version 1.0.0, and future releases plan to follow this scheme:
|
With 1.0.0, we'll be switching to a proper major, minor and bug fix system ([Semantic Versioning](https://semver.org/)). This means the coming release will be version 1.0.0, and future releases plan to follow this scheme:
|
||||||
|
|
||||||
- First digit: Major changes, including new OS support, API changes, and significant patch set changes, etc
|
- First digit: Major changes, including new OS support, API changes, and significant patch set changes, etc
|
||||||
- Second digit: Minor changes, including incoming OS update fixes, minor patch set changes, etc
|
- Second digit: Minor changes, including incoming OS update fixes, minor patch set changes, etc
|
||||||
@@ -17,7 +17,7 @@ With v1.0.0, we'll be switching to a proper major, minor and bug fix system ([Se
|
|||||||
|
|
||||||
* MacBook10,1: MacBook (Retina, 12-inch, 2017)
|
* MacBook10,1: MacBook (Retina, 12-inch, 2017)
|
||||||
* MacBookPro14,1: MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)
|
* MacBookPro14,1: MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)
|
||||||
* MacBookPro14,2: MacBook Pro (13-inch, 2017, Four Thunderbolt 3 Ports)
|
* MacBookPro14,2: MacBook Pro (13-inch, 2017, Four Thunderbolt 3 Ports)
|
||||||
* MacBookPro14,3: MacBook Pro (15-inch, 2017)
|
* MacBookPro14,3: MacBook Pro (15-inch, 2017)
|
||||||
* iMac18,1: iMac (21.5-inch, 2017)
|
* iMac18,1: iMac (21.5-inch, 2017)
|
||||||
* iMac18,2: iMac (Retina 4K, 21.5-inch, 2017)
|
* iMac18,2: iMac (Retina 4K, 21.5-inch, 2017)
|
||||||
@@ -25,7 +25,7 @@ With v1.0.0, we'll be switching to a proper major, minor and bug fix system ([Se
|
|||||||
|
|
||||||
## Current status
|
## Current status
|
||||||
|
|
||||||
OpenCore Legacy Patcher v1.0.0 will support Sonoma for all models normally supported by the Patcher, however some challenges remain. You can find information about them below.
|
OpenCore Legacy Patcher 1.0.0 will support Sonoma for all models normally supported by the Patcher, however some challenges remain. You can find information about them below.
|
||||||
|
|
||||||
## Issues
|
## Issues
|
||||||
|
|
||||||
@@ -43,6 +43,8 @@ Dual boots may also bring the issue back even after the reset.
|
|||||||
|
|
||||||
### T1 Security chip
|
### T1 Security chip
|
||||||
|
|
||||||
|
::: details Support for the T1 Security chip (Resolved in 1.1.0 and newer)
|
||||||
|
|
||||||
Sonoma has removed support for T1 chips found in most 2016 and 2017 Macs. Therefore on these systems, the following will not function:
|
Sonoma has removed support for T1 chips found in most 2016 and 2017 Macs. Therefore on these systems, the following will not function:
|
||||||
|
|
||||||
* Enable or disable FileVault
|
* Enable or disable FileVault
|
||||||
@@ -50,17 +52,17 @@ Sonoma has removed support for T1 chips found in most 2016 and 2017 Macs. Theref
|
|||||||
* Add fingerprints (if upgrading, existing fingerprints will be deleted)
|
* Add fingerprints (if upgrading, existing fingerprints will be deleted)
|
||||||
* Add cards to Apple Pay
|
* Add cards to Apple Pay
|
||||||
|
|
||||||
:::warning
|
[More information here](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1103)
|
||||||
Additionally, due to Sonoma no longer caring about T1, erasing the entire drive will remove the T1 firmware and it won't be reinstalled.
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
No known solution to resolve supporting, a significant amount of time will be required to understand how both the T1 stack works, as well as where the core issue lies for support.
|
::: warning
|
||||||
|
Note that erasing the entire drive will remove the T1 firmware and it won't be reinstalled.
|
||||||
[More information here](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1103)
|
:::
|
||||||
|
|
||||||
### USB 1.1 (OHCI/UHCI) Support
|
### USB 1.1 (OHCI/UHCI) Support
|
||||||
|
|
||||||
For Penryn systems, pre-2013 Mac Pros and Xserve, USB 1.1 support was outright removed in macOS Ventura and naturally this continues in Sonoma.
|
For Penryn systems, pre-2013 Mac Pros and Xserve, USB 1.1 support was outright removed in macOS Ventura and naturally this continues in Sonoma.
|
||||||
While USB 1.1 may seem unimportant, it handles many important devices on your system. These include:
|
While USB 1.1 may seem unimportant, it handles many important devices on your system. These include:
|
||||||
|
|
||||||
* Keyboard and Trackpad for laptops
|
* Keyboard and Trackpad for laptops
|
||||||
@@ -74,7 +76,7 @@ With OpenCore Legacy Patcher v0.6.0+, basic support has been implemented via Roo
|
|||||||
::: warning The following systems rely on USB 1.1
|
::: warning The following systems rely on USB 1.1
|
||||||
|
|
||||||
* iMac10,x and older
|
* iMac10,x and older
|
||||||
* Macmini3,1 and older
|
* Macmini4,1 and older
|
||||||
* MacBook7,1 and older
|
* MacBook7,1 and older
|
||||||
* MacBookAir3,1 and older
|
* MacBookAir3,1 and older
|
||||||
* MacPro5,1 and older
|
* MacPro5,1 and older
|
||||||
@@ -86,6 +88,6 @@ With OpenCore Legacy Patcher v0.6.0+, basic support has been implemented via Roo
|
|||||||
### Graphics support and issues
|
### Graphics support and issues
|
||||||
This build includes both Legacy Metal and non-Metal patches for macOS Sonoma. Refer to the following links for more information about Legacy Metal and non-Metal support and their respective issues.
|
This build includes both Legacy Metal and non-Metal patches for macOS Sonoma. Refer to the following links for more information about Legacy Metal and non-Metal support and their respective issues.
|
||||||
|
|
||||||
* [Legacy Metal](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1008)
|
* [Legacy Metal](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1008)
|
||||||
* [Non-Metal](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)
|
* [Non-Metal](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/108)
|
||||||
|
|
||||||
|
|||||||
@@ -66,14 +66,13 @@ Then revert the snapshot
|
|||||||
```sh
|
```sh
|
||||||
bless --mount "/Volumes/Macintosh HD" --bootefi --last-sealed-snapshot
|
bless --mount "/Volumes/Macintosh HD" --bootefi --last-sealed-snapshot
|
||||||
```
|
```
|
||||||
After that, type the following
|
Now we're going to clean the /Library/Extensions folder from offending kexts while keeping needed ones.
|
||||||
```sh
|
|
||||||
cd "/Volumes/Macintosh HD/Library/Extensions"
|
|
||||||
```
|
|
||||||
Then by typing `ls`, you should see bunch of .kexts.
|
|
||||||
* **Note:** If you only see .kexts starting with "HighPoint", you can ignore this and just restart the system. If other kexts are found, continue.
|
|
||||||
|
|
||||||
Delete everything **except** for the ones that start with HighPoint, 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.
|
Then restart and now your system should be restored to the unpatched snapshot and should be able to boot again.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Uninstalling OpenCore
|
# Uninstalling OpenCore
|
||||||
|
|
||||||
To remove OpenCore:
|
## Uninstalling the bootloader
|
||||||
|
|
||||||
1. Remove OpenCore either from the USB or internal drive
|
1. Remove OpenCore either from the USB or internal drive
|
||||||
|
|
||||||
@@ -13,6 +13,11 @@ To remove OpenCore:
|
|||||||
|
|
||||||
:::warning
|
:::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 recomended 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
|
||||||
|
|
||||||
|
If you want to remove the application without reinstalling the OS, navigate to `/Library/Application Support/` and delete the Dortania folder.
|
||||||
|
|||||||
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",
|
"license": "CC-BY-NC-SA-4.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vuepress/plugin-back-to-top": "^1.7.1",
|
"@vuepress/plugin-back-to-top": "^1.9.10",
|
||||||
"markdown-it-multimd-table": "^4.0.3",
|
"markdown-it-multimd-table": "^4.2.3",
|
||||||
"markdown-link-check": "^3.8.5",
|
"markdown-link-check": "^3.11.2",
|
||||||
"markdownlint-cli": "^0.26.0",
|
"markdownlint-cli": "^0.37.0",
|
||||||
"run-script-os": "^1.1.4",
|
"run-script-os": "^1.1.6",
|
||||||
"spellchecker-cli": "^4.4.0",
|
"spellchecker-cli": "^6.1.1",
|
||||||
"vuepress": "^1.7.1",
|
"vuepress": "^1.9.10",
|
||||||
"vuepress-plugin-medium-zoom": "^1.1.9",
|
"vuepress-plugin-medium-zoom": "^1.1.9",
|
||||||
"vuepress-plugin-zooming": "^1.1.8",
|
"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-dark-new": "^0.1.2",
|
||||||
"vuepress-theme-succinct": "^1.6.4",
|
"vuepress-theme-succinct": "^1.7.2",
|
||||||
"vuepress-theme-yuu": "^2.3.0"
|
"vuepress-theme-yuu": "^3.1.1"
|
||||||
},
|
},
|
||||||
"homepage": "https://dortania.github.io/OpenCore-Legacy-Patcher/"
|
"homepage": "https://dortania.github.io/OpenCore-Legacy-Patcher/"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -284,6 +284,8 @@
|
|||||||
<false/>
|
<false/>
|
||||||
<key>EnableWriteUnprotector</key>
|
<key>EnableWriteUnprotector</key>
|
||||||
<false/>
|
<false/>
|
||||||
|
<key>FixupAppleEfiImages</key>
|
||||||
|
<false/>
|
||||||
<key>ForceBooterSignature</key>
|
<key>ForceBooterSignature</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>ForceExitBootServices</key>
|
<key>ForceExitBootServices</key>
|
||||||
@@ -1743,6 +1745,24 @@
|
|||||||
<key>PlistPath</key>
|
<key>PlistPath</key>
|
||||||
<string>Contents/Info.plist</string>
|
<string>Contents/Info.plist</string>
|
||||||
</dict>
|
</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>
|
<dict>
|
||||||
<key>Arch</key>
|
<key>Arch</key>
|
||||||
<string>x86_64</string>
|
<string>x86_64</string>
|
||||||
@@ -1761,24 +1781,6 @@
|
|||||||
<key>PlistPath</key>
|
<key>PlistPath</key>
|
||||||
<string>Contents/Info.plist</string>
|
<string>Contents/Info.plist</string>
|
||||||
</dict>
|
</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>
|
<dict>
|
||||||
<key>Arch</key>
|
<key>Arch</key>
|
||||||
<string>x86_64</string>
|
<string>x86_64</string>
|
||||||
@@ -1797,6 +1799,42 @@
|
|||||||
<key>PlistPath</key>
|
<key>PlistPath</key>
|
||||||
<string>Contents/Info.plist</string>
|
<string>Contents/Info.plist</string>
|
||||||
</dict>
|
</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>
|
</array>
|
||||||
<key>Block</key>
|
<key>Block</key>
|
||||||
<array>
|
<array>
|
||||||
@@ -1844,7 +1882,7 @@
|
|||||||
<key>MaxKernel</key>
|
<key>MaxKernel</key>
|
||||||
<string></string>
|
<string></string>
|
||||||
<key>MinKernel</key>
|
<key>MinKernel</key>
|
||||||
<string>23.0.0</string>
|
<string>23.4.0</string>
|
||||||
<key>Strategy</key>
|
<key>Strategy</key>
|
||||||
<string>Exclude</string>
|
<string>Exclude</string>
|
||||||
</dict>
|
</dict>
|
||||||
@@ -2378,8 +2416,8 @@
|
|||||||
<true/>
|
<true/>
|
||||||
<key>HideAuxiliary</key>
|
<key>HideAuxiliary</key>
|
||||||
<true/>
|
<true/>
|
||||||
<!-- <key>InstanceIdentifier</key>
|
<key>InstanceIdentifier</key>
|
||||||
<string></string> -->
|
<string></string>
|
||||||
<key>LauncherPath</key>
|
<key>LauncherPath</key>
|
||||||
<string>Default</string>
|
<string>Default</string>
|
||||||
<key>LauncherOption</key>
|
<key>LauncherOption</key>
|
||||||
@@ -3084,8 +3122,8 @@
|
|||||||
<integer>-1</integer>
|
<integer>-1</integer>
|
||||||
<key>ResizeUsePciRbIo</key>
|
<key>ResizeUsePciRbIo</key>
|
||||||
<false/>
|
<false/>
|
||||||
<!-- <key>ShimRetainProtocol</key>
|
<key>ShimRetainProtocol</key>
|
||||||
<false/> -->
|
<false/>
|
||||||
<key>TscSyncTimeout</key>
|
<key>TscSyncTimeout</key>
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
<key>UnblockFsConnect</key>
|
<key>UnblockFsConnect</key>
|
||||||
|
|||||||
@@ -235,7 +235,7 @@
|
|||||||
<key>GID</key>
|
<key>GID</key>
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
<key>PATH</key>
|
<key>PATH</key>
|
||||||
<string>../com.dortania.opencore-legacy-patcher.auto-patch.plist</string>
|
<string>../Launch Services/com.dortania.opencore-legacy-patcher.auto-patch.plist</string>
|
||||||
<key>PATH_TYPE</key>
|
<key>PATH_TYPE</key>
|
||||||
<integer>1</integer>
|
<integer>1</integer>
|
||||||
<key>PERMISSIONS</key>
|
<key>PERMISSIONS</key>
|
||||||
|
|||||||
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:
|
with tempfile.TemporaryDirectory() as temp_dir:
|
||||||
# Download source
|
# Download source
|
||||||
weg_source_zip = f"{temp_dir}/WhateverGreen-{self.weg_version}.zip"
|
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
|
# 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
|
# 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
|
# Grab latest Lilu release, debug version
|
||||||
lilu_zip = f"{temp_dir}/Lilu-{self.lilu_version}-DEBUG.zip"
|
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
|
# 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
|
# Apply patch
|
||||||
patch_path = Path("./Acidanthera/WhateverGreen-Navi-Backlight.patch").absolute()
|
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
|
# Build WEG
|
||||||
for variant in ["Release", "Debug"]:
|
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
|
# Zip Release
|
||||||
for variant in ["RELEASE", "DEBUG"]:
|
for variant in ["RELEASE", "DEBUG"]:
|
||||||
dst_path = Path(f"./Acidanthera/WhateverGreen-v{self.weg_version}-Navi-{variant}.zip").absolute()
|
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():
|
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")
|
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"
|
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():
|
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._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)
|
self._update_constants_file(KEXT_DICTIONARY[kext_folder][kext_name]["Constants Variable"], local_version, remote_version)
|
||||||
|
|
||||||
if override_kext_zip_name:
|
if override_kext_zip_name:
|
||||||
# rename zip file
|
# rename zip file
|
||||||
os.rename(f"./{kext_folder}/{zip_name}", f"./{kext_folder}/{kext_name}-v{remote_version}-{variant}.zip")
|
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):
|
def _get_local_version(self, kext_folder, kext_name, variant):
|
||||||
@@ -247,14 +247,14 @@ class GenerateKexts:
|
|||||||
f.write(download.content)
|
f.write(download.content)
|
||||||
|
|
||||||
# Unzip file
|
# 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}...")
|
print(f" Moving {file} to {file_path}...")
|
||||||
# Zip file
|
# 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
|
# 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):
|
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.
@@ -14,4 +14,4 @@
|
|||||||
<key>RunAtLoad</key>
|
<key>RunAtLoad</key>
|
||||||
<true/>
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>AssociatedBundleIdentifiers</key>
|
||||||
|
<string>com.dortania.opencore-legacy-patcher</string>
|
||||||
|
<key>Label</key>
|
||||||
|
<string>com.dortania.opencore-legacy-patcher.macos-update</string>
|
||||||
|
<key>ProgramArguments</key>
|
||||||
|
<array>
|
||||||
|
<string>/Library/Application Support/Dortania/OpenCore-Patcher.app/Contents/MacOS/OpenCore-Patcher</string>
|
||||||
|
<string>--prepare_for_update</string>
|
||||||
|
</array>
|
||||||
|
<key>WatchPaths</key>
|
||||||
|
<array>
|
||||||
|
<string>/System/Volumes/Update/Update.plist</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>AssociatedBundleIdentifiers</key>
|
||||||
|
<string>com.dortania.opencore-legacy-patcher</string>
|
||||||
|
<key>Label</key>
|
||||||
|
<string>com.dortania.opencore-legacy-patcher.rsr-monitor</string>
|
||||||
|
<key>ProgramArguments</key>
|
||||||
|
<array>
|
||||||
|
<string>/Library/Application Support/Dortania/OpenCore-Patcher.app/Contents/MacOS/OpenCore-Patcher</string>
|
||||||
|
<string>--cache_os</string>
|
||||||
|
</array>
|
||||||
|
<key>WatchPaths</key>
|
||||||
|
<array>
|
||||||
|
<string>/System/Volumes/Update/Preflight.plist</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
Binary file not shown.
Binary file not shown.
@@ -128,24 +128,24 @@ class GenerateOpenCore:
|
|||||||
for variant in BUILD_VARIANTS:
|
for variant in BUILD_VARIANTS:
|
||||||
print(f"Moving {variant} folder...")
|
print(f"Moving {variant} folder...")
|
||||||
subprocess.run (
|
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
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
)
|
)
|
||||||
if variant == "DEBUG":
|
if variant == "DEBUG":
|
||||||
for utility in IMPORTANT_UTILITIES:
|
for utility in IMPORTANT_UTILITIES:
|
||||||
print(f"Moving {utility} from {variant} variant...")
|
print(f"Moving {utility} from {variant} variant...")
|
||||||
subprocess.run (
|
subprocess.run (
|
||||||
["rm", "-rf", f"{self.working_dir}/{utility}"],
|
["/bin/rm", "-rf", f"{self.working_dir}/{utility}"],
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
)
|
)
|
||||||
subprocess.run (
|
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
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
)
|
)
|
||||||
|
|
||||||
# Remove root folder
|
# Remove root folder
|
||||||
subprocess.run (
|
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
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -153,12 +153,12 @@ class GenerateOpenCore:
|
|||||||
print("Removing zip files...")
|
print("Removing zip files...")
|
||||||
# remove debug_zip
|
# remove debug_zip
|
||||||
subprocess.run (
|
subprocess.run (
|
||||||
["rm", "-rf", self.debug_zip],
|
["/bin/rm", "-rf", self.debug_zip],
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
)
|
)
|
||||||
# remove release_zip
|
# remove release_zip
|
||||||
subprocess.run (
|
subprocess.run (
|
||||||
["rm", "-rf", self.release_zip],
|
["/bin/rm", "-rf", self.release_zip],
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -194,7 +194,7 @@ class GenerateOpenCore:
|
|||||||
if (self.working_dir / f"OpenCore-{variant}").exists():
|
if (self.working_dir / f"OpenCore-{variant}").exists():
|
||||||
print(f" Deleting old {variant} variant...")
|
print(f" Deleting old {variant} variant...")
|
||||||
subprocess.run (
|
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
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -212,7 +212,7 @@ class GenerateOpenCore:
|
|||||||
# Create S/L/C
|
# Create S/L/C
|
||||||
print(" Creating SLC folder")
|
print(" Creating SLC folder")
|
||||||
subprocess.run (
|
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
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -220,21 +220,21 @@ class GenerateOpenCore:
|
|||||||
print(" Relocating BOOT folder to SLC")
|
print(" Relocating BOOT folder to SLC")
|
||||||
for file in (self.working_dir / f"OpenCore-{variant}/EFI/BOOT").iterdir():
|
for file in (self.working_dir / f"OpenCore-{variant}/EFI/BOOT").iterdir():
|
||||||
subprocess.run (
|
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
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
)
|
)
|
||||||
|
|
||||||
# Rename BOOTx64.efi to boot.efi
|
# Rename BOOTx64.efi to boot.efi
|
||||||
print(" Renaming BOOTx64.efi to boot.efi")
|
print(" Renaming BOOTx64.efi to boot.efi")
|
||||||
subprocess.run (
|
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
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
)
|
)
|
||||||
|
|
||||||
# Delete BOOT folder
|
# Delete BOOT folder
|
||||||
print(" Deleting BOOT folder")
|
print(" Deleting BOOT folder")
|
||||||
subprocess.run (
|
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
|
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():
|
if Path(f"{self.working_dir}/OpenCore-{variant}/EFI/OC/Drivers/{driver}").exists():
|
||||||
print(f" Deleting {driver}")
|
print(f" Deleting {driver}")
|
||||||
subprocess.run (
|
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
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@@ -256,7 +256,7 @@ class GenerateOpenCore:
|
|||||||
if Path(f"{self.working_dir}/OpenCore-{variant}/EFI/OC/Tools/{tool}").exists():
|
if Path(f"{self.working_dir}/OpenCore-{variant}/EFI/OC/Tools/{tool}").exists():
|
||||||
print(f" Deleting {tool}")
|
print(f" Deleting {tool}")
|
||||||
subprocess.run (
|
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
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@@ -265,21 +265,21 @@ class GenerateOpenCore:
|
|||||||
# Rename OpenCore-<variant> to OpenCore-Build
|
# Rename OpenCore-<variant> to OpenCore-Build
|
||||||
print(" Renaming OpenCore folder")
|
print(" Renaming OpenCore folder")
|
||||||
subprocess.run (
|
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
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create OpenCore-<variant>.zip
|
# Create OpenCore-<variant>.zip
|
||||||
print(" Creating OpenCore.zip")
|
print(" Creating OpenCore.zip")
|
||||||
subprocess.run (
|
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
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
)
|
)
|
||||||
|
|
||||||
# Delete OpenCore-Build
|
# Delete OpenCore-Build
|
||||||
print(" Deleting OpenCore-Build")
|
print(" Deleting OpenCore-Build")
|
||||||
subprocess.run (
|
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
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -1,12 +1,17 @@
|
|||||||
import threading
|
import sys
|
||||||
import time
|
import time
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import plistlib
|
||||||
|
import threading
|
||||||
|
import subprocess
|
||||||
|
|
||||||
from resources import defaults, utilities, validation, constants
|
from pathlib import Path
|
||||||
from resources.sys_patch import sys_patch, sys_patch_auto
|
|
||||||
|
from data import model_array, os_data
|
||||||
from resources.build import build
|
from resources.build import build
|
||||||
from data import model_array
|
from resources.sys_patch import sys_patch, sys_patch_auto
|
||||||
|
from resources import defaults, utilities, validation, constants
|
||||||
|
from resources.wx_gui import gui_entry
|
||||||
|
|
||||||
|
|
||||||
# Generic building args
|
# Generic building args
|
||||||
@@ -41,6 +46,14 @@ class arguments:
|
|||||||
self._sys_unpatch_handler()
|
self._sys_unpatch_handler()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if self.args.prepare_for_update:
|
||||||
|
self._prepare_for_update_handler()
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.args.cache_os:
|
||||||
|
self._cache_os_handler()
|
||||||
|
return
|
||||||
|
|
||||||
if self.args.auto_patch:
|
if self.args.auto_patch:
|
||||||
self._sys_patch_auto_handler()
|
self._sys_patch_auto_handler()
|
||||||
return
|
return
|
||||||
@@ -88,6 +101,62 @@ class arguments:
|
|||||||
sys_patch_auto.AutomaticSysPatch(self.constants).start_auto_patch()
|
sys_patch_auto.AutomaticSysPatch(self.constants).start_auto_patch()
|
||||||
|
|
||||||
|
|
||||||
|
def _prepare_for_update_handler(self) -> None:
|
||||||
|
"""
|
||||||
|
Prepare host for macOS update
|
||||||
|
"""
|
||||||
|
logging.info("Preparing host for macOS update")
|
||||||
|
|
||||||
|
os_data = utilities.fetch_staged_update(variant="Update")
|
||||||
|
if os_data[0] is None:
|
||||||
|
logging.info("No update staged, skipping")
|
||||||
|
return
|
||||||
|
|
||||||
|
os_version = os_data[0]
|
||||||
|
os_build = os_data[1]
|
||||||
|
|
||||||
|
logging.info(f"Preparing for update to {os_version} ({os_build})")
|
||||||
|
|
||||||
|
self._clean_le_handler()
|
||||||
|
|
||||||
|
|
||||||
|
def _cache_os_handler(self) -> None:
|
||||||
|
"""
|
||||||
|
Fetch KDK for incoming OS
|
||||||
|
"""
|
||||||
|
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
|
||||||
|
|
||||||
|
gui_entry.EntryPoint(self.constants).start(entry=gui_entry.SupportedEntryPoints.OS_CACHE)
|
||||||
|
|
||||||
|
|
||||||
|
def _clean_le_handler(self) -> None:
|
||||||
|
"""
|
||||||
|
Clean /Library/Extensions of problematic kexts
|
||||||
|
Note macOS Ventura and older do this automatically
|
||||||
|
"""
|
||||||
|
|
||||||
|
if self.constants.detected_os < os_data.os_data.sonoma:
|
||||||
|
return
|
||||||
|
|
||||||
|
logging.info("Cleaning /Library/Extensions")
|
||||||
|
|
||||||
|
for kext in Path("/Library/Extensions").glob("*.kext"):
|
||||||
|
if not Path(f"{kext}/Contents/Info.plist").exists():
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
kext_plist = plistlib.load(open(f"{kext}/Contents/Info.plist", "rb"))
|
||||||
|
except Exception as e:
|
||||||
|
logging.info(f" - Failed to load plist for {kext.name}: {e}")
|
||||||
|
continue
|
||||||
|
if "GPUCompanionBundles" not in kext_plist:
|
||||||
|
continue
|
||||||
|
logging.info(f" - Removing {kext.name}")
|
||||||
|
subprocess.run(["/bin/rm", "-rf", kext])
|
||||||
|
|
||||||
|
|
||||||
def _build_handler(self) -> None:
|
def _build_handler(self) -> None:
|
||||||
"""
|
"""
|
||||||
Start config building process
|
Start config building process
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
# Copyright (C) 2020-2023, Dhinak G, Mykola Grymalyuk
|
# Copyright (C) 2020-2023, Dhinak G, Mykola Grymalyuk
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import binascii
|
||||||
|
|
||||||
from resources import constants, device_probe
|
from resources import constants, device_probe
|
||||||
from resources.build import support
|
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("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)
|
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"]["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":
|
elif self.computer.bluetooth_chipset == "BRCM20702 Hub":
|
||||||
# BCM94331 can include either BCM2070 or BRCM20702 v1 Bluetooth chipsets
|
# BCM94331 can include either BCM2070 or BRCM20702 v1 Bluetooth chipsets
|
||||||
# Note Monterey only natively supports BRCM20702 v2 (found with BCM94360)
|
# 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)
|
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:
|
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"]["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)
|
support.BuildSupport(self.model, self.constants, self.config).enable_kext("Bluetooth-Spoof.kext", self.constants.btspoof_version, self.constants.btspoof_path)
|
||||||
@@ -305,10 +305,10 @@ class BuildFirmware:
|
|||||||
whereas other drivers like ./qa_logger.efi is invoked via Device Path.
|
whereas other drivers like ./qa_logger.efi is invoked via Device Path.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if "5K Display" not in smbios_data.smbios_dictionary[self.model]:
|
if "Dual DisplayPort Display" not in smbios_data.smbios_dictionary[self.model]:
|
||||||
return
|
return
|
||||||
|
|
||||||
logging.info("- Adding 5K Display Patch")
|
logging.info("- Adding 4K/5K Display Patch")
|
||||||
# Set LauncherPath to '/boot.efi'
|
# Set LauncherPath to '/boot.efi'
|
||||||
# This is to ensure that only the Mac's firmware presents the boot option, but not OpenCore
|
# This is to ensure that only the Mac's firmware presents the boot option, but not OpenCore
|
||||||
# https://github.com/acidanthera/OpenCorePkg/blob/0.7.6/Library/OcAppleBootPolicyLib/OcAppleBootPolicyLib.c#L50-L73
|
# https://github.com/acidanthera/OpenCorePkg/blob/0.7.6/Library/OcAppleBootPolicyLib/OcAppleBootPolicyLib.c#L50-L73
|
||||||
|
|||||||
@@ -180,9 +180,17 @@ class BuildMiscellaneous:
|
|||||||
|
|
||||||
def _topcase_handling(self) -> None:
|
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
|
#On-device probing
|
||||||
if not self.constants.custom_model and self.computer.internal_keyboard_type and self.computer.trackpad_type:
|
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.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.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("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("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)
|
||||||
@@ -35,6 +35,7 @@ class BuildWiredNetworking:
|
|||||||
|
|
||||||
# Always enable due to chance of hot-plugging
|
# Always enable due to chance of hot-plugging
|
||||||
self._usb_ecm_dongles()
|
self._usb_ecm_dongles()
|
||||||
|
self._i210_handling()
|
||||||
|
|
||||||
|
|
||||||
def _usb_ecm_dongles(self) -> None:
|
def _usb_ecm_dongles(self) -> None:
|
||||||
@@ -48,6 +49,21 @@ class BuildWiredNetworking:
|
|||||||
# - Kext: AppleUSBECM.kext
|
# - Kext: AppleUSBECM.kext
|
||||||
support.BuildSupport(self.model, self.constants, self.config).enable_kext("ECM-Override.kext", self.constants.ecm_override_version, self.constants.ecm_override_path)
|
support.BuildSupport(self.model, self.constants, self.config).enable_kext("ECM-Override.kext", self.constants.ecm_override_version, self.constants.ecm_override_path)
|
||||||
|
|
||||||
|
|
||||||
|
def _i210_handling(self) -> None:
|
||||||
|
"""
|
||||||
|
PCIe i210 NIC Handling
|
||||||
|
"""
|
||||||
|
# i210 NICs are broke in macOS 14 due to driver kit downgrades
|
||||||
|
# See ECM logic for why it's always enabled
|
||||||
|
if not self.model in smbios_data.smbios_dictionary:
|
||||||
|
return
|
||||||
|
support.BuildSupport(self.model, self.constants, self.config).enable_kext("CatalinaIntelI210Ethernet.kext", self.constants.i210_version, self.constants.i210_path)
|
||||||
|
# Ivy Bridge and newer natively support DriverKit, so set MinKernel to 23.0.0
|
||||||
|
if smbios_data.smbios_dictionary[self.model]["CPU Generation"] >= cpu_data.CPUGen.ivy_bridge.value:
|
||||||
|
support.BuildSupport(self.model, self.constants, self.config).get_kext_by_bundle_path("CatalinaIntelI210Ethernet.kext")["MinKernel"] = "23.0.0"
|
||||||
|
|
||||||
|
|
||||||
def _on_model(self) -> None:
|
def _on_model(self) -> None:
|
||||||
"""
|
"""
|
||||||
On-Model Hardware Detection Handling
|
On-Model Hardware Detection Handling
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ class BuildSMBIOS:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if self.constants.custom_serial_number == "" or self.constants.custom_board_serial_number == "":
|
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(" | ")
|
macserial_output = macserial_output.stdout.decode().strip().split(" | ")
|
||||||
sn = macserial_output[0]
|
sn = macserial_output[0]
|
||||||
mlb = macserial_output[1]
|
mlb = macserial_output[1]
|
||||||
|
|||||||
@@ -169,6 +169,27 @@ class BuildSupport:
|
|||||||
logging.info(f"- Found extra driver: {driver_file.name}")
|
logging.info(f"- Found extra driver: {driver_file.name}")
|
||||||
raise Exception(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:
|
def cleanup(self) -> None:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ from data import os_data
|
|||||||
class Constants:
|
class Constants:
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
# Patcher Versioning
|
# Patcher Versioning
|
||||||
self.patcher_version: str = "1.1.0" # OpenCore-Legacy-Patcher
|
self.patcher_version: str = "1.4.2" # OpenCore-Legacy-Patcher
|
||||||
self.patcher_support_pkg_version: str = "1.4.2" # PatcherSupportPkg
|
self.patcher_support_pkg_version: str = "1.4.8" # PatcherSupportPkg
|
||||||
self.copyright_date: str = "Copyright © 2020-2023 Dortania"
|
self.copyright_date: str = "Copyright © 2020-2024 Dortania"
|
||||||
self.patcher_name: str = "OpenCore Legacy Patcher"
|
self.patcher_name: str = "OpenCore Legacy Patcher"
|
||||||
|
|
||||||
# URLs
|
# URLs
|
||||||
@@ -28,7 +28,7 @@ class Constants:
|
|||||||
|
|
||||||
# OpenCore Versioning
|
# OpenCore Versioning
|
||||||
# https://github.com/acidanthera/OpenCorePkg
|
# https://github.com/acidanthera/OpenCorePkg
|
||||||
self.opencore_version: str = "0.9.3"
|
self.opencore_version: str = "0.9.7"
|
||||||
|
|
||||||
# Kext Versioning
|
# Kext Versioning
|
||||||
## Acidanthera
|
## Acidanthera
|
||||||
@@ -69,15 +69,18 @@ class Constants:
|
|||||||
self.apple_camera_version: str = "1.0.0" # AppleCameraInterface (14.0 Beta 1)
|
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_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_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
|
## Apple - Dortania Modified
|
||||||
self.bcm570_version: str = "1.0.2" # CatalinaBCM5701Ethernet
|
self.bcm570_version: str = "1.0.2" # CatalinaBCM5701Ethernet
|
||||||
self.i210_version: str = "1.0.0" # CatalinaIntelI210Ethernet
|
self.i210_version: str = "1.0.0" # CatalinaIntelI210Ethernet
|
||||||
self.corecaptureelcap_version: str = "1.0.1" # corecaptureElCap
|
self.corecaptureelcap_version: str = "1.0.2" # corecaptureElCap
|
||||||
self.io80211elcap_version: str = "2.0.0" # IO80211ElCap
|
self.io80211elcap_version: str = "2.0.1" # IO80211ElCap
|
||||||
self.io80211legacy_version: str = "1.0.0" # IO80211FamilyLegacy (Ventura)
|
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.bigsursdxc_version: str = "1.0.0" # BigSurSDXC
|
||||||
self.monterey_ahci_version: str = "1.0.0" # CatalinaAHCI
|
self.monterey_ahci_version: str = "1.0.0" # CatalinaAHCI
|
||||||
|
|
||||||
@@ -279,14 +282,26 @@ class Constants:
|
|||||||
def plist_template(self):
|
def plist_template(self):
|
||||||
return self.payload_path / Path("Config/config.plist")
|
return self.payload_path / Path("Config/config.plist")
|
||||||
|
|
||||||
# Launch Agent
|
# Launch Services
|
||||||
|
@property
|
||||||
|
def launch_services_path(self):
|
||||||
|
return self.payload_path / Path("Launch Services")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def auto_patch_launch_agent_path(self):
|
def auto_patch_launch_agent_path(self):
|
||||||
return self.payload_path / Path("com.dortania.opencore-legacy-patcher.auto-patch.plist")
|
return self.launch_services_path / Path("com.dortania.opencore-legacy-patcher.auto-patch.plist")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def rsr_monitor_launch_daemon_path(self):
|
def rsr_monitor_launch_daemon_path(self):
|
||||||
return self.payload_path / Path("com.dortania.opencore-legacy-patcher.rsr-monitor.plist")
|
return self.launch_services_path / Path("com.dortania.opencore-legacy-patcher.rsr-monitor.plist")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def update_launch_daemon_path(self):
|
||||||
|
return self.launch_services_path / Path("com.dortania.opencore-legacy-patcher.macos-update.plist")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def kdk_launch_daemon_path(self):
|
||||||
|
return self.launch_services_path / Path("com.dortania.opencore-legacy-patcher.os-caching.plist")
|
||||||
|
|
||||||
# ACPI
|
# ACPI
|
||||||
@property
|
@property
|
||||||
@@ -439,6 +454,10 @@ class Constants:
|
|||||||
def t1_key_store_path(self):
|
def t1_key_store_path(self):
|
||||||
return self.payload_kexts_path / Path(f"Misc/AppleKeyStore-v{self.t1_key_store_version}.zip")
|
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
|
@property
|
||||||
def t1_sse_path(self):
|
def t1_sse_path(self):
|
||||||
return self.payload_kexts_path / Path(f"Misc/AppleSSE-v{self.t1_sse_version}.zip")
|
return self.payload_kexts_path / Path(f"Misc/AppleSSE-v{self.t1_sse_version}.zip")
|
||||||
@@ -447,6 +466,14 @@ class Constants:
|
|||||||
def t1_corecrypto_path(self):
|
def t1_corecrypto_path(self):
|
||||||
return self.payload_kexts_path / Path(f"Misc/corecrypto_T1-v{self.t1_corecrypto_version}.zip")
|
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
|
@property
|
||||||
def mousse_path(self):
|
def mousse_path(self):
|
||||||
return self.payload_kexts_path / Path(f"SSE/AAAMouSSE-v{self.mousse_version}.zip")
|
return self.payload_kexts_path / Path(f"SSE/AAAMouSSE-v{self.mousse_version}.zip")
|
||||||
@@ -703,6 +730,13 @@ class Constants:
|
|||||||
return self.payload_path / Path("Tools/RSRRepair")
|
return self.payload_path / Path("Tools/RSRRepair")
|
||||||
|
|
||||||
# Icons
|
# Icons
|
||||||
|
@property
|
||||||
|
def icns_resource_path(self):
|
||||||
|
if self.launcher_script:
|
||||||
|
return self.payload_path / Path("Icon/AppIcons")
|
||||||
|
return Path(self.launcher_binary).parent.parent / Path("Resources")
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def app_icon_path(self):
|
def app_icon_path(self):
|
||||||
return self.payload_path / Path("OC-Patcher.icns")
|
return self.payload_path / Path("OC-Patcher.icns")
|
||||||
@@ -725,23 +759,23 @@ class Constants:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def icon_path_macos_generic(self):
|
def icon_path_macos_generic(self):
|
||||||
return self.payload_path / Path("Icon/AppIcons/Generic.icns")
|
return self.icns_resource_path / Path("Generic.icns")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def icon_path_macos_big_sur(self):
|
def icon_path_macos_big_sur(self):
|
||||||
return self.payload_path / Path("Icon/AppIcons/BigSur.icns")
|
return self.icns_resource_path / Path("BigSur.icns")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def icon_path_macos_monterey(self):
|
def icon_path_macos_monterey(self):
|
||||||
return self.payload_path / Path("Icon/AppIcons/Monterey.icns")
|
return self.icns_resource_path / Path("Monterey.icns")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def icon_path_macos_ventura(self):
|
def icon_path_macos_ventura(self):
|
||||||
return self.payload_path / Path("Icon/AppIcons/Ventura.icns")
|
return self.icns_resource_path / Path("Ventura.icns")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def icon_path_macos_sonoma(self):
|
def icon_path_macos_sonoma(self):
|
||||||
return self.payload_path / Path("Icon/AppIcons/Sonoma.icns")
|
return self.icns_resource_path / Path("Sonoma.icns")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gui_path(self):
|
def gui_path(self):
|
||||||
@@ -764,13 +798,6 @@ class Constants:
|
|||||||
def kdk_download_path(self):
|
def kdk_download_path(self):
|
||||||
return self.payload_path / Path("KDK.dmg")
|
return self.payload_path / Path("KDK.dmg")
|
||||||
|
|
||||||
@property
|
|
||||||
def icns_resource_path(self):
|
|
||||||
if self.launcher_script:
|
|
||||||
return self.payload_path / Path("Icon/AppIcons")
|
|
||||||
return Path(self.launcher_binary).parent.parent / Path("Resources")
|
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def icons_path(self):
|
def icons_path(self):
|
||||||
return [
|
return [
|
||||||
|
|||||||
@@ -329,9 +329,9 @@ class GenerateDefaults:
|
|||||||
|
|
||||||
for key in ["Moraea_BlurBeta"]:
|
for key in ["Moraea_BlurBeta"]:
|
||||||
# Enable BetaBlur if user hasn't disabled it
|
# 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"]:
|
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:
|
def _check_amfipass_supported(self) -> None:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -28,22 +28,24 @@ class CPU:
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class USBDevice:
|
class USBDevice:
|
||||||
vendor_id: int
|
vendor_id: int
|
||||||
device_id: int
|
device_id: int
|
||||||
device_class: int
|
device_class: int
|
||||||
device_speed: int
|
device_speed: int
|
||||||
product_name: str
|
product_name: str
|
||||||
vendor_name: Optional[str] = None
|
vendor_name: Optional[str] = None
|
||||||
|
serial_number: Optional[str] = None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_ioregistry(cls, entry: ioreg.io_registry_entry_t):
|
def from_ioregistry(cls, entry: ioreg.io_registry_entry_t):
|
||||||
properties: dict = ioreg.corefoundation_to_native(ioreg.IORegistryEntryCreateCFProperties(entry, None, ioreg.kCFAllocatorDefault, ioreg.kNilOptions)[1])
|
properties: dict = ioreg.corefoundation_to_native(ioreg.IORegistryEntryCreateCFProperties(entry, None, ioreg.kCFAllocatorDefault, ioreg.kNilOptions)[1])
|
||||||
|
|
||||||
vendor_id = None
|
vendor_id = None
|
||||||
device_id = None
|
device_id = None
|
||||||
device_class = None
|
device_class = None
|
||||||
device_speed = None
|
device_speed = None
|
||||||
vendor_name = None
|
vendor_name = None
|
||||||
|
serial_number = None
|
||||||
product_name = "N/A"
|
product_name = "N/A"
|
||||||
|
|
||||||
if "idVendor" in properties:
|
if "idVendor" in properties:
|
||||||
@@ -58,8 +60,10 @@ class USBDevice:
|
|||||||
vendor_name = properties["kUSBVendorString"].strip()
|
vendor_name = properties["kUSBVendorString"].strip()
|
||||||
if "USBSpeed" in properties:
|
if "USBSpeed" in properties:
|
||||||
device_speed = properties["USBSpeed"]
|
device_speed = properties["USBSpeed"]
|
||||||
|
if "kUSBSerialNumberString" in properties:
|
||||||
|
serial_number = properties["kUSBSerialNumberString"].strip()
|
||||||
|
|
||||||
return cls(vendor_id, device_id, device_class, device_speed, product_name, vendor_name)
|
return cls(vendor_id, device_id, device_class, device_speed, product_name, vendor_name, serial_number)
|
||||||
|
|
||||||
|
|
||||||
def detect(self):
|
def detect(self):
|
||||||
@@ -858,7 +862,7 @@ class Computer:
|
|||||||
# Reported model
|
# Reported model
|
||||||
entry = next(ioreg.ioiterator_to_list(ioreg.IOServiceGetMatchingServices(ioreg.kIOMasterPortDefault, ioreg.IOServiceMatching("IOPlatformExpertDevice".encode()), None)[1]))
|
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
|
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:
|
if translated:
|
||||||
board = "target-type"
|
board = "target-type"
|
||||||
else:
|
else:
|
||||||
@@ -890,14 +894,14 @@ class Computer:
|
|||||||
|
|
||||||
def cpu_probe(self):
|
def cpu_probe(self):
|
||||||
self.cpu = CPU(
|
self.cpu = CPU(
|
||||||
subprocess.run("sysctl machdep.cpu.brand_string".split(), stdout=subprocess.PIPE).stdout.decode().partition(": ")[2].strip(),
|
subprocess.run(["/usr/sbin/sysctl", "machdep.cpu.brand_string"], 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.features"], stdout=subprocess.PIPE).stdout.decode().partition(": ")[2].strip().split(" "),
|
||||||
self.cpu_get_leafs(),
|
self.cpu_get_leafs(),
|
||||||
)
|
)
|
||||||
|
|
||||||
def cpu_get_leafs(self):
|
def cpu_get_leafs(self):
|
||||||
leafs = []
|
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:
|
if result.returncode == 0:
|
||||||
return result.stdout.decode().partition(": ")[2].strip().split(" ")
|
return result.stdout.decode().partition(": ")[2].strip().split(" ")
|
||||||
return leafs
|
return leafs
|
||||||
@@ -945,15 +949,37 @@ class Computer:
|
|||||||
for usb_device in self.usb_devices:
|
for usb_device in self.usb_devices:
|
||||||
if usb_device.vendor_id != 0x5ac:
|
if usb_device.vendor_id != 0x5ac:
|
||||||
continue
|
continue
|
||||||
if usb_device.device_id != 0x8600:
|
# Standard T1
|
||||||
continue
|
if usb_device.device_id == 0x8600:
|
||||||
self.t1_chip = True
|
self.t1_chip = True
|
||||||
break
|
break
|
||||||
|
# T1 in DFU mode
|
||||||
|
# Note all Apple devices report the same device ID in DFU mode
|
||||||
|
if usb_device.device_id == 0x1281:
|
||||||
|
# Break down serial number into components
|
||||||
|
# ex. "CPID:8002 CPRV:10 CPFM:03 SCEP:01 BDID:12 ECID:000E5C8E34600026 IBFL:3D"
|
||||||
|
# Is this overcomplicating T1 detection? Probably...
|
||||||
|
if usb_device.serial_number is None:
|
||||||
|
continue
|
||||||
|
serial_number = usb_device.serial_number.split(" ")
|
||||||
|
# T1s come in 2 known flavours:
|
||||||
|
# - x619dev
|
||||||
|
# - CPID: 0x8002
|
||||||
|
# - BDID: 0x13
|
||||||
|
# - x619ap
|
||||||
|
# - CPID: 0x8002
|
||||||
|
# - BDID: 0x12
|
||||||
|
if "CPID:8002" not in serial_number:
|
||||||
|
continue
|
||||||
|
if "BDID:13" not in serial_number and "BDID:12" not in serial_number:
|
||||||
|
continue
|
||||||
|
self.t1_chip = True
|
||||||
|
break
|
||||||
|
|
||||||
def sata_disk_probe(self):
|
def sata_disk_probe(self):
|
||||||
# Get all SATA Controllers/Disks from 'system_profiler SPSerialATADataType'
|
# Get all SATA Controllers/Disks from 'system_profiler SPSerialATADataType'
|
||||||
# Determine whether SATA SSD is present and Apple-made
|
# 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 root in sp_sata_data:
|
||||||
for ahci_controller in root["_items"]:
|
for ahci_controller in root["_items"]:
|
||||||
# Each AHCI controller will have its own entry
|
# Each AHCI controller will have its own entry
|
||||||
@@ -989,7 +1015,7 @@ class Computer:
|
|||||||
self.oclp_sys_signed = sys_plist["Custom Signature"]
|
self.oclp_sys_signed = sys_plist["Custom Signature"]
|
||||||
|
|
||||||
def check_rosetta(self):
|
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:
|
if "1" in result:
|
||||||
self.rosetta_active = True
|
self.rosetta_active = True
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ class GlobalEnviromentSettings:
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Set file permission to allow any user to write to log file
|
# 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:
|
if result.returncode != 0:
|
||||||
logging.warning("Failed to fix settings file permissions:")
|
logging.warning("Failed to fix settings file permissions:")
|
||||||
if result.stderr:
|
if result.stderr:
|
||||||
|
|||||||
@@ -22,16 +22,16 @@ class tui_disk_installation:
|
|||||||
# TODO: AllDisksAndPartitions is not supported in Snow Leopard and older
|
# TODO: AllDisksAndPartitions is not supported in Snow Leopard and older
|
||||||
try:
|
try:
|
||||||
# High Sierra and newer
|
# 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:
|
except ValueError:
|
||||||
# Sierra and older
|
# 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"]:
|
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:
|
try:
|
||||||
all_disks[disk["DeviceIdentifier"]] = {"identifier": disk_info["DeviceNode"], "name": disk_info["MediaName"], "size": disk_info["TotalSize"], "partitions": {}}
|
all_disks[disk["DeviceIdentifier"]] = {"identifier": disk_info["DeviceNode"], "name": disk_info["MediaName"], "size": disk_info["TotalSize"], "partitions": {}}
|
||||||
for partition in disk["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"]] = {
|
all_disks[disk["DeviceIdentifier"]]["partitions"][partition["DeviceIdentifier"]] = {
|
||||||
"fs": partition_info.get("FilesystemType", partition_info["Content"]),
|
"fs": partition_info.get("FilesystemType", partition_info["Content"]),
|
||||||
"type": partition_info["Content"],
|
"type": partition_info["Content"],
|
||||||
@@ -102,15 +102,15 @@ class tui_disk_installation:
|
|||||||
logging.info("Please disable Safe Mode and try again.")
|
logging.info("Please disable Safe Mode and try again.")
|
||||||
return
|
return
|
||||||
else:
|
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:
|
if result.returncode != 0:
|
||||||
logging.info("Mount failed")
|
logging.info("Mount failed")
|
||||||
logging.info(result.stderr.decode())
|
logging.info(result.stderr.decode())
|
||||||
return
|
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"]
|
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"]
|
sd_type = drive_host_info["MediaName"]
|
||||||
try:
|
try:
|
||||||
ssd_type = drive_host_info["SolidState"]
|
ssd_type = drive_host_info["SolidState"]
|
||||||
@@ -125,49 +125,49 @@ class tui_disk_installation:
|
|||||||
|
|
||||||
if (mount_path / Path("EFI/OC")).exists():
|
if (mount_path / Path("EFI/OC")).exists():
|
||||||
logging.info("Removing preexisting EFI/OC folder")
|
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():
|
if (mount_path / Path("System")).exists():
|
||||||
logging.info("Removing preexisting System folder")
|
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():
|
if (mount_path / Path("boot.efi")).exists():
|
||||||
logging.info("Removing preexisting boot.efi")
|
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")
|
logging.info("Copying OpenCore onto EFI partition")
|
||||||
subprocess.run(["mkdir", "-p", mount_path / Path("EFI")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
subprocess.run(["/bin/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(["/bin/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/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():
|
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:
|
if self.constants.boot_efi is True:
|
||||||
logging.info("Converting Bootstrap to BOOTx64.efi")
|
logging.info("Converting Bootstrap to BOOTx64.efi")
|
||||||
if (mount_path / Path("EFI/BOOT")).exists():
|
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()
|
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(["/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(["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 self._determine_sd_card(sd_type) is True:
|
if self._determine_sd_card(sd_type) is True:
|
||||||
logging.info("Adding SD Card icon")
|
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:
|
elif ssd_type is True:
|
||||||
logging.info("Adding SSD icon")
|
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":
|
elif disk_type == "USB":
|
||||||
logging.info("Adding External USB Drive icon")
|
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:
|
else:
|
||||||
logging.info("Adding Internal Drive icon")
|
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")
|
logging.info("Cleaning install location")
|
||||||
if not self.constants.recovery_status:
|
if not self.constants.recovery_status:
|
||||||
logging.info("Unmounting EFI partition")
|
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")
|
logging.info("OpenCore transfer complete")
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,12 @@ class KernelDebugKitObject:
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, global_constants: constants.Constants, host_build: str, host_version: str, ignore_installed: bool = False, passive: bool = False) -> None:
|
def __init__(self, global_constants: constants.Constants,
|
||||||
|
host_build: str, host_version: str,
|
||||||
|
ignore_installed: bool = False, passive: bool = False,
|
||||||
|
check_backups_only: bool = False
|
||||||
|
) -> None:
|
||||||
|
|
||||||
self.constants: constants.Constants = global_constants
|
self.constants: constants.Constants = global_constants
|
||||||
|
|
||||||
self.host_build: str = host_build # ex. 20A5384c
|
self.host_build: str = host_build # ex. 20A5384c
|
||||||
@@ -57,7 +62,8 @@ class KernelDebugKitObject:
|
|||||||
|
|
||||||
self.passive: bool = passive # Don't perform actions requiring elevated privileges
|
self.passive: bool = passive # Don't perform actions requiring elevated privileges
|
||||||
|
|
||||||
self.ignore_installed: bool = ignore_installed # If True, will ignore any installed KDKs and download the latest
|
self.ignore_installed: bool = ignore_installed # If True, will ignore any installed KDKs and download the latest
|
||||||
|
self.check_backups_only: bool = check_backups_only # If True, will only check for KDK backups, not KDKs already installed
|
||||||
self.kdk_already_installed: bool = False
|
self.kdk_already_installed: bool = False
|
||||||
|
|
||||||
self.kdk_installed_path: str = ""
|
self.kdk_installed_path: str = ""
|
||||||
@@ -114,7 +120,7 @@ class KernelDebugKitObject:
|
|||||||
logging.info("Could not fetch KDK list")
|
logging.info("Could not fetch KDK list")
|
||||||
return None
|
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
|
return KDK_ASSET_LIST
|
||||||
|
|
||||||
@@ -328,7 +334,7 @@ class KernelDebugKitObject:
|
|||||||
kdk_build = kdk_plist_data["ProductBuildVersion"]
|
kdk_build = kdk_plist_data["ProductBuildVersion"]
|
||||||
|
|
||||||
# Check pkg receipts for this build, will give a canonical list if all files that should be present
|
# 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 result.returncode != 0:
|
||||||
# If pkg receipt is missing, we'll fallback to legacy validation
|
# 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")
|
logging.info(f"pkg receipt missing for {kdk_path.name}, falling back to legacy validation")
|
||||||
@@ -400,18 +406,20 @@ class KernelDebugKitObject:
|
|||||||
if not Path(KDK_INSTALL_PATH).exists():
|
if not Path(KDK_INSTALL_PATH).exists():
|
||||||
return None
|
return None
|
||||||
|
|
||||||
for kdk_folder in Path(KDK_INSTALL_PATH).iterdir():
|
# Installed KDKs only
|
||||||
if not kdk_folder.is_dir():
|
if self.check_backups_only is False:
|
||||||
continue
|
for kdk_folder in Path(KDK_INSTALL_PATH).iterdir():
|
||||||
if check_version:
|
if not kdk_folder.is_dir():
|
||||||
if match not in kdk_folder.name:
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
if not kdk_folder.name.endswith(f"{match}.kdk"):
|
|
||||||
continue
|
continue
|
||||||
|
if check_version:
|
||||||
|
if match not in kdk_folder.name:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
if not kdk_folder.name.endswith(f"{match}.kdk"):
|
||||||
|
continue
|
||||||
|
|
||||||
if self._local_kdk_valid(kdk_folder):
|
if self._local_kdk_valid(kdk_folder):
|
||||||
return kdk_folder
|
return kdk_folder
|
||||||
|
|
||||||
# If we can't find a KDK, next check if there's a backup present
|
# If we can't find a KDK, next check if there's a backup present
|
||||||
# Check for KDK packages in the same directory as the KDK
|
# Check for KDK packages in the same directory as the KDK
|
||||||
@@ -460,7 +468,7 @@ class KernelDebugKitObject:
|
|||||||
logging.warning(f"KDK does not exist: {kdk_path}")
|
logging.warning(f"KDK does not exist: {kdk_path}")
|
||||||
return
|
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)
|
result = utilities.elevated(rm_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
@@ -530,7 +538,7 @@ class KernelDebugKitObject:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
# TODO: should we use the checksum from the API?
|
# 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:
|
if result.returncode != 0:
|
||||||
logging.info("Error: Kernel Debug Kit checksum verification failed!")
|
logging.info("Error: Kernel Debug Kit checksum verification failed!")
|
||||||
logging.info(f"Output: {result.stderr.decode('utf-8')}")
|
logging.info(f"Output: {result.stderr.decode('utf-8')}")
|
||||||
@@ -587,7 +595,7 @@ class KernelDebugKitUtilities:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def install_kdk_dmg(self, kdk_path: Path) -> bool:
|
def install_kdk_dmg(self, kdk_path: Path, only_install_backup: bool = False) -> bool:
|
||||||
"""
|
"""
|
||||||
Installs provided KDK disk image
|
Installs provided KDK disk image
|
||||||
|
|
||||||
@@ -604,7 +612,7 @@ class KernelDebugKitUtilities:
|
|||||||
|
|
||||||
logging.info(f"Extracting downloaded KDK disk image")
|
logging.info(f"Extracting downloaded KDK disk image")
|
||||||
with tempfile.TemporaryDirectory() as mount_point:
|
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:
|
if result.returncode != 0:
|
||||||
logging.info("Failed to mount KDK:")
|
logging.info("Failed to mount KDK:")
|
||||||
logging.info(result.stdout.decode('utf-8'))
|
logging.info(result.stdout.decode('utf-8'))
|
||||||
@@ -617,9 +625,11 @@ class KernelDebugKitUtilities:
|
|||||||
self._unmount_disk_image(mount_point)
|
self._unmount_disk_image(mount_point)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if self.install_kdk_pkg(kdk_pkg_path) is False:
|
|
||||||
self._unmount_disk_image(mount_point)
|
if only_install_backup is False:
|
||||||
return False
|
if self.install_kdk_pkg(kdk_pkg_path) is False:
|
||||||
|
self._unmount_disk_image(mount_point)
|
||||||
|
return False
|
||||||
|
|
||||||
self._create_backup(kdk_pkg_path, Path(f"{kdk_path.parent}/{KDK_INFO_PLIST}"))
|
self._create_backup(kdk_pkg_path, Path(f"{kdk_path.parent}/{KDK_INFO_PLIST}"))
|
||||||
self._unmount_disk_image(mount_point)
|
self._unmount_disk_image(mount_point)
|
||||||
@@ -634,7 +644,7 @@ class KernelDebugKitUtilities:
|
|||||||
Parameters:
|
Parameters:
|
||||||
mount_point (Path): Path to mount point
|
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:
|
def _create_backup(self, kdk_path: Path, kdk_info_plist: Path) -> None:
|
||||||
@@ -663,6 +673,9 @@ class KernelDebugKitUtilities:
|
|||||||
logging.warning("Cannot create KDK backup, not running as root")
|
logging.warning("Cannot create KDK backup, not running as root")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if not Path(KDK_INSTALL_PATH).exists():
|
||||||
|
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_name = f"KDK_{kdk_info_dict['version']}_{kdk_info_dict['build']}.pkg"
|
||||||
kdk_dst_path = Path(f"{KDK_INSTALL_PATH}/{kdk_dst_name}")
|
kdk_dst_path = Path(f"{KDK_INSTALL_PATH}/{kdk_dst_name}")
|
||||||
|
|
||||||
@@ -671,7 +684,7 @@ class KernelDebugKitUtilities:
|
|||||||
logging.info("Backup already exists, skipping")
|
logging.info("Backup already exists, skipping")
|
||||||
return
|
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:
|
if result.returncode != 0:
|
||||||
logging.info("Failed to create KDK backup:")
|
logging.info("Failed to create KDK backup:")
|
||||||
logging.info(result.stdout.decode('utf-8'))
|
logging.info(result.stdout.decode('utf-8'))
|
||||||
@@ -61,7 +61,7 @@ class InitializeLoggingSupport:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
base_path = Path("~/Library/Logs").expanduser()
|
base_path = Path("~/Library/Logs").expanduser()
|
||||||
if not base_path.exists():
|
if not base_path.exists() or str(base_path).startswith("/var/root/"):
|
||||||
# Likely in an installer environment, store in /Users/Shared
|
# Likely in an installer environment, store in /Users/Shared
|
||||||
base_path = Path("/Users/Shared")
|
base_path = Path("/Users/Shared")
|
||||||
else:
|
else:
|
||||||
@@ -71,7 +71,7 @@ class InitializeLoggingSupport:
|
|||||||
try:
|
try:
|
||||||
base_path.mkdir()
|
base_path.mkdir()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"Failed to create Dortania folder: {e}")
|
print(f"Failed to create Dortania folder: {e}")
|
||||||
base_path = Path("/Users/Shared")
|
base_path = Path("/Users/Shared")
|
||||||
|
|
||||||
self.log_filepath = Path(f"{base_path}/{self.log_filename}").expanduser()
|
self.log_filepath = Path(f"{base_path}/{self.log_filename}").expanduser()
|
||||||
@@ -130,7 +130,7 @@ class InitializeLoggingSupport:
|
|||||||
]
|
]
|
||||||
|
|
||||||
for path in paths:
|
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:
|
if result.returncode != 0:
|
||||||
logging.error(f"Failed to fix log file permissions")
|
logging.error(f"Failed to fix log file permissions")
|
||||||
if result.stdout:
|
if result.stdout:
|
||||||
@@ -194,6 +194,7 @@ class InitializeLoggingSupport:
|
|||||||
logging.info('#' * str_len)
|
logging.info('#' * str_len)
|
||||||
|
|
||||||
logging.info("Log file set:")
|
logging.info("Log file set:")
|
||||||
|
logging.info(f" {self.log_filepath}")
|
||||||
# Display relative path to avoid disclosing user's username
|
# Display relative path to avoid disclosing user's username
|
||||||
try:
|
try:
|
||||||
path = self.log_filepath.relative_to(Path.home())
|
path = self.log_filepath.relative_to(Path.home())
|
||||||
@@ -250,7 +251,7 @@ class InitializeLoggingSupport:
|
|||||||
return
|
return
|
||||||
|
|
||||||
if cant_log is True:
|
if cant_log is True:
|
||||||
subprocess.run(["open", "--reveal", self.log_filepath])
|
subprocess.run(["/usr/bin/open", "--reveal", self.log_filepath])
|
||||||
return
|
return
|
||||||
|
|
||||||
threading.Thread(target=analytics_handler.Analytics(self.constants).send_crash_report, args=(self.log_filepath,)).start()
|
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}")
|
logging.info(f"Creating temporary directory at {ia_tmp}")
|
||||||
# Delete all files in tmp_dir
|
# Delete all files in tmp_dir
|
||||||
for file in Path(ia_tmp).glob("*"):
|
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)
|
# 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":
|
if utilities.check_filesystem_type() != "apfs":
|
||||||
# HFS+ disks do not support CoW
|
# HFS+ disks do not support CoW
|
||||||
args[1] = "-R"
|
args[1] = "-R"
|
||||||
@@ -179,13 +179,13 @@ fi
|
|||||||
# TODO: AllDisksAndPartitions is not supported in Snow Leopard and older
|
# TODO: AllDisksAndPartitions is not supported in Snow Leopard and older
|
||||||
try:
|
try:
|
||||||
# High Sierra and newer
|
# 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:
|
except ValueError:
|
||||||
# Sierra and older
|
# 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"]:
|
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:
|
try:
|
||||||
all_disks[disk["DeviceIdentifier"]] = {"identifier": disk_info["DeviceNode"], "name": disk_info["MediaName"], "size": disk_info["TotalSize"], "removable": disk_info["Internal"], "partitions": {}}
|
all_disks[disk["DeviceIdentifier"]] = {"identifier": disk_info["DeviceNode"], "name": disk_info["MediaName"], "size": disk_info["TotalSize"], "removable": disk_info["Internal"], "partitions": {}}
|
||||||
except KeyError:
|
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'])}
|
available_apps = {k: v for k, v in sorted(available_apps.items(), key=lambda x: x[1]['Version'])}
|
||||||
|
|
||||||
return available_apps
|
return available_apps
|
||||||
|
|
||||||
|
|
||||||
@@ -623,7 +623,7 @@ class LocalInstallerCatalog:
|
|||||||
|
|
||||||
output = subprocess.run(
|
output = subprocess.run(
|
||||||
[
|
[
|
||||||
"hdiutil", "attach", "-noverify", sharedsupport_path,
|
"/usr/bin/hdiutil", "attach", "-noverify", sharedsupport_path,
|
||||||
"-mountpoint", tmpdir,
|
"-mountpoint", tmpdir,
|
||||||
"-nobrowse",
|
"-nobrowse",
|
||||||
],
|
],
|
||||||
@@ -644,6 +644,6 @@ class LocalInstallerCatalog:
|
|||||||
detected_os = plist["Assets"][0]["OSVersion"]
|
detected_os = plist["Assets"][0]["OSVersion"]
|
||||||
|
|
||||||
# Unmount SharedSupport.dmg
|
# 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)
|
return (detected_build, detected_os)
|
||||||
@@ -44,7 +44,7 @@ class OSProbe:
|
|||||||
str: OS version (ex. 12.0)
|
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:
|
if result.returncode != 0:
|
||||||
raise RuntimeError("Failed to detect OS version")
|
raise RuntimeError("Failed to detect OS version")
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class RoutePayloadDiskImage:
|
|||||||
self._unmount_active_dmgs(unmount_all_active=False)
|
self._unmount_active_dmgs(unmount_all_active=False)
|
||||||
output = subprocess.run(
|
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")),
|
"-mountpoint", Path(self.temp_dir.name / Path("payloads")),
|
||||||
"-nobrowse",
|
"-nobrowse",
|
||||||
"-shadow", Path(self.temp_dir.name / Path("payloads_overlay")),
|
"-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
|
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)
|
dmg_info = plistlib.loads(dmg_info.stdout)
|
||||||
|
|
||||||
|
|
||||||
@@ -80,12 +80,12 @@ class RoutePayloadDiskImage:
|
|||||||
if self.temp_dir.name in image["shadow-path"]:
|
if self.temp_dir.name in image["shadow-path"]:
|
||||||
logging.info(f"Unmounting personal {variant}")
|
logging.info(f"Unmounting personal {variant}")
|
||||||
subprocess.run(
|
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
|
stdout=subprocess.PIPE, stderr=subprocess.STDOUT
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
logging.info(f"Unmounting {variant} at: {image['system-entities'][0]['dev-entry']}")
|
logging.info(f"Unmounting {variant} at: {image['system-entities'][0]['dev-entry']}")
|
||||||
subprocess.run(
|
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
|
stdout=subprocess.PIPE, stderr=subprocess.STDOUT
|
||||||
)
|
)
|
||||||
@@ -209,7 +209,7 @@ class PatchSysVolume:
|
|||||||
if save_hid_cs is True and cs_path.exists():
|
if save_hid_cs is True and cs_path.exists():
|
||||||
logging.info("- Backing up IOHIDEventDriver CodeSignature")
|
logging.info("- Backing up IOHIDEventDriver CodeSignature")
|
||||||
# Note it's a folder, not a file
|
# 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}")
|
logging.info(f"- Merging KDK with Root Volume: {kdk_path.name}")
|
||||||
utilities.elevated(
|
utilities.elevated(
|
||||||
@@ -230,9 +230,9 @@ class PatchSysVolume:
|
|||||||
logging.info("- Restoring IOHIDEventDriver CodeSignature")
|
logging.info("- Restoring IOHIDEventDriver CodeSignature")
|
||||||
if not cs_path.exists():
|
if not cs_path.exists():
|
||||||
logging.info(" - CodeSignature folder missing, creating")
|
logging.info(" - CodeSignature folder missing, creating")
|
||||||
utilities.elevated(["mkdir", "-p", cs_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
utilities.elevated(["/bin/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(["/bin/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/rm", "-rf", f"{self.constants.payload_path}/IOHIDEventDriver_CodeSignature.bak"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||||
|
|
||||||
|
|
||||||
def _unpatch_root_vol(self):
|
def _unpatch_root_vol(self):
|
||||||
@@ -369,7 +369,7 @@ class PatchSysVolume:
|
|||||||
|
|
||||||
if self.skip_root_kmutil_requirement is True:
|
if self.skip_root_kmutil_requirement is True:
|
||||||
# Force rebuild the Auxiliary KC
|
# 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:
|
if result.returncode != 0:
|
||||||
logging.info("- Unable to remove kernel extension policy files")
|
logging.info("- Unable to remove kernel extension policy files")
|
||||||
logging.info(f"\nReason for Patch Failure ({result.returncode}):")
|
logging.info(f"\nReason for Patch Failure ({result.returncode}):")
|
||||||
@@ -422,7 +422,7 @@ class PatchSysVolume:
|
|||||||
"""
|
"""
|
||||||
if self.root_mount_path:
|
if self.root_mount_path:
|
||||||
logging.info("- Unmounting Root Volume (Don't worry if this fails)")
|
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:
|
else:
|
||||||
logging.info("- Skipping Root Volume unmount")
|
logging.info("- Skipping Root Volume unmount")
|
||||||
|
|
||||||
@@ -457,11 +457,11 @@ class PatchSysVolume:
|
|||||||
|
|
||||||
if (Path(self.mount_application_support) / Path("SkyLightPlugins/")).exists():
|
if (Path(self.mount_application_support) / Path("SkyLightPlugins/")).exists():
|
||||||
logging.info("- Found SkylightPlugins folder, removing old plugins")
|
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(["/bin/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/mkdir", f"{self.mount_application_support}/SkyLightPlugins"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||||
else:
|
else:
|
||||||
logging.info("- Creating SkylightPlugins folder")
|
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:
|
def _delete_nonmetal_enforcement(self) -> None:
|
||||||
@@ -471,10 +471,10 @@ class PatchSysVolume:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
for arg in ["useMetal", "useIOP"]:
|
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"]:
|
if result in ["0", "false", "1", "true"]:
|
||||||
logging.info(f"- Removing non-Metal Enforcement Preference: {arg}")
|
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:
|
def _clean_auxiliary_kc(self) -> None:
|
||||||
@@ -516,15 +516,15 @@ class PatchSysVolume:
|
|||||||
|
|
||||||
relocation_path = "/Library/Relocated Extensions"
|
relocation_path = "/Library/Relocated Extensions"
|
||||||
if not Path(relocation_path).exists():
|
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"):
|
for file in Path("/Library/Extensions").glob("*.kext"):
|
||||||
try:
|
try:
|
||||||
if datetime.fromtimestamp(file.stat().st_mtime) < datetime(2021, 10, 1):
|
if datetime.fromtimestamp(file.stat().st_mtime) < datetime(2021, 10, 1):
|
||||||
logging.info(f" - Relocating {file.name} kext to {relocation_path}")
|
logging.info(f" - Relocating {file.name} kext to {relocation_path}")
|
||||||
if Path(relocation_path) / Path(file.name).exists():
|
if Path(relocation_path) / Path(file.name).exists():
|
||||||
utilities.elevated(["rm", "-Rf", relocation_path / Path(file.name)])
|
utilities.elevated(["/bin/rm", "-Rf", relocation_path / Path(file.name)])
|
||||||
utilities.elevated(["mv", file, relocation_path])
|
utilities.elevated(["/bin/mv", file, relocation_path])
|
||||||
except:
|
except:
|
||||||
# Some users have the most cursed /L*/E* folders
|
# Some users have the most cursed /L*/E* folders
|
||||||
# ex. Symlinks pointing to symlinks pointing to dead files
|
# 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):
|
if sys_patch_helpers.SysPatchHelpers(self.constants).generate_patchset_plist(patchset, file_name, self.kdk_path):
|
||||||
logging.info("- Writing patchset information to Root Volume")
|
logging.info("- Writing patchset information to Root Volume")
|
||||||
if Path(destination_path_file).exists():
|
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(["/bin/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/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:
|
def _add_auxkc_support(self, install_file: str, source_folder_path: str, install_patch_directory: str, destination_folder_path: str) -> str:
|
||||||
@@ -648,7 +648,10 @@ class PatchSysVolume:
|
|||||||
self._execute_patchset(sys_patch_generate.GenerateRootPatchSets(self.computer.real_model, self.constants, self.hardware_details).patchset)
|
self._execute_patchset(sys_patch_generate.GenerateRootPatchSets(self.computer.real_model, self.constants, self.hardware_details).patchset)
|
||||||
|
|
||||||
if self.constants.wxpython_variant is True and self.constants.detected_os >= os_data.os_data.big_sur:
|
if self.constants.wxpython_variant is True and self.constants.detected_os >= os_data.os_data.big_sur:
|
||||||
sys_patch_auto.AutomaticSysPatch(self.constants).install_auto_patcher_launch_agent()
|
needs_daemon = False
|
||||||
|
if self.constants.detected_os >= os_data.os_data.ventura and self.skip_root_kmutil_requirement is False:
|
||||||
|
needs_daemon = True
|
||||||
|
sys_patch_auto.AutomaticSysPatch(self.constants).install_auto_patcher_launch_agent(kdk_caching_needed=needs_daemon)
|
||||||
|
|
||||||
self._rebuild_root_volume()
|
self._rebuild_root_volume()
|
||||||
|
|
||||||
@@ -716,8 +719,6 @@ class PatchSysVolume:
|
|||||||
utilities.process_status(subprocess.run(process, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True))
|
utilities.process_status(subprocess.run(process, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True))
|
||||||
if any(x in required_patches for x in ["AMD Legacy GCN", "AMD Legacy Polaris", "AMD Legacy Vega"]):
|
if any(x in required_patches for x in ["AMD Legacy GCN", "AMD Legacy Polaris", "AMD Legacy Vega"]):
|
||||||
sys_patch_helpers.SysPatchHelpers(self.constants).disable_window_server_caching()
|
sys_patch_helpers.SysPatchHelpers(self.constants).disable_window_server_caching()
|
||||||
if any(x in required_patches for x in ["Intel Ivy Bridge", "Intel Haswell"]):
|
|
||||||
sys_patch_helpers.SysPatchHelpers(self.constants).remove_news_widgets()
|
|
||||||
if "Metal 3802 Common Extended" in required_patches:
|
if "Metal 3802 Common Extended" in required_patches:
|
||||||
sys_patch_helpers.SysPatchHelpers(self.constants).patch_gpu_compiler_libraries(mount_point=self.mount_location)
|
sys_patch_helpers.SysPatchHelpers(self.constants).patch_gpu_compiler_libraries(mount_point=self.mount_location)
|
||||||
|
|
||||||
@@ -791,19 +792,19 @@ class PatchSysVolume:
|
|||||||
# Applicable for .kext, .app, .plugin, .bundle, all of which are directories
|
# Applicable for .kext, .app, .plugin, .bundle, all of which are directories
|
||||||
if Path(destination_folder + "/" + file_name).exists():
|
if Path(destination_folder + "/" + file_name).exists():
|
||||||
logging.info(f" - Found existing {file_name}, overwriting...")
|
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:
|
else:
|
||||||
logging.info(f" - Installing: {file_name}")
|
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)
|
self._fix_permissions(destination_folder + "/" + file_name)
|
||||||
else:
|
else:
|
||||||
# Assume it's an individual file, replace as normal
|
# Assume it's an individual file, replace as normal
|
||||||
if Path(destination_folder + "/" + file_name).exists():
|
if Path(destination_folder + "/" + file_name).exists():
|
||||||
logging.info(f" - Found existing {file_name}, overwriting...")
|
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:
|
else:
|
||||||
logging.info(f" - Installing: {file_name}")
|
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)
|
self._fix_permissions(destination_folder + "/" + file_name)
|
||||||
|
|
||||||
|
|
||||||
@@ -819,9 +820,9 @@ class PatchSysVolume:
|
|||||||
if Path(destination_folder + "/" + file_name).exists():
|
if Path(destination_folder + "/" + file_name).exists():
|
||||||
logging.info(f" - Removing: {file_name}")
|
logging.info(f" - Removing: {file_name}")
|
||||||
if Path(destination_folder + "/" + file_name).is_dir():
|
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:
|
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:
|
def _fix_permissions(self, destination_file: Path) -> None:
|
||||||
@@ -856,7 +857,7 @@ class PatchSysVolume:
|
|||||||
|
|
||||||
output = subprocess.run(
|
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")),
|
"-mountpoint", Path(self.constants.payload_path / Path("Universal-Binaries")),
|
||||||
"-nobrowse",
|
"-nobrowse",
|
||||||
"-shadow", Path(self.constants.payload_path / Path("Universal-Binaries_overlay")),
|
"-shadow", Path(self.constants.payload_path / Path("Universal-Binaries_overlay")),
|
||||||
@@ -889,7 +890,7 @@ class PatchSysVolume:
|
|||||||
|
|
||||||
result = subprocess.run(
|
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")),
|
"-mountpoint", Path(self.constants.payload_path / Path("DortaniaInternal")),
|
||||||
"-nobrowse",
|
"-nobrowse",
|
||||||
"-passphrase", password
|
"-passphrase", password
|
||||||
@@ -900,7 +901,7 @@ class PatchSysVolume:
|
|||||||
logging.info("- Mounted DortaniaInternal resources")
|
logging.info("- Mounted DortaniaInternal resources")
|
||||||
result = subprocess.run(
|
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
|
stdout=subprocess.PIPE, stderr=subprocess.STDOUT
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -9,13 +9,15 @@ import logging
|
|||||||
import plistlib
|
import plistlib
|
||||||
import subprocess
|
import subprocess
|
||||||
import webbrowser
|
import webbrowser
|
||||||
|
import hashlib
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
from resources import utilities, updates, global_settings, network_handler, constants
|
from resources import utilities, updates, global_settings, network_handler, constants
|
||||||
from resources.sys_patch import sys_patch_detect
|
from resources.sys_patch import sys_patch_detect
|
||||||
from resources.wx_gui import gui_entry
|
from resources.wx_gui import gui_entry, gui_support
|
||||||
|
from data import css_data
|
||||||
|
|
||||||
|
|
||||||
class AutomaticSysPatch:
|
class AutomaticSysPatch:
|
||||||
@@ -62,46 +64,38 @@ class AutomaticSysPatch:
|
|||||||
|
|
||||||
url = "https://api.github.com/repos/dortania/OpenCore-Legacy-Patcher/releases/latest"
|
url = "https://api.github.com/repos/dortania/OpenCore-Legacy-Patcher/releases/latest"
|
||||||
response = requests.get(url).json()
|
response = requests.get(url).json()
|
||||||
changelog = response["body"].split("## Asset Information")[0]
|
try:
|
||||||
|
changelog = response["body"].split("## Asset Information")[0]
|
||||||
|
except: #if user constantly checks for updates, github will rate limit them
|
||||||
|
changelog = """## Unable to fetch changelog
|
||||||
|
|
||||||
html_markdown = markdown2.markdown(changelog)
|
Please check the Github page for more information about this release."""
|
||||||
html_css = """
|
|
||||||
<style>
|
html_markdown = markdown2.markdown(changelog, extras=["tables"])
|
||||||
body {
|
html_css = css_data.updater_css
|
||||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
|
frame = wx.Dialog(None, -1, title="", size=(650, 500))
|
||||||
line-height: 1.5;
|
frame.SetMinSize((650, 500))
|
||||||
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>
|
|
||||||
"""
|
|
||||||
frame = wx.Dialog(None, -1, title="", size=(600, 500))
|
|
||||||
frame.SetMinSize((600, 500))
|
|
||||||
frame.SetWindowStyle(wx.STAY_ON_TOP)
|
frame.SetWindowStyle(wx.STAY_ON_TOP)
|
||||||
panel = wx.Panel(frame)
|
panel = wx.Panel(frame)
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
sizer.AddSpacer(10)
|
sizer.AddSpacer(10)
|
||||||
self.title_text = wx.StaticText(panel, label="A new version of OpenCore Legacy Patcher is available!")
|
self.title_text = wx.StaticText(panel, label="A new version of OpenCore Legacy Patcher is available!")
|
||||||
self.description = wx.StaticText(panel, label=f"OpenCore Legacy Patcher {version} is now available - You have {self.constants.patcher_version}. Would you like to update?")
|
self.description = wx.StaticText(panel, label=f"OpenCore Legacy Patcher {version} is now available - You have {self.constants.patcher_version}{' (Nightly)' if not self.constants.commit_info[0].startswith('refs/tags') else ''}. Would you like to update?")
|
||||||
self.title_text.SetFont(wx.Font(19, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, ".AppleSystemUIFont"))
|
self.title_text.SetFont(gui_support.font_factory(19, wx.FONTWEIGHT_BOLD))
|
||||||
self.description.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont"))
|
self.description.SetFont(gui_support.font_factory(13, wx.FONTWEIGHT_NORMAL))
|
||||||
self.web_view = wx.html2.WebView.New(panel, style=wx.BORDER_SUNKEN)
|
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.SetPage(html_code, "")
|
||||||
self.web_view.Bind(wx.html2.EVT_WEBVIEW_NEWWINDOW, self._onWebviewNav)
|
self.web_view.Bind(wx.html2.EVT_WEBVIEW_NEWWINDOW, self._onWebviewNav)
|
||||||
self.web_view.EnableContextMenu(False)
|
self.web_view.EnableContextMenu(False)
|
||||||
@@ -126,14 +120,14 @@ class AutomaticSysPatch:
|
|||||||
frame.Centre()
|
frame.Centre()
|
||||||
|
|
||||||
result = frame.ShowModal()
|
result = frame.ShowModal()
|
||||||
|
|
||||||
|
|
||||||
if result == ID_GITHUB:
|
if result == ID_GITHUB:
|
||||||
webbrowser.open(dict["Github Link"])
|
webbrowser.open(dict["Github Link"])
|
||||||
elif result == ID_UPDATE:
|
elif result == ID_UPDATE:
|
||||||
gui_entry.EntryPoint(self.constants).start(entry=gui_entry.SupportedEntryPoints.UPDATE_APP)
|
gui_entry.EntryPoint(self.constants).start(entry=gui_entry.SupportedEntryPoints.UPDATE_APP)
|
||||||
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if utilities.check_seal() is True:
|
if utilities.check_seal() is True:
|
||||||
@@ -164,7 +158,7 @@ class AutomaticSysPatch:
|
|||||||
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"""
|
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 = [
|
args = [
|
||||||
"osascript",
|
"/usr/bin/osascript",
|
||||||
"-e",
|
"-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"""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}"',
|
f'with icon POSIX file "{self.constants.app_icon_path}"',
|
||||||
@@ -176,7 +170,7 @@ class AutomaticSysPatch:
|
|||||||
)
|
)
|
||||||
if output.returncode == 0:
|
if output.returncode == 0:
|
||||||
args = [
|
args = [
|
||||||
"osascript",
|
"/usr/bin/osascript",
|
||||||
"-e",
|
"-e",
|
||||||
f'''do shell script "{args_string}"'''
|
f'''do shell script "{args_string}"'''
|
||||||
f' with prompt "OpenCore Legacy Patcher would like to patch your root volume"'
|
f' with prompt "OpenCore Legacy Patcher would like to patch your root volume"'
|
||||||
@@ -232,7 +226,7 @@ class AutomaticSysPatch:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
args = [
|
args = [
|
||||||
"osascript",
|
"/usr/bin/osascript",
|
||||||
"-e",
|
"-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"""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}"',
|
f'with icon POSIX file "{self.constants.app_icon_path}"',
|
||||||
@@ -298,7 +292,7 @@ class AutomaticSysPatch:
|
|||||||
# Check if OpenCore is on a USB drive
|
# 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")
|
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:
|
try:
|
||||||
if disk_info["Ejectable"] is False:
|
if disk_info["Ejectable"] is False:
|
||||||
logging.info("- Boot Disk is not removable, skipping prompt")
|
logging.info("- Boot Disk is not removable, skipping prompt")
|
||||||
@@ -307,7 +301,7 @@ class AutomaticSysPatch:
|
|||||||
logging.info("- Boot Disk is ejectable, prompting user to install to internal")
|
logging.info("- Boot Disk is ejectable, prompting user to install to internal")
|
||||||
|
|
||||||
args = [
|
args = [
|
||||||
"osascript",
|
"/usr/bin/osascript",
|
||||||
"-e",
|
"-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"""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}"',
|
f'with icon POSIX file "{self.constants.app_icon_path}"',
|
||||||
@@ -326,7 +320,7 @@ class AutomaticSysPatch:
|
|||||||
logging.info("- Unable to determine if boot disk is removable, skipping prompt")
|
logging.info("- Unable to determine if boot disk is removable, skipping prompt")
|
||||||
|
|
||||||
|
|
||||||
def install_auto_patcher_launch_agent(self):
|
def install_auto_patcher_launch_agent(self, kdk_caching_needed: bool = False):
|
||||||
"""
|
"""
|
||||||
Install the Auto Patcher Launch Agent
|
Install the Auto Patcher Launch Agent
|
||||||
|
|
||||||
@@ -341,8 +335,34 @@ class AutomaticSysPatch:
|
|||||||
logging.info("- Skipping Auto Patcher Launch Agent, not supported when running from source")
|
logging.info("- Skipping Auto Patcher Launch Agent, not supported when running from source")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
services = {
|
||||||
|
self.constants.auto_patch_launch_agent_path: "/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist",
|
||||||
|
self.constants.update_launch_daemon_path: "/Library/LaunchDaemons/com.dortania.opencore-legacy-patcher.macos-update.plist",
|
||||||
|
**({ self.constants.rsr_monitor_launch_daemon_path: "/Library/LaunchDaemons/com.dortania.opencore-legacy-patcher.rsr-monitor.plist" } if self._create_rsr_monitor_daemon() else {}),
|
||||||
|
**({ self.constants.kdk_launch_daemon_path: "/Library/LaunchDaemons/com.dortania.opencore-legacy-patcher.os-caching.plist" } if kdk_caching_needed is True else {} ),
|
||||||
|
}
|
||||||
|
|
||||||
|
for service in services:
|
||||||
|
name = Path(service).name
|
||||||
|
logging.info(f"- Installing {name}")
|
||||||
|
if Path(services[service]).exists():
|
||||||
|
if hashlib.sha256(open(service, "rb").read()).hexdigest() == hashlib.sha256(open(services[service], "rb").read()).hexdigest():
|
||||||
|
logging.info(f" - {name} checksums match, skipping")
|
||||||
|
continue
|
||||||
|
logging.info(f" - Existing service found, removing")
|
||||||
|
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(["/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))
|
||||||
|
utilities.process_status(utilities.elevated(["chown", "root:wheel", services[service]], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||||
|
|
||||||
if self.constants.launcher_binary.startswith("/Library/Application Support/Dortania/"):
|
if self.constants.launcher_binary.startswith("/Library/Application Support/Dortania/"):
|
||||||
logging.info("- Skipping Auto Patcher Launch Agent, already installed")
|
logging.info("- Skipping Patcher Install, already installed")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Verify our binary isn't located in '/Library/Application Support/Dortania/'
|
# Verify our binary isn't located in '/Library/Application Support/Dortania/'
|
||||||
@@ -351,64 +371,33 @@ class AutomaticSysPatch:
|
|||||||
|
|
||||||
if not Path("Library/Application Support/Dortania").exists():
|
if not Path("Library/Application Support/Dortania").exists():
|
||||||
logging.info("- Creating /Library/Application Support/Dortania/")
|
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/")
|
logging.info("- Copying OpenCore Patcher to /Library/Application Support/Dortania/")
|
||||||
if Path("/Library/Application Support/Dortania/OpenCore-Patcher.app").exists():
|
if Path("/Library/Application Support/Dortania/OpenCore-Patcher.app").exists():
|
||||||
logging.info("- Deleting existing OpenCore-Patcher")
|
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
|
# Strip everything after OpenCore-Patcher.app
|
||||||
path = str(self.constants.launcher_binary).split("/Contents/MacOS/OpenCore-Patcher")[0]
|
path = str(self.constants.launcher_binary).split("/Contents/MacOS/OpenCore-Patcher")[0]
|
||||||
logging.info(f"- Copying {path} to /Library/Application Support/Dortania/")
|
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():
|
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)
|
# 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
|
# We'll want to rename it to OpenCore-Patcher.app
|
||||||
path = path.split("/")[-1]
|
path = path.split("/")[-1]
|
||||||
logging.info(f"- Renaming {path} to OpenCore-Patcher.app")
|
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)
|
||||||
|
|
||||||
# Copy over our launch agent
|
|
||||||
logging.info("- Copying auto-patch.plist Launch Agent to /Library/LaunchAgents/")
|
|
||||||
if Path("/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist").exists():
|
|
||||||
logging.info("- Deleting existing auto-patch.plist")
|
|
||||||
utilities.process_status(utilities.elevated(["rm", "/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
|
||||||
if not Path("/Library/LaunchAgents/").exists():
|
|
||||||
logging.info("- Creating /Library/LaunchAgents/")
|
|
||||||
utilities.process_status(utilities.elevated(["mkdir", "-p", "/Library/LaunchAgents/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
|
||||||
utilities.process_status(utilities.elevated(["cp", self.constants.auto_patch_launch_agent_path, "/Library/LaunchAgents/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
|
||||||
|
|
||||||
# Set the permissions on the com.dortania.opencore-legacy-patcher.auto-patch.plist
|
|
||||||
logging.info("- Setting permissions on auto-patch.plist")
|
|
||||||
utilities.process_status(utilities.elevated(["chmod", "644", "/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
|
||||||
utilities.process_status(utilities.elevated(["chown", "root:wheel", "/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
|
||||||
|
|
||||||
# Copy over our launch daemon
|
|
||||||
if self._create_rsr_monitor_daemon() is True:
|
|
||||||
logging.info("- Copying rsr-monitor.plist Launch Daemon to /Library/LaunchDaemons/")
|
|
||||||
if Path("/Library/LaunchDaemons/com.dortania.opencore-legacy-patcher.rsr-monitor.plist").exists():
|
|
||||||
logging.info("- Deleting existing rsr-monitor.plist")
|
|
||||||
utilities.process_status(utilities.elevated(["rm", "/Library/LaunchDaemons/com.dortania.opencore-legacy-patcher.rsr-monitor.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
|
||||||
if not Path("/Library/LaunchDaemons/").exists():
|
|
||||||
logging.info("- Creating /Library/LaunchDaemons/")
|
|
||||||
utilities.process_status(utilities.elevated(["mkdir", "-p", "/Library/LaunchDaemons/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
|
||||||
utilities.process_status(utilities.elevated(["cp", self.constants.rsr_monitor_launch_daemon_path, "/Library/LaunchDaemons/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
|
||||||
|
|
||||||
# Set the permissions on the com.dortania.opencore-legacy-patcher.rsr-monitor.plist
|
|
||||||
logging.info("- Setting permissions on rsr-monitor.plist")
|
|
||||||
utilities.process_status(utilities.elevated(["chmod", "644", "/Library/LaunchDaemons/com.dortania.opencore-legacy-patcher.rsr-monitor.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
|
||||||
utilities.process_status(utilities.elevated(["chown", "root:wheel", "/Library/LaunchDaemons/com.dortania.opencore-legacy-patcher.rsr-monitor.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
|
||||||
|
|
||||||
# Making app alias
|
# Making app alias
|
||||||
# Simply an easy way for users to notice the app
|
# Simply an easy way for users to notice the app
|
||||||
# If there's already an alias or exiting app, skip
|
# If there's already an alias or exiting app, skip
|
||||||
if not Path("/Applications/OpenCore-Patcher.app").exists():
|
if not Path("/Applications/OpenCore-Patcher.app").exists():
|
||||||
logging.info("- Making app alias")
|
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:
|
def _create_rsr_monitor_daemon(self) -> bool:
|
||||||
@@ -443,7 +432,7 @@ class AutomaticSysPatch:
|
|||||||
# Load the RSRMonitor plist
|
# Load the RSRMonitor plist
|
||||||
rsr_monitor_plist = plistlib.load(open(self.constants.rsr_monitor_launch_daemon_path, "rb"))
|
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]
|
arguments += [f"/Library/Extensions/{kext}" for kext in kexts]
|
||||||
|
|
||||||
# Add the arguments to the RSRMonitor plist
|
# Add the arguments to the RSRMonitor plist
|
||||||
|
|||||||
@@ -20,10 +20,27 @@ class DetectRootPatch:
|
|||||||
Library for querying root volume patches applicable for booted system
|
Library for querying root volume patches applicable for booted system
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, model: str, global_constants: constants.Constants):
|
def __init__(self, model: str, global_constants: constants.Constants,
|
||||||
|
os_major: int = None, os_minor: int = None,
|
||||||
|
os_build: str = None, os_version: str = None
|
||||||
|
) -> None:
|
||||||
|
|
||||||
self.model: str = model
|
self.model: str = model
|
||||||
|
|
||||||
self.constants: constants.Constants = global_constants
|
self.constants: constants.Constants = global_constants
|
||||||
|
if os_major is None:
|
||||||
|
os_major = self.constants.detected_os
|
||||||
|
if os_minor is None:
|
||||||
|
os_minor = self.constants.detected_os_minor
|
||||||
|
if os_build is None:
|
||||||
|
os_build = self.constants.detected_os_build
|
||||||
|
if os_version is None:
|
||||||
|
os_version = self.constants.detected_os_version
|
||||||
|
|
||||||
|
self.os_major: int = os_major
|
||||||
|
self.os_minor: int = os_minor
|
||||||
|
self.os_build: str = os_build
|
||||||
|
self.os_version: str = os_version
|
||||||
|
|
||||||
self.computer = self.constants.computer
|
self.computer = self.constants.computer
|
||||||
|
|
||||||
@@ -89,7 +106,7 @@ class DetectRootPatch:
|
|||||||
if gpu.class_code and gpu.class_code != 0xFFFFFFFF:
|
if gpu.class_code and gpu.class_code != 0xFFFFFFFF:
|
||||||
logging.info(f"Found GPU ({i}): {utilities.friendly_hex(gpu.vendor_id)}:{utilities.friendly_hex(gpu.device_id)}")
|
logging.info(f"Found GPU ({i}): {utilities.friendly_hex(gpu.vendor_id)}:{utilities.friendly_hex(gpu.device_id)}")
|
||||||
if gpu.arch in [device_probe.NVIDIA.Archs.Tesla] and self.constants.force_nv_web is False:
|
if gpu.arch in [device_probe.NVIDIA.Archs.Tesla] and self.constants.force_nv_web is False:
|
||||||
if self.constants.detected_os > non_metal_os:
|
if self.os_major > non_metal_os:
|
||||||
self.nvidia_tesla = True
|
self.nvidia_tesla = True
|
||||||
self.amfi_must_disable = True
|
self.amfi_must_disable = True
|
||||||
if os_data.os_data.ventura in self.constants.legacy_accel_support:
|
if os_data.os_data.ventura in self.constants.legacy_accel_support:
|
||||||
@@ -97,24 +114,24 @@ class DetectRootPatch:
|
|||||||
self.legacy_keyboard_backlight = self._check_legacy_keyboard_backlight()
|
self.legacy_keyboard_backlight = self._check_legacy_keyboard_backlight()
|
||||||
self.requires_root_kc = True
|
self.requires_root_kc = True
|
||||||
elif gpu.arch == device_probe.NVIDIA.Archs.Kepler and self.constants.force_nv_web is False:
|
elif gpu.arch == device_probe.NVIDIA.Archs.Kepler and self.constants.force_nv_web is False:
|
||||||
if self.constants.detected_os > os_data.os_data.big_sur:
|
if self.os_major > os_data.os_data.big_sur:
|
||||||
# Kepler drivers were dropped with Beta 7
|
# Kepler drivers were dropped with Beta 7
|
||||||
# 12.0 Beta 5: 21.0.0 - 21A5304g
|
# 12.0 Beta 5: 21.0.0 - 21A5304g
|
||||||
# 12.0 Beta 6: 21.1.0 - 21A5506j
|
# 12.0 Beta 6: 21.1.0 - 21A5506j
|
||||||
# 12.0 Beta 7: 21.1.0 - 21A5522h
|
# 12.0 Beta 7: 21.1.0 - 21A5522h
|
||||||
if (
|
if (
|
||||||
self.constants.detected_os >= os_data.os_data.ventura or
|
self.os_major >= os_data.os_data.ventura or
|
||||||
(
|
(
|
||||||
"21A5506j" not in self.constants.detected_os_build and
|
"21A5506j" not in self.os_build and
|
||||||
self.constants.detected_os == os_data.os_data.monterey and
|
self.os_major == os_data.os_data.monterey and
|
||||||
self.constants.detected_os_minor > 0
|
self.os_minor > 0
|
||||||
)
|
)
|
||||||
):
|
):
|
||||||
self.kepler_gpu = True
|
self.kepler_gpu = True
|
||||||
self.supports_metal = True
|
self.supports_metal = True
|
||||||
if self.constants.detected_os >= os_data.os_data.ventura:
|
if self.os_major >= os_data.os_data.ventura:
|
||||||
self.amfi_must_disable = True
|
self.amfi_must_disable = True
|
||||||
if (self.constants.detected_os == os_data.os_data.ventura and self.constants.detected_os_minor >= 4) or self.constants.detected_os > os_data.os_data.ventura:
|
if (self.os_major == os_data.os_data.ventura and self.os_minor >= 4) or self.os_major > os_data.os_data.ventura:
|
||||||
self.amfi_shim_bins = True
|
self.amfi_shim_bins = True
|
||||||
elif gpu.arch in [
|
elif gpu.arch in [
|
||||||
device_probe.NVIDIA.Archs.Fermi,
|
device_probe.NVIDIA.Archs.Fermi,
|
||||||
@@ -122,7 +139,7 @@ class DetectRootPatch:
|
|||||||
device_probe.NVIDIA.Archs.Maxwell,
|
device_probe.NVIDIA.Archs.Maxwell,
|
||||||
device_probe.NVIDIA.Archs.Pascal,
|
device_probe.NVIDIA.Archs.Pascal,
|
||||||
]:
|
]:
|
||||||
if self.constants.detected_os > os_data.os_data.mojave:
|
if self.os_major > os_data.os_data.mojave:
|
||||||
self.nvidia_web = True
|
self.nvidia_web = True
|
||||||
self.amfi_must_disable = True
|
self.amfi_must_disable = True
|
||||||
if os_data.os_data.ventura in self.constants.legacy_accel_support:
|
if os_data.os_data.ventura in self.constants.legacy_accel_support:
|
||||||
@@ -130,14 +147,14 @@ class DetectRootPatch:
|
|||||||
self.needs_nv_web_checks = True
|
self.needs_nv_web_checks = True
|
||||||
self.requires_root_kc = True
|
self.requires_root_kc = True
|
||||||
elif gpu.arch == device_probe.AMD.Archs.TeraScale_1:
|
elif gpu.arch == device_probe.AMD.Archs.TeraScale_1:
|
||||||
if self.constants.detected_os > non_metal_os:
|
if self.os_major > non_metal_os:
|
||||||
self.amd_ts1 = True
|
self.amd_ts1 = True
|
||||||
self.amfi_must_disable = True
|
self.amfi_must_disable = True
|
||||||
if os_data.os_data.ventura in self.constants.legacy_accel_support:
|
if os_data.os_data.ventura in self.constants.legacy_accel_support:
|
||||||
self.amfi_shim_bins = True
|
self.amfi_shim_bins = True
|
||||||
self.requires_root_kc = True
|
self.requires_root_kc = True
|
||||||
elif gpu.arch == device_probe.AMD.Archs.TeraScale_2:
|
elif gpu.arch == device_probe.AMD.Archs.TeraScale_2:
|
||||||
if self.constants.detected_os > non_metal_os:
|
if self.os_major > non_metal_os:
|
||||||
self.amd_ts2 = True
|
self.amd_ts2 = True
|
||||||
self.amfi_must_disable = True
|
self.amfi_must_disable = True
|
||||||
if os_data.os_data.ventura in self.constants.legacy_accel_support:
|
if os_data.os_data.ventura in self.constants.legacy_accel_support:
|
||||||
@@ -149,7 +166,7 @@ class DetectRootPatch:
|
|||||||
device_probe.AMD.Archs.Legacy_GCN_9000,
|
device_probe.AMD.Archs.Legacy_GCN_9000,
|
||||||
device_probe.AMD.Archs.Polaris,
|
device_probe.AMD.Archs.Polaris,
|
||||||
]:
|
]:
|
||||||
if self.constants.detected_os > os_data.os_data.monterey:
|
if self.os_major > os_data.os_data.monterey:
|
||||||
if self.constants.computer.rosetta_active is True:
|
if self.constants.computer.rosetta_active is True:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -171,7 +188,7 @@ class DetectRootPatch:
|
|||||||
if self.model == "MacBookPro13,3":
|
if self.model == "MacBookPro13,3":
|
||||||
self.legacy_gcn = True
|
self.legacy_gcn = True
|
||||||
elif self.model == "MacBookPro14,3":
|
elif self.model == "MacBookPro14,3":
|
||||||
if self.constants.detected_os < os_data.os_data.sonoma:
|
if self.os_major < os_data.os_data.sonoma:
|
||||||
continue
|
continue
|
||||||
self.legacy_gcn_v2 = True
|
self.legacy_gcn_v2 = True
|
||||||
else:
|
else:
|
||||||
@@ -180,7 +197,7 @@ class DetectRootPatch:
|
|||||||
self.requires_root_kc = True
|
self.requires_root_kc = True
|
||||||
self.amfi_must_disable = True
|
self.amfi_must_disable = True
|
||||||
elif gpu.arch == device_probe.AMD.Archs.Vega:
|
elif gpu.arch == device_probe.AMD.Archs.Vega:
|
||||||
if self.constants.detected_os > os_data.os_data.monterey:
|
if self.os_major > os_data.os_data.monterey:
|
||||||
if "AVX2" in self.constants.computer.cpu.leafs:
|
if "AVX2" in self.constants.computer.cpu.leafs:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -189,7 +206,7 @@ class DetectRootPatch:
|
|||||||
self.requires_root_kc = True
|
self.requires_root_kc = True
|
||||||
self.amfi_must_disable = True
|
self.amfi_must_disable = True
|
||||||
elif gpu.arch == device_probe.Intel.Archs.Iron_Lake:
|
elif gpu.arch == device_probe.Intel.Archs.Iron_Lake:
|
||||||
if self.constants.detected_os > non_metal_os:
|
if self.os_major > non_metal_os:
|
||||||
self.iron_gpu = True
|
self.iron_gpu = True
|
||||||
self.amfi_must_disable = True
|
self.amfi_must_disable = True
|
||||||
if os_data.os_data.ventura in self.constants.legacy_accel_support:
|
if os_data.os_data.ventura in self.constants.legacy_accel_support:
|
||||||
@@ -197,7 +214,7 @@ class DetectRootPatch:
|
|||||||
self.legacy_keyboard_backlight = self._check_legacy_keyboard_backlight()
|
self.legacy_keyboard_backlight = self._check_legacy_keyboard_backlight()
|
||||||
self.requires_root_kc = True
|
self.requires_root_kc = True
|
||||||
elif gpu.arch == device_probe.Intel.Archs.Sandy_Bridge:
|
elif gpu.arch == device_probe.Intel.Archs.Sandy_Bridge:
|
||||||
if self.constants.detected_os > non_metal_os:
|
if self.os_major > non_metal_os:
|
||||||
self.sandy_gpu = True
|
self.sandy_gpu = True
|
||||||
self.amfi_must_disable = True
|
self.amfi_must_disable = True
|
||||||
if os_data.os_data.ventura in self.constants.legacy_accel_support:
|
if os_data.os_data.ventura in self.constants.legacy_accel_support:
|
||||||
@@ -205,33 +222,31 @@ class DetectRootPatch:
|
|||||||
self.legacy_keyboard_backlight = self._check_legacy_keyboard_backlight()
|
self.legacy_keyboard_backlight = self._check_legacy_keyboard_backlight()
|
||||||
self.requires_root_kc = True
|
self.requires_root_kc = True
|
||||||
elif gpu.arch == device_probe.Intel.Archs.Ivy_Bridge:
|
elif gpu.arch == device_probe.Intel.Archs.Ivy_Bridge:
|
||||||
if self.constants.detected_os > os_data.os_data.big_sur:
|
if self.os_major > os_data.os_data.big_sur:
|
||||||
self.ivy_gpu = True
|
self.ivy_gpu = True
|
||||||
if self.constants.detected_os >= os_data.os_data.ventura:
|
if self.os_major >= os_data.os_data.ventura:
|
||||||
self.amfi_must_disable = True
|
self.amfi_must_disable = True
|
||||||
if (self.constants.detected_os == os_data.os_data.ventura and self.constants.detected_os_minor >= 4) or self.constants.detected_os > os_data.os_data.ventura:
|
if (self.os_major == os_data.os_data.ventura and self.os_minor >= 4) or self.os_major > os_data.os_data.ventura:
|
||||||
self.amfi_shim_bins = True
|
self.amfi_shim_bins = True
|
||||||
self.supports_metal = True
|
self.supports_metal = True
|
||||||
elif gpu.arch == device_probe.Intel.Archs.Haswell:
|
elif gpu.arch == device_probe.Intel.Archs.Haswell:
|
||||||
if self.constants.detected_os > os_data.os_data.monterey:
|
if self.os_major > os_data.os_data.monterey:
|
||||||
self.haswell_gpu = True
|
self.haswell_gpu = True
|
||||||
self.amfi_must_disable = True
|
self.amfi_must_disable = True
|
||||||
if (self.constants.detected_os == os_data.os_data.ventura and self.constants.detected_os_minor >= 4) or self.constants.detected_os > os_data.os_data.ventura:
|
if (self.os_major == os_data.os_data.ventura and self.os_minor >= 4) or self.os_major > os_data.os_data.ventura:
|
||||||
self.amfi_shim_bins = True
|
self.amfi_shim_bins = True
|
||||||
self.supports_metal = True
|
self.supports_metal = True
|
||||||
elif gpu.arch == device_probe.Intel.Archs.Broadwell:
|
elif gpu.arch == device_probe.Intel.Archs.Broadwell:
|
||||||
if self.constants.detected_os > os_data.os_data.monterey:
|
if self.os_major > os_data.os_data.monterey:
|
||||||
self.broadwell_gpu = True
|
self.broadwell_gpu = True
|
||||||
self.amfi_must_disable = True
|
self.amfi_must_disable = True
|
||||||
self.supports_metal = True
|
self.supports_metal = True
|
||||||
elif gpu.arch == device_probe.Intel.Archs.Skylake:
|
elif gpu.arch == device_probe.Intel.Archs.Skylake:
|
||||||
if self.constants.detected_os > os_data.os_data.monterey:
|
if self.os_major > os_data.os_data.monterey:
|
||||||
self.skylake_gpu = True
|
self.skylake_gpu = True
|
||||||
self.amfi_must_disable = True
|
self.amfi_must_disable = True
|
||||||
self.supports_metal = True
|
self.supports_metal = True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if self.supports_metal is True:
|
if self.supports_metal is True:
|
||||||
# Avoid patching Metal and non-Metal GPUs if both present, prioritize Metal GPU
|
# Avoid patching Metal and non-Metal GPUs if both present, prioritize Metal GPU
|
||||||
# Main concerns are for iMac12,x with Sandy iGPU and Kepler dGPU
|
# Main concerns are for iMac12,x with Sandy iGPU and Kepler dGPU
|
||||||
@@ -251,7 +266,7 @@ class DetectRootPatch:
|
|||||||
self.legacy_polaris = False
|
self.legacy_polaris = False
|
||||||
self.legacy_vega = False
|
self.legacy_vega = False
|
||||||
|
|
||||||
if self.constants.detected_os <= os_data.os_data.monterey:
|
if self.os_major <= os_data.os_data.monterey:
|
||||||
# Always assume Root KC requirement on Monterey and older
|
# Always assume Root KC requirement on Monterey and older
|
||||||
self.requires_root_kc = True
|
self.requires_root_kc = True
|
||||||
else:
|
else:
|
||||||
@@ -272,7 +287,7 @@ class DetectRootPatch:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Increase OS check if modern wifi is detected
|
# Increase OS check if modern wifi is detected
|
||||||
if self.constants.detected_os < (os_data.os_data.ventura if self.legacy_wifi is True else os_data.os_data.sonoma):
|
if self.os_major < (os_data.os_data.ventura if self.legacy_wifi is True else os_data.os_data.sonoma):
|
||||||
return
|
return
|
||||||
if self.legacy_wifi is False and self.modern_wifi is False:
|
if self.legacy_wifi is False and self.modern_wifi is False:
|
||||||
return
|
return
|
||||||
@@ -313,7 +328,7 @@ class DetectRootPatch:
|
|||||||
self.legacy_keyboard_backlight = False
|
self.legacy_keyboard_backlight = False
|
||||||
|
|
||||||
# Currently all graphics patches require a KDK
|
# Currently all graphics patches require a KDK
|
||||||
if self.constants.detected_os >= os_data.os_data.sonoma:
|
if self.os_major >= os_data.os_data.sonoma:
|
||||||
self.kepler_gpu = False
|
self.kepler_gpu = False
|
||||||
self.ivy_gpu = False
|
self.ivy_gpu = False
|
||||||
self.haswell_gpu = False
|
self.haswell_gpu = False
|
||||||
@@ -442,7 +457,7 @@ class DetectRootPatch:
|
|||||||
"""
|
"""
|
||||||
min_os = os_data.os_data.big_sur
|
min_os = os_data.os_data.big_sur
|
||||||
max_os = os_data.os_data.sonoma
|
max_os = os_data.os_data.sonoma
|
||||||
if self.constants.detected_os < min_os or self.constants.detected_os > max_os:
|
if self.os_major < min_os or self.os_major > max_os:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -455,7 +470,7 @@ class DetectRootPatch:
|
|||||||
bool: True if installed, False otherwise
|
bool: True if installed, False otherwise
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return kdk_handler.KernelDebugKitObject(self.constants, self.constants.detected_os_build, self.constants.detected_os_version, passive=True).kdk_already_installed
|
return kdk_handler.KernelDebugKitObject(self.constants, self.os_build, self.os_version, passive=True).kdk_already_installed
|
||||||
|
|
||||||
|
|
||||||
def _check_sip(self):
|
def _check_sip(self):
|
||||||
@@ -466,14 +481,14 @@ class DetectRootPatch:
|
|||||||
tuple: (list, str, str) of SIP values, SIP hex, SIP error message
|
tuple: (list, str, str) of SIP values, SIP hex, SIP error message
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.constants.detected_os > os_data.os_data.catalina:
|
if self.os_major > os_data.os_data.catalina:
|
||||||
if self.nvidia_web is True:
|
if self.nvidia_web is True:
|
||||||
sip = sip_data.system_integrity_protection.root_patch_sip_big_sur_3rd_part_kexts
|
sip = sip_data.system_integrity_protection.root_patch_sip_big_sur_3rd_part_kexts
|
||||||
sip_hex = "0xA03"
|
sip_hex = "0xA03"
|
||||||
sip_value = (
|
sip_value = (
|
||||||
f"For Hackintoshes, please set csr-active-config to '030A0000' ({sip_hex})\nFor non-OpenCore Macs, please run 'csrutil disable' and \n'csrutil authenticated-root disable' in RecoveryOS"
|
f"For Hackintoshes, please set csr-active-config to '030A0000' ({sip_hex})\nFor non-OpenCore Macs, please run 'csrutil disable' and \n'csrutil authenticated-root disable' in RecoveryOS"
|
||||||
)
|
)
|
||||||
elif self.constants.detected_os >= os_data.os_data.ventura:
|
elif self.os_major >= os_data.os_data.ventura:
|
||||||
sip = sip_data.system_integrity_protection.root_patch_sip_ventura
|
sip = sip_data.system_integrity_protection.root_patch_sip_ventura
|
||||||
sip_hex = "0x803"
|
sip_hex = "0x803"
|
||||||
sip_value = (
|
sip_value = (
|
||||||
@@ -500,7 +515,7 @@ class DetectRootPatch:
|
|||||||
bool: True if UHCI/OHCI patches required, False otherwise
|
bool: True if UHCI/OHCI patches required, False otherwise
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.constants.detected_os < os_data.os_data.ventura:
|
if self.os_major < os_data.os_data.ventura:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# If we're on a hackintosh, check for UHCI/OHCI controllers
|
# If we're on a hackintosh, check for UHCI/OHCI controllers
|
||||||
@@ -539,7 +554,7 @@ class DetectRootPatch:
|
|||||||
|
|
||||||
self.has_network = network_handler.NetworkUtilities().verify_network_connection()
|
self.has_network = network_handler.NetworkUtilities().verify_network_connection()
|
||||||
|
|
||||||
if self.constants.detected_os >= os_data.os_data.sonoma:
|
if self.os_major >= os_data.os_data.sonoma:
|
||||||
self.legacy_pcie_webcam = self.constants.computer.pcie_webcam
|
self.legacy_pcie_webcam = self.constants.computer.pcie_webcam
|
||||||
self.legacy_t1_chip = self.constants.computer.t1_chip
|
self.legacy_t1_chip = self.constants.computer.t1_chip
|
||||||
|
|
||||||
@@ -551,25 +566,25 @@ class DetectRootPatch:
|
|||||||
self.requires_root_kc = True
|
self.requires_root_kc = True
|
||||||
|
|
||||||
if self.model in model_array.LegacyBrightness:
|
if self.model in model_array.LegacyBrightness:
|
||||||
if self.constants.detected_os > os_data.os_data.catalina:
|
if self.os_major > os_data.os_data.catalina:
|
||||||
self.brightness_legacy = True
|
self.brightness_legacy = True
|
||||||
|
|
||||||
if self.model in ["iMac7,1", "iMac8,1"] or (self.model in model_array.LegacyAudio and utilities.check_kext_loaded("as.vit9696.AppleALC") is False):
|
if self.model in ["iMac7,1", "iMac8,1"] or (self.model in model_array.LegacyAudio and utilities.check_kext_loaded("as.vit9696.AppleALC") is False):
|
||||||
# Special hack for systems with botched GOPs
|
# Special hack for systems with botched GOPs
|
||||||
# TL;DR: No Boot Screen breaks Lilu, therefore breaking audio
|
# TL;DR: No Boot Screen breaks Lilu, therefore breaking audio
|
||||||
if self.constants.detected_os > os_data.os_data.catalina:
|
if self.os_major > os_data.os_data.catalina:
|
||||||
self.legacy_audio = True
|
self.legacy_audio = True
|
||||||
|
|
||||||
if (
|
if (
|
||||||
isinstance(self.constants.computer.wifi, device_probe.Broadcom)
|
isinstance(self.constants.computer.wifi, device_probe.Broadcom)
|
||||||
and self.constants.computer.wifi.chipset in [device_probe.Broadcom.Chipsets.AirPortBrcm4331, device_probe.Broadcom.Chipsets.AirPortBrcm43224]
|
and self.constants.computer.wifi.chipset in [device_probe.Broadcom.Chipsets.AirPortBrcm4331, device_probe.Broadcom.Chipsets.AirPortBrcm43224]
|
||||||
) or (isinstance(self.constants.computer.wifi, device_probe.Atheros) and self.constants.computer.wifi.chipset == device_probe.Atheros.Chipsets.AirPortAtheros40):
|
) or (isinstance(self.constants.computer.wifi, device_probe.Atheros) and self.constants.computer.wifi.chipset == device_probe.Atheros.Chipsets.AirPortAtheros40):
|
||||||
if self.constants.detected_os > os_data.os_data.big_sur:
|
if self.os_major > os_data.os_data.big_sur:
|
||||||
self.legacy_wifi = True
|
self.legacy_wifi = True
|
||||||
if self.constants.detected_os >= os_data.os_data.ventura:
|
if self.os_major >= os_data.os_data.ventura:
|
||||||
# Due to extracted frameworks for IO80211.framework and co, check library validation
|
# Due to extracted frameworks for IO80211.framework and co, check library validation
|
||||||
self.amfi_must_disable = True
|
self.amfi_must_disable = True
|
||||||
if self.constants.detected_os > os_data.os_data.ventura:
|
if self.os_major > os_data.os_data.ventura:
|
||||||
self.amfi_shim_bins = True
|
self.amfi_shim_bins = True
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -580,7 +595,7 @@ class DetectRootPatch:
|
|||||||
# We don't officially support this chipset, however we'll throw a bone to hackintosh users
|
# We don't officially support this chipset, however we'll throw a bone to hackintosh users
|
||||||
device_probe.Broadcom.Chipsets.AirPortBrcmNICThirdParty,
|
device_probe.Broadcom.Chipsets.AirPortBrcmNICThirdParty,
|
||||||
]):
|
]):
|
||||||
if self.constants.detected_os > os_data.os_data.ventura:
|
if self.os_major > os_data.os_data.ventura:
|
||||||
self.modern_wifi = True
|
self.modern_wifi = True
|
||||||
self.amfi_shim_bins = True
|
self.amfi_shim_bins = True
|
||||||
|
|
||||||
@@ -590,7 +605,7 @@ class DetectRootPatch:
|
|||||||
# Same method is also used for demuxed machines
|
# Same method is also used for demuxed machines
|
||||||
# Note that MacBookPro5,x machines are extremely unstable with this patch set, so disabled until investigated further
|
# Note that MacBookPro5,x machines are extremely unstable with this patch set, so disabled until investigated further
|
||||||
# Ref: https://github.com/dortania/OpenCore-Legacy-Patcher/files/7360909/KP-b10-030.txt
|
# Ref: https://github.com/dortania/OpenCore-Legacy-Patcher/files/7360909/KP-b10-030.txt
|
||||||
if self.constants.detected_os > os_data.os_data.high_sierra:
|
if self.os_major > os_data.os_data.high_sierra:
|
||||||
if self.model in ["MacBookPro8,2", "MacBookPro8,3"]:
|
if self.model in ["MacBookPro8,2", "MacBookPro8,3"]:
|
||||||
# Ref: https://doslabelectronics.com/Demux.html
|
# Ref: https://doslabelectronics.com/Demux.html
|
||||||
if self._detect_demux() is True:
|
if self._detect_demux() is True:
|
||||||
@@ -630,7 +645,7 @@ class DetectRootPatch:
|
|||||||
"Miscellaneous: T1 Security Chip": self.legacy_t1_chip,
|
"Miscellaneous: T1 Security Chip": self.legacy_t1_chip,
|
||||||
"Settings: Requires AMFI exemption": self.amfi_must_disable,
|
"Settings: Requires AMFI exemption": self.amfi_must_disable,
|
||||||
"Settings: Supports Auxiliary Cache": not self.requires_root_kc,
|
"Settings: Supports Auxiliary Cache": not self.requires_root_kc,
|
||||||
"Settings: Kernel Debug Kit missing": self.missing_kdk if self.constants.detected_os >= os_data.os_data.ventura.value else False,
|
"Settings: Kernel Debug Kit missing": self.missing_kdk if self.os_major >= os_data.os_data.ventura.value else False,
|
||||||
"Validation: Patching Possible": self.verify_patch_allowed(),
|
"Validation: Patching Possible": self.verify_patch_allowed(),
|
||||||
"Validation: Unpatching Possible": self._verify_unpatch_allowed(),
|
"Validation: Unpatching Possible": self._verify_unpatch_allowed(),
|
||||||
f"Validation: Unsupported Host OS": self.unsupported_os,
|
f"Validation: Unsupported Host OS": self.unsupported_os,
|
||||||
@@ -644,7 +659,7 @@ class DetectRootPatch:
|
|||||||
"Validation: Force OpenGL property missing": self.missing_nv_web_opengl if self.nvidia_web is True else False,
|
"Validation: Force OpenGL property missing": self.missing_nv_web_opengl if self.nvidia_web is True else False,
|
||||||
"Validation: Force compat property missing": self.missing_nv_compat if self.nvidia_web is True else False,
|
"Validation: Force compat property missing": self.missing_nv_compat if self.nvidia_web is True else False,
|
||||||
"Validation: nvda_drv(_vrl) variable missing": self.missing_nv_web_nvram if self.nvidia_web is True else False,
|
"Validation: nvda_drv(_vrl) variable missing": self.missing_nv_web_nvram if self.nvidia_web is True else False,
|
||||||
"Validation: Network Connection Required": (not self.has_network) if (self.requires_root_kc and self.missing_kdk and self.constants.detected_os >= os_data.os_data.ventura.value) else False,
|
"Validation: Network Connection Required": (not self.has_network) if (self.requires_root_kc and self.missing_kdk and self.os_major >= os_data.os_data.ventura.value) else False,
|
||||||
}
|
}
|
||||||
|
|
||||||
return self.root_patch_dict
|
return self.root_patch_dict
|
||||||
@@ -661,7 +676,7 @@ class DetectRootPatch:
|
|||||||
if self.amfi_must_disable is False:
|
if self.amfi_must_disable is False:
|
||||||
return amfi_detect.AmfiConfigDetectLevel.NO_CHECK
|
return amfi_detect.AmfiConfigDetectLevel.NO_CHECK
|
||||||
|
|
||||||
if self.constants.detected_os < os_data.os_data.big_sur:
|
if self.os_major < os_data.os_data.big_sur:
|
||||||
return amfi_detect.AmfiConfigDetectLevel.NO_CHECK
|
return amfi_detect.AmfiConfigDetectLevel.NO_CHECK
|
||||||
|
|
||||||
amfipass_version = utilities.check_kext_loaded("com.dhinakg.AMFIPass")
|
amfipass_version = utilities.check_kext_loaded("com.dhinakg.AMFIPass")
|
||||||
@@ -670,7 +685,7 @@ class DetectRootPatch:
|
|||||||
# If AMFIPass is loaded, our binaries will work
|
# If AMFIPass is loaded, our binaries will work
|
||||||
return amfi_detect.AmfiConfigDetectLevel.NO_CHECK
|
return amfi_detect.AmfiConfigDetectLevel.NO_CHECK
|
||||||
|
|
||||||
if self.constants.detected_os >= os_data.os_data.ventura:
|
if self.os_major >= os_data.os_data.ventura:
|
||||||
if self.amfi_shim_bins is True:
|
if self.amfi_shim_bins is True:
|
||||||
# Currently we require AMFI outright disabled
|
# Currently we require AMFI outright disabled
|
||||||
# in Ventura to work with shim'd binaries
|
# in Ventura to work with shim'd binaries
|
||||||
@@ -694,7 +709,7 @@ class DetectRootPatch:
|
|||||||
sip = sip_dict[0]
|
sip = sip_dict[0]
|
||||||
sip_value = sip_dict[1]
|
sip_value = sip_dict[1]
|
||||||
|
|
||||||
self.sip_enabled, self.sbm_enabled, self.fv_enabled, self.dosdude_patched = utilities.patching_status(sip, self.constants.detected_os)
|
self.sip_enabled, self.sbm_enabled, self.fv_enabled, self.dosdude_patched = utilities.patching_status(sip, self.os_major)
|
||||||
self.amfi_enabled = not amfi_detect.AmfiConfigurationDetection().check_config(self._get_amfi_level_needed())
|
self.amfi_enabled = not amfi_detect.AmfiConfigurationDetection().check_config(self._get_amfi_level_needed())
|
||||||
|
|
||||||
self.unsupported_os = not self._check_os_compat()
|
self.unsupported_os = not self._check_os_compat()
|
||||||
@@ -748,7 +763,7 @@ class DetectRootPatch:
|
|||||||
logging.info("\nCannot patch! WhateverGreen.kext missing")
|
logging.info("\nCannot patch! WhateverGreen.kext missing")
|
||||||
logging.info("Please ensure WhateverGreen.kext is installed")
|
logging.info("Please ensure WhateverGreen.kext is installed")
|
||||||
|
|
||||||
if (not self.has_network) if (self.requires_root_kc and self.missing_kdk and self.constants.detected_os >= os_data.os_data.ventura.value) else False:
|
if (not self.has_network) if (self.requires_root_kc and self.missing_kdk and self.os_major >= os_data.os_data.ventura.value) else False:
|
||||||
logging.info("\nCannot patch! Network Connection Required")
|
logging.info("\nCannot patch! Network Connection Required")
|
||||||
logging.info("Please ensure you have an active internet connection")
|
logging.info("Please ensure you have an active internet connection")
|
||||||
|
|
||||||
@@ -771,7 +786,7 @@ class DetectRootPatch:
|
|||||||
self.missing_whatever_green if self.nvidia_web is True else False,
|
self.missing_whatever_green if self.nvidia_web is True else False,
|
||||||
|
|
||||||
# KDK specific
|
# KDK specific
|
||||||
(not self.has_network) if (self.requires_root_kc and self.missing_kdk and self.constants.detected_os >= os_data.os_data.ventura.value) else False
|
(not self.has_network) if (self.requires_root_kc and self.missing_kdk and self.os_major >= os_data.os_data.ventura.value) else False
|
||||||
]
|
]
|
||||||
):
|
):
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class GenerateRootPatchSets:
|
|||||||
dict: Dictionary of patches to be applied from sys_patch_dict.py
|
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 = {}
|
required_patches: dict = {}
|
||||||
|
|
||||||
utilities.cls()
|
utilities.cls()
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ class SysPatchHelpers:
|
|||||||
if did_find:
|
if did_find:
|
||||||
with open(file_path, "wb") as f:
|
with open(file_path, "wb") as f:
|
||||||
plistlib.dump(data, f, sort_keys=False)
|
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):
|
def install_rsr_repair_binary(self):
|
||||||
@@ -235,23 +235,30 @@ class SysPatchHelpers:
|
|||||||
- lib (entire directory)
|
- lib (entire directory)
|
||||||
|
|
||||||
Note: With macOS Sonoma, 32023 compiler is used instead and so this patch is not needed
|
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:
|
Parameters:
|
||||||
mount_point: The mount point of the target volume
|
mount_point: The mount point of the target volume
|
||||||
"""
|
"""
|
||||||
|
if os_data.os_data.sonoma < self.constants.detected_os < os_data.os_data.ventura:
|
||||||
if self.constants.detected_os != os_data.os_data.ventura:
|
|
||||||
return
|
|
||||||
if self.constants.detected_os_minor < 4:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
LIBRARY_DIR = f"{mount_point}/System/Library/PrivateFrameworks/GPUCompiler.framework/Versions/31001/Libraries/lib/clang"
|
if self.constants.detected_os == os_data.os_data.ventura:
|
||||||
GPU_VERSION = "31001.669"
|
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}"
|
DEST_DIR = f"{LIBRARY_DIR}/{GPU_VERSION}"
|
||||||
|
|
||||||
if not Path(DEST_DIR).exists():
|
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():
|
for file in Path(LIBRARY_DIR).iterdir():
|
||||||
if file.is_file():
|
if file.is_file():
|
||||||
@@ -260,13 +267,13 @@ class SysPatchHelpers:
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# Partial match as each OS can increment the version
|
# Partial match as each OS can increment the version
|
||||||
if not file.name.startswith("31001."):
|
if not file.name.startswith(f"{BASE_VERSION}."):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
logging.info(f"Merging GPUCompiler.framework libraries to match binary")
|
logging.info(f"Merging GPUCompiler.framework libraries to match binary")
|
||||||
|
|
||||||
src_dir = f"{LIBRARY_DIR}/{file.name}"
|
src_dir = f"{LIBRARY_DIR}/{file.name}"
|
||||||
if not Path(f"{DEST_DIR}/lib").exists():
|
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
|
break
|
||||||
@@ -108,13 +108,14 @@ def check_recovery():
|
|||||||
|
|
||||||
|
|
||||||
def get_disk_path():
|
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_partition_info["DeviceIdentifier"]
|
||||||
root_mount_path = root_mount_path[:-2] if root_mount_path.count("s") > 1 else root_mount_path
|
root_mount_path = root_mount_path[:-2] if root_mount_path.count("s") > 1 else root_mount_path
|
||||||
return root_mount_path
|
return root_mount_path
|
||||||
|
|
||||||
|
|
||||||
def check_if_root_is_apfs_snapshot():
|
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:
|
try:
|
||||||
is_snapshotted = root_partition_info["APFSSnapshot"]
|
is_snapshotted = root_partition_info["APFSSnapshot"]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
@@ -124,7 +125,7 @@ def check_if_root_is_apfs_snapshot():
|
|||||||
|
|
||||||
def check_seal():
|
def check_seal():
|
||||||
# 'Snapshot Sealed' property is only listed on booted snapshots
|
# '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():
|
if "Snapshot Sealed: Yes" in sealed.stdout.decode():
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
@@ -132,7 +133,7 @@ def check_seal():
|
|||||||
|
|
||||||
def check_filesystem_type():
|
def check_filesystem_type():
|
||||||
# Expected to return 'apfs' or 'hfs'
|
# 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"]
|
return filesystem_type["FilesystemType"]
|
||||||
|
|
||||||
|
|
||||||
@@ -186,10 +187,10 @@ def check_kext_loaded(bundle_id: str) -> str:
|
|||||||
# no UUID for kextstat
|
# no UUID for kextstat
|
||||||
pattern = re.compile(re.escape(bundle_id) + r"\s+\((?P<version>.+)\)")
|
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():
|
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)
|
kext_loaded = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||||
if kext_loaded.returncode != 0:
|
if kext_loaded.returncode != 0:
|
||||||
@@ -213,7 +214,7 @@ def check_oclp_boot():
|
|||||||
def check_monterey_wifi():
|
def check_monterey_wifi():
|
||||||
IO80211ElCap = "com.apple.iokit.IO80211ElCap"
|
IO80211ElCap = "com.apple.iokit.IO80211ElCap"
|
||||||
CoreCaptureElCap = "com.apple.driver.corecaptureElCap"
|
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:
|
if IO80211ElCap in loaded_kexts and CoreCaptureElCap in loaded_kexts:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
@@ -307,7 +308,7 @@ def patching_status(os_sip, os):
|
|||||||
|
|
||||||
if os > os_data.os_data.catalina and not check_filevault_skip():
|
if os > os_data.os_data.catalina and not check_filevault_skip():
|
||||||
# Assume non-OCLP Macs do not have our APFS seal patch
|
# 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:
|
if "FileVault is Off" in fv_status:
|
||||||
fv_enabled = False
|
fv_enabled = False
|
||||||
else:
|
else:
|
||||||
@@ -340,8 +341,7 @@ def cls():
|
|||||||
|
|
||||||
def check_command_line_tools():
|
def check_command_line_tools():
|
||||||
# Determine whether Command Line Tools exist
|
# Determine whether Command Line Tools exist
|
||||||
# xcode-select -p
|
xcode_select = subprocess.run(["/usr/bin/xcode-select", "--print-path"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||||
xcode_select = subprocess.run("xcode-select -p".split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
|
||||||
if xcode_select.returncode == 0:
|
if xcode_select.returncode == 0:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
@@ -420,7 +420,7 @@ def find_apfs_physical_volume(device):
|
|||||||
disk_list = None
|
disk_list = None
|
||||||
physical_disks = []
|
physical_disks = []
|
||||||
try:
|
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:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -465,7 +465,7 @@ def find_disk_off_uuid(uuid):
|
|||||||
# Find disk by UUID
|
# Find disk by UUID
|
||||||
disk_list = None
|
disk_list = None
|
||||||
try:
|
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:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
if disk_list:
|
if disk_list:
|
||||||
@@ -492,12 +492,12 @@ def get_free_space(disk=None):
|
|||||||
return free
|
return free
|
||||||
|
|
||||||
def grab_mount_point_from_disk(disk):
|
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"]
|
return data["MountPoint"]
|
||||||
|
|
||||||
def monitor_disk_output(disk):
|
def monitor_disk_output(disk):
|
||||||
# Returns MB written on drive
|
# 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")
|
output = output.decode("utf-8")
|
||||||
# Grab second last entry (last is \n)
|
# Grab second last entry (last is \n)
|
||||||
output = output.split(" ")
|
output = output.split(" ")
|
||||||
@@ -509,7 +509,7 @@ def get_preboot_uuid() -> str:
|
|||||||
"""
|
"""
|
||||||
Get the UUID of the Preboot volume
|
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)
|
output = plistlib.loads(subprocess.run(args, stdout=subprocess.PIPE).stdout)
|
||||||
return output[0]["apfs-preboot-uuid"].strip(b"\0").decode()
|
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 bad_process in current_process:
|
||||||
if pid != "":
|
if pid != "":
|
||||||
logging.info(f"Killing Process: {pid} - {current_process.split('/')[-1]}")
|
logging.info(f"Killing Process: {pid} - {current_process.split('/')[-1]}")
|
||||||
subprocess.run(["kill", "-9", pid])
|
subprocess.run(["/bin/kill", "-9", pid])
|
||||||
break
|
break
|
||||||
|
|
||||||
def check_boot_mode():
|
def check_boot_mode():
|
||||||
# Check whether we're in Safe Mode or not
|
# Check whether we're in Safe Mode or not
|
||||||
try:
|
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"]
|
return sys_plist[0]["_items"][0]["boot_mode"]
|
||||||
except (KeyError, TypeError, plistlib.InvalidFileException):
|
except (KeyError, TypeError, plistlib.InvalidFileException):
|
||||||
return None
|
return None
|
||||||
@@ -550,7 +550,34 @@ def elevated(*args, **kwargs) -> subprocess.CompletedProcess:
|
|||||||
if os.getuid() == 0 or check_cli_args() is not None:
|
if os.getuid() == 0 or check_cli_args() is not None:
|
||||||
return subprocess.run(*args, **kwargs)
|
return subprocess.run(*args, **kwargs)
|
||||||
else:
|
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):
|
||||||
|
"""
|
||||||
|
Check for staged macOS update
|
||||||
|
Supported variants:
|
||||||
|
- Preflight
|
||||||
|
- Update
|
||||||
|
"""
|
||||||
|
|
||||||
|
os_build = None
|
||||||
|
os_version = None
|
||||||
|
|
||||||
|
update_config = f"/System/Volumes/Update/{variant}.plist"
|
||||||
|
if not Path(update_config).exists():
|
||||||
|
return (None, None)
|
||||||
|
try:
|
||||||
|
update_staged = plistlib.load(open(update_config, "rb"))
|
||||||
|
except:
|
||||||
|
return (None, None)
|
||||||
|
if "update-asset-attributes" not in update_staged:
|
||||||
|
return (None, None)
|
||||||
|
|
||||||
|
os_build = update_staged["update-asset-attributes"]["Build"]
|
||||||
|
os_version = update_staged["update-asset-attributes"]["OSVersion"]
|
||||||
|
|
||||||
|
return os_version, os_build
|
||||||
|
|
||||||
|
|
||||||
def check_cli_args():
|
def check_cli_args():
|
||||||
@@ -580,6 +607,8 @@ def check_cli_args():
|
|||||||
# sys_patch args
|
# sys_patch args
|
||||||
parser.add_argument("--patch_sys_vol", help="Patches root volume", action="store_true", required=False)
|
parser.add_argument("--patch_sys_vol", help="Patches root volume", action="store_true", required=False)
|
||||||
parser.add_argument("--unpatch_sys_vol", help="Unpatches root volume, EXPERIMENTAL", action="store_true", required=False)
|
parser.add_argument("--unpatch_sys_vol", help="Unpatches root volume, EXPERIMENTAL", action="store_true", required=False)
|
||||||
|
parser.add_argument("--prepare_for_update", help="Prepares host for macOS update, ex. clean /Library/Extensions", action="store_true", required=False)
|
||||||
|
parser.add_argument("--cache_os", help="Caches patcher files (ex. KDKs) for incoming OS in Preflight.plist", action="store_true", required=False)
|
||||||
|
|
||||||
# validation args
|
# validation args
|
||||||
parser.add_argument("--validate", help="Runs Validation Tests for CI", action="store_true", required=False)
|
parser.add_argument("--validate", help="Runs Validation Tests for CI", action="store_true", required=False)
|
||||||
@@ -591,7 +620,15 @@ def check_cli_args():
|
|||||||
parser.add_argument("--update_installed", help="Prompt user to finish updating via GUI", action="store_true", required=False)
|
parser.add_argument("--update_installed", help="Prompt user to finish updating via GUI", action="store_true", required=False)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
if not (args.build or args.patch_sys_vol or args.unpatch_sys_vol or args.validate or args.auto_patch):
|
if not (
|
||||||
|
args.build or
|
||||||
|
args.patch_sys_vol or
|
||||||
|
args.unpatch_sys_vol or
|
||||||
|
args.validate or
|
||||||
|
args.auto_patch or
|
||||||
|
args.prepare_for_update or
|
||||||
|
args.cache_os
|
||||||
|
):
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return args
|
return args
|
||||||
|
|||||||
@@ -15,8 +15,10 @@ class PatcherValidation:
|
|||||||
Primarily for Continuous Integration
|
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.constants: constants.Constants = global_constants
|
||||||
|
self.verify_unused_files = verify_unused_files
|
||||||
|
self.active_patchset_files = []
|
||||||
|
|
||||||
self.constants.validate = True
|
self.constants.validate = True
|
||||||
|
|
||||||
@@ -102,7 +104,7 @@ class PatcherValidation:
|
|||||||
minor_kernel (int): Minor kernel version
|
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}")
|
host_os_float = float(f"{major_kernel}.{minor_kernel}")
|
||||||
|
|
||||||
for patch_subject in patchset:
|
for patch_subject in patchset:
|
||||||
@@ -119,6 +121,8 @@ class PatcherValidation:
|
|||||||
if not Path(source_file).exists():
|
if not Path(source_file).exists():
|
||||||
logging.info(f"File not found: {source_file}")
|
logging.info(f"File not found: {source_file}")
|
||||||
raise Exception(f"Failed to find {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}")
|
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):
|
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")
|
raise Exception("Failed to download Universal-Binaries.dmg")
|
||||||
|
|
||||||
logging.info("Validating Root Patch File integrity")
|
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(
|
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")),
|
"-mountpoint", Path(self.constants.payload_path / Path("Universal-Binaries")),
|
||||||
"-nobrowse",
|
"-nobrowse",
|
||||||
"-shadow", Path(self.constants.payload_path / Path("Universal-Binaries_overlay")),
|
"-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 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):
|
for i in range(0, 10):
|
||||||
self._validate_root_patch_files(supported_os, i)
|
self._validate_root_patch_files(supported_os, i)
|
||||||
|
|
||||||
logging.info("Validating SNB Board ID patcher")
|
logging.info("Validating SNB Board ID patcher")
|
||||||
self.constants.computer.reported_board_id = "Mac-7BA5B2DFE22DDD8C"
|
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)
|
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
|
# unmount the dmg
|
||||||
output = subprocess.run(
|
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"
|
"-force"
|
||||||
],
|
],
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT
|
stdout=subprocess.PIPE, stderr=subprocess.STDOUT
|
||||||
@@ -187,12 +219,56 @@ class PatcherValidation:
|
|||||||
|
|
||||||
subprocess.run(
|
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
|
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:
|
def _validate_configs(self) -> None:
|
||||||
"""
|
"""
|
||||||
Validates build modules
|
Validates build modules
|
||||||
@@ -222,4 +298,4 @@ class PatcherValidation:
|
|||||||
self._build_prebuilt()
|
self._build_prebuilt()
|
||||||
self._build_dumps()
|
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)
|
||||||
191
resources/wx_gui/gui_cache_os_update.py
Normal file
191
resources/wx_gui/gui_cache_os_update.py
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
"""
|
||||||
|
UI to display to users before a macOS update is applied
|
||||||
|
Primarily for caching updates required for incoming OS (ex. KDKs)
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import logging
|
||||||
|
import threading
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from resources import constants, kdk_handler, utilities
|
||||||
|
from resources.wx_gui import gui_support, gui_download
|
||||||
|
|
||||||
|
|
||||||
|
class OSUpdateFrame(wx.Frame):
|
||||||
|
"""
|
||||||
|
Create a modal frame for displaying information to the user before an update is applied
|
||||||
|
"""
|
||||||
|
def __init__(self, parent: wx.Frame, title: str, global_constants: constants.Constants, screen_location: tuple = None):
|
||||||
|
logging.info("Initializing Prepare Update Frame")
|
||||||
|
|
||||||
|
if parent:
|
||||||
|
self.frame = parent
|
||||||
|
else:
|
||||||
|
super().__init__(parent, title=title, size=(360, 140), style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER ^ wx.MAXIMIZE_BOX)
|
||||||
|
self.frame = self
|
||||||
|
self.frame.Centre()
|
||||||
|
|
||||||
|
self.title = title
|
||||||
|
self.constants: constants.Constants = global_constants
|
||||||
|
|
||||||
|
os_data = utilities.fetch_staged_update(variant="Preflight")
|
||||||
|
if os_data[0] is None:
|
||||||
|
logging.info("No staged update found")
|
||||||
|
self._exit()
|
||||||
|
logging.info(f"Staged update found: {os_data[0]} ({os_data[1]})")
|
||||||
|
self.os_data = os_data
|
||||||
|
|
||||||
|
self._generate_ui()
|
||||||
|
|
||||||
|
self.kdk_obj: kdk_handler.KernelDebugKitObject = None
|
||||||
|
def _kdk_thread_spawn():
|
||||||
|
self.kdk_obj = kdk_handler.KernelDebugKitObject(self.constants, self.os_data[1], self.os_data[0], passive=True, check_backups_only=True)
|
||||||
|
|
||||||
|
kdk_thread = threading.Thread(target=_kdk_thread_spawn)
|
||||||
|
kdk_thread.start()
|
||||||
|
|
||||||
|
while kdk_thread.is_alive():
|
||||||
|
wx.Yield()
|
||||||
|
|
||||||
|
if self.kdk_obj.success is False:
|
||||||
|
self._exit()
|
||||||
|
|
||||||
|
kdk_download_obj = self.kdk_obj.retrieve_download()
|
||||||
|
if not kdk_download_obj:
|
||||||
|
# KDK is already downloaded
|
||||||
|
# Return false since we didn't display anything
|
||||||
|
self._exit()
|
||||||
|
|
||||||
|
self.kdk_download_obj = kdk_download_obj
|
||||||
|
|
||||||
|
self.frame.Show()
|
||||||
|
|
||||||
|
self.did_cancel = -1
|
||||||
|
self._notifyUser()
|
||||||
|
|
||||||
|
# Allow 10 seconds for the user to cancel the download
|
||||||
|
# If nothing, continue
|
||||||
|
for i in range(0, 10):
|
||||||
|
if self.did_cancel == 1:
|
||||||
|
self._exit()
|
||||||
|
if self.did_cancel == -1:
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
gui_download.DownloadFrame(
|
||||||
|
self,
|
||||||
|
title=self.title,
|
||||||
|
global_constants=self.constants,
|
||||||
|
download_obj=kdk_download_obj,
|
||||||
|
item_name=f"KDK Build {self.kdk_obj.kdk_url_build}"
|
||||||
|
)
|
||||||
|
if kdk_download_obj.download_complete is False:
|
||||||
|
self._exit()
|
||||||
|
|
||||||
|
logging.info("KDK download complete, validating with hdiutil")
|
||||||
|
self.kdk_checksum_result = False
|
||||||
|
def _validate_kdk_checksum_thread():
|
||||||
|
self.kdk_checksum_result = self.kdk_obj.validate_kdk_checksum()
|
||||||
|
|
||||||
|
kdk_checksum_thread = threading.Thread(target=_validate_kdk_checksum_thread)
|
||||||
|
kdk_checksum_thread.start()
|
||||||
|
|
||||||
|
while kdk_checksum_thread.is_alive():
|
||||||
|
wx.Yield()
|
||||||
|
|
||||||
|
if self.kdk_checksum_result is False:
|
||||||
|
logging.error("KDK checksum validation failed")
|
||||||
|
logging.error(self.kdk_obj.error_msg)
|
||||||
|
self._exit()
|
||||||
|
|
||||||
|
logging.info("KDK checksum validation passed")
|
||||||
|
|
||||||
|
logging.info("Mounting KDK")
|
||||||
|
if not Path(self.constants.kdk_download_path).exists():
|
||||||
|
logging.error("KDK download path does not exist")
|
||||||
|
self._exit()
|
||||||
|
|
||||||
|
self.kdk_install_result = False
|
||||||
|
def _install_kdk_thread():
|
||||||
|
self.kdk_install_result = kdk_handler.KernelDebugKitUtilities().install_kdk_dmg(self.constants.kdk_download_path, only_install_backup=True)
|
||||||
|
|
||||||
|
kdk_install_thread = threading.Thread(target=_install_kdk_thread)
|
||||||
|
kdk_install_thread.start()
|
||||||
|
|
||||||
|
while kdk_install_thread.is_alive():
|
||||||
|
wx.Yield()
|
||||||
|
|
||||||
|
if self.kdk_install_result is False:
|
||||||
|
logging.info("Failed to install KDK")
|
||||||
|
self._exit()
|
||||||
|
|
||||||
|
logging.info("KDK installed successfully")
|
||||||
|
self._exit()
|
||||||
|
|
||||||
|
|
||||||
|
def _generate_ui(self) -> None:
|
||||||
|
"""
|
||||||
|
Display frame
|
||||||
|
|
||||||
|
|
||||||
|
Title: OpenCore Legacy Patcher is preparing to update your system
|
||||||
|
Body: Please wait while we prepare your system for the update.
|
||||||
|
This may take a few minutes.
|
||||||
|
"""
|
||||||
|
|
||||||
|
header = wx.StaticText(self.frame, label="Preparing for macOS Software Update", pos=(-1,5))
|
||||||
|
header.SetFont(gui_support.font_factory(19, wx.FONTWEIGHT_BOLD))
|
||||||
|
header.Centre(wx.HORIZONTAL)
|
||||||
|
|
||||||
|
# list OS
|
||||||
|
label = wx.StaticText(self.frame, label=f"macOS {self.os_data[0]} ({self.os_data[1]})", pos=(-1, 35))
|
||||||
|
label.SetFont(gui_support.font_factory(13, wx.FONTWEIGHT_NORMAL))
|
||||||
|
label.Centre(wx.HORIZONTAL)
|
||||||
|
|
||||||
|
# this may take a few minutes
|
||||||
|
label = wx.StaticText(self.frame, label="This may take a few minutes.", pos=(-1, 55))
|
||||||
|
label.SetFont(gui_support.font_factory(13, wx.FONTWEIGHT_NORMAL))
|
||||||
|
label.Centre(wx.HORIZONTAL)
|
||||||
|
|
||||||
|
# Add a progress bar
|
||||||
|
self.progress_bar = wx.Gauge(self.frame, range=100, pos=(10, 75), size=(340, 20))
|
||||||
|
self.progress_bar.SetValue(0)
|
||||||
|
self.progress_bar.Pulse()
|
||||||
|
|
||||||
|
# Set frame size below progress bar
|
||||||
|
self.frame.SetSize((360, 140))
|
||||||
|
|
||||||
|
|
||||||
|
def _notifyUser(self) -> None:
|
||||||
|
"""
|
||||||
|
Notify user of what OCLP is doing
|
||||||
|
Note will be spawned through wx.CallAfter
|
||||||
|
"""
|
||||||
|
threading.Thread(target=self._notifyUserThread).start()
|
||||||
|
|
||||||
|
|
||||||
|
def _notifyUserThread(self) -> None:
|
||||||
|
"""
|
||||||
|
Notify user of what OCLP is doing
|
||||||
|
"""
|
||||||
|
message=f"OpenCore Legacy Patcher has detected that a macOS update is being downloaded:\n{self.os_data[0]} ({self.os_data[1]})\n\nThe patcher needs to prepare the system for the update, and will download any additional resources it may need post-update.\n\nThis may take a few minutes, the patcher will exit when it is done."
|
||||||
|
# Yes/No for caching
|
||||||
|
dlg = wx.MessageDialog(self.frame, message=message, caption="OpenCore Legacy Patcher", style=wx.YES_NO | wx.ICON_INFORMATION)
|
||||||
|
dlg.SetYesNoLabels("&Ok", "&Cancel")
|
||||||
|
result = dlg.ShowModal()
|
||||||
|
if result == wx.ID_NO:
|
||||||
|
logging.info("User cancelled OS caching")
|
||||||
|
self.kdk_download_obj.stop()
|
||||||
|
self.did_cancel = 1
|
||||||
|
else:
|
||||||
|
self.did_cancel = 0
|
||||||
|
|
||||||
|
def _exit(self):
|
||||||
|
"""
|
||||||
|
Exit the frame
|
||||||
|
"""
|
||||||
|
self.frame.Close()
|
||||||
|
sys.exit()
|
||||||
@@ -6,6 +6,7 @@ import logging
|
|||||||
|
|
||||||
from resources import constants
|
from resources import constants
|
||||||
from resources.wx_gui import (
|
from resources.wx_gui import (
|
||||||
|
gui_cache_os_update,
|
||||||
gui_main_menu,
|
gui_main_menu,
|
||||||
gui_build,
|
gui_build,
|
||||||
gui_install_oc,
|
gui_install_oc,
|
||||||
@@ -24,6 +25,7 @@ class SupportedEntryPoints:
|
|||||||
INSTALL_OC = gui_install_oc.InstallOCFrame
|
INSTALL_OC = gui_install_oc.InstallOCFrame
|
||||||
SYS_PATCH = gui_sys_patch_start.SysPatchStartFrame
|
SYS_PATCH = gui_sys_patch_start.SysPatchStartFrame
|
||||||
UPDATE_APP = gui_update.UpdateFrame
|
UPDATE_APP = gui_update.UpdateFrame
|
||||||
|
OS_CACHE = gui_cache_os_update.OSUpdateFrame
|
||||||
|
|
||||||
|
|
||||||
class EntryPoint:
|
class EntryPoint:
|
||||||
@@ -58,7 +60,7 @@ class EntryPoint:
|
|||||||
|
|
||||||
self.frame: wx.Frame = entry(
|
self.frame: wx.Frame = entry(
|
||||||
None,
|
None,
|
||||||
title=f"{self.constants.patcher_name} ({self.constants.patcher_version})",
|
title=f"{self.constants.patcher_name} {self.constants.patcher_version}{' (Nightly)' if not self.constants.commit_info[0].startswith('refs/tags') else ''}",
|
||||||
global_constants=self.constants,
|
global_constants=self.constants,
|
||||||
screen_location=None,
|
screen_location=None,
|
||||||
**({"patches": patches} if "--gui_patch" in sys.argv or "--gui_unpatch" in sys.argv else {})
|
**({"patches": patches} if "--gui_patch" in sys.argv or "--gui_unpatch" in sys.argv else {})
|
||||||
|
|||||||
@@ -428,8 +428,8 @@ class macOSInstallerFlashFrame(wx.Frame):
|
|||||||
if not str(path).endswith(".zip"):
|
if not str(path).endswith(".zip"):
|
||||||
return
|
return
|
||||||
if Path(self.constants.installer_pkg_path).exists():
|
if Path(self.constants.installer_pkg_path).exists():
|
||||||
subprocess.run(["rm", self.constants.installer_pkg_path])
|
subprocess.run(["/bin/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(["/usr/bin/ditto", "-V", "-x", "-k", "--sequesterRsrc", "--rsrc", self.constants.installer_pkg_zip_path, self.constants.payload_path])
|
||||||
|
|
||||||
|
|
||||||
def _install_installer_pkg(self, disk):
|
def _install_installer_pkg(self, disk):
|
||||||
@@ -448,8 +448,8 @@ class macOSInstallerFlashFrame(wx.Frame):
|
|||||||
logging.info("Installer unsupported, requires Big Sur or newer")
|
logging.info("Installer unsupported, requires Big Sur or newer")
|
||||||
return
|
return
|
||||||
|
|
||||||
subprocess.run(["mkdir", "-p", f"{path}/Library/Packages/"])
|
subprocess.run(["/bin/mkdir", "-p", f"{path}/Library/Packages/"])
|
||||||
subprocess.run(["cp", "-r", self.constants.installer_pkg_path, 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/"))
|
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
|
# Now that we have a KDK, extract it to get the pkg
|
||||||
with tempfile.TemporaryDirectory() as mount_point:
|
with tempfile.TemporaryDirectory() as mount_point:
|
||||||
logging.info("Mounting KDK")
|
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:
|
if result.returncode != 0:
|
||||||
logging.info("Failed to mount KDK")
|
logging.info("Failed to mount KDK")
|
||||||
logging.info(result.stdout.decode("utf-8"))
|
logging.info(result.stdout.decode("utf-8"))
|
||||||
return
|
return
|
||||||
|
|
||||||
logging.info("Copying KDK")
|
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")
|
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:
|
if result.returncode != 0:
|
||||||
logging.info("Failed to unmount KDK")
|
logging.info("Failed to unmount KDK")
|
||||||
logging.info(result.stdout.decode("utf-8"))
|
logging.info(result.stdout.decode("utf-8"))
|
||||||
@@ -545,7 +545,7 @@ class macOSInstallerFlashFrame(wx.Frame):
|
|||||||
logging.error(f"Failed to find {dmg_path}")
|
logging.error(f"Failed to find {dmg_path}")
|
||||||
error_message = f"Failed to find {dmg_path}"
|
error_message = f"Failed to find {dmg_path}"
|
||||||
return error_message
|
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.returncode != 0:
|
||||||
if result.stdout:
|
if result.stdout:
|
||||||
logging.error(result.stdout.decode("utf-8"))
|
logging.error(result.stdout.decode("utf-8"))
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ from resources import (
|
|||||||
global_settings,
|
global_settings,
|
||||||
updates
|
updates
|
||||||
)
|
)
|
||||||
from data import os_data
|
from data import os_data, css_data
|
||||||
|
|
||||||
|
|
||||||
class MainFrame(wx.Frame):
|
class MainFrame(wx.Frame):
|
||||||
@@ -70,7 +70,7 @@ class MainFrame(wx.Frame):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Title label: OpenCore Legacy Patcher v{X.Y.Z}
|
# Title label: OpenCore Legacy Patcher v{X.Y.Z}
|
||||||
title_label = wx.StaticText(self, label=f"OpenCore Legacy Patcher {'' if self.constants.special_build else 'v'}{self.constants.patcher_version}", pos=(-1, 10))
|
title_label = wx.StaticText(self, label=f"OpenCore Legacy Patcher {'' if self.constants.special_build else ''}{self.constants.patcher_version}{' (Nightly)' if not self.constants.commit_info[0].startswith('refs/tags') else ''}", pos=(-1, 10))
|
||||||
title_label.SetFont(gui_support.font_factory(19, wx.FONTWEIGHT_BOLD))
|
title_label.SetFont(gui_support.font_factory(19, wx.FONTWEIGHT_BOLD))
|
||||||
title_label.Centre(wx.HORIZONTAL)
|
title_label.Centre(wx.HORIZONTAL)
|
||||||
|
|
||||||
@@ -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:
|
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")
|
logging.info("Found user-installed app in /Applications, replacing with symlink")
|
||||||
# Delete app
|
# 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:
|
if result.returncode != 0:
|
||||||
logging.info("Failed to delete app from /Applications")
|
logging.info("Failed to delete app from /Applications")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Create symlink
|
# 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:
|
if result.returncode != 0:
|
||||||
logging.info("Failed to create symlink to /Applications")
|
logging.info("Failed to create symlink to /Applications")
|
||||||
return
|
return
|
||||||
@@ -276,7 +276,7 @@ class MainFrame(wx.Frame):
|
|||||||
def _check_for_updates(self):
|
def _check_for_updates(self):
|
||||||
if self.constants.has_checked_updates is True:
|
if self.constants.has_checked_updates is True:
|
||||||
return
|
return
|
||||||
|
|
||||||
ignore_updates = global_settings.GlobalEnviromentSettings().read_property("IgnoreAppUpdates")
|
ignore_updates = global_settings.GlobalEnviromentSettings().read_property("IgnoreAppUpdates")
|
||||||
if ignore_updates is True:
|
if ignore_updates is True:
|
||||||
self.constants.ignore_updates = True
|
self.constants.ignore_updates = True
|
||||||
@@ -290,7 +290,7 @@ class MainFrame(wx.Frame):
|
|||||||
|
|
||||||
version = dict["Version"]
|
version = dict["Version"]
|
||||||
logging.info(f"New version: {version}")
|
logging.info(f"New version: {version}")
|
||||||
|
|
||||||
wx.CallAfter(self.on_update, dict["Link"], version, dict["Github Link"])
|
wx.CallAfter(self.on_update, dict["Link"], version, dict["Github Link"])
|
||||||
|
|
||||||
def on_build_and_install(self, event: wx.Event = None):
|
def on_build_and_install(self, event: wx.Event = None):
|
||||||
@@ -345,45 +345,38 @@ class MainFrame(wx.Frame):
|
|||||||
|
|
||||||
url = "https://api.github.com/repos/dortania/OpenCore-Legacy-Patcher/releases/latest"
|
url = "https://api.github.com/repos/dortania/OpenCore-Legacy-Patcher/releases/latest"
|
||||||
response = requests.get(url).json()
|
response = requests.get(url).json()
|
||||||
changelog = response["body"].split("## Asset Information")[0]
|
try:
|
||||||
|
changelog = response["body"].split("## Asset Information")[0]
|
||||||
|
except: #if user constantly checks for updates, github will rate limit them
|
||||||
|
changelog = """## Unable to fetch changelog
|
||||||
|
|
||||||
html_markdown = markdown2.markdown(changelog)
|
Please check the Github page for more information about this release."""
|
||||||
html_css = """
|
|
||||||
<style>
|
html_markdown = markdown2.markdown(changelog, extras=["tables"])
|
||||||
body {
|
html_css = css_data.updater_css
|
||||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
|
frame = wx.Dialog(None, -1, title="", size=(650, 500))
|
||||||
line-height: 1.5;
|
frame.SetMinSize((650, 500))
|
||||||
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>
|
|
||||||
"""
|
|
||||||
frame = wx.Dialog(None, -1, title="", size=(600, 500))
|
|
||||||
frame.SetMinSize((600, 500))
|
|
||||||
frame.SetWindowStyle(wx.STAY_ON_TOP)
|
frame.SetWindowStyle(wx.STAY_ON_TOP)
|
||||||
panel = wx.Panel(frame)
|
panel = wx.Panel(frame)
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
sizer.AddSpacer(10)
|
sizer.AddSpacer(10)
|
||||||
self.title_text = wx.StaticText(panel, label="A new version of OpenCore Legacy Patcher is available!")
|
self.title_text = wx.StaticText(panel, label="A new version of OpenCore Legacy Patcher is available!")
|
||||||
self.description = wx.StaticText(panel, label=f"OpenCore Legacy Patcher {oclp_version} is now available - You have {self.constants.patcher_version}. Would you like to update?")
|
self.description = wx.StaticText(panel, label=f"OpenCore Legacy Patcher {oclp_version} is now available - You have {self.constants.patcher_version}{' (Nightly)' if not self.constants.commit_info[0].startswith('refs/tags') else ''}. Would you like to update?")
|
||||||
self.title_text.SetFont(wx.Font(19, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, ".AppleSystemUIFont"))
|
self.title_text.SetFont(gui_support.font_factory(19, wx.FONTWEIGHT_BOLD))
|
||||||
self.description.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont"))
|
self.description.SetFont(gui_support.font_factory(13, wx.FONTWEIGHT_NORMAL))
|
||||||
self.web_view = wx.html2.WebView.New(panel, style=wx.BORDER_SUNKEN)
|
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.SetPage(html_code, "")
|
||||||
self.web_view.Bind(wx.html2.EVT_WEBVIEW_NEWWINDOW, self._onWebviewNav)
|
self.web_view.Bind(wx.html2.EVT_WEBVIEW_NEWWINDOW, self._onWebviewNav)
|
||||||
self.web_view.EnableContextMenu(False)
|
self.web_view.EnableContextMenu(False)
|
||||||
@@ -408,7 +401,7 @@ class MainFrame(wx.Frame):
|
|||||||
frame.Centre()
|
frame.Centre()
|
||||||
|
|
||||||
result = frame.ShowModal()
|
result = frame.ShowModal()
|
||||||
|
|
||||||
|
|
||||||
if result == ID_GITHUB:
|
if result == ID_GITHUB:
|
||||||
webbrowser.open(oclp_github_url)
|
webbrowser.open(oclp_github_url)
|
||||||
@@ -422,6 +415,8 @@ class MainFrame(wx.Frame):
|
|||||||
version_label=oclp_version
|
version_label=oclp_version
|
||||||
)
|
)
|
||||||
|
|
||||||
|
frame.Destroy()
|
||||||
|
|
||||||
def _onWebviewNav(self, event):
|
def _onWebviewNav(self, event):
|
||||||
url = event.GetURL()
|
url = event.GetURL()
|
||||||
webbrowser.open(url)
|
webbrowser.open(url)
|
||||||
@@ -286,7 +286,7 @@ class SettingsFrame(wx.Frame):
|
|||||||
"tampering or corruption."
|
"tampering or corruption."
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
"Show OpenCore Boot Picker": {
|
"Show OpenCore Boot Picker": {
|
||||||
"type": "checkbox",
|
"type": "checkbox",
|
||||||
"value": self.constants.showpicker,
|
"value": self.constants.showpicker,
|
||||||
@@ -685,6 +685,7 @@ class SettingsFrame(wx.Frame):
|
|||||||
"By default this is disabled due to",
|
"By default this is disabled due to",
|
||||||
"common GPU failures on these models.",
|
"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"])
|
"condition": not bool(self.constants.computer.real_model not in ["MacBookPro8,2", "MacBookPro8,3"])
|
||||||
},
|
},
|
||||||
"wrap_around 1": {
|
"wrap_around 1": {
|
||||||
@@ -755,6 +756,16 @@ class SettingsFrame(wx.Frame):
|
|||||||
"override_function": self._update_system_defaults,
|
"override_function": self._update_system_defaults,
|
||||||
"condition": gui_support.CheckProperties(self.constants).host_is_non_metal(general_check=True)
|
"condition": gui_support.CheckProperties(self.constants).host_is_non_metal(general_check=True)
|
||||||
},
|
},
|
||||||
|
"Disable Color Widgets Enforcement": {
|
||||||
|
"type": "checkbox",
|
||||||
|
"value": self._get_system_settings("Moraea_ColorWidgetDisabled"),
|
||||||
|
"variable": "Moraea_ColorWidgetDisabled",
|
||||||
|
"description": [
|
||||||
|
"Control Color Desktop Widgets Enforcement.",
|
||||||
|
],
|
||||||
|
"override_function": self._update_system_defaults,
|
||||||
|
"condition": gui_support.CheckProperties(self.constants).host_is_non_metal(general_check=True)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"App": {
|
"App": {
|
||||||
"General": {
|
"General": {
|
||||||
@@ -846,7 +857,7 @@ class SettingsFrame(wx.Frame):
|
|||||||
"Export constants.py values to a txt file.",
|
"Export constants.py values to a txt file.",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
"Developer Root Volume Patching": {
|
"Developer Root Volume Patching": {
|
||||||
"type": "title",
|
"type": "title",
|
||||||
},
|
},
|
||||||
@@ -1099,7 +1110,7 @@ Hardware Information:
|
|||||||
value_type = "-bool"
|
value_type = "-bool"
|
||||||
|
|
||||||
logging.info(f"Updating System Defaults: {variable} = {value} ({value_type})")
|
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:
|
def _find_parent_for_key(self, key: str) -> str:
|
||||||
@@ -1141,7 +1152,7 @@ Hardware Information:
|
|||||||
if dlg.ShowModal() != wx.ID_YES:
|
if dlg.ShowModal() != wx.ID_YES:
|
||||||
return
|
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(" | ")
|
macserial_output = macserial_output.stdout.decode().strip().split(" | ")
|
||||||
if len(macserial_output) == 2:
|
if len(macserial_output) == 2:
|
||||||
self.custom_serial_number_textbox.SetValue(macserial_output[0])
|
self.custom_serial_number_textbox.SetValue(macserial_output[0])
|
||||||
@@ -1245,7 +1256,7 @@ Hardware Information:
|
|||||||
|
|
||||||
|
|
||||||
def _get_system_settings(self, variable) -> bool:
|
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:
|
if result.returncode == 0:
|
||||||
try:
|
try:
|
||||||
return bool(int(result.stdout.decode().strip()))
|
return bool(int(result.stdout.decode().strip()))
|
||||||
@@ -1305,7 +1316,7 @@ Hardware Information:
|
|||||||
|
|
||||||
def on_test_exception(self, event: wx.Event) -> None:
|
def on_test_exception(self, event: wx.Event) -> None:
|
||||||
raise Exception("Test Exception")
|
raise Exception("Test Exception")
|
||||||
|
|
||||||
def on_mount_root_vol(self, event: wx.Event) -> None:
|
def on_mount_root_vol(self, event: wx.Event) -> None:
|
||||||
if os.geteuid() != 0:
|
if os.geteuid() != 0:
|
||||||
wx.MessageDialog(self.parent, "Please relaunch as Root to mount the Root Volume", "Error", wx.OK | wx.ICON_ERROR).ShowModal()
|
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: 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: 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:
|
if os.geteuid() == 0:
|
||||||
relaunchItem.Enable(False)
|
relaunchItem.Enable(False)
|
||||||
@@ -329,7 +329,7 @@ class RelaunchApplicationAsRoot:
|
|||||||
|
|
||||||
# Relaunch as root
|
# Relaunch as root
|
||||||
args = [
|
args = [
|
||||||
"osascript",
|
"/usr/bin/osascript",
|
||||||
"-e",
|
"-e",
|
||||||
f'''do shell script "{program_arguments}"'''
|
f'''do shell script "{program_arguments}"'''
|
||||||
' with prompt "OpenCore Legacy Patcher needs administrator privileges to relaunch as admin."'
|
' 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:
|
if answer == wx.ID_YES:
|
||||||
output =subprocess.run(
|
output =subprocess.run(
|
||||||
[
|
[
|
||||||
"osascript", "-e",
|
"/usr/bin/osascript", "-e",
|
||||||
'tell app "System Preferences" to activate',
|
'tell app "System Preferences" to activate',
|
||||||
"-e", 'tell app "System Preferences" to reveal anchor "General" of pane id "com.apple.preference.security"',
|
"-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:
|
if output.returncode != 0:
|
||||||
# Some form of fallback if unaccelerated state errors out
|
# 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)
|
time.sleep(5)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
|||||||
@@ -184,13 +184,13 @@ class UpdateFrame(wx.Frame):
|
|||||||
"""
|
"""
|
||||||
logging.info("Extracting update")
|
logging.info("Extracting update")
|
||||||
if Path(self.application_path).exists():
|
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
|
# Some hell spawn at Github decided to double zip our Github Actions artifacts
|
||||||
# So we need to unzip it twice
|
# So we need to unzip it twice
|
||||||
for i in range(2):
|
for i in range(2):
|
||||||
result = subprocess.run(
|
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:
|
if result.returncode != 0:
|
||||||
logging.error(f"Failed to extract update. Error: {result.stderr.decode('utf-8')}")
|
logging.error(f"Failed to extract update. Error: {result.stderr.decode('utf-8')}")
|
||||||
|
|||||||
Reference in New Issue
Block a user