source: rtems/c/src/lib/libbsp/arm/nds/tools/ndstool/source/ndsextract.cpp @ 311dfa6

4.104.114.95
Last change on this file since 311dfa6 was 311dfa6, checked in by Joel Sherrill <joel.sherrill@…>, on Apr 16, 2008 at 6:37:33 PM

2008-04-16 Matthieu Bucchianeri <mbucchia@…>

  • ChangeLog?, Makefile.am, README, bsp_specs, configure.ac, mk_libnds.sh, patch.libnds, preinstall.am, block/block.c, clock/clock.c, console/console.c, coproc/coproc.S, coproc/coproc.c, coproc/coproc.ld, dswifi/dswifi_license.txt, dswifi/makefile, dswifi/arm7/makefile, dswifi/arm7/source/wifi_arm7.c, dswifi/arm7/source/wifi_arm7.h, dswifi/arm9/makefile, dswifi/arm9/source/sgIP.c, dswifi/arm9/source/sgIP.h, dswifi/arm9/source/sgIP_ARP.c, dswifi/arm9/source/sgIP_ARP.h, dswifi/arm9/source/sgIP_Config.h, dswifi/arm9/source/sgIP_DHCP.c, dswifi/arm9/source/sgIP_DHCP.h, dswifi/arm9/source/sgIP_DNS.c, dswifi/arm9/source/sgIP_DNS.h, dswifi/arm9/source/sgIP_Hub.c, dswifi/arm9/source/sgIP_Hub.h, dswifi/arm9/source/sgIP_ICMP.c, dswifi/arm9/source/sgIP_ICMP.h, dswifi/arm9/source/sgIP_IP.c, dswifi/arm9/source/sgIP_IP.h, dswifi/arm9/source/sgIP_TCP.c, dswifi/arm9/source/sgIP_TCP.h, dswifi/arm9/source/sgIP_UDP.c, dswifi/arm9/source/sgIP_UDP.h, dswifi/arm9/source/sgIP_memblock.c, dswifi/arm9/source/sgIP_memblock.h, dswifi/arm9/source/sgIP_sockets.c, dswifi/arm9/source/sgIP_sockets.h, dswifi/arm9/source/wifi_arm9.c, dswifi/arm9/source/wifi_arm9.h, dswifi/common/source/dsregs.h, dswifi/common/source/spinlock.h, dswifi/common/source/spinlock.s, dswifi/common/source/wifi_shared.h, dswifi/include/dswifi7.h, dswifi/include/dswifi9.h, dswifi/include/dswifi_version.h, dswifi/include/netdb.h, dswifi/include/sgIP_errno.h, dswifi/include/netinet/in.h, fb/fb.c, fb/fb.h, include/bsp.h, include/my_ipc.h, include/tm27.h, include/types.h, include/sys/iosupport.h, irq/irq.c, irq/irq.h, libfat/gba/include/fat.h, libfat/include/fat.h, libfat/nds/include/fat.h, libfat/source/bit_ops.h, libfat/source/cache.c, libfat/source/cache.h, libfat/source/common.h, libfat/source/directory.c, libfat/source/directory.h, libfat/source/fatdir.c, libfat/source/fatdir.h, libfat/source/fatfile.c, libfat/source/fatfile.h, libfat/source/file_allocation_table.c, libfat/source/file_allocation_table.h, libfat/source/filetime.c, libfat/source/filetime.h, libfat/source/libfat.c, libfat/source/mem_allocate.h, libfat/source/partition.c, libfat/source/partition.h, libfat/source/disc_io/disc.c, libfat/source/disc_io/disc.h, libfat/source/disc_io/disc_io.h, libfat/source/disc_io/io_cf_common.c, libfat/source/disc_io/io_cf_common.h, libfat/source/disc_io/io_dldi.h, libfat/source/disc_io/io_dldi.s, libfat/source/disc_io/io_efa2.c, libfat/source/disc_io/io_efa2.h, libfat/source/disc_io/io_fcsr.c, libfat/source/disc_io/io_fcsr.h, libfat/source/disc_io/io_m3_common.c, libfat/source/disc_io/io_m3_common.h, libfat/source/disc_io/io_m3cf.c, libfat/source/disc_io/io_m3cf.h, libfat/source/disc_io/io_m3sd.c, libfat/source/disc_io/io_m3sd.h, libfat/source/disc_io/io_mpcf.c, libfat/source/disc_io/io_mpcf.h, libfat/source/disc_io/io_njsd.c, libfat/source/disc_io/io_njsd.h, libfat/source/disc_io/io_nmmc.c, libfat/source/disc_io/io_nmmc.h, libfat/source/disc_io/io_sc_common.c, libfat/source/disc_io/io_sc_common.h, libfat/source/disc_io/io_sccf.c, libfat/source/disc_io/io_sccf.h, libfat/source/disc_io/io_scsd.c, libfat/source/disc_io/io_scsd.h, libfat/source/disc_io/io_scsd_s.s, libfat/source/disc_io/io_sd_common.c, libfat/source/disc_io/io_sd_common.h, libnds/Makefile.arm7, libnds/Makefile.arm9, libnds/libnds_license.txt, libnds/basicARM7/source/defaultARM7.c, libnds/include/default_font_bin.h, libnds/include/gbfs.h, libnds/include/nds.h, libnds/include/nds/bios.h, libnds/include/nds/card.h, libnds/include/nds/dma.h, libnds/include/nds/interrupts.h, libnds/include/nds/ipc.h, libnds/include/nds/jtypes.h, libnds/include/nds/memory.h, libnds/include/nds/registers_alt.h, libnds/include/nds/reload.h, libnds/include/nds/system.h, libnds/include/nds/timers.h, libnds/include/nds/arm7/audio.h, libnds/include/nds/arm7/clock.h, libnds/include/nds/arm7/serial.h, libnds/include/nds/arm7/touch.h, libnds/include/nds/arm9/background.h, libnds/include/nds/arm9/boxtest.h, libnds/include/nds/arm9/cache.h, libnds/include/nds/arm9/console.h, libnds/include/nds/arm9/exceptions.h, libnds/include/nds/arm9/image.h, libnds/include/nds/arm9/input.h, libnds/include/nds/arm9/math.h, libnds/include/nds/arm9/ndsmotion.h, libnds/include/nds/arm9/pcx.h, libnds/include/nds/arm9/postest.h, libnds/include/nds/arm9/rumble.h, libnds/include/nds/arm9/sound.h, libnds/include/nds/arm9/sprite.h, libnds/include/nds/arm9/trig_lut.h, libnds/include/nds/arm9/video.h, libnds/include/nds/arm9/videoGL.h, libnds/source/arm7/audio.c, libnds/source/arm7/clock.c, libnds/source/arm7/microphone.c, libnds/source/arm7/spi.c, libnds/source/arm7/touch.c, libnds/source/arm7/userSettings.c, libnds/source/arm9/COS.bin, libnds/source/arm9/COS.s, libnds/source/arm9/SIN.bin, libnds/source/arm9/SIN.s, libnds/source/arm9/TAN.bin, libnds/source/arm9/TAN.s, libnds/source/arm9/boxtest.c, libnds/source/arm9/console.c, libnds/source/arm9/dcache.s, libnds/source/arm9/default_font.bin, libnds/source/arm9/default_font.s, libnds/source/arm9/exceptionHandler.S, libnds/source/arm9/exceptionHandler.s, libnds/source/arm9/exceptions.c, libnds/source/arm9/gurumeditation.c, libnds/source/arm9/icache.s, libnds/source/arm9/image.c, libnds/source/arm9/initSystem.c, libnds/source/arm9/keys.c, libnds/source/arm9/ndsmotion.c, libnds/source/arm9/pcx.c, libnds/source/arm9/rumble.c, libnds/source/arm9/sound.c, libnds/source/arm9/system.c, libnds/source/arm9/touch.c, libnds/source/arm9/video.c, libnds/source/arm9/videoGL.c, libnds/source/common/biosCalls.s, libnds/source/common/card.c, libnds/source/common/gbfs.c, libnds/source/common/interruptDispatcher.s, libnds/source/common/interrupts.c, rtc/rtc.c, sound/sound.c, sound/sound.h, start/start.S, startup/linkcmds, startup/start.c, timer/timer.c, tools/Makefile.am, tools/bin2s, tools/bin2s.c, tools/configure.ac, tools/runtest, tools/ndstool/include/arm7_sha1_homebrew.h, tools/ndstool/include/arm7_sha1_nintendo.h, tools/ndstool/include/banner.h, tools/ndstool/include/bigint.h, tools/ndstool/include/crc.h, tools/ndstool/include/default_icon.h, tools/ndstool/include/encryption.h, tools/ndstool/include/header.h, tools/ndstool/include/hook.h, tools/ndstool/include/little.h, tools/ndstool/include/loadme.h, tools/ndstool/include/logo.h, tools/ndstool/include/ndscreate.h, tools/ndstool/include/ndsextract.h, tools/ndstool/include/ndstool.h, tools/ndstool/include/ndstree.h, tools/ndstool/include/overlay.h, tools/ndstool/include/passme.h, tools/ndstool/include/passme_sram.h, tools/ndstool/include/passme_vhd1.h, tools/ndstool/include/passme_vhd2.h, tools/ndstool/include/raster.h, tools/ndstool/include/sha1.h, tools/ndstool/include/types.h, tools/ndstool/source/arm7_sha1_homebrew.c, tools/ndstool/source/arm7_sha1_nintendo.c, tools/ndstool/source/banner.cpp, tools/ndstool/source/bigint.cpp, tools/ndstool/source/compile_date.c, tools/ndstool/source/crc.cpp, tools/ndstool/source/default_icon.c, tools/ndstool/source/encryption.cpp, tools/ndstool/source/header.cpp, tools/ndstool/source/hook.cpp, tools/ndstool/source/loadme.c, tools/ndstool/source/logo.cpp, tools/ndstool/source/ndscodes.cpp, tools/ndstool/source/ndscreate.cpp, tools/ndstool/source/ndsextract.cpp, tools/ndstool/source/ndstool.cpp, tools/ndstool/source/ndstree.cpp, tools/ndstool/source/passme.cpp, tools/ndstool/source/passme_sram.c, tools/ndstool/source/raster.cpp, tools/ndstool/source/sha1.cpp, touchscreen/README.reco, touchscreen/parser.c, touchscreen/reco.c, touchscreen/reco.h, touchscreen/touchscreen.c, touchscreen/touchscreen.h, wifi/compat.c, wifi/compat.h, wifi/wifi.c: New files.
  • Property mode set to 100644
