From c26b9bf91024f3d0b8ad74a5a34a09600dc31cf3 Mon Sep 17 00:00:00 2001 From: Adam Demasi Date: Sat, 3 Apr 2021 16:22:29 +1030 Subject: [PATCH] Use MobileDevice to detect device connected + validate iOS version. --- Betelguese.xcodeproj/project.pbxproj | 33 +- Betelguese/AppDelegate.swift | 6 +- Betelguese/Base.lproj/Main.storyboard | 162 ++++--- Betelguese/Betelguese-Bridging-Header.h | 5 + Betelguese/MobileDevice.h | 545 ++++++++++++++++++++++++ Betelguese/MobileDevice.swift | 95 +++++ Betelguese/MobileDevice.tbd | 332 +++++++++++++++ Betelguese/ViewController.swift | 46 +- 8 files changed, 1145 insertions(+), 79 deletions(-) create mode 100644 Betelguese/Betelguese-Bridging-Header.h create mode 100644 Betelguese/MobileDevice.h create mode 100644 Betelguese/MobileDevice.swift create mode 100644 Betelguese/MobileDevice.tbd diff --git a/Betelguese.xcodeproj/project.pbxproj b/Betelguese.xcodeproj/project.pbxproj index 84048de..4cc357e 100644 --- a/Betelguese.xcodeproj/project.pbxproj +++ b/Betelguese.xcodeproj/project.pbxproj @@ -9,6 +9,8 @@ /* Begin PBXBuildFile section */ 9330C5AC2493D27C0070CB55 /* SDWebImage in Frameworks */ = {isa = PBXBuildFile; productRef = 9330C5AB2493D27C0070CB55 /* SDWebImage */; }; 9330C5AE2493D2A30070CB55 /* AboutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9330C5AD2493D2A30070CB55 /* AboutViewController.swift */; }; + 937A087826182467004A6D0A /* MobileDevice.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 937A087726182467004A6D0A /* MobileDevice.tbd */; }; + 937A087E26182ABE004A6D0A /* MobileDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 937A087D26182ABE004A6D0A /* MobileDevice.swift */; }; 937E90822607041D00B9AD28 /* COPYING.sshpass.txt in Resources */ = {isa = PBXBuildFile; fileRef = 937E90812607041D00B9AD28 /* COPYING.sshpass.txt */; }; 938B18E8249262D8008153AB /* COPYING.libplist.txt in Resources */ = {isa = PBXBuildFile; fileRef = 938B18E6249262D8008153AB /* COPYING.libplist.txt */; }; 938B18E9249262D8008153AB /* COPYING.libusbmuxd.txt in Resources */ = {isa = PBXBuildFile; fileRef = 938B18E7249262D8008153AB /* COPYING.libusbmuxd.txt */; }; @@ -24,6 +26,10 @@ /* Begin PBXFileReference section */ 9330C5AD2493D2A30070CB55 /* AboutViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutViewController.swift; sourceTree = ""; }; + 937A087026181EF9004A6D0A /* MobileDevice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MobileDevice.h; sourceTree = ""; }; + 937A087126181F14004A6D0A /* Betelguese-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Betelguese-Bridging-Header.h"; sourceTree = ""; }; + 937A087726182467004A6D0A /* MobileDevice.tbd */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.text-based-dylib-definition"; path = MobileDevice.tbd; sourceTree = ""; }; + 937A087D26182ABE004A6D0A /* MobileDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MobileDevice.swift; sourceTree = ""; }; 937E90812607041D00B9AD28 /* COPYING.sshpass.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = COPYING.sshpass.txt; sourceTree = ""; }; 938B18E6249262D8008153AB /* COPYING.libplist.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = COPYING.libplist.txt; sourceTree = ""; }; 938B18E7249262D8008153AB /* COPYING.libusbmuxd.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = COPYING.libusbmuxd.txt; sourceTree = ""; }; @@ -45,6 +51,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 937A087826182467004A6D0A /* MobileDevice.tbd in Frameworks */, 9330C5AC2493D27C0070CB55 /* SDWebImage in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -58,7 +65,10 @@ 93A12ED82491C3E200765143 /* Betelguese */, 93A12ED72491C3E200765143 /* Products */, ); + indentWidth = 4; sourceTree = ""; + tabWidth = 4; + usesTabs = 0; }; 93A12ED72491C3E200765143 /* Products */ = { isa = PBXGroup; @@ -76,6 +86,9 @@ 938B18E6249262D8008153AB /* COPYING.libplist.txt */, 938B18E7249262D8008153AB /* COPYING.libusbmuxd.txt */, 937E90812607041D00B9AD28 /* COPYING.sshpass.txt */, + 937A087026181EF9004A6D0A /* MobileDevice.h */, + 937A087726182467004A6D0A /* MobileDevice.tbd */, + 937A087D26182ABE004A6D0A /* MobileDevice.swift */, 93A12ED92491C3E200765143 /* AppDelegate.swift */, 93A12EDB2491C3E200765143 /* ViewController.swift */, 938B18F224939CFA008153AB /* WindowController.swift */, @@ -85,6 +98,7 @@ 93A12EE9249207AA00765143 /* BackgroundImage.swift */, 93A12EE22491C3E600765143 /* Info.plist */, 93A878F825FDB0B400187BCB /* Betelguese.entitlements */, + 937A087126181F14004A6D0A /* Betelguese-Bridging-Header.h */, ); path = Betelguese; sourceTree = ""; @@ -119,11 +133,12 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 1140; - LastUpgradeCheck = 1140; + LastUpgradeCheck = 1240; ORGANIZATIONNAME = "23 Aaron"; TargetAttributes = { 93A12ED52491C3E200765143 = { CreatedOnToolsVersion = 11.4.1; + LastSwiftMigration = 1240; }; }; }; @@ -173,6 +188,7 @@ 93A12EEA249207AA00765143 /* BackgroundImage.swift in Sources */, 938B18F324939CFA008153AB /* WindowController.swift in Sources */, 93A12EDC2491C3E200765143 /* ViewController.swift in Sources */, + 937A087E26182ABE004A6D0A /* MobileDevice.swift in Sources */, 9330C5AE2493D2A30070CB55 /* AboutViewController.swift in Sources */, 93A12EDA2491C3E200765143 /* AppDelegate.swift in Sources */, ); @@ -218,6 +234,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -278,6 +295,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -309,6 +327,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Betelguese/Betelguese.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; @@ -317,8 +336,14 @@ "$(inherited)", "@executable_path/../Frameworks", ); + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Betelguese", + ); PRODUCT_BUNDLE_IDENTIFIER = com.23aaron.Betelgeuse; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Betelguese/Betelguese-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; }; name = Debug; @@ -327,6 +352,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Betelguese/Betelguese.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; @@ -335,8 +361,13 @@ "$(inherited)", "@executable_path/../Frameworks", ); + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Betelguese", + ); PRODUCT_BUNDLE_IDENTIFIER = com.23aaron.Betelgeuse; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Betelguese/Betelguese-Bridging-Header.h"; SWIFT_VERSION = 5.0; }; name = Release; diff --git a/Betelguese/AppDelegate.swift b/Betelguese/AppDelegate.swift index f90318c..9f63911 100644 --- a/Betelguese/AppDelegate.swift +++ b/Betelguese/AppDelegate.swift @@ -11,14 +11,14 @@ import Cocoa @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { - - func applicationDidFinishLaunching(_ aNotification: Notification) { // Insert code here to initialize your application + MobileDeviceHelper.subscribeForDeviceNotifications() } func applicationWillTerminate(_ aNotification: Notification) { // Insert code here to tear down your application + MobileDeviceHelper.handleAppWillTerminate() } func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { @@ -29,6 +29,4 @@ class AppDelegate: NSObject, NSApplicationDelegate { NSWorkspace.shared.open(URL(string: "https://github.com/23aaron/Betelguese/issues")!) } - } - diff --git a/Betelguese/Base.lproj/Main.storyboard b/Betelguese/Base.lproj/Main.storyboard index 450a84d..9504423 100644 --- a/Betelguese/Base.lproj/Main.storyboard +++ b/Betelguese/Base.lproj/Main.storyboard @@ -945,72 +945,105 @@ - - - - - - + + + + + + + - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + - + - - - - - - - + + + @@ -1046,9 +1075,10 @@ + - + diff --git a/Betelguese/Betelguese-Bridging-Header.h b/Betelguese/Betelguese-Bridging-Header.h new file mode 100644 index 0000000..835a0e9 --- /dev/null +++ b/Betelguese/Betelguese-Bridging-Header.h @@ -0,0 +1,5 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + +#include "MobileDevice.h" diff --git a/Betelguese/MobileDevice.h b/Betelguese/MobileDevice.h new file mode 100644 index 0000000..45ecd42 --- /dev/null +++ b/Betelguese/MobileDevice.h @@ -0,0 +1,545 @@ +/* ---------------------------------------------------------------------------- + * MobileDevice.h - interface to MobileDevice.framework + * $LastChangedDate: 2007-07-09 18:59:29 -0700 (Mon, 09 Jul 2007) $ + * + * Copied from http://iphonesvn.halifrag.com/svn/iPhone/ + * With modifications from Allen Porter and Scott Turner + * + * ------------------------------------------------------------------------- */ + +#ifndef MOBILEDEVICE_H +#define MOBILEDEVICE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(WIN32) +#include + typedef unsigned int mach_error_t; +#elif defined(__APPLE__) +#include +#include +#endif + + /* Error codes */ +#define MDERR_APPLE_MOBILE (err_system(0x3a)) +#define MDERR_IPHONE (err_sub(0)) + + /* Apple Mobile (AM*) errors */ +#define MDERR_OK ERR_SUCCESS +#define MDERR_SYSCALL (ERR_MOBILE_DEVICE | 0x01) +#define MDERR_OUT_OF_MEMORY (ERR_MOBILE_DEVICE | 0x03) +#define MDERR_QUERY_FAILED (ERR_MOBILE_DEVICE | 0x04) +#define MDERR_INVALID_ARGUMENT (ERR_MOBILE_DEVICE | 0x0b) +#define MDERR_DICT_NOT_LOADED (ERR_MOBILE_DEVICE | 0x25) + + /* Apple File Connection (AFC*) errors */ +#define MDERR_AFC_OUT_OF_MEMORY 0x03 + + /* USBMux errors */ +#define MDERR_USBMUX_ARG_NULL 0x16 +#define MDERR_USBMUX_FAILED 0xffffffff + + /* Messages passed to device notification callbacks: passed as part of + * am_device_notification_callback_info. */ +#define ADNCI_MSG_CONNECTED 1 +#define ADNCI_MSG_DISCONNECTED 2 +#define ADNCI_MSG_UNKNOWN 3 + +#define AMD_IPHONE_PRODUCT_ID 0x1290 +#define AMD_IPHONE_SERIAL "3391002d9c804d105e2c8c7d94fc35b6f3d214a3" + + /* Services, found in /System/Library/Lockdown/Services.plist */ +#define AMSVC_AFC CFSTR("com.apple.afc") +#define AMSVC_BACKUP CFSTR("com.apple.mobilebackup") +#define AMSVC_CRASH_REPORT_COPY CFSTR("com.apple.crashreportcopy") +#define AMSVC_DEBUG_IMAGE_MOUNT CFSTR("com.apple.mobile.debug_image_mount") +#define AMSVC_NOTIFICATION_PROXY CFSTR("com.apple.mobile.notification_proxy") +#define AMSVC_PURPLE_TEST CFSTR("com.apple.purpletestr") +#define AMSVC_SOFTWARE_UPDATE CFSTR("com.apple.mobile.software_update") +#define AMSVC_SYNC CFSTR("com.apple.mobilesync") +#define AMSVC_SCREENSHOT CFSTR("com.apple.screenshotr") +#define AMSVC_SYSLOG_RELAY CFSTR("com.apple.syslog_relay") +#define AMSVC_SYSTEM_PROFILER CFSTR("com.apple.mobile.system_profiler") + + typedef unsigned int afc_error_t; + typedef unsigned int usbmux_error_t; + typedef unsigned int service_conn_t; + + struct am_recovery_device; + + typedef struct am_device_notification_callback_info { + struct am_device *dev; /* 0 device */ + unsigned int msg; /* 4 one of ADNCI_MSG_* */ + } __attribute__ ((packed)) am_device_notification_callback_info; + + /* The type of the device restore notification callback functions. + * TODO: change to correct type. */ + typedef void (*am_restore_device_notification_callback)(struct + am_recovery_device *); + + /* This is a CoreFoundation object of class AMRecoveryModeDevice. */ + typedef struct am_recovery_device { + unsigned char unknown0[8]; /* 0 */ + am_restore_device_notification_callback callback; /* 8 */ + void *user_info; /* 12 */ + unsigned char unknown1[12]; /* 16 */ + unsigned int readwrite_pipe; /* 28 */ + unsigned char read_pipe; /* 32 */ + unsigned char write_ctrl_pipe; /* 33 */ + unsigned char read_unknown_pipe; /* 34 */ + unsigned char write_file_pipe; /* 35 */ + unsigned char write_input_pipe; /* 36 */ + } __attribute__ ((packed)) am_recovery_device; + + /* A CoreFoundation object of class AMRestoreModeDevice. */ + typedef struct am_restore_device { + unsigned char unknown[32]; + int port; + } __attribute__ ((packed)) am_restore_device; + + /* The type of the device notification callback function. */ + typedef void(*am_device_notification_callback)(struct + am_device_notification_callback_info *, void* arg); + + /* The type of the _AMDDeviceAttached function. + * TODO: change to correct type. */ + typedef void *amd_device_attached_callback; + + + typedef struct am_device { + unsigned char unknown0[16]; /* 0 - zero */ + unsigned int device_id; /* 16 */ + unsigned int product_id; /* 20 - set to AMD_IPHONE_PRODUCT_ID */ + char *serial; /* 24 - set to AMD_IPHONE_SERIAL */ + unsigned int unknown1; /* 28 */ + unsigned char unknown2[4]; /* 32 */ + unsigned int lockdown_conn; /* 36 */ + unsigned char unknown3[8]; /* 40 */ + } __attribute__ ((packed)) am_device; + + typedef struct am_device_notification { + unsigned int unknown0; /* 0 */ + unsigned int unknown1; /* 4 */ + unsigned int unknown2; /* 8 */ + am_device_notification_callback callback; /* 12 */ + unsigned int unknown3; /* 16 */ + } __attribute__ ((packed)) am_device_notification; + + typedef struct afc_connection { + unsigned int handle; /* 0 */ + unsigned int unknown0; /* 4 */ + unsigned char unknown1; /* 8 */ + unsigned char padding[3]; /* 9 */ + unsigned int unknown2; /* 12 */ + unsigned int unknown3; /* 16 */ + unsigned int unknown4; /* 20 */ + unsigned int fs_block_size; /* 24 */ + unsigned int sock_block_size; /* 28: always 0x3c */ + unsigned int io_timeout; /* 32: from AFCConnectionOpen, usu. 0 */ + void *afc_lock; /* 36 */ + unsigned int context; /* 40 */ + } __attribute__ ((packed)) afc_connection; + + typedef struct afc_directory { + unsigned char unknown[0]; /* size unknown */ + } __attribute__ ((packed)) afc_directory; + + typedef struct afc_dictionary { + unsigned char unknown[0]; /* size unknown */ + } __attribute__ ((packed)) afc_dictionary; + + typedef unsigned long long afc_file_ref; + + typedef struct usbmux_listener_1 { /* offset value in iTunes */ + unsigned int unknown0; /* 0 1 */ + unsigned char *unknown1; /* 4 ptr, maybe device? */ + amd_device_attached_callback callback; /* 8 _AMDDeviceAttached */ + unsigned int unknown3; /* 12 */ + unsigned int unknown4; /* 16 */ + unsigned int unknown5; /* 20 */ + } __attribute__ ((packed)) usbmux_listener_1; + + typedef struct usbmux_listener_2 { + unsigned char unknown0[4144]; + } __attribute__ ((packed)) usbmux_listener_2; + + typedef struct am_bootloader_control_packet { + unsigned char opcode; /* 0 */ + unsigned char length; /* 1 */ + unsigned char magic[2]; /* 2: 0x34, 0x12 */ + unsigned char payload[0]; /* 4 */ + } __attribute__ ((packed)) am_bootloader_control_packet; + + /* ---------------------------------------------------------------------------- + * Public routines + * ------------------------------------------------------------------------- */ + + void AMDSetLogLevel(int level); + + /* Registers a notification with the current run loop. The callback gets + * copied into the notification struct, as well as being registered with the + * current run loop. dn_unknown3 gets copied into unknown3 in the same. + * (Maybe dn_unknown3 is a user info parameter that gets passed as an arg to + * the callback?) unused0 and unused1 are both 0 when iTunes calls this. + * In iTunes the callback is located from $3db78e-$3dbbaf. + * + * Returns: + * MDERR_OK if successful + * MDERR_SYSCALL if CFRunLoopAddSource() failed + * MDERR_OUT_OF_MEMORY if we ran out of memory + */ + + mach_error_t AMDeviceNotificationSubscribe(am_device_notification_callback + callback, unsigned int unused0, unsigned int unused1, void* //unsigned int + dn_unknown3, struct am_device_notification **notification); + + /* Connects to the iPhone. Pass in the am_device structure that the + * notification callback will give to you. + * + * Returns: + * MDERR_OK if successfully connected + * MDERR_SYSCALL if setsockopt() failed + * MDERR_QUERY_FAILED if the daemon query failed + * MDERR_INVALID_ARGUMENT if USBMuxConnectByPort returned 0xffffffff + */ + + mach_error_t AMDeviceConnect(struct am_device *device); + + /* Calls PairingRecordPath() on the given device, than tests whether the path + * which that function returns exists. During the initial connect, the path + * returned by that function is '/', and so this returns 1. + * + * Returns: + * 0 if the path did not exist + * 1 if it did + */ + + int AMDeviceIsPaired(struct am_device *device); + + /* iTunes calls this function immediately after testing whether the device is + * paired. It creates a pairing file and establishes a Lockdown connection. + * + * Returns: + * MDERR_OK if successful + * MDERR_INVALID_ARGUMENT if the supplied device is null + * MDERR_DICT_NOT_LOADED if the load_dict() call failed + */ + + mach_error_t AMDeviceValidatePairing(struct am_device *device); + + /* Creates a Lockdown session and adjusts the device structure appropriately + * to indicate that the session has been started. iTunes calls this function + * after validating pairing. + * + * Returns: + * MDERR_OK if successful + * MDERR_INVALID_ARGUMENT if the Lockdown conn has not been established + * MDERR_DICT_NOT_LOADED if the load_dict() call failed + */ + + mach_error_t AMDeviceStartSession(struct am_device *device); + + /* Starts a service and returns a handle that can be used in order to further + * access the service. You should stop the session and disconnect before using + * the service. iTunes calls this function after starting a session. It starts + * the service and the SSL connection. unknown may safely be + * NULL (it is when iTunes calls this), but if it is not, then it will be + * filled upon function exit. service_name should be one of the AMSVC_* + * constants. If the service is AFC (AMSVC_AFC), then the handle is the handle + * that will be used for further AFC* calls. + * + * Returns: + * MDERR_OK if successful + * MDERR_SYSCALL if the setsockopt() call failed + * MDERR_INVALID_ARGUMENT if the Lockdown conn has not been established + */ + + mach_error_t AMDeviceStartService(struct am_device *device, CFStringRef + service_name, service_conn_t *handle, unsigned int * + unknown); + + mach_error_t AMDeviceStartHouseArrestService(struct am_device *device, CFStringRef identifier, void *unknown, service_conn_t *handle, unsigned int *what); + + /* Stops a session. You should do this before accessing services. + * + * Returns: + * MDERR_OK if successful + * MDERR_INVALID_ARGUMENT if the Lockdown conn has not been established + */ + + mach_error_t AMDeviceStopSession(struct am_device *device); + + /* Opens an Apple File Connection. You must start the appropriate service + * first with AMDeviceStartService(). In iTunes, io_timeout is 0. + * + * Returns: + * MDERR_OK if successful + * MDERR_AFC_OUT_OF_MEMORY if malloc() failed + */ + + afc_error_t AFCConnectionOpen(service_conn_t handle, unsigned int io_timeout, + struct afc_connection **conn); + + /* Pass in a pointer to an afc_device_info structure. It will be filled. */ + afc_error_t AFCDeviceInfoOpen(afc_connection *conn, struct + afc_dictionary **info); + + /* Turns debug mode on if the environment variable AFCDEBUG is set to a numeric + * value, or if the file '/AFCDEBUG' is present and contains a value. */ + void AFCPlatformInit(); + + /* Opens a directory on the iPhone. Pass in a pointer in dir to be filled in. + * Note that this normally only accesses the iTunes sandbox/partition as the + * root, which is /var/root/Media. Pathnames are specified with '/' delimiters + * as in Unix style. + * + * Returns: + * MDERR_OK if successful + */ + + afc_error_t AFCDirectoryOpen(afc_connection *conn, const char *path, + struct afc_directory **dir); + + /* Acquires the next entry in a directory previously opened with + * AFCDirectoryOpen(). When dirent is filled with a NULL value, then the end + * of the directory has been reached. '.' and '..' will be returned as the + * first two entries in each directory except the root; you may want to skip + * over them. + * + * Returns: + * MDERR_OK if successful, even if no entries remain + */ + + afc_error_t AFCDirectoryRead(afc_connection *conn/*unsigned int unused*/, struct afc_directory *dir, + char **dirent); + + afc_error_t AFCDirectoryClose(afc_connection *conn, struct afc_directory *dir); + afc_error_t AFCDirectoryCreate(afc_connection *conn, const char *dirname); + afc_error_t AFCRemovePath(afc_connection *conn, const char *dirname); + afc_error_t AFCRenamePath(afc_connection *conn, const char *from, const char *to); + afc_error_t AFCLinkPath(afc_connection *conn, long long int linktype, const char *target, const char *linkname); + + /* Returns the context field of the given AFC connection. */ + unsigned int AFCConnectionGetContext(afc_connection *conn); + + /* Returns the fs_block_size field of the given AFC connection. */ + unsigned int AFCConnectionGetFSBlockSize(afc_connection *conn); + + /* Returns the io_timeout field of the given AFC connection. In iTunes this is + * 0. */ + unsigned int AFCConnectionGetIOTimeout(afc_connection *conn); + + /* Returns the sock_block_size field of the given AFC connection. */ + unsigned int AFCConnectionGetSocketBlockSize(afc_connection *conn); + + /* Closes the given AFC connection. */ + afc_error_t AFCConnectionClose(afc_connection *conn); + + /* Registers for device notifications related to the restore process. unknown0 + * is zero when iTunes calls this. In iTunes, + * the callbacks are located at: + * 1: $3ac68e-$3ac6b1, calls $3ac542(unknown1, arg, 0) + * 2: $3ac66a-$3ac68d, calls $3ac542(unknown1, 0, arg) + * 3: $3ac762-$3ac785, calls $3ac6b2(unknown1, arg, 0) + * 4: $3ac73e-$3ac761, calls $3ac6b2(unknown1, 0, arg) + */ + + unsigned int AMRestoreRegisterForDeviceNotifications( + am_restore_device_notification_callback dfu_connect_callback, + am_restore_device_notification_callback recovery_connect_callback, + am_restore_device_notification_callback dfu_disconnect_callback, + am_restore_device_notification_callback recovery_disconnect_callback, + unsigned int unknown0, + void *user_info); + + /* Causes the restore functions to spit out (unhelpful) progress messages to + * the file specified by the given path. iTunes always calls this right before + * restoring with a path of + * "$HOME/Library/Logs/iPhone Updater Logs/iPhoneUpdater X.log", where X is an + * unused number. + */ + + unsigned int AMRestoreEnableFileLogging(char *path); + + /* Initializes a new option dictionary to default values. Pass the constant + * kCFAllocatorDefault as the allocator. The option dictionary looks as + * follows: + * { + * NORImageType => 'production', + * AutoBootDelay => 0, + * KernelCacheType => 'Release', + * UpdateBaseband => true, + * DFUFileType => 'RELEASE', + * SystemImageType => 'User', + * CreateFilesystemPartitions => true, + * FlashNOR => true, + * RestoreBootArgs => 'rd=md0 nand-enable-reformat=1 -progress' + * BootImageType => 'User' + * } + * + * Returns: + * the option dictionary if successful + * NULL if out of memory + */ + + CFMutableDictionaryRef AMRestoreCreateDefaultOptions(CFAllocatorRef allocator); + + /* ---------------------------------------------------------------------------- + * Less-documented public routines + * ------------------------------------------------------------------------- */ + + /* mode 2 = read, mode 3 = write */ + afc_error_t AFCFileRefOpen(afc_connection *conn, const char *path, + unsigned long long mode, afc_file_ref *ref); + afc_error_t AFCFileRefSeek(afc_connection *conn, afc_file_ref ref, + unsigned long long offset1, unsigned long long offset2); + afc_error_t AFCFileRefRead(afc_connection *conn, afc_file_ref ref, + void *buf, unsigned int *len); + afc_error_t AFCFileRefSetFileSize(afc_connection *conn, afc_file_ref ref, + unsigned long long offset); + afc_error_t AFCFileRefWrite(afc_connection *conn, afc_file_ref ref, + const void *buf, unsigned int len); + afc_error_t AFCFileRefClose(afc_connection *conn, afc_file_ref ref); + + afc_error_t AFCFileInfoOpen(afc_connection *conn, const char *path, struct + afc_dictionary **info); + afc_error_t AFCKeyValueRead(struct afc_dictionary *dict, char **key, char ** + val); + afc_error_t AFCKeyValueClose(struct afc_dictionary *dict); + + unsigned int AMRestorePerformRecoveryModeRestore(struct am_recovery_device * + rdev, CFDictionaryRef opts, void *callback, void *user_info); + unsigned int AMRestorePerformRestoreModeRestore(struct am_restore_device * + rdev, CFDictionaryRef opts, void *callback, void *user_info); + + struct am_restore_device *AMRestoreModeDeviceCreate(unsigned int unknown0, + unsigned int connection_id, unsigned int unknown1); + + unsigned int AMRestoreCreatePathsForBundle(CFStringRef restore_bundle_path, + CFStringRef kernel_cache_type, CFStringRef boot_image_type, unsigned int + unknown0, CFStringRef *firmware_dir_path, CFStringRef * + kernelcache_restore_path, unsigned int unknown1, CFStringRef * + ramdisk_path); + + unsigned int AMDeviceGetConnectionID(struct am_device *device); + mach_error_t AMDeviceEnterRecovery(struct am_device *device); + mach_error_t AMDeviceDisconnect(struct am_device *device); + mach_error_t AMDeviceRetain(struct am_device *device); + mach_error_t AMDeviceRelease(struct am_device *device); + CFStringRef AMDeviceCopyValue(struct am_device *device, unsigned int, CFStringRef cfstring); + CFStringRef AMDeviceCopyDeviceIdentifier(struct am_device *device); + + typedef void (*notify_callback)(CFStringRef notification, void *data); + + mach_error_t AMDPostNotification(service_conn_t socket, CFStringRef notification, CFStringRef userinfo); + mach_error_t AMDObserveNotification(void *socket, CFStringRef notification); + mach_error_t AMDListenForNotifications(void *socket, notify_callback cb, void *data); + mach_error_t AMDShutdownNotificationProxy(void *socket); + + /*edits by greysyntax*/ + unsigned int AMRecoveryModeDeviceSetAutoBoot(struct am_recovery_device *rdev, CFStringRef state, int unknown1, int unknown2, int unknown3); + unsigned int AMRecoveryModeDeviceReboot(struct am_recovery_device *rdev, CFStringRef state, int unknown1, int unknown2, int unknown3); + /* + _AMRecoveryModeDeviceSetAutoBoot: + +0 000318e5 55 pushl %ebp + +1 000318e6 89e5 movl %esp,%ebp + +3 000318e8 83ec08 subl $0x08,%esp + +6 000318eb 891c24 movl %ebx,(%esp) + +9 000318ee 89742404 movl %esi,0x04(%esp) + +13 000318f2 8b7508 movl 0x08(%ebp),%esi + +16 000318f5 e800000000 calll 0x000318fa + +21 000318fa 5b popl %ebx + +22 000318fb 807d0c01 cmpb $0x01,0x0c(%ebp) + +26 000318ff 750a jne 0x0003190b + +28 00031901 31c9 xorl %ecx,%ecx + +30 00031903 8d939e7d0300 leal 0x00037d9e(%ebx),%edx + +36 00031909 eb08 jmp 0x00031913 + +38 0003190b 31c9 xorl %ecx,%ecx + +40 0003190d 8d93ae7d0300 leal 0x00037dae(%ebx),%edx + +46 00031913 89f0 movl %esi,%eax + +48 00031915 e875f6ffff calll 0x100030f8f + +53 0003191a 85c0 testl %eax,%eax + +55 0003191c 7517 jne 0x00031935 + +57 0003191e 8d93be7d0300 leal 0x00037dbe(%ebx),%edx + +63 00031924 89f0 movl %esi,%eax + +65 00031926 8b1c24 movl (%esp),%ebx + +68 00031929 8b742404 movl 0x04(%esp),%esi + +72 0003192d 31c9 xorl %ecx,%ecx + +74 0003192f c9 leave + +75 00031930 e95af6ffff jmp 0x100030f8f + +80 00031935 8b1c24 movl (%esp),%ebx + +83 00031938 8b742404 movl 0x04(%esp),%esi + +87 0003193c c9 leave + +88 0003193d c3 ret + + + + */ + + + /* + void AMRecoveryModeDeviceSendCommandToDevice + + _AMRecoveryModeDeviceSendCommandToDevice: + +0 00031980 55 pushl %ebp + +1 00031981 31c9 xorl %ecx,%ecx + +3 00031983 89e5 movl %esp,%ebp + +5 00031985 8b4508 movl 0x08(%ebp),%eax + +8 00031988 8b550c movl 0x0c(%ebp),%edx + +11 0003198b c9 leave + +12 0003198c e9fef5ffff jmp 0x100030f8f + + */ + /*end*/ + + /*edits by geohot*/ + mach_error_t AMDeviceDeactivate(struct am_device *device); + mach_error_t AMDeviceActivate(struct am_device *device, CFMutableDictionaryRef); + /*end*/ + + void *AMDeviceSerialize(struct am_device *device); + void AMDAddLogFileDescriptor(int fd); + kern_return_t AMDeviceSendMessage(service_conn_t socket, void *unused, CFPropertyListRef plist); + kern_return_t AMDeviceReceiveMessage(service_conn_t socket, CFDictionaryRef options, CFPropertyListRef * result); + + /* ---------------------------------------------------------------------------- + * Semi-private routines + * ------------------------------------------------------------------------- */ + + /* Pass in a usbmux_listener_1 structure and a usbmux_listener_2 structure + * pointer, which will be filled with the resulting usbmux_listener_2. + * + * Returns: + * MDERR_OK if completed successfully + * MDERR_USBMUX_ARG_NULL if one of the arguments was NULL + * MDERR_USBMUX_FAILED if the listener was not created successfully + */ + + usbmux_error_t USBMuxListenerCreate(struct usbmux_listener_1 *esi_fp8, struct + usbmux_listener_2 **eax_fp12); + + /* ---------------------------------------------------------------------------- + * Less-documented semi-private routines + * ------------------------------------------------------------------------- */ + + usbmux_error_t USBMuxListenerHandleData(void *); + + /* ---------------------------------------------------------------------------- + * Private routines - here be dragons + * ------------------------------------------------------------------------- */ + + /* AMRestorePerformRestoreModeRestore() calls this function with a dictionary + * in order to perform certain special restore operations + * (RESTORED_OPERATION_*). It is thought that this function might enable + * significant access to the phone. */ + + typedef unsigned int (*t_performOperation)(struct am_restore_device *rdev, + CFDictionaryRef op); // __attribute__ ((regparm(2))); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Betelguese/MobileDevice.swift b/Betelguese/MobileDevice.swift new file mode 100644 index 0000000..02f9a5e --- /dev/null +++ b/Betelguese/MobileDevice.swift @@ -0,0 +1,95 @@ +// +// MobileDevice.swift +// Betelguese +// +// Created by Aaron Kingsley on 03/04/2021. +// Copyright © 2021 23 Aaron. All rights reserved. +// + +import Foundation + +enum MDError: mach_error_t { + case ok = 0 +} + +enum AMDeviceNotificationCallbackMessage: UInt32 { + case connected = 1 + case disconnected = 2 + case unknown = 3 +} + +class MobileDeviceHelper { + + static let deviceDidConnectNotification = Notification.Name(rawValue: "MobileDeviceDidConnectNotification") + static let deviceDidDisconnectNotification = Notification.Name(rawValue: "MobileDeviceDidDisconnectNotification") + + static var deviceConnected: UnsafeMutablePointer? + static var deviceName: String? + static var deviceFirmware: String? + + static func subscribeForDeviceNotifications() { + var notificationPointer: UnsafeMutablePointer? = UnsafeMutablePointer.allocate(capacity: 1) + notificationPointer?.pointee = am_device_notification() + + let callback: am_device_notification_callback = { infoPointer, _ in + if let info = infoPointer?.pointee { + MobileDeviceHelper.deviceNotificationReceived(info: info) + } + } + AMDeviceNotificationSubscribe(callback, 0, 0, nil, ¬ificationPointer) + } + + static func handleAppWillTerminate() { + disconnect() + } + + fileprivate static func deviceNotificationReceived(info: am_device_notification_callback_info) { + switch AMDeviceNotificationCallbackMessage(rawValue: info.msg) ?? .unknown { + case .connected: + if info.dev != deviceConnected { + disconnect() + connect(device: info.dev) + } + break + + case .disconnected: + if info.dev == deviceConnected { + disconnect() + } + break + + case .unknown: break + } + } + + private static func connect(device: UnsafeMutablePointer) { + deviceConnected = device + AMDeviceRetain(device) + + let ok = MDError.ok.rawValue + if AMDeviceConnect(device) == ok, + AMDeviceIsPaired(device) == 1, + AMDeviceValidatePairing(device) == ok, + AMDeviceStartSession(device) == ok { + deviceName = AMDeviceCopyValue(device, 0, "DeviceName" as CFString).takeRetainedValue() as String + deviceFirmware = AMDeviceCopyValue(device, 0, "ProductVersion" as CFString).takeRetainedValue() as String + NotificationCenter.default.post(name: self.deviceDidConnectNotification, object: nil) + } else { + NSLog("MobileDevice connection failed?") + } + } + + private static func disconnect() { + guard let device = deviceConnected else { + return + } + + AMDeviceRelease(device) + AMDeviceStopSession(device) + AMDeviceDisconnect(device) + deviceConnected = nil + + NotificationCenter.default.post(name: self.deviceDidDisconnectNotification, object: nil) + } + +} diff --git a/Betelguese/MobileDevice.tbd b/Betelguese/MobileDevice.tbd new file mode 100644 index 0000000..d5c8270 --- /dev/null +++ b/Betelguese/MobileDevice.tbd @@ -0,0 +1,332 @@ +--- !tapi-tbd +tbd-version: 4 +targets: [ x86_64-macos, arm64e-macos ] +uuids: + - target: x86_64-macos + value: FB764B4A-E3CF-377E-85AD-E0309142FBC9 + - target: arm64e-macos + value: CA6BA857-30E6-3230-AFE2-626B51A8AA3D +install-name: '/System/Library/PrivateFrameworks/MobileDevice.framework/Versions/A/MobileDevice' +exports: + - targets: [ x86_64-macos, arm64e-macos ] + symbols: [ _AFCConnectionClose, _AFCConnectionCopyLastErrorInfo, _AFCConnectionCreate, + _AFCConnectionGetContext, _AFCConnectionGetFSBlockSize, _AFCConnectionGetIOTimeout, + _AFCConnectionGetSecureContext, _AFCConnectionGetSocketBlockSize, + _AFCConnectionGetStatus, _AFCConnectionGetTypeID, _AFCConnectionInvalidate, + _AFCConnectionIsValid, _AFCConnectionOpen, _AFCConnectionProcessOperation, + _AFCConnectionProcessOperations, _AFCConnectionScheduleWithRunLoop, + _AFCConnectionSetCallBack, _AFCConnectionSetContext, _AFCConnectionSetDisposeSecureContextOnInvalidate, + _AFCConnectionSetFSBlockSize, _AFCConnectionSetIOTimeout, + _AFCConnectionSetSecureContext, _AFCConnectionSetSocketBlockSize, + _AFCConnectionSubmitOperation, _AFCConnectionUnscheduleFromRunLoop, + _AFCCopyErrorString, _AFCCopyPacketTypeString, _AFCDeviceInfoOpen, + _AFCDirectoryClose, _AFCDirectoryCreate, _AFCDirectoryOpen, + _AFCDirectoryRead, _AFCErrorString, _AFCFileDescriptorCreateCloseOperation, + _AFCFileDescriptorCreateGetPositionOperation, _AFCFileDescriptorCreateLockOperation, + _AFCFileDescriptorCreateReadAtPositionOperation, _AFCFileDescriptorCreateReadOperation, + _AFCFileDescriptorCreateSetImmutableHintOperation, _AFCFileDescriptorCreateSetPositionOperation, + _AFCFileDescriptorCreateSetSizeOperation, _AFCFileDescriptorCreateUnlockOperation, + _AFCFileDescriptorCreateWriteAtPositionOperation, _AFCFileDescriptorCreateWriteOperation, + _AFCFileDescriptorGetTypeID, _AFCFileDescriptorInvalidate, + _AFCFileDescriptorIsValid, _AFCFileInfoOpen, _AFCFileRefClose, + _AFCFileRefLock, _AFCFileRefOpen, _AFCFileRefRead, _AFCFileRefSeek, + _AFCFileRefSetFileSize, _AFCFileRefTell, _AFCFileRefUnlock, + _AFCFileRefWrite, _AFCGetClientVersionString, _AFCKeyValueClose, + _AFCKeyValueRead, _AFCLinkPath, _AFCLog, _AFCOperationCopyPacketData, + _AFCOperationCreateGetConnectionInfo, _AFCOperationCreateGetDeviceInfo, + _AFCOperationCreateGetFileHash, _AFCOperationCreateGetFileHashWithRange, + _AFCOperationCreateGetFileInfo, _AFCOperationCreateGetSizeOfPathContents, + _AFCOperationCreateLinkPath, _AFCOperationCreateMakeDirectory, + _AFCOperationCreateOpenFile, _AFCOperationCreatePacketHeaderDictionary, + _AFCOperationCreateReadDirectory, _AFCOperationCreateRemovePath, + _AFCOperationCreateRemovePathAndContents, _AFCOperationCreateRenamePath, + _AFCOperationCreateSetConnectionOptions, _AFCOperationCreateSetModTime, + _AFCOperationGetContext, _AFCOperationGetResultObject, _AFCOperationGetResultStatus, + _AFCOperationGetState, _AFCOperationGetTypeID, _AFCOperationSetContext, + _AFCPlatformInitialize, _AFCRemovePath, _AFCRenamePath, _AFCSetLogLevel, + _AMAuthInstallApCopyImageTag, _AMAuthInstallApCreateImageProperties, + _AMAuthInstallApCreatePersonalizedResponse, _AMAuthInstallApExtractZippedDeviceMap, + _AMAuthInstallApImg4CopyPayloadType, _AMAuthInstallApImg4CreateServerRequestDictionary, + _AMAuthInstallApImg4CreateStitchTicket, _AMAuthInstallApImg4ForceLocalSigning, + _AMAuthInstallApImg4PersonalizeFile, _AMAuthInstallApImg4SetSepNonce, + _AMAuthInstallApSetNonce, _AMAuthInstallApSetParameters, _AMAuthInstallCreate, + _AMAuthInstallGetLocalizedStatusString, _AMAuthInstallLogSetHandler, + _AMAuthInstallRequestSendSync, _AMAuthInstallSetSigningServerURL, + _AMAuthInstallSsoEnable, _AMAuthInstallSsoInitialize, _AMAuthInstallSupportCompareStringToInt32, + _AMAuthInstallSupportCopyDataFromHexString, _AMAuthInstallSupportCopyURLToNewTempDirectory, + _AMAuthInstallSupportCreateDataFromFileURL, _AMAuthInstallSupportCreateDictionaryFromFileURL, + _AMAuthInstallSupportDictionarySetBoolean, _AMAuthInstallSupportDictionarySetInteger32, + _AMAuthInstallSupportDictionarySetInteger64, _AMAuthInstallSupportFileURLExists, + _AMAuthInstallSupportGetLibraryVersionString, _AMAuthInstallSupportMakeDirectory, + _AMDCopyArrayOfDevicesMatchingQuery, _AMDCopyAuthenticationIdentityForDevice, + _AMDCopyErrorText, _AMDCopySystemBonjourUniqueID, _AMDCopyUDIDForPairingIdentity, + _AMDCreateDeviceList, _AMDErrorForMobileInstallationCallbackDict, + _AMDErrorString, _AMDFUModeDeviceCopyAPNonce, _AMDFUModeDeviceCopyAuthInstallPreflightOptions, + _AMDFUModeDeviceCopyBoardConfig, _AMDFUModeDeviceCopyEcid, + _AMDFUModeDeviceCopySEPNonce, _AMDFUModeDeviceGetBoardID, + _AMDFUModeDeviceGetChipID, _AMDFUModeDeviceGetECID, _AMDFUModeDeviceGetEffectiveProductionMode, + _AMDFUModeDeviceGetEffectiveSecurityMode, _AMDFUModeDeviceGetImage4Aware, + _AMDFUModeDeviceGetLocationID, _AMDFUModeDeviceGetOperation, + _AMDFUModeDeviceGetProductID, _AMDFUModeDeviceGetProductType, + _AMDFUModeDeviceGetProductionMode, _AMDFUModeDeviceGetProgress, + _AMDFUModeDeviceGetSecurityDomain, _AMDFUModeDeviceGetSecurityEpoch, + _AMDFUModeDeviceGetSecurityMode, _AMDFUModeDeviceGetTypeID, + _AMDFUModeDeviceIsBootstrapOnly, _AMDFUModeDeviceRequestAbbreviatedSendSync, + _AMDFUModeDeviceResetAuthInstallSettings, _AMDGetBundleVersion, + _AMDGetPairingRecordDirectoryPath, _AMDListenForNotifications, + _AMDObserveNotification, _AMDPostNotification, _AMDSecureListenForNotifications, + _AMDSecureListenForNotificationsWithRetainedContext, _AMDSecureObserveNotification, + _AMDSecurePostNotification, _AMDSecureShutdownNotificationProxy, + _AMDServiceConnectionBufferedReadSize, _AMDServiceConnectionCreate, + _AMDServiceConnectionGetSecureIOContext, _AMDServiceConnectionGetSocket, + _AMDServiceConnectionGetTypeID, _AMDServiceConnectionInvalidate, + _AMDServiceConnectionReceive, _AMDServiceConnectionReceiveMessage, + _AMDServiceConnectionSend, _AMDServiceConnectionSendMessage, + _AMDServiceConnectionSetDevice, _AMDServiceConnectionSetServiceName, + _AMDSetLogLevel, _AMDShutdownNotificationProxy, _AMDeviceActivate, + _AMDeviceActivateWithOptions, _AMDeviceArchiveApplication, + _AMDeviceCheckCapabilitiesMatch, _AMDeviceConnect, _AMDeviceCopyAuthInstallPreflightOptions, + _AMDeviceCopyCryptexNonce, _AMDeviceCopyDeviceIdentifier, + _AMDeviceCopyDeviceLocation, _AMDeviceCopyDeviceUSBSerialNumber, + _AMDeviceCopyFDRPreflightOptions, _AMDeviceCopyMountedDevicesList, + _AMDeviceCopyMultipleValuesWithError, _AMDeviceCopyPairedCompanion, + _AMDeviceCopyPairedWatch, _AMDeviceCopyPersonalizationNonce, + _AMDeviceCopyProvisioningProfiles, _AMDeviceCopyValue, _AMDeviceCopyValueWithError, + _AMDeviceCreate, _AMDeviceCreateActivationInfo, _AMDeviceCreateActivationInfoWithOptions, + _AMDeviceCreateActivationSessionInfo, _AMDeviceCreateCopy, + _AMDeviceCreateFromProperties, _AMDeviceCreateHouseArrestService, + _AMDeviceCreateSRPConnection, _AMDeviceCreateWakeupToken, + _AMDeviceDeactivate, _AMDeviceDeleteHostPairingRecordForUDID, + _AMDeviceDisconnect, _AMDeviceEnterRecovery, _AMDeviceExtendedPairWithOptions, + _AMDeviceGetConnectionID, _AMDeviceGetInterfaceSpeed, _AMDeviceGetInterfaceType, + _AMDeviceGetLocalOrRemoteOffsetToResume, _AMDeviceGetName, + _AMDeviceGetTypeID, _AMDeviceGetUserInfo, _AMDeviceGetWirelessBuddyFlags, + _AMDeviceImageMounted, _AMDeviceInstallApplication, _AMDeviceInstallProvisioningProfile, + _AMDeviceIsAtLeastVersionOnPlatform, _AMDeviceIsPaired, _AMDeviceIsValid, + _AMDeviceIsWiFiPairableRef, _AMDeviceLookupApplicationArchives, + _AMDeviceLookupApplications, _AMDeviceMountImage, _AMDeviceMountImageOnHost, + _AMDeviceMountPersonalizedBundle, _AMDeviceNotificationSubscribe, + _AMDeviceNotificationSubscribeWithOptions, _AMDeviceNotificationUnsubscribe, + _AMDevicePair, _AMDevicePairWithCallback, _AMDevicePairWithOptions, + _AMDevicePowerAssertionCreate, _AMDevicePowerAssertionGetTypeID, + _AMDevicePreflightOperationCreate, _AMDevicePreflightOperationGetRunLoopSource, + _AMDevicePreflightOperationGetTypeID, _AMDevicePreflightOperationInvalidate, + _AMDeviceRegisterForCUNotificationsWithOptions, _AMDeviceRegisterForCUStateNotificationsWithOptions, + _AMDeviceRelayFile, _AMDeviceRelease, _AMDeviceRemoteCopyCryptexNonce, + _AMDeviceRemoteCopyMountedDevicesList, _AMDeviceRemoteCopyPersonalizationNonce, + _AMDeviceRemoteImageMounted, _AMDeviceRemoteImageMountedMacOS, + _AMDeviceRemoteMountImage, _AMDeviceRemoteMountImageMacOS, + _AMDeviceRemoteMountPersonalizedBundle, _AMDeviceRemoteRollCryptexNonce, + _AMDeviceRemoteRollPersonalizationNonce, _AMDeviceRemoteUnmountImage, + _AMDeviceRemoveApplicationArchive, _AMDeviceRemoveProvisioningProfile, + _AMDeviceRemoveValue, _AMDeviceRequestAbbreviatedSendSync, + _AMDeviceRestoreApplication, _AMDeviceRetain, _AMDeviceRollCryptexNonce, + _AMDeviceRollPersonalizationNonce, _AMDeviceSecureArchiveApplication, + _AMDeviceSecureCheckCapabilitiesMatch, _AMDeviceSecureInstallApplication, + _AMDeviceSecureInstallApplicationBundle, _AMDeviceSecureRemoveApplicationArchive, + _AMDeviceSecureRestoreApplication, _AMDeviceSecureStartService, + _AMDeviceSecureTransferPath, _AMDeviceSecureUninstallApplication, + _AMDeviceSecureUpgradeApplication, _AMDeviceSetUserInfo, _AMDeviceSetValue, + _AMDeviceSetWirelessBuddyFlags, _AMDeviceStartHouseArrestService, + _AMDeviceStartService, _AMDeviceStartServiceWithOptions, _AMDeviceStartSession, + _AMDeviceStopSession, _AMDeviceTransferApplication, _AMDeviceTransferPath, + _AMDeviceUSBDeviceID, _AMDeviceUSBLocationID, _AMDeviceUSBProductID, + _AMDeviceUninstallApplication, _AMDeviceUnmountImage, _AMDeviceUnmountImageOnHost, + _AMDeviceUnpair, _AMDeviceUpgradeApplication, _AMDeviceValidatePairing, + _AMDeviceVerifySRPConnection, _AMDeviceWakeupOperationCreateWithToken, + _AMDeviceWakeupOperationGetTypeID, _AMDeviceWakeupOperationInvalidate, + _AMDeviceWakeupOperationSchedule, _AMDeviceWakeupUsingToken, + _AMRAuthInstallCopyLocalizedStringForServerError, _AMRAuthInstallCopyPreflightOptions, + _AMRAuthInstallCreateOptionsForBootstrapDevice, _AMRAuthInstallFinalize, + _AMRAuthInstallPreflight, _AMRLocalizedCopyStringForAMRError, + _AMRLocalizedCopyStringForAMROperation, _AMRLog, _AMRLogv, + _AMRecoveryModeDeviceCopyAPNonce, _AMRecoveryModeDeviceCopyAuthInstallPreflightOptions, + _AMRecoveryModeDeviceCopyBoardConfig, _AMRecoveryModeDeviceCopyEcid, + _AMRecoveryModeDeviceCopyEnvironmentVariableFromDevice, _AMRecoveryModeDeviceCopyIMEI, + _AMRecoveryModeDeviceCopySEPNonce, _AMRecoveryModeDeviceCopySerialNumber, + _AMRecoveryModeDeviceCreateWithIOService, _AMRecoveryModeDeviceGetBoardID, + _AMRecoveryModeDeviceGetChipID, _AMRecoveryModeDeviceGetECID, + _AMRecoveryModeDeviceGetEffectiveProductionMode, _AMRecoveryModeDeviceGetEffectiveSecurityMode, + _AMRecoveryModeDeviceGetLocationID, _AMRecoveryModeDeviceGetProductID, + _AMRecoveryModeDeviceGetProductType, _AMRecoveryModeDeviceGetProductionMode, + _AMRecoveryModeDeviceGetProgress, _AMRecoveryModeDeviceGetSecurityDomain, + _AMRecoveryModeDeviceGetSecurityEpoch, _AMRecoveryModeDeviceGetSecurityMode, + _AMRecoveryModeDeviceGetSupportedImageFormat, _AMRecoveryModeDeviceGetTypeID, + _AMRecoveryModeDeviceIsBootstrapOnly, _AMRecoveryModeDeviceReboot, + _AMRecoveryModeDeviceRequestAbbreviatedSendSync, _AMRecoveryModeDeviceSendBlindCommandToDevice, + _AMRecoveryModeDeviceSendCommandToDevice, _AMRecoveryModeDeviceSendFileToDevice, + _AMRecoveryModeDeviceSetAutoBoot, _AMRecoveryModeGetSoftwareBuildVersion, + _AMRestorableAttemptMuxRegistration, _AMRestorableBuildCopyRestoreBundleURL, + _AMRestorableBuildCopySupportedBoardConfigs, _AMRestorableBuildCopySupportedVariants, + _AMRestorableBuildCreate, _AMRestorableCommitStashBag, _AMRestorableCommitStashBagWithManifest, + _AMRestorableCommitStashBagWithRestoreOptions, _AMRestorableDeviceCopyAMDevice, + _AMRestorableDeviceCopyAuthInstallPreflightOptions, _AMRestorableDeviceCopyBoardConfig, + _AMRestorableDeviceCopyDFUModeDevice, _AMRestorableDeviceCopyDefaultRestoreOptions, + _AMRestorableDeviceCopyEnvironmentVariable, _AMRestorableDeviceCopyMDRemoteServiceDevice, + _AMRestorableDeviceCopyProductString, _AMRestorableDeviceCopyRecoveryModeDevice, + _AMRestorableDeviceCopyRestoreModeDevice, _AMRestorableDeviceCopyRestoreOptionsFromDocument, + _AMRestorableDeviceCopySerialDevicePath, _AMRestorableDeviceCopySerialDeviceSWDName, + _AMRestorableDeviceCopySerialNumber, _AMRestorableDeviceCopyUserFriendlyName, + _AMRestorableDeviceCreateFromAMDevice, _AMRestorableDeviceEnableExtraDFUDevices, + _AMRestorableDeviceGetBoardID, _AMRestorableDeviceGetChipID, + _AMRestorableDeviceGetDFUModeDevice, _AMRestorableDeviceGetDeviceClass, + _AMRestorableDeviceGetDeviceMapEntryForBoardAndChipID, _AMRestorableDeviceGetECID, + _AMRestorableDeviceGetFusingInfo, _AMRestorableDeviceGetLocationID, + _AMRestorableDeviceGetProductID, _AMRestorableDeviceGetProductType, + _AMRestorableDeviceGetRecoveryModeDevice, _AMRestorableDeviceGetRestoreOperationsQueue, + _AMRestorableDeviceGetState, _AMRestorableDeviceGetTypeID, + _AMRestorableDeviceIsInDeviceClass, _AMRestorableDeviceNeedsUpdatedFramework, + _AMRestorableDeviceRegisterForNotifications, _AMRestorableDeviceRegisterForNotificationsForDevices, + _AMRestorableDeviceRestore, _AMRestorableDeviceRestoreWithError, + _AMRestorableDeviceSendBlindCommand, _AMRestorableDeviceSendCommand, + _AMRestorableDeviceSendFile, _AMRestorableDeviceSetLogFileURL, + _AMRestorableDeviceSetProxyCredentialsCallback, _AMRestorableDeviceTriggerUpdateForBoardAndChipIDWithPrompt, + _AMRestorableDeviceTriggerUpdateForDeviceWithPrompt, _AMRestorableDeviceUnregisterForNotifications, + _AMRestorableDeviceUpdateAvailableForBoardAndChipID, _AMRestorableDeviceUpdateAvailableForDevice, + _AMRestorableEnableLogStreaming, _AMRestorableGetCheckpointData, + _AMRestorableGetIdentifyingErrorCode, _AMRestorableLogToFile, + _AMRestorablePersonalizeCopyManifestTag, _AMRestorablePersonalizeSendFile, + _AMRestorableSetCheckpointData, _AMRestorableSetGlobalLocationIDFilter, + _AMRestorableSetGlobalLogFileURL, _AMRestorableSetLogLevel, + _AMRestoreCopyNormalizedBoardConfig, _AMRestoreCopySystemRestoreImagePath, + _AMRestoreCreateBootArgsByAddingArg, _AMRestoreCreateBootArgsByRemovingArg, + _AMRestoreCreateDefaultOptions, _AMRestoreCreatePathsForBundle, + _AMRestoreDeviceGetFwImages, _AMRestoreDisableFileLogging, + _AMRestoreEnableExtraDFUDevices, _AMRestoreEnableFileLogging, + _AMRestoreGetSupportedPayloadVersion, _AMRestoreLogFilePaths, + _AMRestoreModeCopyDeviceInfo, _AMRestoreModeDeviceCopyBoardConfig, + _AMRestoreModeDeviceCopyEcid, _AMRestoreModeDeviceCopyIMEI, + _AMRestoreModeDeviceCopyMarketingPartNumber, _AMRestoreModeDeviceCopyRestoreLog, + _AMRestoreModeDeviceCopySerialNumber, _AMRestoreModeDeviceCreate, + _AMRestoreModeDeviceGetDeviceID, _AMRestoreModeDeviceGetLocationID, + _AMRestoreModeDeviceGetProgress, _AMRestoreModeDeviceGetTypeID, + _AMRestoreModeDeviceReboot, _AMRestoreModeGetLastFailureLog, + _AMRestorePerformDFURestore, _AMRestorePerformRecoveryModeRestore, + _AMRestorePerformRestoreModeRestore, _AMRestorePerformRestoreModeRestoreWithError, + _AMRestoreRegisterForDeviceNotifications, _AMRestoreScrubLogs, + _AMRestoreSetLogLevel, _AMRestoreUnregisterForDeviceNotifications, + _AMRestoreUseFactoryLoggingFormat, _AMSArchiveBackup, _AMSBackupWithOptions, + _AMSBeginSync, _AMSBeginSyncForDataClasses, _AMSCancelBackupRestore, + _AMSCancelCrashReportCopy, _AMSCancelSync, _AMSChangeBackupPassword, + _AMSCleanup, _AMSClearDataClasses, _AMSConnectToCrashReportCopyTarget, + _AMSCopyApplicationListFromBackup, _AMSCopyCrashReportPath, + _AMSCopyCrashReportsFromTarget, _AMSCopySourcesForRestoreCompatibleWith, + _AMSDisconnectFromCrashReportCopyTarget, _AMSEnableCloudBackup, + _AMSEnableSyncServices, _AMSEraseDevice, _AMSGetBackupInfo, + _AMSGetBackupPasswordFromKeychainForTarget, _AMSGetCalendarDayLimit, + _AMSGetClientIdentifierAndDisplayNameForTarget, _AMSGetCollectionsForDataClassName, + _AMSGetCrashReportCopyPreferencesForTarget, _AMSGetDataClassInfoForTarget, + _AMSGetLastSyncDateForDataClass, _AMSGetNewRecordCalendarName, + _AMSGetNewRecordGroupName, _AMSGetNumberOfCrashReportsToCopy, + _AMSGetNumberOfCrashReportsToSubmit, _AMSGetSourcesForRestore, + _AMSGetSupportedDataClassNames, _AMSInitialize, _AMSIsSyncServicesEnabled, + _AMSProcessLinkExitChild, _AMSProcessLinkInitializeChild, + _AMSProcessLinkInvalidate, _AMSProcessLinkReadMessageFromChild, + _AMSProcessLinkRelease, _AMSProcessLinkRetain, _AMSProcessLinkRunChild, + _AMSProcessLinkSendMessage, _AMSProcessLinkSendMessageAsync, + _AMSProcessLinkSendMessageLock, _AMSProcessLinkSendMessageToParent, + _AMSRegisterClientWithTargetIdentifierAndDisplayName, _AMSResetSyncData, + _AMSRestoreWithApplications, _AMSSetBackupPasswordInKeychain, + _AMSSetCalendarDayLimit, _AMSSetCrashReportCopyPreferencesForTarget, + _AMSSetDataClassInfoForTarget, _AMSSetFilteredCollectionNamesForDataClassName, + _AMSSetNewRecordCalendarName, _AMSSetNewRecordGroupName, _AMSSubmitCrashReportsFromTarget, + _AMSSubmitRestoreLogFromPath, _AMSUnregisterTarget, _AMSupportCreateDataFromFileURL, + _AMSupportCreateDigest, _AMSupportCreateErrorInternal, _AMSupportCreateURLFromString, + _AMSupportHttpCreateDataFromURL, _AMSupportSafeFree, _AMSupportSafeRelease, + _AMSupportWriteDataToFileURL, _ASRServerHandleConnection, + _ASRServerHandleSlurp, _DERDecodeItemPartialBuffer, _DERParseInteger, + _MDRemoteServiceDeviceGetPropertyDictionary, _MDRemoteServiceDeviceGetTypeID, + _MISCopyErrorStringForErrorCode, _MISEntitlementDictionaryAllowsEntitlementValue, + _MISProfileCopyPayload, _MISProfileCopySignerSubjectSummary, + _MISProfileCreate, _MISProfileCreateDataRepresentation, _MISProfileCreateForProvisioning, + _MISProfileCreateMutableCopy, _MISProfileCreateWithData, _MISProfileCreateWithFile, + _MISProfileGetTypeID, _MISProfileGetValue, _MISProfileIsMutable, + _MISProfileRemoveValue, _MISProfileSetPayload, _MISProfileSetValue, + _MISProfileSignWithKeyAndCertificates, _MISProfileSignWithRSACallBack, + _MISProfileValidateSignature, _MISProfileValidateSignatureWithAnchors, + _MISProfileValidateSignatureWithAnchorsAndPolicy, _MISProfileWriteToFile, + _MISProvisioningProfileAddDeveloperCertificate, _MISProvisioningProfileAddEntitlement, + _MISProvisioningProfileAddProvisionedDevice, _MISProvisioningProfileCheckValidity, + _MISProvisioningProfileCopyApplicationIdentifierPrefixes, + _MISProvisioningProfileCreateMutableCopy, _MISProvisioningProfileGetCreationDate, + _MISProvisioningProfileGetDeveloperCertificates, _MISProvisioningProfileGetEntitlements, + _MISProvisioningProfileGetExpirationDate, _MISProvisioningProfileGetName, + _MISProvisioningProfileGetProvisionedDevices, _MISProvisioningProfileGetTeamIdentifier, + _MISProvisioningProfileGetUUID, _MISProvisioningProfileGetVersion, + _MISProvisioningProfileGrantsEntitlement, _MISProvisioningProfileIncludesDevice, + _MISProvisioningProfileIncludesPlatform, _MISProvisioningProfileIsAppleInternalProfile, + _MISProvisioningProfileIsForLocalProvisioning, _MISProvisioningProfileProvisionsAllDevices, + _MISProvisioningProfileSetApplicationIdentifierPrefixes, _MISProvisioningProfileSetDeveloperCertificates, + _MISProvisioningProfileSetName, _MISProvisioningProfileSetProvisionsAllDevices, + _MISProvisioningProfileSetTimeToLive, _MISProvisioningProfileValidateSignature, + _ProcessLinkSetupParent, _RCGetSystemPartitionExtrasSizeForDevice, + _RPCreateSocksProxyForDeviceRef, _RPSocksProxyInvalidate, + _RPSocksProxySetDoneCallback, _RPSocksProxyStart, _RestoreCheckpointCreateCheckpointFingerprint, + _RestoreCheckpointDataCreate, _RestoreCheckpointGetCheckpointStatements, + _RestoreCheckpointGetCheckpointWarnings, _RestoreCheckpointGetLastCheckpointError, + _RestoreCheckpointGetLastCheckpointID, _RestoreCheckpointGetLastCheckpointResult, + _SZArchiverConvertZipArchiveToStreamable, _SZArchiverCreateStreamableZip, + _SZArchiverExtractFile, _SZConduitSendPath, _SZConduitSendPathWithPreflight, + _USBMuxConnectByPort, _USBMuxCopyDeviceArray, _USBMuxListenForDevices, + _USBMuxListenerClose, _USBMuxListenerCreate, _USBMuxListenerCreateFiltered, + _USBMuxListenerGetRunLoopSource, _USBMuxListenerSetDebug, + __AMRestorableDeviceCopyBoardConfigNoLocking, __AMRestorableDeviceGetECIDNoLocking, + __AMRestorableDeviceGetLocationIDNoLocking, __AMRestorableDeviceGetProxy, + __AMRestorableDeviceSendBlindCommandNoLocking, __AMRestorableDeviceSendCommandNoLocking, + __AMRestorableDeviceSendFileNoLocking, __AMRestorableGetEventQueue, + __AMRestorableGetStateForString, __AMRestorableGetStringForState, + __AMSGetErrorReasonForErrorCode, __CreateBonjourDeviceDescriptions, + __FinalizeMobileDevice, __InitializeMobileDevice, __ensureDirectoryExists, + __logData, __readDictionary, __runBackupTool, __sendMessage, + __writeDictionary, _kAFCErrorCodeKey, _kAFCErrorDebugDescriptionKey, + _kAFCErrorDescriptionKey, _kAFCErrorDomain, _kAFCErrorDomainKey, + _kAFCErrorExtendedInfoKey, _kAFCErrorFileLineKey, _kAFCErrorFileNameKey, + _kAFCErrorLocalizedDescriptionKey, _kAFCErrorLocalizedFailureReasonKey, + _kAFCErrorLocalizedRecoverySuggestionKey, _kAFCErrorUnderlyingErrorKey, + _kAFCErrorVersionKey, _kAFCHeaderKeyHeaderLength, _kAFCHeaderKeyPacketData, + _kAFCHeaderKeyPacketID, _kAFCHeaderKeyPacketLength, _kAFCHeaderKeyPacketType, + _kAFCHeaderKeySignature, _kAMAuthInstallApParameterAllowMixAndMatch, + _kAMAuthInstallApParameterBoardID, _kAMAuthInstallApParameterChipID, + _kAMAuthInstallApParameterECID, _kAMAuthInstallApParameterEffectiveProductionMode, + _kAMAuthInstallApParameterEffectiveSecurityMode, _kAMAuthInstallApParameterProductionMode, + _kAMAuthInstallApParameterSecurityDomain, _kAMAuthInstallApParameterSecurityMode, + _kAMAuthInstallApParameterSupportsImg4, _kAMAuthInstallBuildIdentityApDiagsKey, + _kAMAuthInstallBuildIdentityApOSKey, _kAMAuthInstallBuildIdentityApRecoveryOSDeviceTreeKey, + _kAMAuthInstallBuildIdentityApRecoveryOSKernelCacheKey, _kAMAuthInstallBuildIdentityApRecoveryOSKey, + _kAMAuthInstallBuildIdentityApRecoveryOSLogoKey, _kAMAuthInstallBuildIdentityApRecoveryOSStaticTrustCacheKey, + _kAMAuthInstallBuildIdentityApRecoveryOSiBECKey, _kAMAuthInstallBuildIdentityApRestoreDeviceTreeKey, + _kAMAuthInstallBuildIdentityApRestoreKernelCacheKey, _kAMAuthInstallBuildIdentityApRestoreRamDiskKey, + _kAMAuthInstallBuildIdentityBpBasebandFirmwareKey, _kAMRestorableInvalidClientID, + _kSZArchiverCompressionMethodDEFLATE, _kSZArchiverCompressionMethodLZFSE, + _kSZArchiverCompressionMethodLZMA, _kSZArchiverCompressionOptionForceUncompressed, + _kSZArchiverCompressionOptionPreserveCompression, _kSZArchiverCompressionOptionTryRecompress, + _kSZArchiverHashTypeMD2, _kSZArchiverHashTypeMD4, _kSZArchiverHashTypeMD5, + _kSZArchiverHashTypeSHA1, _kSZArchiverHashTypeSHA224, _kSZArchiverHashTypeSHA256, + _kSZArchiverHashTypeSHA384, _kSZArchiverHashTypeSHA512, _kSZArchiverOptionCommandLineString, + _kSZArchiverOptionCompressionMethod, _kSZArchiverOptionCompressionOptions, + _kSZArchiverOptionExecutableUUID, _kSZArchiverOptionHashType, + _kSZArchiverOptionHashedChunkSize, _kSZArchiverOptionNoCache, + _kSZArchiverOptionNoCentralDirectory, _kSZArchiverOptionNoSeekOutput, + _kSZArchiverOptionSkipPrescan, _kSZArchiverOptionUncompressBloatedFiles, + _kSZArchiverOptionZlibCompressionLevel, _kSZArchiverPreflightTargetPathMode, + _kSZArchiverPreflightTotalFileCount, _kSZArchiverPreflightTotalFileSize, + _kSZArchiverStatsCentralDirectorySize, _kSZArchiverStatsCountCompressMethodDeflated, + _kSZArchiverStatsCountCompressMethodLZFSE, _kSZArchiverStatsCountCompressMethodLZMA, + _kSZArchiverStatsCountCompressMethodOther, _kSZArchiverStatsCountCompressMethodStored, + _kSZArchiverStatsCountDirectories, _kSZArchiverStatsCountRegularFiles, + _kSZArchiverStatsCountSymlinks, _kSZArchiverStatsCountZeroByteFiles, + _kSZArchiverStatsExecutableSize, _kSZArchiverStatsExpectedStreamStopOffset, + _kSZArchiverStatsItemCount, _kSZArchiverStatsItemsConvertedToUncompressed, + _kSZArchiverStatsItemsLargerWithNewCompressionMethod, _kSZArchiverStatsMaxCompressedSize, + _kSZArchiverStatsMaxUncompressedSize, _kSZArchiverStatsNonStandardPermsItemCount, + _kSZArchiverStatsResultRequiresZip64, _kSZArchiverStatsResultSizeDeltaBytes, + _kSZArchiverStatsResultSizeDeltaPercent, _kSZArchiverStatsTotalBytesRecovered, + _kSZArchiverStatsTotalCompressedSize, _kSZArchiverStatsTotalExtractedSize, + _kSZArchiverStatsTotalFileSize, _kSZArchiverStatsTotalUncompressedSize, + _kSZCompressionLevelKey, _kSZConduitInstallPercentCompleteKey, + _kSZConduitInstallStatusKey, _kSZIconLayoutDataKey, _kSZInstallOptionsDictionaryKey, + _kSZInstallTransferResultKey, _kSZUseFactoryServiceKey, _kSZUserInitiatedTransferKey, + _kUSBMuxPropertyLinkType_USB, _kUSBMuxProperty_DeviceID, _kUSBMuxProperty_LinkType, + _kUSBMuxProperty_LocationID, _kUSBMuxProperty_ProductID, _kUSBMuxProperty_SerialNumber, + _sRunning ] +... diff --git a/Betelguese/ViewController.swift b/Betelguese/ViewController.swift index 137880c..4faf948 100644 --- a/Betelguese/ViewController.swift +++ b/Betelguese/ViewController.swift @@ -13,17 +13,25 @@ class ViewController: NSViewController { @IBOutlet weak var progressBar: NSProgressIndicator! @IBOutlet weak var goButton: NSButton! @IBOutlet weak var statusBox: NSBox! - @IBOutlet var statusLabel: NSTextView! + @IBOutlet var logView: NSTextView! + @IBOutlet var statusLabel: NSTextField! var goTouchBarButton: NSButton! var progressTouchBarLabel: NSTextField! var isBusy = false + override func viewWillAppear() { + super.viewWillAppear() + + NotificationCenter.default.addObserver(self, selector: #selector(self.deviceDidConnect), name: MobileDeviceHelper.deviceDidConnectNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(self.deviceDidDisconnect), name: MobileDeviceHelper.deviceDidDisconnectNotification, object: nil) + } + override func viewDidAppear() { super.viewDidAppear() - self.view.window?.styleMask.remove(NSWindow.StyleMask.resizable) + self.view.window?.styleMask.remove(.resizable) if let windowController = view.window?.windowController as? WindowController { goTouchBarButton = windowController.goTouchBarButton @@ -34,16 +42,36 @@ class ViewController: NSViewController { override func viewDidLoad() { super.viewDidLoad() - - statusBox.cornerRadius = 4 + setStatus("Ready!") - + Timer.scheduledTimer(timeInterval: 1 / 60, target: self, selector: #selector(self.refreshStatus), userInfo: nil, repeats: true) } + + @objc private func deviceDidConnect() { + guard let name = MobileDeviceHelper.deviceName, + let firmware = MobileDeviceHelper.deviceFirmware else { + deviceDidDisconnect() + return + } + + if firmware.compare("12.0") == .orderedAscending { + statusLabel.stringValue = "\(name) (iOS \(firmware)) is not compatible." + goButton.isEnabled = false + } else { + statusLabel.stringValue = "Ready to install on \(name) (iOS \(firmware))" + goButton.isEnabled = !isBusy + } + } + + @objc private func deviceDidDisconnect() { + statusLabel.stringValue = "Connect your device to continue." + goButton.isEnabled = false + } @objc func refreshStatus() { if isBusy { - self.statusLabel.scrollToEndOfDocument(self) + self.logView.scrollToEndOfDocument(self) } } @@ -60,9 +88,9 @@ class ViewController: NSViewController { .foregroundColor: NSColor.white ]) if isLogOutput { - statusLabel.textStorage?.append(attributedString) + logView.textStorage?.append(attributedString) } else { - statusLabel.textStorage?.setAttributedString(attributedString) + logView.textStorage?.setAttributedString(attributedString) } } @@ -95,6 +123,7 @@ class ViewController: NSViewController { isBusy = true setStatus("Downloading…\n") goButton.isEnabled = false + statusLabel.isHidden = true progressBar.startAnimation(nil) let tempDir = URL(fileURLWithPath: NSTemporaryDirectory() + "/odysseyra1n") @@ -172,6 +201,7 @@ class ViewController: NSViewController { } progressBar.stopAnimation(nil) goButton.isEnabled = true + statusLabel.isHidden = false } }