summaryrefslogtreecommitdiff
path: root/utils/imxtools/sbtools/rsrc.c
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2012-11-29 17:27:34 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2012-11-29 17:30:54 +0100
commitee36a396cd1619585a83803630db2d79b6cbefbd (patch)
treed24e9737433147ef3e57f00f8734f0e54123b810 /utils/imxtools/sbtools/rsrc.c
parent0ee512ca04e52b62550bd06532ffa67bdeab3d04 (diff)
downloadrockbox-ee36a396cd1619585a83803630db2d79b6cbefbd.tar.gz
rockbox-ee36a396cd1619585a83803630db2d79b6cbefbd.zip
imxtools: introduce rsrctool to manipulate rsrc sections
This tool is very preliminary but could be use for whatever purpose since the format of the rsrc sections is now known. By the way it appears that this format is the same as the one use by the stmp36xx for its resources. Change-Id: Idd7057f5cdce5af9726904169bb100c8bacb0981
Diffstat (limited to 'utils/imxtools/sbtools/rsrc.c')
-rw-r--r--utils/imxtools/sbtools/rsrc.c227
1 files changed, 227 insertions, 0 deletions
diff --git a/utils/imxtools/sbtools/rsrc.c b/utils/imxtools/sbtools/rsrc.c
new file mode 100644
index 0000000000..da3c418d2c
--- /dev/null
+++ b/utils/imxtools/sbtools/rsrc.c
@@ -0,0 +1,227 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2012 Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include <stdio.h>
22#include <time.h>
23#include <stdlib.h>
24#include <ctype.h>
25#include "misc.h"
26#include "crypto.h"
27#include "rsrc.h"
28
29const char crypto_key[16] = "SanDiskSlotRadi";
30
31static void rsrc_crypt(void *buf, int size)
32{
33 if(size % 16)
34 printf("Size must be a multiple of 16 !\n");
35 uint8_t *p = buf;
36 for(int i = 0; i < size; i+= 16, p += 16)
37 {
38 for(int j = 0; j < 16; j++)
39 p[j] ^= crypto_key[j];
40 }
41}
42
43enum rsrc_error_t rsrc_write_file(struct rsrc_file_t *rsrc, const char *filename)
44{
45 FILE *f = fopen(filename, "wb");
46 if(f == NULL)
47 return RSRC_OPEN_ERROR;
48 fwrite(rsrc->data, 1, rsrc->size, f);
49 fclose(f);
50 return RSRC_SUCCESS;
51}
52
53struct rsrc_file_t *rsrc_read_file(const char *filename, void *u,
54 rsrc_color_printf cprintf, enum rsrc_error_t *err)
55{
56 return rsrc_read_file_ex(filename, 0, -1, u, cprintf, err);
57}
58
59struct rsrc_file_t *rsrc_read_file_ex(const char *filename, size_t offset, size_t size, void *u,
60 rsrc_color_printf cprintf, enum rsrc_error_t *err)
61{
62 #define fatal(e, ...) \
63 do { if(err) *err = e; \
64 cprintf(u, true, GREY, __VA_ARGS__); \
65 free(buf); \
66 return NULL; } while(0)
67
68 FILE *f = fopen(filename, "rb");
69 void *buf = NULL;
70 if(f == NULL)
71 fatal(RSRC_OPEN_ERROR, "Cannot open file for reading\n");
72 fseek(f, 0, SEEK_END);
73 size_t read_size = ftell(f);
74 fseek(f, offset, SEEK_SET);
75 if(size != (size_t)-1)
76 read_size = size;
77 buf = xmalloc(read_size);
78 if(fread(buf, read_size, 1, f) != 1)
79 {
80 fclose(f);
81 fatal(RSRC_READ_ERROR, "Cannot read file\n");
82 }
83 fclose(f);
84
85 struct rsrc_file_t *ret = rsrc_read_memory(buf, read_size, u, cprintf, err);
86 free(buf);
87 return ret;
88
89 #undef fatal
90}
91
92static const char *rsrc_table_entry_type_str(int type)
93{
94 switch(type)
95 {
96 case RSRC_TYPE_NONE: return "empty";
97 case RSRC_TYPE_NESTED: return "nested";
98 case RSRC_TYPE_IMAGE: return "image";
99 case RSRC_TYPE_VALUE: return "value";
100 case RSRC_TYPE_AUDIO: return "audio";
101 case RSRC_TYPE_DATA: return "data";
102 default: return "unknown";
103 }
104}
105
106static bool read_entries(void *buf, int filesize, void *u,
107 rsrc_color_printf cprintf, enum rsrc_error_t *err,
108 int offset, uint32_t base_index, int level, char *prefix)
109{
110 #define printf(c, ...) cprintf(u, false, c, __VA_ARGS__)
111 #define fatal(e, ...) \
112 do { if(err) *err = e; \
113 cprintf(u, true, GREY, __VA_ARGS__); \
114 return e; } while(0)
115
116 if(offset >= filesize)
117 fatal(RSRC_FORMAT_ERROR, "Out of bounds at off=%x base=%x level=%d\n ouch\n");
118 if(level < 0)
119 fatal(RSRC_FORMAT_ERROR, "Out of levels at off=%x base=%x level=%d\n aie\n");
120 for(int i = 0; i < 256; i++)
121 {
122 uint32_t te = *(uint32_t *)(buf + offset + 4 * i);
123 if(RSRC_TABLE_ENTRY_TYPE(te) == RSRC_TYPE_NONE)
124 continue;
125 uint32_t sz = 0;
126 if(RSRC_TABLE_ENTRY_TYPE(te) == RSRC_TYPE_VALUE)
127 sz = 2;
128 else if(RSRC_TABLE_ENTRY_TYPE(te) == RSRC_TYPE_NESTED)
129 sz = 4 * 256;
130 else
131 sz = *(uint32_t *)(buf + RSRC_TABLE_ENTRY_OFFSET(te));
132
133 uint32_t index = base_index | i << (level * 8);
134 printf(OFF, "%s+-%s%#08x %s[%s]%s[size=%#x]\n", prefix, YELLOW, index, BLUE,
135 rsrc_table_entry_type_str(RSRC_TABLE_ENTRY_TYPE(te)),
136 GREEN, sz);
137
138 if(RSRC_TABLE_ENTRY_TYPE(te) == RSRC_TYPE_NESTED)
139 {
140 char *p = prefix + strlen(prefix);
141 sprintf(p, "%s| ", RED);
142
143 bool ok = read_entries(buf, filesize, u, cprintf, err,
144 RSRC_TABLE_ENTRY_OFFSET(te), index,
145 level - 1, prefix);
146 if(!ok)
147 return false;
148 *p = 0;
149 }
150 }
151
152 return true;
153 #undef printf
154 #undef fatal
155}
156
157struct rsrc_file_t *rsrc_read_memory(void *_buf, size_t filesize, void *u,
158 rsrc_color_printf cprintf, enum rsrc_error_t *err)
159{
160 struct rsrc_file_t *rsrc_file = NULL;
161 uint8_t *buf = _buf;
162
163 #define printf(c, ...) cprintf(u, false, c, __VA_ARGS__)
164 #define fatal(e, ...) \
165 do { if(err) *err = e; \
166 cprintf(u, true, GREY, __VA_ARGS__); \
167 rsrc_free(rsrc_file); \
168 return NULL; } while(0)
169 #define print_hex(c, p, len, nl) \
170 do { printf(c, ""); print_hex(p, len, nl); } while(0)
171
172 rsrc_file = xmalloc(sizeof(struct rsrc_file_t));
173 memset(rsrc_file, 0, sizeof(struct rsrc_file_t));
174
175 /* There is a padding sector at the beginning of the file with a RSRC string.
176 * It is unclear if this is a signature since no code I've disassembled
177 * actually checks it. Allow use of -force to bypass. */
178 if(memcmp(buf + 20, "RSRC", 4) != 0)
179 {
180 if(g_force)
181 printf(GREY, "Missing RSRC signature\n");
182 else
183 fatal(RSRC_FORMAT_ERROR, "Missing RSRC signature\n");
184 }
185
186 printf(BLUE, "Entries\n");
187 char prefix[1024];
188 sprintf(prefix, "%s", RED);
189 bool ok = read_entries(buf, filesize, u, cprintf, err,
190 RSRC_SECTOR_SIZE, 0, 3, prefix);
191 if(!ok)
192 fatal(*err, "Error while parsing rsrc table\n");
193
194 rsrc_file->data = malloc(filesize);
195 memcpy(rsrc_file->data, _buf, filesize);
196 rsrc_file->size = filesize;
197
198 return rsrc_file;
199 #undef printf
200 #undef fatal
201 #undef print_hex
202}
203
204void rsrc_free(struct rsrc_file_t *file)
205{
206 if(!file) return;
207 free(file);
208}
209
210void rsrc_dump(struct rsrc_file_t *file, void *u, rsrc_color_printf cprintf)
211{
212 #define printf(c, ...) cprintf(u, false, c, __VA_ARGS__)
213 #define print_hex(c, p, len, nl) \
214 do { printf(c, ""); print_hex(p, len, nl); } while(0)
215
216 #define TREE RED
217 #define HEADER GREEN
218 #define TEXT YELLOW
219 #define TEXT2 BLUE
220 #define SEP OFF
221
222 printf(HEADER, "RSRC File\n");
223
224 #undef printf
225 #undef print_hex
226}
227