From bdf248ce2697067a44f11faa2f3d1edf3e71fbd5 Mon Sep 17 00:00:00 2001 From: uncor3 Date: Sat, 8 Nov 2025 05:05:17 +0000 Subject: [PATCH] make recovery device support an optional feature --- CMakeLists.txt | 41 +++++++++++++++++++++++++------ src/appcontext.cpp | 16 ++++++++++++ src/appcontext.h | 9 ++++++- src/core/services/init_device.cpp | 9 +++++-- src/devicemanagerwidget.cpp | 13 ++++++---- src/devicemanagerwidget.h | 6 +++++ src/iDescriptor.h | 1 + src/mainwindow.cpp | 8 ++++++ src/mainwindow.h | 2 ++ src/welcomewidget.cpp | 5 +++- 10 files changed, 93 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a41645..a473410 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,9 @@ cmake_minimum_required(VERSION 3.16) project(iDescriptor VERSION 0.1 LANGUAGES CXX) +# Feature options +option(ENABLE_RECOVERY_DEVICE_SUPPORT "Enable recovery device support (requires libirecovery)" ON) + set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) @@ -102,12 +105,18 @@ find_library(TATSU_LIBRARY pkg_check_modules(QRENCODE REQUIRED IMPORTED_TARGET libqrencode) pkg_check_modules(HEIF REQUIRED IMPORTED_TARGET libheif) pkg_check_modules(ZIP REQUIRED IMPORTED_TARGET libzip) -find_library(IRECOVERY_LIBRARY - NAMES irecovery-1.0 - PATHS ${CUSTOM_LIB_PATH} - NO_DEFAULT_PATH - REQUIRED -) + +if(ENABLE_RECOVERY_DEVICE_SUPPORT) + find_library(IRECOVERY_LIBRARY + NAMES irecovery-1.0 + PATHS ${CUSTOM_LIB_PATH} + NO_DEFAULT_PATH + REQUIRED + ) + message(STATUS "Recovery device support enabled") +else() + message(STATUS "Recovery device support disabled") +endif() find_library(USBMUXD_LIBRARY NAMES usbmuxd-2.0 @@ -183,7 +192,14 @@ if(LINUX) ) endif() - +if (NOT ENABLE_RECOVERY_DEVICE_SUPPORT) + list(REMOVE_ITEM PROJECT_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/src/recoverydeviceinfowidget.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/recoverydeviceinfowidget.h + src/recoverydeviceinfowidget.cpp + src/recoverydeviceinfowidget.h + ) +endif() add_subdirectory(lib/airplay) add_subdirectory(lib/ipatool-go) @@ -235,7 +251,6 @@ target_link_libraries(iDescriptor PRIVATE ${IMOBILEDEVICE_LIBRARY} ${IMOBILEDEVICE_GLUE_LIBRARY} ${TATSU_LIBRARY} - ${IRECOVERY_LIBRARY} ${SSL_LIBRARY} ${CRYPTO_LIBRARY} PkgConfig::SSH @@ -253,6 +268,11 @@ target_link_libraries(iDescriptor PRIVATE ZUpdater ) +# Conditionally link libirecovery +if(ENABLE_RECOVERY_DEVICE_SUPPORT) + target_link_libraries(iDescriptor PRIVATE ${IRECOVERY_LIBRARY}) +endif() + target_include_directories(iDescriptor PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/lib/zupdater/src ) @@ -290,6 +310,11 @@ target_compile_definitions(iDescriptor PRIVATE SOURCE_DIR="${CMAKE_SOURCE_DIR}" ) +# Add compile definition for recovery device support +if(ENABLE_RECOVERY_DEVICE_SUPPORT) + target_compile_definitions(iDescriptor PRIVATE ENABLE_RECOVERY_DEVICE_SUPPORT) +endif() + set_target_properties(iDescriptor PROPERTIES ${BUNDLE_ID_OPTION} MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} diff --git a/src/appcontext.cpp b/src/appcontext.cpp index 1d0ba6e..b3b63ba 100644 --- a/src/appcontext.cpp +++ b/src/appcontext.cpp @@ -128,7 +128,11 @@ void AppContext::addDevice(QString udid, idevice_connection_type conn_type, int AppContext::getConnectedDeviceCount() const { +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT return m_devices.size() + m_recoveryDevices.size(); +#else + return m_devices.size(); +#endif } /* @@ -174,6 +178,7 @@ void AppContext::removeDevice(QString _udid) delete device; } +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT void AppContext::removeRecoveryDevice(uint64_t ecid) { if (!m_recoveryDevices.contains(ecid)) { @@ -195,6 +200,7 @@ void AppContext::removeRecoveryDevice(uint64_t ecid) delete deviceInfo->mutex; delete deviceInfo; } +#endif iDescriptorDevice *AppContext::getDevice(const std::string &uuid) { @@ -206,18 +212,25 @@ QList AppContext::getAllDevices() return m_devices.values(); } +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT QList AppContext::getAllRecoveryDevices() { return m_recoveryDevices.values(); } +#endif // Returns whether there are any devices connected (regular or recovery) bool AppContext::noDevicesConnected() const { +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT return (m_devices.isEmpty() && m_recoveryDevices.isEmpty() && m_pendingDevices.isEmpty()); +#else + return (m_devices.isEmpty() && m_pendingDevices.isEmpty()); +#endif } +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT void AppContext::addRecoveryDevice(uint64_t ecid) { iDescriptorInitDeviceResultRecovery res = @@ -242,6 +255,7 @@ void AppContext::addRecoveryDevice(uint64_t ecid) emit recoveryDeviceAdded(recoveryDevice); emit deviceChange(); } +#endif AppContext::~AppContext() { @@ -256,11 +270,13 @@ AppContext::~AppContext() delete device; } +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT for (auto recoveryDevice : m_recoveryDevices) { emit recoveryDeviceRemoved(recoveryDevice->ecid); delete recoveryDevice->mutex; delete recoveryDevice; } +#endif } void AppContext::setCurrentDeviceSelection(const DeviceSelection &selection) diff --git a/src/appcontext.h b/src/appcontext.h index f138cc0..3ba8c26 100644 --- a/src/appcontext.h +++ b/src/appcontext.h @@ -34,8 +34,9 @@ public: explicit AppContext(QObject *parent = nullptr); bool noDevicesConnected() const; - // Returns whether there are any devices connected (regular or recovery) +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT QList getAllRecoveryDevices(); +#endif ~AppContext(); int getConnectedDeviceCount() const; @@ -44,7 +45,9 @@ public: private: QMap m_devices; +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT QMap m_recoveryDevices; +#endif QStringList m_pendingDevices; DeviceSelection m_currentSelection = DeviceSelection(""); signals: @@ -52,8 +55,10 @@ signals: void deviceRemoved(const std::string &udid); void devicePaired(iDescriptorDevice *device); void devicePasswordProtected(const QString &udid); +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT void recoveryDeviceAdded(const iDescriptorRecoveryDevice *deviceInfo); void recoveryDeviceRemoved(uint64_t ecid); +#endif void devicePairPending(const QString &udid); void devicePairingExpired(const QString &udid); void systemSleepStarting(); @@ -71,8 +76,10 @@ public slots: void removeDevice(QString udid); void addDevice(QString udid, idevice_connection_type connType, AddType addType); +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT void addRecoveryDevice(uint64_t ecid); void removeRecoveryDevice(uint64_t ecid); +#endif }; #endif // APPCONTEXT_H diff --git a/src/core/services/init_device.cpp b/src/core/services/init_device.cpp index 24577a0..3076d06 100644 --- a/src/core/services/init_device.cpp +++ b/src/core/services/init_device.cpp @@ -20,7 +20,9 @@ #include "../../devicedatabase.h" #include "../../iDescriptor.h" #include "../../servicemanager.h" +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT #include "libirecovery.h" +#endif #include #include #include @@ -274,6 +276,8 @@ DeviceInfo fullDeviceInfo(const pugi::xml_document &doc, d.rawProductType = rawProductType; d.jailbroken = detect_jailbroken(afcClient); d.is_iPhone = safeGet("DeviceClass") == "iPhone"; + d.serialNumber = safeGet("SerialNumber"); + d.mobileEquipmentIdentifier = safeGet("MobileEquipmentIdentifier"); /*BatteryInfo*/ plist_t diagnostics = nullptr; @@ -426,7 +430,7 @@ cleanup: return result; } - +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT iDescriptorInitDeviceResultRecovery init_idescriptor_recovery_device(uint64_t ecid) { @@ -485,4 +489,5 @@ cleanup: } return result; -} \ No newline at end of file +} +#endif // ENABLE_RECOVERY_DEVICE_SUPPORT \ No newline at end of file diff --git a/src/devicemanagerwidget.cpp b/src/devicemanagerwidget.cpp index c0f44ae..dacda8c 100644 --- a/src/devicemanagerwidget.cpp +++ b/src/devicemanagerwidget.cpp @@ -21,7 +21,9 @@ #include "appcontext.h" #include "devicemenuwidget.h" #include "devicependingwidget.h" +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT #include "recoverydeviceinfowidget.h" +#endif #include "settingsmanager.h" #include @@ -80,6 +82,7 @@ DeviceManagerWidget::DeviceManagerWidget(QWidget *parent) emit updateNoDevicesConnected(); }); +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT connect(AppContext::sharedInstance(), &AppContext::recoveryDeviceAdded, this, [this](const iDescriptorRecoveryDevice *recoveryDeviceInfo) { addRecoveryDevice(recoveryDeviceInfo); @@ -91,6 +94,7 @@ DeviceManagerWidget::DeviceManagerWidget(QWidget *parent) removeRecoveryDevice(ecid); emit updateNoDevicesConnected(); }); +#endif connect(AppContext::sharedInstance(), &AppContext::devicePairingExpired, this, [this](const QString &udid) { @@ -142,6 +146,7 @@ void DeviceManagerWidget::addDevice(iDescriptorDevice *device) std::pair{deviceWidget, m_sidebar->addDevice(tabTitle, device->udid)}; } +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT void DeviceManagerWidget::addRecoveryDevice( const iDescriptorRecoveryDevice *device) { @@ -185,6 +190,7 @@ void DeviceManagerWidget::removeRecoveryDevice(uint64_t ecid) emit updateNoDevicesConnected(); } } +#endif void DeviceManagerWidget::addPendingDevice(const QString &udid, bool locked) { @@ -297,11 +303,6 @@ void DeviceManagerWidget::setCurrentDevice(const std::string &uuid) QWidget *widget = m_deviceWidgets[uuid].first; m_stackedWidget->setCurrentWidget(widget); - - // This creates a feedback loop. The widget should only react to state - // changes from AppContext, not create them here. - // AppContext::sharedInstance()->setCurrentDeviceSelection( - // DeviceSelection(uuid)); } std::string DeviceManagerWidget::getCurrentDevice() const @@ -334,6 +335,7 @@ void DeviceManagerWidget::onDeviceSelectionChanged( } break; +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT case DeviceSelection::Recovery: if (m_recoveryDeviceWidgets.contains(selection.ecid)) { QWidget *tabWidget = m_recoveryDeviceWidgets[selection.ecid].first; @@ -344,6 +346,7 @@ void DeviceManagerWidget::onDeviceSelectionChanged( } } break; +#endif case DeviceSelection::Pending: if (m_pendingDeviceWidgets.contains(selection.uuid)) { diff --git a/src/devicemanagerwidget.h b/src/devicemanagerwidget.h index dc45bad..3efb6a2 100644 --- a/src/devicemanagerwidget.h +++ b/src/devicemanagerwidget.h @@ -24,7 +24,9 @@ #include "devicependingwidget.h" #include "devicesidebarwidget.h" #include "iDescriptor.h" +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT #include "recoverydeviceinfowidget.h" +#endif #include #include #include @@ -51,8 +53,10 @@ private: void addDevice(iDescriptorDevice *device); void removeDevice(const std::string &uuid); +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT void addRecoveryDevice(const iDescriptorRecoveryDevice *device); void removeRecoveryDevice(uint64_t ecid); +#endif // TODO:udid or uuid ? void addPendingDevice(const QString &udid, bool locked); void addPairedDevice(iDescriptorDevice *device); @@ -69,9 +73,11 @@ private: std::pair> m_pendingDeviceWidgets; // Map to store devices by UDID +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT QMap> m_recoveryDeviceWidgets; // Map to store recovery devices by ECID +#endif std::string m_currentDeviceUuid; }; diff --git a/src/iDescriptor.h b/src/iDescriptor.h index 5b17814..58b238c 100644 --- a/src/iDescriptor.h +++ b/src/iDescriptor.h @@ -94,6 +94,7 @@ struct DeviceInfo { std::string productType; std::string rawProductType; bool jailbroken; + std::string serialNumber; std::string basebandActivationTicketVersion; std::string basebandCertId; std::string basebandChipID; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 894723e..a22a03e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -29,7 +29,9 @@ #include "iDescriptor-ui.h" #include "iDescriptor.h" #include "jailbrokenwidget.h" +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT #include "libirecovery.h" +#endif #include "toolboxwidget.h" #include "welcomewidget.h" #include @@ -96,6 +98,7 @@ void handleCallback(const idevice_event_t *event, void *userData) } } +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT void handleCallbackRecovery(const irecv_device_event_t *event, void *userData) { @@ -117,6 +120,7 @@ void handleCallbackRecovery(const irecv_device_event_t *event, void *userData) } } irecv_device_event_context_t context; +#endif MainWindow *MainWindow::sharedInstance() { @@ -213,6 +217,7 @@ MainWindow::MainWindow(QWidget *parent) } #endif +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT irecv_error_t res_recovery = irecv_device_event_subscribe(&context, handleCallbackRecovery, nullptr); @@ -222,6 +227,7 @@ MainWindow::MainWindow(QWidget *parent) << res_recovery; } qDebug() << "Subscribed to recovery device events successfully."; +#endif idevice_error_t res = idevice_event_subscribe(handleCallback, nullptr); if (res != IDEVICE_E_SUCCESS) { @@ -317,7 +323,9 @@ void MainWindow::updateNoDevicesConnected() MainWindow::~MainWindow() { idevice_event_unsubscribe(); +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT irecv_device_event_unsubscribe(context); +#endif delete ui; delete m_updater; sleep(2); // Give some time for cleanup to finish diff --git a/src/mainwindow.h b/src/mainwindow.h index 358f013..db2938c 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -23,7 +23,9 @@ #include "ZUpdater.h" #include "devicemanagerwidget.h" #include "iDescriptor.h" +#ifdef ENABLE_RECOVERY_DEVICE_SUPPORT #include "libirecovery.h" +#endif #include "ztabwidget.h" #include #include diff --git a/src/welcomewidget.cpp b/src/welcomewidget.cpp index 57bb706..877166f 100644 --- a/src/welcomewidget.cpp +++ b/src/welcomewidget.cpp @@ -90,8 +90,11 @@ void WelcomeWidget::setupUI() m_mainLayout->addWidget(m_githubLabel, 0, Qt::AlignCenter); + // FIXME: we need to disable specific deps in diagnosewidget + // not the whole widget when EnableRecoveryDeviceSupport is off // no additional deps needed on macOS -#ifndef __APPLE__ +#if !defined(__APPLE__) && defined(ENABLE_RECOVERY_DEVICE_SUPPORT) + DiagnoseWidget *diagnoseWidget = new DiagnoseWidget(); m_mainLayout->addWidget(diagnoseWidget); #endif