Skip to content

Commit cdb0020

Browse files
committed
feat(cia): support local cia
1 parent f737b5a commit cdb0020

File tree

6 files changed

+104
-56
lines changed

6 files changed

+104
-56
lines changed

source/core/http.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#define HTTP_TIMEOUT_SEC 15
2121
#define HTTP_TIMEOUT_NS ((u64) HTTP_TIMEOUT_SEC * 1000000000)
2222

23-
extern int use_curl_instead;
23+
extern int is_sc_called;
2424

2525
struct httpc_context_s {
2626
httpcContext httpc;
@@ -293,7 +293,7 @@ Result http_download_callback(const char* url, u32 bufferSize, void* userData, R
293293
void* buf = malloc(bufferSize);
294294
if(buf != NULL) {
295295
httpc_context context = NULL;
296-
if(!use_curl_instead && R_SUCCEEDED(res = httpc_open(&context, url, true))) {
296+
if(!is_sc_called && R_SUCCEEDED(res = httpc_open(&context, url, true))) {
297297
u32 dlSize = 0;
298298
if(R_SUCCEEDED(res = httpc_get_size(context, &dlSize))) {
299299
if(progress != NULL) {
@@ -318,7 +318,7 @@ Result http_download_callback(const char* url, u32 bufferSize, void* userData, R
318318
res = closeRes;
319319
}
320320
}
321-
} else if(use_curl_instead || res == R_HTTP_TLS_VERIFY_FAILED) {
321+
} else if(is_sc_called || res == R_HTTP_TLS_VERIFY_FAILED) {
322322
res = 0;
323323

324324
CURL* curl = curl_easy_init();
@@ -328,7 +328,7 @@ Result http_download_callback(const char* url, u32 bufferSize, void* userData, R
328328
curl_easy_setopt(curl, CURLOPT_URL, url);
329329
curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, bufferSize);
330330
curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "");
331-
if (use_curl_instead) {
331+
if (is_sc_called) {
332332
curl_easy_setopt(curl, CURLOPT_USERAGENT, "pan.baidu.com");
333333
} else {
334334
curl_easy_setopt(curl, CURLOPT_USERAGENT, HTTP_USER_AGENT);

source/fbi/action/action.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,7 @@ void action_delete_secure_value(linked_list* items, list_item* selected);
5353
void action_install_url(const char* confirmMessage, const char* urls, const char* paths, void* userData,
5454
void (*finishedURL)(void* data, u32 index),
5555
void (*finishedAll)(void* data),
56-
void (*drawTop)(ui_view* view, void* data, float x1, float y1, float x2, float y2, u32 index));
56+
void (*drawTop)(ui_view* view, void* data, float x1, float y1, float x2, float y2, u32 index));
57+
58+
void action_install_cia_by_path(const char* path);
59+
void install_from_sc_done(void *data);

source/fbi/action/installcias.c

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include "../task/uitask.h"
1010
#include "../../core/core.h"
1111

12+
extern int is_sc_called;
13+
1214
typedef struct {
1315
linked_list* items;
1416

@@ -195,6 +197,10 @@ static void action_install_cias_free_data(install_cias_data* data) {
195197
}
196198

197199
free(data);
200+
201+
if (is_sc_called) {
202+
install_from_sc_done(NULL);
203+
}
198204
}
199205

200206
static void action_install_cias_update(ui_view* view, void* data, float* progress, char* text) {
@@ -393,4 +399,42 @@ void action_install_cias(linked_list* items, list_item* selected, bool (*filter)
393399

394400
void action_install_cias_delete(linked_list* items, list_item* selected, bool (*filter)(void* data, const char* name, u32 attributes), void* filterData) {
395401
action_install_cias_internal(items, selected, filter, filterData, "Install and delete all CIAs in the current directory?", true);
396-
}
402+
}
403+
404+
void action_install_cia_by_path(const char* path) {
405+
if(path == NULL) {
406+
error_display(NULL, NULL, "Invalid CIA path.");
407+
return;
408+
}
409+
410+
FS_Archive arch;
411+
FSUSER_OpenArchive(&arch, ARCHIVE_SDMC, fsMakePath(PATH_EMPTY, ""));
412+
if(arch == 0) {
413+
error_display(NULL, NULL, "Failed to open SDMC archive.");
414+
return;
415+
}
416+
417+
linked_list list;
418+
linked_list_init(&list);
419+
420+
file_info fileInfo;
421+
422+
fileInfo.archive = arch;
423+
string_copy(fileInfo.path, path, FILE_PATH_MAX);
424+
fileInfo.attributes = 0;
425+
426+
list_item* item = (list_item*) calloc(1, sizeof(list_item));
427+
if(item == NULL) {
428+
linked_list_destroy(&list);
429+
FSUSER_CloseArchive(arch);
430+
error_display(NULL, NULL, "Failed to allocate list item.");
431+
return;
432+
}
433+
434+
item->data = &fileInfo;
435+
linked_list_add(&list, item);
436+
437+
action_install_cias_internal(&list, item, NULL, NULL, "Install the selected CIA?", false);
438+
linked_list_destroy(&list);
439+
FSUSER_CloseArchive(arch);
440+
}

source/fbi/action/installurl.c

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -253,19 +253,6 @@ static bool action_install_url_error(void* data, u32 index, Result res, ui_view*
253253
return true;
254254
}
255255

256-
extern u64 title_id;
257-
extern int cancel_install;
258-
259-
static void sc_install_done_callback(ui_view* view, void* data, u32 response) {
260-
Result res = 0;
261-
if(R_SUCCEEDED(res = APT_PrepareToDoApplicationJump(0, title_id, 1))) {
262-
u8 param[0x300];
263-
u8 hmac[0x20];
264-
265-
APT_DoApplicationJump(param, sizeof(param), hmac);
266-
}
267-
}
268-
269256
static void action_install_url_install_update(ui_view* view, void* data, float* progress, char* text) {
270257
install_url_data* installData = (install_url_data*) data;
271258

@@ -274,11 +261,7 @@ static void action_install_url_install_update(ui_view* view, void* data, float*
274261
info_destroy(view);
275262

276263
if(R_SUCCEEDED(installData->installInfo.result)) {
277-
if (title_id != 0) {
278-
prompt_display_notify("Success", "Install finished.", COLOR_TEXT, NULL, NULL, sc_install_done_callback);
279-
} else {
280-
prompt_display_notify("Success", "Install finished.", COLOR_TEXT, NULL, NULL, NULL);
281-
}
264+
prompt_display_notify("Success", "Install finished.", COLOR_TEXT, NULL, NULL, NULL);
282265
}
283266

284267
action_install_url_free_data(installData);
@@ -287,7 +270,6 @@ static void action_install_url_install_update(ui_view* view, void* data, float*
287270
}
288271

289272
if(hidKeysDown() & KEY_B) {
290-
cancel_install = 1;
291273
svcSignalEvent(installData->installInfo.cancelEvent);
292274
}
293275

@@ -315,7 +297,6 @@ static void action_install_url_confirm_onresponse(ui_view* view, void* data, u32
315297
action_install_url_free_data(installData);
316298
}
317299
} else {
318-
cancel_install = 1;
319300
action_install_url_free_data(installData);
320301
}
321302
}

source/fbi/action/sc.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include "../loader.h"
2+
#include <3ds.h>
3+
4+
extern int exit_code;
5+
extern u64 title_id;
6+
extern int is_local_cia;
7+
extern char *sc_3dsx_path;
8+
9+
void install_from_sc_done(void *data) {
10+
char *args = is_local_cia ? "local" : "cloud";
11+
if (envIsHomebrew()) {
12+
if (sc_3dsx_path != NULL) {
13+
loader_launch_file(sc_3dsx_path, args);
14+
exit_code = 1;
15+
}
16+
} else if (title_id != 0) {
17+
u8 param[0x300];
18+
memset(param, 0, sizeof(param));
19+
strncpy((char *)param, args, sizeof(param));
20+
u8 hmac[0x20];
21+
22+
aptSetChainloader(title_id, MEDIATYPE_SD);
23+
aptSetChainloaderArgs(param, sizeof(param), hmac);
24+
exit_code = 1;
25+
}
26+
}

source/fbi/main.c

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -176,28 +176,10 @@ void cleanup() {
176176
}
177177

178178
int exit_code = 0;
179-
int use_curl_instead = 0;
180-
int cancel_install = 0;
179+
int is_sc_called = 0;
180+
int is_local_cia = 0;
181181
u64 title_id = 0;
182-
183-
void install_from_remote_done(void* data) {
184-
if (envIsHomebrew()) {
185-
char *from_3dsx_path = (char *)data;
186-
if(from_3dsx_path != NULL) {
187-
loader_launch_file(from_3dsx_path, NULL);
188-
exit_code = 1;
189-
}
190-
} else if (title_id != 0 && cancel_install) {
191-
Result res = 0;
192-
193-
if(R_SUCCEEDED(res = APT_PrepareToDoApplicationJump(0, title_id, 1))) {
194-
u8 param[0x300];
195-
u8 hmac[0x20];
196-
197-
APT_DoApplicationJump(param, sizeof(param), hmac);
198-
}
199-
}
200-
}
182+
char *sc_3dsx_path = NULL;
201183

202184
static bool remoteinstall_get_urls_by_path(const char* path, char* out, size_t size) {
203185
if(out == NULL || size == 0) {
@@ -230,17 +212,23 @@ int main(int argc, const char* argv[]) {
230212
// Install from URL if a URL was passed as an argument.
231213
if (envIsHomebrew()) {
232214
if(argc > 2) {
233-
use_curl_instead = 1;
215+
is_sc_called = 1;
234216
char* url = (char*) calloc(1, DOWNLOAD_URL_MAX * INSTALL_URLS_MAX);
235217
remoteinstall_get_urls_by_path(argv[1], url, DOWNLOAD_URL_MAX * INSTALL_URLS_MAX);
236-
action_install_url("Install From URL?",
218+
sc_3dsx_path = (char *)argv[2];
219+
if (strncmp(url, "/", 1) == 0) {
220+
is_local_cia = 1;
221+
action_install_cia_by_path(url);
222+
} else {
223+
action_install_url("Install From URL?",
237224
url,
238225
fs_get_3dsx_path(),
239-
(void *)argv[2],
240226
NULL,
241-
install_from_remote_done,
227+
NULL,
228+
install_from_sc_done,
242229
NULL
243-
);
230+
);
231+
}
244232
free(url);
245233
}
246234
} else {
@@ -259,18 +247,24 @@ int main(int argc, const char* argv[]) {
259247
if (len > 0) {
260248
char *params_str = (char *)param;
261249
if (strncmp(params_str, "sc:", 3) == 0) {
262-
use_curl_instead = 1;
250+
is_sc_called = 1;
263251
char *path = params_str + 3;
264252
char* url = (char*) calloc(1, DOWNLOAD_URL_MAX * INSTALL_URLS_MAX);
265253
remoteinstall_get_urls_by_path(path, url, DOWNLOAD_URL_MAX * INSTALL_URLS_MAX);
266-
action_install_url("Install From URL?",
254+
// file path
255+
if (strncmp(url, "/", 1) == 0) {
256+
is_local_cia = 1;
257+
action_install_cia_by_path(url);
258+
} else {
259+
action_install_url("Install From URL?",
267260
url,
268261
fs_get_3dsx_path(),
269262
NULL,
270263
NULL,
271-
install_from_remote_done,
264+
install_from_sc_done,
272265
NULL
273-
);
266+
);
267+
}
274268
free(url);
275269
}
276270
}

0 commit comments

Comments
 (0)