diff --git a/src/core/services/init_device.cpp b/src/core/services/init_device.cpp index 17856bd..8a293c3 100644 --- a/src/core/services/init_device.cpp +++ b/src/core/services/init_device.cpp @@ -4,21 +4,35 @@ #include #include #include -#include -std::string safeGet(const char *key, pugi::xml_node dict) +std::string safeGetXML(const char *key, pugi::xml_node dict) { for (pugi::xml_node child = dict.first_child(); child; child = child.next_sibling()) { if (strcmp(child.name(), "key") == 0 && strcmp(child.text().as_string(), key) == 0) { pugi::xml_node value = child.next_sibling(); - if (value) - return value.text().as_string(); + if (value) { + // Handle different XML element types + if (strcmp(value.name(), "true") == 0) { + return "true"; + } else if (strcmp(value.name(), "false") == 0) { + return "false"; + } else if (strcmp(value.name(), "integer") == 0) { + return value.text().as_string(); + } else if (strcmp(value.name(), "string") == 0) { + return value.text().as_string(); + } else if (strcmp(value.name(), "real") == 0) { + return value.text().as_string(); + } else { + // For any other type, try to get the text content + return value.text().as_string(); + } + } } } return ""; -}; +} // TODO: return tyype DeviceInfo fullDeviceInfo(const pugi::xml_document &doc, @@ -220,10 +234,10 @@ IDescriptorInitDeviceResult init_idescriptor_device(const char *udid) plist_t diagnostics = nullptr; std::string productType = - safeGet("ProductType", infoXml.child("plist").child("dict")); + safeGetXML("ProductType", infoXml.child("plist").child("dict")); bool is_iphone = - safeGet("DeviceClass", infoXml.child("plist").child("dict")) == + safeGetXML("DeviceClass", infoXml.child("plist").child("dict")) == "iPhone"; if (is_iphone) { diff --git a/src/core/services/query_mobilegestalt.cpp b/src/core/services/query_mobilegestalt.cpp index e69de29..0e73b30 100644 --- a/src/core/services/query_mobilegestalt.cpp +++ b/src/core/services/query_mobilegestalt.cpp @@ -0,0 +1,51 @@ +#include "../../iDescriptor.h" +#include "libimobiledevice/diagnostics_relay.h" +#include +#include + +bool query_mobile_gestalt(iDescriptorDevice *id_device, const QStringList &keys, + uint32_t &xml_size, char *&xml_data) +{ + if (!id_device) { + qDebug() << "Invalid device"; + return false; + } + + diagnostics_relay_client_t diagnostics_client = nullptr; + if (diagnostics_relay_client_start_service(id_device->device, + &diagnostics_client, nullptr) != + DIAGNOSTICS_RELAY_E_SUCCESS) { + qDebug() << "Failed to start diagnostics service"; + return false; + } + + plist_t result = nullptr; + plist_t keys_array = plist_new_array(); + for (const QString &key : keys) { + plist_t key_node = plist_new_string(key.toStdString().c_str()); + plist_array_append_item(keys_array, key_node); + } + + diagnostics_relay_error_t err = diagnostics_relay_query_mobilegestalt( + diagnostics_client, keys_array, &result); + + plist_free(keys_array); // Free the keys array + + if (err != DIAGNOSTICS_RELAY_E_SUCCESS) { + qDebug() << "Failed to query mobile gestalt"; + diagnostics_relay_client_free(diagnostics_client); + return false; + } + + if (!result) { + qDebug() << "No result from mobile gestalt query"; + diagnostics_relay_client_free(diagnostics_client); + return false; + } + + plist_to_xml(result, &xml_data, &xml_size); + plist_free(result); // Free the result plist + diagnostics_relay_client_free(diagnostics_client); + + return true; +} diff --git a/src/querymobilegestaltwidget.cpp b/src/querymobilegestaltwidget.cpp index 245eb82..1560dc2 100644 --- a/src/querymobilegestaltwidget.cpp +++ b/src/querymobilegestaltwidget.cpp @@ -3,9 +3,11 @@ #include #include #include +#include -QueryMobileGestaltWidget::QueryMobileGestaltWidget(QWidget *parent) - : QWidget(parent) +QueryMobileGestaltWidget::QueryMobileGestaltWidget(iDescriptorDevice *device, + QWidget *parent) + : QWidget(parent), m_device(device) { setupUI(); populateKeys(); @@ -1137,28 +1139,36 @@ void QueryMobileGestaltWidget::displayResults( QMap QueryMobileGestaltWidget::queryMobileGestalt(const QStringList &keys) { + char *xml = nullptr; + uint32_t xmlLength = 0; + bool res = query_mobile_gestalt(m_device, keys, xmlLength, xml); + if (!res) { + qDebug() << "MobileGestalt query failed."; + return {}; + } // This is a mock implementation // Replace this with your actual query function that takes a plist dict + pugi::xml_document infoXml; + pugi::xml_parse_result result = infoXml.load_string(xml); + if (xml) + free(xml); + if (!result) { + qDebug() << "Failed to parse XML:" << result.description(); + return {}; + } + pugi::xml_node dictNode = + infoXml.child("plist").child("dict").child("key").next_sibling("dict"); + if (!dictNode) { + qDebug() << "No MobileGestalt node found in XML."; + return {}; + } QMap results; - - // Example mock data - QMap mockData = { - {"DeviceName", "iPhone"}, {"ProductType", "iPhone14,2"}, - {"ProductVersion", "17.1.1"}, {"64-bit", true}, - {"DeviceSupportsCamera", true}, {"DeviceSupportsWiFi", true}, - {"DeviceClass", "iPhone"}, {"SerialNumber", "MOCK123456"}, - {"ModelNumber", "MLPG3"}, {"RegionCode", "US"}, - {"BuildVersion", "21B101"}}; - - // Return only the requested keys for (const QString &key : keys) { - if (mockData.contains(key)) { - results[key] = mockData[key]; - } else { - results[key] = "Not available"; + std::string value = safeGetXML(key.toStdString().c_str(), dictNode); + if (!value.empty()) { + results.insert(key, QString::fromStdString(value)); } } - return results; } \ No newline at end of file diff --git a/src/querymobilegestaltwidget.h b/src/querymobilegestaltwidget.h index 62e25d8..668f5eb 100644 --- a/src/querymobilegestaltwidget.h +++ b/src/querymobilegestaltwidget.h @@ -1,6 +1,7 @@ #ifndef QUERYMOBILEGESTALTWIDGET_H #define QUERYMOBILEGESTALTWIDGET_H +#include "iDescriptor.h" #include #include #include @@ -21,7 +22,8 @@ class QueryMobileGestaltWidget : public QWidget Q_OBJECT public: - QueryMobileGestaltWidget(QWidget *parent = nullptr); + QueryMobileGestaltWidget(iDescriptorDevice *device, + QWidget *parent = nullptr); private slots: void onQueryButtonClicked(); @@ -46,6 +48,7 @@ private: QPushButton *queryButton; QTextEdit *outputTextEdit; QLabel *statusLabel; + iDescriptorDevice *m_device; // Data QStringList mobileGestaltKeys;