File size: 6.9 KB
Line 
1#include "ndstool.h"
2#include "overlay.h"
3#include <errno.h>
4
5/*
6 * MkDir
7 */
8void MkDir(char *name)
9{
10#ifdef __MINGW32__
11        if (mkdir(name))
12#else
13        if (mkdir(name, S_IRWXU))
14#endif
15        {
16                if (errno != EEXIST)
17                {
18                        fprintf(stderr, "Cannot create directory '%s'.\n", name);
19                        exit(1);
20                }
21        }
22}
23
24/*
25 * ExtractFile
26 * if rootdir==0 nothing will be written
27 */
28void ExtractFile(char *rootdir, char *prefix, char *entry_name, unsigned int file_id)
29{
30        unsigned int save_filepos = ftell(fNDS);
31
32        // read FAT data
33        fseek(fNDS, header.fat_offset + 8*file_id, SEEK_SET);
34        unsigned_int top;
35        fread(&top, 1, sizeof(top), fNDS);
36        unsigned_int bottom;
37        fread(&bottom, 1, sizeof(bottom), fNDS);
38        unsigned int size = bottom - top;
39        if (size > (1U << (17 + header.devicecap))) { fprintf(stderr, "File %u: Size is too big. FAT offset 0x%X contains invalid data.\n", file_id, header.fat_offset + 8*file_id); exit(1); }
40
41        // print file info
42        if (!rootdir || verbose)
43        {
44                printf("%5u 0x%08X 0x%08X %9u %s%s\n", file_id, (int)top, (int)bottom, size, prefix, entry_name);
45        }
46
47        // extract file
48        if (rootdir)
49        {
50                // make filename
51                char filename[MAXPATHLEN];
52                strcpy(filename, rootdir);
53                strcat(filename, prefix);
54                strcat(filename, entry_name);
55
56                fseek(fNDS, top, SEEK_SET);
57                FILE *fo = fopen(filename, "wb");
58                if (!fo) { fprintf(stderr, "Cannot create file '%s'.\n", filename); exit(1); }
59                while (size > 0)
60                {
61                        unsigned char copybuf[1024];
62                        unsigned int size2 = (size >= sizeof(copybuf)) ? sizeof(copybuf) : size;
63                        fread(copybuf, 1, size2, fNDS);
64                        fwrite(copybuf, 1, size2, fo);
65                        size -= size2;
66                }
67                fclose(fo);
68        }
69
70        fseek(fNDS, save_filepos, SEEK_SET);
71}
72
73/*
74 * MatchName
75 */
76bool MatchName(char *name, char *mask, int level=0)
77{
78        char *a = name;
79        char *b = mask;
80        //for (int i=0; i<level; i++) printf("  "); printf("matching a='%s' b='%s'\n", a, b);
81        while (1)
82        {
83                //for (int i=0; i<level; i++) printf("a=%s b=%s\n", a, b);
84                if (*b == '*')
85                {
86                        while (*b == '*') b++;
87        //for (int i=0; i<level; i++) printf("  "); printf("* '%s' '%s'\n", a, b);
88                        bool match = false;
89                        char *a2 = a;
90                        do
91                        {
92                                if (MatchName(a2, b, level+1)) { a = a2; match = true; break; }
93                        } while (*a2++);
94                        if (!match) return false;
95                        //for (int i=0; i<level; i++) printf("  "); printf("matched a='%s' b='%s'\n", a, b);
96                }
97                //for (int i=0; i<level; i++) printf("  "); printf("a=%s b=%s\n", a, b);
98                if (!*a && !*b) return true;
99                if (*a && !*b) return false;
100                if (!*a && *b) return false;
101                if (*b != '?' && *a != *b) return false;
102                a++; b++;
103        }
104}
105
106/*
107 * ExtractDirectory
108 * filerootdir can be 0 for just listing files
109 */
110void ExtractDirectory(char *prefix, unsigned int dir_id)
111{
112        char strbuf[MAXPATHLEN];
113        unsigned int save_filepos = ftell(fNDS);
114
115        fseek(fNDS, header.fnt_offset + 8*(dir_id & 0xFFF), SEEK_SET);
116        unsigned_int entry_start;       // reference location of entry name
117        fread(&entry_start, 1, sizeof(entry_start), fNDS);
118        unsigned_short top_file_id;     // file ID of top entry
119        fread(&top_file_id, 1, sizeof(top_file_id), fNDS);
120        unsigned_short parent_id;       // ID of parent directory or directory count (root)
121        fread(&parent_id, 1, sizeof(parent_id), fNDS);
122
123        fseek(fNDS, header.fnt_offset + entry_start, SEEK_SET);
124
125        // print directory name
126        //printf("%04X ", dir_id);
127        if (!filerootdir || verbose)
128        {
129                printf("%s\n", prefix);
130        }
131
132        for (unsigned int file_id=top_file_id; ; file_id++)
133        {
134                unsigned char entry_type_name_length;
135                fread(&entry_type_name_length, 1, sizeof(entry_type_name_length), fNDS);
136                unsigned int name_length = entry_type_name_length & 127;
137                bool entry_type_directory = (entry_type_name_length & 128) ? true : false;
138                if (name_length == 0) break;
139
140                char entry_name[128];
141                memset(entry_name, 0, 128);
142                fread(entry_name, 1, entry_type_name_length & 127, fNDS);
143                if (entry_type_directory)
144                {
145                        unsigned_short dir_id;
146                        fread(&dir_id, 1, sizeof(dir_id), fNDS);
147
148                        if (filerootdir)
149                        {
150                                strcpy(strbuf, filerootdir);
151                                strcat(strbuf, prefix);
152                                strcat(strbuf, entry_name);
153                                MkDir(strbuf);
154                        }
155
156                        strcpy(strbuf, prefix);
157                        strcat(strbuf, entry_name);
158                        strcat(strbuf, "/");
159                        ExtractDirectory(strbuf, dir_id);
160                }
161                else
162                {
163                        if (1)
164                        {
165                                bool match = (filemask_num == 0);
166                                for (int i=0; i<filemask_num; i++)
167                                {
168                                        //printf("%s %s\n", entry_name, filemasks[i]);
169                                        if (MatchName(entry_name, filemasks[i])) { match = true; break; }
170                                }
171
172                                //if (!directorycreated)
173                                //{
174                                //}
175
176                                //printf("%d\n", match);
177
178                                if (match) ExtractFile(filerootdir, prefix, entry_name, file_id);
179                        }
180                }
181        }
182
183        fseek(fNDS, save_filepos, SEEK_SET);
184}
185
186/*
187 * ExtractFiles
188 */
189void ExtractFiles(char *ndsfilename)
190{
191//printf("%d\n", MatchName("hello", "h*el*lo")); exit(0);               // TEST
192        fNDS = fopen(ndsfilename, "rb");
193        if (!fNDS) { fprintf(stderr, "Cannot open file '%s'.\n", ndsfilename); exit(1); }
194        fread(&header, 512, 1, fNDS);
195
196        if (filerootdir)
197        {
198                MkDir(filerootdir);
199        }
200
201        ExtractDirectory("/", 0xF000);          // list or extract
202
203        fclose(fNDS);
204}
205
206/*
207 * ExtractOverlayFiles2
208 */
209 void ExtractOverlayFiles2(unsigned int overlay_offset, unsigned int overlay_size)
210 {
211        OverlayEntry overlayEntry;
212
213        if (overlay_size)
214        {
215                fseek(fNDS, overlay_offset, SEEK_SET);
216                for (unsigned int i=0; i<overlay_size; i+=sizeof(OverlayEntry))
217                {
218                        fread(&overlayEntry, 1, sizeof(overlayEntry), fNDS);
219                        char s[32]; sprintf(s, OVERLAY_FMT, overlayEntry.file_id);
220                        ExtractFile(overlaydir, "/", s, overlayEntry.file_id);
221                }
222        }
223}
224
225/*
226 * ExtractOverlayFiles
227 */
228void ExtractOverlayFiles()
229{
230        fNDS = fopen(ndsfilename, "rb");
231        if (!fNDS) { fprintf(stderr, "Cannot open file '%s'.\n", ndsfilename); exit(1); }
232        fread(&header, 512, 1, fNDS);
233
234        if (overlaydir)
235        {
236                MkDir(overlaydir);
237        }
238
239        ExtractOverlayFiles2(header.arm9_overlay_offset, header.arm9_overlay_size);
240        ExtractOverlayFiles2(header.arm7_overlay_offset, header.arm7_overlay_size);
241
242        fclose(fNDS);
243}
244
245/*
246 * Extract
247 */
248void Extract(char *outfilename, bool indirect_offset, unsigned int offset, bool indirect_size, unsigned size, bool with_footer)
249{
250        fNDS = fopen(ndsfilename, "rb");
251        if (!fNDS) { fprintf(stderr, "Cannot open file '%s'.\n", ndsfilename); exit(1); }
252        fread(&header, 512, 1, fNDS);
253
254        if (indirect_offset) offset = *((unsigned int *)&header + offset/4);
255        if (indirect_size) size = *((unsigned int *)&header + size/4);
256
257        fseek(fNDS, offset, SEEK_SET);
258
259        FILE *fo = fopen(outfilename, "wb");
260        if (!fo) { fprintf(stderr, "Cannot create file '%s'.\n", outfilename); exit(1); }
261
262        unsigned char copybuf[1024];
263        while (size > 0)
264        {
265                unsigned int size2 = (size >= sizeof(copybuf)) ? sizeof(copybuf) : size;
266                fread(copybuf, 1, size2, fNDS);
267                fwrite(copybuf, 1, size2, fo);
268                size -= size2;
269        }
270
271        if (with_footer)
272        {
273                unsigned_int nitrocode;
274                fread(&nitrocode, sizeof(nitrocode), 1, fNDS);
275                if (nitrocode == 0xDEC00621)
276                {
277                        // 0x2106C0DE, version info, reserved?
278                        for (int i=0; i<3; i++)         // write additional 3 words
279                        {
280                                fwrite(&nitrocode, sizeof(nitrocode), 1, fo);
281                                fread(&nitrocode, sizeof(nitrocode), 1, fNDS);  // next field
282                        }
283                }
284        }
285
286        fclose(fo);
287        fclose(fNDS);
288}
Note: See TracBrowser for help on using the repository browser.