Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/bootloader/hos/pkg2_ini_kippatch.c
1476 views
1
/*
2
* Copyright (c) 2019-2024 CTCaer
3
*
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms and conditions of the GNU General Public License,
6
* version 2, as published by the Free Software Foundation.
7
*
8
* This program is distributed in the hope it will be useful, but WITHOUT
9
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11
* more details.
12
*
13
* You should have received a copy of the GNU General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
15
*/
16
17
#include <string.h>
18
#include <stdlib.h>
19
20
#include <bdk.h>
21
22
#include "pkg2_ini_kippatch.h"
23
#include <libs/fatfs/ff.h>
24
25
#define KPS(x) ((u32)(x) << 29)
26
27
static u8 *_htoa(u8 *result, const char *ptr, u8 byte_len, u8 *buf)
28
{
29
char ch = *ptr;
30
u32 ascii_len = byte_len * 2;
31
if (!result)
32
result = buf;
33
u8 *dst = result;
34
35
while (ch == ' ' || ch == '\t')
36
ch = *(++ptr);
37
38
bool shift = true;
39
while (ascii_len)
40
{
41
u8 tmp = 0;
42
if (ch >= '0' && ch <= '9')
43
tmp = (ch - '0');
44
else if (ch >= 'A' && ch <= 'F')
45
tmp = (ch - 'A' + 10);
46
else if (ch >= 'a' && ch <= 'f')
47
tmp = (ch - 'a' + 10);
48
49
if (shift)
50
*dst = (tmp << 4) & 0xF0;
51
else
52
{
53
*dst |= (tmp & 0x0F);
54
dst++;
55
}
56
57
ascii_len--;
58
ch = *(++ptr);
59
shift = !shift;
60
}
61
62
return result;
63
}
64
65
static u32 _find_patch_section_name(char *lbuf, u32 lblen, char schar)
66
{
67
u32 i;
68
// Depends on 'FF_USE_STRFUNC 2' that removes \r.
69
for (i = 0; i < lblen && lbuf[i] != schar && lbuf[i] != '\n'; i++)
70
;
71
lbuf[i] = 0;
72
73
return i;
74
}
75
76
static ini_kip_sec_t *_ini_create_kip_section(link_t *dst, ini_kip_sec_t *ksec, char *name)
77
{
78
if (ksec)
79
list_append(dst, &ksec->link);
80
81
// Calculate total allocation size.
82
u32 len = strlen(name);
83
char *buf = zalloc(sizeof(ini_kip_sec_t) + len + 1);
84
85
ksec = (ini_kip_sec_t *)buf;
86
u32 i = _find_patch_section_name(name, len, ':') + 1;
87
ksec->name = strcpy_ns(buf + sizeof(ini_kip_sec_t), name);
88
89
// Get hash section.
90
_htoa(ksec->hash, &name[i], 8, NULL);
91
92
// Initialize list.
93
list_init(&ksec->pts);
94
95
return ksec;
96
}
97
98
int ini_patch_parse(link_t *dst, const char *ini_path)
99
{
100
FIL fp;
101
u32 lblen;
102
char *lbuf;
103
ini_kip_sec_t *ksec = NULL;
104
105
// Open ini.
106
if (f_open(&fp, ini_path, FA_READ) != FR_OK)
107
return 0;
108
109
lbuf = malloc(512);
110
111
do
112
{
113
// Fetch one line.
114
lbuf[0] = 0;
115
f_gets(lbuf, 512, &fp);
116
lblen = strlen(lbuf);
117
118
// Remove trailing newline. Depends on 'FF_USE_STRFUNC 2' that removes \r.
119
if (lblen && lbuf[lblen - 1] == '\n')
120
lbuf[lblen - 1] = 0;
121
122
if (lblen > 2 && lbuf[0] == '[') // Create new section.
123
{
124
_find_patch_section_name(lbuf, lblen, ']');
125
126
// Set patchset kip name and hash.
127
ksec = _ini_create_kip_section(dst, ksec, &lbuf[1]);
128
}
129
else if (ksec && lbuf[0] == '.') // Extract key/value.
130
{
131
u32 str_start = 0;
132
u32 pos = _find_patch_section_name(lbuf, lblen, '=');
133
134
// Calculate total allocation size.
135
char *buf = zalloc(sizeof(ini_patchset_t) + strlen(&lbuf[1]) + 1);
136
ini_patchset_t *pt = (ini_patchset_t *)buf;
137
138
// Set patch name.
139
pt->name = strcpy_ns(buf + sizeof(ini_patchset_t), &lbuf[1]);
140
141
u8 kip_sidx = lbuf[pos + 1] - '0';
142
pos += 3;
143
144
if (kip_sidx < 6)
145
{
146
// Set patch offset.
147
pt->offset = KPS(kip_sidx);
148
str_start = _find_patch_section_name(&lbuf[pos], lblen - pos, ':');
149
pt->offset |= strtol(&lbuf[pos], NULL, 16);
150
pos += str_start + 1;
151
152
// Set patch size.
153
str_start = _find_patch_section_name(&lbuf[pos], lblen - pos, ':');
154
pt->length = strtol(&lbuf[pos], NULL, 16);
155
pos += str_start + 1;
156
157
u8 *data = malloc(pt->length * 2);
158
159
// Set patch source data.
160
str_start = _find_patch_section_name(&lbuf[pos], lblen - pos, ',');
161
pt->src_data = _htoa(NULL, &lbuf[pos], pt->length, data);
162
pos += str_start + 1;
163
164
// Set patch destination data.
165
pt->dst_data = _htoa(NULL, &lbuf[pos], pt->length, data + pt->length);
166
}
167
168
list_append(&ksec->pts, &pt->link);
169
}
170
} while (!f_eof(&fp));
171
172
f_close(&fp);
173
174
if (ksec)
175
list_append(dst, &ksec->link);
176
177
free(lbuf);
178
179
return 1;
180
}
181
182