diff --git a/CHANGELOG.md b/CHANGELOG.md index ecd0bab71..49b5c548c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,8 @@ - After OS updates, Patcher will detect whether system requires root patches and prompt you - Implemented via Launch Agent in `/Library/LaunchAgents` - OpenCore-Patcher.app will be copied to `/Library/Application Support/Dortania` for storage + - Notify users when OpenCore is booted from external disk not matching macOS (ie. USB installer) + - Disable notification via `defaults write AutoPatch_Notify_Mismatched_Disks -bool FALSE` - GUI Enhancements: - Add Reboot Prompt after Root Patching - Add Disk Installation Prompt after OpenCore Config Building diff --git a/data/os_data.py b/data/os_data.py index 05ebcc80c..bb9145959 100644 --- a/data/os_data.py +++ b/data/os_data.py @@ -18,3 +18,20 @@ class os_data(enum.IntEnum): big_sur = 20 monterey = 21 max_os = 99 + + +class os_conversion: + + def os_to_kernel(os): + # Convert OS version to major XNU version + if os.startswith("10."): + return (int(os.split(".")[1]) + 4) + else: + return (int(os.split(".")[0]) + 9) + + def kernel_to_os(kernel): + # Convert major XNU version to OS version + if kernel >= os_data.big_sur: + return str((kernel - 9)) + else: + return str((f"10.{kernel - 4}")) \ No newline at end of file diff --git a/gui/gui_main.py b/gui/gui_main.py index be66f14c1..54adb587e 100644 --- a/gui/gui_main.py +++ b/gui/gui_main.py @@ -1553,9 +1553,8 @@ class wx_python_gui: if Path(self.constants.installer_pkg_path).exists(): path = utilities.grab_mount_point_from_disk(disk) if Path(path + "/System/Library/CoreServices/SystemVersion.plist").exists(): - kernel_version = plistlib.load(Path(path + "/System/Library/CoreServices/SystemVersion.plist").open("rb")) - kernel_version = kernel_version["ProductBuildVersion"] - kernel_version = kernel_version[:2] # Grab first 2 digits, we can assume the lowest installer to be 10.9 (XNU 13) + os_version = plistlib.load(Path(path + "/System/Library/CoreServices/SystemVersion.plist").open("rb")) + kernel_version = os_data.os_conversion.os_to_kernel(os_version["ProductVersion"]) if int(kernel_version) >= os_data.os_data.big_sur: subprocess.run(["mkdir", "-p", f"{path}/Library/Packages/"]) subprocess.run(["cp", "-r", self.constants.installer_pkg_path, f"{path}/Library/Packages/"]) diff --git a/resources/sys_patch_auto.py b/resources/sys_patch_auto.py index 422100af8..65bd532b2 100644 --- a/resources/sys_patch_auto.py +++ b/resources/sys_patch_auto.py @@ -111,51 +111,55 @@ class AutomaticSysPatch: print("- Determining if macOS drive matches boot drive") - 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["Removable"] is True: - print("- Boot Disk is removable, 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) - else: - print("- Boot Disk is not removable, skipping prompt") - except KeyError: - print("- Unable to determine if boot disk is removable, skipping prompt") - + should_notify = subprocess.run(["defaults", "read", "com.dortania.opencore-legacy-patcher", "AutoPatch_Notify_Mismatched_Disks"], stdout=subprocess.PIPE).stdout.decode("utf-8").strip() + if should_notify in ["0", "false"]: + print("- Skipping due to user preference") else: - print("- Failed to find disk OpenCore launched from") \ No newline at end of file + 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["Removable"] is True: + print("- Boot Disk is removable, 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) + 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") \ No newline at end of file