Skip to content

Commit 5fa16f4

Browse files
committed
+ full PoC getting list dirs, upload file, download file, and delete file
! PoC works great
1 parent c46e16f commit 5fa16f4

3 files changed

Lines changed: 146 additions & 24 deletions

File tree

Src/devicebridge.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,16 @@ void DeviceBridge::StartServices()
297297
});
298298

299299
// For testing only
300+
qDebug() << "FileManager :: Inital";
301+
GetAccessibleStorage("/", "com.gameloft.asphalt9");
302+
303+
qDebug() << "FileManager :: Upload";
304+
UploadToStorage("C:\\Users\\hazmi\\Documents\\SimpleEntra.zip", "/Documents/SimpleUpload.zip", "com.gameloft.asphalt9");
305+
GetAccessibleStorage("/", "com.gameloft.asphalt9");
306+
DownloadFromStorage("/Documents/SimpleUpload.zip", "C:\\Users\\hazmi\\Documents\\SimpleDownload.zip", "com.gameloft.asphalt9");
307+
308+
qDebug() << "FileManager :: Delete";
309+
DeleteFromStorage("/Documents/SimpleUpload.zip", "com.gameloft.asphalt9");
300310
GetAccessibleStorage("/", "com.gameloft.asphalt9");
301311
}
302312

Src/devicebridge.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,15 @@ enum MessagesType {
6060
MSG_WARN
6161
};
6262

63+
enum GenericStatus {
64+
SUCCESS,
65+
FAILED,
66+
IN_PROGRESS,
67+
UPLOADED,
68+
DOWNLOADED,
69+
DELETED
70+
};
71+
6372
class DeviceBridge : public QObject
6473
{
6574
Q_OBJECT
@@ -122,12 +131,16 @@ class DeviceBridge : public QObject
122131
quint64 sizeInBytes = 0;
123132
};
124133
void GetAccessibleStorage(QString startPath = "/", QString bundleId = "");
134+
void UploadToStorage(QString localPath, QString devicePath, QString bundleId = "");
135+
void DownloadFromStorage(QString devicePath, QString localPath, QString bundleId = "");
136+
void DeleteFromStorage(QString devicePath, QString bundleId = "");
125137

126138
private:
127139
int afc_upload_file(afc_client_t &afc, const QString &filename, const QString &dstfn, std::function<void(uint32_t,uint32_t)> callback = nullptr);
128140
bool afc_upload_dir(afc_client_t &afc, const QString &path, const QString &afcpath, std::function<void(int,int,QString)> callback = nullptr);
129141
int afc_copy_crash_reports(afc_client_t &afc, const char* device_directory, const char* host_directory, const char* target_dir = nullptr, const char* filename_filter = nullptr);
130142
void afc_traverse_recursive(afc_client_t afc, const char* path);
143+
void afc_filemanager_action(std::function<void(afc_client_t &afc)> action, const QString& bundleId = "");
131144
afc_client_t m_afc;
132145
afc_client_t m_crashlog;
133146
afc_client_t m_fileManager;
@@ -137,6 +150,7 @@ class DeviceBridge : public QObject
137150
signals:
138151
void CrashlogsStatusChanged(QString messages);
139152
void AccessibleStorageReceived(QMap<QString, FileProperty> contents);
153+
void FileManagerChanged(GenericStatus status, int percentage, QString message);
140154

141155
//InstallerBridge
142156
public:

Src/devicebridge_afc.cpp

Lines changed: 122 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,37 +28,92 @@ void DeviceBridge::SyncCrashlogs(QString path)
2828

