-
Notifications
You must be signed in to change notification settings - Fork 0
/
installurl.c
121 lines (86 loc) · 2.83 KB
/
installurl.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <3ds.h>
#include "common.h"
#include "util.h"
#include "ctr/ctr_debug.h"
static Result action_install_url_open_dst(void *data, void *initialReadBlock, u32 *handle)
{
install_url_data *installData = (install_url_data *) data;
Result res = 0;
installData->responseCode = 0;
installData->titleId = 0;
if (*(u16 *) initialReadBlock == 0x2020)
{
u64 titleId = util_get_cia_title_id((u8 *) initialReadBlock);
if(!titleId)
return R_FBI_BAD_DATA;
if (util_get_title_destination(titleId) == MEDIATYPE_NAND)
return R_FBI_BAD_DATA;
if (R_SUCCEEDED(res = AM_StartCiaInstall(MEDIATYPE_SD, handle)))
installData->titleId = titleId;
}
else
return R_FBI_BAD_DATA;
return res;
}
static Result task_data_op_copy(install_url_data *data)
{
data->currProcessed = 0;
data->currTotal = 0;
Result res = 0;
httpcContext srcHandle = {};
if (R_SUCCEEDED(res = util_http_open(&srcHandle, &data->responseCode, data->url, true)))
{
data->currTotal = 0;
if (R_SUCCEEDED(res = httpcGetDownloadSizeState(&srcHandle, NULL, (u32*)&data->currTotal)))
{
if (data->currTotal == 0)
res = R_FBI_BAD_DATA;
else
{
static u8 buffer[0x4000];
u32 dstHandle = 0;
while (data->currProcessed < data->currTotal)
{
u32 bytesRead = 0;
if (R_FAILED(res = util_http_read(&srcHandle, &bytesRead, buffer, sizeof(buffer))))
break;
if (!dstHandle && R_FAILED(res = action_install_url_open_dst(data, buffer, &dstHandle)))
break;
u32 bytesWritten = 0;
if (R_FAILED(res = FSFILE_Write(dstHandle, &bytesWritten, data->currProcessed, buffer, bytesRead, 0)))
break;
data->currProcessed += bytesWritten;
printf("%llu/%llu\r", data->currProcessed, data->currTotal);
}
printf("\n");
if (dstHandle != 0)
{
Result closeDstRes;
if (res == 0)
closeDstRes = AM_FinishCiaInstall(dstHandle);
else
closeDstRes = AM_CancelCIAInstall(dstHandle);
if (R_SUCCEEDED(res))
res = closeDstRes;
}
}
}
Result closeSrcRes = httpcCloseContext(&srcHandle);
if (R_SUCCEEDED(res))
res = closeSrcRes;
}
return res;
}
void action_install_url(const char *urls)
{
install_url_data data = {};
strncpy(data.url, "http://", 7);
strncpy(&data.url[7], urls, sizeof(data.url) - 7);
DEBUG_RESULT(task_data_op_copy(&data));
extern u64 currTitleId;
currTitleId = data.titleId;
}