merge com.apple.disk_usage dict and update DeviceInfo struct

This commit is contained in:
uncor3
2025-07-28 06:55:02 +00:00
parent 5a04a9a03c
commit f725f06165
2 changed files with 117 additions and 36 deletions
+25 -28
View File
@@ -70,46 +70,44 @@ plist_t get_device_info(const char *udid, int use_network, int simple,
idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
plist_t node = NULL;
#ifndef _WIN32
signal(SIGPIPE, SIG_IGN);
#endif
// FIXME: network support does not properly work yet
// ret = idevice_new_with_options(&device, udid, (use_network) ?
// IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX);
ret = idevice_new_with_options(&device, udid, IDEVICE_LOOKUP_USBMUX);
if (ret != IDEVICE_E_SUCCESS) {
if (udid) {
fprintf(stderr, "ERROR: Device %s not found!\n", udid);
} else {
fprintf(stderr, "ERROR: No device found!\n");
}
return NULL;
}
if (LOCKDOWN_E_SUCCESS !=
(ldret = simple ? lockdownd_client_new(device, &client, "iDescriptor")
: lockdownd_client_new_with_handshake(device, &client,
"iDescriptor"))) {
fprintf(stderr, "ERROR: Could not connect to lockdownd: %s (%d)\n",
lockdownd_strerror(ldret), ldret);
return NULL;
}
/* run query and output information */
if (lockdownd_get_value(client, NULL, NULL, &node) != LOCKDOWN_E_SUCCESS) {
fprintf(stderr, "ERROR: Could not get value\n");
}
plist_t disk_info = nullptr;
u_int64_t total_space = 0;
u_int64_t free_space = 0;
/* {
"AmountDataAvailable": 6663077888,
"AmountDataReserved": 209715200,
"AmountRestoreAvailable": 11524079616,
"CalculateDiskUsage": "OkilyDokily",
"NANDInfo": <01000000 01000000 01000000 00000080 ... 00 00000000 000000>,
"TotalDataAvailable": 6872793088,
"TotalDataCapacity": 11306721280,
"TotalDiskCapacity": 16000000000,
"TotalSystemAvailable": 0,
"TotalSystemCapacity": 4693204992
}*/
/* trying to set DiskInfo as key results in
xplist.c:365: node_to_xml: Assertion `(node->children->count % 2) == 0'
failed. so lets do merge it*/
if (lockdownd_get_value(client, "com.apple.disk_usage", nullptr,
&disk_info) == LOCKDOWN_E_SUCCESS) {
// merge dict
plist_dict_merge(&node, disk_info);
plist_free(disk_info);
}
return node;
}
// Change return type to void
void get_device_info_xml(const char *udid, int use_network, int simple,
pugi::xml_document &infoXml, lockdownd_client_t client,
idevice_t device)
{
plist_t node = get_device_info(udid, use_network, simple, client, device);
if (!node)
return;
@@ -122,5 +120,4 @@ void get_device_info_xml(const char *udid, int use_network, int simple,
infoXml.load_string(xml_string);
free(xml_string);
}
// No return statement needed
}
+92 -8
View File
@@ -4,14 +4,15 @@
#include "./get-device-info.cpp"
#include "libirecovery.h"
#include <QDebug>
#include <libimobiledevice/diagnostics_relay.h>
#include <libimobiledevice/libimobiledevice.h>
#include <libimobiledevice/lockdown.h>
#include <pugixml.hpp>
DeviceInfo xmlToDeviceInfo(const pugi::xml_document &doc,
afc_client_t afcClient)
DeviceInfo fullDeviceInfo(const pugi::xml_document &doc,
afc_client_t &afcClient, plist_t &diagnostics,
DeviceInfo &d)
{
DeviceInfo d;
pugi::xml_node dict = doc.child("plist").child("dict");
auto safeGet = [&](const char *key) -> std::string {
@@ -26,6 +27,7 @@ DeviceInfo xmlToDeviceInfo(const pugi::xml_document &doc,
}
return "";
};
d.deviceName = safeGet("DeviceName");
d.deviceClass = safeGet("DeviceClass");
d.deviceColor = safeGet("DeviceColor");
@@ -38,7 +40,25 @@ DeviceInfo xmlToDeviceInfo(const pugi::xml_document &doc,
d.bluetoothAddress = safeGet("BluetoothAddress");
d.firmwareVersion = safeGet("FirmwareVersion");
d.productVersion = safeGet("ProductVersion");
/*DiskInfo*/
try {
d.diskInfo.totalDiskCapacity =
std::stoull(safeGet("TotalDiskCapacity"));
d.diskInfo.totalDataCapacity =
std::stoull(safeGet("TotalDataCapacity"));
d.diskInfo.totalSystemCapacity =
std::stoull(safeGet("TotalSystemCapacity"));
d.diskInfo.totalDataAvailable =
std::stoull(safeGet("TotalDataAvailable"));
} catch (const std::exception &e) {
qDebug() << e.what();
/*It's ok if any of those fails*/
}
std::string _activationState = safeGet("ActivationState");
// TODO: does "ProductionSOC: true" work as well ?
d.productionDevice = std::stoi(safeGet("FusingStatus")) == 3;
if (_activationState == "Activated") {
d.activationState = DeviceInfo::ActivationState::Activated;
} else if (_activationState == "FactoryActivated") {
@@ -49,10 +69,42 @@ DeviceInfo xmlToDeviceInfo(const pugi::xml_document &doc,
d.activationState =
DeviceInfo::ActivationState::Unactivated; // Default value
}
// TODO:RegionInfo: LL/A
d.productType = parse_product_type(safeGet("ProductType"));
d.jailbroken = detect_jailbroken(
afcClient); // Default value, can be set later if needed
// d.udid = safeGet("UniqueDeviceID");
d.jailbroken = detect_jailbroken(afcClient);
uint64_t cycleCount;
plist_get_uint_val(
PlistNavigator(diagnostics)["IORegistry"]["BatteryData"]["CycleCount"],
&cycleCount);
char *batterySerialNumber;
plist_get_string_val(
PlistNavigator(
diagnostics)["IORegistry"]["BatteryData"]["BatterySerialNumber"],
&batterySerialNumber);
uint64_t designCapacity;
plist_get_uint_val(
PlistNavigator(
diagnostics)["IORegistry"]["BatteryData"]["DesignCapacity"],
&designCapacity);
uint64_t absoluteCapacity;
plist_get_uint_val(
PlistNavigator(diagnostics)["IORegistry"]["AbsoluteCapacity"],
&absoluteCapacity);
d.batteryInfo.health =
QString::number((absoluteCapacity * 100) / designCapacity) + "%";
d.batteryInfo.cycleCount = cycleCount;
d.batteryInfo.serialNumber = batterySerialNumber
? batterySerialNumber
: "Error retrieving serial number";
plist_free(diagnostics);
diagnostics = nullptr;
return d;
}
@@ -65,6 +117,7 @@ IDescriptorInitDeviceResult init_idescriptor_device(const char *udid)
lockdownd_client_t client;
lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR;
lockdownd_service_descriptor_t lockdownService = nullptr;
diagnostics_relay_client_t diagnostics_client = nullptr;
afc_client_t afcClient = nullptr;
try {
idevice_error_t ret = idevice_new_with_options(&result.device, udid,
@@ -108,6 +161,35 @@ IDescriptorInitDeviceResult init_idescriptor_device(const char *udid)
return result;
}
if (diagnostics_relay_client_start_service(
result.device, &diagnostics_client, nullptr) !=
DIAGNOSTICS_RELAY_E_SUCCESS) {
qDebug() << "Failed to start diagnostics relay service.";
return result;
}
plist_t diagnostics = nullptr;
// TODO: iPhone 8 and above should query AppleSmartBattery
if (diagnostics_relay_query_ioregistry_entry(
diagnostics_client, nullptr, "AppleARMPMUCharger",
&diagnostics) != DIAGNOSTICS_RELAY_E_SUCCESS &&
!diagnostics) {
qDebug()
<< "Failed to query diagnostics relay for AppleARMPMUCharger.";
// Clean up resources before returning
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;
}
pugi::xml_document infoXml;
get_device_info_xml(udid, 0, 0, infoXml, client, result.device);
@@ -124,7 +206,7 @@ IDescriptorInitDeviceResult init_idescriptor_device(const char *udid)
// if (result.device) idevice_free(result.device);
result.deviceInfo = xmlToDeviceInfo(infoXml, afcClient);
fullDeviceInfo(infoXml, afcClient, diagnostics, result.deviceInfo);
result.success = true;
if (afcClient)
@@ -133,6 +215,8 @@ IDescriptorInitDeviceResult init_idescriptor_device(const char *udid)
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) {
@@ -168,4 +252,4 @@ init_idescriptor_recovery_device(irecv_device_info *info)
result.success = true;
return result;
}
}