2929
void DeviceBridge::GetAccessibleStorage(QString startPath, QString bundleId)
3030
{
31-
AsyncManager::Get()->StartAsyncRequest([this, startPath, bundleId]() {
31+
afc_filemanager_action([&, this](afc_client_t& afc){
3232
m_accessibleStorage.clear();
33+
afc_traverse_recursive(afc, startPath.toStdString().c_str());
34+
emit AccessibleStorageReceived(m_accessibleStorage);
35+
}, bundleId);
36+
}
3337

34-
if (!bundleId.isEmpty()) {
35-
QStringList serviceIds = QStringList() << HOUSE_ARREST_SERVICE_NAME;
36-
StartLockdown(!m_houseArrest, serviceIds, [this, bundleId](QString& service_id, lockdownd_service_descriptor_t& service){
37-
house_arrest_error_t err = house_arrest_client_new(m_device, service, &m_houseArrest);
38-
if (err != HOUSE_ARREST_E_SUCCESS)
39-
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Could not connect to " + service_id + " client! " + QString::number(err));
38+
void DeviceBridge::UploadToStorage(QString localPath, QString devicePath, QString bundleId)
39+
{
40+
afc_filemanager_action([&, this](afc_client_t& afc){
41+
int percentage = 0;
42+
auto callback = [&](uint32_t uploaded_bytes, uint32_t total_bytes)
43+
{
44+
percentage = int((float(uploaded_bytes) / (float(total_bytes) * 2.f)) * 100.f);
45+
emit FileManagerChanged(GenericStatus::IN_PROGRESS, percentage, devicePath);
46+
};
47+
int result = afc_upload_file(afc, localPath, devicePath, callback);
48+
emit FileManagerChanged(result == 0 ? GenericStatus::UPLOADED : GenericStatus::FAILED, percentage, devicePath);
49+
}, bundleId);
50+
}
4051

41-
err = house_arrest_send_command(m_houseArrest, "VendContainer", bundleId.toUtf8().data());
42-
if (err != HOUSE_ARREST_E_SUCCESS)
43-
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Access Denied to " + bundleId + "'s VendContainer client! " + QString::number(err));
52+
void DeviceBridge::DownloadFromStorage(QString devicePath, QString localPath, QString bundleId)
53+
{
54+
afc_filemanager_action([&, this](afc_client_t& afc){
55+
int percentage = 0;
56+
int CHUNK_SIZE = 8192;
57+
uint64_t handle = 0;
58+
afc_error_t err = afc_file_open(afc, devicePath.toUtf8().data(), AFC_FOPEN_RDONLY, &handle);
59+
if (err != AFC_E_SUCCESS) {
60+
emit FileManagerChanged(GenericStatus::FAILED, percentage, devicePath);
61+
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Could not open remote file: " + devicePath + "! " + QString::number(err));
62+
return;
63+
}
4464

45-
afc_error_t aerr = afc_client_new_from_house_arrest_client(m_houseArrest, &m_fileManager);
46-
if (aerr != AFC_E_SUCCESS)
47-
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Could not connect to afc with " + service_id + " client! " + QString::number(aerr));
48-
});
49-
} else {
50-
QStringList serviceIds = QStringList() << AFC_SERVICE_NAME;
51-
StartLockdown(!m_fileManager, serviceIds, [this](QString& service_id, lockdownd_service_descriptor_t& service){
52-
afc_error_t aerr = afc_client_new(m_device, service, &m_fileManager);
53-
if (aerr != AFC_E_SUCCESS)
54-
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Could not connect to " + service_id + " client! " + QString::number(aerr));
55-
});
65+
FILE *f = fopen(localPath.toUtf8().data(), "wb");
66+
if (!f) {
67+
afc_file_close(afc, handle);
68+
emit FileManagerChanged(GenericStatus::FAILED, percentage, devicePath);
69+
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Could not open local file for writing: " + localPath + "! " + QString::number(err));
70+
return;
5671
}
5772

58-
afc_traverse_recursive(m_fileManager, startPath.toStdString().c_str());
73+
char **info = NULL;
74+
quint64 size_bytes = 0;
75+
if (afc_get_file_info(afc, devicePath.toUtf8().data(), &info) == AFC_E_SUCCESS && info)
76+
{
77+
for (int j = 0; info[j]; j += 2) {
78+
if (std::strcmp(info[j], "st_size") == 0) {
79+
// Convert string to uint64_t
80+
try {
81+
size_bytes = std::stoull(info[j + 1]);
82+
} catch (...) {
83+
size_bytes = 0;
84+
}
85+
}
86+
}
87+
afc_dictionary_free(info);
88+
}
5989

60-
emit AccessibleStorageReceived(m_accessibleStorage);
61-
});
90+
quint64 written_bytes = 0;
91+
uint32_t bytes_read = 0;
92+
char buffer[CHUNK_SIZE];
93+
while (afc_file_read(afc, handle, buffer, CHUNK_SIZE, &bytes_read) == AFC_E_SUCCESS && bytes_read > 0) {
94+
fwrite(buffer, 1, bytes_read, f);
95+
written_bytes += bytes_read;
96+
percentage = int((float(written_bytes) / (float(size_bytes) * 2.f)) * 100.f);
97+
emit FileManagerChanged(GenericStatus::IN_PROGRESS, percentage, devicePath);
98+
}
99+
100+
fclose(f);
101+
afc_file_close(afc, handle);
102+
emit FileManagerChanged(GenericStatus::DOWNLOADED, percentage, devicePath);
103+
}, bundleId);
104+
}
105+
106+
void DeviceBridge::DeleteFromStorage(QString devicePath, QString bundleId)
107+
{
108+
afc_filemanager_action([&, this](afc_client_t& afc){
109+
afc_error_t err = afc_remove_path(afc, devicePath.toUtf8().data());
110+
if (err == AFC_E_SUCCESS) {
111+
emit FileManagerChanged(GenericStatus::DELETED, 100, devicePath);
112+
} else {
113+
emit FileManagerChanged(GenericStatus::FAILED, 100, devicePath);
114+
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Failed to delete: " + devicePath + "! " + QString::number(err));
115+
}
116+
}, bundleId);
62117
}
63118

64119
int DeviceBridge::afc_upload_file(afc_client_t &afc, const QString &filename, const QString &dstfn, std::function<void(uint32_t,uint32_t)> callback)
@@ -414,3 +469,46 @@ void DeviceBridge::afc_traverse_recursive(afc_client_t afc, const char *path)
414469
}
415470
afc_dictionary_free(file_list);
416471
}
472+
473+
void DeviceBridge::afc_filemanager_action(std::function<void(afc_client_t &afc)> action, const QString& bundleId)
474+
{
475+
//AsyncManager::Get()->StartAsyncRequest([&, this]() {
476+
if (!bundleId.isEmpty()) {
477+
QStringList serviceIds = QStringList() << HOUSE_ARREST_SERVICE_NAME;
478+
StartLockdown(!m_houseArrest, serviceIds, [this, bundleId](QString& service_id, lockdownd_service_descriptor_t& service){
479+
house_arrest_error_t err = house_arrest_client_new(m_device, service, &m_houseArrest);
480+
if (err != HOUSE_ARREST_E_SUCCESS)
481+
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Could not connect to " + service_id + " client! " + QString::number(err));
482+
483+
err = house_arrest_send_command(m_houseArrest, "VendContainer", bundleId.toUtf8().data());
484+
if (err != HOUSE_ARREST_E_SUCCESS)
485+
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Access Denied to " + bundleId + "'s VendContainer client! " + QString::number(err));
486+
487+
afc_error_t aerr = afc_client_new_from_house_arrest_client(m_houseArrest, &m_fileManager);
488+
if (aerr != AFC_E_SUCCESS)
489+
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Could not connect to afc with " + service_id + " client! " + QString::number(aerr));
490+
});
491+
} else {
492+
QStringList serviceIds = QStringList() << AFC_SERVICE_NAME;
493+
StartLockdown(!m_fileManager, serviceIds, [this](QString& service_id, lockdownd_service_descriptor_t& service){
494+
afc_error_t aerr = afc_client_new(m_device, service, &m_fileManager);
495+
if (aerr != AFC_E_SUCCESS)
496+
emit MessagesReceived(MessagesType::MSG_ERROR, "ERROR: Could not connect to " + service_id + " client! " + QString::number(aerr));
497+
});
498+
}
499+
500+
//call function pass from params
501+
action(m_fileManager);
502+
503+
if (m_fileManager)
504+
{
505+
afc_client_free(m_fileManager);
506+
m_fileManager = nullptr;
507+
}
508+
if (m_houseArrest)
509+
{
510+
house_arrest_client_free(m_houseArrest);
511+
m_houseArrest = nullptr;
512+
}
513+
//});
514+
}

0 commit comments

Comments
 (0)