Compare commits

..

115 Commits
0.3.2 ... 0.4.0

Author SHA1 Message Date
Mykola Grymalyuk
b205f7943a Merge pull request #898 from dortania/update-docs
Update docs for 0.4.0 release
2022-01-21 09:57:16 -07:00
Mykola Grymalyuk
1163aaa4bd defaults.py: Fix FU logic 2022-01-21 09:38:35 -07:00
Mykola Grymalyuk
3dcf20f0c2 Update docs for 0.4.0 2022-01-20 20:02:16 -07:00
Mykola Grymalyuk
8502ec5f78 defaults.py: limit FU on pre-Ivy
Avoid extra patching when not needed, AirPlay to Mac and Sidecar do not check for older models other than MacPro5,1
2022-01-20 19:58:51 -07:00
Mykola Grymalyuk
54616ea385 gui.py: Fix DEBUG kext support 2022-01-20 19:38:41 -07:00
Mykola Grymalyuk
d1f9170390 Resolve typo 2022-01-20 15:06:10 -07:00
Mykola Grymalyuk
d4d16c3e56 Add enhanced cim menu 2022-01-20 14:21:41 -07:00
Mykola Grymalyuk
751bdceafd Resolve 100% CPU Usage with createinstallmedia 2022-01-19 20:23:24 -07:00
Mykola Grymalyuk
80dcea163f Sync changelog 2022-01-19 12:00:28 -07:00
Mykola Grymalyuk
c2eef22f2d Merge pull request #893 from dortania/test-ga
Add Commit Data to binaries
2022-01-19 11:54:24 -07:00
Mykola Grymalyuk
299fed997d Drop Commit Message 2022-01-19 11:29:56 -07:00
Mykola Grymalyuk
711c512258 Resolve Space in Commit Message 2022-01-19 11:24:26 -07:00
Mykola Grymalyuk
07b9a1a2c6 Add Commit Data to all builds 2022-01-19 11:18:43 -07:00
Mykola Grymalyuk
c78506501f Test Write 2022-01-19 10:57:31 -07:00
Mykola Grymalyuk
5612837492 Test GA events 2022-01-19 10:30:27 -07:00
Mykola Grymalyuk
80644bfbd4 Add Beta Blur config menu 2022-01-19 10:23:50 -07:00
Mykola Grymalyuk
b924e427e2 Disable Windows GMUX support by default
Closes https://github.com/dortania/OpenCore-Legacy-Patcher/issues/888
2022-01-19 10:17:15 -07:00
Mykola Grymalyuk
0cbd1422fe Sync FeatureUnlock 2022-01-18 22:45:08 -07:00
Mykola Grymalyuk
461f9ddb9b Revise Versioning to 0.4.0 2022-01-18 21:39:45 -07:00
Mykola Grymalyuk
b2e5037c2e WINDOWS.md: Adjust wording 2022-01-18 11:20:15 -07:00
Mykola Grymalyuk
be3e7da342 sys_patch.py: Add network error handling 2022-01-18 11:16:44 -07:00
Mykola Grymalyuk
b4830dfd0b gui.py: Add validation checks and download view 2022-01-18 09:56:28 -07:00
Mykola Grymalyuk
b8bdab3576 utilities.py: Fix 100%+ download reporting 2022-01-16 13:41:34 -07:00
Mykola Grymalyuk
a56f3af99c gui.py: Adjust Update wording 2022-01-15 16:23:31 -07:00
Mykola Grymalyuk
0e969ee6cd Add App Update checks to GUI 2022-01-15 16:16:04 -07:00
Mykola Grymalyuk
0bd3ce595d Disable AirPlay to Mac by default
Closes
2022-01-15 10:15:04 -07:00
Mykola Grymalyuk
ea05912b6b Move binary.py run to after pyinstaller 2022-01-14 20:31:26 -07:00
Mykola Grymalyuk
a756058006 Increment PatcherSupportPkg 2022-01-14 19:47:18 -07:00
Mykola Grymalyuk
bd3985ce6c Revert offline_build.py move 2022-01-14 18:24:55 -07:00
Mykola Grymalyuk
1e80691c67 Resolve offline creation 2022-01-14 18:11:41 -07:00
Mykola Grymalyuk
023fec03aa Allow optional spoofing on native Models 2022-01-14 18:04:39 -07:00
Mykola Grymalyuk
64b9e7ada6 Resolve LC_VERSION_MIN_MACOSX patching 2022-01-14 17:16:47 -07:00
Mykola Grymalyuk
efda41fb3a Sync changelog
Closes https://github.com/dortania/OpenCore-Legacy-Patcher/issues/382
Closes https://github.com/dortania/OpenCore-Legacy-Patcher/issues/757
2022-01-14 16:56:05 -07:00
Mykola Grymalyuk
77fccad046 Merge pull request #844 from dortania/wxPython-demo
Implement wxPython Based GUI
2022-01-14 16:53:53 -07:00
Mykola Grymalyuk
cc914aadc1 Add signing to offline TUI 2022-01-14 15:53:17 -07:00
Mykola Grymalyuk
5ea1b5075b Implement single binary for 10.10-12.0 2022-01-14 15:38:12 -07:00
Mykola Grymalyuk
41295e4cb2 Re-add Content Caching for VMM 2022-01-14 15:12:13 -07:00
Mykola Grymalyuk
7d5eea977d Merge branch 'main' into wxPython-demo 2022-01-14 12:07:33 -07:00
Mykola Grymalyuk
65fc232a25 Increment Binaries 2022-01-14 12:07:10 -07:00
Mykola Grymalyuk
43a708d3ae sys_patch.py: Strip User ID printing 2022-01-14 11:28:26 -07:00
Mykola Grymalyuk
c8bb3a3e93 Merge branch 'main' into wxPython-demo 2022-01-13 12:21:52 -07:00
Mykola Grymalyuk
7e236f06e5 gui.py: Add Cmd+Q support 2022-01-13 12:21:16 -07:00
Mykola Grymalyuk
cc1b8781ab Sync changelog 2022-01-11 19:10:36 -07:00
Mykola Grymalyuk
6553562e53 dylib_data.py: Resolve pathing typos 2022-01-11 19:07:46 -07:00
Mykola Grymalyuk
31812f0485 Resolve validation run 2022-01-11 10:35:57 -07:00
Mykola Grymalyuk
7ecf9ff151 Update docs 2022-01-11 09:21:38 -07:00
Mykola Grymalyuk
54b4c27d4a gui.py: Add ThirdPartyDrives option 2022-01-09 10:29:07 -07:00
Mykola Grymalyuk
7ed691993c Merge branch 'main' into wxPython-demo 2022-01-07 18:24:33 -07:00
Mykola Grymalyuk
14de472b6a Add ThirdPartyDrives quirk configurability
Closes https://github.com/dortania/OpenCore-Legacy-Patcher/issues/822
2022-01-07 17:53:56 -07:00
Mykola Grymalyuk
fd67032afe gui.py: Add FeatureUnlock configurability 2022-01-07 17:12:31 -07:00
Mykola Grymalyuk
cb808dc7ca gui.py: clear unused menus 2022-01-05 19:45:41 -07:00
Mykola Grymalyuk
3a65f005fe gui.py: Update cim text 2022-01-05 15:02:59 -07:00
Mykola Grymalyuk
a0978dfd20 gui.py: Resolve admin relaunch with space in path 2022-01-05 13:37:10 -07:00
Mykola Grymalyuk
e701b5b851 Merge branch 'main' into wxPython-demo 2022-01-05 12:50:44 -07:00
Mykola Grymalyuk
4cc2dab964 sys_patch.py: Add partial download error handling
Closes https://github.com/dortania/OpenCore-Legacy-Patcher/issues/873
2022-01-05 12:50:17 -07:00
Mykola Grymalyuk
ca44ba775a Merge branch 'main' into wxPython-demo 2022-01-05 11:11:26 -07:00
Mykola Grymalyuk
b2bb32f988 smbios_data.py: Add VM data sets 2022-01-05 11:11:13 -07:00
Mykola Grymalyuk
0956ad0d3d gui.py: Adjust SIP menu sizing 2022-01-05 10:14:34 -07:00
Mykola Grymalyuk
bf7b63c1be menu_redirect.py: Add configurable delay 2022-01-04 19:43:37 -07:00
Mykola Grymalyuk
c34781bb3c config.plist: Update Kext comments 2022-01-04 18:45:24 -07:00
Mykola Grymalyuk
e962f2bb8f gui.py: Add SIP configuration 2022-01-04 17:51:18 -07:00
Mykola Grymalyuk
a381f1d3bb Merge branch 'main' into wxPython-demo 2022-01-03 13:33:51 -07:00
Mykola Grymalyuk
4b6125d583 GA: Fix offline GUI building 2022-01-03 13:33:46 -07:00
Mykola Grymalyuk
dfa396f385 build.py: Set BoardProduct variable
Resolves Lilu race condition
2022-01-03 13:32:06 -07:00
Mykola Grymalyuk
3fc7424086 GA: Clean up build scripts 2022-01-01 17:18:00 -07:00
Mykola Grymalyuk
c37e035b6d Copyright: 2022 2022-01-01 17:03:00 -07:00
Mykola Grymalyuk
0b21472ccb Merge branch 'main' into wxPython-demo 2022-01-01 17:01:27 -07:00
Mykola Grymalyuk
f66f16441b Copyright: Update to 2022 2022-01-01 17:00:43 -07:00
Mykola Grymalyuk
f512b7336a gui.py: Resolve Root Volume Support 2022-01-01 15:18:01 -07:00
Mykola Grymalyuk
e35b115b81 Merge branch 'main' into wxPython-demo 2021-12-31 11:22:45 -07:00
Mykola Grymalyuk
dfe64e95b2 docs: Misc fixes
- Add MacBookPro11,3 note
- Update iMac15,1 note

Closes https://github.com/dortania/OpenCore-Legacy-Patcher/issues/522
2021-12-31 10:52:31 -07:00
Mykola Grymalyuk
e626c79c81 gui.py: Reroute stderr 2021-12-26 18:23:55 -07:00
Mykola Grymalyuk
98b08432fa gui.py: Add dev notes 2021-12-26 18:03:25 -07:00
Mykola Grymalyuk
7a7f1ce090 sys_patch_detect.py: Fix detection return 2021-12-26 18:01:14 -07:00
Mykola Grymalyuk
78f191dd5b gui.py: Remove pathlib import 2021-12-26 10:51:53 -07:00
Mykola Grymalyuk
e9e72d9641 gui.py: Sort Installer dl before presenting 2021-12-26 09:50:27 -07:00
Mykola Grymalyuk
a2500e50c2 Add error handling for failed downloads 2021-12-25 19:24:52 -07:00
Mykola Grymalyuk
6d917fbc29 gui.py: Adjust Download IA page subheader 2021-12-25 18:54:54 -07:00
Mykola Grymalyuk
c9cb6db0e4 gui.py: Add better stdout printing 2021-12-25 13:55:16 -07:00
Mykola Grymalyuk
0d72f46cb4 gui.py: Keep string in one line
Avoids some IDEs incorrectly collapsing functions (ie. VSCode)
2021-12-24 16:25:19 -07:00
Mykola Grymalyuk
3884ca77d5 gui.py: Ensure emojis supports 10.10-10.13 2021-12-24 16:02:06 -07:00
Mykola Grymalyuk
66a2d67ed9 Temp kill additional runs 2021-12-24 12:48:31 -07:00
Mykola Grymalyuk
5ed5f3aa15 Fix run 2021-12-24 12:44:08 -07:00
Mykola Grymalyuk
86af9e96f4 wxPython Workflow: Add legacy binary 2021-12-24 12:38:51 -07:00
Mykola Grymalyuk
5b97685274 GUI.spec: Add Dark Mode support for binaries
Running from source will launch as lightmode due to older SDK used in Python
2021-12-24 10:22:51 -07:00
Mykola Grymalyuk
3c929edd4b gui_main: Add WriteFlash Configurability 2021-12-24 10:21:46 -07:00
Mykola Grymalyuk
dfec8f2d72 Merge branch 'main' into wxPython-demo 2021-12-24 09:38:28 -07:00
Mykola Grymalyuk
5ff1110e90 Add NVRAM WriteFlash setting for degarded systems
Closes https://github.com/dortania/OpenCore-Legacy-Patcher/issues/831
2021-12-24 09:37:09 -07:00
Mykola Grymalyuk
9b5d25b2be build.py: Resolve check_firewire() bug
Closes https://github.com/dortania/OpenCore-Legacy-Patcher/issues/842
2021-12-24 09:20:47 -07:00
Mykola Grymalyuk
0e25f2f3cf GUI.spec: Add Minimum version
Ensure users do not launch wxPython binary on 10.9, due to missing dylib concerns
2021-12-23 19:27:12 -07:00
Mykola Grymalyuk
ee0b04f05b gui_main.py: Add SMBIOS settings 2021-12-22 21:41:41 -07:00
Mykola Grymalyuk
3c08127013 Resolve wxPython bundling 2021-12-22 20:14:06 -07:00
Mykola Grymalyuk
a17ca2c330 Exclude wxPython from non-GUI workflows 2021-12-22 19:55:40 -07:00
Mykola Grymalyuk
0cb2c84968 wxPython GUI: Initial Commit 2021-12-22 19:29:29 -07:00
Mykola Grymalyuk
aa8643f247 installer.py: Add installer.sh generation 2021-12-22 19:05:45 -07:00
Mykola Grymalyuk
554925d311 main.py: fix ImportError 2021-12-22 19:04:24 -07:00
Mykola Grymalyuk
fbd7150c00 Move init code to main.py 2021-12-22 18:41:15 -07:00
Mykola Grymalyuk
8233e15e42 build.py: Allow GCN setting on real_model build 2021-12-22 15:33:22 -07:00
Mykola Grymalyuk
7c21628ea2 Add launcher type detection 2021-12-22 10:56:16 -07:00
Mykola Grymalyuk
118853cd46 Add FeatureUnlock configurability 2021-12-21 18:12:11 -07:00
Mykola Grymalyuk
7e29758fea device_probe.py: Work-around NVMe PM issues 2021-12-21 12:47:00 -07:00
Mykola Grymalyuk
a8f56c1ec8 installer.py: resolve IA install error 2021-12-21 12:33:10 -07:00
Mykola Grymalyuk
79cd9c76f8 constants.py: Add resource link 2021-12-21 12:21:53 -07:00
Mykola Grymalyuk
fc7656bb25 example_data.py: Add iMac15,1 data set 2021-12-21 12:16:19 -07:00
Mykola Grymalyuk
e3ec7f7137 utilities.py: Add optional cls() argument 2021-12-21 12:15:37 -07:00
Mykola Grymalyuk
1f2ee627f4 cli_menu.py: Fix wording 2021-12-16 15:01:14 -07:00
Mykola Grymalyuk
91f5d9778c install.py: refactor adding disk data requests 2021-12-15 17:30:42 -07:00
Mykola Grymalyuk
fbcf958ead Resolves Install USB Creation using incorrect installer 2021-12-15 15:51:40 -07:00
Mykola Grymalyuk
0d402c4dba Fix crashing on unknown SMBIOS 2021-12-14 17:16:33 -07:00
Mykola Grymalyuk
b51beb8707 Increment build to 0.3.4 2021-12-14 15:20:59 -07:00
Mykola Grymalyuk
90bc9d81bf Disable Asset Caching 2021-12-14 13:04:33 -07:00
Mykola Grymalyuk
5eaa1d0317 Update iMac15,1 note 2021-12-14 12:25:03 -07:00
Mykola Grymalyuk
6b81af3f66 Increment build to 0.3.3 2021-12-13 17:10:05 -07:00
Mykola Grymalyuk
04d6aada33 Update build-gui.yml 2021-12-13 16:45:10 -07:00
Mykola Grymalyuk
acd84bc5c2 Resolve code signing on GUI 2021-12-13 16:40:46 -07:00
98 changed files with 4207 additions and 551 deletions

View File

@@ -10,24 +10,31 @@ jobs:
build:
name: Build Offline TUI
runs-on: x86_64_mojave
env:
branch: ${{ github.event.ref }}
commiturl: ${{ github.event.head_commit.url }}
commitdate: ${{ github.event.head_commit.timestamp }}
steps:
- uses: actions/checkout@v2
- run: python3 create_offline_build.py
- run: /Library/Frameworks/Python.framework/Versions/3.9/bin/pyinstaller OpenCore-Patcher.spec
- run: python3 ./payloads/binary.py $branch $commiturl $commitdate
- run: ./after_pyinstaller.sh
- run: 'codesign -s "Developer ID Application: Mykola Grymalyuk (S74BDJXQMD)" -v --force --deep --timestamp --entitlements ./payloads/entitlements.plist -o runtime "dist/OpenCore-Patcher.app"'
- run: cd dist; zip -r ../OpenCore-Patcher-TUI-Offline.app.zip OpenCore-Patcher.app
- run: cd dist; zip -r ../OpenCore-Patcher-TUI.app.zip OpenCore-Patcher.app
- run: ./../sign-tui.sh
- name: Upload App to Artifacts
uses: actions/upload-artifact@v2
with:
name: OpenCore-Patcher-TUI-Offline.app
path: OpenCore-Patcher-TUI-Offline.app.zip
name: OpenCore-Patcher-TUI.app (Offline)
path: OpenCore-Patcher-TUI.app.zip
- name: Upload to Release
if: github.event_name == 'release'
uses: svenstaro/upload-release-action@e74ff71f7d8a4c4745b560a485cc5fdb9b5b999d
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: OpenCore-Patcher-TUI-Offline.app.zip
asset_name: OpenCore-Patcher-TUI.app (Offline)
file: OpenCore-Patcher-TUI.app.zip
tag: ${{ github.ref }}
file_glob: true

View File

@@ -0,0 +1,40 @@
name: CI - Build wxPython Offline
on:
push:
workflow_dispatch:
release:
types: [published]
jobs:
build:
name: Build wxPython Offline
runs-on: x86_64_mojave
env:
branch: ${{ github.event.ref }}
commiturl: ${{ github.event.head_commit.url }}
commitdate: ${{ github.event.head_commit.timestamp }}
steps:
- uses: actions/checkout@v2
- run: python3 create_offline_build.py
- run: /Library/Frameworks/Python.framework/Versions/3.9/bin/pyinstaller OpenCore-Patcher-GUI.spec
- run: python3 ./payloads/binary.py $branch $commiturl $commitdate
- run: 'codesign -s "Developer ID Application: Mykola Grymalyuk (S74BDJXQMD)" -v --force --deep --timestamp --entitlements ./payloads/entitlements.plist -o runtime "dist/OpenCore-Patcher.app"'
- run: cd dist; zip -r ../OpenCore-Patcher-wxPython.app.zip OpenCore-Patcher.app
- run: ./../sign-wxpython.sh
- name: Upload App to Artifacts
uses: actions/upload-artifact@v2
with:
name: OpenCore-Patcher.app (GUI Offline)
path: OpenCore-Patcher-wxPython.app.zip
- name: Upload to Release
if: github.event_name == 'release'
uses: svenstaro/upload-release-action@e74ff71f7d8a4c4745b560a485cc5fdb9b5b999d
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: OpenCore-Patcher-wxPython.app.zip
tag: ${{ github.ref }}
file_glob: true
asset_name: OpenCore-Patcher.app (GUI Offline)
- name: Validate OpenCore
run: ./dist/OpenCore-Patcher.app/Contents/MacOS/OpenCore-Patcher --validate

