mirror of
https://github.com/dortania/OpenCore-Legacy-Patcher.git
synced 2026-04-15 13:18:56 +10:00
Compare commits
144 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37e99ba49c | ||
|
|
288b827616 | ||
|
|
e8a6f45329 | ||
|
|
a1ffadf582 | ||
|
|
a6c4890d0f | ||
|
|
00b47aef47 | ||
|
|
92f85feda5 | ||
|
|
21778e8d92 | ||
|
|
57d2597c86 | ||
|
|
20baf8c417 | ||
|
|
99a145e7cb | ||
|
|
79f4ba17d9 | ||
|
|
659d842023 | ||
|
|
037ff0f2c3 | ||
|
|
fac1298a6e | ||
|
|
273910b69a | ||
|
|
1974cd6341 | ||
|
|
bef429b758 | ||
|
|
bebbf646e1 | ||
|
|
6504442d4f | ||
|
|
ff0012e214 | ||
|
|
91e7ff40e4 | ||
|
|
07d09d8eb2 | ||
|
|
b95ab91b43 | ||
|
|
4cc9e414d2 | ||
|
|
a5d56147c0 | ||
|
|
3e8963c372 | ||
|
|
f4d6ef1741 | ||
|
|
abbb9c1c66 | ||
|
|
22b66e0a87 | ||
|
|
fd6c3d818d | ||
|
|
cefdd1df66 | ||
|
|
fcda4a26bf | ||
|
|
60f6482d43 | ||
|
|
c316e6f5fe | ||
|
|
d30972e5ef | ||
|
|
5206028478 | ||
|
|
00043087c4 | ||
|
|
d7ecdf3871 | ||
|
|
6fe7ed614c | ||
|
|
09f77490a5 | ||
|
|
1cc6d50474 | ||
|
|
549cb9fc9a | ||
|
|
a8ef84acf9 | ||
|
|
f55d3ba5b2 | ||
|
|
e46a5213a6 | ||
|
|
2331aeb6d9 | ||
|
|
1277fef735 | ||
|
|
5fdde346cf | ||
|
|
907ce75295 | ||
|
|
915d38eab1 | ||
|
|
8678200385 | ||
|
|
66e1cbcf1e | ||
|
|
e1568d9391 | ||
|
|
89069a85f0 | ||
|
|
5b2917cb03 | ||
|
|
73afdc37c3 | ||
|
|
f71fcf6f58 | ||
|
|
6169d593c5 | ||
|
|
f463e505d4 | ||
|
|
6c6ae6145d | ||
|
|
90310fcaca | ||
|
|
27d1ee3b02 | ||
|
|
2fba826f80 | ||
|
|
1f63dffd3f | ||
|
|
f4f4f3e1f3 | ||
|
|
4ffe6bed9b | ||
|
|
d3878e34a2 | ||
|
|
501b228b6b | ||
|
|
c707047530 | ||
|
|
1c24cfee24 | ||
|
|
ebd605d459 | ||
|
|
f4cb0bed68 | ||
|
|
0a395b47ae | ||
|
|
1627f264a2 | ||
|
|
23c0759d7a | ||
|
|
26154d4fdf | ||
|
|
c99805bee5 | ||
|
|
d284dc6248 | ||
|
|
70402af1d7 | ||
|
|
b94a1bf9cf | ||
|
|
a0a740de4f | ||
|
|
8876823ae8 | ||
|
|
94b91b2918 | ||
|
|
1bdc3ef5ff | ||
|
|
be7b0e6492 | ||
|
|
30e2a4471c | ||
|
|
41188edf39 | ||
|
|
9296350e58 | ||
|
|
f06d7f2179 | ||
|
|
d5d2a7fbfe | ||
|
|
a672183880 | ||
|
|
9b7074bde5 | ||
|
|
7543606a1e | ||
|
|
48de65dd30 | ||
|
|
e7e2b0dcad | ||
|
|
8b43727b0b | ||
|
|
9c28d77826 | ||
|
|
93c1983a3f | ||
|
|
7fcef65837 | ||
|
|
93a1d0fb11 | ||
|
|
94b33f6029 | ||
|
|
1d2a7e080b | ||
|
|
b448a4b6dd | ||
|
|
235a9985f4 | ||
|
|
34aa75422a | ||
|
|
3a56f13480 | ||
|
|
50d730b45a | ||
|
|
2e5a61b7fd | ||
|
|
7c43cf0901 | ||
|
|
956d0cffcc | ||
|
|
f8e91feff4 | ||
|
|
55061bc86d | ||
|
|
21c40277bb | ||
|
|
4b05b12a0a | ||
|
|
168930919e | ||
|
|
423a6bc255 | ||
|
|
d8f9c60f0c | ||
|
|
0ef84c1751 | ||
|
|
286df94c87 | ||
|
|
ca11b2741e | ||
|
|
ed9f9a05b5 | ||
|
|
82b4cc26d5 | ||
|
|
003a40a039 | ||
|
|
a1cc9a399a | ||
|
|
1659f8c25e | ||
|
|
8c23ea137b | ||
|
|
4dc14eb9c0 | ||
|
|
2ea3933720 | ||
|
|
ff5139463e | ||
|
|
b0d4dd158f | ||
|
|
71439916b6 | ||
|
|
66a9be5be4 | ||
|
|
55478fd81c | ||
|
|
d2d68fd08f | ||
|
|
2ea982b343 | ||
|
|
9741ef794e | ||
|
|
eb9531f768 | ||
|
|
45e0d5b155 | ||
|
|
47fe853334 | ||
|
|
cd5ff61138 | ||
|
|
59b473a4ce | ||
|
|
5a67212bdc | ||
|
|
f0991d2cd0 |
@@ -85,6 +85,8 @@ class create_binary:
|
||||
self.move_launcher()
|
||||
self.patch_load_command()
|
||||
self.add_commit_data()
|
||||
self.post_flight_cleanup()
|
||||
self.mini_validate()
|
||||
|
||||
def build_binary(self):
|
||||
if Path(f"./dist/OpenCore-Patcher.app").exists():
|
||||
@@ -266,5 +268,31 @@ class create_binary:
|
||||
print(mv_output.stderr.decode('utf-8'))
|
||||
raise Exception("Move failed")
|
||||
|
||||
def post_flight_cleanup(self):
|
||||
# Remove ./dist/OpenCore-Patcher
|
||||
path = "./dist/OpenCore-Patcher"
|
||||
print(f" - Removing {path}")
|
||||
rm_output = subprocess.run(
|
||||
["rm", "-rf", path],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
if rm_output.returncode != 0:
|
||||
print(f" - Remove failed: {path}")
|
||||
print(rm_output.stderr.decode('utf-8'))
|
||||
raise Exception(f"Remove failed: {path}")
|
||||
|
||||
def mini_validate(self):
|
||||
# Ensure binary can start
|
||||
# Only build a single config, TUI CI will do in-depth validation
|
||||
print(" - Validating binary")
|
||||
validate_output = subprocess.run(
|
||||
["./dist/OpenCore-Patcher.app/Contents/MacOS/OpenCore-Patcher", "--build", "--model", "MacPro3,1"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
if validate_output.returncode != 0:
|
||||
print(" - Validation failed")
|
||||
print(validate_output.stderr.decode('utf-8'))
|
||||
raise Exception("Validation failed")
|
||||
|
||||
if __name__ == "__main__":
|
||||
create_binary()
|
||||
109
CHANGELOG.md
109
CHANGELOG.md
@@ -1,5 +1,114 @@
|
||||
# OpenCore Legacy Patcher changelog
|
||||
|
||||
## 0.6.0
|
||||
- Resolve external NVMe reporting regression from 0.5.2
|
||||
- Implement Legacy Wireless support for Ventura
|
||||
- Applicable for BCM94328, BCM94322 and Atheros chipsets
|
||||
- Implement Wifi-only patches when no internet connection available but required (ie. KDKs)
|
||||
- Allows users to install Legacy Wireless patches, then connect to the internet to install remaining patches
|
||||
- Resolve `/Library/Extensions` not being cleaned on KDK-less root patches
|
||||
- Add AMD Vega Graphics support for pre-AVX2.0 systems on Ventura
|
||||
- ex. AMD Vega 56 and 64, AMD Radeon VII
|
||||
- Note: As with Polaris, Vega GPUs cannot be mixed with AMD GCN 1-3 patches
|
||||
- Patcher will prioritize the AMD GCN 1-3 (assumption that GCN is primary GPU, ex. MacPro6,1)
|
||||
- Implement proper `APPLE SSD TS0128F/256F` detection
|
||||
- Allows all Macs to utilize patch if required
|
||||
- Avoids usage of patch when host lacks affected drive (ex. MacBookAir6,x with upgraded SSD)
|
||||
- Prompt with auto patcher when booted OpenCore is out of date to root patcher
|
||||
- ex. Booted OCLP is 0.5.2, root patcher is 0.5.3
|
||||
- Disable native AMD Graphics on pre-Haswell Macs in Ventura
|
||||
- Allows for easy root patching, dropping reliance on Safe Mode to boot
|
||||
- Primarily applicable for iMacs and Mac Pros with AMD Polaris and Vega GPUs
|
||||
- Implement mini validation during GUI build
|
||||
- Add early UHCI/OHCI support (USB1.1)
|
||||
- Implemented via Root Volume patching, ie. no installer support at this time
|
||||
- Support should be seen as experimental, especially for laptops
|
||||
- Applicable for Penryn Macs and Cheese Grater Mac Pros (MacPro3,1 - MacPro5,1)
|
||||
- See associated issue for current limitations: [Legacy UHCI/OHCI support in Ventura](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021)
|
||||
- USB 3.0 controllers cannot be used along side USB 1.1 patches, OCLP will prioritize USB 3.0 support
|
||||
- Add early non-Metal Graphics Acceleration support for macOS Ventura
|
||||
- Applicable for following GPU architectures:
|
||||
- Intel Ironlake and Sandy Bridge
|
||||
- Nvidia Tesla, Maxwell and Pascal
|
||||
- AMD TeraScale 1 and 2
|
||||
- Notes:
|
||||
- Bluetooth Pairing is currently semi-functional, see here for work around: [Tab+Space work-around](https://forums.macrumors.com/threads/macos-13-ventura-on-unsupported-macs-thread.2346881/post-31858759)
|
||||
- AMFI currently needs to be outright disabled in Ventura
|
||||
- Overall non-Metal improvements:
|
||||
- Improved fake rim
|
||||
- Fixed full screen animation
|
||||
- Fixed split screen
|
||||
- Improved menubar blur
|
||||
- Add Nvidia Kepler GOP Driver injection
|
||||
- Primarily for GPUs lacking GOPs and can't have a newer VBIOS flashed
|
||||
- Resolve Rapid Security Response support for Haswell+ Macs requiring KDKs
|
||||
- Implemented via:
|
||||
- Userspace: [RSRRepair](https://github.com/flagersgit/RSRRepair) at `/etc/rc.server` (2b1c9e3)
|
||||
- Kernelspace: [RSRHelper.kext](https://github.com/khronokernel/RSRHelper) (cbe1be9)
|
||||
- Add APFS Trim Configuration
|
||||
- Settings -> Misc Settings -> APFS Trim
|
||||
- Increment Binaries:
|
||||
- OpenCorePkg 0.8.8 - release
|
||||
- PatcherSupportPkg 0.8.2 - release
|
||||
- KDKlessWorkaround 1.0.0 - rolling (4924276)
|
||||
- FeatureUnlock 1.1.2 - release
|
||||
- CPUFriend 1.2.6 - release
|
||||
- Lilu 1.6.3 - release
|
||||
|
||||
## 0.5.3
|
||||
- Integrate FixPCIeLinkrate.efi v0.1.0
|
||||
- Fixes link rate for PCIe 3.0 devices on MacPro3,1
|
||||
- Resolve AppleIntelCPUPowerManagement Panic in Safe Mode
|
||||
- Applicable for pre-Haswell Macs on Ventura
|
||||
- Revert AppleALC 1.7.6 update back to 1.6.3
|
||||
- Resolves audio issues on certain Intel HDEF devices
|
||||
- Regression currently being investigated within AppleALC
|
||||
- Remove `Force Web Drivers` option
|
||||
- Avoids accidental use of non-Metal Web Drivers on Kepler GPUs
|
||||
- Resolve silent auto patcher crash when new OCLP version is available
|
||||
- Implement [`py_sip_xnu`](https://github.com/khronokernel/py_sip_xnu) module
|
||||
- Resolve Content Caching Patch Regression
|
||||
- Resolve KDK Versioning Fallback crashing when primary KDK site is down
|
||||
- Resolve AirPlay to Mac support on Ventura with VMM
|
||||
- Resolve WindowServer crashing on KDK-less with macOS 13.2 and Rapid Security Response updates
|
||||
- Resolve Host Versioning when RSR is installed
|
||||
- Resolve iMac7,1-8,1 and MacBookPro4,1 boot support in Ventura
|
||||
- Increment Binaries:
|
||||
- OpenCorePkg 0.8.7 - release
|
||||
- FeatureUnlock 1.1.2 - rolling (94e29ce)
|
||||
- WhateverGreen 1.6.2 - release
|
||||
|
||||
## 0.5.2
|
||||
- Ventura Specific Updates:
|
||||
- Resolve AMD Polaris external display output support
|
||||
- AMD Polaris and legacy GCN cannot be mixed in the same system
|
||||
- Legacy GCN support will be prioritized when both are present
|
||||
- AMD Polaris GPU can still be used headless for rendering with legacy GCN (ex. [macOS: Prefer External GPU option](https://support.apple.com/en-ca/HT208544))
|
||||
- Disables unsupported `mediaanalysisd` on Metal 1 GPUs
|
||||
- Alleviates kernel panic when on prolonged idle
|
||||
- Automatically remove unsupported News Widgets on Ivy Bridge and Haswell iGPUs
|
||||
- Alleviates Notification Centre Crashing
|
||||
- Implement downloading from Kernel Debug Kit Backup Repository
|
||||
- Alleviates issues with Apple blocking KDK downloads from OCLP (Ref: [Issue #1016](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1016))
|
||||
- Work-around MacPro6,1 and Lilu race condition
|
||||
- Ensure Model and Board ID are set correctly before Lilu loads
|
||||
- Publish Application Version in UI header
|
||||
- Allows for easier identification of version when reporting issues
|
||||
- Drop usage of `HW_BID` rerouting in boot.efi
|
||||
- Patch out PlatformSupport.plist instead, allows for less maintenance overall
|
||||
- Add support for AMD GOP injection (AMDGOP.efi)
|
||||
- For MXM iMacs and Mac Pros with GPU VBIOS lacking GOP support (ie. no UEFI output even after OC loads)
|
||||
- Hide OpenCore Boot Picker when waking from hibernation
|
||||
- Increment Binaries:
|
||||
- AirPortBrcmFixup 2.1.6 - release
|
||||
- AppleALC 1.7.6 - release
|
||||
- CryptexFixup 1.0.1 - release
|
||||
- DebugEnhancer 1.0.7 - release
|
||||
- FeatureUnlock 1.1.0 - release
|
||||
- OpenCorePkg 0.8.7 - rolling (fcb4e33)
|
||||
- RestrictEvents 1.0.9 - release
|
||||
- WhateverGreen 1.6.1 - release
|
||||
|
||||
## 0.5.1
|
||||
- Add support for `APPLE SSD TS0128F/256F` SSDs in macOS Ventura
|
||||
- ie. stock SSD found in MacBookAir6,x
|
||||
|
||||
14
README.md
14
README.md
@@ -44,8 +44,10 @@ To start using the project, please see our in-depth guide:
|
||||
|
||||
## Support
|
||||
|
||||
To get aid with the patcher, we recommend joining the [OpenCore Patcher Paradise Discord Server](https://discord.gg/rqdPgH8xSN). We're actively there and is the quickest way to receive help.
|
||||
This project is offered on an AS-IS basis, we do not guarantee support for any issues that may arise. However, there is a community server with other passionate users and developers that can aid you:
|
||||
|
||||
* [OpenCore Patcher Paradise Discord Server](https://discord.gg/rqdPgH8xSN)
|
||||
* Keep in mind that the Discord is maintained by the community, so we ask everyone to be respectful.
|
||||
* Please review our docs on [how to debug with OpenCore](https://dortania.github.io/OpenCore-Legacy-Patcher/DEBUG.html) to gather important information to help others with troubleshooting.
|
||||
|
||||
## Running from source
|
||||
@@ -87,6 +89,16 @@ To run the project from source, see here: [Build and run from source](./SOURCE.m
|
||||
* Endless hours helping architect and troubleshoot many portions of the project
|
||||
* [flagers](https://github.com/flagersgit)
|
||||
* Aid with Nvidia Web Driver research and development
|
||||
* [joevt](https://github.com/joevt)
|
||||
* [FixPCIeLinkrate](https://github.com/joevt/joevtApps)
|
||||
* Amazing users who've graciously donate hardware:
|
||||
* [JohnD](https://forums.macrumors.com/members/johnd.53633/) - 2013 Mac Pro
|
||||
* [SpiGAndromeda](https://github.com/SpiGAndromeda) - AMD Vega 64
|
||||
* [turbomacs](https://github.com/turbomacs) - 2014 5k iMac
|
||||
* [vinaypundith](https://forums.macrumors.com/members/vinaypundith.1212357/) - MacBook7,1
|
||||
* zephar - 2008 Mac Pro
|
||||
* jazo97 - 2011 15" MacBook Pro
|
||||
* And others (reach out if we forgot you!)
|
||||
* MacRumors and Unsupported Mac Communities
|
||||
* Endless testing, reporting issues
|
||||
* Apple
|
||||
|
||||
@@ -81,13 +81,12 @@ def SystemPatchDictionary(os_major, os_minor, non_metal_os_support):
|
||||
"/Library/Application Support/SkyLightPlugins": {
|
||||
**({ "DropboxHack.dylib": "SkyLightPlugins" } if os_major >= os_data.os_data.monterey else {}),
|
||||
**({ "DropboxHack.txt": "SkyLightPlugins" } if os_major >= os_data.os_data.monterey else {}),
|
||||
**({ "CatalystButton.dylib": "SkyLightPlugins" } if os_major >= os_data.os_data.monterey else {}),
|
||||
**({ "CatalystButton.txt": "SkyLightPlugins" } if os_major >= os_data.os_data.monterey else {}),
|
||||
},
|
||||
},
|
||||
"Processes": {
|
||||
# 'When Space Allows' option introduced in 12.4 (XNU 21.5)
|
||||
**({"defaults write /Library/Preferences/.GlobalPreferences.plist ShowDate -int 1": True } if os_data.os_conversion.is_os_newer(os_data.os_data.monterey, 4, os_major, os_minor) else {}),
|
||||
"defaults write /Library/Preferences/.GlobalPreferences.plist InternalDebugUseGPUProcessForCanvasRenderingEnabled -bool false": True,
|
||||
},
|
||||
},
|
||||
"Non-Metal IOAccelerator Common": {
|
||||
@@ -630,6 +629,7 @@ def SystemPatchDictionary(os_major, os_minor, non_metal_os_support):
|
||||
"AMD8000Controller.kext": "12.5",
|
||||
"AMD9000Controller.kext": "12.5",
|
||||
"AMD9500Controller.kext": "12.5",
|
||||
"AMD10000Controller.kext": "12.5",
|
||||
"AMDRadeonX4000.kext": "12.5",
|
||||
"AMDRadeonX4000HWServices.kext": "12.5",
|
||||
"AMDFramebuffer.kext": "12.5",
|
||||
@@ -640,13 +640,74 @@ def SystemPatchDictionary(os_major, os_minor, non_metal_os_support):
|
||||
"AMDShared.bundle": "12.5",
|
||||
},
|
||||
},
|
||||
"Remove": {
|
||||
"/System/Library/Extensions": [
|
||||
# Due to downgraded AMDSupport.kext
|
||||
# In the future, we will have to downgrade the entire AMD stack
|
||||
# to support non-AVX2.0 machines with Vega or newer
|
||||
"AMD10000Controller.kext",
|
||||
],
|
||||
},
|
||||
# Used only for AMD Polaris with host lacking AVX2.0
|
||||
# Note missing framebuffers are not restored (ex. 'ATY,Berbice')
|
||||
"AMD Legacy Polaris": {
|
||||
"Display Name": "Graphics: AMD Legacy Polaris",
|
||||
"OS Support": {
|
||||
"Minimum OS Support": {
|
||||
"OS Major": os_data.os_data.ventura,
|
||||
"OS Minor": 0
|
||||
},
|
||||
"Maximum OS Support": {
|
||||
"OS Major": os_data.os_data.max_os,
|
||||
"OS Minor": 99
|
||||
},
|
||||
},
|
||||
"Install": {
|
||||
"/System/Library/Extensions": {
|
||||
"AMDRadeonX4000.kext": "12.5",
|
||||
|
||||
"AMDRadeonX4000GLDriver.bundle": "12.5",
|
||||
"AMDMTLBronzeDriver.bundle": "12.5",
|
||||
"AMDShared.bundle": "12.5",
|
||||
},
|
||||
},
|
||||
},
|
||||
"AMD Legacy Vega": {
|
||||
"Display Name": "Graphics: AMD Legacy Vega",
|
||||
"OS Support": {
|
||||
"Minimum OS Support": {
|
||||
"OS Major": os_data.os_data.ventura,
|
||||
"OS Minor": 0
|
||||
},
|
||||
"Maximum OS Support": {
|
||||
"OS Major": os_data.os_data.max_os,
|
||||
"OS Minor": 99
|
||||
},
|
||||
},
|
||||
"Install": {
|
||||
"/System/Library/Extensions": {
|
||||
"AMDRadeonX5000.kext": "12.5",
|
||||
|
||||
"AMDRadeonX5000GLDriver.bundle": "12.5",
|
||||
"AMDRadeonX5000MTLDriver.bundle": "12.5",
|
||||
"AMDRadeonX5000Shared.bundle": "12.5",
|
||||
|
||||
"AMDShared.bundle": "12.5",
|
||||
},
|
||||
},
|
||||
},
|
||||
# Support mixed legacy and modern AMD GPUs
|
||||
# Specifically systems using AMD GCN 1-3 and Vega (ex. MacPro6,1 with eGPU)
|
||||
# Assume 'AMD Legacy GCN' patchset is installed alongside this
|
||||
"AMD Legacy Vega Extended": {
|
||||
"Display Name": "",
|
||||
"OS Support": {
|
||||
"Minimum OS Support": {
|
||||
"OS Major": os_data.os_data.ventura,
|
||||
"OS Minor": 0
|
||||
},
|
||||
"Maximum OS Support": {
|
||||
"OS Major": os_data.os_data.max_os,
|
||||
"OS Minor": 99
|
||||
},
|
||||
},
|
||||
"Install": {
|
||||
"/System/Library/Extensions": {
|
||||
"AMDRadeonX5000HWServices.kext": "12.5",
|
||||
},
|
||||
},
|
||||
},
|
||||
"Intel Ironlake": {
|
||||
@@ -706,9 +767,6 @@ def SystemPatchDictionary(os_major, os_minor, non_metal_os_support):
|
||||
"OS Minor": 99
|
||||
},
|
||||
},
|
||||
"Processes": {
|
||||
"defaults write com.apple.coremedia hardwareVideoDecoder -string enable": False,
|
||||
},
|
||||
"Install": {
|
||||
"/System/Library/Extensions": {
|
||||
"AppleIntelHD4000GraphicsGLDriver.bundle": "11.0 Beta 6",
|
||||
@@ -853,25 +911,50 @@ def SystemPatchDictionary(os_major, os_minor, non_metal_os_support):
|
||||
"OS Minor": 0
|
||||
},
|
||||
"Maximum OS Support": {
|
||||
"OS Major": os_data.os_data.monterey,
|
||||
"OS Major": os_data.os_data.max_os,
|
||||
"OS Minor": 99
|
||||
},
|
||||
},
|
||||
"Install": {
|
||||
"/usr/libexec": {
|
||||
"airportd": "11.5.2",
|
||||
"airportd": "11.7.1",
|
||||
},
|
||||
"/System/Library/CoreServices": {
|
||||
"WiFiAgent.app": "11.5.2",
|
||||
"WiFiAgent.app": "11.7.1",
|
||||
},
|
||||
},
|
||||
"Install Non-Root": {
|
||||
"/Library/Application Support/SkyLightPlugins": {
|
||||
**({ "CoreWLAN.dylib": "SkyLightPlugins" } if os_major >= os_data.os_data.monterey else {}),
|
||||
**({ "CoreWLAN.txt": "SkyLightPlugins" } if os_major >= os_data.os_data.monterey else {}),
|
||||
**({ "CoreWLAN.dylib": "SkyLightPlugins" } if os_major == os_data.os_data.monterey else {}),
|
||||
**({ "CoreWLAN.txt": "SkyLightPlugins" } if os_major == os_data.os_data.monterey else {}),
|
||||
},
|
||||
},
|
||||
},
|
||||
"Legacy Wireless Extended": {
|
||||
"Display Name": "",
|
||||
"OS Support": {
|
||||
"Minimum OS Support": {
|
||||
"OS Major": os_data.os_data.ventura,
|
||||
"OS Minor": 0
|
||||
},
|
||||
"Maximum OS Support": {
|
||||
"OS Major": os_data.os_data.max_os,
|
||||
"OS Minor": 99
|
||||
},
|
||||
},
|
||||
"Install": {
|
||||
"/usr/libexec": {
|
||||
"wps": "12.6.2",
|
||||
},
|
||||
"/System/Library/Frameworks": {
|
||||
"CoreWLAN.framework": "12.6.2",
|
||||
},
|
||||
"/System/Library/PrivateFrameworks": {
|
||||
"CoreWiFi.framework": "12.6.2",
|
||||
"IO80211.framework": "12.6.2",
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
"Brightness": {
|
||||
"Legacy Backlight Control": {
|
||||
@@ -946,6 +1029,28 @@ def SystemPatchDictionary(os_major, os_minor, non_metal_os_support):
|
||||
"defaults write /Library/Preferences/.GlobalPreferences.plist Moraea_BacklightHack -bool true": True,
|
||||
},
|
||||
},
|
||||
"Legacy USB 1.1": {
|
||||
"Display Name": "Miscellaneous: Legacy USB 1.1",
|
||||
"OS Support": {
|
||||
"Minimum OS Support": {
|
||||
"OS Major": os_data.os_data.ventura,
|
||||
"OS Minor": 0
|
||||
},
|
||||
"Maximum OS Support": {
|
||||
"OS Major": os_data.os_data.max_os,
|
||||
"OS Minor": 99
|
||||
},
|
||||
},
|
||||
"Install": {
|
||||
"/System/Library/Extensions/IOUSBHostFamily.kext/Contents/MacOS": {
|
||||
"IOUSBHostFamily": "12.6.2",
|
||||
},
|
||||
"/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns": {
|
||||
"AppleUSBEHCI.kext": "12.6.2",
|
||||
"AppleUSBHub.kext": "12.6.2",
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,11 @@ Next, run the `OpenCore-Patcher.app`:
|
||||
|
||||

|
||||
|
||||
::: warning
|
||||
OpenCore configurations are hardware specific.
|
||||
If you're building OpenCore for a different model than you're currently running, it is absolutely necessary to select the proper model from Settings.
|
||||
:::
|
||||
|
||||
Here we'll select Build and Install OpenCore and start building:
|
||||
|
||||
| Start Building | Finished Building |
|
||||
|
||||
@@ -148,7 +148,7 @@ Regarding OS support, see below:
|
||||
| MacPro3,1 | Early 2008 | <span style="color:#30BCD5"> YES - Monterey and older</span> | - Potential boot issues with built-in USB 1.1 ports (recommend using a USB 2.0 hub or dedicated USB PCIe controller) <br/>- Potential boot issues with stock Bluetooth card, recommend removing to avoid kernel panics |
|
||||
| MacPro4,1 | Early 2009 | ^^ | - Everything is supported as long as GPU is Metal capable <br/> - Supports macOS Monterey and older ([Ventura support in development](./VENTURA-DROP.md)) |
|
||||
| MacPro5,1 | Mid-2010, Mid-2012 | ^^ | ^^ |
|
||||
| MacPro6,1 | Late 2013 | <span style="color:red"> NO </span> | Unsupported, [currently under active development](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1009) |
|
||||
| MacPro6,1 | Late 2013 | ^^ | - CPU Power Management currently unsupported<br/> - No DRM support |
|
||||
|
||||
### Xserve
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# Universal Control on unsupported Macs
|
||||
|
||||
Introduced in macOS 12 Monterey, Universal Control is a feature that allows a Mac to control other Macs and/or iPads, share input devices, and share files across them simultaneously. With OpenCore and FeatureUnlock, Universal Control can be unlocked for most unsupported Macs, as long as they meet the technical requirements listed on this page.
|
||||
@@ -202,11 +203,50 @@ Before we continue, please keep in mind that SMBIOS Spoofing is an advanced feat
|
||||
|
||||
### How to spoof
|
||||
|
||||
Firstly, run the GUI version of OpenCore Legacy Patcher, go to **Settings** and tick **Allow native models**.
|
||||
Ventura has dropped more models which includes all of the blacklisted Macs in question, making the procedure slightly different. It is important to follow the guide for the version you're on, failing to do so is likely to cause boot issues.
|
||||
|
||||
**Note:** Unless you are building OpenCore on a different machine than it's targeted for, **do not** change the model in the main settings view. It is important to understand that OCLP targets this model regardless of what you may have spoofed to, as your Mac is still what the Native SMBIOS shows.
|
||||
::: details macOS Ventura
|
||||
|
||||
Secondly, go to **SMBIOS Settings**, tick **Allow Native Spoofs**, set SMBIOS Spoof Level to **Moderate**. Set SMBIOS Spoof Model to **one listed next to your native model in the table for spoofed models below.**
|
||||
Firstly run the GUI version of OpenCore Legacy Patcher.
|
||||
|
||||
Then go to **Settings**, go to **SMBIOS Settings**, set SMBIOS Spoof Level to **Moderate**. Set SMBIOS Spoof Model **one listed next to your native model in the table for spoofed models below.**
|
||||
|
||||
Notice that "Allow native models" and "Allow Native Spoofs" **are NOT** enabled unlike on Monterey, this is on purpose. They are no longer relevant on Ventura and enabling them will cause boot issues.
|
||||
|
||||
| Main Settings view | SMBIOS settings |
|
||||
| :--- | :--- |
|
||||
|  |  |
|
||||
|
||||
|
||||
|
||||
::: details Table for spoofed models (click to expand)
|
||||
|
||||
Spoofing to any model with native Ventura support should work, but these are the earliest Macs natively supported by Ventura and thus chosen for the sake of simplicity.
|
||||
|
||||
**Reminder:** Macs that are not listed on this table work without spoofing, including systems that do not natively support Ventura as long as the other requirements are met, since they aren't blacklisted.
|
||||
|
||||
|
||||
| Mac by name | Native SMBIOS | Spoof SMBIOS | Tested | Tested by |
|
||||
|-------------|---------------|--------------|--------|-----------|
|
||||
| MacBook Air Early 2015 11" / 13" | MacBookAir7,x | MacBookAir8,1 | <span style="color:red"> NO </span> | N/A |
|
||||
| MacBook Pro Early 2015 13" | MacBookPro12,x | MacBookPro14,1 | ^^ | ^^ |
|
||||
| MacBook Pro Mid 2015 15" | MacBookPro11,4 / 11,5 | MacBookPro14,3 | ^^ | ^^
|
||||
| iMac Late 2015 21" | iMac16,x | iMac18,2 | ^^ | ^^
|
||||
| Mac mini Late 2014 | Macmini7,x | MacMini8,1 | <span style="color:red"> NO </span> | N/A |
|
||||
| Mac Pro Late 2013 | MacPro6,x | MacPro7,1 | <span style="color:red"> NO </span> | N/A |
|
||||
|
||||
:::
|
||||
|
||||
::: details macOS Monterey
|
||||
|
||||
Firstly, run the GUI version of OpenCore Legacy Patcher. Secondly, go to **Settings** and tick **Allow native models**.
|
||||
|
||||
Then, go to **SMBIOS Settings**, tick **Allow Native Spoofs**, set SMBIOS Spoof Level to **Moderate**. Set SMBIOS Spoof Model to **one listed next to your native model in the table for spoofed models below.**
|
||||
|
||||
|
||||
| Main Settings view | SMBIOS settings |
|
||||
| :--- | :--- |
|
||||
|  |  |
|
||||
|
||||
|
||||
::: details Table for spoofed models (click to expand)
|
||||
@@ -227,12 +267,9 @@ Any model after the list of officially blacklisted Macs should be supported, but
|
||||
|
||||
:::
|
||||
|
||||
| Main Settings view | SMBIOS settings |
|
||||
| :--- | :--- |
|
||||
|  |  |
|
||||
**Note:** Unless you are building OpenCore on a different machine than it's targeted for, **do not** change the model in the main settings view. It is important to understand that OCLP targets this model regardless of what you may have spoofed to, as your Mac is still what the Native SMBIOS shows.
|
||||
|
||||
|
||||
Build and install OpenCore again, and reboot back to the OS. Enable Universal Control as explained in the [Enabling Universal Control section.](#enabling-universal-control)
|
||||
Lastly, Build and install OpenCore again, and reboot back to the OS. Enable Universal Control as explained in the [Enabling Universal Control section.](#enabling-universal-control)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -26,16 +26,12 @@ Ventura's release dropped a large amount of Intel hardware, thus requiring the u
|
||||
|
||||
Overall, macOS Ventura is useable on most Metal-capable machines (ie. 2012 and newer). The graphics patches implemented have near feature parity to macOS Monterey, with patches still being under heavy development. See [Legacy Metal Graphics Support and macOS Ventura #1008](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1008) issue for more information.
|
||||
|
||||
* The sole exception for 2012+ hardware support in Ventura is the Late 2013, Trash Can Mac Pro. Currently we're in the process of researching and developing patches for this unit, however at this time the machine is not bootable on Ventura.
|
||||
* More information can be found here: [2013 Mac Pro and macOS Ventura Boot Issues #1009](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1009)
|
||||
|
||||
<img width="625" alt="" src="../images/OCLP-050-Initial-Support.png">
|
||||
<img width="625" alt="" src="../images/OCLP-051-Initial-Support.png">
|
||||
|
||||
For older hardware, see below sections:
|
||||
|
||||
* [Currently Unsupported/Broken Hardware in Ventura](#currently-unsupportedbroken-hardware-in-ventura)
|
||||
* [Late 2013 Mac Pro Boot Issues](#late-2013-mac-pro-boot-issues)
|
||||
* [AMD Polaris, Vega and Navi support on pre-2013 Mac Pros and pre-2012 iMacs](#amd-polaris-vega-and-navi-support-on-pre-2013-mac-pros-and-pre-2012-imacs)
|
||||
* [AMD Polaris, Vega and Navi support on pre-2019 Mac Pros and pre-2012 iMacs](#amd-polaris-vega-and-navi-support-on-pre-2019-mac-pros-and-pre-2012-imacs)
|
||||
* [Non-Metal Graphics Acceleration](#non-metal-graphics-acceleration)
|
||||
* [Legacy Wireless Support](#legacy-wireless-support)
|
||||
* [USB 1.1 (OHCI/UHCI) Support](#usb-11-ohciuhci-support)
|
||||
@@ -45,21 +41,16 @@ The team is doing their best to investigate and fix the aforementioned issues, h
|
||||
|
||||
## Currently Unsupported/Broken Hardware in Ventura
|
||||
|
||||
### Late 2013 Mac Pro Boot Issues
|
||||
### AMD Polaris, Vega and Navi support on pre-2019 Mac Pros and pre-2012 iMacs
|
||||
|
||||
As mentioned above, users of the Late 2013 Trash Can Mac Pro (MacPro6,1) currently cannot boot macOS Ventura. This issue is still being actively researched, however no overall time estimate can be given. See below for more information:
|
||||
|
||||
* [2013 Mac Pro and macOS Ventura Boot Issues #1009](https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1009)
|
||||
|
||||
### AMD Polaris, Vega and Navi support on pre-2013 Mac Pros and pre-2012 iMacs
|
||||
|
||||
For users with 2008 to 2012 Mac Pros (MacPro3,1-5,1) and 2009 to 2011 iMacs (iMac9,1-12,2), keep in mind macOS Ventura now requires [AVX2.0 support in the CPU](https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#Advanced_Vector_Extensions_2) for native graphics acceleration. Thus while your GPU may be natively supported, you cannot run Ventura officially with these GPUs.
|
||||
For users with 2008 to 2013 Mac Pros (MacPro3,1-6,1) and 2009 to 2011 iMacs (iMac9,1-12,2), keep in mind macOS Ventura now requires [AVX2.0 support in the CPU](https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#Advanced_Vector_Extensions_2) for native graphics acceleration. Thus while your GPU may be natively supported, you cannot run Ventura officially with these GPUs.
|
||||
|
||||
* CPUs supporting AVX2.0 are Haswell or newer, which no pre-2019 Mac Pros can be upgraded with.
|
||||
|
||||
Currently at this time, OpenCore Legacy Patcher only supports patching the AMD Polaris Graphics stack to no longer require AVX2.0. However due to lack of hardware on-hand, we cannot support AMD Vega or Navi on Ventura.
|
||||
Currently at this time, OpenCore Legacy Patcher only supports patching the AMD Polaris Graphics stack to no longer require AVX2.0. However due to lack of hardware on-hand, we cannot support Navi on Ventura.
|
||||
|
||||
* If you have spare Vega or Navi GPUs you'd like to donate, feel free to reach out: khronokernel@icloud.com
|
||||
* If you have spare Navi GPU you'd like to donate, feel free to reach out: khronokernel@icloud.com
|
||||
* Thanks to a gracious user, we've gotten an AMD Vega 64 on-hand for testing. No time estimate can be provided for Vega support at this time.
|
||||
|
||||
Additionally, the native stack will crash over and over on macOS Ventura as it fails to load the AVX2.0-based binaries. Thus to patch Ventura, you will need to boot in Safe Mode and run OCLP's Root Volume Patcher
|
||||
|
||||
@@ -152,4 +143,5 @@ For Penryn systems and pre-2013 Mac Pros, USB 1.1 support was outright removed i
|
||||
:::
|
||||
|
||||
### Ethernet issue with Early 2008 Mac Pro
|
||||
|
||||
MacPro3,1 suffers from Ethernet driver dying after returning from sleep, current workaround is to use a USB Ethernet adapter or disable sleep.
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 759 KiB |
BIN
images/OCLP-051-Initial-Support.png
Normal file
BIN
images/OCLP-051-Initial-Support.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 782 KiB |
BIN
images/ventura_uc1.png
Normal file
BIN
images/ventura_uc1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 405 KiB |
BIN
images/ventura_uc2.png
Normal file
BIN
images/ventura_uc2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 330 KiB |
@@ -1527,6 +1527,42 @@
|
||||
<key>PlistPath</key>
|
||||
<string>Contents/Info.plist</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Arch</key>
|
||||
<string>x86_64</string>
|
||||
<key>BundlePath</key>
|
||||
<string>KDKlessWorkaround.kext</string>
|
||||
<key>Comment</key>
|
||||
<string>KDKlessWorkaround</string>
|
||||
<key>Enabled</key>
|
||||
<false/>
|
||||
<key>ExecutablePath</key>
|
||||
<string>Contents/MacOS/KDKlessWorkaround</string>
|
||||
<key>MaxKernel</key>
|
||||
<string></string>
|
||||
<key>MinKernel</key>
|
||||
<string>22.3.0</string>
|
||||
<key>PlistPath</key>
|
||||
<string>Contents/Info.plist</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Arch</key>
|
||||
<string>x86_64</string>
|
||||
<key>BundlePath</key>
|
||||
<string>RSRHelper.kext</string>
|
||||
<key>Comment</key>
|
||||
<string>RSRHelper</string>
|
||||
<key>Enabled</key>
|
||||
<false/>
|
||||
<key>ExecutablePath</key>
|
||||
<string>Contents/MacOS/RSRHelper</string>
|
||||
<key>MaxKernel</key>
|
||||
<string></string>
|
||||
<key>MinKernel</key>
|
||||
<string>20.0.0</string>
|
||||
<key>PlistPath</key>
|
||||
<string>Contents/Info.plist</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Block</key>
|
||||
<array/>
|
||||
@@ -1977,6 +2013,8 @@
|
||||
<integer>0</integer>
|
||||
<key>HibernateMode</key>
|
||||
<string>Auto</string>
|
||||
<key>HibernateSkipsPicker</key>
|
||||
<true/>
|
||||
<key>HideAuxiliary</key>
|
||||
<true/>
|
||||
<key>LauncherPath</key>
|
||||
@@ -2173,6 +2211,8 @@
|
||||
<string>OCLP-Spoofed-MLB</string>
|
||||
<string>revcpu</string>
|
||||
<string>revcpuname</string>
|
||||
<string>revblock</string>
|
||||
<string>revpatch</string>
|
||||
</array>
|
||||
<key>7C436110-AB2A-4BBB-A880-FE41995C9F82</key>
|
||||
<array>
|
||||
@@ -2361,6 +2401,12 @@
|
||||
<integer>0</integer>
|
||||
<key>KeySubsequentDelay</key>
|
||||
<integer>5</integer>
|
||||
<key>PointerDwellClickTimeout</key>
|
||||
<integer>0</integer>
|
||||
<key>PointerDwellDoubleClickTimeout</key>
|
||||
<integer>0</integer>
|
||||
<key>PointerDwellRadius</key>
|
||||
<integer>0</integer>
|
||||
<key>PointerPollMask</key>
|
||||
<integer>-1</integer>
|
||||
<key>PointerPollMax</key>
|
||||
@@ -2499,6 +2545,42 @@
|
||||
<key>LoadEarly</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Comment</key>
|
||||
<string></string>
|
||||
<key>Path</key>
|
||||
<string>AMDGOP.efi</string>
|
||||
<key>Enabled</key>
|
||||
<false/>
|
||||
<key>Arguments</key>
|
||||
<string></string>
|
||||
<key>LoadEarly</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Comment</key>
|
||||
<string></string>
|
||||
<key>Path</key>
|
||||
<string>NVGOP_GK.efi</string>
|
||||
<key>Enabled</key>
|
||||
<false/>
|
||||
<key>Arguments</key>
|
||||
<string></string>
|
||||
<key>LoadEarly</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Comment</key>
|
||||
<string></string>
|
||||
<key>Path</key>
|
||||
<string>FixPCIeLinkRate.efi</string>
|
||||
<key>Enabled</key>
|
||||
<false/>
|
||||
<key>Arguments</key>
|
||||
<string></string>
|
||||
<key>LoadEarly</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Input</key>
|
||||
<dict>
|
||||
|
||||
BIN
payloads/Drivers/AMDGOP.efi
Normal file
BIN
payloads/Drivers/AMDGOP.efi
Normal file
Binary file not shown.
BIN
payloads/Drivers/FixPCIeLinkRate.efi
Normal file
BIN
payloads/Drivers/FixPCIeLinkRate.efi
Normal file
Binary file not shown.
BIN
payloads/Drivers/NVGOP_GK.efi
Normal file
BIN
payloads/Drivers/NVGOP_GK.efi
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
payloads/Kexts/Acidanthera/AirportBrcmFixup-v2.1.6-DEBUG.zip
Normal file
BIN
payloads/Kexts/Acidanthera/AirportBrcmFixup-v2.1.6-DEBUG.zip
Normal file
Binary file not shown.
BIN
payloads/Kexts/Acidanthera/AirportBrcmFixup-v2.1.6-RELEASE.zip
Normal file
BIN
payloads/Kexts/Acidanthera/AirportBrcmFixup-v2.1.6-RELEASE.zip
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
payloads/Kexts/Acidanthera/CPUFriend-v1.2.6-DEBUG.zip
Normal file
BIN
payloads/Kexts/Acidanthera/CPUFriend-v1.2.6-DEBUG.zip
Normal file
Binary file not shown.
BIN
payloads/Kexts/Acidanthera/CPUFriend-v1.2.6-RELEASE.zip
Normal file
BIN
payloads/Kexts/Acidanthera/CPUFriend-v1.2.6-RELEASE.zip
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
payloads/Kexts/Acidanthera/DebugEnhancer-v1.0.7-DEBUG.zip
Normal file
BIN
payloads/Kexts/Acidanthera/DebugEnhancer-v1.0.7-DEBUG.zip
Normal file
Binary file not shown.
BIN
payloads/Kexts/Acidanthera/DebugEnhancer-v1.0.7-RELEASE.zip
Normal file
BIN
payloads/Kexts/Acidanthera/DebugEnhancer-v1.0.7-RELEASE.zip
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
payloads/Kexts/Acidanthera/FeatureUnlock-v1.1.2-DEBUG.zip
Normal file
BIN
payloads/Kexts/Acidanthera/FeatureUnlock-v1.1.2-DEBUG.zip
Normal file
Binary file not shown.
BIN
payloads/Kexts/Acidanthera/FeatureUnlock-v1.1.2-RELEASE.zip
Normal file
BIN
payloads/Kexts/Acidanthera/FeatureUnlock-v1.1.2-RELEASE.zip
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
payloads/Kexts/Acidanthera/Lilu-v1.6.3-DEBUG.zip
Normal file
BIN
payloads/Kexts/Acidanthera/Lilu-v1.6.3-DEBUG.zip
Normal file
Binary file not shown.
BIN
payloads/Kexts/Acidanthera/Lilu-v1.6.3-RELEASE.zip
Normal file
BIN
payloads/Kexts/Acidanthera/Lilu-v1.6.3-RELEASE.zip
Normal file
Binary file not shown.
BIN
payloads/Kexts/Acidanthera/RSRHelper-v1.0.0-DEBUG.zip
Normal file
BIN
payloads/Kexts/Acidanthera/RSRHelper-v1.0.0-DEBUG.zip
Normal file
Binary file not shown.
BIN
payloads/Kexts/Acidanthera/RSRHelper-v1.0.0-RELEASE.zip
Normal file
BIN
payloads/Kexts/Acidanthera/RSRHelper-v1.0.0-RELEASE.zip
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,12 +0,0 @@
|
||||
diff --git a/RestrictEvents/RestrictEvents.cpp b/RestrictEvents/RestrictEvents.cpp
|
||||
index 27562f0..66365a3 100644
|
||||
--- a/RestrictEvents/RestrictEvents.cpp
|
||||
+++ b/RestrictEvents/RestrictEvents.cpp
|
||||
@@ -61,6 +61,7 @@ struct RestrictEventsPolicy {
|
||||
static const char *procBlacklist[] {
|
||||
"/System/Library/CoreServices/ExpansionSlotNotification",
|
||||
"/System/Library/CoreServices/MemorySlotNotification",
|
||||
+ "/usr/libexec/displaypolicyd",
|
||||
};
|
||||
|
||||
char pathbuf[MAXPATHLEN];
|
||||
Binary file not shown.
Binary file not shown.
BIN
payloads/Kexts/Acidanthera/RestrictEvents-v1.0.9-DEBUG.zip
Normal file
BIN
payloads/Kexts/Acidanthera/RestrictEvents-v1.0.9-DEBUG.zip
Normal file
Binary file not shown.
BIN
payloads/Kexts/Acidanthera/RestrictEvents-v1.0.9-RELEASE.zip
Normal file
BIN
payloads/Kexts/Acidanthera/RestrictEvents-v1.0.9-RELEASE.zip
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
payloads/Kexts/Acidanthera/WhateverGreen-v1.6.3-DEBUG.zip
Normal file
BIN
payloads/Kexts/Acidanthera/WhateverGreen-v1.6.3-DEBUG.zip
Normal file
Binary file not shown.
BIN
payloads/Kexts/Acidanthera/WhateverGreen-v1.6.3-RELEASE.zip
Normal file
BIN
payloads/Kexts/Acidanthera/WhateverGreen-v1.6.3-RELEASE.zip
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
payloads/Kexts/Misc/KDKlessWorkaround-v1.0.0-DEBUG.zip
Normal file
BIN
payloads/Kexts/Misc/KDKlessWorkaround-v1.0.0-DEBUG.zip
Normal file
Binary file not shown.
BIN
payloads/Kexts/Misc/KDKlessWorkaround-v1.0.0-RELEASE.zip
Normal file
BIN
payloads/Kexts/Misc/KDKlessWorkaround-v1.0.0-RELEASE.zip
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,89 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# Simple script to delete unnecessary files from OpenCore and move into place
|
||||
# To use, simply :
|
||||
# - Download an OpenCore build
|
||||
# - Place the X64 folder in the /payloads/OpenCore folder
|
||||
# - Rename to OpenCore-VERSION (ie. DEBUG or RELEASE)
|
||||
# - Run script
|
||||
# - Rename folders to appropriate versions (ie. OpenCore-Build)
|
||||
# - Zip folders
|
||||
# TODO:
|
||||
# - Download latest builds from dortania.github.io
|
||||
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
build_types = [
|
||||
"DEBUG",
|
||||
"RELEASE",
|
||||
]
|
||||
|
||||
bad_drivers = [
|
||||
"AudioDxe.efi",
|
||||
"BiosVideo.efi",
|
||||
"CrScreenshotDxe.efi",
|
||||
"Ext4Dxe.efi",
|
||||
"HiiDatabase.efi",
|
||||
"NvmExpressDxe.efi",
|
||||
"OpenHfsPlus.efi",
|
||||
"OpenNtfsDxe.efi",
|
||||
"OpenPartitionDxe.efi",
|
||||
"OpenUsbKbDxe.efi",
|
||||
"OpenVariableRuntimeDxe.efi",
|
||||
"Ps2KeyboardDxe.efi",
|
||||
"Ps2MouseDxe.efi",
|
||||
"ToggleSipEntry.efi",
|
||||
"UsbMouseDxe.efi",
|
||||
"XhciDxe.efi",
|
||||
"Udp4Dxe.efi",
|
||||
"TcpDxe.efi",
|
||||
"SnpDxe.efi",
|
||||
"MnpDxe.efi",
|
||||
"Ip4Dxe.efi",
|
||||
"HttpUtilitiesDxe.efi",
|
||||
"HttpDxe.efi",
|
||||
"HttpBootDxe.efi",
|
||||
"DpcDxe.efi",
|
||||
"DnsDxe.efi",
|
||||
"Dhcp4Dxe.efi",
|
||||
"ArpDxe.efi",
|
||||
]
|
||||
|
||||
bad_tools = [
|
||||
"ChipTune.efi",
|
||||
"CleanNvram.efi",
|
||||
"ControlMsrE2.efi",
|
||||
"GopStop.efi",
|
||||
"KeyTester.efi",
|
||||
"MmapDump.efi",
|
||||
"OpenControl.efi",
|
||||
"ResetSystem.efi",
|
||||
"RtcRw.efi",
|
||||
"CsrUtil.efi",
|
||||
"TpmInfo.efi",
|
||||
]
|
||||
|
||||
for version in build_types:
|
||||
print("- Creating S/L/C")
|
||||
subprocess.run(f"mkdir -p ./OpenCore-{version}/System/Library/CoreServices".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode()
|
||||
print("- Creating boot.efi Bootstrap")
|
||||
subprocess.run(f"cp ./OpenCore-{version}/EFI/BOOT/BOOTx64.efi ./OpenCore-{version}/System/Library/CoreServices/boot.efi".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode()
|
||||
print("- Deleting old BOOTx64.efi")
|
||||
subprocess.run(f"rm -R ./OpenCore-{version}/EFI/BOOT/".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode()
|
||||
for delete_drivers in bad_drivers:
|
||||
if Path(f"./OpenCore-{version}/EFI/OC/Drivers/{delete_drivers}").exists():
|
||||
print(f"- Deleting {delete_drivers}")
|
||||
subprocess.run(f"rm ./OpenCore-{version}/EFI/OC/Drivers/{delete_drivers}".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode()
|
||||
else:
|
||||
print(f"- Unable to find {delete_drivers}, skipping")
|
||||
for delete_tools in bad_tools:
|
||||
if Path(f".//OpenCore-{version}/EFI/OC/Tools/{delete_tools}").exists():
|
||||
print(f"- Deleting {delete_tools}")
|
||||
subprocess.run(f"rm ./OpenCore-{version}/EFI/OC/Tools/{delete_tools}".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode()
|
||||
else:
|
||||
print(f"- Unable to find {delete_tools}, skipping")
|
||||
|
||||
print("- Renaming folder to OpenCore-Build and zipping")
|
||||
subprocess.run(f"mv ./OpenCore-{version} ./OpenCore-Build".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode()
|
||||
subprocess.run(f"zip -r ./OpenCore-{version}.zip ./OpenCore-Build".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode()
|
||||
subprocess.run(f"rm -rf ./OpenCore-Build".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode()
|
||||
286
payloads/OpenCore/generate.command
Executable file
286
payloads/OpenCore/generate.command
Executable file
@@ -0,0 +1,286 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Script to download and generate valid OpenCorePkg folder/file structure for use with OpenCore-Legacy-Patcher
|
||||
# To use:
|
||||
# - Download OpenCore-{VERSION}-{VARIANT}.zip
|
||||
# - If no files are found, the script will download the latest version
|
||||
# - Place zips in same directory as this script
|
||||
# - Run script
|
||||
|
||||
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
import requests
|
||||
|
||||
REPO_URL = "https://api.github.com/repos/acidanthera/OpenCorePkg/releases/latest"
|
||||
|
||||
BUILD_VARIANTS = [
|
||||
"DEBUG",
|
||||
"RELEASE"
|
||||
]
|
||||
|
||||
UNUSED_DRIVERS = [
|
||||
"AudioDxe.efi",
|
||||
"BiosVideo.efi",
|
||||
"CrScreenshotDxe.efi",
|
||||
"Ext4Dxe.efi",
|
||||
"HiiDatabase.efi",
|
||||
"NvmExpressDxe.efi",
|
||||
"OpenHfsPlus.efi",
|
||||
"OpenNtfsDxe.efi",
|
||||
"OpenPartitionDxe.efi",
|
||||
"OpenUsbKbDxe.efi",
|
||||
"OpenVariableRuntimeDxe.efi",
|
||||
"Ps2KeyboardDxe.efi",
|
||||
"Ps2MouseDxe.efi",
|
||||
"ToggleSipEntry.efi",
|
||||
"UsbMouseDxe.efi",
|
||||
"XhciDxe.efi",
|
||||
"Udp4Dxe.efi",
|
||||
"TcpDxe.efi",
|
||||
"SnpDxe.efi",
|
||||
"MnpDxe.efi",
|
||||
"Ip4Dxe.efi",
|
||||
"HttpUtilitiesDxe.efi",
|
||||
"HttpDxe.efi",
|
||||
"HttpBootDxe.efi",
|
||||
"DpcDxe.efi",
|
||||
"DnsDxe.efi",
|
||||
"Dhcp4Dxe.efi",
|
||||
"ArpDxe.efi",
|
||||
]
|
||||
|
||||
UNUSED_TOOLS = [
|
||||
"ChipTune.efi",
|
||||
"CleanNvram.efi",
|
||||
"ControlMsrE2.efi",
|
||||
"GopStop.efi",
|
||||
"KeyTester.efi",
|
||||
"MmapDump.efi",
|
||||
"OpenControl.efi",
|
||||
"ResetSystem.efi",
|
||||
"RtcRw.efi",
|
||||
"CsrUtil.efi",
|
||||
"TpmInfo.efi",
|
||||
]
|
||||
|
||||
IMPORTANT_UTILITIES = [
|
||||
"macserial",
|
||||
"ocvalidate",
|
||||
]
|
||||
|
||||
|
||||
|
||||
class GenerateOpenCore:
|
||||
|
||||
def __init__(self):
|
||||
print("Generating new OpenCore bundles...")
|
||||
|
||||
self.working_dir = None
|
||||
|
||||
self.set_directory()
|
||||
self.validate_files()
|
||||
self.generate()
|
||||
|
||||
print("New OpenCore bundles generated!")
|
||||
|
||||
def set_directory(self):
|
||||
self.working_dir = Path(__file__).parent.absolute()
|
||||
print(f"Working directory: {self.working_dir}")
|
||||
|
||||
self.debug_zip = None
|
||||
self.release_zip = None
|
||||
|
||||
# Find OpenCore DEBUG zip
|
||||
for file in self.working_dir.iterdir():
|
||||
if file.name.endswith("DEBUG.zip") and file.name != "OpenCore-DEBUG.zip":
|
||||
print(f" Found DEBUG zip: {file.name}")
|
||||
self.debug_zip = file
|
||||
|
||||
# Find OpenCore RELEASE zip
|
||||
for file in self.working_dir.iterdir():
|
||||
if file.name.endswith("RELEASE.zip") and file.name != "OpenCore-RELEASE.zip":
|
||||
print(f" Found RELEASE zip: {file.name}")
|
||||
self.release_zip = file
|
||||
|
||||
if self.debug_zip is None:
|
||||
self.download_new_binaries("DEBUG")
|
||||
|
||||
if self.release_zip is None:
|
||||
self.download_new_binaries("RELEASE")
|
||||
|
||||
|
||||
# Unzip both, rename to OpenCore-DEBUG and OpenCore-RELEASE
|
||||
print("Unzipping DEBUG zip...")
|
||||
subprocess.run (
|
||||
["unzip", f"{self.debug_zip}", "-d", f"{self.working_dir}/OpenCore-DEBUG-ROOT"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
print("Unzipping RELEASE zip...")
|
||||
subprocess.run (
|
||||
["unzip", f"{self.release_zip}", "-d", f"{self.working_dir}/OpenCore-RELEASE-ROOT"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
for variant in BUILD_VARIANTS:
|
||||
print(f"Moving {variant} folder...")
|
||||
subprocess.run (
|
||||
["mv", f"{self.working_dir}/OpenCore-{variant}-ROOT/X64", f"{self.working_dir}/OpenCore-{variant}"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
if variant == "DEBUG":
|
||||
for utility in IMPORTANT_UTILITIES:
|
||||
print(f"Moving {utility} from {variant} variant...")
|
||||
subprocess.run (
|
||||
["rm", "-rf", f"{self.working_dir}/{utility}"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
subprocess.run (
|
||||
["mv", f"{self.working_dir}/OpenCore-{variant}-ROOT/Utilities/{utility}/{utility}", f"{self.working_dir}/{utility}"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
# Remove root folder
|
||||
subprocess.run (
|
||||
["rm", "-rf", f"{self.working_dir}/OpenCore-{variant}-ROOT"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
# Remove zip files
|
||||
print("Removing zip files...")
|
||||
# remove debug_zip
|
||||
subprocess.run (
|
||||
["rm", "-rf", self.debug_zip],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
# remove release_zip
|
||||
subprocess.run (
|
||||
["rm", "-rf", self.release_zip],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
def download_new_binaries(self, variant):
|
||||
# Get latest release
|
||||
print(f"Getting latest {variant}...")
|
||||
latest_release = requests.get(REPO_URL).json()
|
||||
|
||||
# Get latest release download url
|
||||
print(f" Getting latest {variant} download url...")
|
||||
for asset in latest_release["assets"]:
|
||||
if asset["name"].endswith(f"{variant}.zip"):
|
||||
download_url = asset["browser_download_url"]
|
||||
print(f" Download url: {download_url}")
|
||||
break
|
||||
|
||||
if variant == "DEBUG":
|
||||
self.debug_zip = f"{self.working_dir}/{asset['name']}"
|
||||
elif variant == "RELEASE":
|
||||
self.release_zip = f"{self.working_dir}/{asset['name']}"
|
||||
else:
|
||||
raise ValueError("Invalid variant!")
|
||||
|
||||
# Download latest release
|
||||
print(f" Downloading latest {variant}...")
|
||||
download = requests.get(download_url)
|
||||
with open(f"{self.working_dir}/{asset['name']}", "wb") as f:
|
||||
f.write(download.content)
|
||||
|
||||
def clean_old_bundles(self):
|
||||
print("Cleaning old bundles...")
|
||||
for variant in BUILD_VARIANTS:
|
||||
if (self.working_dir / f"OpenCore-{variant}").exists():
|
||||
print(f" Deleting old {variant} variant...")
|
||||
subprocess.run (
|
||||
["rm", "-rf", f"{self.working_dir}/OpenCore-{variant}"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
def validate_files(self):
|
||||
for variant in BUILD_VARIANTS:
|
||||
if not (self.working_dir / f"OpenCore-{variant}").exists():
|
||||
raise FileNotFoundError(f"OpenCore-{variant} folder not found!")
|
||||
|
||||
def generate(self):
|
||||
for variant in BUILD_VARIANTS:
|
||||
print(f"Generating {variant} variant...")
|
||||
self.generate_opencore(variant)
|
||||
|
||||
def generate_opencore(self, variant):
|
||||
# Create S/L/C
|
||||
print(" Creating SLC folder")
|
||||
subprocess.run (
|
||||
["mkdir", "-p", f"{self.working_dir}/OpenCore-{variant}/System/Library/CoreServices"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
# Relocate contents of /EFI/BOOT to /S/L/C
|
||||
print(" Relocating BOOT folder to SLC")
|
||||
for file in (self.working_dir / f"OpenCore-{variant}/EFI/BOOT").iterdir():
|
||||
subprocess.run (
|
||||
["mv", f"{file}", f"{self.working_dir}/OpenCore-{variant}/System/Library/CoreServices"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
# Rename BOOTx64.efi to boot.efi
|
||||
print(" Renaming BOOTx64.efi to boot.efi")
|
||||
subprocess.run (
|
||||
["mv", f"{self.working_dir}/OpenCore-{variant}/System/Library/CoreServices/BOOTx64.efi", f"{self.working_dir}/OpenCore-{variant}/System/Library/CoreServices/boot.efi"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
# Delete BOOT folder
|
||||
print(" Deleting BOOT folder")
|
||||
subprocess.run (
|
||||
["rm", "-rf", f"{self.working_dir}/OpenCore-{variant}/EFI/BOOT"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
# Delete unused drivers
|
||||
print(" Deleting unused drivers")
|
||||
for driver in UNUSED_DRIVERS:
|
||||
if Path(f"{self.working_dir}/OpenCore-{variant}/EFI/OC/Drivers/{driver}").exists():
|
||||
print(f" Deleting {driver}")
|
||||
subprocess.run (
|
||||
["rm", f"{self.working_dir}/OpenCore-{variant}/EFI/OC/Drivers/{driver}"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
else:
|
||||
print(f" {driver} not found")
|
||||
|
||||
# Delete unused tools
|
||||
print(" Deleting unused tools")
|
||||
for tool in UNUSED_TOOLS:
|
||||
if Path(f"{self.working_dir}/OpenCore-{variant}/EFI/OC/Tools/{tool}").exists():
|
||||
print(f" Deleting {tool}")
|
||||
subprocess.run (
|
||||
["rm", f"{self.working_dir}/OpenCore-{variant}/EFI/OC/Tools/{tool}"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
else:
|
||||
print(f" {tool} not found")
|
||||
|
||||
# Rename OpenCore-<variant> to OpenCore-Build
|
||||
print(" Renaming OpenCore folder")
|
||||
subprocess.run (
|
||||
["mv", f"{self.working_dir}/OpenCore-{variant}", f"{self.working_dir}/OpenCore-Build"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
# Create OpenCore-<variant>.zip
|
||||
print(" Creating OpenCore.zip")
|
||||
subprocess.run (
|
||||
["ditto", "-c", "-k", "--sequesterRsrc", "--keepParent", f"{self.working_dir}/OpenCore-Build", f"{self.working_dir}/OpenCore-{variant}.zip"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
# Delete OpenCore-Build
|
||||
print(" Deleting OpenCore-Build")
|
||||
subprocess.run (
|
||||
["rm", "-rf", f"{self.working_dir}/OpenCore-Build"],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
GenerateOpenCore()
|
||||
BIN
payloads/OpenCore/macserial
Executable file
BIN
payloads/OpenCore/macserial
Executable file
Binary file not shown.
BIN
payloads/OpenCore/ocvalidate
Executable file
BIN
payloads/OpenCore/ocvalidate
Executable file
Binary file not shown.
BIN
payloads/Tools/RSRRepair
Executable file
BIN
payloads/Tools/RSRRepair
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -3,3 +3,4 @@ pyobjc
|
||||
wxpython
|
||||
pyinstaller
|
||||
packaging
|
||||
py_sip_xnu
|
||||
@@ -1,5 +1,7 @@
|
||||
import sys
|
||||
from resources import defaults, build, utilities, validation, sys_patch, sys_patch_auto
|
||||
from resources import defaults, utilities, validation
|
||||
from resources.sys_patch import sys_patch, sys_patch_auto
|
||||
from resources.build import build
|
||||
from data import model_array
|
||||
import threading
|
||||
import time
|
||||
@@ -92,7 +94,7 @@ class arguments:
|
||||
print("- Building for natively supported model")
|
||||
settings.allow_oc_everywhere = True
|
||||
settings.serial_settings = "None"
|
||||
build.BuildOpenCore(settings.custom_model or settings.computer.real_model, settings).build_opencore()
|
||||
build.build_opencore(settings.custom_model or settings.computer.real_model, settings).build_opencore()
|
||||
elif self.args.patch_sys_vol:
|
||||
print("- Set System Volume patching")
|
||||
|
||||
@@ -110,4 +112,4 @@ class arguments:
|
||||
sys_patch.PatchSysVolume(settings.custom_model or settings.computer.real_model, settings, None).start_unpatch()
|
||||
elif self.args.auto_patch:
|
||||
print("- Set Auto patching")
|
||||
sys_patch_auto.AutomaticSysPatch.start_auto_patch(settings)
|
||||
sys_patch_auto.AutomaticSysPatch(settings).start_auto_patch()
|
||||
292
resources/bplist.py
Normal file
292
resources/bplist.py
Normal file
@@ -0,0 +1,292 @@
|
||||
#################################################################################
|
||||
# Copyright (C) 2009-2011 Vladimir "Farcaller" Pouzanov <farcaller@gmail.com> #
|
||||
# #
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy #
|
||||
# of this software and associated documentation files (the "Software"), to deal #
|
||||
# in the Software without restriction, including without limitation the rights #
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell #
|
||||
# copies of the Software, and to permit persons to whom the Software is #
|
||||
# furnished to do so, subject to the following conditions: #
|
||||
# #
|
||||
# The above copyright notice and this permission notice shall be included in #
|
||||
# all copies or substantial portions of the Software. #
|
||||
# #
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, #
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN #
|
||||
# THE SOFTWARE. #
|
||||
#################################################################################
|
||||
|
||||
import struct
|
||||
import codecs
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
class BPListWriter(object):
|
||||
def __init__(self, objects):
|
||||
self.bplist = ""
|
||||
self.objects = objects
|
||||
|
||||
def binary(self):
|
||||
'''binary -> string
|
||||
|
||||
Generates bplist
|
||||
'''
|
||||
self.data = 'bplist00'
|
||||
|
||||
# TODO: flatten objects and count max length size
|
||||
|
||||
# TODO: write objects and save offsets
|
||||
|
||||
# TODO: write offsets
|
||||
|
||||
# TODO: write metadata
|
||||
|
||||
return self.data
|
||||
|
||||
def write(self, filename):
|
||||
'''
|
||||
|
||||
Writes bplist to file
|
||||
'''
|
||||
if self.bplist != "":
|
||||
pass
|
||||
# TODO: save self.bplist to file
|
||||
else:
|
||||
raise Exception('BPlist not yet generated')
|
||||
|
||||
class BPListReader(object):
|
||||
def __init__(self, s):
|
||||
self.data = s
|
||||
self.objects = []
|
||||
self.resolved = {}
|
||||
|
||||
def __unpackIntStruct(self, sz, s):
|
||||
'''__unpackIntStruct(size, string) -> int
|
||||
|
||||
Unpacks the integer of given size (1, 2 or 4 bytes) from string
|
||||
'''
|
||||
if sz == 1:
|
||||
ot = '!B'
|
||||
elif sz == 2:
|
||||
ot = '!H'
|
||||
elif sz == 4:
|
||||
ot = '!I'
|
||||
elif sz == 8:
|
||||
ot = '!Q'
|
||||
else:
|
||||
raise Exception('int unpack size '+str(sz)+' unsupported')
|
||||
return struct.unpack(ot, s)[0]
|
||||
|
||||
def __unpackInt(self, offset):
|
||||
'''__unpackInt(offset) -> int
|
||||
|
||||
Unpacks int field from plist at given offset
|
||||
'''
|
||||
return self.__unpackIntMeta(offset)[1]
|
||||
|
||||
def __unpackIntMeta(self, offset):
|
||||
'''__unpackIntMeta(offset) -> (size, int)
|
||||
|
||||
Unpacks int field from plist at given offset and returns its size and value
|
||||
'''
|
||||
obj_header = self.data[offset]
|
||||
obj_type, obj_info = (obj_header & 0xF0), (obj_header & 0x0F)
|
||||
int_sz = 2**obj_info
|
||||
return int_sz, self.__unpackIntStruct(int_sz, self.data[offset+1:offset+1+int_sz])
|
||||
|
||||
def __resolveIntSize(self, obj_info, offset):
|
||||
'''__resolveIntSize(obj_info, offset) -> (count, offset)
|
||||
|
||||
Calculates count of objref* array entries and returns count and offset to first element
|
||||
'''
|
||||
if obj_info == 0x0F:
|
||||
ofs, obj_count = self.__unpackIntMeta(offset+1)
|
||||
objref = offset+2+ofs
|
||||
else:
|
||||
obj_count = obj_info
|
||||
objref = offset+1
|
||||
return obj_count, objref
|
||||
|
||||
def __unpackFloatStruct(self, sz, s):
|
||||
'''__unpackFloatStruct(size, string) -> float
|
||||
|
||||
Unpacks the float of given size (4 or 8 bytes) from string
|
||||
'''
|
||||
if sz == 4:
|
||||
ot = '!f'
|
||||
elif sz == 8:
|
||||
ot = '!d'
|
||||
else:
|
||||
raise Exception('float unpack size '+str(sz)+' unsupported')
|
||||
return struct.unpack(ot, s)[0]
|
||||
|
||||
def __unpackFloat(self, offset):
|
||||
'''__unpackFloat(offset) -> float
|
||||
|
||||
Unpacks float field from plist at given offset
|
||||
'''
|
||||
obj_header = self.data[offset]
|
||||
obj_type, obj_info = (obj_header & 0xF0), (obj_header & 0x0F)
|
||||
int_sz = 2**obj_info
|
||||
return int_sz, self.__unpackFloatStruct(int_sz, self.data[offset+1:offset+1+int_sz])
|
||||
|
||||
def __unpackDate(self, offset):
|
||||
td = int(struct.unpack(">d", self.data[offset+1:offset+9])[0])
|
||||
return datetime(year=2001,month=1,day=1) + timedelta(seconds=td)
|
||||
|
||||
def __unpackItem(self, offset):
|
||||
'''__unpackItem(offset)
|
||||
|
||||
Unpacks and returns an item from plist
|
||||
'''
|
||||
obj_header = self.data[offset]
|
||||
obj_type, obj_info = (obj_header & 0xF0), (obj_header & 0x0F)
|
||||
if obj_type == 0x00:
|
||||
if obj_info == 0x00: # null 0000 0000
|
||||
return None
|
||||
elif obj_info == 0x08: # bool 0000 1000 // false
|
||||
return False
|
||||
elif obj_info == 0x09: # bool 0000 1001 // true
|
||||
return True
|
||||
elif obj_info == 0x0F: # fill 0000 1111 // fill byte
|
||||
raise Exception("0x0F Not Implemented") # this is really pad byte, FIXME
|
||||
else:
|
||||
raise Exception('unpack item type '+str(obj_header)+' at '+str(offset)+ 'failed')
|
||||
elif obj_type == 0x10: # int 0001 nnnn ... // # of bytes is 2^nnnn, big-endian bytes
|
||||
return self.__unpackInt(offset)
|
||||
elif obj_type == 0x20: # real 0010 nnnn ... // # of bytes is 2^nnnn, big-endian bytes
|
||||
return self.__unpackFloat(offset)
|
||||
elif obj_type == 0x30: # date 0011 0011 ... // 8 byte float follows, big-endian bytes
|
||||
return self.__unpackDate(offset)
|
||||
elif obj_type == 0x40: # data 0100 nnnn [int] ... // nnnn is number of bytes unless 1111 then int count follows, followed by bytes
|
||||
obj_count, objref = self.__resolveIntSize(obj_info, offset)
|
||||
return self.data[objref:objref+obj_count] # XXX: we return data as str
|
||||
elif obj_type == 0x50: # string 0101 nnnn [int] ... // ASCII string, nnnn is # of chars, else 1111 then int count, then bytes
|
||||
obj_count, objref = self.__resolveIntSize(obj_info, offset)
|
||||
return self.data[objref:objref+obj_count]
|
||||
elif obj_type == 0x60: # string 0110 nnnn [int] ... // Unicode string, nnnn is # of chars, else 1111 then int count, then big-endian 2-byte uint16_t
|
||||
obj_count, objref = self.__resolveIntSize(obj_info, offset)
|
||||
return self.data[objref:objref+obj_count*2].decode('utf-16be')
|
||||
elif obj_type == 0x80: # uid 1000 nnnn ... // nnnn+1 is # of bytes
|
||||
# FIXME: Accept as a string for now
|
||||
obj_count, objref = self.__resolveIntSize(obj_info, offset)
|
||||
return self.data[objref:objref+obj_count]
|
||||
elif obj_type == 0xA0: # array 1010 nnnn [int] objref* // nnnn is count, unless '1111', then int count follows
|
||||
obj_count, objref = self.__resolveIntSize(obj_info, offset)
|
||||
arr = []
|
||||
for i in range(obj_count):
|
||||
arr.append(self.__unpackIntStruct(self.object_ref_size, self.data[objref+i*self.object_ref_size:objref+i*self.object_ref_size+self.object_ref_size]))
|
||||
return arr
|
||||
elif obj_type == 0xC0: # set 1100 nnnn [int] objref* // nnnn is count, unless '1111', then int count follows
|
||||
# XXX: not serializable via apple implementation
|
||||
raise Exception("0xC0 Not Implemented") # FIXME: implement
|
||||
elif obj_type == 0xD0: # dict 1101 nnnn [int] keyref* objref* // nnnn is count, unless '1111', then int count follows
|
||||
obj_count, objref = self.__resolveIntSize(obj_info, offset)
|
||||
keys = []
|
||||
for i in range(obj_count):
|
||||
keys.append(self.__unpackIntStruct(self.object_ref_size, self.data[objref+i*self.object_ref_size:objref+i*self.object_ref_size+self.object_ref_size]))
|
||||
values = []
|
||||
objref += obj_count*self.object_ref_size
|
||||
for i in range(obj_count):
|
||||
values.append(self.__unpackIntStruct(self.object_ref_size, self.data[objref+i*self.object_ref_size:objref+i*self.object_ref_size+self.object_ref_size]))
|
||||
dic = {}
|
||||
for i in range(obj_count):
|
||||
dic[keys[i]] = values[i]
|
||||
return dic
|
||||
else:
|
||||
raise Exception('don\'t know how to unpack obj type '+hex(obj_type)+' at '+str(offset))
|
||||
|
||||
def __resolveObject(self, idx):
|
||||
try:
|
||||
return self.resolved[idx]
|
||||
except KeyError:
|
||||
obj = self.objects[idx]
|
||||
if type(obj) == list:
|
||||
newArr = []
|
||||
for i in obj:
|
||||
newArr.append(self.__resolveObject(i))
|
||||
self.resolved[idx] = newArr
|
||||
return newArr
|
||||
if type(obj) == dict:
|
||||
newDic = {}
|
||||
for k,v in obj.items():
|
||||
key_resolved = self.__resolveObject(k)
|
||||
if isinstance(key_resolved, str):
|
||||
rk = key_resolved
|
||||
else:
|
||||
rk = codecs.decode(key_resolved, "utf-8")
|
||||
rv = self.__resolveObject(v)
|
||||
newDic[rk] = rv
|
||||
self.resolved[idx] = newDic
|
||||
return newDic
|
||||
else:
|
||||
self.resolved[idx] = obj
|
||||
return obj
|
||||
|
||||
def parse(self):
|
||||
# read header
|
||||
if self.data[:8] != b'bplist00':
|
||||
raise Exception('Bad magic')
|
||||
|
||||
# read trailer
|
||||
self.offset_size, self.object_ref_size, self.number_of_objects, self.top_object, self.table_offset = struct.unpack('!6xBB4xI4xI4xI', self.data[-32:])
|
||||
#print "** plist offset_size:",self.offset_size,"objref_size:",self.object_ref_size,"num_objs:",self.number_of_objects,"top:",self.top_object,"table_ofs:",self.table_offset
|
||||
|
||||
# read offset table
|
||||
self.offset_table = self.data[self.table_offset:-32]
|
||||
self.offsets = []
|
||||
ot = self.offset_table
|
||||
for i in range(self.number_of_objects):
|
||||
offset_entry = ot[:self.offset_size]
|
||||
ot = ot[self.offset_size:]
|
||||
self.offsets.append(self.__unpackIntStruct(self.offset_size, offset_entry))
|
||||
#print "** plist offsets:",self.offsets
|
||||
|
||||
# read object table
|
||||
self.objects = []
|
||||
k = 0
|
||||
for i in self.offsets:
|
||||
obj = self.__unpackItem(i)
|
||||
#print "** plist unpacked",k,type(obj),obj,"at",i
|
||||
k += 1
|
||||
self.objects.append(obj)
|
||||
|
||||
# rebuild object tree
|
||||
#for i in range(len(self.objects)):
|
||||
# self.__resolveObject(i)
|
||||
|
||||
# return root object
|
||||
return self.__resolveObject(self.top_object)
|
||||
|
||||
@classmethod
|
||||
def plistWithString(cls, s):
|
||||
parser = cls(s)
|
||||
return parser.parse()
|
||||
|
||||
# helpers for testing
|
||||
def plist(obj):
|
||||
from Foundation import NSPropertyListSerialization, NSPropertyListBinaryFormat_v1_0
|
||||
b = NSPropertyListSerialization.dataWithPropertyList_format_options_error_(obj, NSPropertyListBinaryFormat_v1_0, 0, None)
|
||||
return str(b.bytes())
|
||||
|
||||
def unplist(s):
|
||||
from Foundation import NSData, NSPropertyListSerialization
|
||||
d = NSData.dataWithBytes_length_(s, len(s))
|
||||
return NSPropertyListSerialization.propertyListWithData_options_format_error_(d, 0, None, None)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
file_path = sys.argv[1]
|
||||
|
||||
with open(file_path, "rb") as fp:
|
||||
data = fp.read()
|
||||
|
||||
out = BPListReader(data).parse()
|
||||
|
||||
with open(file_path + ".json", "w") as fp:
|
||||
json.dump(out, indent=4)
|
||||
1540
resources/build.py
1540
resources/build.py
File diff suppressed because it is too large
Load Diff
57
resources/build/bluetooth.py
Normal file
57
resources/build/bluetooth.py
Normal file
@@ -0,0 +1,57 @@
|
||||
# Class for handling Bluetooth Patches, invocation from build.py
|
||||
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
|
||||
|
||||
from resources import constants, device_probe
|
||||
from resources.build import support
|
||||
from data import smbios_data, bluetooth_data
|
||||
|
||||
class build_bluetooth:
|
||||
|
||||
def __init__(self, model, versions, config):
|
||||
self.model = model
|
||||
self.constants: constants.Constants = versions
|
||||
self.config = config
|
||||
self.computer = self.constants.computer
|
||||
|
||||
|
||||
def build(self):
|
||||
# Bluetooth patches
|
||||
if not self.constants.custom_model and self.computer.bluetooth_chipset:
|
||||
self.on_model()
|
||||
else:
|
||||
self.prebuilt_assumption()
|
||||
|
||||
|
||||
def on_model(self):
|
||||
if self.computer.bluetooth_chipset in ["BRCM2070 Hub", "BRCM2046 Hub"]:
|
||||
print("- Fixing Legacy Bluetooth for macOS Monterey")
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("BlueToolFixup.kext", self.constants.bluetool_version, self.constants.bluetool_path)
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("Bluetooth-Spoof.kext", self.constants.btspoof_version, self.constants.btspoof_path)
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -btlfxallowanyaddr"
|
||||
elif self.computer.bluetooth_chipset == "BRCM20702 Hub":
|
||||
# BCM94331 can include either BCM2070 or BRCM20702 v1 Bluetooth chipsets
|
||||
# Note Monterey only natively supports BRCM20702 v2 (found with BCM94360)
|
||||
# Due to this, BlueToolFixup is required to resolve Firmware Uploading on legacy chipsets
|
||||
if self.computer.wifi:
|
||||
if self.computer.wifi.chipset == device_probe.Broadcom.Chipsets.AirPortBrcm4360:
|
||||
print("- Fixing Legacy Bluetooth for macOS Monterey")
|
||||
support.build_support(self.model, self.constants, self.config).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 Bluetooth Chipset")
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("BlueToolFixup.kext", self.constants.bluetool_version, self.constants.bluetool_path)
|
||||
print("- Enabling Bluetooth FeatureFlags")
|
||||
self.config["Kernel"]["Quirks"]["ExtendBTFeatureFlags"] = True
|
||||
|
||||
|
||||
def prebuilt_assumption(self):
|
||||
if not self.model in smbios_data.smbios_dictionary:
|
||||
return
|
||||
if not "Bluetooth Model" in smbios_data.smbios_dictionary[self.model]:
|
||||
return
|
||||
|
||||
if smbios_data.smbios_dictionary[self.model]["Bluetooth Model"] <= bluetooth_data.bluetooth_data.BRCM20702_v1.value:
|
||||
print("- Fixing Legacy Bluetooth for macOS Monterey")
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("BlueToolFixup.kext", self.constants.bluetool_version, self.constants.bluetool_path)
|
||||
if smbios_data.smbios_dictionary[self.model]["Bluetooth Model"] <= bluetooth_data.bluetooth_data.BRCM2070.value:
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -btlfxallowanyaddr"
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("Bluetooth-Spoof.kext", self.constants.btspoof_version, self.constants.btspoof_path)
|
||||
123
resources/build/build.py
Normal file
123
resources/build/build.py
Normal file
@@ -0,0 +1,123 @@
|
||||
# Class for generating OpenCore Configurations tailored for Macs
|
||||
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
|
||||
|
||||
import copy
|
||||
import pickle
|
||||
import plistlib
|
||||
import shutil
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
from datetime import date
|
||||
|
||||
from resources import constants, utilities
|
||||
from resources.build import bluetooth, firmware, graphics_audio, support, storage, smbios, security, misc
|
||||
from resources.build.networking import wired, wireless
|
||||
|
||||
|
||||
def rmtree_handler(func, path, exc_info):
|
||||
if exc_info[0] == FileNotFoundError:
|
||||
return
|
||||
raise # pylint: disable=misplaced-bare-raise
|
||||
|
||||
|
||||
class build_opencore:
|
||||
def __init__(self, model, versions):
|
||||
self.model = model
|
||||
self.config = None
|
||||
self.constants: constants.Constants = versions
|
||||
|
||||
|
||||
def build_efi(self):
|
||||
utilities.cls()
|
||||
if not self.constants.custom_model:
|
||||
print(f"Building Configuration on model: {self.model}")
|
||||
else:
|
||||
print(f"Building Configuration for external model: {self.model}")
|
||||
|
||||
self.generate_base()
|
||||
self.set_revision()
|
||||
|
||||
# Set Lilu and co.
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("Lilu.kext", self.constants.lilu_version, self.constants.lilu_path)
|
||||
self.config["Kernel"]["Quirks"]["DisableLinkeditJettison"] = True
|
||||
|
||||
# Call support functions
|
||||
firmware.build_firmware(self.model, self.constants, self.config).build()
|
||||
wired.build_wired(self.model, self.constants, self.config).build()
|
||||
wireless.build_wireless(self.model, self.constants, self.config).build()
|
||||
graphics_audio.build_graphics_audio(self.model, self.constants, self.config).build()
|
||||
bluetooth.build_bluetooth(self.model, self.constants, self.config).build()
|
||||
storage.build_storage(self.model, self.constants, self.config).build()
|
||||
smbios.build_smbios(self.model, self.constants, self.config).build()
|
||||
security.build_security(self.model, self.constants, self.config).build()
|
||||
misc.build_misc(self.model, self.constants, self.config).build()
|
||||
|
||||
# Work-around ocvalidate
|
||||
if self.constants.validate is False:
|
||||
print("- Adding bootmgfw.efi BlessOverride")
|
||||
self.config["Misc"]["BlessOverride"] += ["\\EFI\\Microsoft\\Boot\\bootmgfw.efi"]
|
||||
|
||||
|
||||
def generate_base(self):
|
||||
# Generate OpenCore base folder and config
|
||||
if not Path(self.constants.build_path).exists():
|
||||
print("Creating build folder")
|
||||
Path(self.constants.build_path).mkdir()
|
||||
else:
|
||||
print("Build folder already present, skipping")
|
||||
|
||||
if Path(self.constants.opencore_zip_copied).exists():
|
||||
print("Deleting old copy of OpenCore zip")
|
||||
Path(self.constants.opencore_zip_copied).unlink()
|
||||
if Path(self.constants.opencore_release_folder).exists():
|
||||
print("Deleting old copy of OpenCore folder")
|
||||
shutil.rmtree(self.constants.opencore_release_folder, onerror=rmtree_handler, ignore_errors=True)
|
||||
|
||||
print(f"\n- Adding OpenCore v{self.constants.opencore_version} {self.constants.opencore_build}")
|
||||
shutil.copy(self.constants.opencore_zip_source, self.constants.build_path)
|
||||
zipfile.ZipFile(self.constants.opencore_zip_copied).extractall(self.constants.build_path)
|
||||
|
||||
# Setup config.plist for editing
|
||||
print("- Adding config.plist for OpenCore")
|
||||
shutil.copy(self.constants.plist_template, self.constants.oc_folder)
|
||||
self.config = plistlib.load(Path(self.constants.plist_path).open("rb"))
|
||||
|
||||
|
||||
def set_revision(self):
|
||||
# Set revision in config
|
||||
self.config["#Revision"]["Build-Version"] = f"{self.constants.patcher_version} - {date.today()}"
|
||||
if not self.constants.custom_model:
|
||||
self.config["#Revision"]["Build-Type"] = "OpenCore Built on Target Machine"
|
||||
computer_copy = copy.copy(self.constants.computer)
|
||||
computer_copy.ioregistry = None
|
||||
self.config["#Revision"]["Hardware-Probe"] = pickle.dumps(computer_copy)
|
||||
else:
|
||||
self.config["#Revision"]["Build-Type"] = "OpenCore Built for External Machine"
|
||||
self.config["#Revision"]["OpenCore-Version"] = f"{self.constants.opencore_version} - {self.constants.opencore_build} - {self.constants.opencore_commit}"
|
||||
self.config["#Revision"]["Original-Model"] = self.model
|
||||
self.config["NVRAM"]["Add"]["4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102"]["OCLP-Version"] = f"{self.constants.patcher_version}"
|
||||
self.config["NVRAM"]["Add"]["4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102"]["OCLP-Model"] = self.model
|
||||
|
||||
|
||||
def save_config(self):
|
||||
plistlib.dump(self.config, Path(self.constants.plist_path).open("wb"), sort_keys=True)
|
||||
|
||||
|
||||
def build_opencore(self):
|
||||
# Generate OpenCore Configuration
|
||||
self.build_efi()
|
||||
if self.constants.allow_oc_everywhere is False or self.constants.allow_native_spoofs is True or (self.constants.custom_serial_number != "" and self.constants.custom_board_serial_number != ""):
|
||||
smbios.build_smbios(self.model, self.constants, self.config).set_smbios()
|
||||
support.build_support(self.model, self.constants, self.config).cleanup()
|
||||
self.save_config()
|
||||
|
||||
# Post-build handling
|
||||
support.build_support(self.model, self.constants, self.config).sign_files()
|
||||
support.build_support(self.model, self.constants, self.config).validate_pathing()
|
||||
|
||||
print("")
|
||||
print(f"Your OpenCore EFI for {self.model} has been built at:")
|
||||
print(f" {self.constants.opencore_release_folder}")
|
||||
print("")
|
||||
if self.constants.gui_mode is False:
|
||||
input("Press [Enter] to continue\n")
|
||||
264
resources/build/firmware.py
Normal file
264
resources/build/firmware.py
Normal file
@@ -0,0 +1,264 @@
|
||||
# Class for handling CPU and Firmware Patches, invocation from build.py
|
||||
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
|
||||
|
||||
from resources import constants, generate_smbios
|
||||
from resources.build import support
|
||||
from data import smbios_data, cpu_data
|
||||
|
||||
import binascii, shutil
|
||||
from pathlib import Path
|
||||
|
||||
class build_firmware:
|
||||
|
||||
def __init__(self, model, versions, config):
|
||||
self.model = model
|
||||
self.constants: constants.Constants = versions
|
||||
self.config = config
|
||||
self.computer = self.constants.computer
|
||||
|
||||
|
||||
def build(self):
|
||||
self.cpu_compatibility_handling()
|
||||
self.power_management_handling()
|
||||
self.acpi_handling()
|
||||
self.firmware_driver_handling()
|
||||
self.firmware_compatibility_handling()
|
||||
|
||||
|
||||
def power_management_handling(self):
|
||||
if not self.model in smbios_data.smbios_dictionary:
|
||||
return
|
||||
if not "CPU Generation" in smbios_data.smbios_dictionary[self.model]:
|
||||
return
|
||||
|
||||
if smbios_data.smbios_dictionary[self.model]["CPU Generation"] <= cpu_data.cpu_data.ivy_bridge.value:
|
||||
# In macOS Ventura, Apple dropped AppleIntelCPUPowerManagement* kexts as they're unused on Haswell+
|
||||
# However re-injecting the AICPUPM kexts is not enough, as Ventura changed how 'intel_cpupm_matching' is set:
|
||||
# macOS 12.5: https://github.com/apple-oss-distributions/xnu/blob/xnu-8020.140.41/osfmk/i386/pal_routines.h#L153-L163
|
||||
# macOS 13.0: https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/osfmk/i386/pal_routines.h#L153-L164
|
||||
#
|
||||
# Specifically Apple has this logic for power management:
|
||||
# - 0: Kext Based Power Management
|
||||
# - 3: Kernel Based Power Management (For Haswell+ and Virtual Machines)
|
||||
# - 4: Generic Virtual Machine Power Management
|
||||
#
|
||||
# Apple determines which to use by verifying whether 'plugin-type' exists in ACPI (with a value of 1 for Haswell, 2 for VMs)
|
||||
# By default however, the plugin-type is not set, and thus the default value of '0' is used
|
||||
# https://github.com/apple-oss-distributions/xnu/blob/e7776783b89a353188416a9a346c6cdb4928faad/osfmk/i386/pal_native.h#L62
|
||||
#
|
||||
# With Ventura, Apple no longer sets '0' as the default value, and instead sets it to '3'
|
||||
# This breaks AppleIntelCPUPowerManagement.kext matching as it no longer matches against the correct criteria
|
||||
#
|
||||
# To resolve, we patched AICPUPM to attach regardless of the value of 'intel_cpupm_matching'
|
||||
print("- Enabling legacy power management support")
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("AppleIntelCPUPowerManagement.kext", self.constants.aicpupm_version, self.constants.aicpupm_path)
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("AppleIntelCPUPowerManagementClient.kext", self.constants.aicpupm_version, self.constants.aicpupm_client_path)
|
||||
|
||||
if smbios_data.smbios_dictionary[self.model]["CPU Generation"] <= cpu_data.cpu_data.sandy_bridge.value or self.constants.disable_xcpm is True:
|
||||
# With macOS 12.3 Beta 1, Apple dropped the 'plugin-type' check within X86PlatformPlugin
|
||||
# Because of this, X86PP will match onto the CPU instead of ACPI_SMC_PlatformPlugin
|
||||
# This causes power management to break on pre-Ivy Bridge CPUs as they don't have correct
|
||||
# power management tables provided.
|
||||
# This patch will simply increase ASPP's 'IOProbeScore' to outmatch X86PP
|
||||
print("- Overriding ACPI SMC matching")
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("ASPP-Override.kext", self.constants.aspp_override_version, self.constants.aspp_override_path)
|
||||
if self.constants.disable_xcpm is True:
|
||||
# Only inject on older OSes if user requests
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Add"], "BundlePath", "ASPP-Override.kext")["MinKernel"] = ""
|
||||
|
||||
if self.constants.disable_msr_power_ctl is True and smbios_data.smbios_dictionary[self.model]["CPU Generation"] >= cpu_data.cpu_data.nehalem.value:
|
||||
print("- Disabling Firmware Throttling")
|
||||
# Nehalem and newer systems force firmware throttling via MSR_POWER_CTL
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("SimpleMSR.kext", self.constants.simplemsr_version, self.constants.simplemsr_path)
|
||||
|
||||
|
||||
def acpi_handling(self):
|
||||
if not self.model in smbios_data.smbios_dictionary:
|
||||
return
|
||||
if not "CPU Generation" in smbios_data.smbios_dictionary[self.model]:
|
||||
return
|
||||
|
||||
# Resolves Big Sur support for consumer Nehalem
|
||||
# CPBG device in ACPI is a Co-Processor Bridge Device, which is not actually physically present
|
||||
# IOPCIFamily will error when enumerating this device, thus we'll power it off via _STA (has no effect in older OSes)
|
||||
if smbios_data.smbios_dictionary[self.model]["CPU Generation"] == cpu_data.cpu_data.nehalem.value and not (self.model.startswith("MacPro") or self.model.startswith("Xserve")):
|
||||
print("- Adding SSDT-CPBG.aml")
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["ACPI"]["Add"], "Path", "SSDT-CPBG.aml")["Enabled"] = True
|
||||
shutil.copy(self.constants.pci_ssdt_path, self.constants.acpi_path)
|
||||
|
||||
if cpu_data.cpu_data.sandy_bridge <= smbios_data.smbios_dictionary[self.model]["CPU Generation"] <= cpu_data.cpu_data.ivy_bridge.value and self.model != "MacPro6,1":
|
||||
# Based on: https://egpu.io/forums/pc-setup/fix-dsdt-override-to-correct-error-12/
|
||||
# Applicable for Sandy and Ivy Bridge Macs
|
||||
print("- Enabling Windows 10 UEFI Audio support")
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["ACPI"]["Add"], "Path", "SSDT-PCI.aml")["Enabled"] = True
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["ACPI"]["Patch"], "Comment", "BUF0 to BUF1")["Enabled"] = True
|
||||
shutil.copy(self.constants.windows_ssdt_path, self.constants.acpi_path)
|
||||
|
||||
|
||||
def cpu_compatibility_handling(self):
|
||||
if not self.model in smbios_data.smbios_dictionary:
|
||||
return
|
||||
if not "CPU Generation" in smbios_data.smbios_dictionary[self.model]:
|
||||
return
|
||||
|
||||
# SSE4,1 support (ie. Penryn)
|
||||
# Required for macOS Mojave and newer
|
||||
if smbios_data.smbios_dictionary[self.model]["CPU Generation"] <= cpu_data.cpu_data.penryn.value:
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("AAAMouSSE.kext", self.constants.mousse_version, self.constants.mousse_path)
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("telemetrap.kext", self.constants.telemetrap_version, self.constants.telemetrap_path)
|
||||
|
||||
# Force Rosetta Cryptex installation in macOS Ventura
|
||||
# Restores support for CPUs lacking AVX2.0 support
|
||||
if smbios_data.smbios_dictionary[self.model]["CPU Generation"] <= cpu_data.cpu_data.ivy_bridge.value:
|
||||
print("- Enabling Rosetta Cryptex support in Ventura")
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("CryptexFixup.kext", self.constants.cryptexfixup_version, self.constants.cryptexfixup_path)
|
||||
|
||||
# i3 Ivy Bridge iMacs don't support RDRAND
|
||||
# However for prebuilt, assume they do
|
||||
if (not self.constants.custom_model and "RDRAND" not in self.computer.cpu.flags) or \
|
||||
(smbios_data.smbios_dictionary[self.model]["CPU Generation"] <= cpu_data.cpu_data.sandy_bridge.value):
|
||||
# Ref: https://github.com/reenigneorcim/SurPlus
|
||||
# Enable for all systems missing RDRAND support
|
||||
print("- Adding SurPlus Patch for Race Condition")
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "SurPlus v1 - PART 1 of 2 - Patch read_erandom (inlined in _early_random)")["Enabled"] = True
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "SurPlus v1 - PART 2 of 2 - Patch register_and_init_prng")["Enabled"] = True
|
||||
if self.constants.force_surplus is True:
|
||||
# Syncretic forces SurPlus to only run on Beta 7 and older by default for saftey reasons
|
||||
# If users desires, allow forcing in newer OSes
|
||||
print("- Allowing SurPlus on all newer OSes")
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "SurPlus v1 - PART 1 of 2 - Patch read_erandom (inlined in _early_random)")["MaxKernel"] = ""
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "SurPlus v1 - PART 2 of 2 - Patch register_and_init_prng")["MaxKernel"] = ""
|
||||
|
||||
# In macOS 12.4 and 12.5 Beta 1, Apple added AVX1.0 usage in AppleFSCompressionTypeZlib
|
||||
# Pre-Sandy Bridge CPUs don't support AVX1.0, thus we'll downgrade the kext to 12.3.1's
|
||||
# Currently a (hopefully) temporary workaround for the issue, proper fix needs to be investigated
|
||||
# Ref:
|
||||
# https://forums.macrumors.com/threads/macos-12-monterey-on-unsupported-macs-thread.2299557/post-31120235
|
||||
# https://forums.macrumors.com/threads/monterand-probably-the-start-of-an-ongoing-saga.2320479/post-31123553
|
||||
|
||||
# To verify the non-AVX kext is used, check IOService for 'com_apple_AppleFSCompression_NoAVXCompressionTypeZlib'
|
||||
if smbios_data.smbios_dictionary[self.model]["CPU Generation"] < cpu_data.cpu_data.sandy_bridge.value:
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("NoAVXFSCompressionTypeZlib.kext", self.constants.apfs_zlib_version, self.constants.apfs_zlib_path)
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("NoAVXFSCompressionTypeZlib-AVXpel.kext", self.constants.apfs_zlib_v2_version, self.constants.apfs_zlib_v2_path)
|
||||
|
||||
# HID patches
|
||||
if smbios_data.smbios_dictionary[self.model]["CPU Generation"] <= cpu_data.cpu_data.penryn.value:
|
||||
print("- Adding IOHIDFamily patch")
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Identifier", "com.apple.iokit.IOHIDFamily")["Enabled"] = True
|
||||
|
||||
|
||||
def firmware_driver_handling(self):
|
||||
# Firmware Drivers (Drivers/*.efi)
|
||||
if not self.model in smbios_data.smbios_dictionary:
|
||||
return
|
||||
if not "CPU Generation" in smbios_data.smbios_dictionary[self.model]:
|
||||
return
|
||||
|
||||
# Exfat check
|
||||
if smbios_data.smbios_dictionary[self.model]["CPU Generation"] < cpu_data.cpu_data.sandy_bridge.value:
|
||||
# Sandy Bridge and newer Macs natively support ExFat
|
||||
print("- Adding ExFatDxeLegacy.efi")
|
||||
shutil.copy(self.constants.exfat_legacy_driver_path, self.constants.drivers_path)
|
||||
support.build_support(self.model, self.constants, self.config).get_efi_binary_by_path("ExFatDxeLegacy.efi", "UEFI", "Drivers")["Enabled"] = True
|
||||
|
||||
# NVMe check
|
||||
if self.constants.nvme_boot is True:
|
||||
print("- Enabling NVMe boot support")
|
||||
shutil.copy(self.constants.nvme_driver_path, self.constants.drivers_path)
|
||||
support.build_support(self.model, self.constants, self.config).get_efi_binary_by_path("NvmExpressDxe.efi", "UEFI", "Drivers")["Enabled"] = True
|
||||
|
||||
# USB check
|
||||
if self.constants.xhci_boot is True:
|
||||
print("- Adding USB 3.0 Controller Patch")
|
||||
print("- Adding XhciDxe.efi and UsbBusDxe.efi")
|
||||
shutil.copy(self.constants.xhci_driver_path, self.constants.drivers_path)
|
||||
shutil.copy(self.constants.usb_bus_driver_path, self.constants.drivers_path)
|
||||
support.build_support(self.model, self.constants, self.config).get_efi_binary_by_path("XhciDxe.efi", "UEFI", "Drivers")["Enabled"] = True
|
||||
support.build_support(self.model, self.constants, self.config).get_efi_binary_by_path("UsbBusDxe.efi", "UEFI", "Drivers")["Enabled"] = True
|
||||
|
||||
# PCIe Link Rate check
|
||||
if self.model == "MacPro3,1":
|
||||
print("- Adding PCIe Link Rate Patch")
|
||||
shutil.copy(self.constants.link_rate_driver_path, self.constants.drivers_path)
|
||||
support.build_support(self.model, self.constants, self.config).get_efi_binary_by_path("FixPCIeLinkRate.efi", "UEFI", "Drivers")["Enabled"] = True
|
||||
|
||||
|
||||
def firmware_compatibility_handling(self):
|
||||
self.dual_dp_handling()
|
||||
|
||||
# Force VMM as a temporary solution to getting the MacPro6,1 booting in Ventura
|
||||
# With macOS Ventura, Apple removed AppleIntelCPUPowerManagement.kext and assumed XCPM support across all Macs
|
||||
# This change resulted in broken OS booting as the machine had no power management support
|
||||
# Currently the AICPUPM fix is not fully functional, thus forcing VMM is a temporary solution
|
||||
# Waiting for XNU source to be released to fix this properly
|
||||
# Ref: https://forums.macrumors.com/threads/opencore-on-the-mac-pro.2207814/
|
||||
if self.model in ["MacPro6,1", "iMac7,1", "iMac8,1", "MacBookPro4,1"] or self.constants.set_vmm_cpuid is True:
|
||||
print("- Enabling VMM patch")
|
||||
self.config["Kernel"]["Emulate"]["Cpuid1Data"] = binascii.unhexlify("00000000000000000000008000000000")
|
||||
self.config["Kernel"]["Emulate"]["Cpuid1Mask"] = binascii.unhexlify("00000000000000000000008000000000")
|
||||
self.config["Kernel"]["Emulate"]["MinKernel"] = "22.0.0"
|
||||
|
||||
if (
|
||||
self.model.startswith("MacBook")
|
||||
and (
|
||||
smbios_data.smbios_dictionary[self.model]["CPU Generation"] == cpu_data.cpu_data.haswell.value or
|
||||
smbios_data.smbios_dictionary[self.model]["CPU Generation"] == cpu_data.cpu_data.broadwell.value
|
||||
)
|
||||
):
|
||||
# Fix Virtual Machine support for non-macOS OSes
|
||||
# Haswell and Broadwell MacBooks lock out the VMX bit if booting UEFI Windows
|
||||
print("- Enabling VMX Bit for non-macOS OSes")
|
||||
self.config["UEFI"]["Quirks"]["EnableVmx"] = True
|
||||
|
||||
# Works-around Hibernation bug where connecting all firmware drivers breaks the transition from S4
|
||||
# Mainly applicable for MacBookPro9,1
|
||||
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.constants.serial_settings != "None":
|
||||
# AppleMCEReporter is very picky about which models attach to the kext
|
||||
# Commonly it will kernel panic on multi-socket systems, however even on single-socket systems it may cause instability
|
||||
# To avoid any issues, we'll disable it if the spoof is set to an affected SMBIOS
|
||||
affected_smbios = ["MacPro6,1", "MacPro7,1", "iMacPro1,1"]
|
||||
if self.model not in affected_smbios:
|
||||
# If MacPro6,1 host spoofs, we can safely enable it
|
||||
if self.constants.override_smbios in affected_smbios or generate_smbios.set_smbios_model_spoof(self.model) in affected_smbios:
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("AppleMCEReporterDisabler.kext", self.constants.mce_version, self.constants.mce_path)
|
||||
|
||||
|
||||
def dual_dp_handling(self):
|
||||
# Check if model has 5K display
|
||||
# Apple has 2 modes for display handling on 5K iMacs and iMac Pro
|
||||
# If at any point in the boot chain an "unsupported" entry is loaded, the firmware will tell the
|
||||
# Display Controller to enter a 4K compatible mode that only uses a single DisplayPort 1.2 stream internally.
|
||||
# This is to prevent situations where the system would boot into an enviroment that cannot handle the custom
|
||||
# dual DisplayPort 1.2 streams the 5k Display uses
|
||||
|
||||
# To work around this issue, we trick the firmware into loading OpenCore through Apple's Hardware Diagnostic Tests
|
||||
# Specifically hiding as Product.efi under '/System/Library/CoreServices/.diagnostics/Drivers/HardwareDrivers/Product.efi'
|
||||
# The reason chainloading via ./Drivers/HardwareDrivers is possible is thanks to it being loaded via an encrypted file buffer
|
||||
# whereas other drivers like ./qa_logger.efi is invoked via Device Path.
|
||||
|
||||
if "5K Display" not in smbios_data.smbios_dictionary[self.model]:
|
||||
return
|
||||
|
||||
print("- Adding 5K Display Patch")
|
||||
# Set LauncherPath to '/boot.efi'
|
||||
# This is to ensure that only the Mac's firmware presents the boot option, but not OpenCore
|
||||
# https://github.com/acidanthera/OpenCorePkg/blob/0.7.6/Library/OcAppleBootPolicyLib/OcAppleBootPolicyLib.c#L50-L73
|
||||
self.config["Misc"]["Boot"]["LauncherPath"] = "\\boot.efi"
|
||||
|
||||
# Setup diags.efi chainloading
|
||||
Path(self.constants.opencore_release_folder / Path("System/Library/CoreServices/.diagnostics/Drivers/HardwareDrivers")).mkdir(parents=True, exist_ok=True)
|
||||
if self.constants.boot_efi is True:
|
||||
path_oc_loader = self.constants.opencore_release_folder / Path("EFI/BOOT/BOOTx64.efi")
|
||||
else:
|
||||
path_oc_loader = self.constants.opencore_release_folder / Path("System/Library/CoreServices/boot.efi")
|
||||
shutil.move(path_oc_loader, self.constants.opencore_release_folder / Path("System/Library/CoreServices/.diagnostics/Drivers/HardwareDrivers/Product.efi"))
|
||||
shutil.copy(self.constants.diags_launcher_path, self.constants.opencore_release_folder)
|
||||
shutil.move(self.constants.opencore_release_folder / Path("diags.efi"), self.constants.opencore_release_folder / Path("boot.efi"))
|
||||
419
resources/build/graphics_audio.py
Normal file
419
resources/build/graphics_audio.py
Normal file
@@ -0,0 +1,419 @@
|
||||
# Class for handling Graphics and Audio Patches, invocation from build.py
|
||||
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
|
||||
|
||||
from resources import constants, device_probe, utilities
|
||||
from resources.build import support
|
||||
from data import smbios_data, model_array, os_data, cpu_data
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import shutil, binascii
|
||||
|
||||
class build_graphics_audio:
|
||||
|
||||
def __init__(self, model, versions, config):
|
||||
self.model = model
|
||||
self.constants: constants.Constants = versions
|
||||
self.config = config
|
||||
self.computer = self.constants.computer
|
||||
|
||||
self.gfx0_path = None
|
||||
|
||||
|
||||
def build(self):
|
||||
self.graphics_handling()
|
||||
self.audio_handling()
|
||||
self.firmware_handling()
|
||||
self.spoof_handling()
|
||||
self.imac_mxm_patching()
|
||||
self.ioaccel_workaround()
|
||||
|
||||
|
||||
def graphics_handling(self):
|
||||
if self.constants.allow_oc_everywhere is False and self.constants.serial_settings != "None":
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("WhateverGreen.kext", self.constants.whatevergreen_version, self.constants.whatevergreen_path)
|
||||
|
||||
# Mac Pro handling
|
||||
if self.model in model_array.MacPro:
|
||||
if not self.constants.custom_model:
|
||||
for i, device in enumerate(self.computer.gpus):
|
||||
print(f"- Found dGPU ({i + 1}): {utilities.friendly_hex(device.vendor_id)}:{utilities.friendly_hex(device.device_id)}")
|
||||
self.config["#Revision"][f"Hardware-MacPro-dGPU-{i + 1}"] = f"{utilities.friendly_hex(device.vendor_id)}:{utilities.friendly_hex(device.device_id)}"
|
||||
|
||||
if device.pci_path and device.acpi_path:
|
||||
print(f"- Found dGPU ({i + 1}) at {device.pci_path}")
|
||||
if isinstance(device, device_probe.AMD):
|
||||
print("- Adding Mac Pro, Xserve DRM patches")
|
||||
self.config["DeviceProperties"]["Add"][device.pci_path] = {"shikigva": 128, "unfairgva": 1, "rebuild-device-tree": 1, "agdpmod": "pikera", "enable-gva-support": 1}
|
||||
elif isinstance(device, device_probe.NVIDIA):
|
||||
print("- Enabling Nvidia Output Patch")
|
||||
self.config["DeviceProperties"]["Add"][device.pci_path] = {"rebuild-device-tree": 1, "agdpmod": "vit9696"}
|
||||
self.config["UEFI"]["Quirks"]["ForgeUefiSupport"] = True
|
||||
self.config["UEFI"]["Quirks"]["ReloadOptionRoms"] = True
|
||||
|
||||
else:
|
||||
print(f"- Failed to find Device path for dGPU {i + 1}")
|
||||
if isinstance(device, device_probe.AMD):
|
||||
print("- Adding Mac Pro, Xserve DRM patches")
|
||||
if "shikigva=128 unfairgva=1" not in self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"]:
|
||||
print("- Falling back to boot-args")
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " shikigva=128 unfairgva=1 agdpmod=pikera radgva=1" + (
|
||||
" -wegtree" if "-wegtree" not in self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] else ""
|
||||
)
|
||||
elif isinstance(device, device_probe.NVIDIA):
|
||||
print("- Enabling Nvidia Output Patch")
|
||||
if "-wegtree agdpmod=vit9696" not in self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"]:
|
||||
print("- Falling back to boot-args")
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -wegtree agdpmod=vit9696"
|
||||
self.config["UEFI"]["Quirks"]["ForgeUefiSupport"] = True
|
||||
self.config["UEFI"]["Quirks"]["ReloadOptionRoms"] = True
|
||||
|
||||
if not self.computer.gpus:
|
||||
print("- No socketed dGPU found")
|
||||
|
||||
else:
|
||||
print("- Adding Mac Pro, Xserve DRM patches")
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " shikigva=128 unfairgva=1 -wegtree"
|
||||
|
||||
if not support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("WhateverGreen.kext")["Enabled"] is True:
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("WhateverGreen.kext", self.constants.whatevergreen_version, self.constants.whatevergreen_path)
|
||||
|
||||
# Web Driver specific
|
||||
if not self.constants.custom_model:
|
||||
for i, device in enumerate(self.computer.gpus):
|
||||
if isinstance(device, device_probe.NVIDIA):
|
||||
if (
|
||||
device.arch in [device_probe.NVIDIA.Archs.Fermi, device_probe.NVIDIA.Archs.Maxwell, device_probe.NVIDIA.Archs.Pascal] or
|
||||
(self.constants.force_nv_web is True and device.arch in [device_probe.NVIDIA.Archs.Tesla, device_probe.NVIDIA.Archs.Kepler])
|
||||
):
|
||||
print(f"- Enabling Web Driver Patches for GPU ({i + 1}): {utilities.friendly_hex(device.vendor_id)}:{utilities.friendly_hex(device.device_id)}")
|
||||
if device.pci_path and device.acpi_path:
|
||||
if device.pci_path in self.config["DeviceProperties"]["Add"]:
|
||||
self.config["DeviceProperties"]["Add"][device.pci_path].update({"disable-metal": 1, "force-compat": 1})
|
||||
else:
|
||||
self.config["DeviceProperties"]["Add"][device.pci_path] = {"disable-metal": 1, "force-compat": 1}
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("WhateverGreen.kext", self.constants.whatevergreen_version, self.constants.whatevergreen_path)
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"].update({"nvda_drv": binascii.unhexlify("31")})
|
||||
if "nvda_drv" not in self.config["NVRAM"]["Delete"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]:
|
||||
self.config["NVRAM"]["Delete"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"] += ["nvda_drv"]
|
||||
else:
|
||||
if "ngfxgl=1 ngfxcompat=1" not in self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"]:
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " ngfxgl=1 ngfxcompat=1"
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("WhateverGreen.kext", self.constants.whatevergreen_version, self.constants.whatevergreen_path)
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"].update({"nvda_drv": binascii.unhexlify("31")})
|
||||
if "nvda_drv" not in self.config["NVRAM"]["Delete"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]:
|
||||
self.config["NVRAM"]["Delete"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"] += ["nvda_drv"]
|
||||
|
||||
|
||||
def backlight_path_detection(self):
|
||||
if not self.constants.custom_model and self.computer.dgpu and self.computer.dgpu.pci_path:
|
||||
self.gfx0_path = self.computer.dgpu.pci_path
|
||||
print(f"- Found GFX0 Device Path: {self.gfx0_path}")
|
||||
else:
|
||||
if not self.constants.custom_model:
|
||||
print("- Failed to find GFX0 Device path, falling back on known logic")
|
||||
if self.model in ["iMac11,1", "iMac11,3"]:
|
||||
self.gfx0_path = "PciRoot(0x0)/Pci(0x3,0x0)/Pci(0x0,0x0)"
|
||||
elif self.model == "iMac10,1":
|
||||
self.gfx0_path = "PciRoot(0x0)/Pci(0xc,0x0)/Pci(0x0,0x0)"
|
||||
else:
|
||||
self.gfx0_path = "PciRoot(0x0)/Pci(0x1,0x0)/Pci(0x0,0x0)"
|
||||
|
||||
|
||||
def nvidia_mxm_patch(self, backlight_path):
|
||||
if not support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("WhateverGreen.kext")["Enabled"] is True:
|
||||
# Ensure WEG is enabled as we need if for Backlight patching
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("WhateverGreen.kext", self.constants.whatevergreen_version, self.constants.whatevergreen_path)
|
||||
if self.model in ["iMac11,1", "iMac11,2", "iMac11,3", "iMac10,1"]:
|
||||
print("- Adding Nvidia Brightness Control and DRM patches")
|
||||
self.config["DeviceProperties"]["Add"][backlight_path] = {
|
||||
"applbkl": binascii.unhexlify("01000000"),
|
||||
"@0,backlight-control": binascii.unhexlify("01000000"),
|
||||
"@0,built-in": binascii.unhexlify("01000000"),
|
||||
"shikigva": 256,
|
||||
"agdpmod": "vit9696",
|
||||
}
|
||||
if self.constants.custom_model and self.model == "iMac11,2":
|
||||
# iMac11,2 can have either PciRoot(0x0)/Pci(0x3,0x0)/Pci(0x0,0x0) or PciRoot(0x0)/Pci(0x1,0x0)/Pci(0x0,0x0)
|
||||
# Set both properties when we cannot run hardware detection
|
||||
self.config["DeviceProperties"]["Add"]["PciRoot(0x0)/Pci(0x3,0x0)/Pci(0x0,0x0)"] = {
|
||||
"applbkl": binascii.unhexlify("01000000"),
|
||||
"@0,backlight-control": binascii.unhexlify("01000000"),
|
||||
"@0,built-in": binascii.unhexlify("01000000"),
|
||||
"shikigva": 256,
|
||||
"agdpmod": "vit9696",
|
||||
}
|
||||
elif self.model in ["iMac12,1", "iMac12,2"]:
|
||||
print("- Adding Nvidia Brightness Control and DRM patches")
|
||||
self.config["DeviceProperties"]["Add"][backlight_path] = {
|
||||
"applbkl": binascii.unhexlify("01000000"),
|
||||
"@0,backlight-control": binascii.unhexlify("01000000"),
|
||||
"@0,built-in": binascii.unhexlify("01000000"),
|
||||
"shikigva": 256,
|
||||
"agdpmod": "vit9696",
|
||||
}
|
||||
print("- Disabling unsupported iGPU")
|
||||
self.config["DeviceProperties"]["Add"]["PciRoot(0x0)/Pci(0x2,0x0)"] = {
|
||||
"name": binascii.unhexlify("23646973706C6179"),
|
||||
"IOName": "#display",
|
||||
"class-code": binascii.unhexlify("FFFFFFFF"),
|
||||
}
|
||||
shutil.copy(self.constants.backlight_injector_path, self.constants.kexts_path)
|
||||
support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("BacklightInjector.kext")["Enabled"] = True
|
||||
self.config["UEFI"]["Quirks"]["ForgeUefiSupport"] = True
|
||||
self.config["UEFI"]["Quirks"]["ReloadOptionRoms"] = True
|
||||
|
||||
|
||||
def amd_mxm_patch(self, backlight_path):
|
||||
print("- Adding AMD DRM patches")
|
||||
if not support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("WhateverGreen.kext")["Enabled"] is True:
|
||||
# Ensure WEG is enabled as we need if for Backlight patching
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("WhateverGreen.kext", self.constants.whatevergreen_version, self.constants.whatevergreen_path)
|
||||
self.config["DeviceProperties"]["Add"][backlight_path] = {"shikigva": 128, "unfairgva": 1, "agdpmod": "pikera", "rebuild-device-tree": 1, "enable-gva-support": 1}
|
||||
if self.constants.custom_model and self.model == "iMac11,2":
|
||||
# iMac11,2 can have either PciRoot(0x0)/Pci(0x3,0x0)/Pci(0x0,0x0) or PciRoot(0x0)/Pci(0x1,0x0)/Pci(0x0,0x0)
|
||||
# Set both properties when we cannot run hardware detection
|
||||
self.config["DeviceProperties"]["Add"]["PciRoot(0x0)/Pci(0x3,0x0)/Pci(0x0,0x0)"] = {"shikigva": 128, "unfairgva": 1, "agdpmod": "pikera", "rebuild-device-tree": 1, "enable-gva-support": 1}
|
||||
if self.model in ["iMac12,1", "iMac12,2"]:
|
||||
print("- Disabling unsupported iGPU")
|
||||
self.config["DeviceProperties"]["Add"]["PciRoot(0x0)/Pci(0x2,0x0)"] = {
|
||||
"name": binascii.unhexlify("23646973706C6179"),
|
||||
"IOName": "#display",
|
||||
"class-code": binascii.unhexlify("FFFFFFFF"),
|
||||
}
|
||||
elif self.model == "iMac10,1":
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("AAAMouSSE.kext", self.constants.mousse_version, self.constants.mousse_path)
|
||||
if self.computer and self.computer.dgpu:
|
||||
if self.computer.dgpu.arch == device_probe.AMD.Archs.Legacy_GCN_7000:
|
||||
print("- Adding Legacy GCN Power Gate Patches")
|
||||
self.config["DeviceProperties"]["Add"][backlight_path].update({
|
||||
"CAIL,CAIL_DisableDrmdmaPowerGating": 1,
|
||||
"CAIL,CAIL_DisableGfxCGPowerGating": 1,
|
||||
"CAIL,CAIL_DisableUVDPowerGating": 1,
|
||||
"CAIL,CAIL_DisableVCEPowerGating": 1,
|
||||
})
|
||||
if self.constants.imac_model == "Legacy GCN":
|
||||
print("- Adding Legacy GCN Power Gate Patches")
|
||||
self.config["DeviceProperties"]["Add"][backlight_path].update({
|
||||
"CAIL,CAIL_DisableDrmdmaPowerGating": 1,
|
||||
"CAIL,CAIL_DisableGfxCGPowerGating": 1,
|
||||
"CAIL,CAIL_DisableUVDPowerGating": 1,
|
||||
"CAIL,CAIL_DisableVCEPowerGating": 1,
|
||||
})
|
||||
if self.model == "iMac11,2":
|
||||
self.config["DeviceProperties"]["Add"]["PciRoot(0x0)/Pci(0x3,0x0)/Pci(0x0,0x0)"].update({
|
||||
"CAIL,CAIL_DisableDrmdmaPowerGating": 1,
|
||||
"CAIL,CAIL_DisableGfxCGPowerGating": 1,
|
||||
"CAIL,CAIL_DisableUVDPowerGating": 1,
|
||||
"CAIL,CAIL_DisableVCEPowerGating": 1,
|
||||
})
|
||||
|
||||
|
||||
def audio_handling(self):
|
||||
if (self.model in model_array.LegacyAudio or self.model in model_array.MacPro) and self.constants.set_alc_usage is True:
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("AppleALC.kext", self.constants.applealc_version, self.constants.applealc_path)
|
||||
|
||||
# Audio Patch
|
||||
if self.constants.set_alc_usage is True:
|
||||
if smbios_data.smbios_dictionary[self.model]["Max OS Supported"] <= os_data.os_data.high_sierra:
|
||||
# Models dropped in Mojave also lost Audio support
|
||||
# Xserves and MacPro4,1 are exceptions
|
||||
# iMac7,1 and iMac8,1 require AppleHDA/IOAudioFamily downgrade
|
||||
if not (self.model.startswith("Xserve") or self.model in ["MacPro4,1", "iMac7,1", "iMac8,1"]):
|
||||
if "nForce Chipset" in smbios_data.smbios_dictionary[self.model]:
|
||||
hdef_path = "PciRoot(0x0)/Pci(0x8,0x0)"
|
||||
else:
|
||||
hdef_path = "PciRoot(0x0)/Pci(0x1b,0x0)"
|
||||
# In AppleALC, MacPro3,1's original layout is already in use, forcing layout 13 instead
|
||||
if self.model == "MacPro3,1":
|
||||
self.config["DeviceProperties"]["Add"][hdef_path] = {
|
||||
"apple-layout-id": 90,
|
||||
"use-apple-layout-id": 1,
|
||||
"alc-layout-id": 13,
|
||||
}
|
||||
else:
|
||||
self.config["DeviceProperties"]["Add"][hdef_path] = {
|
||||
"apple-layout-id": 90,
|
||||
"use-apple-layout-id": 1,
|
||||
"use-layout-id": 1,
|
||||
}
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("AppleALC.kext", self.constants.applealc_version, self.constants.applealc_path)
|
||||
elif (self.model.startswith("MacPro") and self.model != "MacPro6,1") or self.model.startswith("Xserve"):
|
||||
# Used to enable Audio support for non-standard dGPUs
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("AppleALC.kext", self.constants.applealc_version, self.constants.applealc_path)
|
||||
|
||||
# Due to regression in AppleALC 1.6.4+, temporarily use 1.6.3 and set override
|
||||
if support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("AppleALC.kext")["Enabled"] is True:
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -lilubetaall"
|
||||
|
||||
def firmware_handling(self):
|
||||
# Add UGA to GOP layer
|
||||
if "UGA Graphics" in smbios_data.smbios_dictionary[self.model]:
|
||||
print("- Adding UGA to GOP Patch")
|
||||
self.config["UEFI"]["Output"]["GopPassThrough"] = "Apple"
|
||||
|
||||
# GMUX handling
|
||||
if self.constants.software_demux is True and self.model in ["MacBookPro8,2", "MacBookPro8,3"]:
|
||||
print("- Enabling software demux")
|
||||
# Add ACPI patches
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["ACPI"]["Add"], "Path", "SSDT-DGPU.aml")["Enabled"] = True
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["ACPI"]["Patch"], "Comment", "_INI to XINI")["Enabled"] = True
|
||||
shutil.copy(self.constants.demux_ssdt_path, self.constants.acpi_path)
|
||||
# Disable dGPU
|
||||
# IOACPIPlane:/_SB/PCI0@0/P0P2@10000/GFX0@0
|
||||
self.config["DeviceProperties"]["Add"]["PciRoot(0x0)/Pci(0x1,0x0)/Pci(0x0,0x0)"] = {
|
||||
"class-code": binascii.unhexlify("FFFFFFFF"),
|
||||
"device-id": binascii.unhexlify("FFFF0000"),
|
||||
"IOName": "Dortania Disabled Card",
|
||||
"name": "Dortania Disabled Card"
|
||||
}
|
||||
self.config["DeviceProperties"]["Delete"]["PciRoot(0x0)/Pci(0x1,0x0)/Pci(0x0,0x0)"] = ["class-code", "device-id", "IOName", "name"]
|
||||
# Add AMDGPUWakeHandler
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("AMDGPUWakeHandler.kext", self.constants.gpu_wake_version, self.constants.gpu_wake_path)
|
||||
|
||||
if self.constants.dGPU_switch is True and "Switchable GPUs" in smbios_data.smbios_dictionary[self.model]:
|
||||
print("- Allowing GMUX switching in Windows")
|
||||
self.config["Booter"]["Quirks"]["SignalAppleOS"] = True
|
||||
|
||||
# Force Output support PC VBIOS on Mac Pros
|
||||
if self.constants.force_output_support is True:
|
||||
print("- Forcing GOP Support")
|
||||
self.config["UEFI"]["Quirks"]["ForgeUefiSupport"] = True
|
||||
self.config["UEFI"]["Quirks"]["ReloadOptionRoms"] = True
|
||||
|
||||
# AMD GOP VBIOS injection for AMD GCN 1-4 GPUs
|
||||
if self.constants.amd_gop_injection is True:
|
||||
print("- Adding AMDGOP.efi")
|
||||
shutil.copy(self.constants.amd_gop_driver_path, self.constants.drivers_path)
|
||||
support.build_support(self.model, self.constants, self.config).get_efi_binary_by_path("AMDGOP.efi", "UEFI", "Drivers")["Enabled"] = True
|
||||
|
||||
# Nvidia Kepler GOP VBIOS injection
|
||||
if self.constants.nvidia_kepler_gop_injection is True:
|
||||
print("- Adding NVGOP_GK.efi")
|
||||
shutil.copy(self.constants.nvidia_kepler_gop_driver_path, self.constants.drivers_path)
|
||||
support.build_support(self.model, self.constants, self.config).get_efi_binary_by_path("NVGOP_GK.efi", "UEFI", "Drivers")["Enabled"] = True
|
||||
|
||||
|
||||
def spoof_handling(self):
|
||||
if self.constants.serial_settings == "None":
|
||||
return
|
||||
|
||||
# AppleMuxControl Override
|
||||
if self.model == "MacBookPro9,1":
|
||||
print("- Adding AppleMuxControl Override")
|
||||
amc_map_path = Path(self.constants.plist_folder_path) / Path("AppleMuxControl/Info.plist")
|
||||
self.config["DeviceProperties"]["Add"]["PciRoot(0x0)/Pci(0x1,0x0)/Pci(0x0,0x0)"] = {"agdpmod": "vit9696"}
|
||||
Path(self.constants.amc_kext_folder).mkdir()
|
||||
Path(self.constants.amc_contents_folder).mkdir()
|
||||
shutil.copy(amc_map_path, self.constants.amc_contents_folder)
|
||||
support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("AMC-Override.kext")["Enabled"] = True
|
||||
|
||||
if self.model not in model_array.NoAGPMSupport:
|
||||
print("- Adding AppleGraphicsPowerManagement Override")
|
||||
agpm_map_path = Path(self.constants.plist_folder_path) / Path("AppleGraphicsPowerManagement/Info.plist")
|
||||
Path(self.constants.agpm_kext_folder).mkdir()
|
||||
Path(self.constants.agpm_contents_folder).mkdir()
|
||||
shutil.copy(agpm_map_path, self.constants.agpm_contents_folder)
|
||||
support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("AGPM-Override.kext")["Enabled"] = True
|
||||
|
||||
if self.model in model_array.AGDPSupport:
|
||||
print("- Adding AppleGraphicsDevicePolicy Override")
|
||||
agdp_map_path = Path(self.constants.plist_folder_path) / Path("AppleGraphicsDevicePolicy/Info.plist")
|
||||
Path(self.constants.agdp_kext_folder).mkdir()
|
||||
Path(self.constants.agdp_contents_folder).mkdir()
|
||||
shutil.copy(agdp_map_path, self.constants.agdp_contents_folder)
|
||||
support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("AGDP-Override.kext")["Enabled"] = True
|
||||
|
||||
# AGPM Patch
|
||||
if self.model in model_array.DualGPUPatch:
|
||||
print("- Adding dual GPU patch")
|
||||
if not self.constants.custom_model and self.computer.dgpu and self.computer.dgpu.pci_path:
|
||||
self.gfx0_path = self.computer.dgpu.pci_path
|
||||
print(f"- Found GFX0 Device Path: {self.gfx0_path}")
|
||||
else:
|
||||
if not self.constants.custom_model:
|
||||
print("- Failed to find GFX0 Device path, falling back on known logic")
|
||||
self.gfx0_path = "PciRoot(0x0)/Pci(0x1,0x0)/Pci(0x0,0x0)"
|
||||
|
||||
if self.model in model_array.IntelNvidiaDRM and self.constants.drm_support is True:
|
||||
print("- Prioritizing DRM support over Intel QuickSync")
|
||||
self.config["DeviceProperties"]["Add"][self.gfx0_path] = {"agdpmod": "vit9696", "shikigva": 256}
|
||||
self.config["DeviceProperties"]["Add"]["PciRoot(0x0)/Pci(0x2,0x0)"] = {
|
||||
"name": binascii.unhexlify("23646973706C6179"),
|
||||
"IOName": "#display",
|
||||
"class-code": binascii.unhexlify("FFFFFFFF"),
|
||||
}
|
||||
elif self.constants.serial_settings != "None":
|
||||
self.config["DeviceProperties"]["Add"][self.gfx0_path] = {"agdpmod": "vit9696"}
|
||||
|
||||
if self.model.startswith("iMac14,1"):
|
||||
# Ensure that agdpmod is applied to iMac14,x with iGPU only
|
||||
self.config["DeviceProperties"]["Add"]["PciRoot(0x0)/Pci(0x2,0x0)"] = {"agdpmod": "vit9696"}
|
||||
|
||||
|
||||
def imac_mxm_patching(self):
|
||||
# Check GPU Vendor
|
||||
if self.constants.metal_build is True:
|
||||
self.backlight_path_detection()
|
||||
print("- Adding Metal GPU patches on request")
|
||||
if self.constants.imac_vendor == "AMD":
|
||||
self.amd_mxm_patch(self.gfx0_path)
|
||||
elif self.constants.imac_vendor == "Nvidia":
|
||||
self.nvidia_mxm_patch(self.gfx0_path)
|
||||
else:
|
||||
print("- Failed to find vendor")
|
||||
elif not self.constants.custom_model and self.model in model_array.LegacyGPU and self.computer.dgpu:
|
||||
print(f"- Detected dGPU: {utilities.friendly_hex(self.computer.dgpu.vendor_id)}:{utilities.friendly_hex(self.computer.dgpu.device_id)}")
|
||||
if self.computer.dgpu.arch in [
|
||||
device_probe.AMD.Archs.Legacy_GCN_7000,
|
||||
device_probe.AMD.Archs.Legacy_GCN_8000,
|
||||
device_probe.AMD.Archs.Legacy_GCN_9000,
|
||||
device_probe.AMD.Archs.Polaris,
|
||||
device_probe.AMD.Archs.Vega,
|
||||
device_probe.AMD.Archs.Navi,
|
||||
]:
|
||||
self.backlight_path_detection()
|
||||
self.amd_mxm_patch(self.gfx0_path)
|
||||
elif self.computer.dgpu.arch == device_probe.NVIDIA.Archs.Kepler:
|
||||
self.backlight_path_detection()
|
||||
self.nvidia_mxm_patch(self.gfx0_path)
|
||||
|
||||
def ioaccel_workaround(self):
|
||||
# Handle misc IOAccelerator issues
|
||||
|
||||
# When MTL bundles are missing from disk, WindowServer will repeatedly crash
|
||||
# This primarily occurs when installing an RSR update, where root is cleaned but AuxKC is not
|
||||
gpu_dict = []
|
||||
if not self.constants.custom_model:
|
||||
gpu_dict = self.constants.computer.gpus
|
||||
else:
|
||||
if not self.model in smbios_data.smbios_dictionary:
|
||||
return
|
||||
gpu_dict = smbios_data.smbios_dictionary[self.model]["Stock GPUs"]
|
||||
for gpu in gpu_dict:
|
||||
if not self.constants.custom_model:
|
||||
gpu = gpu.arch
|
||||
if gpu in [
|
||||
device_probe.Intel.Archs.Ivy_Bridge,
|
||||
device_probe.Intel.Archs.Haswell,
|
||||
device_probe.Intel.Archs.Broadwell,
|
||||
device_probe.Intel.Archs.Skylake,
|
||||
device_probe.NVIDIA.Archs.Kepler,
|
||||
]:
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("KDKlessWorkaround.kext", self.constants.kdkless_version, self.constants.kdkless_path)
|
||||
return
|
||||
|
||||
# KDKlessWorkaround supports disabling native AMD stack on Ventura for pre-AVX2.0 CPUs
|
||||
# Applicable for Polaris, Vega, Navi GPUs
|
||||
if smbios_data.smbios_dictionary[self.model]["CPU Generation"] > cpu_data.cpu_data.ivy_bridge.value:
|
||||
return
|
||||
for gpu in gpu_dict:
|
||||
if not self.constants.custom_model:
|
||||
gpu = gpu.arch
|
||||
if gpu in [
|
||||
device_probe.AMD.Archs.Polaris,
|
||||
device_probe.AMD.Archs.Vega,
|
||||
device_probe.AMD.Archs.Navi,
|
||||
]:
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("KDKlessWorkaround.kext", self.constants.kdkless_version, self.constants.kdkless_path)
|
||||
return
|
||||
249
resources/build/misc.py
Normal file
249
resources/build/misc.py
Normal file
@@ -0,0 +1,249 @@
|
||||
# Class for handling Misc Patches, invocation from build.py
|
||||
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
|
||||
|
||||
from resources import constants, device_probe, generate_smbios, utilities
|
||||
from resources.build import support
|
||||
from data import model_array, smbios_data, cpu_data
|
||||
|
||||
import binascii, shutil
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class build_misc:
|
||||
|
||||
def __init__(self, model, versions, config):
|
||||
self.model = model
|
||||
self.constants: constants.Constants = versions
|
||||
self.config = config
|
||||
self.computer = self.constants.computer
|
||||
|
||||
def rmtree_handler(func, path, exc_info):
|
||||
if exc_info[0] == FileNotFoundError:
|
||||
return
|
||||
raise # pylint: disable=misplaced-bare-raise
|
||||
|
||||
def build(self):
|
||||
self.feature_unlock_handling()
|
||||
self.restrict_events_handling()
|
||||
self.firewire_handling()
|
||||
self.trackpad_handling()
|
||||
self.thunderbolt_handling()
|
||||
self.webcam_handling()
|
||||
self.usb_handling()
|
||||
self.debug_handling()
|
||||
self.cpu_friend_handling()
|
||||
self.general_oc_handling()
|
||||
|
||||
def feature_unlock_handling(self):
|
||||
if self.constants.fu_status is True:
|
||||
support.build_support(self.model, self.constants, self.config).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
|
||||
|
||||
def restrict_events_handling(self):
|
||||
# RestrictEvents handling
|
||||
# - revpatch: Process patching
|
||||
# - revblock: Process blocking
|
||||
block_args = ""
|
||||
if self.model in ["MacBookPro6,1", "MacBookPro6,2", "MacBookPro9,1", "MacBookPro10,1"]:
|
||||
block_args += "gmux,"
|
||||
if self.model in model_array.MacPro:
|
||||
print("- Disabling memory error reporting")
|
||||
block_args += "pcie,"
|
||||
gpu_dict = []
|
||||
if not self.constants.custom_model:
|
||||
gpu_dict = self.constants.computer.gpus
|
||||
else:
|
||||
if self.model in smbios_data.smbios_dictionary:
|
||||
gpu_dict = smbios_data.smbios_dictionary[self.model]["Stock GPUs"]
|
||||
for gpu in gpu_dict:
|
||||
if not self.constants.custom_model:
|
||||
gpu = gpu.arch
|
||||
if gpu in [
|
||||
device_probe.Intel.Archs.Ivy_Bridge,
|
||||
device_probe.Intel.Archs.Haswell,
|
||||
device_probe.NVIDIA.Archs.Kepler,
|
||||
]:
|
||||
print("- Disabling mediaanalysisd")
|
||||
block_args += "media,"
|
||||
break
|
||||
if block_args.endswith(","):
|
||||
block_args = block_args[:-1]
|
||||
|
||||
if block_args != "":
|
||||
print(f"- Setting RestrictEvents block arguments: {block_args}")
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("RestrictEvents.kext", self.constants.restrictevents_version, self.constants.restrictevents_path)
|
||||
self.config["NVRAM"]["Add"]["4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102"]["revblock"] = block_args
|
||||
|
||||
patch_args = ""
|
||||
if support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "Reroute kern.hv_vmm_present patch (1)")["Enabled"] is True and self.constants.set_content_caching is True:
|
||||
print("- Fixing Content Caching support")
|
||||
patch_args += "asset,"
|
||||
|
||||
if patch_args.endswith(","):
|
||||
patch_args = patch_args[:-1]
|
||||
|
||||
if block_args != "" and patch_args == "":
|
||||
# Disable unneeded Userspace patching (cs_validate_page is quite expensive)
|
||||
patch_args = "none"
|
||||
|
||||
if patch_args != "":
|
||||
print(f"- Setting RestrictEvents patch arguments: {patch_args}")
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("RestrictEvents.kext", self.constants.restrictevents_version, self.constants.restrictevents_path)
|
||||
self.config["NVRAM"]["Add"]["4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102"]["revpatch"] = patch_args
|
||||
|
||||
if self.constants.custom_cpu_model == 0 or self.constants.custom_cpu_model == 1:
|
||||
self.config["NVRAM"]["Add"]["4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102"]["revcpu"] = self.constants.custom_cpu_model
|
||||
if self.constants.custom_cpu_model_value != "":
|
||||
print(f"- Adding custom CPU Name: {self.constants.custom_cpu_model_value}")
|
||||
self.config["NVRAM"]["Add"]["4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102"]["revcpuname"] = self.constants.custom_cpu_model_value
|
||||
else:
|
||||
print("- Adding CPU Name Patch")
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("RestrictEvents.kext", self.constants.restrictevents_version, self.constants.restrictevents_path)
|
||||
|
||||
if support.build_support(self.model, self.constants, self.config).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 conflict if both are injected
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("EFICheckDisabler.kext", "", self.constants.efi_disabler_path)
|
||||
|
||||
|
||||
def cpu_friend_handling(self):
|
||||
if self.model not in ["iMac7,1", "Xserve2,1", "Dortania1,1"] and self.constants.disallow_cpufriend is False and self.constants.serial_settings != "None":
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("CPUFriend.kext", self.constants.cpufriend_version, self.constants.cpufriend_path)
|
||||
|
||||
# CPUFriendDataProvider handling
|
||||
pp_map_path = Path(self.constants.platform_plugin_plist_path) / Path(f"{self.model}/Info.plist")
|
||||
if not pp_map_path.exists():
|
||||
raise Exception(f"{pp_map_path} does not exist!!! Please file an issue stating file is missing for {self.model}.")
|
||||
Path(self.constants.pp_kext_folder).mkdir()
|
||||
Path(self.constants.pp_contents_folder).mkdir()
|
||||
shutil.copy(pp_map_path, self.constants.pp_contents_folder)
|
||||
support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("CPUFriendDataProvider.kext")["Enabled"] = True
|
||||
|
||||
def firewire_handling(self):
|
||||
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")
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("IOFireWireFamily.kext", self.constants.fw_kext, self.constants.fw_family_path)
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("IOFireWireSBP2.kext", self.constants.fw_kext, self.constants.fw_sbp2_path)
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("IOFireWireSerialBusProtocolTransport.kext", self.constants.fw_kext, self.constants.fw_bus_path)
|
||||
support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("IOFireWireFamily.kext/Contents/PlugIns/AppleFWOHCI.kext")["Enabled"] = True
|
||||
|
||||
def trackpad_handling(self):
|
||||
# Pre-Force Touch trackpad support for macOS Ventura
|
||||
if smbios_data.smbios_dictionary[self.model]["CPU Generation"] < cpu_data.cpu_data.skylake.value:
|
||||
if self.model.startswith("MacBook"):
|
||||
# These units got force touch early, so ignore them
|
||||
if self.model not in ["MacBookPro11,4", "MacBookPro11,5", "MacBookPro12,1", "MacBook8,1"]:
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("AppleUSBTopCase.kext", self.constants.topcase_version, self.constants.top_case_path)
|
||||
support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("AppleUSBTopCase.kext/Contents/PlugIns/AppleUSBTCButtons.kext")["Enabled"] = True
|
||||
support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("AppleUSBTopCase.kext/Contents/PlugIns/AppleUSBTCKeyboard.kext")["Enabled"] = True
|
||||
support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("AppleUSBTopCase.kext/Contents/PlugIns/AppleUSBTCKeyEventDriver.kext")["Enabled"] = True
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("AppleUSBMultitouch.kext", self.constants.multitouch_version, self.constants.multitouch_path)
|
||||
# Legacy Trackpad support
|
||||
if self.model in ["MacBook4,1", "MacBook5,2"]:
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("AppleUSBTrackpad.kext", self.constants.apple_trackpad, self.constants.apple_trackpad_path)
|
||||
|
||||
def thunderbolt_handling(self):
|
||||
if self.constants.disable_tb is True and self.model in ["MacBookPro11,1", "MacBookPro11,2", "MacBookPro11,3", "MacBookPro11,4", "MacBookPro11,5"]:
|
||||
print("- Disabling 2013-2014 laptop Thunderbolt Controller")
|
||||
if self.model in ["MacBookPro11,3", "MacBookPro11,5"]:
|
||||
# 15" dGPU models: IOACPIPlane:/_SB/PCI0@0/PEG1@10001/UPSB@0/DSB0@0/NHI0@0
|
||||
tb_device_path = "PciRoot(0x0)/Pci(0x1,0x1)/Pci(0x0,0x0)/Pci(0x0,0x0)/Pci(0x0,0x0)"
|
||||
else:
|
||||
# 13" and 15" iGPU 2013-2014 models: IOACPIPlane:/_SB/PCI0@0/P0P2@10000/UPSB@0/DSB0@0/NHI0@0
|
||||
tb_device_path = "PciRoot(0x0)/Pci(0x1,0x0)/Pci(0x0,0x0)/Pci(0x0,0x0)/Pci(0x0,0x0)"
|
||||
|
||||
self.config["DeviceProperties"]["Add"][tb_device_path] = {"class-code": binascii.unhexlify("FFFFFFFF"), "device-id": binascii.unhexlify("FFFF0000")}
|
||||
|
||||
def webcam_handling(self):
|
||||
# Legacy iSight patches
|
||||
if "Legacy iSight" in smbios_data.smbios_dictionary[self.model]:
|
||||
if smbios_data.smbios_dictionary[self.model]["Legacy iSight"] is True:
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("LegacyUSBVideoSupport.kext", self.constants.apple_isight_version, self.constants.apple_isight_path)
|
||||
|
||||
def usb_handling(self):
|
||||
# USB Map
|
||||
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 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.model in model_array.Missing_USB_Map_Ventura)
|
||||
or self.constants.serial_settings in ["Moderate", "Advanced"])
|
||||
):
|
||||
print("- Adding USB-Map.kext")
|
||||
Path(self.constants.map_kext_folder).mkdir()
|
||||
Path(self.constants.map_contents_folder).mkdir()
|
||||
shutil.copy(usb_map_path, self.constants.map_contents_folder)
|
||||
support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("USB-Map.kext")["Enabled"] = True
|
||||
if self.model in model_array.Missing_USB_Map_Ventura and self.constants.serial_settings not in ["Moderate", "Advanced"]:
|
||||
support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("USB-Map.kext")["MinKernel"] = "22.0.0"
|
||||
|
||||
# Add UHCI/OHCI drivers
|
||||
# All Penryn Macs lack an internal USB hub to route USB 1.1 devices to the EHCI controller
|
||||
# And MacPro4,1 and MacPro5,1 are the only post-Penryn Macs that lack an internal USB hub
|
||||
# - Ref: https://techcommunity.microsoft.com/t5/microsoft-usb-blog/reasons-to-avoid-companion-controllers/ba-p/270710
|
||||
#
|
||||
# Required downgrades:
|
||||
# - IOUSBHostFamily.kext (only kext itself, not plugins)
|
||||
# - AppleUSBHub.kext
|
||||
# - AppleUSBEHCI.kext
|
||||
if (
|
||||
smbios_data.smbios_dictionary[self.model]["CPU Generation"] <= cpu_data.cpu_data.penryn.value or \
|
||||
self.model in ["MacPro4,1", "MacPro5,1"]
|
||||
):
|
||||
print("- Adding UHCI/OHCI USB support")
|
||||
shutil.copy(self.constants.apple_usb_11_injector_path, self.constants.kexts_path)
|
||||
support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("USB1.1-Injector.kext/Contents/PlugIns/AppleUSBOHCI.kext")["Enabled"] = True
|
||||
support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("USB1.1-Injector.kext/Contents/PlugIns/AppleUSBOHCIPCI.kext")["Enabled"] = True
|
||||
support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("USB1.1-Injector.kext/Contents/PlugIns/AppleUSBUHCI.kext")["Enabled"] = True
|
||||
support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("USB1.1-Injector.kext/Contents/PlugIns/AppleUSBUHCIPCI.kext")["Enabled"] = True
|
||||
|
||||
def debug_handling(self):
|
||||
# DEBUG Settings (OpenCorePkg and Kernel Space)
|
||||
|
||||
if self.constants.verbose_debug is True:
|
||||
print("- Enabling Verbose boot")
|
||||
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 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"
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("DebugEnhancer.kext", self.constants.debugenhancer_version, self.constants.debugenhancer_path)
|
||||
|
||||
if self.constants.opencore_debug is True:
|
||||
print("- Enabling DEBUG OpenCore")
|
||||
self.config["Misc"]["Debug"]["Target"] = 0x43
|
||||
self.config["Misc"]["Debug"]["DisplayLevel"] = 0x80000042
|
||||
|
||||
def general_oc_handling(self):
|
||||
# OpenCorePkg Settings
|
||||
|
||||
# OpenCanopy Settings (GUI)
|
||||
print("- Adding OpenCanopy GUI")
|
||||
shutil.rmtree(self.constants.resources_path, onerror=self.rmtree_handler)
|
||||
shutil.copy(self.constants.gui_path, self.constants.oc_folder)
|
||||
support.build_support(self.model, self.constants, self.config).get_efi_binary_by_path("OpenCanopy.efi", "UEFI", "Drivers")["Enabled"] = True
|
||||
support.build_support(self.model, self.constants, self.config).get_efi_binary_by_path("OpenRuntime.efi", "UEFI", "Drivers")["Enabled"] = True
|
||||
support.build_support(self.model, self.constants, self.config).get_efi_binary_by_path("OpenLinuxBoot.efi", "UEFI", "Drivers")["Enabled"] = True
|
||||
support.build_support(self.model, self.constants, self.config).get_efi_binary_by_path("ResetNvramEntry.efi", "UEFI", "Drivers")["Enabled"] = True
|
||||
|
||||
if self.constants.showpicker is False:
|
||||
print("- Hiding OpenCore picker")
|
||||
self.config["Misc"]["Boot"]["ShowPicker"] = False
|
||||
|
||||
if self.constants.oc_timeout != 5:
|
||||
print(f"- Setting custom OpenCore picker timeout to {self.constants.oc_timeout} seconds")
|
||||
self.config["Misc"]["Boot"]["Timeout"] = self.constants.oc_timeout
|
||||
|
||||
if self.constants.vault is True and utilities.check_command_line_tools() is True:
|
||||
print("- Setting Vault configuration")
|
||||
self.config["Misc"]["Security"]["Vault"] = "Secure"
|
||||
support.build_support(self.model, self.constants, self.config).get_efi_binary_by_path("OpenShell.efi", "Misc", "Tools")["Enabled"] = False
|
||||
72
resources/build/networking/wired.py
Normal file
72
resources/build/networking/wired.py
Normal file
@@ -0,0 +1,72 @@
|
||||
# Class for handling Wired Networking Patches, invocation from build.py
|
||||
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
|
||||
|
||||
from resources import constants, device_probe
|
||||
from resources.build import support
|
||||
from data import smbios_data, cpu_data
|
||||
|
||||
class build_wired:
|
||||
|
||||
def __init__(self, model, versions, config):
|
||||
self.model = model
|
||||
self.constants: constants.Constants = versions
|
||||
self.config = config
|
||||
self.computer = self.constants.computer
|
||||
|
||||
|
||||
def build(self):
|
||||
# Check if Ethernet was detected, otherwise fall back to assumptions (mainly for 2011 MacBook Airs and TB Ethernet)
|
||||
if not self.constants.custom_model and self.constants.computer.ethernet:
|
||||
self.on_model()
|
||||
else:
|
||||
self.prebuilt_assumption()
|
||||
|
||||
|
||||
def on_model(self):
|
||||
# On-model hardware detection
|
||||
for controller in self.constants.computer.ethernet:
|
||||
if isinstance(controller, device_probe.BroadcomEthernet) and controller.chipset == device_probe.BroadcomEthernet.Chipsets.AppleBCM5701Ethernet:
|
||||
if not self.model in smbios_data.smbios_dictionary:
|
||||
continue
|
||||
if smbios_data.smbios_dictionary[self.model]["CPU Generation"] < cpu_data.cpu_data.ivy_bridge.value:
|
||||
# Required due to Big Sur's BCM5701 requiring VT-D support
|
||||
# Applicable for pre-Ivy Bridge models
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("CatalinaBCM5701Ethernet.kext", self.constants.bcm570_version, self.constants.bcm570_path)
|
||||
elif isinstance(controller, device_probe.IntelEthernet):
|
||||
if not self.model in smbios_data.smbios_dictionary:
|
||||
continue
|
||||
if smbios_data.smbios_dictionary[self.model]["CPU Generation"] < cpu_data.cpu_data.ivy_bridge.value:
|
||||
# Apple's IOSkywalkFamily in DriverKit requires VT-D support
|
||||
# Applicable for pre-Ivy Bridge models
|
||||
if controller.chipset == device_probe.IntelEthernet.Chipsets.AppleIntelI210Ethernet:
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("CatalinaIntelI210Ethernet.kext", self.constants.i210_version, self.constants.i210_path)
|
||||
elif controller.chipset == device_probe.IntelEthernet.Chipsets.AppleIntel8254XEthernet:
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("AppleIntel8254XEthernet.kext", self.constants.intel_8254x_version, self.constants.intel_8254x_path)
|
||||
elif controller.chipset == device_probe.IntelEthernet.Chipsets.Intel82574L:
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("Intel82574L.kext", self.constants.intel_82574l_version, self.constants.intel_82574l_path)
|
||||
elif isinstance(controller, device_probe.NVIDIAEthernet):
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("nForceEthernet.kext", self.constants.nforce_version, self.constants.nforce_path)
|
||||
elif isinstance(controller, device_probe.Marvell) or isinstance(controller, device_probe.SysKonnect):
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("MarvelYukonEthernet.kext", self.constants.marvel_version, self.constants.marvel_path)
|
||||
|
||||
|
||||
def prebuilt_assumption(self):
|
||||
# Stock hardware assumptions
|
||||
if not self.model in smbios_data.smbios_dictionary:
|
||||
return
|
||||
if not "Ethernet Chipset" in smbios_data.smbios_dictionary[self.model]:
|
||||
return
|
||||
|
||||
if smbios_data.smbios_dictionary[self.model]["Ethernet Chipset"] == "Broadcom":
|
||||
if smbios_data.smbios_dictionary[self.model]["CPU Generation"] < cpu_data.cpu_data.ivy_bridge.value:
|
||||
# Required due to Big Sur's BCM5701 requiring VT-D support
|
||||
# Applicable for pre-Ivy Bridge models
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("CatalinaBCM5701Ethernet.kext", self.constants.bcm570_version, self.constants.bcm570_path)
|
||||
elif smbios_data.smbios_dictionary[self.model]["Ethernet Chipset"] == "Nvidia":
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("nForceEthernet.kext", self.constants.nforce_version, self.constants.nforce_path)
|
||||
elif smbios_data.smbios_dictionary[self.model]["Ethernet Chipset"] == "Marvell":
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("MarvelYukonEthernet.kext", self.constants.marvel_version, self.constants.marvel_path)
|
||||
elif smbios_data.smbios_dictionary[self.model]["Ethernet Chipset"] == "Intel 80003ES2LAN":
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("AppleIntel8254XEthernet.kext", self.constants.intel_8254x_version, self.constants.intel_8254x_path)
|
||||
elif smbios_data.smbios_dictionary[self.model]["Ethernet Chipset"] == "Intel 82574L":
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("Intel82574L.kext", self.constants.intel_82574l_version, self.constants.intel_82574l_path)
|
||||
129
resources/build/networking/wireless.py
Normal file
129
resources/build/networking/wireless.py
Normal file
@@ -0,0 +1,129 @@
|
||||
# Class for handling Wireless Networking Patches, invocation from build.py
|
||||
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
|
||||
|
||||
from resources import constants, device_probe, utilities
|
||||
from resources.build import support
|
||||
from data import smbios_data
|
||||
|
||||
class build_wireless:
|
||||
|
||||
def __init__(self, model, versions, config):
|
||||
self.model = model
|
||||
self.constants: constants.Constants = versions
|
||||
self.config = config
|
||||
self.computer = self.constants.computer
|
||||
|
||||
|
||||
def build(self):
|
||||
# WiFi patches
|
||||
if not self.constants.custom_model and self.constants.computer.wifi:
|
||||
self.on_model()
|
||||
else:
|
||||
self.prebuilt_assumption()
|
||||
self.wowl_handling()
|
||||
|
||||
|
||||
def on_model(self):
|
||||
print(f"- Found Wireless Device {utilities.friendly_hex(self.computer.wifi.vendor_id)}:{utilities.friendly_hex(self.computer.wifi.device_id)}")
|
||||
self.config["#Revision"]["Hardware-Wifi"] = f"{utilities.friendly_hex(self.computer.wifi.vendor_id)}:{utilities.friendly_hex(self.computer.wifi.device_id)}"
|
||||
|
||||
if isinstance(self.computer.wifi, device_probe.Broadcom):
|
||||
# This works around OCLP spoofing the Wifi card and therefore unable to actually detect the correct device
|
||||
if self.computer.wifi.chipset == device_probe.Broadcom.Chipsets.AirportBrcmNIC and self.constants.validate is False and self.computer.wifi.country_code:
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("AirportBrcmFixup.kext", self.constants.airportbcrmfixup_version, self.constants.airportbcrmfixup_path)
|
||||
print(f"- Setting Wireless Card's Country Code: {self.computer.wifi.country_code}")
|
||||
if self.computer.wifi.pci_path:
|
||||
arpt_path = self.computer.wifi.pci_path
|
||||
print(f"- Found ARPT device at {arpt_path}")
|
||||
self.config["DeviceProperties"]["Add"][arpt_path] = {"brcmfx-country": self.computer.wifi.country_code}
|
||||
else:
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += f" brcmfx-country={self.computer.wifi.country_code}"
|
||||
if self.constants.enable_wake_on_wlan is True:
|
||||
print("- Enabling Wake on WLAN support")
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += f" -brcmfxwowl"
|
||||
elif self.computer.wifi.chipset == device_probe.Broadcom.Chipsets.AirPortBrcm4360:
|
||||
self.wifi_fake_id()
|
||||
elif self.computer.wifi.chipset == device_probe.Broadcom.Chipsets.AirPortBrcm4331:
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("corecaptureElCap.kext", self.constants.corecaptureelcap_version, self.constants.corecaptureelcap_path)
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("IO80211ElCap.kext", self.constants.io80211elcap_version, self.constants.io80211elcap_path)
|
||||
support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("IO80211ElCap.kext/Contents/PlugIns/AirPortBrcm4331.kext")["Enabled"] = True
|
||||
elif self.computer.wifi.chipset == device_probe.Broadcom.Chipsets.AirPortBrcm43224:
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("corecaptureElCap.kext", self.constants.corecaptureelcap_version, self.constants.corecaptureelcap_path)
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("IO80211ElCap.kext", self.constants.io80211elcap_version, self.constants.io80211elcap_path)
|
||||
support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("IO80211ElCap.kext/Contents/PlugIns/AppleAirPortBrcm43224.kext")["Enabled"] = True
|
||||
elif isinstance(self.computer.wifi, device_probe.Atheros) and self.computer.wifi.chipset == device_probe.Atheros.Chipsets.AirPortAtheros40:
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("corecaptureElCap.kext", self.constants.corecaptureelcap_version, self.constants.corecaptureelcap_path)
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("IO80211ElCap.kext", self.constants.io80211elcap_version, self.constants.io80211elcap_path)
|
||||
support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("IO80211ElCap.kext/Contents/PlugIns/AirPortAtheros40.kext")["Enabled"] = True
|
||||
|
||||
|
||||
def prebuilt_assumption(self):
|
||||
if not self.model in smbios_data.smbios_dictionary:
|
||||
return
|
||||
if not "Wireless Model" in smbios_data.smbios_dictionary[self.model]:
|
||||
return
|
||||
if smbios_data.smbios_dictionary[self.model]["Wireless Model"] == device_probe.Broadcom.Chipsets.AirPortBrcm4360:
|
||||
print("- Enabling BCM943224 and BCM94331 Networking Support")
|
||||
self.wifi_fake_id()
|
||||
elif smbios_data.smbios_dictionary[self.model]["Wireless Model"] == device_probe.Broadcom.Chipsets.AirPortBrcm4331:
|
||||
print("- Enabling BCM94328 Networking Support")
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("corecaptureElCap.kext", self.constants.corecaptureelcap_version, self.constants.corecaptureelcap_path)
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("IO80211ElCap.kext", self.constants.io80211elcap_version, self.constants.io80211elcap_path)
|
||||
support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("IO80211ElCap.kext/Contents/PlugIns/AirPortBrcm4331.kext")["Enabled"] = True
|
||||
elif smbios_data.smbios_dictionary[self.model]["Wireless Model"] == device_probe.Broadcom.Chipsets.AirPortBrcm43224:
|
||||
print("- Enabling BCM94328 Networking Support")
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("corecaptureElCap.kext", self.constants.corecaptureelcap_version, self.constants.corecaptureelcap_path)
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("IO80211ElCap.kext", self.constants.io80211elcap_version, self.constants.io80211elcap_path)
|
||||
support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("IO80211ElCap.kext/Contents/PlugIns/AppleAirPortBrcm43224.kext")["Enabled"] = True
|
||||
elif smbios_data.smbios_dictionary[self.model]["Wireless Model"] == device_probe.Atheros.Chipsets.AirPortAtheros40:
|
||||
print("- Enabling Atheros Networking Support")
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("corecaptureElCap.kext", self.constants.corecaptureelcap_version, self.constants.corecaptureelcap_path)
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("IO80211ElCap.kext", self.constants.io80211elcap_version, self.constants.io80211elcap_path)
|
||||
support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("IO80211ElCap.kext/Contents/PlugIns/AirPortAtheros40.kext")["Enabled"] = True
|
||||
elif smbios_data.smbios_dictionary[self.model]["Wireless Model"] == device_probe.Broadcom.Chipsets.AirportBrcmNIC:
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("AirportBrcmFixup.kext", self.constants.airportbcrmfixup_version, self.constants.airportbcrmfixup_path)
|
||||
|
||||
|
||||
def wowl_handling(self):
|
||||
# To avoid reduced networking performance from wake, AirPortBrcmFixup is used to disable wake on WLAN by default.
|
||||
# However some users may want to enable wake on WLAN, so enable if requested.
|
||||
if self.constants.enable_wake_on_wlan is False:
|
||||
return
|
||||
if support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("AirportBrcmFixup.kext")["Enabled"] is False:
|
||||
return
|
||||
|
||||
print("- Enabling Wake on WLAN support")
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += f" -brcmfxwowl"
|
||||
|
||||
|
||||
def wifi_fake_id(self):
|
||||
# BCM94331 and BCM943224 are both partially supported within Big Sur's native AirPortBrcmNIC stack
|
||||
# Simply adding the Device IDs and usage of AirPortBrcmFixup will restore full functionality
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("AirportBrcmFixup.kext", self.constants.airportbcrmfixup_version, self.constants.airportbcrmfixup_path)
|
||||
support.build_support(self.model, self.constants, self.config).get_kext_by_bundle_path("AirportBrcmFixup.kext/Contents/PlugIns/AirPortBrcmNIC_Injector.kext")["Enabled"] = True
|
||||
if not self.constants.custom_model and self.computer.wifi and self.computer.wifi.pci_path:
|
||||
arpt_path = self.computer.wifi.pci_path
|
||||
print(f"- Found ARPT device at {arpt_path}")
|
||||
else:
|
||||
if not self.model in smbios_data.smbios_dictionary:
|
||||
print("No known PCI pathing for this model")
|
||||
return
|
||||
if "nForce Chipset" in smbios_data.smbios_dictionary[self.model]:
|
||||
# Nvidia chipsets all have the same path to ARPT
|
||||
arpt_path = "PciRoot(0x0)/Pci(0x15,0x0)/Pci(0x0,0x0)"
|
||||
else:
|
||||
if self.model in ("iMac7,1", "iMac8,1", "MacPro3,1", "MacBookPro4,1"):
|
||||
arpt_path = "PciRoot(0x0)/Pci(0x1C,0x4)/Pci(0x0,0x0)"
|
||||
elif self.model in ("iMac13,1", "iMac13,2"):
|
||||
arpt_path = "PciRoot(0x0)/Pci(0x1C,0x3)/Pci(0x0,0x0)"
|
||||
elif self.model in ("MacPro4,1", "MacPro5,1"):
|
||||
arpt_path = "PciRoot(0x0)/Pci(0x1C,0x5)/Pci(0x0,0x0)"
|
||||
else:
|
||||
# Assumes we have a laptop with Intel chipset
|
||||
# iMac11,x-12,x also apply
|
||||
arpt_path = "PciRoot(0x0)/Pci(0x1C,0x1)/Pci(0x0,0x0)"
|
||||
print(f"- Using known ARPT Path: {arpt_path}")
|
||||
|
||||
if not self.constants.custom_model and self.computer.wifi and self.constants.validate is False and self.computer.wifi.country_code:
|
||||
print(f"- Applying fake ID for WiFi, setting Country Code: {self.computer.wifi.country_code}")
|
||||
self.config["DeviceProperties"]["Add"][arpt_path] = {"brcmfx-country": self.computer.wifi.country_code}
|
||||
70
resources/build/security.py
Normal file
70
resources/build/security.py
Normal file
@@ -0,0 +1,70 @@
|
||||
# Class for handling macOS Security Patches, invocation from build.py
|
||||
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
|
||||
|
||||
from resources import constants, utilities
|
||||
from resources.build import support
|
||||
|
||||
import binascii
|
||||
|
||||
|
||||
class build_security:
|
||||
|
||||
def __init__(self, model, versions, config):
|
||||
self.model = model
|
||||
self.constants: constants.Constants = versions
|
||||
self.config = config
|
||||
self.computer = self.constants.computer
|
||||
|
||||
|
||||
def build(self):
|
||||
if self.constants.sip_status is False or self.constants.custom_sip_value:
|
||||
# Work-around 12.3 bug where Electron apps no longer launch with SIP lowered
|
||||
# Unknown whether this is intended behavior or not, revisit with 12.4
|
||||
print("- Adding ipc_control_port_options=0 to boot-args")
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " ipc_control_port_options=0"
|
||||
# Adds AutoPkgInstaller for Automatic OpenCore-Patcher installation
|
||||
# Only install if running the GUI (AutoPkg-Assets.pkg requires the GUI)
|
||||
if self.constants.wxpython_variant is True:
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("AutoPkgInstaller.kext", self.constants.autopkg_version, self.constants.autopkg_path)
|
||||
if self.constants.custom_sip_value:
|
||||
print(f"- Setting SIP value to: {self.constants.custom_sip_value}")
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["csr-active-config"] = utilities.string_to_hex(self.constants.custom_sip_value.lstrip("0x"))
|
||||
elif self.constants.sip_status is False:
|
||||
print("- Set SIP to allow Root Volume patching")
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["csr-active-config"] = binascii.unhexlify("03080000")
|
||||
|
||||
# apfs.kext has an undocumented boot-arg that allows FileVault usage on broken APFS seals (-arv_allow_fv)
|
||||
# This is however hidden behind kern.development, thus we patch _apfs_filevault_allowed to always return true
|
||||
# Note this function was added in 11.3 (20E232, 20.4), older builds do not support this (ie. 11.2.3)
|
||||
print("- Allowing FileVault on Root Patched systems")
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "Force FileVault on Broken Seal")["Enabled"] = True
|
||||
# Lets us check in sys_patch.py if config supports FileVault
|
||||
self.config["NVRAM"]["Add"]["4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102"]["OCLP-Settings"] += " -allow_fv"
|
||||
|
||||
# Patch KC UUID panics due to RSR installation
|
||||
# - Ref: https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1019
|
||||
print("- Enabling KC UUID mismatch patch")
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -nokcmismatchpanic"
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("RSRHelper.kext", self.constants.rsrhelper_version, self.constants.rsrhelper_path)
|
||||
|
||||
if self.constants.disable_cs_lv is True:
|
||||
print("- Disabling Library Validation")
|
||||
# In Ventura, LV patch broke. For now, add AMFI arg
|
||||
# Before merging into mainline, this needs to be resolved
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "Disable Library Validation Enforcement")["Enabled"] = True
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "Disable _csr_check() in _vnode_check_signature")["Enabled"] = True
|
||||
if self.constants.disable_amfi is True:
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " amfi=0x80"
|
||||
self.config["NVRAM"]["Add"]["4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102"]["OCLP-Settings"] += " -allow_amfi"
|
||||
# CSLVFixup simply patches out __RESTRICT and __restrict out of the Music.app Binary
|
||||
# Ref: https://pewpewthespells.com/blog/blocking_code_injection_on_ios_and_os_x.html
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("CSLVFixup.kext", self.constants.cslvfixup_version, self.constants.cslvfixup_path)
|
||||
|
||||
if self.constants.secure_status is False:
|
||||
print("- Disabling SecureBootModel")
|
||||
self.config["Misc"]["Security"]["SecureBootModel"] = "Disabled"
|
||||
if self.constants.force_vmm is True:
|
||||
print("- Forcing VMM patchset to support OTA updates")
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "Reroute kern.hv_vmm_present patch (1)")["Enabled"] = True
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "Reroute kern.hv_vmm_present patch (2) Legacy")["Enabled"] = True
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "Reroute kern.hv_vmm_present patch (2) Ventura")["Enabled"] = True
|
||||
277
resources/build/smbios.py
Normal file
277
resources/build/smbios.py
Normal file
@@ -0,0 +1,277 @@
|
||||
# Class for handling SMBIOS Patches, invocation from build.py
|
||||
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
|
||||
|
||||
from resources import constants, utilities, generate_smbios
|
||||
from resources.build import support
|
||||
from data import smbios_data, cpu_data, model_array
|
||||
|
||||
import subprocess, plistlib, binascii, uuid, ast
|
||||
from pathlib import Path
|
||||
|
||||
class build_smbios:
|
||||
|
||||
def __init__(self, model, versions, config):
|
||||
self.model = model
|
||||
self.constants: constants.Constants = versions
|
||||
self.config = config
|
||||
|
||||
def build(self):
|
||||
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")
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["Booter"]["Patch"], "Comment", "Skip Board ID check")["Enabled"] = True
|
||||
|
||||
print("- Enabling VMM exemption patch")
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "Reroute kern.hv_vmm_present patch (1)")["Enabled"] = True
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "Reroute kern.hv_vmm_present patch (2) Legacy")["Enabled"] = True
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "Reroute kern.hv_vmm_present patch (2) Ventura")["Enabled"] = True
|
||||
else:
|
||||
print("- Enabling SMC exemption patch")
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Identifier", "com.apple.driver.AppleSMC")["Enabled"] = True
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("SMC-Spoof.kext", self.constants.smcspoof_version, self.constants.smcspoof_path)
|
||||
|
||||
if self.constants.serial_settings in ["Moderate", "Advanced"]:
|
||||
print("- Enabling USB Rename Patches")
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["ACPI"]["Patch"], "Comment", "XHC1 to SHC1")["Enabled"] = True
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["ACPI"]["Patch"], "Comment", "EHC1 to EH01")["Enabled"] = True
|
||||
support.build_support(self.model, self.constants, self.config).get_item_by_kv(self.config["ACPI"]["Patch"], "Comment", "EHC2 to EH02")["Enabled"] = True
|
||||
|
||||
if self.model == self.constants.override_smbios:
|
||||
print("- Adding -no_compat_check")
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -no_compat_check"
|
||||
|
||||
|
||||
def set_smbios(self):
|
||||
spoofed_model = self.model
|
||||
|
||||
if self.constants.override_smbios == "Default":
|
||||
if self.constants.serial_settings != "None":
|
||||
print("- Setting macOS Monterey Supported SMBIOS")
|
||||
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}")
|
||||
|
||||
spoofed_board = ""
|
||||
if spoofed_model in smbios_data.smbios_dictionary:
|
||||
if "Board ID" in smbios_data.smbios_dictionary[spoofed_model]:
|
||||
spoofed_board = smbios_data.smbios_dictionary[spoofed_model]["Board ID"]
|
||||
print(f"- Using Board ID: {spoofed_board}")
|
||||
|
||||
self.spoofed_model = spoofed_model
|
||||
self.spoofed_board = spoofed_board
|
||||
|
||||
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}"
|
||||
|
||||
if self.constants.serial_settings == "Moderate":
|
||||
print("- Using Moderate SMBIOS patching")
|
||||
self.moderate_serial_patch()
|
||||
elif self.constants.serial_settings == "Advanced":
|
||||
print("- Using Advanced SMBIOS patching")
|
||||
self.advanced_serial_patch()
|
||||
elif self.constants.serial_settings == "Minimal":
|
||||
print("- Using Minimal SMBIOS patching")
|
||||
self.spoofed_model = self.model
|
||||
self.minimal_serial_patch()
|
||||
else:
|
||||
# Update DataHub to resolve Lilu Race Condition
|
||||
# macOS Monterey will sometimes not present the boardIdentifier in the DeviceTree on UEFI 1.2 or older Mac,
|
||||
# Thus resulting in an infinite 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
|
||||
# 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):
|
||||
print("- Detected UEFI 1.2 or older Mac, updating BoardProduct")
|
||||
self.config["PlatformInfo"]["DataHub"]["BoardProduct"] = self.spoofed_board
|
||||
self.config["PlatformInfo"]["UpdateDataHub"] = True
|
||||
|
||||
if self.constants.custom_serial_number != "" and self.constants.custom_board_serial_number != "":
|
||||
print("- Adding custom serial numbers")
|
||||
self.config["PlatformInfo"]["Automatic"] = True
|
||||
self.config["PlatformInfo"]["UpdateDataHub"] = True
|
||||
self.config["PlatformInfo"]["UpdateNVRAM"] = True
|
||||
self.config["PlatformInfo"]["UpdateSMBIOS"] = True
|
||||
self.config["UEFI"]["ProtocolOverrides"]["DataHub"] = True
|
||||
self.config["PlatformInfo"]["Generic"]["SystemSerialNumber"] = self.constants.custom_serial_number
|
||||
self.config["PlatformInfo"]["Generic"]["MLB"] = self.constants.custom_board_serial_number
|
||||
self.config["PlatformInfo"]["Generic"]["MaxBIOSVersion"] = False
|
||||
self.config["PlatformInfo"]["Generic"]["SystemProductName"] = self.spoofed_model
|
||||
self.config["NVRAM"]["Add"]["4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102"]["OCLP-Spoofed-SN"] = self.constants.custom_serial_number
|
||||
self.config["NVRAM"]["Add"]["4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102"]["OCLP-Spoofed-MLB"] = self.constants.custom_board_serial_number
|
||||
|
||||
# USB Map and CPUFriend Patching
|
||||
if (
|
||||
self.constants.allow_oc_everywhere is False
|
||||
and self.model not in ["Xserve2,1", "Dortania1,1"]
|
||||
and ((self.model in model_array.Missing_USB_Map or self.model in model_array.Missing_USB_Map_Ventura) or self.constants.serial_settings in ["Moderate", "Advanced"])
|
||||
):
|
||||
new_map_ls = Path(self.constants.map_contents_folder) / Path("Info.plist")
|
||||
map_config = plistlib.load(Path(new_map_ls).open("rb"))
|
||||
# Strip unused USB maps
|
||||
for entry in list(map_config["IOKitPersonalities_x86_64"]):
|
||||
if not entry.startswith(self.model):
|
||||
map_config["IOKitPersonalities_x86_64"].pop(entry)
|
||||
else:
|
||||
try:
|
||||
map_config["IOKitPersonalities_x86_64"][entry]["model"] = self.spoofed_model
|
||||
if self.constants.serial_settings in ["Minimal", "None"]:
|
||||
if map_config["IOKitPersonalities_x86_64"][entry]["IONameMatch"] == "EH01":
|
||||
map_config["IOKitPersonalities_x86_64"][entry]["IONameMatch"] = "EHC1"
|
||||
if map_config["IOKitPersonalities_x86_64"][entry]["IONameMatch"] == "EH02":
|
||||
map_config["IOKitPersonalities_x86_64"][entry]["IONameMatch"] = "EHC2"
|
||||
if map_config["IOKitPersonalities_x86_64"][entry]["IONameMatch"] == "SHC1":
|
||||
map_config["IOKitPersonalities_x86_64"][entry]["IONameMatch"] = "XHC1"
|
||||
except KeyError:
|
||||
continue
|
||||
plistlib.dump(map_config, Path(new_map_ls).open("wb"), sort_keys=True)
|
||||
if self.constants.allow_oc_everywhere is False and self.model not in ["iMac7,1", "Xserve2,1", "Dortania1,1"] and self.constants.disallow_cpufriend is False and self.constants.serial_settings != "None":
|
||||
# Adjust CPU Friend Data to correct SMBIOS
|
||||
new_cpu_ls = Path(self.constants.pp_contents_folder) / Path("Info.plist")
|
||||
cpu_config = plistlib.load(Path(new_cpu_ls).open("rb"))
|
||||
string_stuff = str(cpu_config["IOKitPersonalities"]["CPUFriendDataProvider"]["cf-frequency-data"])
|
||||
string_stuff = string_stuff.replace(self.model, self.spoofed_model)
|
||||
string_stuff = ast.literal_eval(string_stuff)
|
||||
cpu_config["IOKitPersonalities"]["CPUFriendDataProvider"]["cf-frequency-data"] = string_stuff
|
||||
plistlib.dump(cpu_config, Path(new_cpu_ls).open("wb"), sort_keys=True)
|
||||
|
||||
if self.constants.allow_oc_everywhere is False and self.constants.serial_settings != "None":
|
||||
if self.model == "MacBookPro9,1":
|
||||
new_amc_ls = Path(self.constants.amc_contents_folder) / Path("Info.plist")
|
||||
amc_config = plistlib.load(Path(new_amc_ls).open("rb"))
|
||||
amc_config["IOKitPersonalities"]["AppleMuxControl"]["ConfigMap"][self.spoofed_board] = amc_config["IOKitPersonalities"]["AppleMuxControl"]["ConfigMap"].pop(self.model)
|
||||
for entry in list(amc_config["IOKitPersonalities"]["AppleMuxControl"]["ConfigMap"]):
|
||||
if not entry.startswith(self.spoofed_board):
|
||||
amc_config["IOKitPersonalities"]["AppleMuxControl"]["ConfigMap"].pop(entry)
|
||||
plistlib.dump(amc_config, Path(new_amc_ls).open("wb"), sort_keys=True)
|
||||
if self.model not in model_array.NoAGPMSupport:
|
||||
new_agpm_ls = Path(self.constants.agpm_contents_folder) / Path("Info.plist")
|
||||
agpm_config = plistlib.load(Path(new_agpm_ls).open("rb"))
|
||||
agpm_config["IOKitPersonalities"]["AGPM"]["Machines"][self.spoofed_board] = agpm_config["IOKitPersonalities"]["AGPM"]["Machines"].pop(self.model)
|
||||
if self.model == "MacBookPro6,2":
|
||||
# Force G State to not exceed moderate state
|
||||
# Ref: https://github.com/fabioiop/MBP-2010-GPU-Panic-fix
|
||||
print("- Patching G State for MacBookPro6,2")
|
||||
for gpu in ["Vendor10deDevice0a34", "Vendor10deDevice0a29"]:
|
||||
agpm_config["IOKitPersonalities"]["AGPM"]["Machines"][self.spoofed_board][gpu]["BoostPState"] = [2, 2, 2, 2]
|
||||
agpm_config["IOKitPersonalities"]["AGPM"]["Machines"][self.spoofed_board][gpu]["BoostTime"] = [2, 2, 2, 2]
|
||||
|
||||
for entry in list(agpm_config["IOKitPersonalities"]["AGPM"]["Machines"]):
|
||||
if not entry.startswith(self.spoofed_board):
|
||||
agpm_config["IOKitPersonalities"]["AGPM"]["Machines"].pop(entry)
|
||||
|
||||
plistlib.dump(agpm_config, Path(new_agpm_ls).open("wb"), sort_keys=True)
|
||||
if self.model in model_array.AGDPSupport:
|
||||
new_agdp_ls = Path(self.constants.agdp_contents_folder) / Path("Info.plist")
|
||||
agdp_config = plistlib.load(Path(new_agdp_ls).open("rb"))
|
||||
agdp_config["IOKitPersonalities"]["AppleGraphicsDevicePolicy"]["ConfigMap"][self.spoofed_board] = agdp_config["IOKitPersonalities"]["AppleGraphicsDevicePolicy"]["ConfigMap"].pop(
|
||||
self.model
|
||||
)
|
||||
for entry in list(agdp_config["IOKitPersonalities"]["AppleGraphicsDevicePolicy"]["ConfigMap"]):
|
||||
if not entry.startswith(self.spoofed_board):
|
||||
agdp_config["IOKitPersonalities"]["AppleGraphicsDevicePolicy"]["ConfigMap"].pop(entry)
|
||||
plistlib.dump(agdp_config, Path(new_agdp_ls).open("wb"), sort_keys=True)
|
||||
|
||||
|
||||
def minimal_serial_patch(self):
|
||||
# Generate Firmware Features
|
||||
fw_feature = generate_smbios.generate_fw_features(self.model, self.constants.custom_model)
|
||||
# fw_feature = self.patch_firmware_feature()
|
||||
fw_feature = hex(fw_feature).lstrip("0x").rstrip("L").strip()
|
||||
print(f"- Setting Firmware Feature: {fw_feature}")
|
||||
fw_feature = utilities.string_to_hex(fw_feature)
|
||||
|
||||
# FirmwareFeatures
|
||||
self.config["PlatformInfo"]["PlatformNVRAM"]["FirmwareFeatures"] = fw_feature
|
||||
self.config["PlatformInfo"]["PlatformNVRAM"]["FirmwareFeaturesMask"] = fw_feature
|
||||
self.config["PlatformInfo"]["SMBIOS"]["FirmwareFeatures"] = fw_feature
|
||||
self.config["PlatformInfo"]["SMBIOS"]["FirmwareFeaturesMask"] = fw_feature
|
||||
|
||||
# Board ID
|
||||
self.config["PlatformInfo"]["DataHub"]["BoardProduct"] = self.spoofed_board
|
||||
self.config["PlatformInfo"]["PlatformNVRAM"]["BID"] = self.spoofed_board
|
||||
self.config["PlatformInfo"]["SMBIOS"]["BoardProduct"] = self.spoofed_board
|
||||
|
||||
# Model (ensures tables are not mismatched, even if we're not spoofing)
|
||||
self.config["PlatformInfo"]["DataHub"]["SystemProductName"] = self.model
|
||||
self.config["PlatformInfo"]["SMBIOS"]["SystemProductName"] = self.model
|
||||
self.config["PlatformInfo"]["SMBIOS"]["BoardVersion"] = self.model
|
||||
|
||||
# ProcessorType (when RestrictEvent's CPU naming is used)
|
||||
if self.constants.custom_cpu_model == 0 or self.constants.custom_cpu_model == 1:
|
||||
self.config["PlatformInfo"]["SMBIOS"]["ProcessorType"] = 1537
|
||||
|
||||
# Avoid incorrect Firmware Updates
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["run-efi-updater"] = "No"
|
||||
self.config["PlatformInfo"]["SMBIOS"]["BIOSVersion"] = "9999.999.999.999.999"
|
||||
|
||||
# Update tables
|
||||
self.config["PlatformInfo"]["UpdateNVRAM"] = True
|
||||
self.config["PlatformInfo"]["UpdateSMBIOS"] = True
|
||||
self.config["PlatformInfo"]["UpdateDataHub"] = True
|
||||
|
||||
if self.constants.custom_serial_number != "" and self.constants.custom_board_serial_number != "":
|
||||
print("- Adding custom serial numbers")
|
||||
sn = self.constants.custom_serial_number
|
||||
mlb = self.constants.custom_board_serial_number
|
||||
|
||||
# Serial Number
|
||||
self.config["PlatformInfo"]["SMBIOS"]["ChassisSerialNumber"] = sn
|
||||
self.config["PlatformInfo"]["SMBIOS"]["SystemSerialNumber"] = sn
|
||||
self.config["PlatformInfo"]["DataHub"]["SystemSerialNumber"] = sn
|
||||
self.config["PlatformInfo"]["PlatformNVRAM"]["SystemSerialNumber"] = sn
|
||||
self.config["NVRAM"]["Add"]["4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102"]["OCLP-Spoofed-SN"] = sn
|
||||
|
||||
# Board Serial Number
|
||||
self.config["PlatformInfo"]["SMBIOS"]["BoardSerialNumber"] = mlb
|
||||
self.config["PlatformInfo"]["PlatformNVRAM"]["BoardSerialNumber"] = mlb
|
||||
self.config["NVRAM"]["Add"]["4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102"]["OCLP-Spoofed-MLB"] = mlb
|
||||
|
||||
|
||||
def moderate_serial_patch(self):
|
||||
if self.constants.custom_cpu_model == 0 or self.constants.custom_cpu_model == 1:
|
||||
self.config["PlatformInfo"]["Generic"]["ProcessorType"] = 1537
|
||||
if self.constants.custom_serial_number != "" and self.constants.custom_board_serial_number != "":
|
||||
print("- Adding custom serial numbers")
|
||||
self.config["PlatformInfo"]["Generic"]["SystemSerialNumber"] = self.constants.custom_serial_number
|
||||
self.config["PlatformInfo"]["Generic"]["MLB"] = self.constants.custom_board_serial_number
|
||||
self.config["NVRAM"]["Add"]["4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102"]["OCLP-Spoofed-SN"] = self.constants.custom_serial_number
|
||||
self.config["NVRAM"]["Add"]["4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102"]["OCLP-Spoofed-MLB"] = self.constants.custom_board_serial_number
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["run-efi-updater"] = "No"
|
||||
self.config["PlatformInfo"]["Automatic"] = True
|
||||
self.config["PlatformInfo"]["UpdateDataHub"] = True
|
||||
self.config["PlatformInfo"]["UpdateNVRAM"] = True
|
||||
self.config["PlatformInfo"]["UpdateSMBIOS"] = True
|
||||
self.config["UEFI"]["ProtocolOverrides"]["DataHub"] = True
|
||||
self.config["PlatformInfo"]["Generic"]["SystemProductName"] = self.spoofed_model
|
||||
|
||||
|
||||
def advanced_serial_patch(self):
|
||||
if self.constants.custom_cpu_model == 0 or self.constants.custom_cpu_model == 1:
|
||||
self.config["PlatformInfo"]["Generic"]["ProcessorType"] = 1537
|
||||
if self.constants.custom_serial_number == "" or self.constants.custom_board_serial_number == "":
|
||||
macserial_output = subprocess.run([self.constants.macserial_path] + f"-g -m {self.spoofed_model} -n 1".split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
macserial_output = macserial_output.stdout.decode().strip().split(" | ")
|
||||
sn = macserial_output[0]
|
||||
mlb = macserial_output[1]
|
||||
else:
|
||||
sn = self.constants.custom_serial_number
|
||||
mlb = self.constants.custom_board_serial_number
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["run-efi-updater"] = "No"
|
||||
self.config["PlatformInfo"]["Automatic"] = True
|
||||
self.config["PlatformInfo"]["UpdateDataHub"] = True
|
||||
self.config["PlatformInfo"]["UpdateNVRAM"] = True
|
||||
self.config["PlatformInfo"]["UpdateSMBIOS"] = True
|
||||
self.config["UEFI"]["ProtocolOverrides"]["DataHub"] = True
|
||||
self.config["PlatformInfo"]["Generic"]["ROM"] = binascii.unhexlify("0016CB445566")
|
||||
self.config["PlatformInfo"]["Generic"]["SystemProductName"] = self.spoofed_model
|
||||
self.config["PlatformInfo"]["Generic"]["SystemSerialNumber"] = sn
|
||||
self.config["PlatformInfo"]["Generic"]["MLB"] = mlb
|
||||
self.config["PlatformInfo"]["Generic"]["SystemUUID"] = str(uuid.uuid4()).upper()
|
||||
self.config["NVRAM"]["Add"]["4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102"]["OCLP-Spoofed-SN"] = sn
|
||||
self.config["NVRAM"]["Add"]["4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102"]["OCLP-Spoofed-MLB"] = mlb
|
||||
136
resources/build/storage.py
Normal file
136
resources/build/storage.py
Normal file
@@ -0,0 +1,136 @@
|
||||
# Class for handling Storage Controller Patches, invocation from build.py
|
||||
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
|
||||
|
||||
from resources import constants, device_probe, utilities
|
||||
from resources.build import support
|
||||
from data import model_array, smbios_data, cpu_data
|
||||
|
||||
|
||||
class build_storage:
|
||||
|
||||
def __init__(self, model, versions, config):
|
||||
self.model = model
|
||||
self.constants: constants.Constants = versions
|
||||
self.config = config
|
||||
self.computer = self.constants.computer
|
||||
|
||||
|
||||
def build(self):
|
||||
self.ahci_handling()
|
||||
self.pata_handling()
|
||||
self.misc_handling()
|
||||
self.pcie_handling()
|
||||
self.trim_handling()
|
||||
|
||||
def ahci_handling(self):
|
||||
# MacBookAir6,x ship with an AHCI over PCIe SSD model 'APPLE SSD TS0128F' and 'APPLE SSD TS0256F'
|
||||
# This controller is not supported properly in macOS Ventura, instead populating itself as 'Media' with no partitions
|
||||
# To work-around this, use Monterey's AppleAHCI driver to force support
|
||||
if not self.constants.custom_model:
|
||||
sata_devices = [i for i in self.computer.storage if isinstance(i, device_probe.SATAController)]
|
||||
for controller in sata_devices:
|
||||
# https://linux-hardware.org/?id=pci:1179-010b-1b4b-9183
|
||||
if controller.vendor_id == 0x1179 and controller.device_id == 0x010b:
|
||||
print("- Enabling AHCI SSD patch")
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("MonteAHCIPort.kext", self.constants.monterey_ahci_version, self.constants.monterey_ahci_path)
|
||||
break
|
||||
elif self.model in ["MacBookAir6,1", "MacBookAir6,2"]:
|
||||
print("- Enabling AHCI SSD patch")
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("MonteAHCIPort.kext", self.constants.monterey_ahci_version, self.constants.monterey_ahci_path)
|
||||
|
||||
# ThirdPartyDrives Check
|
||||
if self.constants.allow_3rd_party_drives is True:
|
||||
for drive in ["SATA 2.5", "SATA 3.5", "mSATA"]:
|
||||
if not self.model in smbios_data.smbios_dictionary:
|
||||
break
|
||||
if not "Stock Storage" in smbios_data.smbios_dictionary[self.model]:
|
||||
break
|
||||
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
|
||||
|
||||
|
||||
def pata_handling(self):
|
||||
if not self.model in smbios_data.smbios_dictionary:
|
||||
return
|
||||
if not "Stock Storage" in smbios_data.smbios_dictionary[self.model]:
|
||||
return
|
||||
if not "PATA" in smbios_data.smbios_dictionary[self.model]["Stock Storage"]:
|
||||
return
|
||||
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("AppleIntelPIIXATA.kext", self.constants.piixata_version, self.constants.piixata_path)
|
||||
|
||||
|
||||
def pcie_handling(self):
|
||||
if not self.constants.custom_model and (self.constants.allow_oc_everywhere is True or self.model in model_array.MacPro):
|
||||
# Use Innie's same logic:
|
||||
# https://github.com/cdf/Innie/blob/v1.3.0/Innie/Innie.cpp#L90-L97
|
||||
for i, controller in enumerate(self.computer.storage):
|
||||
print(f"- Fixing PCIe Storage Controller ({i + 1}) reporting")
|
||||
if controller.pci_path:
|
||||
self.config["DeviceProperties"]["Add"][controller.pci_path] = {"built-in": 1}
|
||||
else:
|
||||
print(f"- Failed to find Device path for PCIe Storage Controller {i}, falling back to Innie")
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("Innie.kext", self.constants.innie_version, self.constants.innie_path)
|
||||
|
||||
if not self.constants.custom_model and self.constants.allow_nvme_fixing is True:
|
||||
nvme_devices = [i for i in self.computer.storage if isinstance(i, device_probe.NVMeController)]
|
||||
for i, controller in enumerate(nvme_devices):
|
||||
print(f"- Found 3rd Party NVMe SSD ({i + 1}): {utilities.friendly_hex(controller.vendor_id)}:{utilities.friendly_hex(controller.device_id)}")
|
||||
self.config["#Revision"][f"Hardware-NVMe-{i}"] = f"{utilities.friendly_hex(controller.vendor_id)}:{utilities.friendly_hex(controller.device_id)}"
|
||||
|
||||
# Disable Bit 0 (L0s), enable Bit 1 (L1)
|
||||
nvme_aspm = (controller.aspm & (~0b11)) | 0b10
|
||||
|
||||
if controller.pci_path:
|
||||
print(f"- Found NVMe ({i}) at {controller.pci_path}")
|
||||
self.config["DeviceProperties"]["Add"].setdefault(controller.pci_path, {})["pci-aspm-default"] = nvme_aspm
|
||||
self.config["DeviceProperties"]["Add"][controller.pci_path.rpartition("/")[0]] = {"pci-aspm-default": nvme_aspm}
|
||||
else:
|
||||
if "-nvmefaspm" not in self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"]:
|
||||
print("- Falling back to -nvmefaspm")
|
||||
self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -nvmefaspm"
|
||||
|
||||
if (controller.vendor_id != 0x144D and controller.device_id != 0xA804):
|
||||
# Avoid injecting NVMeFix when a native Apple NVMe drive is present
|
||||
# https://github.com/acidanthera/NVMeFix/blob/1.0.9/NVMeFix/NVMeFix.cpp#L220-L225
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("NVMeFix.kext", self.constants.nvmefix_version, self.constants.nvmefix_path)
|
||||
|
||||
# Apple RAID Card check
|
||||
if not self.constants.custom_model:
|
||||
if self.computer.storage:
|
||||
for storage_controller in self.computer.storage:
|
||||
if storage_controller.vendor_id == 0x106b and storage_controller.device_id == 0x008A:
|
||||
# AppleRAIDCard.kext only supports pci106b,8a
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("AppleRAIDCard.kext", self.constants.apple_raid_version, self.constants.apple_raid_path)
|
||||
break
|
||||
elif self.model.startswith("Xserve"):
|
||||
# For Xserves, assume RAID is present
|
||||
# Namely due to Xserve2,1 being limited to 10.7, thus no hardware detection
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("AppleRAIDCard.kext", self.constants.apple_raid_version, self.constants.apple_raid_path)
|
||||
|
||||
|
||||
def misc_handling(self):
|
||||
if not self.model in smbios_data.smbios_dictionary:
|
||||
return
|
||||
if not "CPU Generation" in smbios_data.smbios_dictionary[self.model]:
|
||||
return
|
||||
|
||||
# With macOS Monterey, Apple's SDXC driver requires the system to support VT-D
|
||||
# However pre-Ivy Bridge don't support this feature
|
||||
if smbios_data.smbios_dictionary[self.model]["CPU Generation"] <= cpu_data.cpu_data.sandy_bridge.value:
|
||||
if (self.constants.computer.sdxc_controller and not self.constants.custom_model) or (self.model.startswith("MacBookPro8") or self.model.startswith("Macmini5")):
|
||||
support.build_support(self.model, self.constants, self.config).enable_kext("BigSurSDXC.kext", self.constants.bigsursdxc_version, self.constants.bigsursdxc_path)
|
||||
|
||||
|
||||
def trim_handling(self):
|
||||
if self.constants.apfs_trim_timeout is False:
|
||||
print(f"- Disabling APFS TRIM timeout")
|
||||
self.config["Kernel"]["Quirks"]["SetApfsTrimTimeout"] = 0
|
||||
179
resources/build/support.py
Normal file
179
resources/build/support.py
Normal file
@@ -0,0 +1,179 @@
|
||||
# Utility class for build functions
|
||||
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
|
||||
|
||||
from resources import constants, utilities
|
||||
|
||||
from pathlib import Path
|
||||
import shutil, plistlib, subprocess, zipfile
|
||||
|
||||
class build_support:
|
||||
|
||||
def __init__(self, model, versions, config):
|
||||
self.model = model
|
||||
self.constants: constants.Constants = versions
|
||||
self.config = config
|
||||
|
||||
|
||||
@staticmethod
|
||||
def get_item_by_kv(iterable, key, value):
|
||||
item = None
|
||||
for i in iterable:
|
||||
if i[key] == value:
|
||||
item = i
|
||||
break
|
||||
return item
|
||||
|
||||
|
||||
def get_kext_by_bundle_path(self, bundle_path):
|
||||
kext = self.get_item_by_kv(self.config["Kernel"]["Add"], "BundlePath", bundle_path)
|
||||
if not kext:
|
||||
print(f"- Could not find kext {bundle_path}!")
|
||||
raise IndexError
|
||||
return kext
|
||||
|
||||
|
||||
def get_efi_binary_by_path(self, bundle_path, entry_location, efi_type):
|
||||
efi_binary = self.get_item_by_kv(self.config[entry_location][efi_type], "Path", bundle_path)
|
||||
if not efi_binary:
|
||||
print(f"- Could not find {efi_type}: {bundle_path}!")
|
||||
raise IndexError
|
||||
return efi_binary
|
||||
|
||||
|
||||
def enable_kext(self, kext_name, kext_version, kext_path, check=False):
|
||||
kext = self.get_kext_by_bundle_path(kext_name)
|
||||
|
||||
if callable(check) and not check():
|
||||
# Check failed
|
||||
return
|
||||
|
||||
if kext["Enabled"] is True:
|
||||
return
|
||||
|
||||
print(f"- Adding {kext_name} {kext_version}")
|
||||
shutil.copy(kext_path, self.constants.kexts_path)
|
||||
kext["Enabled"] = True
|
||||
|
||||
|
||||
def sign_files(self):
|
||||
if self.constants.vault is False:
|
||||
return
|
||||
|
||||
if utilities.check_command_line_tools() is False:
|
||||
# sign.command checks for the existence of '/usr/bin/strings' however does not verify whether it's executable
|
||||
# sign.command will continue to run and create an unbootable OpenCore.efi due to the missing strings binary
|
||||
# macOS has dummy binaries that just reroute to the actual binaries after you install Xcode's Command Line Tools
|
||||
print("- Missing Command Line tools, skipping Vault for saftey reasons")
|
||||
print("- Install via 'xcode-select --install' and rerun OCLP if you wish to vault this config")
|
||||
return
|
||||
|
||||
print("- Vaulting EFI")
|
||||
subprocess.run([str(self.constants.vault_path), f"{self.constants.oc_folder}/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
|
||||
|
||||
def validate_pathing(self):
|
||||
# Verify whether all files are accounted for on-disk
|
||||
# This ensures that OpenCore won't hit a critical error and fail to boot
|
||||
print("- Validating generated config")
|
||||
if not Path(self.constants.opencore_release_folder / Path("EFI/OC/config.plist")):
|
||||
print("- OpenCore config file missing!!!")
|
||||
raise Exception("OpenCore config file missing")
|
||||
|
||||
config_plist = plistlib.load(Path(self.constants.opencore_release_folder / Path("EFI/OC/config.plist")).open("rb"))
|
||||
|
||||
for acpi in config_plist["ACPI"]["Add"]:
|
||||
if not Path(self.constants.opencore_release_folder / Path("EFI/OC/ACPI") / Path(acpi["Path"])).exists():
|
||||
print(f" - Missing ACPI Table: {acpi['Path']}")
|
||||
raise Exception(f"Missing ACPI Table: {acpi['Path']}")
|
||||
|
||||
for kext in config_plist["Kernel"]["Add"]:
|
||||
kext_path = Path(self.constants.opencore_release_folder / Path("EFI/OC/Kexts") / Path(kext["BundlePath"]))
|
||||
kext_binary_path = Path(kext_path / Path(kext["ExecutablePath"]))
|
||||
kext_plist_path = Path(kext_path / Path(kext["PlistPath"]))
|
||||
if not kext_path.exists():
|
||||
print(f"- Missing kext: {kext_path}")
|
||||
raise Exception(f"Missing {kext_path}")
|
||||
if not kext_binary_path.exists():
|
||||
print(f"- Missing {kext['BundlePath']}'s binary: {kext_binary_path}")
|
||||
raise Exception(f"Missing {kext_binary_path}")
|
||||
if not kext_plist_path.exists():
|
||||
print(f"- Missing {kext['BundlePath']}'s plist: {kext_plist_path}")
|
||||
raise Exception(f"Missing {kext_plist_path}")
|
||||
|
||||
for tool in config_plist["Misc"]["Tools"]:
|
||||
if not Path(self.constants.opencore_release_folder / Path("EFI/OC/Tools") / Path(tool["Path"])).exists():
|
||||
print(f" - Missing tool: {tool['Path']}")
|
||||
raise Exception(f"Missing tool: {tool['Path']}")
|
||||
|
||||
for driver in config_plist["UEFI"]["Drivers"]:
|
||||
if not Path(self.constants.opencore_release_folder / Path("EFI/OC/Drivers") / Path(driver["Path"])).exists():
|
||||
print(f" - Missing driver: {driver['Path']}")
|
||||
raise Exception(f"Missing driver: {driver['Path']}")
|
||||
|
||||
# Validating local files
|
||||
# Report if they have no associated config.plist entry (i.e. they're not being used)
|
||||
for tool_files in Path(self.constants.opencore_release_folder / Path("EFI/OC/Tools")).glob("*"):
|
||||
if tool_files.name not in [x["Path"] for x in config_plist["Misc"]["Tools"]]:
|
||||
print(f" - Missing tool from config: {tool_files.name}")
|
||||
raise Exception(f"Missing tool from config: {tool_files.name}")
|
||||
|
||||
for driver_file in Path(self.constants.opencore_release_folder / Path("EFI/OC/Drivers")).glob("*"):
|
||||
if driver_file.name not in [x["Path"] for x in config_plist["UEFI"]["Drivers"]]:
|
||||
print(f"- Found extra driver: {driver_file.name}")
|
||||
raise Exception(f"Found extra driver: {driver_file.name}")
|
||||
|
||||
|
||||
def cleanup(self):
|
||||
print("- Cleaning up files")
|
||||
# Remove unused entries
|
||||
entries_to_clean = {
|
||||
"ACPI": ["Add", "Delete", "Patch"],
|
||||
"Booter": ["Patch"],
|
||||
"Kernel": ["Add", "Block", "Force", "Patch"],
|
||||
"Misc": ["Tools"],
|
||||
"UEFI": ["Drivers"],
|
||||
}
|
||||
|
||||
for entry in entries_to_clean:
|
||||
for sub_entry in entries_to_clean[entry]:
|
||||
for item in list(self.config[entry][sub_entry]):
|
||||
if item["Enabled"] is False:
|
||||
self.config[entry][sub_entry].remove(item)
|
||||
|
||||
for kext in self.constants.kexts_path.rglob("*.zip"):
|
||||
with zipfile.ZipFile(kext) as zip_file:
|
||||
zip_file.extractall(self.constants.kexts_path)
|
||||
kext.unlink()
|
||||
|
||||
for item in self.constants.oc_folder.rglob("*.zip"):
|
||||
with zipfile.ZipFile(item) as zip_file:
|
||||
zip_file.extractall(self.constants.oc_folder)
|
||||
item.unlink()
|
||||
|
||||
if not self.constants.recovery_status:
|
||||
# Crashes in RecoveryOS for unknown reason
|
||||
for i in self.constants.build_path.rglob("__MACOSX"):
|
||||
shutil.rmtree(i)
|
||||
|
||||
# Remove unused plugins inside of kexts
|
||||
# Following plugins are sometimes unused as there's different variants machines need
|
||||
known_unused_plugins = [
|
||||
"AirPortBrcm4331.kext",
|
||||
"AirPortAtheros40.kext",
|
||||
"AppleAirPortBrcm43224.kext",
|
||||
"AirPortBrcm4360_Injector.kext",
|
||||
"AirPortBrcmNIC_Injector.kext"
|
||||
]
|
||||
for kext in Path(self.constants.opencore_release_folder / Path("EFI/OC/Kexts")).glob("*.kext"):
|
||||
for plugin in Path(kext / "Contents/PlugIns/").glob("*.kext"):
|
||||
should_remove = True
|
||||
for enabled_kexts in self.config["Kernel"]["Add"]:
|
||||
if enabled_kexts["BundlePath"].endswith(plugin.name):
|
||||
should_remove = False
|
||||
break
|
||||
if should_remove:
|
||||
if plugin.name not in known_unused_plugins:
|
||||
raise Exception(f" - Unknown plugin found: {plugin.name}")
|
||||
shutil.rmtree(plugin)
|
||||
|
||||
Path(self.constants.opencore_zip_copied).unlink()
|
||||
@@ -2,7 +2,8 @@
|
||||
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
|
||||
import sys
|
||||
|
||||
from resources import constants, install, utilities, defaults, sys_patch, installer, tui_helpers, global_settings
|
||||
from resources import constants, install, utilities, defaults, installer, tui_helpers, global_settings
|
||||
from resources.sys_patch import sys_patch
|
||||
from data import cpu_data, smbios_data, model_array, os_data, mirror_data
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# pylint: disable=multiple-statements
|
||||
# Define Files
|
||||
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
|
||||
# Copyright (C) 2020-2023, Dhinak G, Mykola Grymalyuk
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
@@ -12,36 +12,35 @@ from data import os_data
|
||||
class Constants:
|
||||
def __init__(self):
|
||||
# Patcher Versioning
|
||||
self.patcher_version = "0.5.1" # OpenCore-Legacy-Patcher
|
||||
self.patcher_support_pkg_version = "0.7.1" # PatcherSupportPkg
|
||||
self.patcher_version = "0.6.0" # OpenCore-Legacy-Patcher
|
||||
self.patcher_support_pkg_version = "0.8.2" # 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}"
|
||||
self.copyright_date = "Copyright © 2020-2022 Dortania"
|
||||
self.copyright_date = "Copyright © 2020-2023 Dortania"
|
||||
self.installer_pkg_url = f"{self.repo_link}/releases/download/{self.patcher_version}/AutoPkg-Assets.pkg"
|
||||
self.installer_pkg_url_nightly = "http://nightly.link/dortania/OpenCore-Legacy-Patcher/workflows/build-app-wxpython/main/AutoPkg-Assets.pkg.zip"
|
||||
|
||||
# OpenCore Versioning
|
||||
# https://github.com/acidanthera/OpenCorePkg
|
||||
self.opencore_commit = "c14b2ab - 10-04-2022"
|
||||
self.opencore_version = "0.8.5"
|
||||
self.opencore_commit = "a753334 - 01-02-2023"
|
||||
self.opencore_version = "0.8.8"
|
||||
|
||||
# Kext Versioning
|
||||
## Acidanthera
|
||||
## https://github.com/acidanthera
|
||||
self.lilu_version = "1.6.2" # Lilu
|
||||
self.whatevergreen_version = "1.5.8" # WhateverGreen
|
||||
self.airportbcrmfixup_version = "2.1.3" # AirPortBrcmFixup
|
||||
self.lilu_version = "1.6.3" # Lilu
|
||||
self.whatevergreen_version = "1.6.3" # WhateverGreen
|
||||
self.airportbcrmfixup_version = "2.1.6" # AirPortBrcmFixup
|
||||
self.nvmefix_version = "1.0.9" # NVMeFix
|
||||
self.applealc_version = "1.6.3" # AppleALC
|
||||
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.9" # FeatureUnlock
|
||||
self.debugenhancer_version = "1.0.4" # DebugEnhancer
|
||||
self.cpufriend_version = "1.2.5" # CPUFriend
|
||||
self.restrictevents_version = "1.0.9" # RestrictEvents
|
||||
self.featureunlock_version = "1.1.2" # FeatureUnlock
|
||||
self.debugenhancer_version = "1.0.7" # DebugEnhancer
|
||||
self.cpufriend_version = "1.2.6" # CPUFriend
|
||||
self.bluetool_version = "2.6.4" # BlueToolFixup (BrcmPatchRAM)
|
||||
self.cslvfixup_version = "2.6.1" # CSLVFixup
|
||||
self.autopkg_version = "1.0.1" # AutoPkgInstaller
|
||||
@@ -80,6 +79,7 @@ class Constants:
|
||||
self.mce_version = "1.0.0" # AppleMCEReporterDisabler
|
||||
self.btspoof_version = "1.0.0" # Bluetooth-Spoof
|
||||
self.aspp_override_version = "1.0.1" # ACPI_SMC_PlatformPlugin Override
|
||||
self.rsrhelper_version = "1.0.0" # RSRHelper
|
||||
|
||||
## Syncretic
|
||||
## https://forums.macrumors.com/members/syncretic.1173816/
|
||||
@@ -99,6 +99,10 @@ class Constants:
|
||||
## https://github.com/blackgate/AMDGPUWakeHandler
|
||||
self.gpu_wake_version = "1.0.0"
|
||||
|
||||
## flagersgit
|
||||
## https://github.com/flagersgit/KDKlessWorkaround
|
||||
self.kdkless_version = "1.0.0"
|
||||
|
||||
# Get resource path
|
||||
self.current_path = Path(__file__).parent.parent.resolve()
|
||||
self.payload_path = self.current_path / Path("payloads")
|
||||
@@ -116,7 +120,8 @@ class Constants:
|
||||
self.wxpython_variant = False # Determine if using wxPython variant
|
||||
self.unpack_thread = None # Determine if unpack thread finished
|
||||
self.cli_mode = False # Determine if running in CLI mode
|
||||
self.should_nuke_kdks = True # Determine if KDKs should be nuked if unused in /L*/D*/KDKs
|
||||
self.should_nuke_kdks = True # Determine if KDKs should be nuked if unused in /L*/D*/KDKs
|
||||
self.has_checked_updates = False # Determine if check for updates has been run
|
||||
|
||||
## Hardware
|
||||
self.computer: device_probe.Computer = None # type: ignore
|
||||
@@ -177,6 +182,8 @@ class Constants:
|
||||
self.allow_ts2_accel = True # Set TeraScale 2 Acceleration support
|
||||
self.force_nv_web = False # Force Nvidia Web Drivers on Tesla and Kepler
|
||||
self.force_output_support = False # Force Output support for Mac Pros with PC VBIOS
|
||||
self.amd_gop_injection = False # Set GOP Injection support
|
||||
self.nvidia_kepler_gop_injection = False # Set Kepler GOP Injection support
|
||||
|
||||
## Miscellaneous
|
||||
self.disallow_cpufriend = False # Disable CPUFriend
|
||||
@@ -205,10 +212,12 @@ class Constants:
|
||||
self.commit_info = (None, None, None)
|
||||
self.set_vmm_cpuid = False # Set VMM bit inside CPUID
|
||||
self.oc_timeout = 5 # Set OpenCore timeout
|
||||
self.apfs_trim_timeout = True # Set APFS Trim timeout
|
||||
|
||||
self.legacy_accel_support = [
|
||||
os_data.os_data.big_sur,
|
||||
os_data.os_data.monterey,
|
||||
os_data.os_data.ventura,
|
||||
]
|
||||
|
||||
# Payload Location
|
||||
@@ -248,6 +257,14 @@ class Constants:
|
||||
def exfat_legacy_driver_path(self):
|
||||
return self.payload_path / Path("Drivers/ExFatDxeLegacy.efi")
|
||||
|
||||
@property
|
||||
def amd_gop_driver_path(self):
|
||||
return self.payload_path / Path("Drivers/AMDGOP.efi")
|
||||
|
||||
@property
|
||||
def nvidia_kepler_gop_driver_path(self):
|
||||
return self.payload_path / Path("Drivers/NVGOP_GK.efi")
|
||||
|
||||
@property
|
||||
def xhci_driver_path(self):
|
||||
return self.payload_path / Path("Drivers/XhciDxe.efi")
|
||||
@@ -260,6 +277,10 @@ class Constants:
|
||||
def diags_launcher_path(self):
|
||||
return self.payload_path / Path("Drivers/diags.efi")
|
||||
|
||||
@property
|
||||
def link_rate_driver_path(self):
|
||||
return self.payload_path / Path("Drivers/FixPCIeLinkRate.efi")
|
||||
|
||||
@property
|
||||
def list_txt_path(self):
|
||||
return self.payload_path / Path("List.txt")
|
||||
@@ -291,11 +312,7 @@ class Constants:
|
||||
|
||||
@property
|
||||
def efi_disabler_path(self):
|
||||
return self.payload_kexts_path / Path(f"Acidanthera/EFICheckDisabler-v{self.restrictevents_version}.zip")
|
||||
|
||||
@property
|
||||
def restrictevents_mbp_path(self):
|
||||
return self.payload_kexts_path / Path(f"Acidanthera/RestrictEvents-MBP91-v{self.restrictevents_mbp_version}-{self.kext_variant}.zip")
|
||||
return self.payload_kexts_path / Path(f"Acidanthera/EFICheckDisabler.zip")
|
||||
|
||||
@property
|
||||
def bcm570_path(self):
|
||||
@@ -433,6 +450,10 @@ class Constants:
|
||||
def cryptexfixup_path(self):
|
||||
return self.payload_kexts_path / Path(f"Acidanthera/CryptexFixup-v{self.cryptexfixup_version}-{self.kext_variant}.zip")
|
||||
|
||||
@property
|
||||
def rsrhelper_path(self):
|
||||
return self.payload_kexts_path / Path(f"Acidanthera/RSRHelper-v{self.rsrhelper_version}-{self.kext_variant}.zip")
|
||||
|
||||
@property
|
||||
def innie_path(self):
|
||||
return self.payload_kexts_path / Path(f"Misc/Innie-v{self.innie_version}.zip")
|
||||
@@ -457,6 +478,10 @@ class Constants:
|
||||
def apple_raid_path(self):
|
||||
return self.payload_kexts_path / Path(f"Misc/AppleRAIDCard-v{self.apple_raid_version}.zip")
|
||||
|
||||
@property
|
||||
def kdkless_path(self):
|
||||
return self.payload_kexts_path / Path(f"Misc/KDKlessWorkaround-v{self.kdkless_version}-{self.kext_variant}.zip")
|
||||
|
||||
@property
|
||||
def plist_folder_path(self):
|
||||
return self.payload_kexts_path / Path("Plists")
|
||||
@@ -557,11 +582,7 @@ class Constants:
|
||||
# Tools
|
||||
@property
|
||||
def macserial_path(self):
|
||||
return self.payload_path / Path("Tools/macserial")
|
||||
|
||||
@property
|
||||
def gfxutil_path(self):
|
||||
return self.payload_path / Path("Tools/gfxutil")
|
||||
return self.payload_path / Path("OpenCore/macserial")
|
||||
|
||||
@property
|
||||
def vault_path(self):
|
||||
@@ -569,12 +590,16 @@ class Constants:
|
||||
|
||||
@property
|
||||
def ocvalidate_path(self):
|
||||
return self.payload_path / Path(f"Tools/ocvalidate-{self.opencore_version}")
|
||||
return self.payload_path / Path(f"OpenCore/ocvalidate")
|
||||
|
||||
@property
|
||||
def oclp_helper_path(self):
|
||||
return self.payload_path / Path("Tools/OCLP-Helper")
|
||||
|
||||
@property
|
||||
def rsrrepair_userspace_path(self):
|
||||
return self.payload_path / Path("Tools/RSRRepair")
|
||||
|
||||
# Icons
|
||||
@property
|
||||
def app_icon_path(self):
|
||||
|
||||
@@ -16,6 +16,8 @@ class generate_defaults:
|
||||
self.constants.secure_status = False
|
||||
self.constants.disable_cs_lv = False
|
||||
self.constants.disable_amfi = False
|
||||
self.constants.fu_status = True
|
||||
self.constants.fu_arguments = None
|
||||
|
||||
self.constants.custom_serial_number = ""
|
||||
self.constants.custom_board_serial_number = ""
|
||||
@@ -46,13 +48,6 @@ class generate_defaults:
|
||||
self.constants.allow_ts2_accel = False
|
||||
|
||||
if self.model in smbios_data.smbios_dictionary:
|
||||
if smbios_data.smbios_dictionary[self.model]["CPU Generation"] < cpu_data.cpu_data.ivy_bridge.value and self.model != "MacPro5,1":
|
||||
# Sidecar and AirPlay to Mac only blacklist Ivy and newer (as well as MacPro5,1)
|
||||
# Avoid extra patching without benefit
|
||||
self.constants.fu_arguments = " -disable_sidecar_mac"
|
||||
else:
|
||||
self.constants.fu_arguments = None
|
||||
|
||||
if smbios_data.smbios_dictionary[self.model]["CPU Generation"] >= cpu_data.cpu_data.skylake.value:
|
||||
# On 2016-2017 MacBook Pros, 15" devices used a stock Samsung SSD with IONVMeController
|
||||
# Technically this should be patched based on NVMeFix.kext logic,
|
||||
@@ -126,17 +121,41 @@ class generate_defaults:
|
||||
|
||||
|
||||
def networking_probe(self):
|
||||
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
|
||||
):
|
||||
# 12.0: Legacy Wireless chipsets require root patching
|
||||
self.constants.sip_status = False
|
||||
self.constants.secure_status = False
|
||||
if self.host_is_target:
|
||||
if not (
|
||||
(
|
||||
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
|
||||
)
|
||||
):
|
||||
return
|
||||
|
||||
else:
|
||||
if not self.model in smbios_data.smbios_dictionary:
|
||||
return
|
||||
if (
|
||||
smbios_data.smbios_dictionary[self.model]["Wireless Model"] not in [
|
||||
device_probe.Broadcom.Chipsets.AirPortBrcm4331,
|
||||
device_probe.Broadcom.Chipsets.AirPortBrcm43224,
|
||||
device_probe.Atheros.Chipsets.AirPortAtheros40
|
||||
]
|
||||
):
|
||||
return
|
||||
|
||||
# 12.0: Legacy Wireless chipsets require root patching
|
||||
self.constants.sip_status = False
|
||||
self.constants.secure_status = False
|
||||
|
||||
# 13.0: Enabling AirPlay to Mac patches breaks Control Center on legacy chipsets
|
||||
# AirPlay to Mac was unsupported regardless, so we can safely disable it
|
||||
self.constants.fu_status = True
|
||||
self.constants.fu_arguments = " -disable_sidecar_mac"
|
||||
|
||||
def misc_hardwares_probe(self):
|
||||
if self.host_is_target:
|
||||
@@ -233,14 +252,4 @@ class generate_defaults:
|
||||
self.constants.disable_cs_lv = True
|
||||
if os_data.os_data.ventura in self.constants.legacy_accel_support:
|
||||
# Only disable AMFI if we officially support Ventura
|
||||
self.constants.disable_amfi = True
|
||||
|
||||
if self.host_is_target:
|
||||
self.constants.host_is_non_metal = True
|
||||
# If a Mac is non-Metal based, Beta Blur is highly recommended
|
||||
if self.constants.detected_os >= os_data.os_data.big_sur:
|
||||
for arg in ["Moraea_BlurBeta"]:
|
||||
# If user explicitly set the blur, don't override
|
||||
arg_result = subprocess.run(["defaults", "read", "-g", arg], stdout=subprocess.PIPE).stdout.decode("utf-8").strip()
|
||||
if arg_result not in ["true", "1", "false", "0"]:
|
||||
subprocess.run(["defaults", "write", "-g", arg, "-bool", "TRUE"])
|
||||
self.constants.disable_amfi = True
|
||||
@@ -15,10 +15,14 @@ import threading
|
||||
from pathlib import Path
|
||||
import binascii
|
||||
import hashlib
|
||||
from datetime import datetime
|
||||
import py_sip_xnu
|
||||
|
||||
from resources import constants, defaults, build, install, installer, sys_patch_download, utilities, sys_patch_detect, sys_patch, run, generate_smbios, updates, integrity_verification, global_settings, kdk_handler
|
||||
from data import model_array, os_data, smbios_data, sip_data
|
||||
from gui import menu_redirect, gui_help
|
||||
from resources import constants, defaults, install, installer, utilities, run, generate_smbios, updates, integrity_verification, global_settings, kdk_handler
|
||||
from resources.sys_patch import sys_patch_download, sys_patch_detect, sys_patch, sys_patch_auto
|
||||
from resources.build import build
|
||||
from data import model_array, os_data, smbios_data, sip_data, cpu_data
|
||||
from resources.gui import menu_redirect, gui_help
|
||||
|
||||
|
||||
class wx_python_gui:
|
||||
@@ -53,7 +57,7 @@ class wx_python_gui:
|
||||
self.app = wx.App()
|
||||
if frame is None:
|
||||
self.frame = wx.Frame(
|
||||
None, title="OpenCore Legacy Patcher",
|
||||
None, title=f"OpenCore Legacy Patcher ({self.constants.patcher_version})",
|
||||
size=(self.WINDOW_WIDTH_MAIN, self.WINDOW_HEIGHT_MAIN),
|
||||
style = wx.DEFAULT_FRAME_STYLE & ~(wx.RESIZE_BORDER | wx.MAXIMIZE_BOX)
|
||||
)
|
||||
@@ -182,10 +186,108 @@ class wx_python_gui:
|
||||
# Spawn thread to check for updates
|
||||
threading.Thread(target=self.check_for_updates).start()
|
||||
|
||||
def check_for_local_installs(self, event=None):
|
||||
# Update app in '/Library/Application Support/Dortania' folder
|
||||
|
||||
# Skip if we're running from source
|
||||
if self.constants.launcher_script:
|
||||
return False
|
||||
|
||||
# Only performed if application is already installed (ie. we're updating)
|
||||
application_path = Path("/Library/Application Support/Dortania/OpenCore-Patcher.app")
|
||||
if not application_path.exists():
|
||||
return False
|
||||
|
||||
# Check application version
|
||||
# If we're older than the installed version, skip
|
||||
application_plist_path = application_path / "Contents/Info.plist"
|
||||
if not application_plist_path.exists():
|
||||
return False
|
||||
|
||||
application_plist = plistlib.load(application_plist_path.open("rb"))
|
||||
if not "CFBundleShortVersionString" in application_plist:
|
||||
return False
|
||||
|
||||
application_version = application_plist["CFBundleShortVersionString"].split(".")
|
||||
local_version = self.constants.patcher_version.split(".")
|
||||
|
||||
if application_version == local_version:
|
||||
if "Build Date" not in application_plist:
|
||||
return False
|
||||
|
||||
# Check build date of installed version
|
||||
plist_path = self.constants.launcher_binary.replace("MacOS/OpenCore-Patcher", "Info.plist")
|
||||
if not Path(plist_path).exists():
|
||||
return False
|
||||
|
||||
plist = plistlib.load(Path(plist_path).open("rb"))
|
||||
if "Build Date" not in plist:
|
||||
return False
|
||||
|
||||
if plist["Build Date"] == application_plist["Build Date"]:
|
||||
return False
|
||||
|
||||
local_build_date = datetime.strptime(plist["Build Date"], "%Y-%m-%d %H:%M:%S")
|
||||
installed_build_date = datetime.strptime(application_plist["Build Date"], "%Y-%m-%d %H:%M:%S")
|
||||
|
||||
if local_build_date <= installed_build_date:
|
||||
return False
|
||||
|
||||
elif updates.check_binary_updates(self.constants).check_if_build_newer(local_version, application_version) is False:
|
||||
return False
|
||||
|
||||
# Ask user if they want to move the application to the Applications folder
|
||||
self.popup = wx.MessageDialog(
|
||||
self.frame,
|
||||
f"We've detected an old version of OpenCore-Patcher.app installed in the Application Support directory.\n\nWould you like to replace it with this version?",
|
||||
"Move to Applications?",
|
||||
wx.YES_NO | wx.ICON_INFORMATION
|
||||
)
|
||||
self.popup.SetYesNoLabels("Replace", "Ignore")
|
||||
answer = self.popup.ShowModal()
|
||||
if answer != wx.ID_YES:
|
||||
return False
|
||||
|
||||
path = str(self.constants.launcher_binary).split("/Contents/MacOS/OpenCore-Patcher")[0]
|
||||
|
||||
args = [
|
||||
"osascript",
|
||||
"-e",
|
||||
f'''do shell script "ditto {path} '/Library/Application Support/Dortania/OpenCore-Patcher.app'"'''
|
||||
' with prompt "OpenCore Legacy Patcher needs administrator privileges to copy in."'
|
||||
" with administrator privileges"
|
||||
" without altering line endings",
|
||||
]
|
||||
|
||||
result = subprocess.run(args,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
if result.returncode != 0:
|
||||
print("- Failed to move application into /Library/Application Support/Dortania/OpenCore-Patcher.app")
|
||||
# Notify user we failed to move the application
|
||||
self.popup = wx.MessageDialog(
|
||||
self.frame,
|
||||
f"Failed to move the application to the Applications folder.\n\nThis is likely due to permission errors, you can copy the app manually into '/Library/Application Support/Dortania/OpenCore-Patcher.app' if you continue to see this error.",
|
||||
"Failed to Move!",
|
||||
style = wx.OK | wx.ICON_EXCLAMATION
|
||||
)
|
||||
self.popup.ShowModal()
|
||||
return False
|
||||
|
||||
subprocess.run(["xattr", "-cr", "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
subprocess.run(["open", "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
if "AppTranslocation" not in path:
|
||||
subprocess.run(["rm", "-R", path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
|
||||
self.OnCloseFrame()
|
||||
|
||||
def check_for_updates(self, event=None):
|
||||
if self.constants.has_checked_updates is True:
|
||||
return
|
||||
|
||||
did_find_update = False
|
||||
ignore_updates = global_settings.global_settings().read_property("IgnoreAppUpdates")
|
||||
if ignore_updates is not True:
|
||||
self.constants.ignore_updates = False
|
||||
self.constants.has_checked_updates = True
|
||||
dict = updates.check_binary_updates(self.constants).check_binary_updates()
|
||||
if dict:
|
||||
for entry in dict:
|
||||
@@ -200,6 +302,7 @@ class wx_python_gui:
|
||||
)
|
||||
self.dialog.SetYesNoCancelLabels("View on Github", "Always Ignore", "Ignore Once")
|
||||
response = self.dialog.ShowModal()
|
||||
did_find_update = True
|
||||
if response == wx.ID_YES:
|
||||
webbrowser.open(github_link)
|
||||
elif response == wx.ID_NO:
|
||||
@@ -210,6 +313,9 @@ class wx_python_gui:
|
||||
self.constants.ignore_updates = True
|
||||
print("- Ignoring App Updates due to defaults")
|
||||
|
||||
# if did_find_update is False:
|
||||
# self.check_for_local_installs()
|
||||
|
||||
def relaunch_as_root(self, event=None):
|
||||
|
||||
# Add Dialog Box asking if it's ok to relaunch as root
|
||||
@@ -343,7 +449,7 @@ class wx_python_gui:
|
||||
self.reset_window()
|
||||
|
||||
# Set header text
|
||||
self.frame.SetTitle(f"OpenCore Legacy Patcher")
|
||||
self.frame.SetTitle(f"OpenCore Legacy Patcher ({self.constants.patcher_version})")
|
||||
# Header
|
||||
self.header = wx.StaticText(self.frame, label=f"OpenCore Legacy Patcher v{self.constants.patcher_version}")
|
||||
self.header.SetFont(wx.Font(18, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD))
|
||||
@@ -623,7 +729,7 @@ class wx_python_gui:
|
||||
while self.is_unpack_finished() is False:
|
||||
time.sleep(0.1)
|
||||
|
||||
build.BuildOpenCore(self.constants.custom_model or self.constants.computer.real_model, self.constants).build_opencore()
|
||||
build.build_opencore(self.constants.custom_model or self.constants.computer.real_model, self.constants).build_opencore()
|
||||
# Once finished, change build_opencore button to "Install OpenCore"
|
||||
self.build_opencore.SetLabel("🔩 Install OpenCore")
|
||||
self.build_opencore.Bind(wx.EVT_BUTTON, self.install_menu)
|
||||
@@ -1585,20 +1691,33 @@ class wx_python_gui:
|
||||
def download_macos_click(self, app_dict):
|
||||
# Unsupported Models include:
|
||||
# - USB 1.1 machines (Penryn, MacPro3,1-5,1)
|
||||
# - VBIOS Boot Issue (MacPro6,1)
|
||||
# - Non-Metal GPUs
|
||||
has_legacy_usb = False
|
||||
issues_list = ""
|
||||
model = self.constants.custom_model or self.constants.computer.real_model
|
||||
if model in model_array.LegacyGPU or model in ["MacPro3,1", "MacPro4,1", "MacPro5,1"]:
|
||||
if model in ["MacPro3,1", "MacPro4,1", "MacPro5,1"]:
|
||||
has_legacy_usb = True
|
||||
issues_list = "- Lack of Keyboard/Mouse in macOS installer without a USB hub\n"
|
||||
elif model in smbios_data.smbios_dictionary[model]:
|
||||
if "CPU Generation" in smbios_data.smbios_dictionary[model]:
|
||||
if smbios_data.smbios_dictionary[model]["CPU Generation"] <= cpu_data.cpu_data.penryn:
|
||||
has_legacy_usb = True
|
||||
if model.startswith("MacBook"):
|
||||
issues_list = "- Lack of internal Keyboard/Trackpad in macOS installer\n"
|
||||
elif not model.startswith("MacPro"):
|
||||
issues_list = "- Lack of internal Keyboard/Mouse in macOS installer\n"
|
||||
|
||||
if has_legacy_usb:
|
||||
try:
|
||||
app_major = app_dict['Version'].split(".")[0]
|
||||
if float(app_major) > self.constants.os_support:
|
||||
# Throw pop up warning OCLP does not support this OS
|
||||
os = os_data.os_conversion.convert_kernel_to_marketing_name(os_data.os_conversion.os_to_kernel(app_major))
|
||||
dlg = wx.MessageDialog(self.frame_modal, f"OpenCore Legacy Patcher currently does not support macOS {os} on your machine ({model}).\n\nThe newest version we officially support is macOS {os_data.os_conversion.convert_kernel_to_marketing_name(os_data.os_conversion.os_to_kernel(str(self.constants.os_support)))}. For more information, see the associated Ventura Github Issue.\n\nWould you still want to continue downloading macOS {os}?", "Unsupported OS", style=wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION)
|
||||
dlg = wx.MessageDialog(self.frame_modal, f"OpenCore Legacy Patcher may not fully support macOS {os} on your machine ({model}).\n\nThe main issues include:\n{issues_list}\nThe newest version we recommend is macOS {os_data.os_conversion.convert_kernel_to_marketing_name(os_data.os_conversion.os_to_kernel(str(self.constants.os_support)))}. For more information, see the associated Github Issue.\n\nWould you still want to continue downloading macOS {os}?", "Unsupported OS", style=wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION)
|
||||
dlg.SetYesNoCancelLabels("View Github Issue", "Download Anyways", "Cancel")
|
||||
result = dlg.ShowModal()
|
||||
if result == wx.ID_YES:
|
||||
webbrowser.open("https://github.com/dortania/OpenCore-Legacy-Patcher/issues/998")
|
||||
webbrowser.open("https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1021")
|
||||
return
|
||||
elif result == wx.ID_NO:
|
||||
pass
|
||||
@@ -2356,7 +2475,7 @@ class wx_python_gui:
|
||||
chassis_type = "aluminum"
|
||||
if self.constants.computer.real_model in ["MacBook4,1", "MacBook5,2", "MacBook6,1", "MacBook7,1"]:
|
||||
chassis_type = "plastic"
|
||||
dlg = wx.MessageDialog(self.frame_modal, f"This model, {self.constants.computer.real_model}, does not natively support macOS {os_data.os_conversion.kernel_to_os(self.constants.detected_os)}, {os_data.os_conversion.convert_kernel_to_marketing_name(self.constants.detected_os)}. The last native OS was macOS {os_data.os_conversion.kernel_to_os(smbios_data.smbios_dictionary[self.constants.computer.real_model]['Max OS Supported'])}, {os_data.os_conversion.convert_kernel_to_marketing_name(smbios_data.smbios_dictionary[self.constants.computer.real_model]['Max OS Supported'])}\n\nToggling this option will breaking booting on this OS. Are you absolutely certain this is desired?\n\nYou may end up with a nice {chassis_type} brick 🧱", "Are you certain?", wx.YES_NO | wx.ICON_WARNING)
|
||||
dlg = wx.MessageDialog(self.frame_modal, f"This model, {self.constants.computer.real_model}, does not natively support macOS {os_data.os_conversion.kernel_to_os(self.constants.detected_os)}, {os_data.os_conversion.convert_kernel_to_marketing_name(self.constants.detected_os)}. The last native OS was macOS {os_data.os_conversion.kernel_to_os(smbios_data.smbios_dictionary[self.constants.computer.real_model]['Max OS Supported'])}, {os_data.os_conversion.convert_kernel_to_marketing_name(smbios_data.smbios_dictionary[self.constants.computer.real_model]['Max OS Supported'])}\n\nToggling this option will break booting on this OS. Are you absolutely certain this is desired?\n\nYou may end up with a nice {chassis_type} brick 🧱", "Are you certain?", wx.YES_NO | wx.ICON_WARNING)
|
||||
if dlg.ShowModal() == wx.ID_NO:
|
||||
self.checkbox_allow_native_models.SetValue(False)
|
||||
return
|
||||
@@ -2475,13 +2594,34 @@ class wx_python_gui:
|
||||
self.timeout_spinner.Bind(wx.EVT_SPINCTRL, self.timeout_spinner_click)
|
||||
self.timeout_spinner.Centre(wx.HORIZONTAL)
|
||||
|
||||
# AMD GOP Injection
|
||||
self.set_amd_gop_injection = wx.CheckBox(self.frame_modal, label="AMD GOP Injection")
|
||||
self.set_amd_gop_injection.SetPosition(wx.Point(
|
||||
30,
|
||||
self.timeout_spinner.GetPosition().y + self.timeout_spinner.GetSize().height + 5))
|
||||
self.set_amd_gop_injection.SetValue(self.constants.amd_gop_injection)
|
||||
self.set_amd_gop_injection.Bind(wx.EVT_CHECKBOX, self.amd_gop_injection_checkbox_click)
|
||||
models = ["iMac10,1", "iMac11,1", "iMac11,2", "iMac11,3", "iMac12,1", "iMac12,2", "MacPro3,1", "MacPro4,1", "MacPro5,1", "Xserve2,1", "Xserve3,1"]
|
||||
if (not self.constants.custom_model and self.computer.real_model not in models) or (self.constants.custom_model and self.constants.custom_model not in models):
|
||||
self.set_amd_gop_injection.Disable()
|
||||
|
||||
# Nvidia Kepler GOP injection
|
||||
self.set_nvidia_kepler_gop_injection = wx.CheckBox(self.frame_modal, label="Nvidia Kepler GOP Injection")
|
||||
self.set_nvidia_kepler_gop_injection.SetPosition(wx.Point(
|
||||
self.set_amd_gop_injection.GetPosition().x,
|
||||
self.set_amd_gop_injection.GetPosition().y + self.set_amd_gop_injection.GetSize().height))
|
||||
self.set_nvidia_kepler_gop_injection.SetValue(self.constants.nvidia_kepler_gop_injection)
|
||||
self.set_nvidia_kepler_gop_injection.Bind(wx.EVT_CHECKBOX, self.nvidia_kepler_gop_injection_checkbox_click)
|
||||
if (not self.constants.custom_model and self.computer.real_model not in models) or (self.constants.custom_model and self.constants.custom_model not in models):
|
||||
self.set_nvidia_kepler_gop_injection.Disable()
|
||||
|
||||
# Disable Thunderbolt
|
||||
self.disable_thunderbolt_checkbox = wx.CheckBox(self.frame_modal, label="Disable Thunderbolt")
|
||||
self.disable_thunderbolt_checkbox.SetValue(self.constants.disable_tb)
|
||||
self.disable_thunderbolt_checkbox.Bind(wx.EVT_CHECKBOX, self.disable_tb_click)
|
||||
self.disable_thunderbolt_checkbox.SetPosition(wx.Point(
|
||||
30,
|
||||
self.timeout_spinner.GetPosition().y + self.timeout_spinner.GetSize().height + 5))
|
||||
self.set_nvidia_kepler_gop_injection.GetPosition().x,
|
||||
self.set_nvidia_kepler_gop_injection.GetPosition().y + self.set_nvidia_kepler_gop_injection.GetSize().height))
|
||||
self.disable_thunderbolt_checkbox.SetToolTip(wx.ToolTip("Disables Thunderbolt support on MacBookPro11,x\nMainly applicable for systems that cannot boot with Thunderbolt enabled"))
|
||||
if not self.constants.custom_model and not self.computer.real_model.startswith("MacBookPro11"):
|
||||
self.disable_thunderbolt_checkbox.Disable()
|
||||
@@ -2497,23 +2637,13 @@ class wx_python_gui:
|
||||
self.set_terascale_accel_checkbox.Disable()
|
||||
self.set_terascale_accel_checkbox.SetValue(False)
|
||||
|
||||
# Force Web Drivers in Tesla/Kepler
|
||||
self.force_web_drivers_checkbox = wx.CheckBox(self.frame_modal, label="Force Web Drivers")
|
||||
self.force_web_drivers_checkbox.SetValue(self.constants.force_nv_web)
|
||||
self.force_web_drivers_checkbox.Bind(wx.EVT_CHECKBOX, self.force_web_drivers_click)
|
||||
self.force_web_drivers_checkbox.SetPosition(wx.Point(
|
||||
self.disable_thunderbolt_checkbox.GetPosition().x,
|
||||
self.set_terascale_accel_checkbox.GetPosition().y + self.set_terascale_accel_checkbox.GetSize().height))
|
||||
self.force_web_drivers_checkbox.SetToolTip(wx.ToolTip("This option will force Nvidia Web Driver support onto Nvidia Tesla and Kepler GPUs. This should only be used for development purposes."))
|
||||
|
||||
|
||||
# Windows GMUX
|
||||
self.windows_gmux_checkbox = wx.CheckBox(self.frame_modal, label="Windows GMUX")
|
||||
self.windows_gmux_checkbox.SetValue(self.constants.dGPU_switch)
|
||||
self.windows_gmux_checkbox.Bind(wx.EVT_CHECKBOX, self.windows_gmux_click)
|
||||
self.windows_gmux_checkbox.SetPosition(wx.Point(
|
||||
self.force_web_drivers_checkbox.GetPosition().x,
|
||||
self.force_web_drivers_checkbox.GetPosition().y + self.force_web_drivers_checkbox.GetSize().height))
|
||||
self.set_terascale_accel_checkbox.GetPosition().x,
|
||||
self.set_terascale_accel_checkbox.GetPosition().y + self.set_terascale_accel_checkbox.GetSize().height))
|
||||
self.windows_gmux_checkbox.SetToolTip(wx.ToolTip("Enable this option to allow usage of the hardware GMUX to switch between Intel and Nvidia/AMD GPUs in Windows."))
|
||||
|
||||
# Hibernation Workaround
|
||||
@@ -2732,6 +2862,14 @@ class wx_python_gui:
|
||||
print("Wake on WLAN Disabled")
|
||||
self.constants.enable_wake_on_wlan = False
|
||||
|
||||
def apfs_trim_click(self, event=None):
|
||||
if self.apfs_trim_checkbox.GetValue():
|
||||
print("APFS Trim Enabled")
|
||||
self.constants.apfs_trim_timeout = True
|
||||
else:
|
||||
print("APFS Trim Disabled")
|
||||
self.constants.apfs_trim_timeout = False
|
||||
|
||||
def content_caching_click(self, event=None):
|
||||
if self.content_caching_checkbox.GetValue():
|
||||
print("Content Caching Enabled")
|
||||
@@ -2740,6 +2878,22 @@ class wx_python_gui:
|
||||
print("Content Caching Disabled")
|
||||
self.constants.set_content_caching = False
|
||||
|
||||
def amd_gop_injection_checkbox_click(self, event=None):
|
||||
if self.set_amd_gop_injection.GetValue():
|
||||
print("AMD GOP Injection Enabled")
|
||||
self.constants.amd_gop_injection = True
|
||||
else:
|
||||
print("AMD GOP Injection Disabled")
|
||||
self.constants.amd_gop_injection = False
|
||||
|
||||
def nvidia_kepler_gop_injection_checkbox_click(self, event=None):
|
||||
if self.set_nvidia_kepler_gop_injection.GetValue():
|
||||
print("Nvidia Kepler GOP Injection Enabled")
|
||||
self.constants.nvidia_kepler_gop_injection = True
|
||||
else:
|
||||
print("Nvidia Kepler GOP Injection Disabled")
|
||||
self.constants.nvidia_kepler_gop_injection = False
|
||||
|
||||
def disable_tb_click(self, event=None):
|
||||
if self.disable_thunderbolt_checkbox.GetValue():
|
||||
print("Disable Thunderbolt Enabled")
|
||||
@@ -3231,7 +3385,7 @@ class wx_python_gui:
|
||||
)
|
||||
self.sip_label_2.Center(wx.HORIZONTAL)
|
||||
|
||||
self.sip_label_2_2 = wx.StaticText(self.frame_modal, label=f"Currently Booted SIP: {hex(utilities.csr_dump())}")
|
||||
self.sip_label_2_2 = wx.StaticText(self.frame_modal, label=f"Currently Booted SIP: {hex(py_sip_xnu.SipXnu().get_sip_status().value)}")
|
||||
self.sip_label_2_2.SetFont(wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
|
||||
self.sip_label_2_2.SetPosition(
|
||||
wx.Point(self.sip_label_2.GetPosition().x, self.sip_label_2.GetPosition().y + self.sip_label_2.GetSize().height + 5)
|
||||
@@ -3404,12 +3558,19 @@ OpenCore Legacy Patcher by default knows the most ideal
|
||||
self.content_caching_checkbox.SetPosition(wx.Point(self.wake_on_wlan_checkbox.GetPosition().x, self.wake_on_wlan_checkbox.GetPosition().y + self.wake_on_wlan_checkbox.GetSize().height))
|
||||
self.content_caching_checkbox.SetToolTip(wx.ToolTip("Enables content caching support in macOS"))
|
||||
|
||||
# APFS Trim
|
||||
self.apfs_trim_checkbox = wx.CheckBox(self.frame_modal, label="APFS Trim")
|
||||
self.apfs_trim_checkbox.SetValue(self.constants.apfs_trim_timeout)
|
||||
self.apfs_trim_checkbox.Bind(wx.EVT_CHECKBOX, self.apfs_trim_click)
|
||||
self.apfs_trim_checkbox.SetPosition(wx.Point(self.content_caching_checkbox.GetPosition().x, self.content_caching_checkbox.GetPosition().y + self.content_caching_checkbox.GetSize().height))
|
||||
self.apfs_trim_checkbox.SetToolTip(wx.ToolTip("Enables APFS Trim support in macOS"))
|
||||
|
||||
# Button: return to main menu
|
||||
self.return_to_main_menu_button = wx.Button(self.frame_modal, label="Return to Settings")
|
||||
self.return_to_main_menu_button.Bind(wx.EVT_BUTTON, self.settings_menu)
|
||||
self.return_to_main_menu_button.SetPosition(wx.Point(
|
||||
self.content_caching_checkbox.GetPosition().x,
|
||||
self.content_caching_checkbox.GetPosition().y + self.content_caching_checkbox.GetSize().height + 10))
|
||||
self.apfs_trim_checkbox.GetPosition().x,
|
||||
self.apfs_trim_checkbox.GetPosition().y + self.apfs_trim_checkbox.GetSize().height + 10))
|
||||
self.return_to_main_menu_button.Center(wx.HORIZONTAL)
|
||||
|
||||
# set frame_modal size below return to main menu button
|
||||
@@ -3476,11 +3637,11 @@ OpenCore Legacy Patcher by default knows the most ideal
|
||||
else:
|
||||
is_blur_enabled = False
|
||||
|
||||
is_rim_enabled = subprocess.run(["defaults", "read", "-g", "Moraea_RimBeta"], stdout=subprocess.PIPE).stdout.decode("utf-8").strip()
|
||||
if is_rim_enabled in ["1", "true"]:
|
||||
is_rim_enabled = True
|
||||
is_rim_disabled = subprocess.run(["defaults", "read", "-g", "Moraea_RimBetaDisabled"], stdout=subprocess.PIPE).stdout.decode("utf-8").strip()
|
||||
if is_rim_disabled in ["1", "true"]:
|
||||
is_rim_disabled = True
|
||||
else:
|
||||
is_rim_enabled = False
|
||||
is_rim_disabled = False
|
||||
|
||||
# Checkbox: Dark Menu Bar
|
||||
self.dark_menu_bar_checkbox = wx.CheckBox(self.frame_modal, label="Dark Menu Bar")
|
||||
@@ -3496,8 +3657,8 @@ OpenCore Legacy Patcher by default knows the most ideal
|
||||
self.enable_beta_blur_checkbox.SetPosition(wx.Point(self.dark_menu_bar_checkbox.GetPosition().x, self.dark_menu_bar_checkbox.GetPosition().y + self.dark_menu_bar_checkbox.GetSize().height + 7))
|
||||
|
||||
# Checkbox: Enable Beta Rim
|
||||
self.enable_beta_rim_checkbox = wx.CheckBox(self.frame_modal, label="Enable Beta Rim")
|
||||
self.enable_beta_rim_checkbox.SetValue(is_rim_enabled)
|
||||
self.enable_beta_rim_checkbox = wx.CheckBox(self.frame_modal, label="Disable Beta Rim")
|
||||
self.enable_beta_rim_checkbox.SetValue(is_rim_disabled)
|
||||
self.enable_beta_rim_checkbox.Bind(wx.EVT_CHECKBOX, self.enable_beta_rim_click)
|
||||
self.enable_beta_rim_checkbox.SetPosition(wx.Point(self.enable_beta_blur_checkbox.GetPosition().x, self.enable_beta_blur_checkbox.GetPosition().y + self.enable_beta_blur_checkbox.GetSize().height + 7))
|
||||
|
||||
@@ -3526,7 +3687,7 @@ OpenCore Legacy Patcher by default knows the most ideal
|
||||
|
||||
def enable_beta_rim_click(self, event=None):
|
||||
if event.IsChecked():
|
||||
subprocess.run(["defaults", "write", "-g", "Moraea_RimBeta", "-bool", "true"])
|
||||
subprocess.run(["defaults", "write", "-g", "Moraea_RimBetaDisabled", "-bool", "true"])
|
||||
else:
|
||||
subprocess.run(["defaults", "write", "-g", "Moraea_RimBeta", "-bool", "false"])
|
||||
subprocess.run(["defaults", "write", "-g", "Moraea_RimBetaDisabled", "-bool", "false"])
|
||||
print("Beta Rim Enabled:", event.IsChecked())
|
||||
@@ -25,7 +25,7 @@ class kernel_debug_kit_handler:
|
||||
print("- Fetching available KDKs")
|
||||
|
||||
try:
|
||||
results = utilities.SESSION.get(KDK_API_LINK, headers={"User-Agent": f"OCLP/{self.constants.patcher_version}"})
|
||||
results = utilities.SESSION.get(KDK_API_LINK, headers={"User-Agent": f"OCLP/{self.constants.patcher_version}"}, timeout=10)
|
||||
except (requests.exceptions.Timeout, requests.exceptions.TooManyRedirects, requests.exceptions.ConnectionError):
|
||||
print("- Could not contact KDK API")
|
||||
return None
|
||||
@@ -62,7 +62,7 @@ class kernel_debug_kit_handler:
|
||||
macos_builds = [i for i in results.json()["ios"] if i["osType"] == "macOS"]
|
||||
# If the version is borked, put it at the bottom of the list
|
||||
# Would omit it, but can't do that in this lambda
|
||||
macos_builds.sort(key=lambda x: (packaging.version.parse(VERSION_PATTERN.match(x["version"]).group() if VERSION_PATTERN.match(x["version"]) else "0.0.0"), datetime.datetime.fromisoformat(x["released"])), reverse=True) # type: ignore
|
||||
macos_builds.sort(key=lambda x: (packaging.version.parse(VERSION_PATTERN.match(x["version"]).group() if VERSION_PATTERN.match(x["version"]) else "0.0.0"), datetime.datetime.fromisoformat(x["released"] if x["released"] != "" else "1984-01-01")), reverse=True) # type: ignore
|
||||
|
||||
# Iterate through, find build that is closest to the host version
|
||||
# Use date to determine which is closest
|
||||
@@ -96,6 +96,11 @@ class kernel_debug_kit_handler:
|
||||
# 0: Portal is up and file is available
|
||||
# 1: Portal is up but file is not available
|
||||
# 2: Portal is down
|
||||
# 3: Network error
|
||||
|
||||
if utilities.verify_network_connection("https://developerservices2.apple.com/services/download") is False:
|
||||
print("- Could not connect to the network")
|
||||
return 3
|
||||
|
||||
TOKEN_URL_BASE = "https://developerservices2.apple.com/services/download"
|
||||
remote_path = urllib.parse.urlparse(link).path
|
||||
@@ -180,18 +185,33 @@ class kernel_debug_kit_handler:
|
||||
return False, msg, ""
|
||||
elif result == 2:
|
||||
msg = "Could not contact Apple download servers"
|
||||
print(f"- {msg}")
|
||||
return False, msg, ""
|
||||
download_link = self.kdk_backup_site(closest_build)
|
||||
if download_link is None:
|
||||
msg += " and could not find a backup copy online"
|
||||
print(f"- {msg}")
|
||||
return False, msg, ""
|
||||
else:
|
||||
msg = "Unknown error"
|
||||
print(f"- {msg}")
|
||||
return False, msg, ""
|
||||
elif result == 2:
|
||||
msg = "Could not contact Apple download servers"
|
||||
download_link = self.kdk_backup_site(build)
|
||||
if download_link is None:
|
||||
msg += " and could not find a backup copy online"
|
||||
print(f"- {msg}")
|
||||
return False, msg, ""
|
||||
elif result == 3:
|
||||
msg = "Failed to connect to the internet"
|
||||
print(f"- {msg}")
|
||||
return False, msg, ""
|
||||
|
||||
if utilities.download_apple_developer_portal(download_link, self.constants.kdk_download_path):
|
||||
if "github" in download_link:
|
||||
result = utilities.download_file(download_link, self.constants.kdk_download_path)
|
||||
else:
|
||||
result = utilities.download_apple_developer_portal(download_link, self.constants.kdk_download_path)
|
||||
|
||||
if result:
|
||||
result = subprocess.run(["hdiutil", "verify", self.constants.kdk_download_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
if result.returncode != 0:
|
||||
print(f"Error: Kernel Debug Kit checksum verification failed!")
|
||||
@@ -247,4 +267,26 @@ class kernel_debug_kit_handler:
|
||||
if should_remove is False:
|
||||
continue
|
||||
print(f" - Removing {kdk_folder.name}")
|
||||
utilities.elevated(["rm", "-rf", kdk_folder], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
utilities.elevated(["rm", "-rf", kdk_folder], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
|
||||
|
||||
def kdk_backup_site(self, build):
|
||||
KDK_MIRROR_REPOSITORY = "https://api.github.com/repos/dortania/KdkSupportPkg/releases"
|
||||
|
||||
# Check if tag exists
|
||||
catalog = requests.get(KDK_MIRROR_REPOSITORY)
|
||||
if catalog.status_code != 200:
|
||||
print(f"- Could not contact KDK mirror repository")
|
||||
return None
|
||||
|
||||
catalog = catalog.json()
|
||||
|
||||
for release in catalog:
|
||||
if release["tag_name"] == build:
|
||||
print(f"- Found KDK mirror for build: {build}")
|
||||
for asset in release["assets"]:
|
||||
if asset["name"].endswith(".dmg"):
|
||||
return asset["browser_download_url"]
|
||||
|
||||
print(f"- Could not find KDK mirror for build {build}")
|
||||
return None
|
||||
@@ -6,7 +6,8 @@ from pathlib import Path
|
||||
import time
|
||||
import threading
|
||||
|
||||
from resources import build, cli_menu, constants, utilities, device_probe, os_probe, defaults, arguments, install, tui_helpers, reroute_payloads, commit_info
|
||||
from resources import cli_menu, constants, utilities, device_probe, os_probe, defaults, arguments, install, tui_helpers, reroute_payloads, commit_info
|
||||
from resources.build import build
|
||||
from data import model_array
|
||||
|
||||
class OpenCoreLegacyPatcher:
|
||||
@@ -18,7 +19,7 @@ class OpenCoreLegacyPatcher:
|
||||
if utilities.check_cli_args() is None:
|
||||
if launch_gui is True:
|
||||
utilities.disable_cls()
|
||||
from gui import gui_main
|
||||
from resources.gui import gui_main
|
||||
gui_main.wx_python_gui(self.constants).main_menu(None)
|
||||
else:
|
||||
self.main_menu()
|
||||
@@ -105,7 +106,7 @@ class OpenCoreLegacyPatcher:
|
||||
menu = tui_helpers.TUIMenu(title, "Please select an option: ", in_between=in_between, auto_number=True, top_level=True)
|
||||
|
||||
options = (
|
||||
[["Build OpenCore", build.BuildOpenCore(self.constants.custom_model or self.constants.computer.real_model, self.constants).build_opencore]]
|
||||
[["Build OpenCore", build.build_opencore(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 []
|
||||
) + [
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import platform
|
||||
import subprocess
|
||||
import plistlib
|
||||
|
||||
|
||||
def detect_kernel_major():
|
||||
@@ -25,4 +26,10 @@ def detect_os_version():
|
||||
def detect_os_build():
|
||||
# Return OS build
|
||||
# Example Output: 21A5522h (string)
|
||||
return subprocess.run("sw_vers -buildVersion".split(), stdout=subprocess.PIPE).stdout.decode().strip()
|
||||
|
||||
# With macOS 13.2, Apple implemented the Rapid Security Response system which
|
||||
# will change the reported build to the RSR version and not the original host
|
||||
# To get the proper versions:
|
||||
# - Host: /System/Library/CoreServices/SystemVersion.plist
|
||||
# - RSR: /System/Volumes/Preboot/Cryptexes/OS/System/Library/CoreServices/SystemVersion.plist
|
||||
return plistlib.load(open("/System/Library/CoreServices/SystemVersion.plist", "rb"))["ProductBuildVersion"]
|
||||
|
||||
@@ -38,7 +38,9 @@ import subprocess
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
from resources import constants, utilities, sys_patch_download, sys_patch_detect, sys_patch_auto, sys_patch_helpers, kdk_handler
|
||||
from resources import constants, utilities, kdk_handler
|
||||
from resources.sys_patch import sys_patch_download, sys_patch_detect, sys_patch_auto, sys_patch_helpers
|
||||
|
||||
from data import os_data
|
||||
|
||||
|
||||
@@ -109,7 +111,7 @@ class PatchSysVolume:
|
||||
print(result.stdout.decode().strip())
|
||||
return False
|
||||
|
||||
def merge_kdk_with_root(self):
|
||||
def merge_kdk_with_root(self, save_hid_cs=False):
|
||||
if self.skip_root_kmutil_requirement is True:
|
||||
return
|
||||
if self.constants.detected_os < os_data.os_data.ventura:
|
||||
@@ -143,6 +145,14 @@ class PatchSysVolume:
|
||||
raise Exception("Unable to find Kernel Debug Kit")
|
||||
self.kdk_path = kdk_path
|
||||
print(f"- Found KDK at: {kdk_path}")
|
||||
|
||||
# Due to some IOHIDFamily oddities, we need to ensure their CodeSignature is retained
|
||||
cs_path = Path(self.mount_location) / Path("System/Library/Extensions/IOHIDFamily.kext/Contents/PlugIns/IOHIDEventDriver.kext/Contents/_CodeSignature")
|
||||
if save_hid_cs is True and cs_path.exists():
|
||||
print("- Backing up IOHIDEventDriver CodeSignature")
|
||||
# Note it's a folder, not a file
|
||||
utilities.elevated(["cp", "-r", cs_path, f"{self.constants.payload_path}/IOHIDEventDriver_CodeSignature.bak"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
|
||||
print("- Merging KDK with Root Volume")
|
||||
utilities.elevated(
|
||||
# Only merge '/System/Library/Extensions'
|
||||
@@ -157,6 +167,16 @@ class PatchSysVolume:
|
||||
raise Exception("Failed to merge KDK with Root Volume")
|
||||
print("- Successfully merged KDK with Root Volume")
|
||||
|
||||
# Restore IOHIDEventDriver CodeSignature
|
||||
if save_hid_cs is True and Path(f"{self.constants.payload_path}/IOHIDEventDriver_CodeSignature.bak").exists():
|
||||
print("- Restoring IOHIDEventDriver CodeSignature")
|
||||
if not cs_path.exists():
|
||||
print(" - CodeSignature folder missing, creating")
|
||||
utilities.elevated(["mkdir", "-p", cs_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
utilities.elevated(["cp", "-r", f"{self.constants.payload_path}/IOHIDEventDriver_CodeSignature.bak", cs_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
utilities.elevated(["rm", "-rf", f"{self.constants.payload_path}/IOHIDEventDriver_CodeSignature.bak"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
|
||||
|
||||
def unpatch_root_vol(self):
|
||||
if self.constants.detected_os > os_data.os_data.catalina and self.root_supports_snapshot is True:
|
||||
print("- Reverting to last signed APFS snapshot")
|
||||
@@ -275,6 +295,9 @@ class PatchSysVolume:
|
||||
|
||||
for file in ["KextPolicy", "KextPolicy-shm", "KextPolicy-wal"]:
|
||||
self.remove_file("/private/var/db/SystemPolicyConfiguration/", file)
|
||||
else:
|
||||
# Install RSRHelper utility to handle desynced KCs
|
||||
sys_patch_helpers.sys_patch_helpers(self.constants).install_rsr_repair_binary()
|
||||
|
||||
print("- Successfully built new kernel cache")
|
||||
return True
|
||||
@@ -337,23 +360,20 @@ class PatchSysVolume:
|
||||
if self.constants.detected_os < os_data.os_data.big_sur:
|
||||
return
|
||||
|
||||
oclp_path = "/System/Library/CoreServices/OpenCore-Legacy-Patcher.plist"
|
||||
if not Path(oclp_path).exists():
|
||||
return
|
||||
|
||||
print("- Cleaning Auxiliary Kernel Collection")
|
||||
oclp_plist_data = plistlib.load(Path(oclp_path).open("rb"))
|
||||
|
||||
for key in oclp_plist_data:
|
||||
if "Install" not in oclp_plist_data[key]:
|
||||
continue
|
||||
for location in oclp_plist_data[key]["Install"]:
|
||||
if not location.endswith("Extensions"):
|
||||
oclp_path = "/System/Library/CoreServices/OpenCore-Legacy-Patcher.plist"
|
||||
if Path(oclp_path).exists():
|
||||
oclp_plist_data = plistlib.load(Path(oclp_path).open("rb"))
|
||||
for key in oclp_plist_data:
|
||||
if "Install" not in oclp_plist_data[key]:
|
||||
continue
|
||||
for file in oclp_plist_data[key]["Install"][location]:
|
||||
if not file.endswith(".kext"):
|
||||
for location in oclp_plist_data[key]["Install"]:
|
||||
if not location.endswith("Extensions"):
|
||||
continue
|
||||
self.remove_file("/Library/Extensions", file)
|
||||
for file in oclp_plist_data[key]["Install"][location]:
|
||||
if not file.endswith(".kext"):
|
||||
continue
|
||||
self.remove_file("/Library/Extensions", file)
|
||||
|
||||
# Handle situations where users migrated from older OSes with a lot of garbage in /L*/E*
|
||||
# ex. Nvidia Web Drivers, NetUSB, dosdude1's patches, etc.
|
||||
@@ -366,9 +386,16 @@ class PatchSysVolume:
|
||||
utilities.elevated(["mkdir", relocation_path])
|
||||
|
||||
for file in Path("/Library/Extensions").glob("*.kext"):
|
||||
if datetime.fromtimestamp(file.stat().st_mtime) < datetime(2021, 10, 1):
|
||||
print(f" - Relocating {file.name} kext to {relocation_path}")
|
||||
utilities.elevated(["mv", file, relocation_path])
|
||||
try:
|
||||
if datetime.fromtimestamp(file.stat().st_mtime) < datetime(2021, 10, 1):
|
||||
print(f" - Relocating {file.name} kext to {relocation_path}")
|
||||
if Path(relocation_path) / Path(file.name).exists():
|
||||
utilities.elevated(["rm", "-Rf", relocation_path / Path(file.name)])
|
||||
utilities.elevated(["mv", file, relocation_path])
|
||||
except:
|
||||
# Some users have the most cursed /L*/E* folders
|
||||
# ex. Symlinks pointing to symlinks pointing to dead files
|
||||
pass
|
||||
|
||||
def write_patchset(self, patchset):
|
||||
destination_path = f"{self.mount_location}/System/Library/CoreServices"
|
||||
@@ -450,7 +477,7 @@ class PatchSysVolume:
|
||||
self.execute_patchset(sys_patch_detect.detect_root_patch(self.computer.real_model, self.constants).generate_patchset(self.hardware_details))
|
||||
|
||||
if self.constants.wxpython_variant is True and self.constants.detected_os >= os_data.os_data.big_sur:
|
||||
sys_patch_auto.AutomaticSysPatch.install_auto_patcher_launch_agent(self.constants)
|
||||
sys_patch_auto.AutomaticSysPatch(self.constants).install_auto_patcher_launch_agent()
|
||||
|
||||
self.rebuild_snapshot()
|
||||
|
||||
@@ -504,8 +531,10 @@ class PatchSysVolume:
|
||||
else:
|
||||
print(f"- Running Process:\n{process}")
|
||||
utilities.process_status(subprocess.run(process, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True))
|
||||
if "AMD Legacy GCN" in required_patches:
|
||||
if any(x in required_patches for x in ["AMD Legacy GCN", "AMD Legacy Polaris", "AMD Legacy Vega"]):
|
||||
sys_patch_helpers.sys_patch_helpers(self.constants).disable_window_server_caching()
|
||||
if any(x in required_patches for x in ["Intel Ivy Bridge", "Intel Haswell"]):
|
||||
sys_patch_helpers.sys_patch_helpers(self.constants).remove_news_widgets()
|
||||
self.write_patchset(required_patches)
|
||||
|
||||
def preflight_checks(self, required_patches, source_files_path):
|
||||
@@ -533,7 +562,10 @@ class PatchSysVolume:
|
||||
raise Exception(f"Failed to find {source_file}")
|
||||
|
||||
# Ensure KDK is properly installed
|
||||
self.merge_kdk_with_root()
|
||||
should_save_cs = False
|
||||
if "Legacy USB 1.1" in required_patches:
|
||||
should_save_cs = True
|
||||
self.merge_kdk_with_root(save_hid_cs=should_save_cs)
|
||||
|
||||
print("- Finished Preflight, starting patching")
|
||||
|
||||
283
resources/sys_patch/sys_patch_auto.py
Normal file
283
resources/sys_patch/sys_patch_auto.py
Normal file
@@ -0,0 +1,283 @@
|
||||
# Auto Patching's main purpose is to try and tell the user they're missing root patches
|
||||
# New users may not realize OS updates remove our patches, so we try and run when nessasary
|
||||
# Conditions for running:
|
||||
# - Verify running GUI (TUI users can write their own scripts)
|
||||
# - Verify the Snapshot Seal is intact (if not, assume user is running patches)
|
||||
# - Verify this model needs patching (if not, assume user upgraded hardware and OCLP was not removed)
|
||||
# - Verify there are no updates for OCLP (ensure we have the latest patch sets)
|
||||
# If all these tests pass, start Root Patcher
|
||||
# Copyright (C) 2022, Mykola Grymalyuk
|
||||
|
||||
from pathlib import Path
|
||||
import plistlib
|
||||
import subprocess
|
||||
import webbrowser
|
||||
from resources import utilities, updates, global_settings
|
||||
from resources.sys_patch import sys_patch_detect
|
||||
from resources.gui import gui_main
|
||||
|
||||
class AutomaticSysPatch:
|
||||
|
||||
def __init__(self, constants):
|
||||
self.constants = constants
|
||||
|
||||
|
||||
def start_auto_patch(self):
|
||||
print("- Starting Automatic Patching")
|
||||
if self.constants.wxpython_variant is False:
|
||||
print("- Auto Patch option is not supported on TUI, please use GUI")
|
||||
return
|
||||
|
||||
if utilities.check_seal() is True:
|
||||
print("- Detected Snapshot seal intact, detecting patches")
|
||||
patches = sys_patch_detect.detect_root_patch(self.constants.computer.real_model, self.constants).detect_patch_set()
|
||||
if not any(not patch.startswith("Settings") and not patch.startswith("Validation") and patches[patch] is True for patch in patches):
|
||||
patches = []
|
||||
if patches:
|
||||
print("- Detected applicable patches, determining whether possible to patch")
|
||||
if patches["Validation: Patching Possible"] is False:
|
||||
print("- Cannot run patching")
|
||||
return
|
||||
|
||||
print("- Determined patching is possible, checking for OCLP updates")
|
||||
patch_string = ""
|
||||
for patch in patches:
|
||||
if patches[patch] is True and not patch.startswith("Settings") and not patch.startswith("Validation"):
|
||||
patch_string += f"- {patch}\n"
|
||||
# Check for updates
|
||||
dict = updates.check_binary_updates(self.constants).check_binary_updates()
|
||||
if not dict:
|
||||
print("- No new binaries found on Github, proceeding with patching")
|
||||
if self.constants.launcher_script is None:
|
||||
args_string = f"'{self.constants.launcher_binary}' --gui_patch"
|
||||
else:
|
||||
args_string = f"{self.constants.launcher_binary} {self.constants.launcher_script} --gui_patch"
|
||||
|
||||
warning_str = ""
|
||||
if utilities.verify_network_connection("https://api.github.com/repos/dortania/OpenCore-Legacy-Patcher/releases/latest") is False:
|
||||
warning_str = f"""\n\nWARNING: We're unable to verify whether there are any new releases of OpenCore Legacy Patcher on Github. Be aware that you may be using an outdated version for this OS. If you're unsure, verify on Github that OpenCore Legacy Patcher {self.constants.patcher_version} is the latest official release"""
|
||||
|
||||
args = [
|
||||
"osascript",
|
||||
"-e",
|
||||
f"""display dialog "OpenCore Legacy Patcher has detected you're running without Root Patches, and would like to install them.\n\nmacOS wipes all root patches during OS installs and updates, so they need to be reinstalled.\n\nFollowing Patches have been detected for your system: \n{patch_string}\nWould you like to apply these patches?{warning_str}" """
|
||||
f'with icon POSIX file "{self.constants.app_icon_path}"',
|
||||
]
|
||||
output = subprocess.run(
|
||||
args,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT
|
||||
)
|
||||
if output.returncode == 0:
|
||||
args = [
|
||||
"osascript",
|
||||
"-e",
|
||||
f'''do shell script "{args_string}"'''
|
||||
f' with prompt "OpenCore Legacy Patcher would like to patch your root volume"'
|
||||
" with administrator privileges"
|
||||
" without altering line endings"
|
||||
]
|
||||
subprocess.run(
|
||||
args,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT
|
||||
)
|
||||
return
|
||||
else:
|
||||
for key in dict:
|
||||
version = dict[key]["Version"]
|
||||
github_link = dict[key]["Github Link"]
|
||||
print(f"- Found new version: {version}")
|
||||
|
||||
# launch osascript to ask user if they want to apply the update
|
||||
# if yes, open the link in the default browser
|
||||
# we never want to run the root patcher if there are updates available
|
||||
args = [
|
||||
"osascript",
|
||||
"-e",
|
||||
f"""display dialog "OpenCore Legacy Patcher has detected you're running without Root Patches, and would like to install them.\n\nHowever we've detected a new version of OCLP on Github. Would you like to view this?\n\nCurrent Version: {self.constants.patcher_version}\nLatest Version: {version}\n\nNote: After downloading the latest OCLP version, open the app and run the 'Post Install Root Patcher' from the main menu." """
|
||||
f'with icon POSIX file "{self.constants.app_icon_path}"',
|
||||
]
|
||||
output = subprocess.run(
|
||||
args,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT
|
||||
)
|
||||
if output.returncode == 0:
|
||||
webbrowser.open(github_link)
|
||||
|
||||
return
|
||||
else:
|
||||
print("- No patches detected")
|
||||
else:
|
||||
print("- Detected Snapshot seal not intact, skipping")
|
||||
|
||||
if self.determine_if_versions_match() is False:
|
||||
self.determine_if_boot_matches()
|
||||
|
||||
|
||||
def determine_if_versions_match(self):
|
||||
print("- Checking booted vs installed OCLP Build")
|
||||
if self.constants.computer.oclp_version is None:
|
||||
print("- Booted version not found")
|
||||
return False
|
||||
|
||||
if self.constants.computer.oclp_version == self.constants.patcher_version:
|
||||
print("- Versions match")
|
||||
return False
|
||||
|
||||
# Check if installed version is newer than booted version
|
||||
if updates.check_binary_updates(self.constants).check_if_build_newer(
|
||||
self.constants.computer.oclp_version.split("."), self.constants.patcher_version.split(".")
|
||||
) is True:
|
||||
print("- Installed version is newer than booted version")
|
||||
return False
|
||||
|
||||
args = [
|
||||
"osascript",
|
||||
"-e",
|
||||
f"""display dialog "OpenCore Legacy Patcher has detected that you are booting an outdated OpenCore build\n- Booted: {self.constants.computer.oclp_version}\n- Installed: {self.constants.patcher_version}\n\nWould you like to update the OpenCore bootloader?" """
|
||||
f'with icon POSIX file "{self.constants.app_icon_path}"',
|
||||
]
|
||||
output = subprocess.run(
|
||||
args,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT
|
||||
)
|
||||
if output.returncode == 0:
|
||||
print("- Launching GUI's Build/Install menu")
|
||||
self.constants.start_build_install = True
|
||||
gui_main.wx_python_gui(self.constants).main_menu(None)
|
||||
|
||||
return True
|
||||
|
||||
def determine_if_boot_matches(self):
|
||||
# Goal of this function is to determine whether the user
|
||||
# is using a USB drive to Boot OpenCore but macOS does not
|
||||
# reside on the same drive as the USB.
|
||||
|
||||
# If we determine them to be mismatched, notify the user
|
||||
# and ask if they want to install to install to disk
|
||||
|
||||
print("- Determining if macOS drive matches boot drive")
|
||||
should_notify = global_settings.global_settings().read_property("AutoPatch_Notify_Mismatched_Disks")
|
||||
if should_notify is False:
|
||||
print("- Skipping due to user preference")
|
||||
return
|
||||
if self.constants.host_is_hackintosh is True:
|
||||
print("- Skipping due to hackintosh")
|
||||
return
|
||||
if not self.constants.booted_oc_disk:
|
||||
print("- Failed to find disk OpenCore launched from")
|
||||
return
|
||||
|
||||
root_disk = self.constants.booted_oc_disk.strip("disk")
|
||||
root_disk = "disk" + root_disk.split("s")[0]
|
||||
|
||||
print(f" - Boot Drive: {self.constants.booted_oc_disk} ({root_disk})")
|
||||
macOS_disk = utilities.get_disk_path()
|
||||
print(f" - macOS Drive: {macOS_disk}")
|
||||
physical_stores = utilities.find_apfs_physical_volume(macOS_disk)
|
||||
print(f" - APFS Physical Stores: {physical_stores}")
|
||||
|
||||
disk_match = False
|
||||
for disk in physical_stores:
|
||||
if root_disk in disk:
|
||||
print(f"- Boot drive matches macOS drive ({disk})")
|
||||
disk_match = True
|
||||
break
|
||||
|
||||
if disk_match is True:
|
||||
return
|
||||
|
||||
# Check if OpenCore is on a USB drive
|
||||
print("- Boot Drive does not match macOS drive, checking if OpenCore is on a USB drive")
|
||||
|
||||
disk_info = plistlib.loads(subprocess.run(["diskutil", "info", "-plist", root_disk], stdout=subprocess.PIPE).stdout)
|
||||
try:
|
||||
if disk_info["Ejectable"] is False:
|
||||
print("- Boot Disk is not removable, skipping prompt")
|
||||
return
|
||||
|
||||
print("- Boot Disk is ejectable, prompting user to install to internal")
|
||||
|
||||
args = [
|
||||
"osascript",
|
||||
"-e",
|
||||
f"""display dialog "OpenCore Legacy Patcher has detected that you are booting OpenCore from an USB or External drive.\n\nIf you would like to boot your Mac normally without a USB drive plugged in, you can install OpenCore to the internal hard drive.\n\nWould you like to launch OpenCore Legacy Patcher and install to disk?" """
|
||||
f'with icon POSIX file "{self.constants.app_icon_path}"',
|
||||
]
|
||||
output = subprocess.run(
|
||||
args,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT
|
||||
)
|
||||
if output.returncode == 0:
|
||||
print("- Launching GUI's Build/Install menu")
|
||||
self.constants.start_build_install = True
|
||||
gui_main.wx_python_gui(self.constants).main_menu(None)
|
||||
|
||||
except KeyError:
|
||||
print("- Unable to determine if boot disk is removable, skipping prompt")
|
||||
|
||||
|
||||
def install_auto_patcher_launch_agent(self):
|
||||
# Installs the following:
|
||||
# - OpenCore-Patcher.app in /Library/Application Support/Dortania/
|
||||
# - com.dortania.opencore-legacy-patcher.auto-patch.plist in /Library/LaunchAgents/
|
||||
if self.constants.launcher_script is not None:
|
||||
print("- Skipping Auto Patcher Launch Agent, not supported when running from source")
|
||||
return
|
||||
|
||||
if self.constants.launcher_binary.startswith("/Library/Application Support/Dortania/"):
|
||||
print("- Skipping Auto Patcher Launch Agent, already installed")
|
||||
return
|
||||
|
||||
# Verify our binary isn't located in '/Library/Application Support/Dortania/'
|
||||
# As we'd simply be duplicating ourselves
|
||||
print("- Installing Auto Patcher Launch Agent")
|
||||
|
||||
if not Path("Library/Application Support/Dortania").exists():
|
||||
print("- Creating /Library/Application Support/Dortania/")
|
||||
utilities.process_status(utilities.elevated(["mkdir", "-p", "/Library/Application Support/Dortania"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
print("- Copying OpenCore Patcher to /Library/Application Support/Dortania/")
|
||||
if Path("/Library/Application Support/Dortania/OpenCore-Patcher.app").exists():
|
||||
print("- Deleting existing OpenCore-Patcher")
|
||||
utilities.process_status(utilities.elevated(["rm", "-R", "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
# Strip everything after OpenCore-Patcher.app
|
||||
path = str(self.constants.launcher_binary).split("/Contents/MacOS/OpenCore-Patcher")[0]
|
||||
print(f"- Copying {path} to /Library/Application Support/Dortania/")
|
||||
utilities.process_status(utilities.elevated(["ditto", path, "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
if not Path("/Library/Application Support/Dortania/OpenCore-Patcher.app").exists():
|
||||
# Sometimes the binary the user launches may have a suffix (ie. OpenCore-Patcher 3.app)
|
||||
# We'll want to rename it to OpenCore-Patcher.app
|
||||
path = path.split("/")[-1]
|
||||
print(f"- Renaming {path} to OpenCore-Patcher.app")
|
||||
utilities.process_status(utilities.elevated(["mv", f"/Library/Application Support/Dortania/{path}", "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
subprocess.run(["xattr", "-cr", "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
|
||||
# Copy over our launch agent
|
||||
print("- Copying auto-patch.plist Launch Agent to /Library/LaunchAgents/")
|
||||
if Path("/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist").exists():
|
||||
print("- Deleting existing auto-patch.plist")
|
||||
utilities.process_status(utilities.elevated(["rm", "/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
if not Path("/Library/LaunchAgents/").exists():
|
||||
print("- Creating /Library/LaunchAgents/")
|
||||
utilities.process_status(utilities.elevated(["mkdir", "-p", "/Library/LaunchAgents/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
utilities.process_status(utilities.elevated(["cp", self.constants.auto_patch_launch_agent_path, "/Library/LaunchAgents/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
# Set the permissions on the com.dortania.opencore-legacy-patcher.auto-patch.plist
|
||||
print("- Setting permissions on auto-patch.plist")
|
||||
utilities.process_status(utilities.elevated(["chmod", "644", "/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
utilities.process_status(utilities.elevated(["chown", "root:wheel", "/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
# Making app alias
|
||||
# Simply an easy way for users to notice the app
|
||||
# If there's already an alias or exiting app, skip
|
||||
if not Path("/Applications/OpenCore-Patcher.app").exists():
|
||||
print("- Making app alias")
|
||||
utilities.process_status(utilities.elevated(["ln", "-s", "/Library/Application Support/Dortania/OpenCore-Patcher.app", "/Applications/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
@@ -3,9 +3,13 @@
|
||||
# Used when supplying data to sys_patch.py
|
||||
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
|
||||
|
||||
import subprocess
|
||||
from resources import constants, device_probe, utilities, sys_patch_helpers, amfi_detect
|
||||
from data import model_array, os_data, sip_data, sys_patch_dict
|
||||
from resources import constants, device_probe, utilities, amfi_detect
|
||||
from resources.sys_patch import sys_patch_helpers
|
||||
from data import model_array, os_data, sip_data, sys_patch_dict, smbios_data, cpu_data
|
||||
|
||||
import py_sip_xnu
|
||||
from pathlib import Path
|
||||
import plistlib
|
||||
|
||||
class detect_root_patch:
|
||||
def __init__(self, model, versions):
|
||||
@@ -14,18 +18,20 @@ class detect_root_patch:
|
||||
self.computer = self.constants.computer
|
||||
|
||||
# GPU Patch Detection
|
||||
self.nvidia_tesla = False
|
||||
self.kepler_gpu = False
|
||||
self.nvidia_web = False
|
||||
self.amd_ts1 = False
|
||||
self.amd_ts2 = False
|
||||
self.iron_gpu = False
|
||||
self.sandy_gpu = False
|
||||
self.ivy_gpu = False
|
||||
self.haswell_gpu = False
|
||||
self.broadwell_gpu = False
|
||||
self.skylake_gpu = False
|
||||
self.legacy_gcn = False
|
||||
self.nvidia_tesla = False
|
||||
self.kepler_gpu = False
|
||||
self.nvidia_web = False
|
||||
self.amd_ts1 = False
|
||||
self.amd_ts2 = False
|
||||
self.iron_gpu = False
|
||||
self.sandy_gpu = False
|
||||
self.ivy_gpu = False
|
||||
self.haswell_gpu = False
|
||||
self.broadwell_gpu = False
|
||||
self.skylake_gpu = False
|
||||
self.legacy_gcn = False
|
||||
self.legacy_polaris = False
|
||||
self.legacy_vega = False
|
||||
|
||||
# Misc Patch Detection
|
||||
self.brightness_legacy = False
|
||||
@@ -33,6 +39,7 @@ class detect_root_patch:
|
||||
self.legacy_wifi = False
|
||||
self.legacy_gmux = False
|
||||
self.legacy_keyboard_backlight = False
|
||||
self.legacy_uhci_ohci = False
|
||||
|
||||
# Patch Requirements
|
||||
self.amfi_must_disable = False
|
||||
@@ -48,6 +55,7 @@ class detect_root_patch:
|
||||
self.fv_enabled = False
|
||||
self.dosdude_patched = False
|
||||
self.missing_kdk = False
|
||||
self.has_network = False
|
||||
|
||||
self.missing_whatever_green = False
|
||||
self.missing_nv_web_nvram = False
|
||||
@@ -130,10 +138,23 @@ class detect_root_patch:
|
||||
# full compatibility (namely power states, etc)
|
||||
# Reference: https://github.com/dortania/bugtracker/issues/292
|
||||
# TODO: Probe framebuffer families further
|
||||
if "AVX2" in self.constants.computer.cpu.leafs and self.model != "MacBookPro13,3":
|
||||
continue
|
||||
if self.model != "MacBookPro13,3":
|
||||
if "AVX2" in self.constants.computer.cpu.leafs:
|
||||
continue
|
||||
self.legacy_polaris = True
|
||||
else:
|
||||
self.legacy_gcn = True
|
||||
else:
|
||||
self.legacy_gcn = True
|
||||
self.supports_metal = True
|
||||
self.requires_root_kc = True
|
||||
self.amfi_must_disable = True
|
||||
elif gpu.arch == device_probe.AMD.Archs.Vega:
|
||||
if self.constants.detected_os > os_data.os_data.monterey:
|
||||
if "AVX2" in self.constants.computer.cpu.leafs:
|
||||
continue
|
||||
|
||||
self.legacy_gcn = True
|
||||
self.legacy_vega = True
|
||||
self.supports_metal = True
|
||||
self.requires_root_kc = True
|
||||
self.amfi_must_disable = True
|
||||
@@ -185,6 +206,14 @@ class detect_root_patch:
|
||||
self.sandy_gpu = False
|
||||
self.legacy_keyboard_backlight = False
|
||||
|
||||
if self.legacy_gcn is True:
|
||||
# We can only support one or the other due to the nature of relying
|
||||
# on portions of the native AMD stack for Polaris and Vega
|
||||
# Thus we'll prioritize legacy GCN due to being the internal card
|
||||
# ex. MacPro6,1 and MacBookPro11,5 with eGPUs
|
||||
self.legacy_polaris = False
|
||||
self.legacy_vega = False
|
||||
|
||||
if self.constants.detected_os <= os_data.os_data.monterey:
|
||||
# Always assume Root KC requirement on Monterey and older
|
||||
self.requires_root_kc = True
|
||||
@@ -192,6 +221,55 @@ class detect_root_patch:
|
||||
if self.requires_root_kc is True:
|
||||
self.missing_kdk = not self.check_kdk()
|
||||
|
||||
self.check_networking_support()
|
||||
|
||||
|
||||
def check_networking_support(self):
|
||||
# On macOS Ventura, networking support is required to download KDKs.
|
||||
# However for machines such as BCM94322, BCM94328 and Atheros chipsets,
|
||||
# users may only have wifi as their only supported network interface.
|
||||
# Thus we'll allow for KDK-less installs for these machines on first run.
|
||||
# On subsequent runs, we'll require networking to be enabled.
|
||||
|
||||
if self.constants.detected_os < os_data.os_data.ventura:
|
||||
return
|
||||
if self.legacy_wifi is False:
|
||||
return
|
||||
if self.requires_root_kc is False:
|
||||
return
|
||||
if self.missing_kdk is False:
|
||||
return
|
||||
if self.has_network is True:
|
||||
return
|
||||
|
||||
# Verify whether OCLP already installed network patches to the root volume
|
||||
# If so, require networking to be enabled (user just needs to connect to wifi)
|
||||
oclp_patch_path = "/System/Library/CoreServices/OpenCore-Legacy-Patcher.plist"
|
||||
if Path(oclp_patch_path).exists():
|
||||
oclp_plist = plistlib.load(open(oclp_patch_path, "rb"))
|
||||
if "Legacy Wireless" in oclp_plist:
|
||||
return
|
||||
|
||||
# Due to the reliance of KDKs for most older patches, we'll allow KDK-less
|
||||
# installs for Legacy Wifi patches and remove others
|
||||
self.missing_kdk = False
|
||||
self.requires_root_kc = False
|
||||
|
||||
# Reset patches needing KDK
|
||||
self.nvidia_tesla = False
|
||||
self.nvidia_web = False
|
||||
self.amd_ts1 = False
|
||||
self.amd_ts2 = False
|
||||
self.iron_gpu = False
|
||||
self.sandy_gpu = False
|
||||
self.legacy_gcn = False
|
||||
self.legacy_polaris = False
|
||||
self.legacy_vega = False
|
||||
self.brightness_legacy = False
|
||||
self.legacy_audio = False
|
||||
self.legacy_gmux = False
|
||||
self.legacy_keyboard_backlight = False
|
||||
|
||||
|
||||
def check_dgpu_status(self):
|
||||
dgpu = self.constants.computer.dgpu
|
||||
@@ -288,8 +366,47 @@ class detect_root_patch:
|
||||
sip_value = f"For Hackintoshes, please set csr-active-config to '03060000' ({sip_hex})\nFor non-OpenCore Macs, please run 'csrutil disable' in RecoveryOS"
|
||||
return (sip, sip_value, sip_hex)
|
||||
|
||||
def check_uhci_ohci(self):
|
||||
if self.constants.detected_os < os_data.os_data.ventura:
|
||||
return False
|
||||
|
||||
for controller in self.constants.computer.usb_controllers:
|
||||
if (isinstance(controller, device_probe.XHCIController)):
|
||||
# Currently USB 1.1 patches are incompatible with USB 3.0 controllers
|
||||
# TODO: Downgrade remaining USB stack to ensure full support
|
||||
return False
|
||||
|
||||
# If we're on a hackintosh, check for UHCI/OHCI controllers
|
||||
if self.constants.host_is_hackintosh is True:
|
||||
for controller in self.constants.computer.usb_controllers:
|
||||
if (
|
||||
isinstance(controller, device_probe.UHCIController) or
|
||||
isinstance(controller, device_probe.OHCIController)
|
||||
):
|
||||
return True
|
||||
return False
|
||||
|
||||
if self.model not in smbios_data.smbios_dictionary:
|
||||
return False
|
||||
|
||||
# If we're on a Mac, check for Penryn or older
|
||||
# This is due to Apple implementing an internal USB hub on post-Penryn (excluding MacPro4,1 and MacPro5,1)
|
||||
# Ref: https://techcommunity.microsoft.com/t5/microsoft-usb-blog/reasons-to-avoid-companion-controllers/ba-p/270710
|
||||
if (
|
||||
smbios_data.smbios_dictionary[self.model]["CPU Generation"] <= cpu_data.cpu_data.penryn.value or \
|
||||
self.model in ["MacPro4,1", "MacPro5,1"]
|
||||
):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def detect_patch_set(self):
|
||||
self.detect_gpus()
|
||||
self.has_network = utilities.verify_network_connection()
|
||||
|
||||
if self.check_uhci_ohci() is True:
|
||||
self.legacy_uhci_ohci = True
|
||||
self.requires_root_kc = True
|
||||
|
||||
if self.model in model_array.LegacyBrightness:
|
||||
if self.constants.detected_os > os_data.os_data.catalina:
|
||||
self.brightness_legacy = True
|
||||
@@ -304,8 +421,11 @@ class detect_root_patch:
|
||||
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 os_data.os_data.ventura > self.constants.detected_os > os_data.os_data.big_sur:
|
||||
if self.constants.detected_os > os_data.os_data.big_sur:
|
||||
self.legacy_wifi = True
|
||||
if self.constants.detected_os >= os_data.os_data.ventura:
|
||||
# Due to extracted frameworks for IO80211.framework and co, check library validation
|
||||
self.amfi_must_disable = True
|
||||
|
||||
# if self.model in ["MacBookPro5,1", "MacBookPro5,2", "MacBookPro5,3", "MacBookPro8,2", "MacBookPro8,3"]:
|
||||
if self.model in ["MacBookPro8,2", "MacBookPro8,3"]:
|
||||
@@ -321,6 +441,8 @@ class detect_root_patch:
|
||||
else:
|
||||
self.legacy_gmux = True
|
||||
|
||||
self.detect_gpus()
|
||||
|
||||
self.root_patch_dict = {
|
||||
"Graphics: Nvidia Tesla": self.nvidia_tesla,
|
||||
"Graphics: Nvidia Kepler": self.kepler_gpu,
|
||||
@@ -328,6 +450,8 @@ class detect_root_patch:
|
||||
"Graphics: AMD TeraScale 1": self.amd_ts1,
|
||||
"Graphics: AMD TeraScale 2": self.amd_ts2,
|
||||
"Graphics: AMD Legacy GCN": self.legacy_gcn,
|
||||
"Graphics: AMD Legacy Polaris": self.legacy_polaris,
|
||||
"Graphics: AMD Legacy Vega": self.legacy_vega,
|
||||
"Graphics: Intel Ironlake": self.iron_gpu,
|
||||
"Graphics: Intel Sandy Bridge": self.sandy_gpu,
|
||||
"Graphics: Intel Ivy Bridge": self.ivy_gpu,
|
||||
@@ -339,12 +463,13 @@ class detect_root_patch:
|
||||
"Networking: Legacy Wireless": self.legacy_wifi,
|
||||
"Miscellaneous: Legacy GMUX": self.legacy_gmux,
|
||||
"Miscellaneous: Legacy Keyboard Backlight": self.legacy_keyboard_backlight,
|
||||
"Miscellaneous: Legacy USB 1.1": self.legacy_uhci_ohci,
|
||||
"Settings: Requires AMFI exemption": self.amfi_must_disable,
|
||||
"Settings: Supports Auxiliary Cache": not self.requires_root_kc,
|
||||
"Settings: Kernel Debug Kit missing": self.missing_kdk if self.constants.detected_os >= os_data.os_data.ventura.value else False,
|
||||
"Validation: Patching Possible": self.verify_patch_allowed(),
|
||||
f"Validation: SIP is enabled (Required: {self.check_sip()[2]} or higher)": self.sip_enabled,
|
||||
f"Validation: Currently Booted SIP: ({hex(utilities.csr_dump())})": self.sip_enabled,
|
||||
f"Validation: Currently Booted SIP: ({hex(py_sip_xnu.SipXnu().get_sip_status().value)})": self.sip_enabled,
|
||||
"Validation: SecureBootModel is enabled": self.sbm_enabled,
|
||||
f"Validation: {'AMFI' if self.constants.host_is_hackintosh is True or self.get_amfi_level_needed() > 2 else 'Library Validation'} is enabled": self.amfi_enabled if self.amfi_must_disable is True else False,
|
||||
"Validation: FileVault is enabled": self.fv_enabled,
|
||||
@@ -353,6 +478,7 @@ class detect_root_patch:
|
||||
"Validation: Force OpenGL property missing": self.missing_nv_web_opengl if self.nvidia_web is True else False,
|
||||
"Validation: Force compat property missing": self.missing_nv_compat if self.nvidia_web is True else False,
|
||||
"Validation: nvda_drv(_vrl) variable missing": self.missing_nv_web_nvram if self.nvidia_web is True else False,
|
||||
"Validation: Network Connection Required": (not self.has_network) if (self.requires_root_kc and self.missing_kdk and self.constants.detected_os >= os_data.os_data.ventura.value) else False,
|
||||
}
|
||||
|
||||
return self.root_patch_dict
|
||||
@@ -425,6 +551,10 @@ class detect_root_patch:
|
||||
print("\nCannot patch! WhateverGreen.kext missing")
|
||||
print("Please ensure WhateverGreen.kext is installed")
|
||||
|
||||
if (not self.has_network) if (self.requires_root_kc and self.missing_kdk and self.constants.detected_os >= os_data.os_data.ventura.value) else False:
|
||||
print("\nCannot patch! Network Connection Required")
|
||||
print("Please ensure you have an active internet connection")
|
||||
|
||||
if any(
|
||||
[
|
||||
# General patch checks
|
||||
@@ -438,6 +568,9 @@ class detect_root_patch:
|
||||
self.missing_nv_web_opengl if self.nvidia_web is True else False,
|
||||
self.missing_nv_compat if self.nvidia_web is True else False,
|
||||
self.missing_whatever_green if self.nvidia_web is True else False,
|
||||
|
||||
# KDK specific
|
||||
(not self.has_network) if (self.requires_root_kc and self.missing_kdk and self.constants.detected_os >= os_data.os_data.ventura.value) else False
|
||||
]
|
||||
):
|
||||
return False
|
||||
@@ -518,13 +651,23 @@ class detect_root_patch:
|
||||
# TeraScale 2 MacBooks with faulty GPUs are highly prone to crashing with AMDRadeonX3000 attached
|
||||
# Additionally, AMDRadeonX3000 requires IOAccelerator downgrade which is not installed without 'Non-Metal IOAccelerator Common'
|
||||
del(required_patches["AMD TeraScale 2"]["Install"]["/System/Library/Extensions"]["AMDRadeonX3000.kext"])
|
||||
if hardware_details["Graphics: AMD Legacy GCN"] is True:
|
||||
if hardware_details["Graphics: AMD Legacy GCN"] is True or hardware_details["Graphics: AMD Legacy Polaris"] is True:
|
||||
required_patches.update({"Revert Metal Downgrade": all_hardware_patchset["Graphics"]["Revert Metal Downgrade"]})
|
||||
required_patches.update({"Monterey GVA": all_hardware_patchset["Graphics"]["Monterey GVA"]})
|
||||
required_patches.update({"Monterey OpenCL": all_hardware_patchset["Graphics"]["Monterey OpenCL"]})
|
||||
required_patches.update({"AMD Legacy GCN": all_hardware_patchset["Graphics"]["AMD Legacy GCN"]})
|
||||
if hardware_details["Graphics: AMD Legacy GCN"] is True:
|
||||
required_patches.update({"AMD Legacy GCN": all_hardware_patchset["Graphics"]["AMD Legacy GCN"]})
|
||||
else:
|
||||
required_patches.update({"AMD Legacy Polaris": all_hardware_patchset["Graphics"]["AMD Legacy Polaris"]})
|
||||
if "AVX2" not in self.constants.computer.cpu.leafs:
|
||||
required_patches.update({"AMD OpenCL": all_hardware_patchset["Graphics"]["AMD OpenCL"]})
|
||||
if hardware_details["Graphics: AMD Legacy Vega"] is True:
|
||||
required_patches.update({"Monterey GVA": all_hardware_patchset["Graphics"]["Monterey GVA"]})
|
||||
required_patches.update({"Monterey OpenCL": all_hardware_patchset["Graphics"]["Monterey OpenCL"]})
|
||||
required_patches.update({"AMD Legacy Vega": all_hardware_patchset["Graphics"]["AMD Legacy Vega"]})
|
||||
required_patches.update({"AMD OpenCL": all_hardware_patchset["Graphics"]["AMD OpenCL"]})
|
||||
if hardware_details["Graphics: AMD Legacy GCN"] is True:
|
||||
required_patches.update({"AMD Legacy Vega Extended": all_hardware_patchset["Graphics"]["AMD Legacy Vega Extended"]})
|
||||
if hardware_details["Brightness: Legacy Backlight Control"] is True:
|
||||
required_patches.update({"Legacy Backlight Control": all_hardware_patchset["Brightness"]["Legacy Backlight Control"]})
|
||||
if hardware_details["Audio: Legacy Realtek"] is True:
|
||||
@@ -534,10 +677,13 @@ class detect_root_patch:
|
||||
required_patches.update({"Legacy Non-GOP": all_hardware_patchset["Audio"]["Legacy Non-GOP"]})
|
||||
if hardware_details["Networking: Legacy Wireless"] is True:
|
||||
required_patches.update({"Legacy Wireless": all_hardware_patchset["Networking"]["Legacy Wireless"]})
|
||||
required_patches.update({"Legacy Wireless Extended": all_hardware_patchset["Networking"]["Legacy Wireless Extended"]})
|
||||
if hardware_details["Miscellaneous: Legacy GMUX"] is True:
|
||||
required_patches.update({"Legacy GMUX": all_hardware_patchset["Miscellaneous"]["Legacy GMUX"]})
|
||||
if hardware_details["Miscellaneous: Legacy Keyboard Backlight"] is True:
|
||||
required_patches.update({"Legacy Keyboard Backlight": all_hardware_patchset["Miscellaneous"]["Legacy Keyboard Backlight"]})
|
||||
if hardware_details["Miscellaneous: Legacy USB 1.1"] is True:
|
||||
required_patches.update({"Legacy USB 1.1": all_hardware_patchset["Miscellaneous"]["Legacy USB 1.1"]})
|
||||
|
||||
if required_patches:
|
||||
host_os_float = float(f"{self.constants.detected_os}.{self.constants.detected_os_minor}")
|
||||
@@ -10,7 +10,7 @@ from datetime import datetime
|
||||
import plistlib
|
||||
import os
|
||||
|
||||
from resources import constants
|
||||
from resources import constants, bplist
|
||||
|
||||
class sys_patch_helpers:
|
||||
|
||||
@@ -65,6 +65,7 @@ class sys_patch_helpers:
|
||||
"Time Patched": f"{datetime.now().strftime('%B %d, %Y @ %H:%M:%S')}",
|
||||
"Commit URL": f"{self.constants.commit_info[2]}",
|
||||
"Kernel Debug Kit Used": f"{kdk_string}",
|
||||
"OS Version": f"{self.constants.detected_os}.{self.constants.detected_os_minor} ({self.constants.detected_os_build})",
|
||||
}
|
||||
data.update(patchset)
|
||||
if Path(source_path_file).exists():
|
||||
@@ -82,9 +83,23 @@ class sys_patch_helpers:
|
||||
print(f"- Installing downloaded KDK (this may take a while)")
|
||||
with tempfile.TemporaryDirectory() as mount_point:
|
||||
utilities.process_status(subprocess.run(["hdiutil", "attach", self.constants.kdk_download_path, "-mountpoint", mount_point, "-nobrowse"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
# Install the KDK
|
||||
utilities.process_status(utilities.elevated(["installer", "-pkg", f"{mount_point}/KernelDebugKit.pkg", "-target", "/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
subprocess.run(["hdiutil", "detach", mount_point], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) # Do not really care if this fails
|
||||
# Due to a permissions bug in macOS, sometimes the OS will fail on a Read-only file system error
|
||||
# We don't actually need to write inside the KDK DMG, however macOS will do whatever it wants
|
||||
# Thus move the KDK to another location, and run the installer from there
|
||||
kdk_dst_path = Path(f"{self.constants.payload_path}/KernelDebugKit.pkg")
|
||||
if kdk_dst_path.exists():
|
||||
utilities.process_status(utilities.elevated(["rm", kdk_dst_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
utilities.process_status(subprocess.run(["cp", f"{mount_point}/KernelDebugKit.pkg", self.constants.payload_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
result = utilities.elevated(["installer", "-pkg", kdk_dst_path, "-target", "/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
if result.returncode != 0:
|
||||
print("- Failed to install KDK:")
|
||||
print(result.stdout.decode('utf-8'))
|
||||
if result.stderr:
|
||||
print(result.stderr.decode('utf-8'))
|
||||
utilities.elevated(["hdiutil", "detach", mount_point], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
raise Exception("Failed to install KDK")
|
||||
utilities.process_status(utilities.elevated(["rm", kdk_dst_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
utilities.elevated(["hdiutil", "detach", mount_point], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
print("- Successfully installed KDK")
|
||||
|
||||
|
||||
@@ -137,8 +152,73 @@ class sys_patch_helpers:
|
||||
# corrupted Opaque shaders.
|
||||
# To work-around this, we disable WindowServer caching
|
||||
# And force macOS into properly generating the Opaque shaders
|
||||
if self.constants.detected_os < os_data.os_data.ventura:
|
||||
return
|
||||
print("- Disabling WindowServer Caching")
|
||||
# Invoke via 'bash -c' to resolve pathing
|
||||
utilities.elevated(["bash", "-c", "rm -rf /private/var/folders/*/*/*/WindowServer/com.apple.WindowServer"])
|
||||
# Disable writing to WindowServer folder
|
||||
utilities.elevated(["bash", "-c", "chflags uchg /private/var/folders/*/*/*/WindowServer"])
|
||||
# Reference:
|
||||
# To reverse write lock:
|
||||
# 'chflags nouchg /private/var/folders/*/*/*/WindowServer'
|
||||
|
||||
|
||||
def remove_news_widgets(self):
|
||||
# On Ivy Bridge and Haswell iGPUs, RenderBox will crash the News Widgets in
|
||||
# Notification Centre. To ensure users can access Notifications normally,
|
||||
# we manually remove all News Widgets
|
||||
if self.constants.detected_os < os_data.os_data.ventura:
|
||||
return
|
||||
print("- Parsing Notification Centre Widgets")
|
||||
file_path = "~/Library/Containers/com.apple.notificationcenterui/Data/Library/Preferences/com.apple.notificationcenterui.plist"
|
||||
file_path = Path(file_path).expanduser()
|
||||
|
||||
if not file_path.exists():
|
||||
print(" - Defaults file not found, skipping")
|
||||
return
|
||||
|
||||
did_find = False
|
||||
with open(file_path, "rb") as f:
|
||||
data = plistlib.load(f)
|
||||
if "widgets" in data:
|
||||
if "instances" in data["widgets"]:
|
||||
for widget in list(data["widgets"]["instances"]):
|
||||
widget_data = bplist.BPListReader(widget).parse()
|
||||
for entry in widget_data:
|
||||
if not 'widget' in entry:
|
||||
continue
|
||||
sub_data = bplist.BPListReader(widget_data[entry]).parse()
|
||||
for sub_entry in sub_data:
|
||||
if not '$object' in sub_entry:
|
||||
continue
|
||||
if not b'com.apple.news' in sub_data[sub_entry][2]:
|
||||
continue
|
||||
print(f" - Found News Widget to remove: {sub_data[sub_entry][2].decode('ascii')}")
|
||||
data["widgets"]["instances"].remove(widget)
|
||||
did_find = True
|
||||
if did_find:
|
||||
with open(file_path, "wb") as f:
|
||||
plistlib.dump(data, f, sort_keys=False)
|
||||
subprocess.run(["killall", "NotificationCenter"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
|
||||
|
||||
def install_rsr_repair_binary(self):
|
||||
# With macOS 13.2, Apple implemented the Rapid Security Response System
|
||||
# However Apple added a half baked snapshot reversion system if seal was broken,
|
||||
# which forgets to handle Preboot BootKC syncing
|
||||
|
||||
# Thus this application will try to re-sync the BootKC with SysKC in the event of a panic
|
||||
# Reference: https://github.com/dortania/OpenCore-Legacy-Patcher/issues/1019
|
||||
|
||||
# This is a (hopefully) temporary work-around, however likely to stay.
|
||||
# RSRRepair has the added bonus of fixing desynced KCs from 'bless', so useful in Big Sur+
|
||||
# https://github.com/flagersgit/RSRRepair
|
||||
|
||||
if self.constants.detected_os < os_data.os_data.big_sur:
|
||||
return
|
||||
|
||||
print("- Installing Kernel Collection syncing utility")
|
||||
result = utilities.elevated([self.constants.rsrrepair_userspace_path, "--install"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
if result.returncode != 0:
|
||||
print(f" - Failed to install RSRRepair: {result.stdout.decode()}")
|
||||
@@ -1,224 +0,0 @@
|
||||
# Auto Patching's main purpose is to try and tell the user they're missing root patches
|
||||
# New users may not realize OS updates remove our patches, so we try and run when nessasary
|
||||
# Conditions for running:
|
||||
# - Verify running GUI (TUI users can write their own scripts)
|
||||
# - Verify the Snapshot Seal is intact (if not, assume user is running patches)
|
||||
# - Verify this model needs patching (if not, assume user upgraded hardware and OCLP was not removed)
|
||||
# - Verify there are no updates for OCLP (ensure we have the latest patch sets)
|
||||
# If all these tests pass, start Root Patcher
|
||||
# Copyright (C) 2022, Mykola Grymalyuk
|
||||
|
||||
from pathlib import Path
|
||||
import plistlib
|
||||
import subprocess
|
||||
import webbrowser
|
||||
from resources import sys_patch_detect, utilities, sys_patch_detect, updates, global_settings
|
||||
from gui import gui_main
|
||||
|
||||
class AutomaticSysPatch:
|
||||
def start_auto_patch(settings):
|
||||
print("- Starting Automatic Patching")
|
||||
if settings.wxpython_variant is True:
|
||||
if utilities.check_seal() is True:
|
||||
print("- Detected Snapshot seal intact, detecting patches")
|
||||
patches = sys_patch_detect.detect_root_patch(settings.computer.real_model, settings).detect_patch_set()
|
||||
if not any(not patch.startswith("Settings") and not patch.startswith("Validation") and patches[patch] is True for patch in patches):
|
||||
patches = []
|
||||
if patches:
|
||||
print("- Detected applicable patches, determining whether possible to patch")
|
||||
if patches["Validation: Patching Possible"] is True:
|
||||
print("- Determined patching is possible, checking for OCLP updates")
|
||||
patch_string = ""
|
||||
for patch in patches:
|
||||
if patches[patch] is True and not patch.startswith("Settings") and not patch.startswith("Validation"):
|
||||
patch_string += f"- {patch}\n"
|
||||
# Check for updates
|
||||
dict = updates.check_binary_updates(settings).check_binary_updates()
|
||||
if not dict:
|
||||
print("- No new binaries found on Github, proceeding with patching")
|
||||
if settings.launcher_script is None:
|
||||
args_string = f"'{settings.launcher_binary}' --gui_patch"
|
||||
else:
|
||||
args_string = f"{settings.launcher_binary} {settings.launcher_script} --gui_patch"
|
||||
|
||||
warning_str = ""
|
||||
if utilities.verify_network_connection("https://api.github.com/repos/dortania/OpenCore-Legacy-Patcher/releases/latest") is False:
|
||||
warning_str = f"""\n\nWARNING: We're unable to verify whether there are any new releases of OpenCore Legacy Patcher on Github. Be aware that you may be using an outdated version for this OS. If you're unsure, verify on Github that OpenCore Legacy Patcher {settings.patcher_version} is the latest official release"""
|
||||
|
||||
args = [
|
||||
"osascript",
|
||||
"-e",
|
||||
f"""display dialog "OpenCore Legacy Patcher has detected you're running without Root Patches, and would like to install them.\n\nmacOS wipes all root patches during OS installs and updates, so they need to be reinstalled.\n\nFollowing Patches have been detected for your system: \n{patch_string}\nWould you like to apply these patches?{warning_str}" """
|
||||
f'with icon POSIX file "{settings.app_icon_path}"',
|
||||
]
|
||||
output = subprocess.run(
|
||||
args,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT
|
||||
)
|
||||
if output.returncode == 0:
|
||||
args = [
|
||||
"osascript",
|
||||
"-e",
|
||||
f'''do shell script "{args_string}"'''
|
||||
f' with prompt "OpenCore Legacy Patcher would like to patch your root volume"'
|
||||
" with administrator privileges"
|
||||
" without altering line endings"
|
||||
]
|
||||
subprocess.run(
|
||||
args,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT
|
||||
)
|
||||
else:
|
||||
version = dict[0]["Version"]
|
||||
github_link = dict[0]["Github Link"]
|
||||
print(f"- Found new version: {version}")
|
||||
|
||||
# launch oascript to ask user if they want to apply the update
|
||||
# if yes, open the link in the default browser
|
||||
# we never want to run the root patcher if there are updates available
|
||||
args = [
|
||||
"osascript",
|
||||
"-e",
|
||||
f"""display dialog "OpenCore Legacy Patcher has detected you're running without Root Patches, and would like to install them.\n\nHowever we've detected a new version of OCLP on Github. Would you like to view this?\n\nCurrent Version: {settings.patcher_version}\nLatest Version: {version}\n\nNote: After downloading the latest OCLP version, open the app and run the 'Post Install Root Patcher' from the main menu." """
|
||||
f'with icon POSIX file "{settings.app_icon_path}"',
|
||||
]
|
||||
output = subprocess.run(
|
||||
args,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT
|
||||
)
|
||||
if output.returncode == 0:
|
||||
webbrowser.open(github_link)
|
||||
else:
|
||||
print("- Cannot run patching")
|
||||
else:
|
||||
print("- No patches detected")
|
||||
AutomaticSysPatch.determine_if_boot_matches(settings)
|
||||
else:
|
||||
print("- Detected Snapshot seal not intact, skipping")
|
||||
AutomaticSysPatch.determine_if_boot_matches(settings)
|
||||
else:
|
||||
print("- Auto Patch option is not supported on TUI, please use GUI")
|
||||
|
||||
def determine_if_boot_matches(settings):
|
||||
# Goal of this function is to determine whether the user
|
||||
# is using a USB drive to Boot OpenCore but macOS does not
|
||||
# reside on the same drive as the USB.
|
||||
|
||||
# If we determine them to be mismatched, notify the user
|
||||
# and ask if they want to install to install to disk
|
||||
|
||||
print("- Determining if macOS drive matches boot drive")
|
||||
|
||||
should_notify = global_settings.global_settings().read_property("AutoPatch_Notify_Mismatched_Disks")
|
||||
if should_notify is False:
|
||||
print("- Skipping due to user preference")
|
||||
elif settings.host_is_hackintosh is True:
|
||||
print("- Skipping due to hackintosh")
|
||||
else:
|
||||
if settings.booted_oc_disk:
|
||||
root_disk = settings.booted_oc_disk.strip("disk")
|
||||
root_disk = "disk" + root_disk.split("s")[0]
|
||||
|
||||
print(f" - Boot Drive: {settings.booted_oc_disk} ({root_disk})")
|
||||
macOS_disk = utilities.get_disk_path()
|
||||
print(f" - macOS Drive: {macOS_disk}")
|
||||
physical_stores = utilities.find_apfs_physical_volume(macOS_disk)
|
||||
print(f" - APFS Physical Stores: {physical_stores}")
|
||||
|
||||
disk_match = False
|
||||
for disk in physical_stores:
|
||||
if root_disk in disk:
|
||||
print(f"- Boot drive matches macOS drive ({disk})")
|
||||
disk_match = True
|
||||
break
|
||||
|
||||
if disk_match is False:
|
||||
# Check if OpenCore is on a USB drive
|
||||
print("- Boot Drive does not match macOS drive, checking if OpenCore is on a USB drive")
|
||||
|
||||
disk_info = plistlib.loads(subprocess.run(["diskutil", "info", "-plist", root_disk], stdout=subprocess.PIPE).stdout)
|
||||
try:
|
||||
if disk_info["Ejectable"] is True:
|
||||
print("- Boot Disk is ejectable, prompting user to install to internal")
|
||||
|
||||
args = [
|
||||
"osascript",
|
||||
"-e",
|
||||
f"""display dialog "OpenCore Legacy Patcher has detected that you are booting OpenCore from an USB or External drive.\n\nIf you would like to boot your Mac normally without a USB drive plugged in, you can install OpenCore to the internal hard drive.\n\nWould you like to launch OpenCore Legacy Patcher and install to disk?" """
|
||||
f'with icon POSIX file "{settings.app_icon_path}"',
|
||||
]
|
||||
output = subprocess.run(
|
||||
args,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT
|
||||
)
|
||||
if output.returncode == 0:
|
||||
print("- Launching GUI's Build/Install menu")
|
||||
settings.start_build_install = True
|
||||
gui_main.wx_python_gui(settings).main_menu(None)
|
||||
else:
|
||||
print("- Boot Disk is not removable, skipping prompt")
|
||||
except KeyError:
|
||||
print("- Unable to determine if boot disk is removable, skipping prompt")
|
||||
|
||||
else:
|
||||
print("- Failed to find disk OpenCore launched from")
|
||||
|
||||
|
||||
def install_auto_patcher_launch_agent(settings):
|
||||
# Installs the following:
|
||||
# - OpenCore-Patcher.app in /Library/Application Support/Dortania/
|
||||
# - com.dortania.opencore-legacy-patcher.auto-patch.plist in /Library/LaunchAgents/
|
||||
if settings.launcher_script is None:
|
||||
# Verify our binary isn't located in '/Library/Application Support/Dortania/'
|
||||
# As we'd simply be duplicating ourselves
|
||||
if not settings.launcher_binary.startswith("/Library/Application Support/Dortania/"):
|
||||
print("- Installing Auto Patcher Launch Agent")
|
||||
|
||||
if not Path("Library/Application Support/Dortania").exists():
|
||||
print("- Creating /Library/Application Support/Dortania/")
|
||||
utilities.process_status(utilities.elevated(["mkdir", "-p", "/Library/Application Support/Dortania"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
print("- Copying OpenCore Patcher to /Library/Application Support/Dortania/")
|
||||
if Path("/Library/Application Support/Dortania/OpenCore-Patcher.app").exists():
|
||||
print("- Deleting existing OpenCore-Patcher")
|
||||
utilities.process_status(utilities.elevated(["rm", "-R", "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
# Strip everything after OpenCore-Patcher.app
|
||||
path = str(settings.launcher_binary).split("/Contents/MacOS/OpenCore-Patcher")[0]
|
||||
print(f"- Copying {path} to /Library/Application Support/Dortania/")
|
||||
utilities.process_status(utilities.elevated(["ditto", path, "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
if not Path("/Library/Application Support/Dortania/OpenCore-Patcher.app").exists():
|
||||
# Sometimes the binary the user launches may have a suffix (ie. OpenCore-Patcher 3.app)
|
||||
# We'll want to rename it to OpenCore-Patcher.app
|
||||
path = path.split("/")[-1]
|
||||
print(f"- Renaming {path} to OpenCore-Patcher.app")
|
||||
utilities.process_status(utilities.elevated(["mv", f"/Library/Application Support/Dortania/{path}", "/Library/Application Support/Dortania/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
# Copy over our launch agent
|
||||
print("- Copying auto-patch.plist Launch Agent to /Library/LaunchAgents/")
|
||||
if Path("/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist").exists():
|
||||
print("- Deleting existing auto-patch.plist")
|
||||
utilities.process_status(utilities.elevated(["rm", "/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
if not Path("/Library/LaunchAgents/").exists():
|
||||
print("- Creating /Library/LaunchAgents/")
|
||||
utilities.process_status(utilities.elevated(["mkdir", "-p", "/Library/LaunchAgents/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
utilities.process_status(utilities.elevated(["cp", settings.auto_patch_launch_agent_path, "/Library/LaunchAgents/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
# Set the permissions on the com.dortania.opencore-legacy-patcher.auto-patch.plist
|
||||
print("- Setting permissions on auto-patch.plist")
|
||||
utilities.process_status(utilities.elevated(["chmod", "644", "/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
utilities.process_status(utilities.elevated(["chown", "root:wheel", "/Library/LaunchAgents/com.dortania.opencore-legacy-patcher.auto-patch.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
|
||||
# Making app alias
|
||||
# Simply an easy way for users to notice the app
|
||||
# If there's already an alias or exiting app, skip
|
||||
if not Path("/Applications/OpenCore-Patcher.app").exists():
|
||||
print("- Making app alias")
|
||||
utilities.process_status(utilities.elevated(["ln", "-s", "/Library/Application Support/Dortania/OpenCore-Patcher.app", "/Applications/OpenCore-Patcher.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
|
||||
else:
|
||||
print("- Skipping Auto Patcher Launch Agent, not supported when running from source")
|
||||
@@ -27,17 +27,22 @@ class check_binary_updates:
|
||||
return False
|
||||
return False
|
||||
|
||||
def check_if_build_newer(self):
|
||||
# Pad version numbers to match length (ie. 0.1.0 vs 0.1.0.1)
|
||||
while len(self.remote_version_array) > len(self.binary_version_array):
|
||||
self.binary_version_array.append(0)
|
||||
while len(self.remote_version_array) < len(self.binary_version_array):
|
||||
self.remote_version_array.append(0)
|
||||
def check_if_build_newer(self, remote_version=None, local_version=None):
|
||||
if remote_version is None:
|
||||
remote_version = self.remote_version_array
|
||||
if local_version is None:
|
||||
local_version = self.binary_version_array
|
||||
|
||||
for i in range(0, len(self.remote_version_array)):
|
||||
if int(self.remote_version_array[i]) < int(self.binary_version_array[i]):
|
||||
# Pad version numbers to match length (ie. 0.1.0 vs 0.1.0.1)
|
||||
while len(remote_version) > len(local_version):
|
||||
local_version.append(0)
|
||||
while len(remote_version) < len(local_version):
|
||||
remote_version.append(0)
|
||||
|
||||
for i in range(0, len(remote_version)):
|
||||
if int(remote_version[i]) < int(local_version[i]):
|
||||
break
|
||||
elif int(self.remote_version_array[i]) > int(self.binary_version_array[i]):
|
||||
elif int(remote_version[i]) > int(local_version[i]):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
@@ -9,14 +9,14 @@ from pathlib import Path
|
||||
import os
|
||||
import binascii
|
||||
import argparse
|
||||
from ctypes import CDLL, c_uint, byref
|
||||
import time
|
||||
import atexit
|
||||
import requests
|
||||
import shutil
|
||||
import urllib.parse
|
||||
import py_sip_xnu
|
||||
|
||||
from resources import constants, ioreg, amfi_detect
|
||||
from resources import constants, ioreg
|
||||
from data import sip_data, os_data
|
||||
|
||||
SESSION = requests.Session()
|
||||
@@ -40,7 +40,7 @@ def string_to_hex(input_string):
|
||||
def process_status(process_result):
|
||||
if process_result.returncode != 0:
|
||||
print(f"Process failed with exit code {process_result.returncode}")
|
||||
print(f"Please file an issue on our Github")
|
||||
print(f"Please report the issue on the Discord server")
|
||||
raise Exception(f"Process result: \n{process_result.stdout.decode()}")
|
||||
|
||||
|
||||
@@ -102,24 +102,9 @@ def check_filesystem_type():
|
||||
filesystem_type = plistlib.loads(subprocess.run(["diskutil", "info", "-plist", "/"], stdout=subprocess.PIPE).stdout.decode().strip().encode())
|
||||
return filesystem_type["FilesystemType"]
|
||||
|
||||
def csr_dump():
|
||||
# Based off sip_config.py
|
||||
# https://gist.github.com/pudquick/8b320be960e1654b908b10346272326b
|
||||
# https://opensource.apple.com/source/xnu/xnu-7195.141.2/libsyscall/wrappers/csr.c.auto.html
|
||||
# Far more reliable than parsing NVRAM's csr-active-config (ie. user can wipe it, boot.efi can strip bits)
|
||||
|
||||
# Note that 'csr_get_active_config' was not introduced until 10.11
|
||||
try:
|
||||
libsys = CDLL('/usr/lib/libSystem.dylib')
|
||||
raw = c_uint(0)
|
||||
errmsg = libsys.csr_get_active_config(byref(raw))
|
||||
return raw.value
|
||||
except AttributeError:
|
||||
return 0
|
||||
|
||||
|
||||
def csr_decode(os_sip):
|
||||
sip_int = csr_dump()
|
||||
sip_int = py_sip_xnu.SipXnu().get_sip_status().value
|
||||
for i, current_sip_bit in enumerate(sip_data.system_integrity_protection.csr_values):
|
||||
if sip_int & (1 << i):
|
||||
sip_data.system_integrity_protection.csr_values[current_sip_bit] = True
|
||||
@@ -375,7 +360,9 @@ def get_firmware_vendor(*, decode: bool = False):
|
||||
value = value.strip("\0")
|
||||
return value
|
||||
|
||||
def verify_network_connection(url):
|
||||
def verify_network_connection(url=None):
|
||||
if url is None:
|
||||
url = "https://www.google.com"
|
||||
try:
|
||||
response = SESSION.head(url, timeout=5, allow_redirects=True)
|
||||
return True
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import subprocess
|
||||
from resources import build, sys_patch_helpers
|
||||
from resources.sys_patch import sys_patch_helpers
|
||||
from resources.build import build
|
||||
from data import example_data, model_array, sys_patch_dict, os_data
|
||||
from pathlib import Path
|
||||
|
||||
@@ -42,7 +43,7 @@ def validate(settings):
|
||||
for model in model_array.SupportedSMBIOS:
|
||||
print(f"Validating predefined model: {model}")
|
||||
settings.custom_model = model
|
||||
build.BuildOpenCore(settings.custom_model, settings).build_opencore()
|
||||
build.build_opencore(settings.custom_model, settings).build_opencore()
|
||||
result = subprocess.run([settings.ocvalidate_path, f"{settings.opencore_release_folder}/EFI/OC/config.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
if result.returncode != 0:
|
||||
print("Error on build!")
|
||||
@@ -56,7 +57,7 @@ def validate(settings):
|
||||
settings.computer = model
|
||||
settings.custom_model = ""
|
||||
print(f"Validating dumped model: {settings.computer.real_model}")
|
||||
build.BuildOpenCore(settings.computer.real_model, settings).build_opencore()
|
||||
build.build_opencore(settings.computer.real_model, settings).build_opencore()
|
||||
result = subprocess.run([settings.ocvalidate_path, f"{settings.opencore_release_folder}/EFI/OC/config.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
if result.returncode != 0:
|
||||
print("Error on build!")
|
||||
|
||||
Reference in New Issue
Block a user