From c84276eabc6c78d3a93de6517a3807b9827e0416 Mon Sep 17 00:00:00 2001 From: uncor3 Date: Sun, 24 Aug 2025 01:46:49 +0000 Subject: [PATCH] various enhancements - add helper function declarations to iDescriptor.h - remove unnessery mountDevImage - single instance lock for devdiskimages (may be removed in future) - implement safe_afc_read_directory to make sure client is long lived ( for now ony for afc_read_directory needs to be wrapped) - remove some cleanup code for testing (init_device.cpp) - clean leave label for mount_dev_image.cpp --- .vscode/c_cpp_properties.json | 42 +- .vscode/settings.json | 14 +- CMakeLists.txt | 4 + src/appcontext.cpp | 6 + src/appcontext.h | 1 + src/core/helpers/clean_device.cpp | 38 - src/core/helpers/safe_afc_read_directory.cpp | 22 + src/core/services/init_device.cpp | 27 +- src/core/services/mount_dev_image.cpp | 344 +++--- src/iDescriptor.h | 27 + src/querymobilegestaltwidget.cpp | 1107 +++++++++++++++--- src/recoverydeviceinfowidget.cpp | 1 - src/toolboxwidget.cpp | 36 +- src/toolboxwidget.h | 2 + 14 files changed, 1222 insertions(+), 449 deletions(-) delete mode 100644 src/core/helpers/clean_device.cpp create mode 100644 src/core/helpers/safe_afc_read_directory.cpp diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 57a1346..be8b15b 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -1,22 +1,22 @@ { - "configurations": [ - { - "name": "Linux", - "includePath": [ - "${workspaceFolder}/**", - "/usr/include/qt/**", - "/usr/local/opt/qt/**", - "${workspaceFolder}/build/Desktop-Debug/iDescriptor_autogen/include", - "${workspaceFolder}/build/Desktop-Debug/src/lib/**", - "/usr/local/include/**", - "/usr/include/python3.13" - ], - "defines": [], - "compilerPath": "/usr/bin/gcc", - "cStandard": "c17", - "cppStandard": "gnu++17", - "intelliSenseMode": "linux-gcc-x64" - } - ], - "version": 4 -} \ No newline at end of file + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**", + "/usr/include/qt/**", + "/usr/local/opt/qt/**", + "${workspaceFolder}/build/Desktop-Debug/iDescriptor_autogen/include", + "${workspaceFolder}/build/Desktop-Debug/src/lib/**", + "/usr/local/include/**", + "/usr/include/qt6/**" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc", + "cStandard": "c17", + "cppStandard": "gnu++17", + "intelliSenseMode": "linux-gcc-x64" + } + ], + "version": 4 +} diff --git a/.vscode/settings.json b/.vscode/settings.json index 80dd8f5..72a9d0f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -155,6 +155,18 @@ "qcoreapplication": "cpp", "qdialog": "cpp", "qcombobox": "cpp", - "qtconcurrent": "cpp" + "qtconcurrent": "cpp", + "qicon": "cpp", + "qlistwidget": "cpp", + "qfuturewatcher": "cpp", + "qgraphicsview": "cpp", + "qtglobal": "cpp", + "qgraphicspixmapitem": "cpp", + "qresizeevent": "cpp", + "qmediaplayer": "cpp", + "qvideowidget": "cpp", + "qhostaddress": "cpp", + "qtcpsocket": "cpp", + "qstackedwidget": "cpp" } } diff --git a/CMakeLists.txt b/CMakeLists.txt index 7703b07..71983cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,6 +114,7 @@ find_library(PLIST_LIBRARY file(GLOB PROJECT_SOURCES src/*.cpp + src/core/helpers/*.cpp src/*.h src/*.ui resources.qrc @@ -131,6 +132,8 @@ find_package(Qt6 REQUIRED COMPONENTS Location) find_package(Qt6 REQUIRED COMPONENTS Positioning) find_package(Qt6 REQUIRED COMPONENTS QuickWidgets) find_package(Qt6 REQUIRED COMPONENTS Widgets) +find_package(Qt6 REQUIRED COMPONENTS Multimedia) +find_package(Qt6 REQUIRED COMPONENTS MultimediaWidgets) qt_add_executable(iDescriptor @@ -162,6 +165,7 @@ target_link_libraries(iDescriptor PRIVATE Qt${QT_VERSION_MAJOR}::Svg Qt${QT_VERSION_MAJOR}::SvgWidgets Qt${QT_VERSION_MAJOR}::Multimedia + Qt${QT_VERSION_MAJOR}::MultimediaWidgets Qt${QT_VERSION_MAJOR}::Network Qt${QT_VERSION_MAJOR}::DBus Qt${QT_VERSION_MAJOR}::Core diff --git a/src/appcontext.cpp b/src/appcontext.cpp index 864ea27..71d9e6a 100644 --- a/src/appcontext.cpp +++ b/src/appcontext.cpp @@ -106,6 +106,7 @@ void AppContext::addDevice(QString udid, idevice_connection_type conn_type, .conn_type = conn_type, .device = initResult.device, .deviceInfo = initResult.deviceInfo, + .afcClient = initResult.afcClient, }; m_devices[device->udid] = device; if (addType == AddType::Regular) @@ -178,6 +179,11 @@ QList AppContext::getAllDevices() return m_devices.values(); } +QList AppContext::getAllRecoveryDevices() +{ + return m_recoveryDevices.values(); +} + // Returns whether there are any devices connected (regular or recovery) bool AppContext::noDevicesConnected() { diff --git a/src/appcontext.h b/src/appcontext.h index 2a5100d..5d52495 100644 --- a/src/appcontext.h +++ b/src/appcontext.h @@ -24,6 +24,7 @@ public: // Returns whether there are any devices connected (regular or recovery) bool noDevicesConnected(); + QList getAllRecoveryDevices(); ~AppContext(); private: diff --git a/src/core/helpers/clean_device.cpp b/src/core/helpers/clean_device.cpp deleted file mode 100644 index a2570d1..0000000 --- a/src/core/helpers/clean_device.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "../../iDescriptor.h" - -bool cleanDevice(iDescriptorDevice device) -{ - lockdownd_error_t lockdownd_free = - lockdownd_client_free(device.lockdownClient); - afc_error_t afc_free = afc_client_free(device.afcClient); - idevice_error_t _idevice_free = idevice_free(device.device); - lockdownd_error_t _lockdownd_service_descriptor_free = - lockdownd_service_descriptor_free(device.lockdownService); - - if (lockdownd_free != LOCKDOWN_E_SUCCESS) { - return false; - } - if (afc_free != AFC_E_SUCCESS) { - return false; - } - if (_idevice_free != IDEVICE_E_SUCCESS) { - return false; - } - if (_lockdownd_service_descriptor_free != LOCKDOWN_E_SUCCESS) { - return false; - } - return true; -} - -void cleanDeviceAt(unsigned index) -{ - iDescriptorDevice &device = idescriptor_devices.at(index); - cleanDevice(device); - - idescriptor_devices.erase(std::remove_if(idescriptor_devices.begin(), - idescriptor_devices.end(), - [&](const iDescriptorDevice &d) { - return d.udid == device.udid; - }), - idescriptor_devices.end()); -} \ No newline at end of file diff --git a/src/core/helpers/safe_afc_read_directory.cpp b/src/core/helpers/safe_afc_read_directory.cpp new file mode 100644 index 0000000..1c15e69 --- /dev/null +++ b/src/core/helpers/safe_afc_read_directory.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +afc_error_t safe_afc_read_directory(afc_client_t afcClient, idevice_t device, + const char *path, char ***dirs) +{ + afc_error_t res = afc_read_directory(afcClient, path, dirs); + // maybe the afc client is not valid anymore, so we try to reinitialize it + if (res != AFC_E_SUCCESS) { + qDebug() << "AFC read directory error: " << res; + afc_client_free(afcClient); + afc_client_new(device, NULL, &afcClient); + res = afc_read_directory(afcClient, path, dirs); + if (res != AFC_E_SUCCESS) { + qDebug() << "Failed to re-read directory after AFC client reset: " + << res; + } + } + + return res; +} diff --git a/src/core/services/init_device.cpp b/src/core/services/init_device.cpp index 03bc754..5aab219 100644 --- a/src/core/services/init_device.cpp +++ b/src/core/services/init_device.cpp @@ -1,5 +1,4 @@ #include "../../iDescriptor.h" -#include "../helpers/parse_product_type.cpp" #include "./detect_jailbroken.cpp" #include "./get-device-info.cpp" #include "libirecovery.h" @@ -108,8 +107,11 @@ DeviceInfo fullDeviceInfo(const pugi::xml_document &doc, return d; } +// TODO: need to handle errors and free resources properly IDescriptorInitDeviceResult init_idescriptor_device(const char *udid) { + // TODO:on a broken usb cable this can hang for a long time + // causing the UI to freeze qDebug() << "Initializing iDescriptor device with UDID: " << QString::fromUtf8(udid); IDescriptorInitDeviceResult result = {}; @@ -179,8 +181,8 @@ IDescriptorInitDeviceResult init_idescriptor_device(const char *udid) qDebug() << "Failed to query diagnostics relay for AppleARMPMUCharger."; // Clean up resources before returning - if (afcClient) - afc_client_free(afcClient); + // if (afcClient) + // afc_client_free(afcClient); if (lockdownService) lockdownd_service_descriptor_free(lockdownService); if (client) @@ -207,16 +209,17 @@ IDescriptorInitDeviceResult init_idescriptor_device(const char *udid) // if (result.device) idevice_free(result.device); fullDeviceInfo(infoXml, afcClient, diagnostics, result.deviceInfo); + result.afcClient = afcClient; result.success = true; - - if (afcClient) - afc_client_free(afcClient); - if (lockdownService) - lockdownd_service_descriptor_free(lockdownService); - if (client) - lockdownd_client_free(client); - if (diagnostics_client) - diagnostics_relay_client_free(diagnostics_client); + // TODO: cleanup needed ? + // if (afcClient) + // afc_client_free(afcClient); + // if (lockdownService) + // lockdownd_service_descriptor_free(lockdownService); + // if (client) + // lockdownd_client_free(client); + // if (diagnostics_client) + // diagnostics_relay_client_free(diagnostics_client); return result; } catch (const std::exception &e) { diff --git a/src/core/services/mount_dev_image.cpp b/src/core/services/mount_dev_image.cpp index 91b8135..207b98a 100644 --- a/src/core/services/mount_dev_image.cpp +++ b/src/core/services/mount_dev_image.cpp @@ -89,6 +89,8 @@ static ssize_t mim_upload_cb(void *buf, size_t size, void *userdata) return fread(buf, 1, size, (FILE *)userdata); } // TODO: cleanup +// TODO: may not work on a broken ,faulty or fake usb cable +// TypeC cables work better bool mount_dev_image(const char *udid, const char *image_dir_path) { mobile_image_mounter_client_t mim = NULL; @@ -99,68 +101,79 @@ bool mount_dev_image(const char *udid, const char *image_dir_path) afc_client_t afc = NULL; lockdownd_service_descriptor_t service = NULL; idevice_t device = NULL; + char *image_path = NULL; + char *image_sig_path = NULL; + FILE *f = NULL; + unsigned char *sig = NULL; + plist_t mount_options = NULL; + char *targetname = NULL; + char *mountname = NULL; + unsigned int device_version = 0; + disk_image_upload_type_t disk_image_upload_type = + DISK_IMAGE_UPLOAD_TYPE_AFC; + + mobile_image_mounter_error_t err = MOBILE_IMAGE_MOUNTER_E_UNKNOWN_ERROR; + plist_t result = NULL; + size_t sig_length = 0; if (IDEVICE_E_SUCCESS != idevice_new_with_options(&device, udid, (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX)) { qDebug() << "ERROR: Could not create idevice!"; - return false; + res = -1; + goto leave; } + device_version = idevice_get_device_version(device); if (LOCKDOWN_E_SUCCESS != (ldret = lockdownd_client_new_with_handshake( device, &lckd, TOOL_NAME))) { qDebug() << "ERROR: Could not connect to lockdownd service!"; - return false; - // goto leave; + res = -1; + goto leave; } - lockdownd_error_t lerr = - lockdownd_start_service(lckd, "com.apple.afc", &service); - if (lerr != LOCKDOWN_E_SUCCESS) { - qDebug() << "ERROR: Could not start AFC service!" - << lockdownd_strerror(lerr) << "(" << lerr << ")"; - lockdownd_client_free(lckd); - lckd = NULL; - idevice_free(device); - device = NULL; - return false; + if (device_version >= IDEVICE_DEVICE_VERSION(7, 0, 0)) { + disk_image_upload_type = DISK_IMAGE_UPLOAD_TYPE_UPLOAD_IMAGE; } - afc_error_t rafc = afc_client_new(device, service, &afc); - if (rafc != AFC_E_SUCCESS) { - qDebug() << "ERROR: Could not connect to AFC!" << afc_strerror(rafc) - << "(" << rafc << ")"; - return false; - } + if (disk_image_upload_type == DISK_IMAGE_UPLOAD_TYPE_AFC) { + lockdownd_error_t lerr = + lockdownd_start_service(lckd, "com.apple.afc", &service); + if (lerr != LOCKDOWN_E_SUCCESS) { + qDebug() << "ERROR: Could not start AFC service!" + << lockdownd_strerror(lerr) << "(" << lerr << ")"; + res = -1; + goto leave; + } - char *image_path = nullptr; - char *image_sig_path = nullptr; + afc_error_t rafc = afc_client_new(device, service, &afc); + if (rafc != AFC_E_SUCCESS) { + qDebug() << "ERROR: Could not connect to AFC!" << afc_strerror(rafc) + << "(" << rafc << ")"; + res = -1; + goto leave; + } + lockdownd_service_descriptor_free(service); + service = NULL; + } if (asprintf(&image_path, "%s/DeveloperDiskImage.dmg", image_dir_path) < 0) { qDebug() << "Out of memory constructing image path!"; - return false; + res = -1; + goto leave; } if (asprintf(&image_sig_path, "%s/DeveloperDiskImage.dmg.signature", image_dir_path) < 0) { qDebug() << "Out of memory constructing signature path!"; - free(image_path); - return false; + res = -1; + goto leave; } - // #ifndef _WIN32 - // signal(SIGPIPE, SIG_IGN); - // #endif - - unsigned int device_version = idevice_get_device_version(device); - - disk_image_upload_type_t disk_image_upload_type = - DISK_IMAGE_UPLOAD_TYPE_AFC; - if (device_version >= IDEVICE_DEVICE_VERSION(7, 0, 0)) { - disk_image_upload_type = DISK_IMAGE_UPLOAD_TYPE_UPLOAD_IMAGE; - } + qDebug() << "Using image:" << image_path; + qDebug() << "Using signature:" << image_sig_path; if (device_version >= IDEVICE_DEVICE_VERSION(16, 0, 0)) { uint8_t dev_mode_status = 0; @@ -175,7 +188,8 @@ bool mount_dev_image(const char *udid, const char *image_dir_path) qDebug() << "ERROR: You have to enable Developer Mode on the given " "device in order to allowing mounting a developer disk " "image."; - return false; + res = -1; + goto leave; } } @@ -184,121 +198,64 @@ bool mount_dev_image(const char *udid, const char *image_dir_path) if (!service || service->port == 0) { qDebug() << "ERROR: Could not start mobile_image_mounter service!"; - return false; + res = -1; + goto leave; } if (mobile_image_mounter_new(device, service, &mim) != MOBILE_IMAGE_MOUNTER_E_SUCCESS) { qDebug() << "ERROR: Could not connect to mobile_image_mounter!"; - return false; + res = -1; + goto leave; } - - // if (service) - // { - // lockdownd_service_descriptor_free(service); - // service = NULL; - // } + lockdownd_service_descriptor_free(service); + service = NULL; struct stat fst; - if (disk_image_upload_type == DISK_IMAGE_UPLOAD_TYPE_AFC) { - if (!service || !service->port) { - qDebug() << "Could not start com.apple.afc!"; - return false; - } - if (!afc) { - qDebug() << "Could not connect to AFC!"; - return false; - } - if (service) { - // lockdownd_service_descriptor_free(service); - service = NULL; - } - } if (stat(image_path, &fst) != 0) { qDebug() << "ERROR: stat:" << image_path << ":" << strerror(errno); - return false; + res = -1; + goto leave; } image_size = fst.st_size; if (device_version < IDEVICE_DEVICE_VERSION(17, 0, 0) && stat(image_sig_path, &fst) != 0) { qDebug() << "ERROR: stat:" << image_sig_path << ":" << strerror(errno); - return false; + res = -1; + goto leave; } - // lockdownd_client_free(lckd); - // lckd = NULL; - - mobile_image_mounter_error_t err = MOBILE_IMAGE_MOUNTER_E_UNKNOWN_ERROR; - plist_t result = NULL; - - // if (cmd == CMD_LIST) - // { - // /* list mounts mode */ - // if (!imagetype) - // { - // if (device_version < IDEVICE_DEVICE_VERSION(17, 0, 0)) - // { - // imagetype = "Developer"; - // } - // else - // { - // imagetype = "Personalized"; - // } - // } - // err = mobile_image_mounter_lookup_image(mim, imagetype, &result); - // if (err == MOBILE_IMAGE_MOUNTER_E_SUCCESS) - // { - // res = 0; - // plist_write_to_stream(result, stdout, (xml_mode) ? - // PLIST_FORMAT_XML : PLIST_FORMAT_LIMD, 0); - // } - // else - // { - // printf("Error: lookup_image returned %d\n", err); - // } - // } - - unsigned char *sig = NULL; - size_t sig_length = 0; - FILE *f; - // struct stat fst; - plist_t mount_options = NULL; - if (device_version < IDEVICE_DEVICE_VERSION(17, 0, 0)) { f = fopen(image_sig_path, "rb"); if (!f) { qDebug() << "Error opening signature file" << image_sig_path << ":" << strerror(errno); - return false; + res = -1; + goto leave; } if (fstat(fileno(f), &fst) != 0) { qDebug() << "Error: fstat:" << strerror(errno); - return false; + res = -1; + goto leave; } sig = (unsigned char *)malloc(fst.st_size); sig_length = fread(sig, 1, fst.st_size, f); fclose(f); + f = NULL; if (sig_length == 0) { qDebug() << "Could not read signature from file" << image_sig_path; - return false; + res = -1; + goto leave; } f = fopen(image_path, "rb"); if (!f) { qDebug() << "Error opening image file" << image_path << ":" << strerror(errno); - return false; + res = -1; + goto leave; } } else { - if (stat(image_path, &fst) != 0) { - qDebug() << "Error: stat:" << image_path << ":" << strerror(errno); - return false; - } - if (!S_ISDIR(fst.st_mode)) { - qDebug() << "Error: Personalized Disk Image mount expects a " - "directory as image path."; - return false; - } char *build_manifest_path = string_build_path(image_path, "BuildManifest.plist", NULL); plist_t build_manifest = NULL; @@ -318,7 +275,8 @@ bool mount_dev_image(const char *udid, const char *image_dir_path) if (!build_manifest) { qDebug() << "Error: Could not locate BuildManifest.plist inside " "given disk image path!"; - return false; + res = -1; + goto leave; } plist_t identifiers = NULL; @@ -327,7 +285,8 @@ bool mount_dev_image(const char *udid, const char *image_dir_path) mim, NULL, &identifiers); if (merr != MOBILE_IMAGE_MOUNTER_E_SUCCESS) { qDebug() << "Failed to query personalization identifiers:" << merr; - return false; + res = -1; + goto leave; } unsigned int board_id = plist_dict_get_uint(identifiers, "BoardId"); @@ -357,20 +316,23 @@ bool mount_dev_image(const char *udid, const char *image_dir_path) if (!build_identity) { qDebug() << "Error: The given disk image is not compatible with " "the current device."; - return false; + res = -1; + goto leave; } plist_t p_tc_path = plist_access_path(build_identity, 4, "Manifest", "LoadableTrustCache", "Info", "Path"); if (!p_tc_path) { qDebug() << "Error: Could not determine path for trust cache!"; - return false; + res = -1; + goto leave; } plist_t p_dmg_path = plist_access_path( build_identity, 4, "Manifest", "PersonalizedDMG", "Info", "Path"); if (!p_dmg_path) { qDebug() << "Error: Could not determine path for disk image!"; - return false; + res = -1; + goto leave; } char *tc_path = string_build_path( image_path, plist_get_string_ptr(p_tc_path, NULL), NULL); @@ -380,7 +342,8 @@ bool mount_dev_image(const char *udid, const char *image_dir_path) &trust_cache_size)) { qDebug() << "Error: Trust cache does not exist at" << tc_path << "!"; - return false; + res = -1; + goto leave; } mount_options = plist_new_dict(); plist_dict_set_item( @@ -395,7 +358,8 @@ bool mount_dev_image(const char *udid, const char *image_dir_path) if (!f) { qDebug() << "Error opening image file" << image_path << ":" << strerror(errno); - return false; + res = -1; + goto leave; } unsigned char buf[8192]; @@ -427,7 +391,8 @@ bool mount_dev_image(const char *udid, const char *image_dir_path) mim = NULL; if (mobile_image_mounter_start_service(device, &mim, TOOL_NAME) != MOBILE_IMAGE_MOUNTER_E_SUCCESS) { - return false; + res = -1; + goto leave; } qDebug() << "No personalization manifest, requesting from TSS..."; unsigned char *nonce = NULL; @@ -469,7 +434,8 @@ bool mount_dev_image(const char *udid, const char *image_dir_path) qDebug() << "ERROR: Failed to query nonce for developer disk image:" << merr; - return false; + res = -1; + goto leave; } mobile_image_mounter_free(mim); mim = NULL; @@ -492,7 +458,8 @@ bool mount_dev_image(const char *udid, const char *image_dir_path) plist_t p_manifest = plist_dict_get_item(response, "ApImg4Ticket"); if (!PLIST_IS_DATA(p_manifest)) { qDebug() << "Failed to get Img4Ticket"; - return false; + res = -1; + goto leave; } uint64_t m4m_len = 0; @@ -507,28 +474,21 @@ bool mount_dev_image(const char *udid, const char *image_dir_path) imagetype = "Personalized"; } - char *targetname = NULL; if (asprintf(&targetname, "%s/%s", PKG_PATH, "staging.dimage") < 0) { qDebug() << "Out of memory!?"; - return false; + res = -1; + goto leave; } - char *mountname = NULL; if (asprintf(&mountname, "%s/%s", PATH_PREFIX, targetname) < 0) { qDebug() << "Out of memory!?"; - return false; + res = -1; + goto leave; } if (!imagetype) { imagetype = "Developer"; } - if (!mim) { - if (mobile_image_mounter_start_service(device, &mim, TOOL_NAME) != - MOBILE_IMAGE_MOUNTER_E_SUCCESS) { - return false; - } - } - switch (disk_image_upload_type) { case DISK_IMAGE_UPLOAD_TYPE_UPLOAD_IMAGE: qDebug() << "Uploading" << image_path; @@ -552,9 +512,9 @@ bool mount_dev_image(const char *udid, const char *image_dir_path) if ((afc_file_open(afc, targetname, AFC_FOPEN_WRONLY, &af) != AFC_E_SUCCESS) || !af) { - fclose(f); qDebug() << "afc_file_open on" << targetname << "failed!"; - return false; + res = -1; + goto leave; } char buf[8192]; @@ -576,8 +536,8 @@ bool mount_dev_image(const char *udid, const char *image_dir_path) qDebug() << "Error: wrote only" << total << "of" << (unsigned int)amount; afc_file_close(afc, af); - fclose(f); - return false; + res = -1; + goto leave; } } } while (amount > 0); @@ -586,8 +546,6 @@ bool mount_dev_image(const char *udid, const char *image_dir_path) break; } - fclose(f); - if (err != MOBILE_IMAGE_MOUNTER_E_SUCCESS) { if (err == MOBILE_IMAGE_MOUNTER_E_DEVICE_LOCKED) { qDebug() << "ERROR: Device is locked, can't mount. Unlock device " @@ -595,7 +553,8 @@ bool mount_dev_image(const char *udid, const char *image_dir_path) } else { qDebug() << "ERROR: Unknown error occurred, can't mount."; } - return false; + res = -1; + goto leave; } qDebug() << "done."; @@ -612,79 +571,70 @@ bool mount_dev_image(const char *udid, const char *image_dir_path) if (!strcmp(status, "Complete")) { qDebug() << "Done."; res = 0; - } else { - qDebug() << "unexpected status value:"; - plist_write_to_stream(result, stdout, - (xml_mode) ? PLIST_FORMAT_XML - : PLIST_FORMAT_LIMD, - (plist_write_options_t)0); } free(status); - } else { - qDebug() << "unexpected result:"; - plist_write_to_stream(result, stdout, - (xml_mode) ? PLIST_FORMAT_XML - : PLIST_FORMAT_LIMD, - (plist_write_options_t)0); } } - node = plist_dict_get_item(result, "Error"); - if (node) { - char *error = NULL; - plist_get_string_val(node, &error); - if (error) { - qDebug() << "Error:" << error; - free(error); - } else { - qDebug() << "unexpected result:"; - plist_write_to_stream(result, stdout, - (xml_mode) ? PLIST_FORMAT_XML - : PLIST_FORMAT_LIMD, - (plist_write_options_t)0); - } - node = plist_dict_get_item(result, "DetailedError"); + if (res != 0) { // If not complete, log the error + node = plist_dict_get_item(result, "Error"); if (node) { - qDebug() - << "DetailedError:" << plist_get_string_ptr(node, NULL); + char *error = NULL; + plist_get_string_val(node, &error); + if (error) { + qDebug() << "Error:" << error; + free(error); + } + node = plist_dict_get_item(result, "DetailedError"); + if (node) { + qDebug() << "DetailedError:" + << plist_get_string_ptr(node, NULL); + } } - } else { - plist_write_to_stream(result, stdout, - (xml_mode) ? PLIST_FORMAT_XML - : PLIST_FORMAT_LIMD, - (plist_write_options_t)0); } } } else { qDebug() << "Error: mount_image returned" << err; } +leave: + if (f) { + fclose(f); + } if (result) { plist_free(result); } - // error_out: - // /* perform hangup command */ - // mobile_image_mounter_hangup(mim); - // /* free client */ - // mobile_image_mounter_free(mim); + if (mim) { + mobile_image_mounter_free(mim); + } + if (afc) { + afc_client_free(afc); + } + if (lckd) { + lockdownd_client_free(lckd); + } + if (device) { + idevice_free(device); + } + if (image_path) { + free(image_path); + } + if (image_sig_path) { + free(image_sig_path); + } + if (sig) { + free(sig); + } + if (mount_options) { + plist_free(mount_options); + } + if (targetname) { + free(targetname); + } + if (mountname) { + free(mountname); + } - // leave: - // if (afc) - // { - // afc_client_free(afc); - // } - // if (lckd) - // { - // lockdownd_client_free(lckd); - // } - // idevice_free(device); - - // if (image_path) - // free(image_path); - // if (image_sig_path) - // free(image_sig_path); - - // return res; - return true; + return res == 0; } // int main(){return 0;} \ No newline at end of file diff --git a/src/iDescriptor.h b/src/iDescriptor.h index 3bfa55e..cff7afb 100644 --- a/src/iDescriptor.h +++ b/src/iDescriptor.h @@ -117,6 +117,11 @@ struct iDescriptorDevice { idevice_connection_type conn_type; idevice_t device; DeviceInfo deviceInfo; + /* + inital afc client to start the file explorer and gallery with + clients are not long lived, so do not assume this will be valid + */ + afc_client_t afcClient; }; struct IDescriptorInitDeviceResult { @@ -124,6 +129,7 @@ struct IDescriptorInitDeviceResult { lockdownd_error_t error; idevice_t device; DeviceInfo deviceInfo; + afc_client_t afcClient; }; // Device model identifier to marketing name mapping @@ -218,3 +224,24 @@ public: operator plist_t() const { return current_node; } bool valid() const { return current_node != nullptr; } }; + +afc_error_t safe_afc_read_directory(afc_client_t afcClient, idevice_t device, + const char *path, char ***dirs); + +std::string parse_product_type(const std::string &productType); + +std::string parse_recovery_mode(irecv_mode productType); + +struct MediaEntry { + std::string name; + bool isDir; +}; + +struct MediaFileTree { + std::vector entries; + bool success; + std::string currentPath; +}; + +MediaFileTree get_file_tree(afc_client_t afcClient, idevice_t device, + const std::string &path = "/"); \ No newline at end of file diff --git a/src/querymobilegestaltwidget.cpp b/src/querymobilegestaltwidget.cpp index bbf8102..245eb82 100644 --- a/src/querymobilegestaltwidget.cpp +++ b/src/querymobilegestaltwidget.cpp @@ -114,173 +114,946 @@ void QueryMobileGestaltWidget::setupUI() void QueryMobileGestaltWidget::populateKeys() { - mobileGestaltKeys = {"3GProximityCapability", - "3GVeniceCapability", - "3Gvenice", - "3d-imagery", - "3d-maps", - "64-bit", - "720p", - "720pPlaybackCapability", - "APNCapability", - "ARM64ExecutionCapability", - "ARMV6ExecutionCapability", - "ARMV7ExecutionCapability", - "ARMV7SExecutionCapability", - "ASTC", - "ActiveWirelessTechnology", - "AirDropCapability", - "AirPlayCapability", - "AllowsUnrestrictedCellularDataConnections", - "AppleInternalInstallCapability", - "ApplePay", - "ArtworkDeviceIdiom", - "ArtworkDeviceSubType", - "ArtworkDisplayGamut", - "ArtworkDynamicDisplayMode", - "ArtworkScaleFactor", - "AssistantCapability", - "AudioCodecCapability", - "AutoFocusCamera", - "BasebandCapability", - "BasebandChipset", - "BasebandFirmwareVersion", - "BasebandKeyHashInformation", - "BasebandMasterKeyHash", - "BasebandPostponementStatus", - "BasebandStatus", - "BatteryCurrentCapacity", - "BatteryIsCharging", - "BatteryIsFullyCharged", - "BatteryWillCharge", - "BiometricKitTemplateStorageCapability", - "BluetoothCapability", - "BoardId", - "BuildVersion", - "CameraCapability", - "CameraFlashCapability", - "CameraHDRCapability", - "CarIntegrationCapability", - "CellularTelephonyCapability", - "ChipID", - "CompassCapability", - "DeviceClass", - "DeviceColor", - "DeviceEnclosureColor", - "DeviceName", - "DeviceSupportsAlwaysOnCompass", - "DeviceSupports1080p", - "DeviceSupports3DMaps", - "DeviceSupports64BitApps", - "DeviceSupportsARKit", - "DeviceSupportsAOP", - "DeviceSupportsApplePay", - "DeviceSupportsAutoFocus", - "DeviceSupportsCamera", - "DeviceSupportsCameraCapture", - "DeviceSupportsCameraFlash", - "DeviceSupportsCarPlay", - "DeviceSupportsCompass", - "DeviceSupportsDeepColor", - "DeviceSupportsEncryptedBackups", - "DeviceSupportsFlashlight", - "DeviceSupportsForceTouch", - "DeviceSupportsGPS", - "DeviceSupportsGyroscope", - "DeviceSupportsHDR", - "DeviceSupportsHeadphoneJack", - "DeviceSupportsHiDPI", - "DeviceSupportsLightning", - "DeviceSupportsLineIn", - "DeviceSupportsLowPowerMode", - "DeviceSupportsMultitasking", - "DeviceSupportsNavigation", - "DeviceSupportsNFC", - "DeviceSupportsOpenGL", - "DeviceSupportsRearFacingCamera", - "DeviceSupportsSecureElement", - "DeviceSupportsSiri", - "DeviceSupportsStillCamera", - "DeviceSupportsUSBHost", - "DeviceSupportsVideoCapture", - "DeviceSupportsVideoRecording", - "DeviceSupportsVibrator", - "DeviceSupportsVoiceControl", - "DeviceSupportsWiFi", - "DeviceSupportsWirelessPower", - "DiskUsage", - "ExternalChargeCapability", - "FaceTimeCameraCapability", - "FrontFacingCameraCapability", - "GPSCapability", - "GSMCapability", - "GyroscopeCapability", - "HardwarePlatform", - "HasBaseband", - "HasExtendedColorDisplay", - "HasThinBezel", - "HomeButtonCapability", - "HearingAidCapability", - "InternalBuild", - "International", - "IsSimulator", - "IsUIBuild", - "MagnetometerCapability", - "MainScreenClass", - "MainScreenHeight", - "MainScreenPitchX", - "MainScreenPitchY", - "MainScreenScale", - "MainScreenWidth", - "MobileDeviceMinimumVersions", - "MobileEquipmentIdentifier", - "ModelNumber", - "NikeIpodCapability", - "OlsonTimeZone", - "PanoramaCameraCapability", - "PearlIDCapability", - "PhoneNumber", - "PictureRemoteCapability", - "PlatformName", - "ProductName", - "ProductType", - "ProductVersion", - "RearFacingCameraCapability", - "RegionCode", - "RegionInfo", - "RegionalBehaviorAll", - "RegionalBehaviorEUVolumeLimit", - "RegionalBehaviorGoogleMail", - "RegionalBehaviorNoPasscodeLocationTiles", - "RegionalBehaviorNoVOIP", - "RegionalBehaviorNoWiFi", - "RegionalBehaviorShutterClick", - "RegionalBehaviorVolumeLimit", - "ReleaseType", - "RequiredBatteryLevelForSoftwareUpdate", - "SIMStatus", - "SIMTrayStatus", - "SensitiveUI", - "SerialNumber", - "ShouldHactivate", - "SigningFuse", - "SoftwareBehavior", - "SoftwareBundleVersion", - "SpeakerCalibration", - "StillCameraCapability", - "SystemMemorySize", - "TotalSystemAvailable", - "UniqueChipID", - "UniqueDeviceID", - "UserIntentPhysicalButtonNormalizedCGRect", - "UserIntentPhysicalButtonSkipThreshold", - "VideoCameraCapability", - "VoiceControlCapability", - "VolumeButtonCapability", - "WiFiCapability", - "WirelessChargingCapability", - "YearClass", - "ZoomCameraCapability"}; + // Credits -> + // https://github.com/doronz88/pymobiledevice3/blob/master/pymobiledevice3/services/diagnostics.py + mobileGestaltKeys = { + "3GProximityCapability", + "3GVeniceCapability", + "3Gvenice", + "3d-imagery", + "3d-maps", + "64-bit", + "720p", + "720pPlaybackCapability", + "APNCapability", + "ARM64ExecutionCapability", + "ARMV6ExecutionCapability", + "ARMV7ExecutionCapability", + "ARMV7SExecutionCapability", + "ASTC", + "AWDID", + "AWDLCapability", + "AccelerometerCapability", + "AccessibilityCapability", + "AcousticID", + "ActivationProtocol", + "ActiveWirelessTechnology", + "ActuatorResonantFrequency", + "AdditionalTextTonesCapability", + "AggregateDevicePhotoZoomFactor", + "AggregateDeviceVideoZoomFactor", + "AirDropCapability", + "AirDropRestriction", + "AirplaneMode", + "AirplayMirroringCapability", + "AllDeviceCapabilities", + "Allow32BitApps", + "AllowOnlyATVCPSDKApps", + "AllowYouTube", + "AllowYouTubePlugin", + "AmbientLightSensorCapability", + "AmbientLightSensorSerialNumber", + "ApNonce", + "ApNonceRetrieve", + "AppCapacityTVOS", + "AppStore", + "AppStoreCapability", + "AppleInternalInstallCapability", + "AppleNeuralEngineSubtype", + "ApplicationInstallationCapability", + "ArcModuleSerialNumber", + "ArrowChipID", + "ArrowUniqueChipID", + "ArtworkTraits", + "AssistantCapability", + "AudioPlaybackCapability", + "AutoFocusCameraCapability", + "AvailableDisplayZoomSizes", + "BacklightCapability", + "BasebandAPTimeSync", + "BasebandBoardSnum", + "BasebandCertId", + "BasebandChipId", + "BasebandChipset", + "BasebandClass", + "BasebandFirmwareManifestData", + "BasebandFirmwareUpdateInfo", + "BasebandFirmwareVersion", + "BasebandKeyHashInformation", + "BasebandPostponementStatus", + "BasebandPostponementStatusBlob", + "BasebandRegionSKU", + "BasebandRegionSKURadioTechnology", + "BasebandSecurityInfoBlob", + "BasebandSerialNumber", + "BasebandSkeyId", + "BasebandStatus", + "BasebandUniqueId", + "BatteryCurrentCapacity", + "BatteryIsCharging", + "BatteryIsFullyCharged", + "BatterySerialNumber", + "BlueLightReductionSupported", + "BluetoothAddress", + "BluetoothAddressData", + "BluetoothCapability", + "BluetoothLE2Capability", + "BluetoothLECapability", + "BoardId", + "BoardRevision", + "BootManifestHash", + "BootNonce", + "BridgeBuild", + "BridgeRestoreVersion", + "BuddyLanguagesAnimationRequiresOptimization", + "BuildID", + "BuildVersion", + "C2KDeviceCapability", + "CPUArchitecture", + "CPUSubType", + "CPUType", + "CallForwardingCapability", + "CallWaitingCapability", + "CallerIDCapability", + "CameraAppUIVersion", + "CameraCapability", + "CameraFlashCapability", + "CameraFrontFlashCapability", + "CameraHDR2Capability", + "CameraHDRVersion", + "CameraLiveEffectsCapability", + "CameraMaxBurstLength", + "CameraRestriction", + "CarrierBundleInfoArray", + "CarrierInstallCapability", + "CellBroadcastCapability", + "CellularDataCapability", + "CellularTelephonyCapability", + "CertificateProductionStatus", + "CertificateSecurityMode", + "ChipID", + "CloudPhotoLibraryCapability", + "CoastlineGlowRenderingCapability", + "CompassCalibration", + "CompassCalibrationDictionary", + "CompassType", + "ComputerName", + "ConferenceCallType", + "ConfigNumber", + "ContainsCellularRadioCapability", + "ContinuityCapability", + "CoreRoutineCapability", + "CoverglassSerialNumber", + "DMin", + "DataPlanCapability", + "DebugBoardRevision", + "DelaySleepForHeadsetClickCapability", + "DesenseBuild", + "DeviceAlwaysPrewarmActuator", + "DeviceBackGlassMaterial", + "DeviceBackingColor", + "DeviceBrand", + "DeviceClass", + "DeviceClassNumber", + "DeviceColor", + "DeviceColorMapPolicy", + "DeviceCornerRadius", + "DeviceCoverGlassColor", + "DeviceCoverGlassMaterial", + "DeviceCoverMaterial", + "DeviceEnclosureColor", + "DeviceEnclosureMaterial", + "DeviceEnclosureRGBColor", + "DeviceHasAggregateCamera", + "DeviceHousingColor", + "DeviceIsMuseCapable", + "DeviceKeyboardCalibration", + "DeviceLaunchTimeLimitScale", + "DeviceName", + "DeviceNameString", + "DevicePrefers3DBuildingStrokes", + "DevicePrefersBuildingStrokes", + "DevicePrefersCheapTrafficShaders", + "DevicePrefersProceduralAntiAliasing", + "DevicePrefersTrafficAlpha", + "DeviceProximityCapability", + "DeviceRGBColor", + "DeviceRequiresPetalOptimization", + "DeviceRequiresProximityAmeliorations", + "DeviceRequiresSoftwareBrightnessCalculations", + "DeviceSceneUpdateTimeLimitScale", + "DeviceSubBrand", + "DeviceSupports1080p", + "DeviceSupports3DImagery", + "DeviceSupports3DMaps", + "DeviceSupports3rdPartyHaptics", + "DeviceSupports4G", + "DeviceSupports4k", + "DeviceSupports64Bit", + "DeviceSupports720p", + "DeviceSupports9Pin", + "DeviceSupportsAOP", + "DeviceSupportsARKit", + "DeviceSupportsASTC", + "DeviceSupportsAdaptiveMapsUI", + "DeviceSupportsAlwaysListening", + "DeviceSupportsAlwaysOnCompass", + "DeviceSupportsAlwaysOnTime", + "DeviceSupportsApplePencil", + "DeviceSupportsAutoLowLightVideo", + "DeviceSupportsAvatars", + "DeviceSupportsBatteryModuleAuthentication", + "DeviceSupportsBerkelium2", + "DeviceSupportsCCK", + "DeviceSupportsCameraCaptureOnTouchDown", + "DeviceSupportsCameraDeferredProcessing", + "DeviceSupportsCameraHaptics", + "DeviceSupportsCarIntegration", + "DeviceSupportsCinnamon", + "DeviceSupportsClosedLoopHaptics", + "DeviceSupportsCrudeProx", + "DeviceSupportsDClr", + "DeviceSupportsDoNotDisturbWhileDriving", + "DeviceSupportsELabel", + "DeviceSupportsEnhancedAC3", + "DeviceSupportsEnvironmentalDosimetry", + "DeviceSupportsExternalHDR", + "DeviceSupportsFloorCounting", + "DeviceSupportsHDRDeferredProcessing", + "DeviceSupportsHMEInARKit", + "DeviceSupportsHaptics", + "DeviceSupportsHardwareDetents", + "DeviceSupportsHeartHealthAlerts", + "DeviceSupportsHeartRateVariability", + "DeviceSupportsHiResBuildings", + "DeviceSupportsLineIn", + "DeviceSupportsLiquidDetection_CorrosionMitigation", + "DeviceSupportsLivePhotoAuto", + "DeviceSupportsLongFormAudio", + "DeviceSupportsMapsBlurredUI", + "DeviceSupportsMapsOpticalHeading", + "DeviceSupportsMomentCapture", + "DeviceSupportsNFC", + "DeviceSupportsNavigation", + "DeviceSupportsNewton", + "DeviceSupportsOnDemandPhotoAnalysis", + "DeviceSupportsP3ColorspaceVideoRecording", + "DeviceSupportsPeriodicALSUpdates", + "DeviceSupportsPhotosLocalLight", + "DeviceSupportsPortraitIntensityAdjustments", + "DeviceSupportsPortraitLightEffectFilters", + "DeviceSupportsRGB10", + "DeviceSupportsRaiseToSpeak", + "DeviceSupportsSiDP", + "DeviceSupportsSideButtonClickSpeed", + "DeviceSupportsSimplisticRoadMesh", + "DeviceSupportsSingleCameraPortrait", + "DeviceSupportsSiriBargeIn", + "DeviceSupportsSiriSpeaks", + "DeviceSupportsSiriSpokenMessages", + "DeviceSupportsSpatialOverCapture", + "DeviceSupportsStereoAudioRecording", + "DeviceSupportsStudioLightPortraitPreview", + "DeviceSupportsSwimmingWorkouts", + "DeviceSupportsTapToWake", + "DeviceSupportsTelephonyOverUSB", + "DeviceSupportsTethering", + "DeviceSupportsToneMapping", + "DeviceSupportsUSBTypeC", + "DeviceSupportsVSHCompensation", + "DeviceSupportsVoiceOverCanUseSiriVoice", + "DeviceSupportsWebkit", + "DeviceSupportsWirelessSplitting", + "DeviceSupportsYCbCr10", + "DeviceVariant", + "DeviceVariantGuess", + "DiagData", + "DictationCapability", + "DieId", + "DiskUsage", + "DisplayDriverICChipID", + "DisplayFCCLogosViaSoftwareCapability", + "DisplayMirroringCapability", + "DisplayPortCapability", + "DualSIMActivationPolicyCapable", + "EUICCChipID", + "EffectiveProductionStatus", + "EffectiveProductionStatusAp", + "EffectiveProductionStatusSEP", + "EffectiveSecurityMode", + "EffectiveSecurityModeAp", + "EffectiveSecurityModeSEP", + "EncodeAACCapability", + "EncryptedDataPartitionCapability", + "EnforceCameraShutterClick", + "EnforceGoogleMail", + "EthernetMacAddress", + "EthernetMacAddressData", + "ExplicitContentRestriction", + "ExternalChargeCapability", + "ExternalPowerSourceConnected", + "FDRSealingStatus", + "FMFAllowed", + "FaceTimeBackCameraTemporalNoiseReductionMode", + "FaceTimeBitRate2G", + "FaceTimeBitRate3G", + "FaceTimeBitRateLTE", + "FaceTimeBitRateWiFi", + "FaceTimeCameraRequiresFastSwitchOptions", + "FaceTimeCameraSupportsHardwareFaceDetection", + "FaceTimeDecodings", + "FaceTimeEncodings", + "FaceTimeFrontCameraTemporalNoiseReductionMode", + "FaceTimePhotosOptIn", + "FaceTimePreferredDecoding", + "FaceTimePreferredEncoding", + "FirmwareNonce", + "FirmwarePreflightInfo", + "FirmwareVersion", + "FirstPartyLaunchTimeLimitScale", + "ForwardCameraCapability", + "FrontCameraOffsetFromDisplayCenter", + "FrontCameraRotationFromDisplayNormal", + "FrontFacingCameraAutoHDRCapability", + "FrontFacingCameraBurstCapability", + "FrontFacingCameraCapability", + "FrontFacingCameraHDRCapability", + "FrontFacingCameraHDROnCapability", + "FrontFacingCameraHFRCapability", + "FrontFacingCameraHFRVideoCapture1080pMaxFPS", + "FrontFacingCameraHFRVideoCapture720pMaxFPS", + "FrontFacingCameraMaxVideoZoomFactor", + "FrontFacingCameraModuleSerialNumber", + "FrontFacingCameraStillDurationForBurst", + "FrontFacingCameraVideoCapture1080pMaxFPS", + "FrontFacingCameraVideoCapture4kMaxFPS", + "FrontFacingCameraVideoCapture720pMaxFPS", + "FrontFacingIRCameraModuleSerialNumber", + "FrontFacingIRStructuredLightProjectorModuleSerialNumber", + "Full6FeaturesCapability", + "GPSCapability", + "GSDeviceName", + "GameKitCapability", + "GasGaugeBatteryCapability", + "GreenTeaDeviceCapability", + "GyroscopeCapability", + "H264EncoderCapability", + "HDRImageCaptureCapability", + "HDVideoCaptureCapability", + "HEVCDecoder10bitSupported", + "HEVCDecoder12bitSupported", + "HEVCDecoder8bitSupported", + "HEVCEncodingCapability", + "HMERefreshRateInARKit", + "HWModelStr", + "HallEffectSensorCapability", + "HardwareEncodeSnapshotsCapability", + "HardwareKeyboardCapability", + "HardwarePlatform", + "HardwareSnapshotsRequirePurpleGfxCapability", + "HasAllFeaturesCapability", + "HasAppleNeuralEngine", + "HasBaseband", + "HasBattery", + "HasDaliMode", + "HasExtendedColorDisplay", + "HasIcefall", + "HasInternalSettingsBundle", + "HasMesa", + "HasPKA", + "HasSEP", + "HasSpringBoard", + "HasThinBezel", + "HealthKitCapability", + "HearingAidAudioEqualizationCapability", + "HearingAidLowEnergyAudioCapability", + "HearingAidPowerReductionCapability", + "HiDPICapability", + "HiccoughInterval", + "HideNonDefaultApplicationsCapability", + "HighestSupportedVideoMode", + "HomeButtonType", + "HomeScreenWallpaperCapability", + "IDAMCapability", + "IOSurfaceBackedImagesCapability", + "IOSurfaceFormatDictionary", + "IceFallID", + "IcefallInRestrictedMode", + "IcefallInfo", + "Image4CryptoHashMethod", + "Image4Supported", + "InDiagnosticsMode", + "IntegratedCircuitCardIdentifier", + "IntegratedCircuitCardIdentifier2", + "InternalBuild", + "InternationalMobileEquipmentIdentity", + "InternationalMobileEquipmentIdentity2", + "InternationalSettingsCapability", + "InverseDeviceID", + "IsEmulatedDevice", + "IsLargeFormatPhone", + "IsPwrOpposedVol", + "IsServicePart", + "IsSimulator", + "IsThereEnoughBatteryLevelForSoftwareUpdate", + "IsUIBuild", + "JasperSerialNumber", + "LTEDeviceCapability", + "LaunchTimeLimitScaleSupported", + "LisaCapability", + "LoadThumbnailsWhileScrollingCapability", + "LocalizedDeviceNameString", + "LocationRemindersCapability", + "LocationServicesCapability", + "LowPowerWalletMode", + "LunaFlexSerialNumber", + "LynxPublicKey", + "LynxSerialNumber", + "MLBSerialNumber", + "MLEHW", + "MMSCapability", + "MacBridgingKeys", + "MagnetometerCapability", + "MainDisplayRotation", + "MainScreenCanvasSizes", + "MainScreenClass", + "MainScreenHeight", + "MainScreenOrientation", + "MainScreenPitch", + "MainScreenScale", + "MainScreenStaticInfo", + "MainScreenWidth", + "MarketingNameString", + "MarketingProductName", + "MarketingVersion", + "MaxH264PlaybackLevel", + "MaximumScreenScale", + "MedusaFloatingLiveAppCapability", + "MedusaOverlayAppCapability", + "MedusaPIPCapability", + "MedusaPinnedAppCapability", + "MesaSerialNumber", + "MetalCapability", + "MicrophoneCapability", + "MicrophoneCount", + "MinimumSupportediTunesVersion", + "MixAndMatchPrevention", + "MobileDeviceMinimumVersion", + "MobileEquipmentIdentifier", + "MobileEquipmentInfoBaseId", + "MobileEquipmentInfoBaseProfile", + "MobileEquipmentInfoBaseVersion", + "MobileEquipmentInfoCSN", + "MobileEquipmentInfoDisplayCSN", + "MobileSubscriberCountryCode", + "MobileSubscriberNetworkCode", + "MobileWifi", + "ModelNumber", + "MonarchLowEndHardware", + "MultiLynxPublicKeyArray", + "MultiLynxSerialNumberArray", + "MultitaskingCapability", + "MultitaskingGesturesCapability", + "MusicStore", + "MusicStoreCapability", + "N78aHack", + "NFCRadio", + "NFCRadioCalibrationDataPresent", + "NFCUniqueChipID", + "NVRAMDictionary", + "NandControllerUID", + "NavajoFusingState", + "NikeIpodCapability", + "NotGreenTeaDeviceCapability", + "OLEDDisplay", + "OTAActivationCapability", + "OfflineDictationCapability", + "OpenGLES1Capability", + "OpenGLES2Capability", + "OpenGLES3Capability", + "OpenGLESVersion", + "PTPLargeFilesCapability", + "PanelSerialNumber", + "PanoramaCameraCapability", + "PartitionType", + "PasswordConfigured", + "PasswordProtected", + "PearlCameraCapability", + "PearlIDCapability", + "PeekUICapability", + "PeekUIWidth", + "Peer2PeerCapability", + "PersonalHotspotCapability", + "PhoneNumber", + "PhoneNumber2", + "PhosphorusCapability", + "PhotoAdjustmentsCapability", + "PhotoCapability", + "PhotoSharingCapability", + "PhotoStreamCapability", + "PhotosPostEffectsCapability", + "PiezoClickerCapability", + "PintoMacAddress", + "PintoMacAddressData", + "PipelinedStillImageProcessingCapability", + "PlatformStandAloneContactsCapability", + "PlatinumCapability", + "ProductHash", + "ProductName", + "ProductType", + "ProductVersion", + "ProximitySensorCalibration", + "ProximitySensorCalibrationDictionary", + "ProximitySensorCapability", + "RF-exposure-separation-distance", + "RFExposureSeparationDistance", + "RawPanelSerialNumber", + "RearCameraCapability", + "RearCameraOffsetFromDisplayCenter", + "RearFacingCamera60fpsVideoCaptureCapability", + "RearFacingCameraAutoHDRCapability", + "RearFacingCameraBurstCapability", + "RearFacingCameraCapability", + "RearFacingCameraHDRCapability", + "RearFacingCameraHDROnCapability", + "RearFacingCameraHFRCapability", + "RearFacingCameraHFRVideoCapture1080pMaxFPS", + "RearFacingCameraHFRVideoCapture720pMaxFPS", + "RearFacingCameraMaxVideoZoomFactor", + "RearFacingCameraModuleSerialNumber", + "RearFacingCameraStillDurationForBurst", + "RearFacingCameraSuperWideCameraCapability", + "RearFacingCameraTimeOfFlightCameraCapability", + "RearFacingCameraVideoCapture1080pMaxFPS", + "RearFacingCameraVideoCapture4kMaxFPS", + "RearFacingCameraVideoCapture720pMaxFPS", + "RearFacingCameraVideoCaptureFPS", + "RearFacingLowLightCameraCapability", + "RearFacingSuperWideCameraModuleSerialNumber", + "RearFacingTelephotoCameraCapability", + "RearFacingTelephotoCameraModuleSerialNumber", + "RecoveryOSVersion", + "RegionCode", + "RegionInfo", + "RegionSupportsCinnamon", + "RegionalBehaviorAll", + "RegionalBehaviorChinaBrick", + "RegionalBehaviorEUVolumeLimit", + "RegionalBehaviorGB18030", + "RegionalBehaviorGoogleMail", + "RegionalBehaviorNTSC", + "RegionalBehaviorNoPasscodeLocationTiles", + "RegionalBehaviorNoVOIP", + "RegionalBehaviorNoWiFi", + "RegionalBehaviorShutterClick", + "RegionalBehaviorValid", + "RegionalBehaviorVolumeLimit", + "RegulatoryModelNumber", + "ReleaseType", + "RemoteBluetoothAddress", + "RemoteBluetoothAddressData", + "RenderWideGamutImagesAtDisplayTime", + "RendersLetterPressSlowly", + "RequiredBatteryLevelForSoftwareUpdate", + "RestoreOSBuild", + "RestrictedCountryCodes", + "RingerSwitchCapability", + "RosalineSerialNumber", + "RoswellChipID", + "RotateToWakeStatus", + "SBAllowSensitiveUI", + "SBCanForceDebuggingInfo", + "SDIOManufacturerTuple", + "SDIOProductInfo", + "SEInfo", + "SEPNonce", + "SIMCapability", + "SIMPhonebookCapability", + "SIMStatus", + "SIMStatus2", + "SIMTrayStatus", + "SIMTrayStatus2", + "SMSCapability", + "SavageChipID", + "SavageInfo", + "SavageSerialNumber", + "SavageUID", + "ScreenDimensions", + "ScreenDimensionsCapability", + "ScreenRecorderCapability", + "ScreenSerialNumber", + "SecondaryBluetoothMacAddress", + "SecondaryBluetoothMacAddressData", + "SecondaryEthernetMacAddress", + "SecondaryEthernetMacAddressData", + "SecondaryWifiMacAddress", + "SecondaryWifiMacAddressData", + "SecureElement", + "SecureElementID", + "SecurityDomain", + "SensitiveUICapability", + "SerialNumber", + "ShoeboxCapability", + "ShouldHactivate", + "SiKACapability", + "SigningFuse", + "SiliconBringupBoard", + "SimultaneousCallAndDataCurrentlySupported", + "SimultaneousCallAndDataSupported", + "SiriGestureCapability", + "SiriOfflineCapability", + "Skey", + "SoftwareBehavior", + "SoftwareBundleVersion", + "SoftwareDimmingAlpha", + "SpeakerCalibrationMiGa", + "SpeakerCalibrationSpGa", + "SpeakerCalibrationSpTS", + "SphereCapability", + "StarkCapability", + "StockholmJcopInfo", + "StrictWakeKeyboardCases", + "SupportedDeviceFamilies", + "SupportedKeyboards", + "SupportsBurninMitigation", + "SupportsEDUMU", + "SupportsForceTouch", + "SupportsIrisCapture", + "SupportsLowPowerMode", + "SupportsPerseus", + "SupportsRotateToWake", + "SupportsSOS", + "SupportsSSHBButtonType", + "SupportsTouchRemote", + "SysCfg", + "SysCfgDict", + "SystemImageID", + "SystemTelephonyOfAnyKindCapability", + "TVOutCrossfadeCapability", + "TVOutSettingsCapability", + "TelephonyCapability", + "TelephonyMaximumGeneration", + "TimeSyncCapability", + "TopModuleAuthChipID", + "TouchDelivery120Hz", + "TouchIDCapability", + "TristarID", + "UIBackgroundQuality", + "UIParallaxCapability", + "UIProceduralWallpaperCapability", + "UIReachability", + "UMTSDeviceCapability", + "UnifiedIPodCapability", + "UniqueChipID", + "UniqueDeviceID", + "UniqueDeviceIDData", + "UserAssignedDeviceName", + "UserIntentPhysicalButtonCGRect", + "UserIntentPhysicalButtonCGRectString", + "UserIntentPhysicalButtonNormalizedCGRect", + "VOIPCapability", + "VeniceCapability", + "VibratorCapability", + "VideoCameraCapability", + "VideoStillsCapability", + "VoiceControlCapability", + "VolumeButtonCapability", + "WAGraphicQuality", + "WAPICapability", + "WLANBkgScanCache", + "WSKU", + "WatchCompanionCapability", + "WatchSupportsAutoPlaylistPlayback", + "WatchSupportsHighQualityClockFaceGraphics", + "WatchSupportsListeningOnGesture", + "WatchSupportsMusicStreaming", + "WatchSupportsSiriCommute", + "WiFiCallingCapability", + "WiFiCapability", + "WifiAddress", + "WifiAddressData", + "WifiAntennaSKUVersion", + "WifiCallingSecondaryDeviceCapability", + "WifiChipset", + "WifiFirmwareVersion", + "WifiVendor", + "WirelessBoardSnum", + "WirelessChargingCapability", + "YonkersChipID", + "YonkersSerialNumber", + "YonkersUID", + "YouTubeCapability", + "YouTubePluginCapability", + "accelerometer", + "accessibility", + "additional-text-tones", + "aggregate-cam-photo-zoom", + "aggregate-cam-video-zoom", + "airDropRestriction", + "airplay-mirroring", + "airplay-no-mirroring", + "all-features", + "allow-32bit-apps", + "ambient-light-sensor", + "ane", + "any-telephony", + "apn", + "apple-internal-install", + "applicationInstallation", + "arkit", + "arm64", + "armv6", + "armv7", + "armv7s", + "assistant", + "auto-focus", + "auto-focus-camera", + "baseband-chipset", + "bitrate-2g", + "bitrate-3g", + "bitrate-lte", + "bitrate-wifi", + "bluetooth", + "bluetooth-le", + "board-id", + "boot-manifest-hash", + "boot-nonce", + "builtin-mics", + "c2k-device", + "calibration", + "call-forwarding", + "call-waiting", + "caller-id", + "camera-flash", + "camera-front", + "camera-front-flash", + "camera-rear", + "cameraRestriction", + "car-integration", + "cell-broadcast", + "cellular-data", + "certificate-production-status", + "certificate-security-mode", + "chip-id", + "class", + "closed-loop", + "config-number", + "contains-cellular-radio", + "crypto-hash-method", + "dali-mode", + "data-plan", + "debug-board-revision", + "delay-sleep-for-headset-click", + "device-color-policy", + "device-colors", + "device-name", + "device-name-localized", + "dictation", + "die-id", + "display-mirroring", + "display-rotation", + "displayport", + "does-not-support-gamekit", + "effective-production-status", + "effective-production-status-ap", + "effective-production-status-sep", + "effective-security-mode", + "effective-security-mode-ap", + "effective-security-mode-sep", + "enc-top-type", + "encode-aac", + "encrypted-data-partition", + "enforce-googlemail", + "enforce-shutter-click", + "euicc-chip-id", + "explicitContentRestriction", + "face-detection-support", + "fast-switch-options", + "fcc-logos-via-software", + "fcm-type", + "firmware-version", + "flash", + "front-auto-hdr", + "front-burst", + "front-burst-image-duration", + "front-facing-camera", + "front-flash-capability", + "front-hdr", + "front-hdr-on", + "front-max-video-fps-1080p", + "front-max-video-fps-4k", + "front-max-video-fps-720p", + "front-max-video-zoom", + "front-slowmo", + "full-6", + "function-button_halleffect", + "function-button_ringerab", + "gamekit", + "gas-gauge-battery", + "gps", + "gps-capable", + "green-tea", + "gyroscope", + "h264-encoder", + "hall-effect-sensor", + "haptics", + "hardware-keyboard", + "has-sphere", + "hd-video-capture", + "hdr-image-capture", + "healthkit", + "hearingaid-audio-equalization", + "hearingaid-low-energy-audio", + "hearingaid-power-reduction", + "hiccough-interval", + "hide-non-default-apps", + "hidpi", + "home-button-type", + "homescreen-wallpaper", + "hw-encode-snapshots", + "hw-snapshots-need-purplegfx", + "iAP2Capability", + "iPadCapability", + "iTunesFamilyID", + "iap2-protocol-supported", + "image4-supported", + "international-settings", + "io-surface-backed-images", + "ipad", + "kConferenceCallType", + "kSimultaneousCallAndDataCurrentlySupported", + "kSimultaneousCallAndDataSupported", + "large-format-phone", + "live-effects", + "live-photo-capture", + "load-thumbnails-while-scrolling", + "location-reminders", + "location-services", + "low-power-wallet-mode", + "lte-device", + "magnetometer", + "main-screen-class", + "main-screen-height", + "main-screen-orientation", + "main-screen-pitch", + "main-screen-scale", + "main-screen-width", + "marketing-name", + "mesa", + "metal", + "microphone", + "mix-n-match-prevention-status", + "mms", + "modelIdentifier", + "multi-touch", + "multitasking", + "multitasking-gestures", + "n78a-mode", + "name", + "navigation", + "nfc", + "nfcWithRadio", + "nike-ipod", + "nike-support", + "no-coreroutine", + "no-hi-res-buildings", + "no-simplistic-road-mesh", + "not-green-tea", + "offline-dictation", + "opal", + "opengles-1", + "opengles-2", + "opengles-3", + "opposed-power-vol-buttons", + "ota-activation", + "panorama", + "peek-ui-width", + "peer-peer", + "personal-hotspot", + "photo-adjustments", + "photo-stream", + "piezo-clicker", + "pipelined-stillimage-capability", + "platinum", + "post-effects", + "pressure", + "prox-sensor", + "proximity-sensor", + "ptp-large-files", + "public-key-accelerator", + "rear-auto-hdr", + "rear-burst", + "rear-burst-image-duration", + "rear-cam-telephoto-capability", + "rear-facing-camera", + "rear-hdr", + "rear-hdr-on", + "rear-max-slomo-video-fps-1080p", + "rear-max-slomo-video-fps-720p", + "rear-max-video-fps-1080p", + "rear-max-video-fps-4k", + "rear-max-video-fps-720p", + "rear-max-video-frame_rate", + "rear-max-video-zoom", + "rear-slowmo", + "regulatory-model-number", + "ringer-switch", + "role", + "s8000\")", + "s8003\")", + "sandman-support", + "screen-dimensions", + "sensitive-ui", + "shoebox", + "sika-support", + "sim", + "sim-phonebook", + "siri-gesture", + "slow-letterpress-rendering", + "sms", + "software-bundle-version", + "software-dimming-alpha", + "stand-alone-contacts", + "still-camera", + "stockholm", + "supports-always-listening", + "t7000\")", + "telephony", + "telephony-maximum-generation", + "thin-bezel", + "tnr-mode-back", + "tnr-mode-front", + "touch-id", + "tv-out-crossfade", + "tv-out-settings", + "ui-background-quality", + "ui-no-parallax", + "ui-no-procedural-wallpaper", + "ui-pip", + "ui-reachability", + "ui-traffic-cheap-shaders", + "ui-weather-quality", + "umts-device", + "unified-ipod", + "unique-chip-id", + "venice", + "video-camera", + "video-cap", + "video-stills", + "voice-control", + "voip", + "volume-buttons", + "wapi", + "watch-companion", + "wi-fi", + "wifi", + "wifi-antenna-sku-info", + "wifi-chipset", + "wifi-module-sn", + "wlan", + "wlan.background-scan-cache", + "youtube", + "youtubePlugin"}; // Create checkboxes for each key for (const QString &key : mobileGestaltKeys) { diff --git a/src/recoverydeviceinfowidget.cpp b/src/recoverydeviceinfowidget.cpp index ecf8f70..ca54223 100644 --- a/src/recoverydeviceinfowidget.cpp +++ b/src/recoverydeviceinfowidget.cpp @@ -1,5 +1,4 @@ #include "recoverydeviceinfowidget.h" -#include "./core/helpers/parse_recovery_mode.cpp" #include "iDescriptor.h" #include "libirecovery.h" #include diff --git a/src/toolboxwidget.cpp b/src/toolboxwidget.cpp index d3dba2e..d64625a 100644 --- a/src/toolboxwidget.cpp +++ b/src/toolboxwidget.cpp @@ -124,10 +124,8 @@ void ToolboxWidget::setupUI() QWidget *faceIdBox = createToolbox("Face ID Test", "Test Face ID functionality", "SP_DialogOkButton", true); - QWidget *mountDevImage = createToolbox( - "Mount Dev Image", "Mount a device image", "SP_DialogOkButton", true); QWidget *unmountDevImage = - createToolbox("Unmount Dev Image", "Unmount a device image", + createToolbox("Unmount Dev Image", "Unmount a developer image", "SP_DialogOkButton", true); QWidget *enterRecoveryMode = createToolbox("Enter Recovery Mode", "Enter device recovery mode", @@ -148,9 +146,8 @@ void ToolboxWidget::setupUI() m_gridLayout->addWidget(touchIdBox, 2, 1); m_gridLayout->addWidget(faceIdBox, 2, 2); m_gridLayout->addWidget(enterRecoveryMode, 3, 0); - m_gridLayout->addWidget(mountDevImage, 3, 1); - m_gridLayout->addWidget(unmountDevImage, 3, 2); - m_gridLayout->addWidget(devDiskImages, 4, 0, 1, 3); + m_gridLayout->addWidget(unmountDevImage, 3, 1); + m_gridLayout->addWidget(devDiskImages, 3, 2); m_gridLayout->setRowStretch(3, 1); @@ -380,12 +377,27 @@ void ToolboxWidget::onToolboxClicked(const QString &toolName) queryMobileGestaltWidget->show(); } else if (toolName == "Developer Disk Images") { // Handle developer disk images - DevDiskImagesWidget *devDiskImagesWidget = - new DevDiskImagesWidget(m_currentDevice); - devDiskImagesWidget->setAttribute(Qt::WA_DeleteOnClose); - devDiskImagesWidget->setWindowFlag(Qt::Window); - devDiskImagesWidget->resize(800, 600); - devDiskImagesWidget->show(); + if (!m_devDiskImagesWidget) { + m_devDiskImagesWidget = new DevDiskImagesWidget(m_currentDevice); + m_devDiskImagesWidget->setAttribute(Qt::WA_DeleteOnClose); + m_devDiskImagesWidget->setWindowFlag(Qt::Window); + m_devDiskImagesWidget->resize(800, 600); + connect(m_devDiskImagesWidget, &QObject::destroyed, this, + [this]() { m_devDiskImagesWidget = nullptr; }); + m_devDiskImagesWidget->show(); + } else { + m_devDiskImagesWidget->raise(); + m_devDiskImagesWidget->activateWindow(); + } + } else if (toolName == "Touch ID Test") { + // Handle Touch ID test + QMessageBox::information( + this, "Touch ID Test", + "Touch ID test functionality not implemented."); + } else if (toolName == "Face ID Test") { + // Handle Face ID test + QMessageBox::information(this, "Face ID Test", + "Face ID test functionality not implemented."); } // Implement specific tool functionality here } diff --git a/src/toolboxwidget.h b/src/toolboxwidget.h index 06c785a..901bff4 100644 --- a/src/toolboxwidget.h +++ b/src/toolboxwidget.h @@ -1,6 +1,7 @@ #ifndef TOOLBOXWIDGET_H #define TOOLBOXWIDGET_H +#include "devdiskimageswidget.h" #include "iDescriptor.h" #include #include @@ -40,6 +41,7 @@ private: QList m_requiresDevice; iDescriptorDevice *m_currentDevice; std::string m_uuid; + DevDiskImagesWidget *m_devDiskImagesWidget; signals: };