View File

@@ -0,0 +1,37 @@
name: CI - Build wxPython
on:
push:
workflow_dispatch:
release:
types: [published]
jobs:
build:
name: Build wxPython
runs-on: x86_64_mojave
env:
branch: ${{ github.event.ref }}
commiturl: ${{ github.event.head_commit.url }}
commitdate: ${{ github.event.head_commit.timestamp }}
steps:
- uses: actions/checkout@v2
- run: /Library/Frameworks/Python.framework/Versions/3.9/bin/pyinstaller OpenCore-Patcher-GUI.spec
- run: python3 ./payloads/binary.py $branch $commiturl $commitdate
- run: 'codesign -s "Developer ID Application: Mykola Grymalyuk (S74BDJXQMD)" -v --force --deep --timestamp --entitlements ./payloads/entitlements.plist -o runtime "dist/OpenCore-Patcher.app"'
- run: cd dist; zip -r ../OpenCore-Patcher-wxPython.app.zip OpenCore-Patcher.app
- run: ./../sign-wxpython.sh
- name: Upload App to Artifacts
uses: actions/upload-artifact@v2
with:
name: OpenCore-Patcher.app (GUI)
path: OpenCore-Patcher-wxPython.app.zip
- name: Upload to Release
if: github.event_name == 'release'
uses: svenstaro/upload-release-action@e74ff71f7d8a4c4745b560a485cc5fdb9b5b999d
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: OpenCore-Patcher-wxPython.app.zip
tag: ${{ github.ref }}
file_glob: true
asset_name: OpenCore-Patcher.app (GUI)

View File

@@ -10,9 +10,14 @@ jobs:
build:
name: Build TUI
runs-on: x86_64_mojave
env:
branch: ${{ github.event.ref }}
commiturl: ${{ github.event.head_commit.url }}
commitdate: ${{ github.event.head_commit.timestamp }}
steps:
- uses: actions/checkout@v2
- run: /Library/Frameworks/Python.framework/Versions/3.9/bin/pyinstaller OpenCore-Patcher.spec
- run: python3 ./payloads/binary.py $branch $commiturl $commitdate
- run: ./after_pyinstaller.sh
- run: 'codesign -s "Developer ID Application: Mykola Grymalyuk (S74BDJXQMD)" -v --force --deep --timestamp --entitlements ./payloads/entitlements.plist -o runtime "dist/OpenCore-Patcher.app"'
- run: cd dist; zip -r ../OpenCore-Patcher-TUI.app.zip OpenCore-Patcher.app

View File

@@ -1,54 +0,0 @@
name: CI - Build GUI
on:
push:
workflow_dispatch:
release:
types: [published]
jobs:
build:
name: Build GUI
runs-on: x86_64_mojave
steps:
- uses: actions/checkout@v2
- run: /Library/Frameworks/Python.framework/Versions/3.9/bin/pyinstaller OpenCore-Patcher.spec
- run: cd dist; cp OpenCore-Patcher ../; cd ..; mv OpenCore-Patcher OCLP-CLI
- name: Download latest nightly OCLP-GUI
run: curl -S -L https://nightly.link/dortania/OCLP-GUI/workflows/build-app/master/OpenCore-Patcher-GUI.app.zip --output ./OpenCore-Patcher-GUI.app.zip --insecure
- run: unzip -o OpenCore-Patcher-GUI.app.zip
- run: unzip OpenCore-Patcher-GUI.app.zip; rm OpenCore-Patcher-GUI.app.zip
- name: Merge new GUI
run: cp OCLP-CLI OpenCore\ Patcher.app/Contents/Resources/
- run: python3 merge_gui.py
- name: Code Sign Binaries for release
if: github.event_name == 'release'
run: |
'codesign -s "Developer ID Application: Mykola Grymalyuk (S74BDJXQMD)" -v --force --deep --timestamp --entitlements ./payloads/entitlements.plist -o runtime "OpenCore Patcher.app/Contents/Resources/OCLP-CLI"'
'codesign -s "Developer ID Application: Mykola Grymalyuk (S74BDJXQMD)" -v --force --deep --timestamp --entitlements ./payloads/entitlements.plist -o runtime "OpenCore Patcher.app/Contents/Resources/oclpd"'
'codesign -s "Developer ID Application: Mykola Grymalyuk (S74BDJXQMD)" -v --force --deep --timestamp --entitlements ./payloads/entitlements.plist -o runtime "OpenCore Patcher.app"'
- run: ditto -c -k --sequesterRsrc --keepParent OpenCore\ Patcher.app OpenCore-Patcher-GUI.app.zip
- name: Notarize Binaries for release
if: github.event_name == 'release'
run: ./../sign-gui.sh
- name: Upload GUI to Artifacts
uses: actions/upload-artifact@v2
with:
name: OpenCore-Patcher-GUI.app
path: OpenCore-Patcher-GUI.app.zip
- name: Upload CLI to Artifacts
uses: actions/upload-artifact@v2
with:
name: OCLP-CLI
path: OCLP-CLI
- name: Upload to Release
if: github.event_name == 'release'
uses: svenstaro/upload-release-action@e74ff71f7d8a4c4745b560a485cc5fdb9b5b999d
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: OpenCore-Patcher-GUI.app.zip
tag: ${{ github.ref }}
file_glob: true
- name: Validate OpenCore
run: ./OCLP-CLI --validate

1
.gitignore vendored
View File

@@ -21,3 +21,4 @@ __pycache__/
/docs/yarn-error.log
/docs/node_modules/
/payloads/List.txt
/payloads/Installer.sh

View File

@@ -1,5 +1,41 @@
# OpenCore Legacy Patcher changelog
## 0.4.0
- Resolves Install USB Creation using incorrect installer
- Resolves `installer` failing to extract InstallAssistant in older OSes
- Resolves certain Samsung NVMe drives appearing as external on Mac Pros
- Add FeatureUnlock configurability
- Add NVRAM WriteFlash configurability for degarded/fragile systems
- Add `ThirdPartyDrives` quirk configurability
- Resolve Skylight dylib injection issue
- Increment Binaries:
- OpenCore 0.7.7 - release
- RestrictEvents 1.0.6 - release
- FeatureUnlock 1.0.6 - rolling (1d0bc7b)
- WhateverGreen 1.5.6 - release
- Lilu 1.5.9 - release
- gfxutil 1.8.2b - release
- PatcherSupportPkg 0.2.9 - release
- Re-add Content Caching support for VMM-spoofed systems
- Add wxPython Based GUI
- Superceeds Obj-C Based GUI
- Both standard and offline builds provided
- Allow optional spoofing on native Models
- Recommended for systems that cannot update their firmware natively (ie. dead internal drive)
- Add Dropbox fix for non-Metal on Monterey
- Add App Update checks to GUI
- If new version available, app will prompt on launch.
- Configurable in Developer Settings
- Resolved OS crashing on slow Macs with FeatureUnlock
- Disable Windows GMUX support by default
- Resolves brightness control issues on MacBookPro11,3 in Windows
- Configurable in Developer Settings
- Add Commit Data to Info.plist
## 0.3.3
- Disable Asset Caching support with spoofless approach
- Switch to Minimal or higher if required
## 0.3.2
- Implement spoofless support (ie. no SMBIOS patching)
- Requires macOS 11.3 or newer, for 11.2.3 and older use Minimal or higher spoofing

6
OpenCore-Patcher-GUI.command Executable file
View File

@@ -0,0 +1,6 @@
#!/usr/bin/env python3
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
from resources import main
if __name__ == '__main__':
main.OpenCoreLegacyPatcher(True)

55
OpenCore-Patcher-GUI.spec Normal file
View File

@@ -0,0 +1,55 @@
# -*- mode: python ; coding: utf-8 -*-
import sys, os, time, subprocess
sys.path.append(os.path.abspath(os.getcwd()))
from resources import constants
block_cipher = None
a = Analysis(['OpenCore-Patcher-GUI.command'],
pathex=['resources', 'data', 'gui'],
binaries=[],
datas=[('payloads', 'payloads')],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='OpenCore-Patcher',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
app = BUNDLE(exe,
name='OpenCore-Patcher.app',
icon="payloads/OC-Patcher.icns",
bundle_identifier="com.dortania.opencore-legacy-patcher-wxpython",
info_plist={
"CFBundleShortVersionString": constants.Constants().patcher_version,
"NSHumanReadableCopyright": "Copyright 2020-2022 Dortania",
"LSMinimumSystemVersion": "10.10.0",
"NSRequiresAquaSystemAppearance": False,
"NSHighResolutionCapable": True,
"Build Date": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
"BuildMachineOSBuild": subprocess.run("sw_vers -buildVersion".split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.decode().strip(),
})

View File

@@ -1,92 +1,6 @@
#!/usr/bin/env python3
# Copyright (C) 2020-2021, Dhinak G, Mykola Grymalyuk
from __future__ import print_function
import subprocess
import sys
from pathlib import Path
from resources import build, cli_menu, constants, utilities, device_probe, os_probe, defaults, arguments, install
from data import model_array
class OpenCoreLegacyPatcher:
def __init__(self):
print("- Loading...")
self.constants = constants.Constants()
self.generate_base_data()
if utilities.check_cli_args() is None:
self.main_menu()
def generate_base_data(self):
self.constants.detected_os = os_probe.detect_kernel_major()
self.constants.detected_os_minor = os_probe.detect_kernel_minor()
self.constants.detected_os_build = os_probe.detect_kernel_build()
self.constants.computer = device_probe.Computer.probe()
self.constants.recovery_status = utilities.check_recovery()
self.computer = self.constants.computer
defaults.generate_defaults.probe(self.computer.real_model, True, self.constants)
if utilities.check_cli_args() is not None:
print("- Detected arguments, switching to CLI mode")
self.constants.gui_mode = True # Assumes no user interaction is required
self.constants.current_path = Path.cwd()
if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"):
print("- Rerouting payloads location")
self.constants.payload_path = sys._MEIPASS / Path("payloads")
arguments.arguments().parse_arguments(self.constants)
else:
print("- No arguments present, loading TUI")
def main_menu(self):
response = None
while not (response and response == -1):
title = [
f"OpenCore Legacy Patcher v{self.constants.patcher_version}",
f"Selected Model: {self.constants.custom_model or self.computer.real_model}",
]
if (self.constants.custom_model or self.computer.real_model) not in model_array.SupportedSMBIOS and self.constants.allow_oc_everywhere is False:
in_between = [
"Your model is not supported by this patcher for running unsupported OSes!",
"",
'If you plan to create the USB for another machine, please select the \n"Change Model" option in the menu.',
"",
'If you want to run OCLP on a native Mac, please toggle \n"Allow OpenCore on native Models" in settings',
]
elif not self.constants.custom_model and self.computer.real_model == "iMac7,1" and "SSE4.1" not in self.computer.cpu.flags:
in_between = [
"Your model requires a CPU upgrade to a CPU supporting SSE4.1+ to be supported by this patcher!",
"",
f'If you plan to create the USB for another {self.computer.real_model} with SSE4.1+, please select the "Change Model" option in the menu.',
]
elif self.constants.custom_model == "iMac7,1":
in_between = ["This model is supported", "However please ensure the CPU has been upgraded to support SSE4.1+"]
else:
in_between = ["This model is supported"]
menu = utilities.TUIMenu(title, "Please select an option: ", in_between=in_between, auto_number=True, top_level=True)
options = (
[["Build OpenCore", build.BuildOpenCore(self.constants.custom_model or self.constants.computer.real_model, self.constants).build_opencore]]
if ((self.constants.custom_model or self.computer.real_model) in model_array.SupportedSMBIOS) or self.constants.allow_oc_everywhere is True
else []
) + [
["Install OpenCore to USB/internal drive", install.tui_disk_installation(self.constants).copy_efi],
["Post-Install Volume Patch", cli_menu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).PatchVolume],
["Change Model", cli_menu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).change_model],
["Patcher Settings", cli_menu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).patcher_settings],
["Installer Creation", cli_menu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).download_macOS],
["Credits", cli_menu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).credits],
]
for option in options:
menu.add_menu_option(option[0], function=option[1])
response = menu.start()
if getattr(sys, "frozen", False) and self.constants.recovery_status is False:
subprocess.run("""osascript -e 'tell application "Terminal" to close first window' & exit""", shell=True)
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
from resources import main
if __name__ == '__main__':
OpenCoreLegacyPatcher()
main.OpenCoreLegacyPatcher()

View File

@@ -12,7 +12,7 @@ a = Analysis(['OpenCore-Patcher.command'],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
excludes=['wxPython', 'wxpython'],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
@@ -40,5 +40,5 @@ app = BUNDLE(exe,
info_plist={
"CFBundleShortVersionString": constants.Constants().patcher_version,
"CFBundleExecutable": "MacOS/Launcher",
"NSHumanReadableCopyright": "Copyright 2020-2021 Dortania"
"NSHumanReadableCopyright": "Copyright 2020-2022 Dortania"
})

View File

@@ -3,7 +3,7 @@
<h1>OpenCore Legacy Patcher</h1>
</div>
A python program with an [Objective-C GUI](https://github.com/dortania/OCLP-GUI) for building and booting [OpenCore](https://github.com/acidanthera/OpenCorePkg) on both legacy and modern Macs, see our in-depth [Guide](https://dortania.github.io/OpenCore-Legacy-Patcher/) for more information.
A python program for building and booting [OpenCore](https://github.com/acidanthera/OpenCorePkg) on both legacy and modern Macs, see our in-depth [Guide](https://dortania.github.io/OpenCore-Legacy-Patcher/) for more information.
Supported features:

View File

@@ -4,9 +4,10 @@ OpenCore Legacy Patcher at its core is a python-based TUI/CLI based application.
For developers wishing to validate mainline changes, you may use these nightly links:
* [GUI (Graphical Based App)](https://nightly.link/dortania/OpenCore-Legacy-Patcher/workflows/build-gui/main/OpenCore-Patcher-GUI.app.zip)
* [GUI (Graphical Based App)](https://nightly.link/dortania/OpenCore-Legacy-Patcher/workflows/build-app-wxpython/main/OpenCore-Patcher.app%20%28GUI%29.zip)
* [GUI (Graphical Based App) - Offline Variant](https://nightly.link/dortania/OpenCore-Legacy-Patcher/workflows/build-app-wxpython-offline/main/OpenCore-Patcher.app%20%28GUI%20Offline%29.zip)
* [TUI (Text Based App)](https://nightly.link/dortania/OpenCore-Legacy-Patcher/workflows/build-app/main/OpenCore-Patcher-TUI.app.zip)
* [TUI (Text Based App) - Offline Variant](https://nightly.link/dortania/OpenCore-Legacy-Patcher/workflows/build-app/main/OpenCore-Patcher-TUI-Offline.app.zip)
* [TUI (Text Based App) - Offline Variant](https://nightly.link/dortania/OpenCore-Legacy-Patcher/workflows/build-app-offline/main/OpenCore-Patcher-TUI.app%20%28Offline%29.zip)
**Warning**: These binaries should not be used without first consulting the [CHANGELOG](./CHANGELOG.md). Do not distribute these links in forums, instead direct to this file.
@@ -36,12 +37,19 @@ pip3 install -r requirements.txt
To run the project from source, simply invoke via python3:
```sh
# Launch TUI
python3 OpenCore-Patcher.command
```
```sh
# Launch GUI
python3 OpenCore-Patcher-GUI.command
```
Note that the OpenCore-Patcher.command file can be run as both a TUI and a CLI utility for other programs to call. If no core arguments are passed, the TUI is initialized. Otherwise the CLI will start:
```sh
# Launch CLI
python3 OpenCore-Patcher.command --build --model iMac12,2 --verbose
```
@@ -49,7 +57,7 @@ See `-h`/`--help` for more information on supported CLI arguments.
## Generating prebuilt binaries
The main goal of generating prebuilt binaries is to strip the requirement of a local python installation for users. For developers, there's very little benefit besides for usage with the project's GUI ([Generating the GUI](#generating-the-gui)). For development, simply use the OpenCore-Patcher.command file with a python3 installation.
The main goal of generating prebuilt binaries is to strip the requirement of a local python installation for users. For developers, there's very little benefit besides enabling dark mode support in the GUI. For development, simply use the OpenCore-Patcher.command file with a python3 installation.
* Note that due to PyInstaller's linking mechanism, binaries generated on Catalina and newer are not compatible with High Sierra and older
* To ensure the largest compatibility, generate binaries on macOS Mojave. These binaries will be compatible with macOS 10.9 to macOS 12.
@@ -60,9 +68,9 @@ The main goal of generating prebuilt binaries is to strip the requirement of a l
pip3 install pyinstaller
# Move into project directory
cd ~/Developer/OpenCore-Legacy-Patcher/
# Create the pyinstaller based Application
# Create the pyinstaller based Application (replace OpenCore-Patcher.spec with OpenCore-Patcher-GUI.spec for GUI binary)
pyinstaller OpenCore-Patcher.spec
# Post PyInstaller clean up
# Post PyInstaller clean up (only for the TUI)
./after_pyinstaller.sh
# Open build folder
open ./dist/
@@ -70,25 +78,4 @@ open ./dist/
Once done, you'll find the application generated at `./dist/OpenCore-Patcher.app`:
![](./images/build-dist.png)
## Generating the GUI
To generate a GUI, you will have need a core `OpenCore-Patcher` binary generated during the above stage([Generating prebuilt binaries](#generating-prebuilt-binaries)).
Once conditions are met, you'll be able to work with the GUI portion. The source of which is found at [dortania/OCLP-GUI](https://github.com/dortania/OCLP-GUI).
```sh
# Move into a directory to store the project
cd ~/Developer
# Clone project
git clone https://github.com/dortania/OCLP-GUI
# Update the OpenCore-Patcher binary from the core project
cp ./OpenCore-Legacy-Patcher/dist/OpenCore-Patcher ./OCLP-GUI/OpenCore\ Patcher/OpenCore\ Patcher/
# Rename binary to OCLP-CLI
mv ./OCLP-GUI/OpenCore\ Patcher/OpenCore\ Patcher/OCLP-GUI/OpenCore-Patcher ./OCLP-GUI/OpenCore\ Patcher/OpenCore\ Patcher/OCLP-GUI/OCLP-CLI
# Build project
cd ./OCLP-GUI/OpenCore\ Patcher; xcodebuild; cd ../../
# Open build folder
open ./OCLP-GUI/OpenCore\ Patcher/build/Release/
```
![](./images/build-dist.png)

View File

@@ -1,8 +1,8 @@
# Data for SkyLightShim Plugin systems
class shim_list:
shim_pathing = {
"CoreWLAN.dylib": "/Systen/Library/CoreServices/WiFiAgent.app/Contents/MacOS/WiFiAgent",
"BacklightFixup.dylib": "/System/Library/CoreServices/loginwindow.app/Contents/Mac0S/loginwindow",
"CoreWLAN.dylib": "/System/Library/CoreServices/WiFiAgent.app/Contents/MacOS/WiFiAgent",
"BacklightFixup.dylib": "/System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow",
}
shim_legacy_accel = [

View File

@@ -179,6 +179,31 @@ class iMac:
opencore_version=None,
)
iMac151_Stock = device_probe.Computer(
real_model='iMac15,1',
real_board_id='Mac-42FD25EABCABB274',
reported_model='iMac15,1', reported_board_id='Mac-42FD25EABCABB274',
gpus=[
device_probe.Intel(vendor_id=32902, device_id=1042, class_code=196608, name='IGPU', model='Intel Iris Pro', acpi_path=None, pci_path='PciRoot(0x0)/Pci(0x2,0x0)'),
device_probe.AMD(vendor_id=4098, device_id=26640, class_code=196608, name='GFX0', model='AMD Radeon R9 M290X', acpi_path=None, pci_path='PciRoot(0x0)/Pci(0x1,0x0)/Pci(0x0,0x0)')
],
igpu=device_probe.Intel(vendor_id=32902, device_id=1042, class_code=196608, name='IGPU', model='Intel Iris Pro', acpi_path=None, pci_path='PciRoot(0x0)/Pci(0x2,0x0)'),
dgpu=device_probe.AMD(vendor_id=4098, device_id=26640, class_code=196608, name='GFX0', model='AMD Radeon R9 M290X', acpi_path=None, pci_path='PciRoot(0x0)/Pci(0x1,0x0)/Pci(0x0,0x0)'),
storage=[
device_probe.SATAController(vendor_id=32902, device_id=35842, class_code=67073, name='SATA', model=None, acpi_path=None, pci_path='PciRoot(0x0)/Pci(0x1f,0x2)'),
device_probe.SATAController(vendor_id=6987, device_id=37251, class_code=67073, name='SSD0', model=None, acpi_path=None, pci_path='PciRoot(0x0)/Pci(0x1c,0x0)/Pci(0x0,0x0)')
],
wifi=device_probe.Broadcom(vendor_id=5348, device_id=17312, class_code=163840, name='ARPT', model=None, acpi_path=None, pci_path='PciRoot(0x0)/Pci(0x1c,0x2)/Pci(0x0,0x0)'),
cpu=device_probe.CPU(
name='Intel(R) Core(TM) i5-4690 CPU @ 3.50GHz',
flags=['FPU', 'VME', 'DE', 'PSE', 'TSC', 'MSR', 'PAE', 'MCE', 'CX8', 'APIC', 'SEP', 'MTRR', 'PGE', 'MCA', 'CMOV', 'PAT', 'PSE36', 'CLFSH', 'DS', 'ACPI', 'MMX', 'FXSR', 'SSE', 'SSE2', 'SS', 'HTT', 'TM', 'PBE', 'SSE3', 'PCLMULQDQ', 'DTES64', 'MON', 'DSCPL', 'VMX', 'SMX', 'EST', 'TM2', 'SSSE3', 'FMA', 'CX16', 'TPR', 'PDCM', 'SSE4.1', 'SSE4.2', 'x2APIC', 'MOVBE', 'POPCNT', 'AES', 'PCID', 'XSAVE', 'OSXSAVE', 'SEGLIM64', 'TSCTMR', 'AVX1.0', 'RDRAND', 'F16C']
),
oclp_version=None,
opencore_version=None,
bluetooth_chipset='BRCM20702 Hub',
third_party_sata_ssd=False
)
class MacPro:
MacPro31_Stock = device_probe.Computer(

View File

@@ -1,5 +1,5 @@
# Lists all models and required patches
# Copyright (C) 2020-2021, Dhinak G, Mykola Grymalyuk
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
SupportedSMBIOS = [
# MacBook
"MacBook4,1",

View File

@@ -1,3 +1,4 @@
from data import os_data
class system_integrity_protection:
csr_values = {
# Source: macOS 11.4 (XNU's csr.h)
@@ -17,6 +18,101 @@ class system_integrity_protection:
"CSR_ALLOW_UNAUTHENTICATED_ROOT": False, # 0x800 - Allow Root Volume Mounting - Introduced in Big Sur # noqa: E241
}
csr_values_extended = {
"CSR_ALLOW_UNTRUSTED_KEXTS": {
"name": "CSR_ALLOW_UNTRUSTED_KEXTS",
"description": "Allows Unsigned Kexts",
"introduced": os_data.os_data.el_capitan.value,
"introduced_friendly": "El Capitan",
"value": 0x1,
},
"CSR_ALLOW_UNRESTRICTED_FS": {
"name": "CSR_ALLOW_UNRESTRICTED_FS",
"description": "File System Access",
"introduced": os_data.os_data.el_capitan.value,
"introduced_friendly": "El Capitan",
"value": 0x2,
},
"CSR_ALLOW_TASK_FOR_PID": {
"name": "CSR_ALLOW_TASK_FOR_PID",
"description": "Unrestricted task_for_pid()",
"introduced": os_data.os_data.el_capitan.value,
"introduced_friendly": "El Capitan",
"value": 0x4,
},
"CSR_ALLOW_KERNEL_DEBUGGER": {
"name": "CSR_ALLOW_KERNEL_DEBUGGER",
"description": "Allow Kernel Debugger",
"introduced": os_data.os_data.el_capitan.value,
"introduced_friendly": "El Capitan",
"value": 0x8,
},
"CSR_ALLOW_APPLE_INTERNAL": {
"name": "CSR_ALLOW_APPLE_INTERNAL",
"description": "Set AppleInternal Features",
"introduced": os_data.os_data.el_capitan.value,
"introduced_friendly": "El Capitan",
"value": 0x10,
},
# "CSR_ALLOW_DESTRUCTIVE_DTRACE": {
# "name": "CSR_ALLOW_DESTRUCTIVE_DTRACE",
# "description": "Allow destructive DTrace",
# "deprecated": True,
# "introduced": os_data.os_data.el_capitan.value,
# "introduced_friendly": "El Capitan",
# "value": 0x20,
# },
"CSR_ALLOW_UNRESTRICTED_DTRACE": {
"name": "CSR_ALLOW_UNRESTRICTED_DTRACE",
"description": "Unrestricted DTrace usage",
"introduced": os_data.os_data.el_capitan.value,
"introduced_friendly": "El Capitan",
"value": 0x20,
},
"CSR_ALLOW_UNRESTRICTED_NVRAM": {
"name": "CSR_ALLOW_UNRESTRICTED_NVRAM",
"description": "Unrestricted NVRAM write",
"introduced": os_data.os_data.el_capitan.value,
"introduced_friendly": "El Capitan",
"value": 0x40,
},
"CSR_ALLOW_DEVICE_CONFIGURATION": {
"name": "CSR_ALLOW_DEVICE_CONFIGURATION",
"description": "Allow custom DeviceTree (iOS)",
"introduced": os_data.os_data.el_capitan.value,
"introduced_friendly": "El Capitan",
"value": 0x80,
},
"CSR_ALLOW_ANY_RECOVERY_OS": {
"name": "CSR_ALLOW_ANY_RECOVERY_OS",
"description": "Skip BaseSystem Verification",
"introduced": os_data.os_data.sierra.value,
"introduced_friendly": "Sierra",
"value": 0x100,
},
"CSR_ALLOW_UNAPPROVED_KEXTS": {
"name": "CSR_ALLOW_UNAPPROVED_KEXTS",
"description": "Allow Unnotarized Kexts",
"introduced": os_data.os_data.high_sierra.value,
"introduced_friendly": "High Sierra",
"value": 0x200,
},
"CSR_ALLOW_EXECUTABLE_POLICY_OVERRIDE": {
"name": "CSR_ALLOW_EXECUTABLE_POLICY_OVERRIDE",
"description": "Override Executable Policy",
"introduced": os_data.os_data.mojave.value,
"introduced_friendly": "Mojave",
"value": 0x400,
},
"CSR_ALLOW_UNAUTHENTICATED_ROOT": {
"name": "CSR_ALLOW_UNAUTHENTICATED_ROOT",
"description": "Allow Root Volume Mounting",
"introduced": os_data.os_data.big_sur.value,
"introduced_friendly": "Big Sur",
"value": 0x800,
},
}
root_patch_sip_mojave = [
# Variables required to root patch in Mojave and Catalina
"CSR_ALLOW_UNTRUSTED_KEXTS", # 0x1

View File

@@ -2803,6 +2803,28 @@ smbios_dictionary = {
"Stock GPUs": [],
"Stock Storage": [],
},
"VMware7,1": {
# VMware Virtual Machine
"Board ID": "440BX Desktop Reference Platform",
"FirmwareFeatures": None,
"CPU Generation": cpu_data.cpu_data.penryn.value,
"Max OS Supported": os_data.os_data.max_os,
"Wireless Model": None,
"Bluetooth Model": bluetooth_data.bluetooth_data.NonApplicable,
"Stock GPUs": [],
"Stock Storage": [],
},
"Parallels17,1": {
# Parallels Virtual Machine
"Board ID": "Parallels Virtual Platform",
"FirmwareFeatures": None,
"CPU Generation": cpu_data.cpu_data.penryn.value,
"Max OS Supported": os_data.os_data.max_os,
"Wireless Model": None,
"Bluetooth Model": bluetooth_data.bluetooth_data.NonApplicable,
"Stock GPUs": [],
"Stock Storage": [],
},
"iBridge2,11": {
# Unknown ID, Intel based, present in Monterey
"Board ID": None,

View File

@@ -18,4 +18,8 @@ After plenty of verbose booting, you will reach the installer screen! From there
* [OpenCore Legacy Patcher Boot Process](https://www.youtube.com/watch?v=AN3zsbQV_n4)
**MacBookPro11,3 Note**: When booting macOS Monterey, you'll need to boot into safe mode if acceleration patches are not installed yet. [Otherwise you'll hit a black screen due to missing Nvidia drivers.](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/522)
* Safe Mode can be started by holding Shift+Enter when selecting macOS Monterey in OCLP's Boot Menu.
# Once installed and booting, head to [Post-Installation](./POST-INSTALL.md)

View File

@@ -2,35 +2,27 @@
Now that we have a macOS installer, lets now build our OpenCore configuration!
First Download the latest release:
If you haven't downloaded OpenCore Patcher yet, do so now:
* [OpenCore Legacy Patcher Releases](https://github.com/dortania/Opencore-Legacy-Patcher/releases)
Next, run the `OpenCore-Patcher.app`:
![](../images/first-run.png)
![](../images/OCLP-GUI-Main-Menu.png)
From here you have a couple important options:
Here we'll select Build and Install OpenCore and start building:
* Build OpenCore
* Install OpenCore to USB/internal drive
* Change Model
* Patcher Settings
If you're patching for a different machine than you're running, please select "Change Model" and enter the updated SMBIOS. For more advanced users, you may also tweak the patcher's build settings via "Patcher Settings"
Now lets enter "Build OpenCore":
![](../images/build-efi.png)
The process should be quite quick to build, once finished you'll be plopped back to the main menu.
Next lets run `Install OpenCore to USB/internal drive`:
| Select Drive | Select EFI/FAT32 Partition |
| Start Building | Finished Building |
| :--- | :--- |
| ![](../images/disk-start.png) | ![](../images/disk-efi.png) |
| ![](../images/OCLP-GUI-Build-Start.png) | ![OCLP GUI Build Finished](../images/OCLP-GUI-Build-Finished.png) |
Once it finishes building, you'll want to select the Install OpenCore button:
* If you created a macOS USB manually and don't see it listed, make sure it's either formatted as GUID/GPT or has a FAT32 partition for OpenCore to sit on
| Select Drive | Select Partition |
| :--- | :--- |
| ![](../images/OCLP-GUI-EFI-Select-Disk.png) | ![](../images/OCLP-GUI-EFI-Select-Partition.png) |
* If you have issues, please ensure you install OpenCore onto a FAT32 partition to ensure your Mac is able to boot it. You will need to format your drive as GUID/GPT in Disk Utility
# Once finished, head to [Booting OpenCore and macOS](./BOOT.md)

View File

@@ -27,9 +27,16 @@ Current hardware we own:
| Model | CPU | GPU | Owner | Notes |
| :--- | :--- | :--- | :--- | :--- |
| MacBook5,1 | Penryn | 9400M | Mykola | N/A |
| MacBook7,1 | Penryn | GT320M | Dhinak | N/A |
| MacBook7,1 | Penryn | GT320M | Mykola | N/A |
| MacBookPro5,3 | Penryn | 9400M + 9600M | Dhinak | Display's partially broken |
| MacBookPro8,2 | Sandy Bridge | HD3000 | Mykola | Dead dGPU |
| MacPro3,1 | Penryn | GTX 680 | Dhinak | N/A |
| Macmini4,1 | Penryn | GT320M | Dhinak | N/A |
| iMac11,2 | Clarksdale | HD4670 | Mykola | N/A |
| MacPro3,1 | Penryn | HD5770, RX570, GT710 | Mykola | N/A |
Dead Hardware:
| Model | CPU | GPU | Owner | Notes |
| :--- | :--- | :--- | :--- | :--- |
| MacPro3,1 | Penryn | HD5770, RX570, GT710 | Mykola | No longer powers on |
| MacPro4,1 | Westmere | HD7950 | Mykola | Dead Northbridge on CPU Tray |

View File

@@ -7,53 +7,46 @@ This doc is centered around downloading and writing the macOS installer to a USB
* Note: 16GB+ USB will be required for the installer
## Downloading
## Creating the installer
The simplest way to download macOS installs would be to use installinstallmacos:
With OpenCore Legacy Patcher, our new GUI includes a download menu for macOS installers. So to start off, you'll want to grab our app:
```sh
[ ! -d ~/macOS-installer/ ] && mkdir ~/macOS-installer; cd ~/macOS-installer; [ ! -f ~/macOS-installer/installinstallmacos.py ] && curl -O https://raw.githubusercontent.com/munki/macadmin-scripts/main/installinstallmacos.py ; sudo python installinstallmacos.py
```
* [OpenCore Legacy Patcher Release Apps](https://github.com/dortania/OpenCore-Legacy-Patcher/releases)
* Note: On El Capitan (10.11) and older, you'll need to specify a catalog at the end of the command:
For this guide, we'll be using the standard OpenCore-Patcher (GUI).
```
--catalogurl https://swscan.apple.com/content/catalogs/others/index-11-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog
```
Once downloaded, open the app and you should be greeted with this menu:
![](../images/munki.png)
![OCLP GUI Main Menu](../images/OCLP-GUI-Main-Menu.png)
As you can see, we get a nice list of macOS installers. If you need a particular versions of macOS, you can select it by typing the number next to it. For this example we'll choose 10:
First we'll want to select the "Create macOS Installer" button. This will present you with 2 options:
![](../images/munki-process.png)
![](../images/OCLP-GUI-Create-Installer-Menu.png)
This is going to take a while as we're downloading the entire 12GB+ macOS installer.
For this example, we'll assume you'll need an installer. Selecting this option will download Apple's Installer Catalogs and build a list for you to choose:
Once finished, you'll find in your `~/macOS-Installer/` folder a DMG containing the macOS Installer, called `Install_macOS_11.1-20C69.dmg` for example. Mount it and you'll find the installer application.
* Note: We recommend to move the Install macOS.app into the `/Applications` folder, as we'll be executing commands from there.
* Note 2: Running Cmd+Shift+G in Finder will allow you to easily jump to `~/macOS-installer`
| Downloading | Listed Installers |
| :--- | :--- |
| ![OCLP GUI Installer Download Catalog](../images/OCLP-GUI-Installer-Download-Catalog.png) | ![OCLP GUI Installer Download Listed Products](../images/OCLP-GUI-Installer-Download-Listed-Products.png) |
![](../images/munki-done-2.png)
Since the patcher officially supports Big Sur and newer for patching, only those entires will be showen. For ourselves, we'll select 12.1 as that's the latest public release at the time of writing. This will download and install the macOS installer to your applications folder.
![](../images/munki-dmg.png)
| Downloading the Installer | Requesting to install | Finished Installing |
| :--- | :--- | :--- |
| ![OCLP GUI Installer Download Progress](../images/OCLP-GUI-Installer-Download-Progress.png) | ![OCLP GUI Installer Needs Installing](../images/OCLP-GUI-Installer-Needs-Installing.png) | ![OCLP GUI Installer Download Finished](../images/OCLP-GUI-Installer-Download-Finished.png) |
## Building
Once finished, you can proceed to write the installer onto a USB drive.
Now we'll be formatting the USB to prep for both the macOS installer and OpenCore. We'll want to use macOS Extended (HFS+) with a GUID partition map(Using GUID is important for the patcher). This will create two partitions: the main `MyVolume` and a second called `EFI` which is used as a boot partition where your Mac's firmware will check for boot files. `EFI` partitions will be hidden by default, so don't worry if you don't immediately see them.
* Note: The entire USB drive will be formatted
* Note: By default, Disk Utility only shows partitions press Cmd/Win+2 to show all devices (alternatively you can press the View button)
| Select Downloaded Installer | Select disk to format |
| :--- | :--- |
| ![](../images/OCLP-GUI-Installer-Select-Local-Installer.png) | ![](../images/OCLP-GUI-Installer-Format-USB.png) |
![Formatting the USB](../images/format-usb.png)
Next run the `createinstallmedia` command provided by [Apple](https://support.apple.com/en-us/HT201372). Note that the command is made for USB's formatted with the name `MyVolume`:
```sh
sudo /Applications/Install\ macOS\ Big\ Sur.app/Contents/Resources/createinstallmedia --volume /Volumes/MyVolume
```
* Note: You can also replace the `createinstallmedia` path with that of where your installer's located (same idea with the drive name).
![](../images/createinstallmedia.png)
Now the patcher will start the installer flashing!
| Flashing | Success Prompt | Finished Flashing |
| :--- | :--- |
| ![](../images/OCLP-GUI-Installer-Flashing-Process.png) | ![](../images/OCLP-GUI-Installer-Sucess-Prompt.png) | ![](../images/OCLP-GUI-Installer-Finished-Script.png) |
# Once finished, head to [Building and installing OpenCore](./BUILD.md)

View File

@@ -20,4 +20,4 @@ This patcher is made of multiple external applications from different people and
* [VMM Patch Set](https://github.com/dortania/OpenCore-Legacy-Patcher/blob/4a8f61a01da72b38a4b2250386cc4b497a31a839/payloads/Config/config.plist#L1222-L1281) - parrotgeek1
* Apple Binaries - Apple Inc.
Remaining files within OpenCore Legacy Patcher are copyrighted 2020-2021 Mykola Grymalyuk & Dhinak G. For integration into other projects, please request written permission.
Remaining files within OpenCore Legacy Patcher are copyrighted 2020-2022 Mykola Grymalyuk & Dhinak G. For integration into other projects, please request written permission.

View File

@@ -123,7 +123,7 @@ Regarding OS support, see below:
| iMac14,2 | ^^ | ^^ | ^^ |
| iMac14,3 | ^^ | ^^ | ^^ |
| iMac14,4 | Mid-2014 | ^^ | ^^ |
| iMac15,1 | Late 2014, Mid-2015 | ^^ | [Display will output to 4k instead of 5k](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/359) |
| iMac15,1 | Late 2014, Mid-2015 | ^^ | ^^ |
* For iMac10,1 through iMac12,x, we highly recommend users upgrade the GPU to a Metal supported model. See here for more information: [iMac late 2009 to mid-2011 Graphics Card Upgrade Guide](https://forums.macrumors.com/threads/2011-imac-graphics-card-upgrade.1596614/?post=17425857#post-17425857)

View File

@@ -15,10 +15,19 @@ With Monterey, Apple continues their their somewhat ruthless march of dropping I
* MacBookPro11,2
* MacBookPro11,3
All of these models now have support in OpenCore Legacy Patcher. Note iMac15,1 does have [an unfortunate firmware bug preventing resolutions above 4k](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/359) with OpenCore Legacy Patcher
All of these models now have support in OpenCore Legacy Patcher.
## Previously Broken Hardware
::: details iMac15,1 5K Display Output Issue (Resolved in 0.3.2 and newer)
* Documentation:
* [5K iMac and UEFI: Fixing the dreaded output limitation](https://khronokernel.github.io/macos/2021/12/08/5K-UEFI.html)
* Associated Github Issue:
* [5k Output issues on iMac15,1 (27" 5k iMac - 2014) #359](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/359)
:::
::: details macOS 12.0 Beta 4 issue on 2012 to early 2013 machines (Resolved in 0.2.5 and newer)
Currently in macOS 12.0 Beta 4, many Ivy Bridge Macs have experienced Bluetooth issues relating to their BCM20702 chipset. Currently the exact issue is unknown however is assumed to be a bug on Apple's end. Recommend downgrading to macOS 12.0 Beta 3 till resolved:

View File

@@ -16,5 +16,5 @@ features:
details: Install updates the moment they come out just like on a supported Mac, and no more 12GB+ updates.
- title: Zero firmware patching
details: No need to patch APFS ROM support, all protocol upgrades are done in memory and never permanent.
footer: Copyright © Dortania 2020-2021
footer: Copyright © Dortania 2020-2022
---

View File

@@ -12,6 +12,7 @@ Here are some common errors users may experience while using this patcher:
* [No Brightness Control](#no-brightness-control)
* [Cannot connect Wi-Fi on Monterey with legacy cards](#cannot-connect-Wi-Fi-on-Monterey-with-legacy-cards)
* [No Graphics Acceleration on Intel Ivy Bridge and Nvidia Kepler GPUs](#no-graphics-acceleration-on-intel-ivy-bridge-and-nvidia-kepler-gpus)
* [Black Screen on MacBookPro11,3 in macOS Monterey](#black-screen-on-macbookpro113-in-macos-monterey)
## Stuck on `This version of Mac OS X is not supported on this platform`
@@ -81,4 +82,10 @@ To work-around, we recommend users to manually connect using the "other" option
With macOS Monterey, Apple removed Graphics Drivers for both Intel Ivy Bride and Nvidia Kepler. To re-enable acceleration, simply run the Post Install Root Volume patches.
Once rebooted, acceleration will be re-enabled as well as brightness control for laptops.
Once rebooted, acceleration will be re-enabled as well as brightness control for laptops.
## Black Screen on MacBookPro11,3 in macOS Monterey
Due to Apple dropping Nvidia Kepler support in macOS Monterey, [MacBookPro11,3's GMUX has difficulties switching back to the iGPU to display macOS correctly.](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/522) To work-around this issue, boot the MacBookPro11,3 in Safe Mode and once macOS is installed, run OCLP's Post Install Root Patches to enable GPU Acceleration for the Nvidia dGPU.
* Safe Mode can be started by holding Shift+Enter when selecting macOS Monterey in OCLP's Boot Menu.

View File

@@ -6,15 +6,19 @@ To install UEFI is actually super simple! All it requires is to boot Windows' In
* Note: UEFI Windows is generally quite usable for Arrendale and newer models, however machines with Penryn CPUs may experience issues
* Recommended Models:
* MacBookAir4,x and newer
* MacBookPro8,x and newer
* Macmini5,x and newer
* iMac11,x and newer
* MacPro4,1 and newer
* Xserve3,1 and newer
* MacBookAir4,x - 5,x
* MacBookPro8,x - 10,x
* Macmini5,x - 6,x
* iMac11,x - 13,x
Once you know your model is supported, you're good to go with the rest of this guide
* Newer models than listed here will already natively support UEFI Windows through Boot Camp
For MacPro4,1/5,1 and Xserve3,1 users, please be aware that Windows has troubles with automatic installation, so please refer to cdf's guide on manual installation:
* [cdf's Mac Pro Thread](https://forums.macrumors.com/threads/opencore-on-the-mac-pro.2207814/)
## Disk Formatting
To start off, we'll need the following:

2483
gui/gui_main.py Normal file

File diff suppressed because it is too large Load Diff

43
gui/menu_redirect.py Normal file
View File

@@ -0,0 +1,43 @@
import wx
import time
class RedirectText(object):
def __init__(self,aWxTextCtrl, sleep):
self.out=aWxTextCtrl
self.sleep = sleep
def write(self,string):
self.out.WriteText(string)
wx.GetApp().Yield()
if self.sleep:
time.sleep(0.01)
def fileno(self):
return 1
def flush(self):
pass
class RedirectLabel(object):
def __init__(self,aWxTextCtrl):
self.out=aWxTextCtrl
def write(self,string):
if string.endswith("MB/s"):
self.out.SetLabel(string)
self.out.Centre(wx.HORIZONTAL)
wx.GetApp().Yield()
time.sleep(0.01)
def flush(self):
pass
class RedirectLabelAll(object):
def __init__(self,aWxTextCtrl):
self.out=aWxTextCtrl
def write(self,string):
self.out.SetLabel(string)
self.out.Centre(wx.HORIZONTAL)
wx.GetApp().Yield()
time.sleep(0.01)

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

View File

@@ -1,10 +0,0 @@
# Updates build version in OCLP-GUI during CI builds
# Copyright (C) 2021 Mykola Grymalyuk
import plistlib
from pathlib import Path
from resources import constants
app_path = Path.cwd() / Path ("OpenCore Patcher.app/Contents/Info.plist")
info = plistlib.load(Path(app_path).open("rb"))
info["CFBundleShortVersionString"] = constants.Constants().patcher_version
plistlib.dump(info, Path(app_path).open("wb"), sort_keys=True)

View File

@@ -433,7 +433,7 @@
<key>Arch</key>
<string>x86_64</string>
<key>Comment</key>
<string>4331 Wifi Patch</string>
<string>Broadcom Wifi Patch</string>
<key>Enabled</key>
<false/>
<key>MaxKernel</key>
@@ -921,7 +921,7 @@
<key>BundlePath</key>
<string>IOFireWireFamily.kext</string>
<key>Comment</key>
<string></string>
<string>Enable FireWire Rooting #1</string>
<key>Enabled</key>
<false/>
<key>ExecutablePath</key>
@@ -939,7 +939,7 @@
<key>BundlePath</key>
<string>IOFireWireFamily.kext/Contents/PlugIns/AppleFWOHCI.kext</string>
<key>Comment</key>
<string></string>
<string>Enable FireWire Rooting #2</string>
<key>Enabled</key>
<false/>
<key>ExecutablePath</key>
@@ -957,7 +957,7 @@
<key>BundlePath</key>
<string>IOFireWireSBP2.kext</string>
<key>Comment</key>
<string></string>
<string>Enable FireWire Rooting #3</string>
<key>Enabled</key>
<false/>
<key>ExecutablePath</key>
@@ -975,7 +975,7 @@
<key>BundlePath</key>
<string>IOFireWireSerialBusProtocolTransport.kext</string>
<key>Comment</key>
<string></string>
<string>Enable FireWire Rooting #4</string>
<key>Enabled</key>
<false/>
<key>ExecutablePath</key>
@@ -1854,6 +1854,12 @@
<integer>0</integer>
<key>KeySubsequentDelay</key>
<integer>5</integer>
<key>PointerPollMask</key>
<integer>-1</integer>
<key>PointerPollMax</key>
<integer>2</integer>
<key>PointerPollMin</key>
<integer>2</integer>
<key>GraphicsInputMirroring</key>
<false/>
<key>PointerSpeedDiv</key>
@@ -1867,20 +1873,24 @@
<integer>0</integer>
<key>AudioDevice</key>
<string></string>
<key>AudioOut</key>
<integer>0</integer>
<key>AudioOutMask</key>
<integer>1</integer>
<key>AudioSupport</key>
<false/>
<key>MinimumVolume</key>
<integer>20</integer>
<key>DisconnectHda</key>
<false/>
<key>MaximumGain</key>
<integer>-15</integer>
<key>MinimumAssistGain</key>
<integer>-30</integer>
<key>MinimumAudibleGain</key>
<integer>-55</integer>
<key>PlayChime</key>
<string>Disabled</string>
<key>ResetTrafficClass</key>
<false/>
<key>SetupDelay</key>
<integer>0</integer>
<key>VolumeAmplifier</key>
<integer>0</integer>
</dict>
<key>ConnectDrivers</key>
<true/>

Binary file not shown.

Binary file not shown.

View File

@@ -9,7 +9,7 @@
<key>CFBundleExecutable</key>
<string>AppleGraphicsDevicePolicy</string>
<key>CFBundleGetInfoString</key>
<string>6.2.9, Copyright 2008-2021 Apple Inc. All rights reserved.</string>
<string>6.2.9, Copyright 2008-2022 Apple Inc. All rights reserved.</string>
<key>CFBundleIdentifier</key>
<string>com.apple.driver.AppleGraphicsDevicePolicy</string>
<key>CFBundleInfoDictionaryVersion</key>
@@ -190,7 +190,7 @@
<key>LSMinimumSystemVersion</key>
<string>11.3</string>
<key>NSHumanReadableCopyright</key>
<string>6.2.9, Copyright © 2008-2021 Apple Inc. All rights reserved.</string>
<string>6.2.9, Copyright © 2008-2022 Apple Inc. All rights reserved.</string>
<key>OSBundleLibraries</key>
<dict>
<key>com.apple.AppleGraphicsDeviceControl</key>

View File

@@ -9,7 +9,7 @@
<key>CFBundleExecutable</key>
<string>AppleMuxControl</string>
<key>CFBundleGetInfoString</key>
<string>6.2.9, Copyright 2008-2021 Apple Inc. All rights reserved.</string>
<string>6.2.9, Copyright 2008-2022 Apple Inc. All rights reserved.</string>
<key>CFBundleIdentifier</key>
<string>com.apple.driver.AppleMuxControl</string>
<key>CFBundleInfoDictionaryVersion</key>
@@ -390,7 +390,7 @@
<key>LSMinimumSystemVersion</key>
<string>11.3</string>
<key>NSHumanReadableCopyright</key>
<string>6.2.9, Copyright © 2008-2021 Apple Inc. All rights reserved.</string>
<string>6.2.9, Copyright © 2008-2022 Apple Inc. All rights reserved.</string>
<key>OSBundleLibraries</key>
<dict>
<key>com.apple.AppleGraphicsDeviceControl</key>

Binary file not shown.

BIN
payloads/Tools/OCLP-Helper Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
payloads/Tools/ocvalidate-0.7.7 Executable file

Binary file not shown.

54
payloads/binary.py Normal file
View File

@@ -0,0 +1,54 @@
# Handle Misc patching for binaries during commit
# This includes Load Command Patching as well as Info.plist patching
# Copyright (C) 2022 - Mykola Grymalyuk
import sys
import plistlib
from pathlib import Path
def main():
patch_load_command()
patch_info_plist()
def patch_load_command():
# Patches LC_VERSION_MIN_MACOSX in Load Command to report 10.10
#
# By default Pyinstaller will create binaries supporting 10.13+
# However this limitation is entirely arbitrary for our libraries
# and instead we're able to support 10.10 without issues.
#
# To verify set version:
# otool -l ./dist/OpenCore-Patcher.app/Contents/MacOS/OpenCore-Patcher
#
# cmd LC_VERSION_MIN_MACOSX
# cmdsize 16
# version 10.13
# sdk 10.9
print("- Patching LC_VERSION_MIN_MACOSX")
path = './dist/OpenCore-Patcher.app/Contents/MacOS/OpenCore-Patcher'
find = b'\x00\x0D\x0A\x00' # 10.13 (0xA0D)
replace = b'\x00\x0A\x0A\x00' # 10.10 (0xA0A)
with open(path, 'rb') as f:
data = f.read()
data = data.replace(find, replace)
with open(path, 'wb') as f:
f.write(data)
def patch_info_plist():
# Add Commit Data to Info.plist
print("- Updating Info.plist")
argsv = sys.argv
argsv.pop(0)
if argsv:
plist_path = './dist/OpenCore-Patcher.app/Contents/Info.plist'
plist = plistlib.load(Path(plist_path).open("rb"))
print("- Adding Github Dictionary")
plist["Github"] = {
"Branch": argsv[0],
"Commit URL": argsv[1],
"Commit Date": argsv[2],
}
print("- Writing Plist")
plistlib.dump(plist, Path(plist_path).open("wb"), sort_keys=True)
else:
print("- No commit data supplied, skipping")
main()

View File

@@ -1,2 +1,3 @@
requests
pyobjc
pyobjc
wxpython

View File

@@ -1,5 +1,5 @@
# Commands for building the EFI and SMBIOS
# Copyright (C) 2020-2021, Dhinak G, Mykola Grymalyuk
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
from __future__ import print_function
import binascii
@@ -139,18 +139,12 @@ class BuildOpenCore:
# IDE patch
("AppleIntelPIIXATA.kext", self.constants.piixata_version, self.constants.piixata_path, lambda: "PATA" in smbios_data.smbios_dictionary[self.model]["Stock Storage"]),
# Misc
(
"FeatureUnlock.kext",
self.constants.featureunlock_version,
self.constants.featureunlock_path,
lambda: smbios_data.smbios_dictionary[self.model]["CPU Generation"] <= cpu_data.cpu_data.kaby_lake.value,
),
("DebugEnhancer.kext", self.constants.debugenhancer_version, self.constants.debugenhancer_path, lambda: self.constants.kext_debug is True),
("AppleUSBTrackpad.kext", self.constants.apple_trackpad, self.constants.apple_trackpad_path, lambda: self.model in ["MacBook4,1", "MacBook5,2"]),
]:
self.enable_kext(name, version, path, check)
if self.constants.allow_oc_everywhere is False:
if self.constants.allow_oc_everywhere is False or self.constants.allow_native_spoofs is True:
if self.constants.serial_settings == "None":
# Credit to Parrotgeek1 for boot.efi and hv_vmm_present patch sets
# print("- Enabling Board ID exemption patch")
@@ -175,6 +169,14 @@ class BuildOpenCore:
# Required for Lilu in 11.0+
self.config["Kernel"]["Quirks"]["DisableLinkeditJettison"] = True
if smbios_data.smbios_dictionary[self.model]["CPU Generation"] <= cpu_data.cpu_data.kaby_lake.value:
if self.constants.fu_status is True:
# Enable FeatureUnlock.kext
self.enable_kext("FeatureUnlock.kext", self.constants.featureunlock_version, self.constants.featureunlock_path)
if self.constants.fu_arguments is not None:
print(f"- Adding additional FeatureUnlock args: {self.constants.fu_arguments}")
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += self.constants.fu_arguments
if self.model in ["MacBookPro6,1", "MacBookPro6,2", "MacBookPro9,1", "MacBookPro10,1"]:
# Modded RestrictEvents with displaypolicyd blocked to fix dGPU switching
self.enable_kext("RestrictEvents.kext", self.constants.restrictevents_mbp_version, self.constants.restrictevents_mbp_path)
@@ -234,8 +236,14 @@ class BuildOpenCore:
print("- Falling back to -nvmefaspm")
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -nvmefaspm"
if self.get_kext_by_bundle_path("NVMeFix.kext")["Enabled"] is False:
self.enable_kext("NVMeFix.kext", self.constants.nvmefix_version, self.constants.nvmefix_path)
if (controller.vendor_id != 0x144D and controller.device_id != 0xA804 and self.model not in ["MacBookPro13,3", "MacBookPro14,3"]):
# Avoid injecting NVMeFix when a native Apple NVMe drive is present
# Note on 2016-2017 MacBook Pros, 15" devices used a stock Samsung SSD with IONVMeController
# Technically this should be patched based on NVMeFix.kext logic,
# however Apple deemed the SSD unsupported for enhanced performance
# https://github.com/acidanthera/NVMeFix/blob/1.0.9/NVMeFix/NVMeFix.cpp#L220-L225
if self.get_kext_by_bundle_path("NVMeFix.kext")["Enabled"] is False:
self.enable_kext("NVMeFix.kext", self.constants.nvmefix_version, self.constants.nvmefix_path)
if not nvme_devices:
print("- No 3rd Party NVMe drives found")
@@ -376,7 +384,7 @@ class BuildOpenCore:
usb_map_path = Path(self.constants.plist_folder_path) / Path("AppleUSBMaps/Info.plist")
if (
usb_map_path.exists()
and self.constants.allow_oc_everywhere is False
and (self.constants.allow_oc_everywhere is False or self.constants.allow_native_spoofs is True)
and self.model not in ["Xserve2,1", "Dortania1,1"]
and (self.model in model_array.Missing_USB_Map or self.constants.serial_settings in ["Moderate", "Advanced"])
):
@@ -387,7 +395,7 @@ class BuildOpenCore:
self.get_kext_by_bundle_path("USB-Map.kext")["Enabled"] = True
if self.constants.allow_oc_everywhere is False:
if self.constants.serial_settings != "None":
if self.constants.serial_settings != "None":
if self.model == "MacBookPro9,1":
print("- Adding AppleMuxControl Override")
amc_map_path = Path(self.constants.plist_folder_path) / Path("AppleMuxControl/Info.plist")
@@ -470,18 +478,8 @@ class BuildOpenCore:
# Used to enable Audio support for non-standard dGPUs
self.enable_kext("AppleALC.kext", self.constants.applealc_version, self.constants.applealc_path)
def check_firewire(model):
# MacBooks never supported FireWire
# Pre-Thunderbolt MacBook Airs as well
if model.startswith("MacBook"):
return False
elif model.startswith("MacBookAir"):
if smbios_data.smbios_dictionary[self.model]["CPU Generation"] < cpu_data.cpu_data.sandy_bridge.value:
return False
else:
return True
if self.constants.firewire_boot is True and check_firewire(self.model) is True:
if self.constants.firewire_boot is True and generate_smbios.check_firewire(self.model) is True:
# Enable FireWire Boot Support
# Applicable for both native FireWire and Thunderbolt to FireWire adapters
print("- Enabling FireWire Boot Support")
@@ -579,7 +577,7 @@ class BuildOpenCore:
"CAIL,CAIL_DisableVCEPowerGating": 1,
"agdpmod": "pikera",
})
elif self.constants.imac_model == "Legacy GCN":
if self.constants.imac_model == "Legacy GCN":
print("- Adding Legacy GCN Power Gate Patches")
self.config["DeviceProperties"]["Add"][backlight_path].update({
"rebuild-device-tree": 1,
@@ -703,6 +701,9 @@ class BuildOpenCore:
if self.computer.wifi.chipset == device_probe.Broadcom.Chipsets.AirPortBrcm4360:
print("- Fixing Legacy Bluetooth for macOS Monterey")
self.enable_kext("BlueToolFixup.kext", self.constants.bluetool_version, self.constants.bluetool_path)
elif self.computer.bluetooth_chipset == "3rd Party Bluetooth 4.0 Hub":
print("- Detected 3rd Party Chipset")
self.enable_kext("BlueToolFixup.kext", self.constants.bluetool_version, self.constants.bluetool_path)
elif smbios_data.smbios_dictionary[self.model]["Bluetooth Model"] <= bluetooth_data.bluetooth_data.BRCM20702_v1.value:
print("- Fixing Legacy Bluetooth for macOS Monterey")
self.enable_kext("BlueToolFixup.kext", self.constants.bluetool_version, self.constants.bluetool_path)
@@ -761,17 +762,18 @@ class BuildOpenCore:
pass
# ThirdPartDrives Check
for drive in ["SATA 2.5", "SATA 3.5", "mSATA"]:
if drive in smbios_data.smbios_dictionary[self.model]["Stock Storage"]:
if not self.constants.custom_model:
if self.computer.third_party_sata_ssd is True:
if self.constants.allow_3rd_party_drives is True:
for drive in ["SATA 2.5", "SATA 3.5", "mSATA"]:
if drive in smbios_data.smbios_dictionary[self.model]["Stock Storage"]:
if not self.constants.custom_model:
if self.computer.third_party_sata_ssd is True:
print("- Adding SATA Hibernation Patch")
self.config["Kernel"]["Quirks"]["ThirdPartyDrives"] = True
break
else:
print("- Adding SATA Hibernation Patch")
self.config["Kernel"]["Quirks"]["ThirdPartyDrives"] = True
break
else:
print("- Adding SATA Hibernation Patch")
self.config["Kernel"]["Quirks"]["ThirdPartyDrives"] = True
break
# Apple RAID Card check
if not self.constants.custom_model:
@@ -792,7 +794,7 @@ class BuildOpenCore:
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -v"
if self.constants.kext_debug is True:
print("- Enabling DEBUG Kexts")
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -liludbgall"
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -liludbgall liludump=90"
# Disabled due to macOS Monterey crashing shortly after kernel init
# Use DebugEnhancer.kext instead
# self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " msgbuf=1048576"
@@ -889,10 +891,15 @@ class BuildOpenCore:
if self.constants.disable_connectdrivers is True:
print("- Disabling ConnectDrivers")
self.config["UEFI"]["ConnectDrivers"] = False
if self.constants.nvram_write is False:
print("- Disabling Hardware NVRAM Write")
self.config["NVRAM"]["WriteFlash"] = False
if self.get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "Reroute kern.hv_vmm_present patch (1)")["Enabled"] is True:
# Add Content Caching patch
print("- Fixing Content Caching support")
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -allow_assetcache"
if self.get_kext_by_bundle_path("RestrictEvents.kext")["Enabled"] is False:
self.enable_kext("RestrictEvents.kext", self.constants.restrictevents_version, self.constants.restrictevents_path)
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -revasset"
if self.get_kext_by_bundle_path("RestrictEvents.kext")["Enabled"] is False:
# Ensure this is done at the end so all previous RestrictEvents patches are applied
# RestrictEvents and EFICheckDisabler will confilict if both are injected
@@ -903,7 +910,10 @@ class BuildOpenCore:
if self.constants.override_smbios == "Default":
if self.constants.serial_settings != "None":
print("- Setting macOS Monterey Supported SMBIOS")
spoofed_model = generate_smbios.set_smbios_model_spoof(self.model)
if self.constants.allow_native_spoofs is True:
spoofed_model = self.model
else:
spoofed_model = generate_smbios.set_smbios_model_spoof(self.model)
else:
spoofed_model = self.constants.override_smbios
print(f"- Using Model ID: {spoofed_model}")
@@ -914,7 +924,7 @@ class BuildOpenCore:
spoofed_board = ""
self.spoofed_model = spoofed_model
self.spoofed_board = spoofed_board
if self.constants.allow_oc_everywhere is False:
if self.constants.allow_oc_everywhere is False or self.constants.allow_native_spoofs is True:
self.config["#Revision"]["Spoofed-Model"] = f"{self.spoofed_model} - {self.constants.serial_settings}"
# Setup menu
@@ -953,10 +963,7 @@ class BuildOpenCore:
# Update tables
self.config["PlatformInfo"]["UpdateNVRAM"] = True
self.config["PlatformInfo"]["UpdateSMBIOS"] = True
# Updating DataHub breaks hibernation, disabling for time being
# self.config["PlatformInfo"]["UpdateDataHub"] = True
# self.config["UEFI"]["ProtocolOverrides"]["DataHub"] = True
self.config["PlatformInfo"]["UpdateDataHub"] = True
def moderate_serial_patch(self):
if self.constants.custom_cpu_model == 0 or self.constants.custom_cpu_model == 1:
@@ -997,6 +1004,18 @@ class BuildOpenCore:
print("- Using Minimal SMBIOS patching")
self.spoofed_model = self.model
minimal_serial_patch(self)
else:
# Update DataHub to resolve Lilu Race Condition
# macOS Monterey will somtimes not present the boardIdentifier in the DeviceTree on UEFI 1.2 or older Mac,
# Thus resulting in an infitinte loop as Lilu tries to request the Board ID
# To resolve this, set PlatformInfo -> DataHub -> BoardProduct and enable UpdateDataHub
# Note 1: Only apply if system is UEFI 1.2, this is generally Ivy Bridge and older, excluding MacPro6,1
# Note 2: Flipping 'UEFI -> ProtocolOverrides -> DataHub' will break hibernation
if (smbios_data.smbios_dictionary[self.model]["CPU Generation"] <= cpu_data.cpu_data.ivy_bridge.value and self.model != "MacPro6,1"):
print("- Detected UEFI 1.2 or older Mac, updating BoardProduct")
self.config["PlatformInfo"]["DataHub"]["BoardProduct"] = self.spoofed_board
self.config["PlatformInfo"]["UpdateDataHub"] = True
# USB Map and CPUFriend Patching
if (
@@ -1162,7 +1181,7 @@ class BuildOpenCore:
def build_opencore(self):
self.build_efi()
if self.constants.allow_oc_everywhere is False:
if self.constants.allow_oc_everywhere is False or self.constants.allow_native_spoofs is True:
self.set_smbios()
self.cleanup()
self.sign_files()

View File

@@ -1,5 +1,5 @@
# Handle misc CLI menu options
# Copyright (C) 2020-2021, Dhinak G, Mykola Grymalyuk
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
from __future__ import print_function
import sys
@@ -101,17 +101,16 @@ option is for those patching on a different machine or OCLP cannot detect.
utilities.header(["Set SMBIOS Spoof Level"])
print(
"""This section is for setting how OpenCore generates the SMBIOS
Recommended for adanced users who want control how serials are handled
Recommended for advanced users who want control how serials are handled
Valid options:
0. None:\tOnly update FirmwareFeatures
0. None:\tUse stock SMBIOS (VMM Masking)
1. Minimal:\tUse original serials and minimally update SMBIOS
2. Moderate:\tReplace entire SMBIOS but keep original serials
3. Advanced:\tReplace entire SMBIOS and generate new serials
Q. Return to previous menu
Note: For new users we recommend leaving as default(1. Minimal)
"""
)
change_menu = input("Set SMBIOS Spoof Level(ie. 1): ")
@@ -697,6 +696,29 @@ for Windows may prefer to only work with the dGPU and eGPU active.
else:
self.dGPU_switch_support()
def set_3rd_party_drices(self):
utilities.cls()
utilities.header(["Set enhanced 3rd Party SSD Support"])
print(
"""
On SATA-based Macs, Apple restricts enhanced OS support to native
drives. Namely hibernation and TRIM.
This option allows you to disable enhanced support in situations where
TRIM is not ideal.
"""
)
change_menu = input("Set enhanced 3rd Party SSD Support?(y/n/q): ")
if change_menu in {"y", "Y", "yes", "Yes"}:
self.constants.allow_3rd_party_drives = True
elif change_menu in {"n", "N", "no", "No"}:
self.constants.allow_3rd_party_drives = False
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else:
self.set_3rd_party_drices()
def set_software_demux(self):
utilities.cls()
utilities.header(["Set Software Demux"])
@@ -832,7 +854,90 @@ To disable SIP outright, set it to 0xFEF
except ValueError:
print("Invalid input, returning to previous menu")
self.set_custom_sip_value()
def set_fu_settings(self):
utilities.cls()
utilities.header(["Set FeatureUnlock Settings"])
print(
"""
By default OCLP will add a kext called FeatureUnlock to enable
features locked out from older models. Including:
- AirPlay to Mac
- SideCar
- Night Shift
However for systems experiencing memory instability, disabling this
kext can help.
Supported Options:
1. Enable FeatureUnlock and all patches
2. Enable FeatureUnlock and disable AirPlay to Mac and SideCar
3. Disable FeatureUnlock
"""
)
change_menu = input("Set FeatreUnlock (ie. 1): ")
if change_menu == "1":
self.constants.fu_status = True
self.constants.fu_arguments = None
elif change_menu == "2":
self.constants.fu_status = True
self.constants.fu_arguments = " -disable_sidecar_mac"
elif change_menu == "3":
self.constants.fu_status = False
self.constants.fu_arguments = None
else:
print("Invalid input, returning to previous menu")
self.set_fu_settings()
def set_allow_native_spoofs(self):
utilities.cls()
utilities.header(["Allow Native Spoofs"])
print(
"""
By default OCLP will not touch the SMBIOS of native models
to ensure a "stock-like" environment. However for systems that
cannot update their firmware, this option will allow OCLP to
spoof the SMBIOS.
By default VMM is used to spoof the SMBIOS. Minimal and higher are
available however not officially supported.
"""
)
change_menu = input("Allow Native Spoofs?(y/n/q): ")
if change_menu in {"y", "Y", "yes", "Yes"}:
self.constants.allow_native_spoofs = True
elif change_menu in {"n", "N", "no", "No"}:
self.constants.allow_native_spoofs = False
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else:
self.set_allow_native_spoofs()
def set_nvram_write(self):
utilities.cls()
utilities.header(["Set NVRAM Write"])
print(
"""
By default, OpenCore will write NVRAM variables to flash. This is
recommended for majority of systems however for extremely degraded
or fragile systems, you may wish to disable this.
Supported Options:
1. Enable NVRAM Write
2. Disable NVRAM Write
"""
)
change_menu = input("Set NVRAM Write (ie. 1): ")
if change_menu == "1":
self.constants.nvram_write = True
elif change_menu == "2":
self.constants.nvram_write = False
else:
print("Invalid input, returning to previous menu")
self.set_nvram_write()
def credits(self):
utilities.TUIOnlyPrint(
@@ -1007,6 +1112,7 @@ system_profiler SPHardwareDataType | grep 'Model Identifier'
options = [
[f"Set SMBIOS Spoof Level:\tCurrently {self.constants.serial_settings}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).change_serial],
[f"Set SMBIOS Spoof Model:\tCurrently {self.constants.override_smbios}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).set_smbios],
[f"Allow Native Spoofs:\tCurrently {self.constants.allow_native_spoofs}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).set_allow_native_spoofs],
[f"Set Custom name {self.constants.custom_cpu_model_value}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).custom_cpu],
]
@@ -1055,7 +1161,9 @@ system_profiler SPHardwareDataType | grep 'Model Identifier'
[f"Set Hibernation Workaround:\tCurrently {self.constants.disable_connectdrivers}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).set_hibernation_workaround],
[f"Disable Battery Throttling:\tCurrently {self.constants.disable_msr_power_ctl}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).set_battery_throttle],
[f"Set Software Demux:\tCurrently {self.constants.software_demux}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).set_software_demux],
[f"Set 3rd Party SSD Support:\tCurrently {self.constants.allow_3rd_party_drives}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).set_3rd_party_drices],
[f"Set FeatureUnlock: \tCurrently {self.constants.fu_status}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).set_fu_settings],
[f"Set NVRAM Write:\t\tCurrently {self.constants.nvram_write}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).set_nvram_write],
]
for option in options:
@@ -1107,9 +1215,14 @@ B. Exit
self.download_macOS()
def download_install_assistant(self, link):
installer.download_install_assistant(self.constants.payload_path, link)
# To avoid selecting the wrong installer by mistake, let user select the correct one
self.find_local_installer()
if installer.download_install_assistant(self.constants.payload_path, link):
installer.install_macOS_installer(self.constants.payload_path)
input("Press any key to continue...")
# To avoid selecting the wrong installer by mistake, let user select the correct one
self.find_local_installer()
else:
print("Failed to start download")
input("Press any key to continue...")
def download_macOS_installer(self):
@@ -1137,7 +1250,7 @@ B. Exit
avalible_installers = installer.list_local_macOS_installers()
if avalible_installers:
for app in avalible_installers:
options.append([f"{avalible_installers[app]['Short Name']}: {avalible_installers[app]['Version']} ({avalible_installers[app]['Build']})", lambda: self.list_disks(avalible_installers[app]['Path'])])
options.append([f"{avalible_installers[app]['Short Name']}: {avalible_installers[app]['Version']} ({avalible_installers[app]['Build']})", lambda x=app: self.list_disks(avalible_installers[x]['Path'])])
for option in options:
menu.add_menu_option(option[0], function=option[1])
response = menu.start()

View File

@@ -1,6 +1,6 @@
# pylint: disable=multiple-statements
# Define Files
# Copyright (C) 2020-2021, Dhinak G, Mykola Grymalyuk
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
from __future__ import print_function
@@ -14,27 +14,31 @@ from data import os_data
class Constants:
def __init__(self):
# Patcher Versioning
self.patcher_version = "0.3.2" # OpenCore-Legacy-Patcher
self.patcher_support_pkg_version = "0.2.8" # PatcherSupportPkg
self.patcher_version = "0.4.0" # OpenCore-Legacy-Patcher
self.patcher_support_pkg_version = "0.2.9" # PatcherSupportPkg
self.url_patcher_support_pkg = "https://github.com/dortania/PatcherSupportPkg/releases/download/"
self.nightly_url_patcher_support_pkg = "https://nightly.link/dortania/PatcherSupportPkg/workflows/build/master/"
self.discord_link = "https://discord.gg/rqdPgH8xSN"
self.guide_link = "https://dortania.github.io/OpenCore-Legacy-Patcher/"
self.repo_link = "https://github.com/dortania/OpenCore-Legacy-Patcher"
self.repo_link_latest = f"{self.repo_link}/releases/tag/{self.patcher_version}"
# OpenCore Versioning
# https://github.com/acidanthera/OpenCorePkg
self.opencore_commit = "7266ec9 - 12-06-2021"
self.opencore_version = "0.7.6"
self.opencore_commit = "b530a29 - 01-11-2022"
self.opencore_version = "0.7.7"
# Kext Versioning
## Acidanthera
## https://github.com/acidanthera
self.lilu_version = "1.5.8" # Lilu
self.whatevergreen_version = "1.5.5" # WhateverGreen
self.lilu_version = "1.5.9" # Lilu
self.whatevergreen_version = "1.5.6" # WhateverGreen
self.airportbcrmfixup_version = "2.1.3" # AirPortBrcmFixup
self.nvmefix_version = "1.0.9" # NVMeFix
self.applealc_version = "1.6.3" # AppleALC
self.restrictevents_version = "1.0.5" # RestrictEvents
self.restrictevents_mbp_version = "1.0.5" # RestrictEvents blocking displaypolicyd (see RestrictEvents-MBP91.patch)
self.featureunlock_version = "1.0.5" # FeatureUnlock
self.restrictevents_version = "1.0.6" # RestrictEvents
self.restrictevents_mbp_version = "1.0.6" # RestrictEvents blocking displaypolicyd (see RestrictEvents-MBP91.patch)
self.featureunlock_version = "1.0.6" # FeatureUnlock
self.debugenhancer_version = "1.0.4" # DebugEnhancer
self.cpufriend_version = "1.2.4" # CPUFriend
self.bluetool_version = "2.6.1" # BlueToolFixup (BrcmPatchRAM)
@@ -94,6 +98,9 @@ class Constants:
self.patch_disk = "" # Set Root Volume to patch
self.validate = False # Enable validation testing for CI
self.recovery_status = False # Detect if booted into RecoveryOS
self.launcher_binary = None # Determine launch binary (ie. Python vs PyInstaller)
self.launcher_script = None # Determine launch file (if run via Python)
self.ignore_updates = False # Ignore OCLP updates
## Hardware
self.computer: device_probe.Computer = None # type: ignore
@@ -102,8 +109,9 @@ class Constants:
## OpenCore Settings
self.opencore_debug = False
self.opencore_build = "RELEASE"
self.showpicker = True # Show or Hide OpenCore's Boot Picker
self.boot_efi = False # Use EFI/BOOT/BOOTx64.efi bootstrap
self.showpicker = True # Show or Hide OpenCore's Boot Picker
self.boot_efi = False # Use EFI/BOOT/BOOTx64.efi bootstrap
self.nvram_write = True # Write to hardware NVRAM
## Kext Settings
self.kext_debug = False # Enables Lilu debug and DebugEnhancer
@@ -117,6 +125,11 @@ class Constants:
self.custom_cpu_model_value = "" # New CPU name within About This Mac
self.serial_settings = "None" # Set SMBIOS level used
self.override_smbios = "Default" # Set SMBIOS model used
self.allow_native_spoofs = False # Allow native models to recieve spoofs
## FeatureUnlock Settings
self.fu_status = True # Enable FeatureUnlock
self.fu_arguments = None # Set FeatureUnlock arguments
## Latebloom Settings
self.latebloom_status = False # Latebloom Enabled
@@ -157,7 +170,7 @@ class Constants:
self.enable_wake_on_wlan = False # Allow Wake on WLAN for modern Broadcom
self.disable_tb = False # Disable Thunderbolt Controller
self.set_alc_usage = True # Set AppleALC usage
self.dGPU_switch = True # Set Display GPU Switching for Windows
self.dGPU_switch = False # Set Display GPU Switching for Windows
self.force_surplus = False # Force SurPlus patch in newer OSes
self.force_latest_psp = False # Force latest PatcherSupportPkg
self.disable_msr_power_ctl = False # Disable MSR Power Control (missing battery throttling)
@@ -166,6 +179,7 @@ class Constants:
self.custom_sip_value = None # Set custom SIP value
self.walkthrough = False # Enable Walkthrough
self.disable_connectdrivers = False # Disable ConnectDrivers (hibernation)
self.allow_3rd_party_drives = True # Allow ThridPartyDrives quirk
self.legacy_accel_support = [
os_data.os_data.mojave,
@@ -222,6 +236,10 @@ class Constants:
@property
def list_txt_path(self):
return self.payload_path / Path("List.txt")
@property
def installer_sh_path(self):
return self.payload_path / Path("Installer.sh")
# Kexts
@property
@@ -477,6 +495,10 @@ class Constants:
@property
def ocvalidate_path(self):
return self.payload_path / Path(f"Tools/ocvalidate-{self.opencore_version}")
@property
def oclp_helper_path(self):
return self.payload_path / Path("Tools/OCLP-Helper")
# Icons
@property
@@ -529,6 +551,10 @@ class Constants:
def payload_apple_libexec_path(self):
return self.payload_apple_usr_path / Path("libexec")
@property
def payload_apple_application_support(self):
return self.payload_apple_root_path / Path("Application Support")
@property
def payload_apple_private_path(self):
return self.payload_apple_root_path / Path("private")
@@ -651,12 +677,16 @@ class Constants:
return self.payload_apple_libexec_path / Path("Legacy-Wifi")
@property
def legacy_wifi_etc(self):
return self.payload_apple_etc_path / Path("Legacy-Wifi")
def legacy_wifi_support(self):
return self.payload_apple_application_support / Path("Legacy-Wifi")
@property
def legacy_keyboard_backlight_etc(self):
return self.payload_apple_etc_path / Path("Keyboard-Backlight")
def legacy_keyboard_backlight_support(self):
return self.payload_apple_application_support / Path("Keyboard-Backlight")
@property
def legacy_dropbox_support(self):
return self.payload_apple_application_support / Path("Dropbox")
sbm_values = [
"j137ap", # iMacPro1,1

View File

@@ -1,6 +1,6 @@
# Generate Default Data
from resources import utilities, device_probe, generate_smbios
from data import model_array, smbios_data
from data import model_array, smbios_data, cpu_data
class generate_defaults:
@@ -90,6 +90,13 @@ class generate_defaults:
# Users disabling TS2 most likely have a faulty dGPU
# users can override this in settings
settings.allow_ts2_accel = False
if smbios_data.smbios_dictionary[model]["CPU Generation"] < cpu_data.cpu_data.ivy_bridge.value and model != "MacPro5,1":
# Sidecar and AirPlay to Mac only blacklist Ivy and newer (as well as MacPro5,1)
# Avoid extra patching without benefit
settings.fu_arguments = " -disable_sidecar_mac"
else:
settings.fu_arguments = None
# Check if running in RecoveryOS
settings.recovery_status = utilities.check_recovery()
@@ -103,12 +110,15 @@ class generate_defaults:
# Native Macs (mainly M1s) will error out as they don't know what SMBIOS to spoof to
# As we don't spoof on native models, we can safely ignore this
spoof_model = model
if smbios_data.smbios_dictionary[spoof_model]["SecureBootModel"] is not None:
if settings.sip_status is False:
# Force VMM as root patching breaks .im4m signature
settings.secure_status = False
settings.force_vmm = True
else:
# Allow SecureBootModel
settings.secure_status = True
settings.force_vmm = False
try:
if smbios_data.smbios_dictionary[spoof_model]["SecureBootModel"] is not None:
if settings.sip_status is False:
# Force VMM as root patching breaks .im4m signature
settings.secure_status = False
settings.force_vmm = True
else:
# Allow SecureBootModel
settings.secure_status = True
settings.force_vmm = False
except KeyError:
pass

View File

@@ -1,5 +1,5 @@
# Hardware probing
# Copyright (C) 2020-2021, Dhinak G, Mykola Grymalyuk
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
from __future__ import annotations
@@ -453,19 +453,8 @@ class Computer:
controller = NVMeController.from_ioregistry(parent)
controller.aspm = aspm
if (
if controller.vendor_id != 0x106B:
# Handle Apple Vendor ID
controller.vendor_id != 0x106B
and (
# Handle soldered Samsung SSDs
controller.vendor_id != 0x144D and controller.device_id != 0xA804
)
):
# Avoid patching when a native Apple NVMe drive is present
# Note on 2016-2017 MacBook Pros, 15" devices used a stock Samsung SSD with IONVMeController
# Technically this should be patched based on NVMeFix.kext logic,
# however Apple deemed the SSD unsupported for usage with AppleNVMeController class
# https://github.com/acidanthera/NVMeFix/blob/1.0.9/NVMeFix/NVMeFix.cpp#L220-L225
self.storage.append(controller)
ioreg.IOObjectRelease(parent)
@@ -499,13 +488,15 @@ class Computer:
def bluetooth_probe(self):
usb_data: str = subprocess.run("system_profiler SPUSBDataType".split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.decode()
if "BRCM2070 Hub" in usb_data:
if "BRCM20702 Hub" in usb_data:
self.bluetooth_chipset = "BRCM20702 Hub"
elif "BCM20702A0" in usb_data or "BCM2045A0" in usb_data:
self.bluetooth_chipset = "3rd Party Bluetooth 4.0 Hub"
elif "BRCM2070 Hub" in usb_data:
self.bluetooth_chipset = "BRCM2070 Hub"
elif "BRCM2046 Hub" in usb_data:
self.bluetooth_chipset = "BRCM2046 Hub"
elif "BRCM20702 Hub" in usb_data:
self.bluetooth_chipset = "BRCM20702 Hub"
elif "Bluetooth":
elif "Bluetooth" in usb_data:
self.bluetooth_chipset = "Generic"
def sata_disk_probe(self):

View File

@@ -1,4 +1,4 @@
from data import smbios_data, os_data
from data import smbios_data, os_data, cpu_data
from resources import utilities
@@ -71,9 +71,15 @@ def generate_fw_features(model, custom):
firmwarefeature = utilities.get_rom("firmware-features")
if not firmwarefeature:
print("- Failed to find FirmwareFeatures, falling back on defaults")
firmwarefeature = int(smbios_data.smbios_dictionary[model]["FirmwareFeatures"], 16)
if smbios_data.smbios_dictionary[model]["FirmwareFeatures"] is None:
firmwarefeature = 0
else:
firmwarefeature = int(smbios_data.smbios_dictionary[model]["FirmwareFeatures"], 16)
else:
firmwarefeature = int(smbios_data.smbios_dictionary[model]["FirmwareFeatures"], 16)
if smbios_data.smbios_dictionary[model]["FirmwareFeatures"] is None:
firmwarefeature = 0
else:
firmwarefeature = int(smbios_data.smbios_dictionary[model]["FirmwareFeatures"], 16)
firmwarefeature = update_firmware_features(firmwarefeature)
return firmwarefeature
@@ -98,3 +104,16 @@ def find_model_off_board(board):
key = "MacPro5,1"
return key
return None
def check_firewire(model):
# MacBooks never supported FireWire
# Pre-Thunderbolt MacBook Airs as well
if model.startswith("MacBookPro"):
return True
elif model.startswith("MacBookAir"):
if smbios_data.smbios_dictionary[model]["CPU Generation"] < cpu_data.cpu_data.sandy_bridge.value:
return False
elif model.startswith("MacBook"):
return False
else:
return True

View File

@@ -1,6 +1,6 @@
# Installation of OpenCore files to ESP
# Usage soley for TUI
# Copyright (C) 2020-2021, Dhinak G, Mykola Grymalyuk
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
import plistlib
import subprocess
@@ -14,23 +14,7 @@ class tui_disk_installation:
def __init__(self, versions):
self.constants: constants.Constants = versions
def copy_efi(self):
utilities.cls()
utilities.header(["Installing OpenCore to Drive"])
if not self.constants.opencore_release_folder.exists():
utilities.TUIOnlyPrint(
["Installing OpenCore to Drive"],
"Press [Enter] to go back.\n",
[
"""OpenCore folder missing!
Please build OpenCore first!"""
],
).start()
return
print("\nDisk picker is loading...")
def list_disks(self):
all_disks = {}
# TODO: AllDisksAndPartitions is not supported in Snow Leopard and older
try:
@@ -54,7 +38,60 @@ Please build OpenCore first!"""
except KeyError:
# Avoid crashing with CDs installed
continue
# TODO: Advanced mode
supported_disks = {}
for disk in all_disks:
if not any(all_disks[disk]["partitions"][partition]["fs"] in ("msdos", "EFI") for partition in all_disks[disk]["partitions"]):
continue
supported_disks.update({
disk: {
"disk": disk,
"name": all_disks[disk]["name"],
"size": utilities.human_fmt(all_disks[disk]['size']),
"partitions": all_disks[disk]["partitions"]
}
})
return supported_disks
def list_partitions(self, disk_response, supported_disks):
# Takes disk UUID as well as diskutil dataset generated by list_disks
# Returns list of FAT32 partitions
disk_identifier = disk_response
selected_disk = supported_disks[disk_identifier]
supported_partitions = {}
for partition in selected_disk["partitions"]:
if selected_disk["partitions"][partition]["fs"] not in ("msdos", "EFI"):
continue
supported_partitions.update({
partition: {
"partition": partition,
"name": selected_disk["partitions"][partition]["name"],
"size": utilities.human_fmt(selected_disk["partitions"][partition]["size"])
}
})
return supported_partitions
def copy_efi(self):
utilities.cls()
utilities.header(["Installing OpenCore to Drive"])
if not self.constants.opencore_release_folder.exists():
utilities.TUIOnlyPrint(
["Installing OpenCore to Drive"],
"Press [Enter] to go back.\n",
[
"""OpenCore folder missing!
Please build OpenCore first!"""
],
).start()
return
print("\nDisk picker is loading...")
all_disks = self.list_disks()
menu = utilities.TUIMenu(
["Select Disk"],
"Please select the disk you would like to install OpenCore to: ",
@@ -63,9 +100,7 @@ Please build OpenCore first!"""
loop=True,
)
for disk in all_disks:
if not any(all_disks[disk]["partitions"][partition]["fs"] in ("msdos", "EFI") for partition in all_disks[disk]["partitions"]):
continue
menu.add_menu_option(f"{disk}: {all_disks[disk]['name']} ({utilities.human_fmt(all_disks[disk]['size'])})", key=disk[4:])
menu.add_menu_option(f"{disk}: {all_disks[disk]['name']} ({all_disks[disk]['size']})", key=disk[4:])
response = menu.start()
@@ -96,9 +131,9 @@ Please build OpenCore first!"""
if response == -1:
return
self.install_opencore(disk_identifier, response)
self.install_opencore(f"{disk_identifier}s{response}")
def install_opencore(self, disk_identifier, response):
def install_opencore(self, full_disk_identifier):
def determine_sd_card(media_name):
# Array filled with common SD Card names
# Note most USB-based SD Card readers generally report as "Storage Device"
@@ -117,7 +152,7 @@ Please build OpenCore first!"""
args = [
"osascript",
"-e",
f'''do shell script "diskutil mount {disk_identifier}s{response}"'''
f'''do shell script "diskutil mount {full_disk_identifier}"'''
' with prompt "OpenCore Legacy Patcher needs administrator privileges to mount your EFI."'
" with administrator privileges"
" without altering line endings",
@@ -126,7 +161,7 @@ Please build OpenCore first!"""
if self.constants.detected_os >= os_data.os_data.el_capitan and not self.constants.recovery_status:
result = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
else:
result = subprocess.run(f"diskutil mount {disk_identifier}s{response}".split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
result = subprocess.run(f"diskutil mount {full_disk_identifier}".split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if result.returncode != 0:
if "execution error" in result.stderr.decode() and result.stderr.decode().strip()[-5:-1] == "-128":
@@ -137,8 +172,9 @@ Please build OpenCore first!"""
["Copying OpenCore"], "Press [Enter] to go back.\n", ["An error occurred!"] + result.stderr.decode().split("\n") + ["", "Please report this to the devs at GitHub."]
).start()
return
drive_host_info = plistlib.loads(subprocess.run(f"diskutil info -plist {disk_identifier}".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
partition_info = plistlib.loads(subprocess.run(f"diskutil info -plist {disk_identifier}s{response}".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
partition_info = plistlib.loads(subprocess.run(f"diskutil info -plist {full_disk_identifier}".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
parent_disk = partition_info["ParentWholeDisk"]
drive_host_info = plistlib.loads(subprocess.run(f"diskutil info -plist {parent_disk}".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
sd_type = drive_host_info["MediaName"]
try:
ssd_type = drive_host_info["SolidState"]
@@ -150,7 +186,7 @@ Please build OpenCore first!"""
utilities.header(["Copying OpenCore"])
if mount_path.exists():
if (mount_path / Path("EFI/Microsoft")).exists():
if (mount_path / Path("EFI/Microsoft")).exists() and self.constants.gui_mode is False:
print("- Found Windows Boot Loader")
print("\nWould you like to continue installing OpenCore?")
print("Installing OpenCore onto this drive may make Windows unbootable until OpenCore")
@@ -202,8 +238,9 @@ Please build OpenCore first!"""
print("- Unmounting EFI partition")
subprocess.run(["diskutil", "umount", mount_path], stdout=subprocess.PIPE).stdout.decode().strip().encode()
print("- OpenCore transfer complete")
print("\nPress [Enter] to continue.\n")
input()
if self.constants.gui_mode is False:
print("\nPress [Enter] to continue.\n")
input()
else:
utilities.TUIOnlyPrint(["Copying OpenCore"], "Press [Enter] to go back.\n", ["EFI failed to mount!", "Please report this to the devs at GitHub."]).start()

View File

@@ -53,11 +53,29 @@ def create_installer(installer_path, volume_name):
return False
def download_install_assistant(download_path, ia_link):
# Downloads and unpackages InstallAssistant.pkg into /Applications
utilities.download_file(ia_link, (Path(download_path) / Path("InstallAssistant.pkg")))
print("- Installing InstallAssistant.pkg to /Applications/")
utilities.elevated(["installer", "-pkg", (Path(download_path) / Path("InstallAssistant.pkg")), "-target", "/Applications"])
input("- Press ENTER to continue: ")
# Downloads InstallAssistant.pkg
if utilities.download_file(ia_link, (Path(download_path) / Path("InstallAssistant.pkg"))):
return True
return False
def install_macOS_installer(download_path):
args = [
"osascript",
"-e",
f'''do shell script "installer -pkg {Path(download_path)}/InstallAssistant.pkg -target /"'''
' with prompt "OpenCore Legacy Patcher needs administrator privileges to add InstallAssistant."'
" with administrator privileges"
" without altering line endings",
]
result = subprocess.run(args,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if result.returncode == 0:
print("- InstallAssistant installed")
return True
else:
print("- Failed to install InstallAssistant")
print(f" Error Code: {result.returncode}")
return False
def list_downloadable_macOS_installers(download_path, catalog):
avalible_apps = {}
@@ -69,41 +87,41 @@ def list_downloadable_macOS_installers(download_path, catalog):
link = "https://swscan.apple.com/content/catalogs/others/index-12customerseed-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz"
# Download and unzip the catalog
utilities.download_file(link, (Path(download_path) / Path("seed.sucatalog.gz")))
subprocess.run(["gunzip", "-d", "-f", Path(download_path) / Path("seed.sucatalog.gz")])
catalog_plist = plistlib.load((Path(download_path) / Path("seed.sucatalog")).open("rb"))
if utilities.download_file(link, (Path(download_path) / Path("seed.sucatalog.gz"))):
subprocess.run(["gunzip", "-d", "-f", Path(download_path) / Path("seed.sucatalog.gz")])
catalog_plist = plistlib.load((Path(download_path) / Path("seed.sucatalog")).open("rb"))
for item in catalog_plist["Products"]:
try:
# Check if entry has SharedSupport and BuildManifest
# Ensures only Big Sur and newer Installers are listed
catalog_plist["Products"][item]["ExtendedMetaInfo"]["InstallAssistantPackageIdentifiers"]["SharedSupport"]
catalog_plist["Products"][item]["ExtendedMetaInfo"]["InstallAssistantPackageIdentifiers"]["BuildManifest"]
for item in catalog_plist["Products"]:
try:
# Check if entry has SharedSupport and BuildManifest
# Ensures only Big Sur and newer Installers are listed
catalog_plist["Products"][item]["ExtendedMetaInfo"]["InstallAssistantPackageIdentifiers"]["SharedSupport"]
catalog_plist["Products"][item]["ExtendedMetaInfo"]["InstallAssistantPackageIdentifiers"]["BuildManifest"]
for bm_package in catalog_plist["Products"][item]["Packages"]:
if "BuildManifest.plist" in bm_package["URL"]:
utilities.download_file(bm_package["URL"], (Path(download_path) / Path("BuildManifest.plist")))
build_plist = plistlib.load((Path(download_path) / Path("BuildManifest.plist")).open("rb"))
version = build_plist["ProductVersion"]
build = build_plist["ProductBuildVersion"]
for ia_package in catalog_plist["Products"][item]["Packages"]:
if "InstallAssistant.pkg" in ia_package["URL"]:
download_link = ia_package["URL"]
size = ia_package["Size"]
integrity = ia_package["IntegrityDataURL"]
for bm_package in catalog_plist["Products"][item]["Packages"]:
if "BuildManifest.plist" in bm_package["URL"]:
utilities.download_file(bm_package["URL"], (Path(download_path) / Path("BuildManifest.plist")))
build_plist = plistlib.load((Path(download_path) / Path("BuildManifest.plist")).open("rb"))
version = build_plist["ProductVersion"]
build = build_plist["ProductBuildVersion"]
for ia_package in catalog_plist["Products"][item]["Packages"]:
if "InstallAssistant.pkg" in ia_package["URL"]:
download_link = ia_package["URL"]
size = ia_package["Size"]
integrity = ia_package["IntegrityDataURL"]
avalible_apps.update({
item: {
"Version": version,
"Build": build,
"Link": download_link,
"Size": size,
"integrity": integrity,
"Source": "Apple Inc.",
}
})
except KeyError:
pass
avalible_apps.update({
item: {
"Version": version,
"Build": build,
"Link": download_link,
"Size": size,
"integrity": integrity,
"Source": "Apple Inc.",
}
})
except KeyError:
pass
return avalible_apps
def format_drive(disk_id):
@@ -172,4 +190,66 @@ def select_disk_to_format():
if response == -1:
return None
return response
return response
def list_disk_to_format():
all_disks = {}
list_disks = {}
# TODO: AllDisksAndPartitions is not supported in Snow Leopard and older
try:
# High Sierra and newer
disks = plistlib.loads(subprocess.run("diskutil list -plist physical".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
except ValueError:
# Sierra and older
disks = plistlib.loads(subprocess.run("diskutil list -plist".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
for disk in disks["AllDisksAndPartitions"]:
disk_info = plistlib.loads(subprocess.run(f"diskutil info -plist {disk['DeviceIdentifier']}".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
try:
all_disks[disk["DeviceIdentifier"]] = {"identifier": disk_info["DeviceNode"], "name": disk_info["MediaName"], "size": disk_info["TotalSize"], "removable": disk_info["Internal"], "partitions": {}}
except KeyError:
# Avoid crashing with CDs installed
continue
for disk in all_disks:
# Strip disks that are under 14GB (15,032,385,536 bytes)
# createinstallmedia isn't great at detecting if a disk has enough space
if not any(all_disks[disk]['size'] > 15032385536 for partition in all_disks[disk]):
continue
# Strip internal disks as well (avoid user formatting their SSD/HDD)
# Ensure user doesn't format their boot drive
if not any(all_disks[disk]['removable'] is False for partition in all_disks[disk]):
continue
print(f"disk {disk}: {all_disks[disk]['name']} ({utilities.human_fmt(all_disks[disk]['size'])})")
list_disks.update({
disk: {
"identifier": all_disks[disk]["identifier"],
"name": all_disks[disk]["name"],
"size": all_disks[disk]["size"],
}
})
return list_disks
def generate_installer_creation_script(script_location, installer_path, disk):
# Creates installer.sh to be piped to OCLP-Helper and run as admin
# Goals:
# - Format provided disk as HFS+ GPT
# - Run createinstallmedia on provided disk
# Implemnting this into a single installer.sh script allows us to only call
# OCLP-Helper once to avoid nagging the user about permissions
createinstallmedia_path = str(Path(installer_path) / Path("Contents/Resources/createinstallmedia"))
if script_location.exists():
script_location.unlink()
script_location.touch()
with script_location.open("w") as script:
script.write(f'''#!/bin/bash
earse_disk='diskutil eraseDisk HFS+ OCLP-Installer {disk}'
if $earse_disk; then
"{createinstallmedia_path}" --volume /Volumes/OCLP-Installer --nointeraction
fi
''')
return True

View File

@@ -1,5 +1,5 @@
# Handle misc CLI menu options
# Copyright (C) 2020-2021, Dhinak G
# Copyright (C) 2020-2022, Dhinak G
from __future__ import annotations

100
resources/main.py Normal file
View File

@@ -0,0 +1,100 @@
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
from __future__ import print_function
import subprocess
import sys
from pathlib import Path
from resources import build, cli_menu, constants, utilities, device_probe, os_probe, defaults, arguments, install
from data import model_array
class OpenCoreLegacyPatcher:
def __init__(self, launch_gui=False):
print("- Loading...")
self.constants = constants.Constants()
self.generate_base_data()
if utilities.check_cli_args() is None:
if launch_gui is True:
from gui import gui_main
gui_main.wx_python_gui(self.constants)
else:
self.main_menu()
def generate_base_data(self):
self.constants.detected_os = os_probe.detect_kernel_major()
self.constants.detected_os_minor = os_probe.detect_kernel_minor()
self.constants.detected_os_build = os_probe.detect_kernel_build()
self.constants.computer = device_probe.Computer.probe()
self.constants.recovery_status = utilities.check_recovery()
self.computer = self.constants.computer
launcher_script = None
launcher_binary = sys.executable
if "python" in launcher_binary:
# We're running from source
launcher_script = __file__
if "main.py" in launcher_script:
launcher_script = launcher_script.replace("/resources/main.py", "/OpenCore-Patcher-GUI.command")
self.constants.launcher_binary = launcher_binary
self.constants.launcher_script = launcher_script
defaults.generate_defaults.probe(self.computer.real_model, True, self.constants)
if utilities.check_cli_args() is not None:
print("- Detected arguments, switching to CLI mode")
self.constants.gui_mode = True # Assumes no user interaction is required
self.constants.current_path = Path.cwd()
if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"):
print("- Rerouting payloads location")
self.constants.payload_path = sys._MEIPASS / Path("payloads")
arguments.arguments().parse_arguments(self.constants)
else:
print("- No arguments present, loading TUI")
def main_menu(self):
response = None
while not (response and response == -1):
title = [
f"OpenCore Legacy Patcher v{self.constants.patcher_version}",
f"Selected Model: {self.constants.custom_model or self.computer.real_model}",
]
if (self.constants.custom_model or self.computer.real_model) not in model_array.SupportedSMBIOS and self.constants.allow_oc_everywhere is False:
in_between = [
"Your model is not supported by this patcher for running unsupported OSes!",
"",
'If you plan to create the USB for another machine, please select the \n"Change Model" option in the menu.',
"",
'If you want to run OCLP on a native Mac, please toggle \n"Allow OpenCore on native Models" in settings',
]
elif not self.constants.custom_model and self.computer.real_model == "iMac7,1" and "SSE4.1" not in self.computer.cpu.flags:
in_between = [
"Your model requires a CPU upgrade to a CPU supporting SSE4.1+ to be supported by this patcher!",
"",
f'If you plan to create the USB for another {self.computer.real_model} with SSE4.1+, please select the "Change Model" option in the menu.',
]
elif self.constants.custom_model == "iMac7,1":
in_between = ["This model is supported", "However please ensure the CPU has been upgraded to support SSE4.1+"]
else:
in_between = ["This model is supported"]
menu = utilities.TUIMenu(title, "Please select an option: ", in_between=in_between, auto_number=True, top_level=True)
options = (
[["Build OpenCore", build.BuildOpenCore(self.constants.custom_model or self.constants.computer.real_model, self.constants).build_opencore]]
if ((self.constants.custom_model or self.computer.real_model) in model_array.SupportedSMBIOS) or self.constants.allow_oc_everywhere is True
else []
) + [
["Install OpenCore to USB/internal drive", install.tui_disk_installation(self.constants).copy_efi],
["Post-Install Volume Patch", cli_menu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).PatchVolume],
["Change Model", cli_menu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).change_model],
["Patcher Settings", cli_menu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).patcher_settings],
["Installer Creation", cli_menu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).download_macOS],
["Credits", cli_menu.MenuOptions(self.constants.custom_model or self.computer.real_model, self.constants).credits],
]
for option in options:
menu.add_menu_option(option[0], function=option[1])
response = menu.start()
if getattr(sys, "frozen", False) and self.constants.recovery_status is False:
subprocess.run("""osascript -e 'tell application "Terminal" to close first window' & exit""", shell=True)

155
resources/run.py Normal file
View File

@@ -0,0 +1,155 @@
# Module for running processes with real time output
# Written by CorpNewt
# Source: https://github.com/corpnewt/pymodules/blob/884c3de15b6a2570afde52fe8a14a3e946ffb18a/run.py
import sys, subprocess, time, threading, shlex
try:
from Queue import Queue, Empty
except:
from queue import Queue, Empty
ON_POSIX = 'posix' in sys.builtin_module_names
class Run:
def __init__(self):
return
def _read_output(self, pipe, q):
try:
for line in iter(lambda: pipe.read(1), b''):
q.put(line)
except ValueError:
pass
pipe.close()
def _create_thread(self, output):
# Creates a new queue and thread object to watch based on the output pipe sent
q = Queue()
t = threading.Thread(target=self._read_output, args=(output, q))
t.daemon = True
return (q,t)
def _stream_output(self, comm, shell = False):
output = error = ""
p = None
try:
if shell and type(comm) is list:
comm = " ".join(shlex.quote(x) for x in comm)
if not shell and type(comm) is str:
comm = shlex.split(comm)
p = subprocess.Popen(comm, shell=shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=0, universal_newlines=True, close_fds=ON_POSIX)
# Setup the stdout thread/queue
q,t = self._create_thread(p.stdout)
qe,te = self._create_thread(p.stderr)
# Start both threads
t.start()
te.start()
while True:
c = z = ""
try: c = q.get_nowait()
except Empty: pass
else:
sys.stdout.write(c)
output += c
sys.stdout.flush()
try: z = qe.get_nowait()
except Empty: pass
else:
sys.stderr.write(z)
error += z
sys.stderr.flush()
if not c==z=="": continue # Keep going until empty
# No output - see if still running
p.poll()
if p.returncode != None:
# Subprocess ended
break
# No output, but subprocess still running - stall for 20ms
time.sleep(0.02)
o, e = p.communicate()
return (output+o, error+e, p.returncode)
except:
if p:
try: o, e = p.communicate()
except: o = e = ""
return (output+o, error+e, p.returncode)
return ("", "Command not found!", 1)
def _decode(self, value, encoding="utf-8", errors="ignore"):
# Helper method to only decode if bytes type
if sys.version_info >= (3,0) and isinstance(value, bytes):
return value.decode(encoding,errors)
return value
def _run_command(self, comm, shell = False):
c = None
try:
if shell and type(comm) is list:
comm = " ".join(shlex.quote(x) for x in comm)
if not shell and type(comm) is str:
comm = shlex.split(comm)
p = subprocess.Popen(comm, shell=shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
c = p.communicate()
except:
if c == None:
return ("", "Command not found!", 1)
return (self._decode(c[0]), self._decode(c[1]), p.returncode)
def run(self, command_list, leave_on_fail = False):
# Command list should be an array of dicts
if type(command_list) is dict:
# We only have one command
command_list = [command_list]
output_list = []
for comm in command_list:
args = comm.get("args", [])
shell = comm.get("shell", False)
stream = comm.get("stream", False)
sudo = comm.get("sudo", False)
stdout = comm.get("stdout", False)
stderr = comm.get("stderr", False)
mess = comm.get("message", None)
show = comm.get("show", False)
if not mess == None:
print(mess)
if not len(args):
# nothing to process
continue
if sudo:
# Check if we have sudo
out = self._run_command(["which", "sudo"])
if "sudo" in out[0]:
# Can sudo
if type(args) is list:
args.insert(0, out[0].replace("\n", "")) # add to start of list
elif type(args) is str:
args = out[0].replace("\n", "") + " " + args # add to start of string
if show:
print(" ".join(args))
if stream:
# Stream it!
out = self._stream_output(args, shell)
else:
# Just run and gather output
out = self._run_command(args, shell)
if stdout and len(out[0]):
print(out[0])
if stderr and len(out[1]):
print(out[1])
# Append output
output_list.append(out)
# Check for errors
if leave_on_fail and out[2] != 0:
# Got an error - leave
break
if len(output_list) == 1:
# We only ran one command - just return that output
return output_list[0]
return output_list

View File

@@ -1,5 +1,5 @@
# Framework for mounting and patching macOS root volume
# Copyright (C) 2020-2021, Dhinak G, Mykola Grymalyuk
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
# Missing Features:
# - Full System/Library Snapshotting (need to research how Apple achieves this)
# - Temporary Work-around: sudo bless --mount /System/Volumes/Update/mnt1 --bootefi --last-sealed-snapshot
@@ -12,8 +12,8 @@ import zipfile
from pathlib import Path
import sys
from resources import constants, device_probe, utilities, generate_smbios
from data import sip_data, sys_patch_data, model_array, os_data, smbios_data, cpu_data, dylib_data
from resources import constants, device_probe, utilities, generate_smbios, sys_patch_download
from data import sip_data, sys_patch_data, model_array, os_data, smbios_data, cpu_data
class PatchSysVolume:
@@ -62,6 +62,7 @@ class PatchSysVolume:
self.mount_libexec = f"{self.mount_location}/usr/libexec"
self.mount_extensions_mux = f"{self.mount_location}/System/Library/Extensions/AppleGraphicsControl.kext/Contents/PlugIns/"
self.mount_private_etc = f"{self.mount_location_data}/private/etc"
self.mount_application_support = f"{self.mount_location_data}/Library/Application Support"
def find_mount_root_vol(self, patch):
self.root_mount_path = utilities.get_disk_path()
@@ -85,7 +86,9 @@ class PatchSysVolume:
else:
if self.constants.detected_os > os_data.os_data.catalina:
print("- Mounting APFS Snapshot as writable")
utilities.elevated(["mount", "-o", "nobrowse", "-t", "apfs", f"/dev/{self.root_mount_path}", self.mount_location], stdout=subprocess.PIPE).stdout.decode().strip().encode()
result = utilities.elevated(["mount", "-o", "nobrowse", "-t", "apfs", f"/dev/{self.root_mount_path}", self.mount_location], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
if result.returncode == 0:
print(f"- Mounted APFS Snapshot as writable at: {self.mount_location}")
if Path(self.mount_extensions).exists():
print("- Successfully mounted the Root Volume")
if patch is True:
@@ -215,26 +218,6 @@ class PatchSysVolume:
self.manual_root_patch_revert()
def rebuild_snapshot(self):
# Grab List.txt if appropriate
dylib_list = self.build_skylight_plugin_list()
if dylib_list is not None:
print("- Updating SkyLightPlugins List.txt")
if (Path(self.mount_private_etc) / Path("SkyLightPlugins/List.txt")).exists():
print("- Removing existing List.txt")
utilities.process_status(
utilities.elevated(
["rm", "-f", f"{self.mount_private_etc}/SkyLightPlugins/List.txt"],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
)
utilities.process_status(
utilities.elevated(
["cp", dylib_list, f"{self.mount_private_etc}/SkyLightPlugins/"],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
)
print("- Rebuilding Kernel Cache (This may take some time)")
if self.constants.detected_os > os_data.os_data.catalina:
result = utilities.elevated(["kmutil", "install", "--volume-root", self.mount_location, "--update-all"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
@@ -272,7 +255,7 @@ class PatchSysVolume:
print(bless.stdout.decode())
if "Can't use last-sealed-snapshot or create-snapshot on non system volume" in bless.stdout.decode():
print("- This is an APFS bug with Monterey! Perform a clean installation to ensure your APFS volume is built correctly")
sys.exit(1)
return
else:
self.unmount_drive()
else:
@@ -316,35 +299,7 @@ set million colour before rebooting"""
utilities.process_status(utilities.elevated(["cp", "-R", f"{vendor_location}/{add_current_kext}", self.mount_extensions], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
utilities.process_status(utilities.elevated(["chmod", "-Rf", "755", f"{self.mount_extensions}/{add_current_kext}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
utilities.process_status(utilities.elevated(["chown", "-Rf", "root:wheel", f"{self.mount_extensions}/{add_current_kext}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
def build_skylight_plugin_list(self):
# ASentientBot's Skylight system support injecting additional dylibs into macOS
# To do so, it parses the List.txt file in '/private/etc/SkyLightPlugins/'
# The format of this file is:
# <plugin path> : <plugin name>
# Parse all dylibs in /private/etc/SkyLightPlugins/, generate an appropriate List.txt
skylight_plugins = []
if self.constants.list_txt_path.exists():
self.constants.list_txt_path.unlink()
if (Path(self.mount_private_etc) / Path("SkyLightPlugins")).exists():
for file in (Path(self.mount_private_etc) / Path("SkyLightPlugins")).glob("*.dylib"):
skylight_plugins.append(file.name)
if len(skylight_plugins) > 0:
with open(self.constants.list_txt_path, "w") as f:
for plugin in skylight_plugins:
try:
path = dylib_data.shim_list.shim_pathing[plugin]
print(f"- Adding {plugin} to list.txt")
f.write(f"{path} : {plugin}\n")
except KeyError:
print(f"- Skipping {plugin}, unknown pathing")
continue
return self.constants.list_txt_path
return None
def add_brightness_patch(self):
self.delete_old_binaries(sys_patch_data.DeleteBrightness)
self.add_new_binaries(sys_patch_data.AddBrightness, self.constants.legacy_brightness)
@@ -372,8 +327,8 @@ set million colour before rebooting"""
# dylib patch to resolve password crash prompt
# Note requires ASentientBot's SkyLight to function
# Thus Metal machines do not benefit from this patch, however install anyways as harmless
print("- Merging Wireless private/etc")
utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.legacy_wifi_etc}/", self.mount_private_etc], stdout=subprocess.PIPE)
print("- Merging Wireless SkyLightPlugins")
utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.legacy_wifi_support}/", self.mount_application_support], stdout=subprocess.PIPE)
def add_legacy_mux_patch(self):
self.delete_old_binaries(sys_patch_data.DeleteDemux)
@@ -383,8 +338,12 @@ set million colour before rebooting"""
)
def add_legacy_keyboard_backlight_patch(self):
print("- Merging Backlight private/etc")
utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.legacy_keyboard_backlight_etc}/", self.mount_private_etc], stdout=subprocess.PIPE)
print("- Merging Keyboard Backlight SkyLightPlugins")
utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.legacy_keyboard_backlight_support}/", self.mount_application_support], stdout=subprocess.PIPE)
def add_legacy_dropbox_patch(self):
print("- Merging DropboxHack SkyLightPlugins")
utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.legacy_dropbox_support}/", self.mount_application_support], stdout=subprocess.PIPE)
def gpu_accel_legacy(self):
if self.constants.detected_os == os_data.os_data.mojave:
@@ -543,6 +502,9 @@ set million colour before rebooting"""
utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.payload_apple_private_frameworks_path_legacy_drm}/", self.mount_private_frameworks], stdout=subprocess.PIPE)
def gpu_accel_legacy_extended(self):
if self.constants.detected_os == os_data.os_data.monterey:
self.add_legacy_dropbox_patch()
print("- Merging general legacy Frameworks")
utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.payload_apple_frameworks_path_accel}/", self.mount_frameworks], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
if self.constants.detected_os > os_data.os_data.big_sur:
@@ -677,47 +639,26 @@ set million colour before rebooting"""
def check_files(self):
if Path(self.constants.payload_apple_root_path).exists():
print("- Found Apple Binaries")
print("- Found local Apple Binaries")
if self.constants.gui_mode is False:
patch_input = input("Would you like to redownload?(y/n): ")
if patch_input in {"y", "Y", "yes", "Yes"}:
shutil.rmtree(Path(self.constants.payload_apple_root_path))
self.download_files()
output = self.download_files()
else:
self.download_files()
output = self.download_files()
else:
print("- Apple binaries missing")
self.download_files()
output = self.download_files()
return output
def download_files(self):
if self.constants.detected_os == os_data.os_data.monterey:
os_ver = "12-Monterey"
elif self.constants.detected_os == os_data.os_data.big_sur:
os_ver = "11-Big-Sur"
elif self.constants.detected_os == os_data.os_data.catalina:
os_ver = "10.15-Catalina"
elif self.constants.detected_os == os_data.os_data.mojave:
os_ver = "10.14-Mojave"
if self.constants.gui_mode is False:
download_result, os_ver, link = sys_patch_download.grab_patcher_support_pkg(self.constants).download_files()
else:
raise Exception(f"Unsupported OS: {self.constants.detected_os}")
link = f"{self.constants.url_patcher_support_pkg}{self.constants.patcher_support_pkg_version}/{os_ver}.zip"
download_result = True
os_ver, link = sys_patch_download.grab_patcher_support_pkg(self.constants).generate_pkg_link()
if Path(self.constants.payload_apple_root_path).exists():
print("- Removing old Apple Binaries folder")
Path(self.constants.payload_apple_root_path).unlink()
if Path(self.constants.payload_apple_root_path_zip).exists():
print("- Removing old Apple Binaries zip")
Path(self.constants.payload_apple_root_path_zip).unlink()
local_zip = Path(self.constants.payload_path) / f"{os_ver}.zip"
if Path(local_zip).exists():
print(f"- Found local {os_ver} zip, skipping download")
print(f"- Duplicating into Apple.zip")
shutil.copy(local_zip, self.constants.payload_apple_root_path_zip)
else:
utilities.download_file(link, self.constants.payload_apple_root_path_zip)
if self.constants.payload_apple_root_path_zip.exists():
if download_result and self.constants.payload_apple_root_path_zip.exists():
print("- Download completed")
print("- Unzipping download...")
try:
@@ -727,15 +668,19 @@ set million colour before rebooting"""
Path(self.constants.payload_apple_root_path_zip).unlink()
print("- Binaries downloaded to:")
print(self.constants.payload_path)
# if self.constants.gui_mode is False:
# input("Press [ENTER] to continue")
return self.constants.payload_apple_root_path
except zipfile.BadZipFile:
print("- Couldn't unzip")
return
return None
else:
print("- Download failed, please verify the below link works:")
print(link)
input("Press [ENTER] to continue")
if self.constants.gui_mode is True:
print("- Download failed, please verify the below link works:")
print(link)
print("\nIf you continue to have issues, try using the Offline builds")
print("located on Github next to the other builds")
else:
input("\nPress enter to continue")
return None
def detect_gpus(self):
gpus = self.constants.computer.gpus
@@ -952,7 +897,7 @@ set million colour before rebooting"""
# Entry Function
def start_patch(self):
print("- Starting Patch Process")
print(f"- Determinging Required Patch set for Darwin {self.constants.detected_os}")
print(f"- Determining Required Patch set for Darwin {self.constants.detected_os}")
self.detect_patch_set()
if self.no_patch is True:
change_menu = None
@@ -963,14 +908,14 @@ set million colour before rebooting"""
change_menu = input("Would you like to continue with Root Volume Patching?(y/n): ")
else:
change_menu = "y"
print("Continuing root patching")
print("- Continuing root patching")
if change_menu in ["y", "Y"]:
print("- Continuing with Patching")
print("- Verifying whether Root Patching possible")
if self.verify_patch_allowed() is True:
print("- Patcher is capable of patching")
self.check_files()
self.find_mount_root_vol(True)
if self.check_files():
self.find_mount_root_vol(True)
elif self.constants.gui_mode is False:
input("\nPress [ENTER] to return to the main menu: ")

View File

@@ -0,0 +1,196 @@
from resources import constants, device_probe, utilities, generate_smbios
from data import model_array, os_data, smbios_data, cpu_data, sip_data
class detect_root_patch:
def __init__(self, model, versions):
self.model = model
self.constants: constants.Constants() = versions
self.computer = self.constants.computer
# GPU Patch Detection
self.nvidia_legacy= False
self.kepler_gpu= False
self.amd_ts1= False
self.amd_ts2= False
self.iron_gpu= False
self.sandy_gpu= False
self.ivy_gpu= False
# Misc Patch Detection
self.brightness_legacy= False
self.legacy_audio= False
self.legacy_wifi= False
self.legacy_gmux= False
self.legacy_keyboard_backlight= False
# Patch Requirements
self.amfi_must_disable= False
self.check_board_id= False
self.supports_metal= False
# Validation Checks
self.sip_enabled = False
self.sbm_enabled = False
self.amfi_enabled = False
self.fv_enabled = False
self.dosdude_patched = False
self.bad_board_id = False
def detect_gpus(self):
gpus = self.constants.computer.gpus
if self.constants.moj_cat_accel is True:
non_metal_os = os_data.os_data.high_sierra
else:
non_metal_os = os_data.os_data.catalina
for i, gpu in enumerate(gpus):
if gpu.class_code and gpu.class_code != 0xFFFFFFFF:
print(f"- Found GPU ({i}): {utilities.friendly_hex(gpu.vendor_id)}:{utilities.friendly_hex(gpu.device_id)}")
if gpu.arch in [device_probe.NVIDIA.Archs.Tesla, device_probe.NVIDIA.Archs.Fermi]:
if self.constants.detected_os > non_metal_os:
self.nvidia_legacy = True
self.amfi_must_disable = True
# self.legacy_keyboard_backlight = self.check_legacy_keyboard_backlight()
elif gpu.arch == device_probe.NVIDIA.Archs.Kepler:
if self.constants.detected_os > os_data.os_data.big_sur:
# Kepler drivers were dropped with Beta 7
# 12.0 Beta 5: 21.0.0 - 21A5304g
# 12.0 Beta 6: 21.1.0 - 21A5506j
# 12.0 Beta 7: 21.1.0 - 21A5522h
if self.constants.detected_os == os_data.os_data.monterey and self.constants.detected_os_minor > 0:
if "21A5506j" not in self.constants.detected_os_build:
self.kepler_gpu = True
self.supports_metal = True
elif gpu.arch == device_probe.AMD.Archs.TeraScale_1:
if self.constants.detected_os > non_metal_os:
self.amd_ts1 = True
self.amfi_must_disable = True
elif gpu.arch == device_probe.AMD.Archs.TeraScale_2:
if self.constants.detected_os > non_metal_os:
self.amd_ts2 = True
self.amfi_must_disable = True
elif gpu.arch == device_probe.Intel.Archs.Iron_Lake:
if self.constants.detected_os > non_metal_os:
self.iron_gpu = True
self.amfi_must_disable = True
elif gpu.arch == device_probe.Intel.Archs.Sandy_Bridge:
if self.constants.detected_os > non_metal_os:
self.sandy_gpu = True
self.amfi_must_disable = True
self.check_board_id = True
elif gpu.arch == device_probe.Intel.Archs.Ivy_Bridge:
if self.constants.detected_os > os_data.os_data.big_sur:
self.ivy_gpu = True
self.supports_metal = True
if self.supports_metal is True:
# Avoid patching Metal and non-Metal GPUs if both present, prioritize Metal GPU
# Main concerns are for iMac12,x with Sandy iGPU and Kepler dGPU
self.nvidia_legacy = False
self.amd_ts1 = False
self.amd_ts2 = False
self.iron_gpu = False
self.sandy_gpu = False
def check_dgpu_status(self):
dgpu = self.constants.computer.dgpu
if dgpu:
if dgpu.class_code and dgpu.class_code == 0xFFFFFFFF:
# If dGPU is disabled via class-codes, assume demuxed
return False
return True
return False
def detect_demux(self):
# If GFX0 is missing, assume machine was demuxed
# -wegnoegpu would also trigger this, so ensure arg is not present
if not "-wegnoegpu" in (utilities.get_nvram("boot-args") or ""):
igpu = self.constants.computer.igpu
dgpu = self.check_dgpu_status()
if igpu and not dgpu:
return True
return False
def check_legacy_keyboard_backlight(self):
# With Big Sur and newer, Skylight patch set unfortunately breaks native keyboard backlight
# Penryn Macs are able to re-enable the keyboard backlight by simply running '/usr/libexec/TouchBarServer'
# For Arrendale and newer, this has no effect.
if self.model.startswith("MacBookPro") or self.model.startswith("MacBookAir"):
# non-Metal MacBooks never had keyboard backlight
if smbios_data.smbios_dictionary[self.model]["CPU Generation"] <= cpu_data.cpu_data.penryn.value:
if self.constants.detected_os > os_data.os_data.catalina:
return True
return False
def detect_patch_set(self):
self.detect_gpus()
if self.model in model_array.LegacyBrightness:
if self.constants.detected_os > os_data.os_data.catalina:
self.brightness_legacy = True
if self.model in ["iMac7,1", "iMac8,1"] or (self.model in model_array.LegacyAudio and utilities.check_kext_loaded("AppleALC", self.constants.detected_os) is False):
# Special hack for systems with botched GOPs
# TL;DR: No Boot Screen breaks Lilu, therefore breaking audio
if self.constants.detected_os > os_data.os_data.catalina:
self.legacy_audio = True
if (
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]
) 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:
self.legacy_wifi = True
# if self.model in ["MacBookPro5,1", "MacBookPro5,2", "MacBookPro5,3", "MacBookPro8,2", "MacBookPro8,3"]:
if self.model in ["MacBookPro8,2", "MacBookPro8,3"]:
# Sierra uses a legacy GMUX control method needed for dGPU switching on MacBookPro5,x
# 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
# 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.model in ["MacBookPro8,2", "MacBookPro8,3"]:
# Ref: https://doslabelectronics.com/Demux.html
if self.detect_demux() is True:
self.legacy_gmux = True
else:
self.legacy_gmux = True
self.root_patch_dict = {
"Graphics: Nvidia Tesla": self.nvidia_legacy,
"Graphics: Nvidia Kepler": self.kepler_gpu,
"Graphics: AMD TeraScale 1": self.amd_ts1,
"Graphics: AMD TeraScale 2": self.amd_ts2,
"Graphics: Intel Ironlake": self.iron_gpu,
"Graphics: Intel Sandy Bridge": self.sandy_gpu,
"Graphics: Intel Ivy Bridge": self.ivy_gpu,
# "Graphics: Intel Ivy Bridge": True,
"Brightness: Legacy Backlight Control": self.brightness_legacy,
"Audio: Legacy Realtek": self.legacy_audio,
"Networking: Legacy Wireless": self.legacy_wifi,
"Miscellaneous: Legacy GMUX": self.legacy_gmux,
"Miscellaneous: Legacy Keyboard Backlight": self.legacy_keyboard_backlight,
"Settings: Requires AMFI exemption": self.amfi_must_disable,
"Settings: Requires Board ID validation": self.check_board_id,
"Validation: Patching Possible": self.verify_patch_allowed(),
"Validation: SIP is enabled": self.sip_enabled,
"Validation: SBM is enabled": self.sbm_enabled,
"Validation: AMFI is enabled": self.amfi_enabled,
"Validation: FileVault is enabled": self.fv_enabled,
"Validation: System is dosdude1 patched": self.dosdude_patched,
"Validation: Board ID is unsupported": self.bad_board_id,
}
return self.root_patch_dict
def verify_patch_allowed(self):
sip = sip_data.system_integrity_protection.root_patch_sip_big_sur if self.constants.detected_os > os_data.os_data.catalina else sip_data.system_integrity_protection.root_patch_sip_mojave
self.sip_enabled, self.sbm_enabled, self.amfi_enabled, self.fv_enabled, self.dosdude_patched = utilities.patching_status(sip, self.constants.detected_os)
if self.check_board_id is True and (self.computer.reported_board_id not in self.constants.sandy_board_id and self.computer.reported_board_id not in self.constants.sandy_board_id_stock):
self.bad_board_id = True
if any(
[self.sip_enabled, self.sbm_enabled, self.fv_enabled, self.dosdude_patched, self.amfi_enabled if self.amfi_must_disable else False, self.bad_board_id if self.check_board_id else False]
):
return False
else:
return True

View File

@@ -0,0 +1,48 @@
# Download PatcherSupportPkg for usage with Root Patching
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
from data import os_data
from resources import utilities
from pathlib import Path
import shutil
class grab_patcher_support_pkg:
def __init__(self, constants):
self.constants = constants
def generate_pkg_link(self):
if self.constants.detected_os == os_data.os_data.monterey:
os_ver = "12-Monterey"
elif self.constants.detected_os == os_data.os_data.big_sur:
os_ver = "11-Big-Sur"
elif self.constants.detected_os == os_data.os_data.catalina:
os_ver = "10.15-Catalina"
elif self.constants.detected_os == os_data.os_data.mojave:
os_ver = "10.14-Mojave"
else:
raise Exception(f"Unsupported OS: {self.constants.detected_os}")
link = f"{self.constants.url_patcher_support_pkg}{self.constants.patcher_support_pkg_version}/{os_ver}.zip"
return os_ver, link
def download_files(self):
os_ver, link = self.generate_pkg_link()
if Path(self.constants.payload_apple_root_path).exists():
print("- Removing old Apple Binaries folder")
# Delete folder
shutil.rmtree(self.constants.payload_apple_root_path)
if Path(self.constants.payload_apple_root_path_zip).exists():
print("- Removing old Apple Binaries zip")
Path(self.constants.payload_apple_root_path_zip).unlink()
download_result = None
local_zip = Path(self.constants.payload_path) / f"{os_ver}.zip"
if Path(local_zip).exists():
print(f"- Found local {os_ver} zip, skipping download")
print(f"- Duplicating into Apple.zip")
shutil.copy(local_zip, self.constants.payload_apple_root_path_zip)
download_result = True
else:
download_result = utilities.download_file(link, self.constants.payload_apple_root_path_zip)
return download_result, os_ver, link

120
resources/updates.py Normal file
View File

@@ -0,0 +1,120 @@
# Copyright (C) 2022, Mykola Grymalyuk
# Check whether new updates are available for OpenCore Legacy Patcher binary
# Call check_binary_updates() to determine if any updates are available
# Returns dict with Link and Version of the latest binary update if available
import requests
from pathlib import Path
class check_binary_updates:
def __init__(self, constants):
self.constants = constants
self.binary_version = self.constants.patcher_version
self.binary_version_array = self.binary_version.split(".")
self.binary_version_array = [int(x) for x in self.binary_version_array]
self.binary_url = "https://api.github.com/repos/dortania/OpenCore-Legacy-Patcher/releases/latest"
self.available_binaries = {}
def verify_network_connection(self, url):
try:
response = requests.head(url, timeout=5)
if response:
return True
except (requests.exceptions.Timeout,
requests.exceptions.TooManyRedirects,
requests.exceptions.ConnectionError,
requests.exceptions.HTTPError):
return False
return False
def check_if_build_newer(self):
if self.remote_version_array[0] > self.binary_version_array[0]:
return True
elif self.remote_version_array[0] == self.binary_version_array[0]:
if self.remote_version_array[1] > self.binary_version_array[1]:
return True
elif self.remote_version_array[1] == self.binary_version_array[1]:
if self.remote_version_array[2] > self.binary_version_array[2]:
return True
else:
return False
else:
return False
return False
def determine_local_build_type(self):
if self.constants.gui_mode is True:
return "GUI"
else:
return "TUI"
def determine_local_build_type_offline(self):
if (Path(self.constants.payload_path) / f"12-Monterey.zip").exists():
return True
else:
return False
def determine_remote_type(self, remote_name):
if "TUI" in remote_name:
return "TUI"
elif "GUI" in remote_name:
return "GUI"
else:
return "Unknown"
def determine_remote_offline_type(self, remote_name):
if "Offline" in remote_name:
return True
else:
return False
def check_binary_updates(self):
# print("- Checking for updates...")
if self.verify_network_connection(self.binary_url):
# print("- Network connection functional")
response = requests.get(self.binary_url)
data_set = response.json()
# print("- Retrived latest version data")
self.remote_version = data_set["tag_name"]
# print(f"- Latest version: {self.remote_version}")
self.remote_version_array = self.remote_version.split(".")
self.remote_version_array = [
int(x) for x in self.remote_version_array
]
if self.check_if_build_newer() is True:
# print("- Remote version is newer")
for asset in data_set["assets"]:
print(f"- Found asset: {asset['name']}")
if self.determine_remote_type(
asset["name"]) == self.determine_local_build_type(
) and self.determine_remote_offline_type(
asset["name"]
) == self.determine_local_build_type_offline():
# print(f"- Found matching asset: {asset['name']}")
self.available_binaries.update({
asset['name']: {
"Name":
asset["name"],
"Version":
self.remote_version,
"Link":
asset["browser_download_url"],
"Type":
self.determine_remote_type(asset["name"]),
"Offline":
self.determine_remote_offline_type(
asset["name"]),
"Github Link":
f"https://github.com/dortania/OpenCore-Legacy-Patcher/releases/{self.remote_version}"
}
})
break
if self.available_binaries:
return self.available_binaries
else:
# print("- No matching binaries available")
return None
# else:
# print("- Failed to connect to GitHub API")
return None

View File

@@ -1,4 +1,4 @@
# Copyright (C) 2020-2021, Dhinak G
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymaluk
from __future__ import print_function
import hashlib
@@ -312,22 +312,31 @@ def verify_network_connection(url):
except (requests.exceptions.Timeout, requests.exceptions.TooManyRedirects, requests.exceptions.ConnectionError, requests.exceptions.HTTPError):
return False
def download_file(link, location):
def download_file(link, location, is_gui=None):
if verify_network_connection(link):
short_link = os.path.basename(link)
if Path(location).exists():
Path(location).unlink()
header = requests.head(link).headers
try:
# Try to get true file
# ex. Github's release links provides a "fake" header
# Thus need to resolve to the real link
link = requests.head(link).headers["location"]
header = requests.head(link).headers
except KeyError:
pass
try:
# Handle cases where Content-Length has garbage or is missing
total_file_size = int(requests.head(link).headers['Content-Length'])
except KeyError:
total_file_size = 0
if total_file_size != 0:
if total_file_size > 1024:
file_size_rounded = round(total_file_size / 1024 / 1024, 2)
file_size_string = f" of {file_size_rounded}MB"
else:
file_size_string = ""
response = requests.get(link, stream=True)
short_link = os.path.basename(link)
# SU Catalog's link is quite long, strip to make it bearable
if "sucatalog.gz" in short_link:
short_link = "sucatalog.gz"
@@ -343,15 +352,15 @@ def download_file(link, location):
dl += len(chunk)
file.write(chunk)
count += len(chunk)
cls()
print(box_string)
print(header)
print(box_string)
print("")
if total_file_size != 0:
if is_gui is None:
cls()
print(box_string)
print(header)
print(box_string)
print("")
if total_file_size > 1024:
total_downloaded_string = f" ({round(float(dl / total_file_size * 100), 2)}%)"
print(f"{round(count / 1024 / 1024, 2)}MB Downloaded{file_size_string}{total_downloaded_string}")
print(f"Average Download Speed: {round(dl//(time.perf_counter() - start) / 100000 / 8, 2)} MB/s")
print(f"{round(count / 1024 / 1024, 2)}MB Downloaded{file_size_string}{total_downloaded_string}\nAverage Download Speed: {round(dl//(time.perf_counter() - start) / 100000 / 8, 2)} MB/s")
checksum = hashlib.sha256()
with location.open("rb") as file:
chunk = file.read(1024 * 1024 * 16)
@@ -373,7 +382,16 @@ def download_file(link, location):
print(f"https://github.com/dortania/OpenCore-Legacy-Patcher/releases/download/{constants.Constants().patcher_version}/OpenCore-Patcher-TUI-Offline.app.zip")
else:
print(link)
sys.exit()
return None
def monitor_disk_output(disk):
# Returns MB written on drive
output = subprocess.check_output(["iostat", "-Id", disk])
output = output.decode("utf-8")
# Grab second last entry (last is \n)
output = output.split(" ")
output = output[-2]
return output
def elevated(*args, **kwargs) -> subprocess.CompletedProcess:
# When runnign through our GUI, we run as root, however we do not get uid 0

View File

@@ -13,6 +13,7 @@ def validate(settings):
example_data.iMac.iMac81_Stock,
example_data.iMac.iMac112_Stock,
example_data.iMac.iMac122_Upgraded,
example_data.iMac.iMac151_Stock,
example_data.MacPro.MacPro31_Stock,
example_data.MacPro.MacPro31_Upgrade,
example_data.MacPro.MacPro31_Modern_AMD,