diff options
author | Dominik Riebeling <Dominik.Riebeling@gmail.com> | 2021-12-15 21:04:28 +0100 |
---|---|---|
committer | Dominik Riebeling <Dominik.Riebeling@gmail.com> | 2021-12-24 18:05:53 +0100 |
commit | c876d3bbefe0dc00c27ca0c12d29da5874946962 (patch) | |
tree | 69f468a185a369b01998314bc3ecc19b70f4fcaa /rbutil | |
parent | 6c6f0757d7a902feb293be165d1490c42bc8e7ad (diff) | |
download | rockbox-c876d3bbefe0dc00c27ca0c12d29da5874946962.tar.gz rockbox-c876d3bbefe0dc00c27ca0c12d29da5874946962.zip |
rbutil: Merge rbutil with utils folder.
rbutil uses several components from the utils folder, and can be
considered part of utils too. Having it in a separate folder is an
arbitrary split that doesn't help anymore these days, so merge them.
This also allows other utils to easily use libtools.make without the
need to navigate to a different folder.
Change-Id: I3fc2f4de19e3e776553efb5dea5f779dfec0dc21
Diffstat (limited to 'rbutil')
494 files changed, 0 insertions, 154361 deletions
diff --git a/rbutil/bspatch/LICENSE b/rbutil/bspatch/LICENSE deleted file mode 100644 index c82090b3eb..0000000000 --- a/rbutil/bspatch/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ - Copyright 2003-2005 Colin Percival - All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted providing that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. diff --git a/rbutil/bspatch/Makefile b/rbutil/bspatch/Makefile deleted file mode 100644 index 8f287a5ebb..0000000000 --- a/rbutil/bspatch/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# __________ __ ___. -# Open \______ \ ____ ____ | | _\_ |__ _______ ___ -# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -# \/ \/ \/ \/ \/ -# $Id$ -# - -LIBSOURCES := bspatch.c - -SOURCES := main.c - -OUTPUT := bspatch -EXTRADEPS := libbz2.a - -include ../libtools.make diff --git a/rbutil/bspatch/bspatch.c b/rbutil/bspatch/bspatch.c deleted file mode 100644 index d1d7a5aa7a..0000000000 --- a/rbutil/bspatch/bspatch.c +++ /dev/null @@ -1,218 +0,0 @@ -/*- - * Copyright 2003-2005 Colin Percival - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifdef WIN32 -#include <io.h> -#else -#include <stdarg.h> -#include <sys/types.h> -#endif -#include "../bzip2/bzlib.h" -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> - -#define errx err -void err(int exitcode, const char * fmt, ...) -{ - va_list valist; - va_start(valist, fmt); - vprintf(fmt, valist); - va_end(valist); - exit(exitcode); -} - -static long offtin(u_char *buf) -{ - long y; - - y = buf[7] & 0x7F; - y = y * 256;y += buf[6]; - y = y * 256;y += buf[5]; - y = y * 256;y += buf[4]; - y = y * 256;y += buf[3]; - y = y * 256;y += buf[2]; - y = y * 256;y += buf[1]; - y = y * 256;y += buf[0]; - - if (buf[7] & 0x80) y = -y; - - return y; -} - -int apply_bspatch(const char *infile, const char *outfile, const char *patchfile) -{ - FILE * f, *cpf, *dpf, *epf; - BZFILE * cpfbz2, *dpfbz2, *epfbz2; - int cbz2err, dbz2err, ebz2err; - FILE * fs; - long oldsize, newsize; - long bzctrllen, bzdatalen; - u_char header[32], buf[8]; - u_char *pold, *pnew; - long oldpos, newpos; - long ctrl[3]; - long lenread; - long i; - - /* Open patch file */ - if ((f = fopen(patchfile, "r")) == NULL) - err(1, "fopen(%s)", patchfile); - - /* - File format: - 0 8 "BSDIFF40" - 8 8 X - 16 8 Y - 24 8 sizeof(newfile) - 32 X bzip2(control block) - 32+X Y bzip2(diff block) - 32+X+Y ??? bzip2(extra block) - with control block a set of triples (x,y,z) meaning "add x bytes - from oldfile to x bytes from the diff block; copy y bytes from the - extra block; seek forwards in oldfile by z bytes". - */ - - /* Read header */ - if (fread(header, 1, 32, f) < 32) { - if (feof(f)) - errx(1, "Corrupt patch\n"); - err(1, "fread(%s)", patchfile); - } - - /* Check for appropriate magic */ - if (memcmp(header, "BSDIFF40", 8) != 0) - errx(1, "Corrupt patch\n"); - - /* Read lengths from header */ - bzctrllen = offtin(header + 8); - bzdatalen = offtin(header + 16); - newsize = offtin(header + 24); - if ((bzctrllen < 0) || (bzdatalen < 0) || (newsize < 0)) - errx(1, "Corrupt patch\n"); - - /* Close patch file and re-open it via libbzip2 at the right places */ - if (fclose(f)) - err(1, "fclose(%s)", patchfile); - if ((cpf = fopen(patchfile, "rb")) == NULL) - err(1, "fopen(%s)", patchfile); - if (fseek(cpf, 32, SEEK_SET)) - err(1, "fseeko(%s, %lld)", patchfile, - (long long)32); - if ((cpfbz2 = BZ2_bzReadOpen(&cbz2err, cpf, 0, 0, NULL, 0)) == NULL) - errx(1, "BZ2_bzReadOpen, bz2err = %d", cbz2err); - if ((dpf = fopen(patchfile, "rb")) == NULL) - err(1, "fopen(%s)", patchfile); - if (fseek(dpf, 32 + bzctrllen, SEEK_SET)) - err(1, "fseeko(%s, %lld)", patchfile, - (long long)(32 + bzctrllen)); - if ((dpfbz2 = BZ2_bzReadOpen(&dbz2err, dpf, 0, 0, NULL, 0)) == NULL) - errx(1, "BZ2_bzReadOpen, bz2err = %d", dbz2err); - if ((epf = fopen(patchfile, "rb")) == NULL) - err(1, "fopen(%s)", patchfile); - if (fseek(epf, 32 + bzctrllen + bzdatalen, SEEK_SET)) - err(1, "fseeko(%s, %lld)", patchfile, - (long long)(32 + bzctrllen + bzdatalen)); - if ((epfbz2 = BZ2_bzReadOpen(&ebz2err, epf, 0, 0, NULL, 0)) == NULL) - errx(1, "BZ2_bzReadOpen, bz2err = %d", ebz2err); - - fs = fopen(infile, "rb"); - if (fs == NULL)err(1, "Open failed :%s", infile); - if (fseek(fs, 0, SEEK_END) != 0)err(1, "Seek failed :%s", infile); - oldsize = ftell(fs); - pold = (u_char *)malloc(oldsize + 1); - if (pold == NULL) err(1, "Malloc failed :%s", infile); - fseek(fs, 0, SEEK_SET); - if (fread(pold, 1, oldsize, fs) == -1) err(1, "Read failed :%s", infile); - if (fclose(fs) == -1) err(1, "Close failed :%s", infile); - - pnew = malloc(newsize + 1); - if (pnew == NULL)err(1, NULL); - - oldpos = 0;newpos = 0; - while (newpos < newsize) { - /* Read control data */ - for (i = 0;i <= 2;i++) { - lenread = BZ2_bzRead(&cbz2err, cpfbz2, buf, 8); - if ((lenread < 8) || ((cbz2err != BZ_OK) && - (cbz2err != BZ_STREAM_END))) - errx(1, "Corrupt patch\n"); - ctrl[i] = offtin(buf); - }; - - /* Sanity-check */ - if (newpos + ctrl[0] > newsize) - errx(1, "Corrupt patch\n"); - - /* Read diff string */ - lenread = BZ2_bzRead(&dbz2err, dpfbz2, pnew + newpos, ctrl[0]); - if ((lenread < ctrl[0]) || - ((dbz2err != BZ_OK) && (dbz2err != BZ_STREAM_END))) - errx(1, "Corrupt patch\n"); - - /* Add pold data to diff string */ - for (i = 0;i < ctrl[0];i++) - if ((oldpos + i >= 0) && (oldpos + i < oldsize)) - pnew[newpos + i] += pold[oldpos + i]; - - /* Adjust pointers */ - newpos += ctrl[0]; - oldpos += ctrl[0]; - - /* Sanity-check */ - if (newpos + ctrl[1] > newsize) - errx(1, "Corrupt patch\n"); - - /* Read extra string */ - lenread = BZ2_bzRead(&ebz2err, epfbz2, pnew + newpos, ctrl[1]); - if ((lenread < ctrl[1]) || - ((ebz2err != BZ_OK) && (ebz2err != BZ_STREAM_END))) - errx(1, "Corrupt patch\n"); - - /* Adjust pointers */ - newpos += ctrl[1]; - oldpos += ctrl[2]; - }; - - /* Clean up the bzip2 reads */ - BZ2_bzReadClose(&cbz2err, cpfbz2); - BZ2_bzReadClose(&dbz2err, dpfbz2); - BZ2_bzReadClose(&ebz2err, epfbz2); - if (fclose(cpf) || fclose(dpf) || fclose(epf)) - err(1, "fclose(%s)", patchfile); - - /* Write the pnew file */ - fs = fopen(outfile, "wb"); - if (fs == NULL)err(1, "Create failed :%s", outfile); - if (fwrite(pnew, 1, newsize, fs) == -1)err(1, "Write failed :%s", outfile); - if (fclose(fs) == -1)err(1, "Close failed :%s", outfile); - - free(pnew); - free(pold); - - return 0; -} diff --git a/rbutil/bspatch/bspatch.h b/rbutil/bspatch/bspatch.h deleted file mode 100644 index 46edd5db0c..0000000000 --- a/rbutil/bspatch/bspatch.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Simple wrapper for the bspatch entry point. - */ - -#ifndef _BSPATCH_H -#define _BSPATCH_H - -#ifdef __cplusplus -extern "C" { -#endif - -int apply_bspatch(const char *infile, const char *outfile, const char *patchfile); - -#ifdef __cplusplus -} -#endif - - -#endif /* _BSPATCH_H */ diff --git a/rbutil/bspatch/main.c b/rbutil/bspatch/main.c deleted file mode 100644 index e130457256..0000000000 --- a/rbutil/bspatch/main.c +++ /dev/null @@ -1,34 +0,0 @@ -/*- - * Copyright 2003-2005 Colin Percival - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "bspatch.c" - -int main(int argc, char * argv[]) -{ - if (argc != 4) errx(1, "usage: %s oldfile newfile patchfile\n", argv[0]); - - apply_bspatch(argv[1], argv[2], argv[3]); -} diff --git a/rbutil/bzip2/LICENSE b/rbutil/bzip2/LICENSE deleted file mode 100644 index cc614178cf..0000000000 --- a/rbutil/bzip2/LICENSE +++ /dev/null @@ -1,42 +0,0 @@ - --------------------------------------------------------------------------- - -This program, "bzip2", the associated library "libbzip2", and all -documentation, are copyright (C) 1996-2010 Julian R Seward. All -rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. The origin of this software must not be misrepresented; you must - not claim that you wrote the original software. If you use this - software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. - -3. Altered source versions must be plainly marked as such, and must - not be misrepresented as being the original software. - -4. The name of the author may not be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS -OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Julian Seward, jseward@bzip.org -bzip2/libbzip2 version 1.0.6 of 6 September 2010 - --------------------------------------------------------------------------- diff --git a/rbutil/bzip2/Makefile b/rbutil/bzip2/Makefile deleted file mode 100644 index 6dc59ed025..0000000000 --- a/rbutil/bzip2/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# __________ __ ___. -# Open \______ \ ____ ____ | | _\_ |__ _______ ___ -# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -# \/ \/ \/ \/ \/ -# $Id$ -# - -LIBSOURCES := blocksort.c compress.c decompress.c randtable.c \ - bzlib.c crctable.c huffman.c - -OUTPUT := bz2 - -include ../libtools.make diff --git a/rbutil/bzip2/blocksort.c b/rbutil/bzip2/blocksort.c deleted file mode 100644 index d0d662cd4e..0000000000 --- a/rbutil/bzip2/blocksort.c +++ /dev/null @@ -1,1094 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Block sorting machinery ---*/ -/*--- blocksort.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org> - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#include "bzlib_private.h" - -/*---------------------------------------------*/ -/*--- Fallback O(N log(N)^2) sorting ---*/ -/*--- algorithm, for repetitive blocks ---*/ -/*---------------------------------------------*/ - -/*---------------------------------------------*/ -static -__inline__ -void fallbackSimpleSort ( UInt32* fmap, - UInt32* eclass, - Int32 lo, - Int32 hi ) -{ - Int32 i, j, tmp; - UInt32 ec_tmp; - - if (lo == hi) return; - - if (hi - lo > 3) { - for ( i = hi-4; i >= lo; i-- ) { - tmp = fmap[i]; - ec_tmp = eclass[tmp]; - for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 ) - fmap[j-4] = fmap[j]; - fmap[j-4] = tmp; - } - } - - for ( i = hi-1; i >= lo; i-- ) { - tmp = fmap[i]; - ec_tmp = eclass[tmp]; - for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ ) - fmap[j-1] = fmap[j]; - fmap[j-1] = tmp; - } -} - - -/*---------------------------------------------*/ -#define fswap(zz1, zz2) \ - { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; } - -#define fvswap(zzp1, zzp2, zzn) \ -{ \ - Int32 yyp1 = (zzp1); \ - Int32 yyp2 = (zzp2); \ - Int32 yyn = (zzn); \ - while (yyn > 0) { \ - fswap(fmap[yyp1], fmap[yyp2]); \ - yyp1++; yyp2++; yyn--; \ - } \ -} - - -#define fmin(a,b) ((a) < (b)) ? (a) : (b) - -#define fpush(lz,hz) { stackLo[sp] = lz; \ - stackHi[sp] = hz; \ - sp++; } - -#define fpop(lz,hz) { sp--; \ - lz = stackLo[sp]; \ - hz = stackHi[sp]; } - -#define FALLBACK_QSORT_SMALL_THRESH 10 -#define FALLBACK_QSORT_STACK_SIZE 100 - - -static -void fallbackQSort3 ( UInt32* fmap, - UInt32* eclass, - Int32 loSt, - Int32 hiSt ) -{ - Int32 unLo, unHi, ltLo, gtHi, n, m; - Int32 sp, lo, hi; - UInt32 med, r, r3; - Int32 stackLo[FALLBACK_QSORT_STACK_SIZE]; - Int32 stackHi[FALLBACK_QSORT_STACK_SIZE]; - - r = 0; - - sp = 0; - fpush ( loSt, hiSt ); - - while (sp > 0) { - - AssertH ( sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004 ); - - fpop ( lo, hi ); - if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) { - fallbackSimpleSort ( fmap, eclass, lo, hi ); - continue; - } - - /* Random partitioning. Median of 3 sometimes fails to - avoid bad cases. Median of 9 seems to help but - looks rather expensive. This too seems to work but - is cheaper. Guidance for the magic constants - 7621 and 32768 is taken from Sedgewick's algorithms - book, chapter 35. - */ - r = ((r * 7621) + 1) % 32768; - r3 = r % 3; - if (r3 == 0) med = eclass[fmap[lo]]; else - if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else - med = eclass[fmap[hi]]; - - unLo = ltLo = lo; - unHi = gtHi = hi; - - while (1) { - while (1) { - if (unLo > unHi) break; - n = (Int32)eclass[fmap[unLo]] - (Int32)med; - if (n == 0) { - fswap(fmap[unLo], fmap[ltLo]); - ltLo++; unLo++; - continue; - }; - if (n > 0) break; - unLo++; - } - while (1) { - if (unLo > unHi) break; - n = (Int32)eclass[fmap[unHi]] - (Int32)med; - if (n == 0) { - fswap(fmap[unHi], fmap[gtHi]); - gtHi--; unHi--; - continue; - }; - if (n < 0) break; - unHi--; - } - if (unLo > unHi) break; - fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--; - } - - AssertD ( unHi == unLo-1, "fallbackQSort3(2)" ); - - if (gtHi < ltLo) continue; - - n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n); - m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m); - - n = lo + unLo - ltLo - 1; - m = hi - (gtHi - unHi) + 1; - - if (n - lo > hi - m) { - fpush ( lo, n ); - fpush ( m, hi ); - } else { - fpush ( m, hi ); - fpush ( lo, n ); - } - } -} - -#undef fmin -#undef fpush -#undef fpop -#undef fswap -#undef fvswap -#undef FALLBACK_QSORT_SMALL_THRESH -#undef FALLBACK_QSORT_STACK_SIZE - - -/*---------------------------------------------*/ -/* Pre: - nblock > 0 - eclass exists for [0 .. nblock-1] - ((UChar*)eclass) [0 .. nblock-1] holds block - ptr exists for [0 .. nblock-1] - - Post: - ((UChar*)eclass) [0 .. nblock-1] holds block - All other areas of eclass destroyed - fmap [0 .. nblock-1] holds sorted order - bhtab [ 0 .. 2+(nblock/32) ] destroyed -*/ - -#define SET_BH(zz) bhtab[(zz) >> 5] |= (1 << ((zz) & 31)) -#define CLEAR_BH(zz) bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31)) -#define ISSET_BH(zz) (bhtab[(zz) >> 5] & (1 << ((zz) & 31))) -#define WORD_BH(zz) bhtab[(zz) >> 5] -#define UNALIGNED_BH(zz) ((zz) & 0x01f) - -static -void fallbackSort ( UInt32* fmap, - UInt32* eclass, - UInt32* bhtab, - Int32 nblock, - Int32 verb ) -{ - Int32 ftab[257]; - Int32 ftabCopy[256]; - Int32 H, i, j, k, l, r, cc, cc1; - Int32 nNotDone; - Int32 nBhtab; - UChar* eclass8 = (UChar*)eclass; - - /*-- - Initial 1-char radix sort to generate - initial fmap and initial BH bits. - --*/ - if (verb >= 4) - VPrintf0 ( " bucket sorting ...\n" ); - for (i = 0; i < 257; i++) ftab[i] = 0; - for (i = 0; i < nblock; i++) ftab[eclass8[i]]++; - for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i]; - for (i = 1; i < 257; i++) ftab[i] += ftab[i-1]; - - for (i = 0; i < nblock; i++) { - j = eclass8[i]; - k = ftab[j] - 1; - ftab[j] = k; - fmap[k] = i; - } - - nBhtab = 2 + (nblock / 32); - for (i = 0; i < nBhtab; i++) bhtab[i] = 0; - for (i = 0; i < 256; i++) SET_BH(ftab[i]); - - /*-- - Inductively refine the buckets. Kind-of an - "exponential radix sort" (!), inspired by the - Manber-Myers suffix array construction algorithm. - --*/ - - /*-- set sentinel bits for block-end detection --*/ - for (i = 0; i < 32; i++) { - SET_BH(nblock + 2*i); - CLEAR_BH(nblock + 2*i + 1); - } - - /*-- the log(N) loop --*/ - H = 1; - while (1) { - - if (verb >= 4) - VPrintf1 ( " depth %6d has ", H ); - - j = 0; - for (i = 0; i < nblock; i++) { - if (ISSET_BH(i)) j = i; - k = fmap[i] - H; if (k < 0) k += nblock; - eclass[k] = j; - } - - nNotDone = 0; - r = -1; - while (1) { - - /*-- find the next non-singleton bucket --*/ - k = r + 1; - while (ISSET_BH(k) && UNALIGNED_BH(k)) k++; - if (ISSET_BH(k)) { - while (WORD_BH(k) == 0xffffffff) k += 32; - while (ISSET_BH(k)) k++; - } - l = k - 1; - if (l >= nblock) break; - while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++; - if (!ISSET_BH(k)) { - while (WORD_BH(k) == 0x00000000) k += 32; - while (!ISSET_BH(k)) k++; - } - r = k - 1; - if (r >= nblock) break; - - /*-- now [l, r] bracket current bucket --*/ - if (r > l) { - nNotDone += (r - l + 1); - fallbackQSort3 ( fmap, eclass, l, r ); - - /*-- scan bucket and generate header bits-- */ - cc = -1; - for (i = l; i <= r; i++) { - cc1 = eclass[fmap[i]]; - if (cc != cc1) { SET_BH(i); cc = cc1; }; - } - } - } - - if (verb >= 4) - VPrintf1 ( "%6d unresolved strings\n", nNotDone ); - - H *= 2; - if (H > nblock || nNotDone == 0) break; - } - - /*-- - Reconstruct the original block in - eclass8 [0 .. nblock-1], since the - previous phase destroyed it. - --*/ - if (verb >= 4) - VPrintf0 ( " reconstructing block ...\n" ); - j = 0; - for (i = 0; i < nblock; i++) { - while (ftabCopy[j] == 0) j++; - ftabCopy[j]--; - eclass8[fmap[i]] = (UChar)j; - } - AssertH ( j < 256, 1005 ); -} - -#undef SET_BH -#undef CLEAR_BH -#undef ISSET_BH -#undef WORD_BH -#undef UNALIGNED_BH - - -/*---------------------------------------------*/ -/*--- The main, O(N^2 log(N)) sorting ---*/ -/*--- algorithm. Faster for "normal" ---*/ -/*--- non-repetitive blocks. ---*/ -/*---------------------------------------------*/ - -/*---------------------------------------------*/ -static -__inline__ -Bool mainGtU ( UInt32 i1, - UInt32 i2, - UChar* block, - UInt16* quadrant, - UInt32 nblock, - Int32* budget ) -{ - Int32 k; - UChar c1, c2; - UInt16 s1, s2; - - AssertD ( i1 != i2, "mainGtU" ); - /* 1 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 2 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 3 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 4 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 5 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 6 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 7 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 8 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 9 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 10 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 11 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 12 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - - k = nblock + 8; - - do { - /* 1 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 2 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 3 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 4 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 5 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 6 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 7 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 8 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - - if (i1 >= nblock) i1 -= nblock; - if (i2 >= nblock) i2 -= nblock; - - k -= 8; - (*budget)--; - } - while (k >= 0); - - return False; -} - - -/*---------------------------------------------*/ -/*-- - Knuth's increments seem to work better - than Incerpi-Sedgewick here. Possibly - because the number of elems to sort is - usually small, typically <= 20. ---*/ -static -Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280, - 9841, 29524, 88573, 265720, - 797161, 2391484 }; - -static -void mainSimpleSort ( UInt32* ptr, - UChar* block, - UInt16* quadrant, - Int32 nblock, - Int32 lo, - Int32 hi, - Int32 d, - Int32* budget ) -{ - Int32 i, j, h, bigN, hp; - UInt32 v; - - bigN = hi - lo + 1; - if (bigN < 2) return; - - hp = 0; - while (incs[hp] < bigN) hp++; - hp--; - - for (; hp >= 0; hp--) { - h = incs[hp]; - - i = lo + h; - while (True) { - - /*-- copy 1 --*/ - if (i > hi) break; - v = ptr[i]; - j = i; - while ( mainGtU ( - ptr[j-h]+d, v+d, block, quadrant, nblock, budget - ) ) { - ptr[j] = ptr[j-h]; - j = j - h; - if (j <= (lo + h - 1)) break; - } - ptr[j] = v; - i++; - - /*-- copy 2 --*/ - if (i > hi) break; - v = ptr[i]; - j = i; - while ( mainGtU ( - ptr[j-h]+d, v+d, block, quadrant, nblock, budget - ) ) { - ptr[j] = ptr[j-h]; - j = j - h; - if (j <= (lo + h - 1)) break; - } - ptr[j] = v; - i++; - - /*-- copy 3 --*/ - if (i > hi) break; - v = ptr[i]; - j = i; - while ( mainGtU ( - ptr[j-h]+d, v+d, block, quadrant, nblock, budget - ) ) { - ptr[j] = ptr[j-h]; - j = j - h; - if (j <= (lo + h - 1)) break; - } - ptr[j] = v; - i++; - - if (*budget < 0) return; - } - } -} - - -/*---------------------------------------------*/ -/*-- - The following is an implementation of - an elegant 3-way quicksort for strings, - described in a paper "Fast Algorithms for - Sorting and Searching Strings", by Robert - Sedgewick and Jon L. Bentley. ---*/ - -#define mswap(zz1, zz2) \ - { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; } - -#define mvswap(zzp1, zzp2, zzn) \ -{ \ - Int32 yyp1 = (zzp1); \ - Int32 yyp2 = (zzp2); \ - Int32 yyn = (zzn); \ - while (yyn > 0) { \ - mswap(ptr[yyp1], ptr[yyp2]); \ - yyp1++; yyp2++; yyn--; \ - } \ -} - -static -__inline__ -UChar mmed3 ( UChar a, UChar b, UChar c ) -{ - UChar t; - if (a > b) { t = a; a = b; b = t; }; - if (b > c) { - b = c; - if (a > b) b = a; - } - return b; -} - -#define mmin(a,b) ((a) < (b)) ? (a) : (b) - -#define mpush(lz,hz,dz) { stackLo[sp] = lz; \ - stackHi[sp] = hz; \ - stackD [sp] = dz; \ - sp++; } - -#define mpop(lz,hz,dz) { sp--; \ - lz = stackLo[sp]; \ - hz = stackHi[sp]; \ - dz = stackD [sp]; } - - -#define mnextsize(az) (nextHi[az]-nextLo[az]) - -#define mnextswap(az,bz) \ - { Int32 tz; \ - tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \ - tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \ - tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; } - - -#define MAIN_QSORT_SMALL_THRESH 20 -#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT) -#define MAIN_QSORT_STACK_SIZE 100 - -static -void mainQSort3 ( UInt32* ptr, - UChar* block, - UInt16* quadrant, - Int32 nblock, - Int32 loSt, - Int32 hiSt, - Int32 dSt, - Int32* budget ) -{ - Int32 unLo, unHi, ltLo, gtHi, n, m, med; - Int32 sp, lo, hi, d; - - Int32 stackLo[MAIN_QSORT_STACK_SIZE]; - Int32 stackHi[MAIN_QSORT_STACK_SIZE]; - Int32 stackD [MAIN_QSORT_STACK_SIZE]; - - Int32 nextLo[3]; - Int32 nextHi[3]; - Int32 nextD [3]; - - sp = 0; - mpush ( loSt, hiSt, dSt ); - - while (sp > 0) { - - AssertH ( sp < MAIN_QSORT_STACK_SIZE - 2, 1001 ); - - mpop ( lo, hi, d ); - if (hi - lo < MAIN_QSORT_SMALL_THRESH || - d > MAIN_QSORT_DEPTH_THRESH) { - mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget ); - if (*budget < 0) return; - continue; - } - - med = (Int32) - mmed3 ( block[ptr[ lo ]+d], - block[ptr[ hi ]+d], - block[ptr[ (lo+hi)>>1 ]+d] ); - - unLo = ltLo = lo; - unHi = gtHi = hi; - - while (True) { - while (True) { - if (unLo > unHi) break; - n = ((Int32)block[ptr[unLo]+d]) - med; - if (n == 0) { - mswap(ptr[unLo], ptr[ltLo]); - ltLo++; unLo++; continue; - }; - if (n > 0) break; - unLo++; - } - while (True) { - if (unLo > unHi) break; - n = ((Int32)block[ptr[unHi]+d]) - med; - if (n == 0) { - mswap(ptr[unHi], ptr[gtHi]); - gtHi--; unHi--; continue; - }; - if (n < 0) break; - unHi--; - } - if (unLo > unHi) break; - mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--; - } - - AssertD ( unHi == unLo-1, "mainQSort3(2)" ); - - if (gtHi < ltLo) { - mpush(lo, hi, d+1 ); - continue; - } - - n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n); - m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m); - - n = lo + unLo - ltLo - 1; - m = hi - (gtHi - unHi) + 1; - - nextLo[0] = lo; nextHi[0] = n; nextD[0] = d; - nextLo[1] = m; nextHi[1] = hi; nextD[1] = d; - nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1; - - if (mnextsize(0) < mnextsize(1)) mnextswap(0,1); - if (mnextsize(1) < mnextsize(2)) mnextswap(1,2); - if (mnextsize(0) < mnextsize(1)) mnextswap(0,1); - - AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" ); - AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" ); - - mpush (nextLo[0], nextHi[0], nextD[0]); - mpush (nextLo[1], nextHi[1], nextD[1]); - mpush (nextLo[2], nextHi[2], nextD[2]); - } -} - -#undef mswap -#undef mvswap -#undef mpush -#undef mpop -#undef mmin -#undef mnextsize -#undef mnextswap -#undef MAIN_QSORT_SMALL_THRESH -#undef MAIN_QSORT_DEPTH_THRESH -#undef MAIN_QSORT_STACK_SIZE - - -/*---------------------------------------------*/ -/* Pre: - nblock > N_OVERSHOOT - block32 exists for [0 .. nblock-1 +N_OVERSHOOT] - ((UChar*)block32) [0 .. nblock-1] holds block - ptr exists for [0 .. nblock-1] - - Post: - ((UChar*)block32) [0 .. nblock-1] holds block - All other areas of block32 destroyed - ftab [0 .. 65536 ] destroyed - ptr [0 .. nblock-1] holds sorted order - if (*budget < 0), sorting was abandoned -*/ - -#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8]) -#define SETMASK (1 << 21) -#define CLEARMASK (~(SETMASK)) - -static -void mainSort ( UInt32* ptr, - UChar* block, - UInt16* quadrant, - UInt32* ftab, - Int32 nblock, - Int32 verb, - Int32* budget ) -{ - Int32 i, j, k, ss, sb; - Int32 runningOrder[256]; - Bool bigDone[256]; - Int32 copyStart[256]; - Int32 copyEnd [256]; - UChar c1; - Int32 numQSorted; - UInt16 s; - if (verb >= 4) VPrintf0 ( " main sort initialise ...\n" ); - - /*-- set up the 2-byte frequency table --*/ - for (i = 65536; i >= 0; i--) ftab[i] = 0; - - j = block[0] << 8; - i = nblock-1; - for (; i >= 3; i -= 4) { - quadrant[i] = 0; - j = (j >> 8) | ( ((UInt16)block[i]) << 8); - ftab[j]++; - quadrant[i-1] = 0; - j = (j >> 8) | ( ((UInt16)block[i-1]) << 8); - ftab[j]++; - quadrant[i-2] = 0; - j = (j >> 8) | ( ((UInt16)block[i-2]) << 8); - ftab[j]++; - quadrant[i-3] = 0; - j = (j >> 8) | ( ((UInt16)block[i-3]) << 8); - ftab[j]++; - } - for (; i >= 0; i--) { - quadrant[i] = 0; - j = (j >> 8) | ( ((UInt16)block[i]) << 8); - ftab[j]++; - } - - /*-- (emphasises close relationship of block & quadrant) --*/ - for (i = 0; i < BZ_N_OVERSHOOT; i++) { - block [nblock+i] = block[i]; - quadrant[nblock+i] = 0; - } - - if (verb >= 4) VPrintf0 ( " bucket sorting ...\n" ); - - /*-- Complete the initial radix sort --*/ - for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1]; - - s = block[0] << 8; - i = nblock-1; - for (; i >= 3; i -= 4) { - s = (s >> 8) | (block[i] << 8); - j = ftab[s] -1; - ftab[s] = j; - ptr[j] = i; - s = (s >> 8) | (block[i-1] << 8); - j = ftab[s] -1; - ftab[s] = j; - ptr[j] = i-1; - s = (s >> 8) | (block[i-2] << 8); - j = ftab[s] -1; - ftab[s] = j; - ptr[j] = i-2; - s = (s >> 8) | (block[i-3] << 8); - j = ftab[s] -1; - ftab[s] = j; - ptr[j] = i-3; - } - for (; i >= 0; i--) { - s = (s >> 8) | (block[i] << 8); - j = ftab[s] -1; - ftab[s] = j; - ptr[j] = i; - } - - /*-- - Now ftab contains the first loc of every small bucket. - Calculate the running order, from smallest to largest - big bucket. - --*/ - for (i = 0; i <= 255; i++) { - bigDone [i] = False; - runningOrder[i] = i; - } - - { - Int32 vv; - Int32 h = 1; - do h = 3 * h + 1; while (h <= 256); - do { - h = h / 3; - for (i = h; i <= 255; i++) { - vv = runningOrder[i]; - j = i; - while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) { - runningOrder[j] = runningOrder[j-h]; - j = j - h; - if (j <= (h - 1)) goto zero; - } - zero: - runningOrder[j] = vv; - } - } while (h != 1); - } - - /*-- - The main sorting loop. - --*/ - - numQSorted = 0; - - for (i = 0; i <= 255; i++) { - - /*-- - Process big buckets, starting with the least full. - Basically this is a 3-step process in which we call - mainQSort3 to sort the small buckets [ss, j], but - also make a big effort to avoid the calls if we can. - --*/ - ss = runningOrder[i]; - - /*-- - Step 1: - Complete the big bucket [ss] by quicksorting - any unsorted small buckets [ss, j], for j != ss. - Hopefully previous pointer-scanning phases have already - completed many of the small buckets [ss, j], so - we don't have to sort them at all. - --*/ - for (j = 0; j <= 255; j++) { - if (j != ss) { - sb = (ss << 8) + j; - if ( ! (ftab[sb] & SETMASK) ) { - Int32 lo = ftab[sb] & CLEARMASK; - Int32 hi = (ftab[sb+1] & CLEARMASK) - 1; - if (hi > lo) { - if (verb >= 4) - VPrintf4 ( " qsort [0x%x, 0x%x] " - "done %d this %d\n", - ss, j, numQSorted, hi - lo + 1 ); - mainQSort3 ( - ptr, block, quadrant, nblock, - lo, hi, BZ_N_RADIX, budget - ); - numQSorted += (hi - lo + 1); - if (*budget < 0) return; - } - } - ftab[sb] |= SETMASK; - } - } - - AssertH ( !bigDone[ss], 1006 ); - - /*-- - Step 2: - Now scan this big bucket [ss] so as to synthesise the - sorted order for small buckets [t, ss] for all t, - including, magically, the bucket [ss,ss] too. - This will avoid doing Real Work in subsequent Step 1's. - --*/ - { - for (j = 0; j <= 255; j++) { - copyStart[j] = ftab[(j << 8) + ss] & CLEARMASK; - copyEnd [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1; - } - for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) { - k = ptr[j]-1; if (k < 0) k += nblock; - c1 = block[k]; - if (!bigDone[c1]) - ptr[ copyStart[c1]++ ] = k; - } - for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) { - k = ptr[j]-1; if (k < 0) k += nblock; - c1 = block[k]; - if (!bigDone[c1]) - ptr[ copyEnd[c1]-- ] = k; - } - } - - AssertH ( (copyStart[ss]-1 == copyEnd[ss]) - || - /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1. - Necessity for this case is demonstrated by compressing - a sequence of approximately 48.5 million of character - 251; 1.0.0/1.0.1 will then die here. */ - (copyStart[ss] == 0 && copyEnd[ss] == nblock-1), - 1007 ) - - for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK; - - /*-- - Step 3: - The [ss] big bucket is now done. Record this fact, - and update the quadrant descriptors. Remember to - update quadrants in the overshoot area too, if - necessary. The "if (i < 255)" test merely skips - this updating for the last bucket processed, since - updating for the last bucket is pointless. - - The quadrant array provides a way to incrementally - cache sort orderings, as they appear, so as to - make subsequent comparisons in fullGtU() complete - faster. For repetitive blocks this makes a big - difference (but not big enough to be able to avoid - the fallback sorting mechanism, exponential radix sort). - - The precise meaning is: at all times: - - for 0 <= i < nblock and 0 <= j <= nblock - - if block[i] != block[j], - - then the relative values of quadrant[i] and - quadrant[j] are meaningless. - - else { - if quadrant[i] < quadrant[j] - then the string starting at i lexicographically - precedes the string starting at j - - else if quadrant[i] > quadrant[j] - then the string starting at j lexicographically - precedes the string starting at i - - else - the relative ordering of the strings starting - at i and j has not yet been determined. - } - --*/ - bigDone[ss] = True; - - if (i < 255) { - Int32 bbStart = ftab[ss << 8] & CLEARMASK; - Int32 bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart; - Int32 shifts = 0; - - while ((bbSize >> shifts) > 65534) shifts++; - - for (j = bbSize-1; j >= 0; j--) { - Int32 a2update = ptr[bbStart + j]; - UInt16 qVal = (UInt16)(j >> shifts); - quadrant[a2update] = qVal; - if (a2update < BZ_N_OVERSHOOT) - quadrant[a2update + nblock] = qVal; - } - AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 ); - } - - } - - if (verb >= 4) - VPrintf3 ( " %d pointers, %d sorted, %d scanned\n", - nblock, numQSorted, nblock - numQSorted ); -} - -#undef BIGFREQ -#undef SETMASK -#undef CLEARMASK - - -/*---------------------------------------------*/ -/* Pre: - nblock > 0 - arr2 exists for [0 .. nblock-1 +N_OVERSHOOT] - ((UChar*)arr2) [0 .. nblock-1] holds block - arr1 exists for [0 .. nblock-1] - - Post: - ((UChar*)arr2) [0 .. nblock-1] holds block - All other areas of block destroyed - ftab [ 0 .. 65536 ] destroyed - arr1 [0 .. nblock-1] holds sorted order -*/ -void BZ2_blockSort ( EState* s ) -{ - UInt32* ptr = s->ptr; - UChar* block = s->block; - UInt32* ftab = s->ftab; - Int32 nblock = s->nblock; - Int32 verb = s->verbosity; - Int32 wfact = s->workFactor; - UInt16* quadrant; - Int32 budget; - Int32 budgetInit; - Int32 i; - - if (nblock < 10000) { - fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb ); - } else { - /* Calculate the location for quadrant, remembering to get - the alignment right. Assumes that &(block[0]) is at least - 2-byte aligned -- this should be ok since block is really - the first section of arr2. - */ - i = nblock+BZ_N_OVERSHOOT; - if (i & 1) i++; - quadrant = (UInt16*)(&(block[i])); - - /* (wfact-1) / 3 puts the default-factor-30 - transition point at very roughly the same place as - with v0.1 and v0.9.0. - Not that it particularly matters any more, since the - resulting compressed stream is now the same regardless - of whether or not we use the main sort or fallback sort. - */ - if (wfact < 1 ) wfact = 1; - if (wfact > 100) wfact = 100; - budgetInit = nblock * ((wfact-1) / 3); - budget = budgetInit; - - mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget ); - if (verb >= 3) - VPrintf3 ( " %d work, %d block, ratio %5.2f\n", - budgetInit - budget, - nblock, - (float)(budgetInit - budget) / - (float)(nblock==0 ? 1 : nblock) ); - if (budget < 0) { - if (verb >= 2) - VPrintf0 ( " too repetitive; using fallback" - " sorting algorithm\n" ); - fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb ); - } - } - - s->origPtr = -1; - for (i = 0; i < s->nblock; i++) - if (ptr[i] == 0) - { s->origPtr = i; break; }; - - AssertH( s->origPtr != -1, 1003 ); -} - - -/*-------------------------------------------------------------*/ -/*--- end blocksort.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/rbutil/bzip2/bzlib.c b/rbutil/bzip2/bzlib.c deleted file mode 100644 index 6e78e19407..0000000000 --- a/rbutil/bzip2/bzlib.c +++ /dev/null @@ -1,1572 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Library top-level functions. ---*/ -/*--- bzlib.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org> - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - -/* CHANGES - 0.9.0 -- original version. - 0.9.0a/b -- no changes in this file. - 0.9.0c -- made zero-length BZ_FLUSH work correctly in bzCompress(). - fixed bzWrite/bzRead to ignore zero-length requests. - fixed bzread to correctly handle read requests after EOF. - wrong parameter order in call to bzDecompressInit in - bzBuffToBuffDecompress. Fixed. -*/ - -#include "bzlib_private.h" - - -/*---------------------------------------------------*/ -/*--- Compression stuff ---*/ -/*---------------------------------------------------*/ - - -/*---------------------------------------------------*/ -#ifndef BZ_NO_STDIO -void BZ2_bz__AssertH__fail ( int errcode ) -{ - fprintf(stderr, - "\n\nbzip2/libbzip2: internal error number %d.\n" - "This is a bug in bzip2/libbzip2, %s.\n" - "Please report it to me at: jseward@bzip.org. If this happened\n" - "when you were using some program which uses libbzip2 as a\n" - "component, you should also report this bug to the author(s)\n" - "of that program. Please make an effort to report this bug;\n" - "timely and accurate bug reports eventually lead to higher\n" - "quality software. Thanks. Julian Seward, 10 December 2007.\n\n", - errcode, - BZ2_bzlibVersion() - ); - - if (errcode == 1007) { - fprintf(stderr, - "\n*** A special note about internal error number 1007 ***\n" - "\n" - "Experience suggests that a common cause of i.e. 1007\n" - "is unreliable memory or other hardware. The 1007 assertion\n" - "just happens to cross-check the results of huge numbers of\n" - "memory reads/writes, and so acts (unintendedly) as a stress\n" - "test of your memory system.\n" - "\n" - "I suggest the following: try compressing the file again,\n" - "possibly monitoring progress in detail with the -vv flag.\n" - "\n" - "* If the error cannot be reproduced, and/or happens at different\n" - " points in compression, you may have a flaky memory system.\n" - " Try a memory-test program. I have used Memtest86\n" - " (www.memtest86.com). At the time of writing it is free (GPLd).\n" - " Memtest86 tests memory much more thorougly than your BIOSs\n" - " power-on test, and may find failures that the BIOS doesn't.\n" - "\n" - "* If the error can be repeatably reproduced, this is a bug in\n" - " bzip2, and I would very much like to hear about it. Please\n" - " let me know, and, ideally, save a copy of the file causing the\n" - " problem -- without which I will be unable to investigate it.\n" - "\n" - ); - } - - exit(3); -} -#endif - - -/*---------------------------------------------------*/ -static -int bz_config_ok ( void ) -{ - if (sizeof(int) != 4) return 0; - if (sizeof(short) != 2) return 0; - if (sizeof(char) != 1) return 0; - return 1; -} - - -/*---------------------------------------------------*/ -static -void* default_bzalloc ( void* opaque, Int32 items, Int32 size ) -{ - void* v = malloc ( items * size ); - return v; -} - -static -void default_bzfree ( void* opaque, void* addr ) -{ - if (addr != NULL) free ( addr ); -} - - -/*---------------------------------------------------*/ -static -void prepare_new_block ( EState* s ) -{ - Int32 i; - s->nblock = 0; - s->numZ = 0; - s->state_out_pos = 0; - BZ_INITIALISE_CRC ( s->blockCRC ); - for (i = 0; i < 256; i++) s->inUse[i] = False; - s->blockNo++; -} - - -/*---------------------------------------------------*/ -static -void init_RL ( EState* s ) -{ - s->state_in_ch = 256; - s->state_in_len = 0; -} - - -static -Bool isempty_RL ( EState* s ) -{ - if (s->state_in_ch < 256 && s->state_in_len > 0) - return False; else - return True; -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzCompressInit) - ( bz_stream* strm, - int blockSize100k, - int verbosity, - int workFactor ) -{ - Int32 n; - EState* s; - - if (!bz_config_ok()) return BZ_CONFIG_ERROR; - - if (strm == NULL || - blockSize100k < 1 || blockSize100k > 9 || - workFactor < 0 || workFactor > 250) - return BZ_PARAM_ERROR; - - if (workFactor == 0) workFactor = 30; - if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc; - if (strm->bzfree == NULL) strm->bzfree = default_bzfree; - - s = BZALLOC( sizeof(EState) ); - if (s == NULL) return BZ_MEM_ERROR; - s->strm = strm; - - s->arr1 = NULL; - s->arr2 = NULL; - s->ftab = NULL; - - n = 100000 * blockSize100k; - s->arr1 = BZALLOC( n * sizeof(UInt32) ); - s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) ); - s->ftab = BZALLOC( 65537 * sizeof(UInt32) ); - - if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) { - if (s->arr1 != NULL) BZFREE(s->arr1); - if (s->arr2 != NULL) BZFREE(s->arr2); - if (s->ftab != NULL) BZFREE(s->ftab); - if (s != NULL) BZFREE(s); - return BZ_MEM_ERROR; - } - - s->blockNo = 0; - s->state = BZ_S_INPUT; - s->mode = BZ_M_RUNNING; - s->combinedCRC = 0; - s->blockSize100k = blockSize100k; - s->nblockMAX = 100000 * blockSize100k - 19; - s->verbosity = verbosity; - s->workFactor = workFactor; - - s->block = (UChar*)s->arr2; - s->mtfv = (UInt16*)s->arr1; - s->zbits = NULL; - s->ptr = (UInt32*)s->arr1; - - strm->state = s; - strm->total_in_lo32 = 0; - strm->total_in_hi32 = 0; - strm->total_out_lo32 = 0; - strm->total_out_hi32 = 0; - init_RL ( s ); - prepare_new_block ( s ); - return BZ_OK; -} - - -/*---------------------------------------------------*/ -static -void add_pair_to_block ( EState* s ) -{ - Int32 i; - UChar ch = (UChar)(s->state_in_ch); - for (i = 0; i < s->state_in_len; i++) { - BZ_UPDATE_CRC( s->blockCRC, ch ); - } - s->inUse[s->state_in_ch] = True; - switch (s->state_in_len) { - case 1: - s->block[s->nblock] = (UChar)ch; s->nblock++; - break; - case 2: - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - break; - case 3: - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - break; - default: - s->inUse[s->state_in_len-4] = True; - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = ((UChar)(s->state_in_len-4)); - s->nblock++; - break; - } -} - - -/*---------------------------------------------------*/ -static -void flush_RL ( EState* s ) -{ - if (s->state_in_ch < 256) add_pair_to_block ( s ); - init_RL ( s ); -} - - -/*---------------------------------------------------*/ -#define ADD_CHAR_TO_BLOCK(zs,zchh0) \ -{ \ - UInt32 zchh = (UInt32)(zchh0); \ - /*-- fast track the common case --*/ \ - if (zchh != zs->state_in_ch && \ - zs->state_in_len == 1) { \ - UChar ch = (UChar)(zs->state_in_ch); \ - BZ_UPDATE_CRC( zs->blockCRC, ch ); \ - zs->inUse[zs->state_in_ch] = True; \ - zs->block[zs->nblock] = (UChar)ch; \ - zs->nblock++; \ - zs->state_in_ch = zchh; \ - } \ - else \ - /*-- general, uncommon cases --*/ \ - if (zchh != zs->state_in_ch || \ - zs->state_in_len == 255) { \ - if (zs->state_in_ch < 256) \ - add_pair_to_block ( zs ); \ - zs->state_in_ch = zchh; \ - zs->state_in_len = 1; \ - } else { \ - zs->state_in_len++; \ - } \ -} - - -/*---------------------------------------------------*/ -static -Bool copy_input_until_stop ( EState* s ) -{ - Bool progress_in = False; - - if (s->mode == BZ_M_RUNNING) { - - /*-- fast track the common case --*/ - while (True) { - /*-- block full? --*/ - if (s->nblock >= s->nblockMAX) break; - /*-- no input? --*/ - if (s->strm->avail_in == 0) break; - progress_in = True; - ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); - s->strm->next_in++; - s->strm->avail_in--; - s->strm->total_in_lo32++; - if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++; - } - - } else { - - /*-- general, uncommon case --*/ - while (True) { - /*-- block full? --*/ - if (s->nblock >= s->nblockMAX) break; - /*-- no input? --*/ - if (s->strm->avail_in == 0) break; - /*-- flush/finish end? --*/ - if (s->avail_in_expect == 0) break; - progress_in = True; - ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); - s->strm->next_in++; - s->strm->avail_in--; - s->strm->total_in_lo32++; - if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++; - s->avail_in_expect--; - } - } - return progress_in; -} - - -/*---------------------------------------------------*/ -static -Bool copy_output_until_stop ( EState* s ) -{ - Bool progress_out = False; - - while (True) { - - /*-- no output space? --*/ - if (s->strm->avail_out == 0) break; - - /*-- block done? --*/ - if (s->state_out_pos >= s->numZ) break; - - progress_out = True; - *(s->strm->next_out) = s->zbits[s->state_out_pos]; - s->state_out_pos++; - s->strm->avail_out--; - s->strm->next_out++; - s->strm->total_out_lo32++; - if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; - } - - return progress_out; -} - - -/*---------------------------------------------------*/ -static -Bool handle_compress ( bz_stream* strm ) -{ - Bool progress_in = False; - Bool progress_out = False; - EState* s = strm->state; - - while (True) { - - if (s->state == BZ_S_OUTPUT) { - progress_out |= copy_output_until_stop ( s ); - if (s->state_out_pos < s->numZ) break; - if (s->mode == BZ_M_FINISHING && - s->avail_in_expect == 0 && - isempty_RL(s)) break; - prepare_new_block ( s ); - s->state = BZ_S_INPUT; - if (s->mode == BZ_M_FLUSHING && - s->avail_in_expect == 0 && - isempty_RL(s)) break; - } - - if (s->state == BZ_S_INPUT) { - progress_in |= copy_input_until_stop ( s ); - if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) { - flush_RL ( s ); - BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) ); - s->state = BZ_S_OUTPUT; - } - else - if (s->nblock >= s->nblockMAX) { - BZ2_compressBlock ( s, False ); - s->state = BZ_S_OUTPUT; - } - else - if (s->strm->avail_in == 0) { - break; - } - } - - } - - return progress_in || progress_out; -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action ) -{ - Bool progress; - EState* s; - if (strm == NULL) return BZ_PARAM_ERROR; - s = strm->state; - if (s == NULL) return BZ_PARAM_ERROR; - if (s->strm != strm) return BZ_PARAM_ERROR; - - preswitch: - switch (s->mode) { - - case BZ_M_IDLE: - return BZ_SEQUENCE_ERROR; - - case BZ_M_RUNNING: - if (action == BZ_RUN) { - progress = handle_compress ( strm ); - return progress ? BZ_RUN_OK : BZ_PARAM_ERROR; - } - else - if (action == BZ_FLUSH) { - s->avail_in_expect = strm->avail_in; - s->mode = BZ_M_FLUSHING; - goto preswitch; - } - else - if (action == BZ_FINISH) { - s->avail_in_expect = strm->avail_in; - s->mode = BZ_M_FINISHING; - goto preswitch; - } - else - return BZ_PARAM_ERROR; - - case BZ_M_FLUSHING: - if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR; - if (s->avail_in_expect != s->strm->avail_in) - return BZ_SEQUENCE_ERROR; - progress = handle_compress ( strm ); - if (s->avail_in_expect > 0 || !isempty_RL(s) || - s->state_out_pos < s->numZ) return BZ_FLUSH_OK; - s->mode = BZ_M_RUNNING; - return BZ_RUN_OK; - - case BZ_M_FINISHING: - if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR; - if (s->avail_in_expect != s->strm->avail_in) - return BZ_SEQUENCE_ERROR; - progress = handle_compress ( strm ); - if (!progress) return BZ_SEQUENCE_ERROR; - if (s->avail_in_expect > 0 || !isempty_RL(s) || - s->state_out_pos < s->numZ) return BZ_FINISH_OK; - s->mode = BZ_M_IDLE; - return BZ_STREAM_END; - } - return BZ_OK; /*--not reached--*/ -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzCompressEnd) ( bz_stream *strm ) -{ - EState* s; - if (strm == NULL) return BZ_PARAM_ERROR; - s = strm->state; - if (s == NULL) return BZ_PARAM_ERROR; - if (s->strm != strm) return BZ_PARAM_ERROR; - - if (s->arr1 != NULL) BZFREE(s->arr1); - if (s->arr2 != NULL) BZFREE(s->arr2); - if (s->ftab != NULL) BZFREE(s->ftab); - BZFREE(strm->state); - - strm->state = NULL; - - return BZ_OK; -} - - -/*---------------------------------------------------*/ -/*--- Decompression stuff ---*/ -/*---------------------------------------------------*/ - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzDecompressInit) - ( bz_stream* strm, - int verbosity, - int small ) -{ - DState* s; - - if (!bz_config_ok()) return BZ_CONFIG_ERROR; - - if (strm == NULL) return BZ_PARAM_ERROR; - if (small != 0 && small != 1) return BZ_PARAM_ERROR; - if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR; - - if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc; - if (strm->bzfree == NULL) strm->bzfree = default_bzfree; - - s = BZALLOC( sizeof(DState) ); - if (s == NULL) return BZ_MEM_ERROR; - s->strm = strm; - strm->state = s; - s->state = BZ_X_MAGIC_1; - s->bsLive = 0; - s->bsBuff = 0; - s->calculatedCombinedCRC = 0; - strm->total_in_lo32 = 0; - strm->total_in_hi32 = 0; - strm->total_out_lo32 = 0; - strm->total_out_hi32 = 0; - s->smallDecompress = (Bool)small; - s->ll4 = NULL; - s->ll16 = NULL; - s->tt = NULL; - s->currBlockNo = 0; - s->verbosity = verbosity; - - return BZ_OK; -} - - -/*---------------------------------------------------*/ -/* Return True iff data corruption is discovered. - Returns False if there is no problem. -*/ -static -Bool unRLE_obuf_to_output_FAST ( DState* s ) -{ - UChar k1; - - if (s->blockRandomised) { - - while (True) { - /* try to finish existing run */ - while (True) { - if (s->strm->avail_out == 0) return False; - if (s->state_out_len == 0) break; - *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; - BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); - s->state_out_len--; - s->strm->next_out++; - s->strm->avail_out--; - s->strm->total_out_lo32++; - if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; - } - - /* can a new run be started? */ - if (s->nblock_used == s->save_nblock+1) return False; - - /* Only caused by corrupt data stream? */ - if (s->nblock_used > s->save_nblock+1) - return True; - - s->state_out_len = 1; - s->state_out_ch = s->k0; - BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 2; - BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 3; - BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - s->state_out_len = ((Int32)k1) + 4; - BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK; - s->k0 ^= BZ_RAND_MASK; s->nblock_used++; - } - - } else { - - /* restore */ - UInt32 c_calculatedBlockCRC = s->calculatedBlockCRC; - UChar c_state_out_ch = s->state_out_ch; - Int32 c_state_out_len = s->state_out_len; - Int32 c_nblock_used = s->nblock_used; - Int32 c_k0 = s->k0; - UInt32* c_tt = s->tt; - UInt32 c_tPos = s->tPos; - char* cs_next_out = s->strm->next_out; - unsigned int cs_avail_out = s->strm->avail_out; - Int32 ro_blockSize100k = s->blockSize100k; - /* end restore */ - - UInt32 avail_out_INIT = cs_avail_out; - Int32 s_save_nblockPP = s->save_nblock+1; - unsigned int total_out_lo32_old; - - while (True) { - - /* try to finish existing run */ - if (c_state_out_len > 0) { - while (True) { - if (cs_avail_out == 0) goto return_notr; - if (c_state_out_len == 1) break; - *( (UChar*)(cs_next_out) ) = c_state_out_ch; - BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch ); - c_state_out_len--; - cs_next_out++; - cs_avail_out--; - } - s_state_out_len_eq_one: - { - if (cs_avail_out == 0) { - c_state_out_len = 1; goto return_notr; - }; - *( (UChar*)(cs_next_out) ) = c_state_out_ch; - BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch ); - cs_next_out++; - cs_avail_out--; - } - } - /* Only caused by corrupt data stream? */ - if (c_nblock_used > s_save_nblockPP) - return True; - - /* can a new run be started? */ - if (c_nblock_used == s_save_nblockPP) { - c_state_out_len = 0; goto return_notr; - }; - c_state_out_ch = c_k0; - BZ_GET_FAST_C(k1); c_nblock_used++; - if (k1 != c_k0) { - c_k0 = k1; goto s_state_out_len_eq_one; - }; - if (c_nblock_used == s_save_nblockPP) - goto s_state_out_len_eq_one; - - c_state_out_len = 2; - BZ_GET_FAST_C(k1); c_nblock_used++; - if (c_nblock_used == s_save_nblockPP) continue; - if (k1 != c_k0) { c_k0 = k1; continue; }; - - c_state_out_len = 3; - BZ_GET_FAST_C(k1); c_nblock_used++; - if (c_nblock_used == s_save_nblockPP) continue; - if (k1 != c_k0) { c_k0 = k1; continue; }; - - BZ_GET_FAST_C(k1); c_nblock_used++; - c_state_out_len = ((Int32)k1) + 4; - BZ_GET_FAST_C(c_k0); c_nblock_used++; - } - - return_notr: - total_out_lo32_old = s->strm->total_out_lo32; - s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out); - if (s->strm->total_out_lo32 < total_out_lo32_old) - s->strm->total_out_hi32++; - - /* save */ - s->calculatedBlockCRC = c_calculatedBlockCRC; - s->state_out_ch = c_state_out_ch; - s->state_out_len = c_state_out_len; - s->nblock_used = c_nblock_used; - s->k0 = c_k0; - s->tt = c_tt; - s->tPos = c_tPos; - s->strm->next_out = cs_next_out; - s->strm->avail_out = cs_avail_out; - /* end save */ - } - return False; -} - - - -/*---------------------------------------------------*/ -__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab ) -{ - Int32 nb, na, mid; - nb = 0; - na = 256; - do { - mid = (nb + na) >> 1; - if (indx >= cftab[mid]) nb = mid; else na = mid; - } - while (na - nb != 1); - return nb; -} - - -/*---------------------------------------------------*/ -/* Return True iff data corruption is discovered. - Returns False if there is no problem. -*/ -static -Bool unRLE_obuf_to_output_SMALL ( DState* s ) -{ - UChar k1; - - if (s->blockRandomised) { - - while (True) { - /* try to finish existing run */ - while (True) { - if (s->strm->avail_out == 0) return False; - if (s->state_out_len == 0) break; - *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; - BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); - s->state_out_len--; - s->strm->next_out++; - s->strm->avail_out--; - s->strm->total_out_lo32++; - if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; - } - - /* can a new run be started? */ - if (s->nblock_used == s->save_nblock+1) return False; - - /* Only caused by corrupt data stream? */ - if (s->nblock_used > s->save_nblock+1) - return True; - - s->state_out_len = 1; - s->state_out_ch = s->k0; - BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 2; - BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 3; - BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - s->state_out_len = ((Int32)k1) + 4; - BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK; - s->k0 ^= BZ_RAND_MASK; s->nblock_used++; - } - - } else { - - while (True) { - /* try to finish existing run */ - while (True) { - if (s->strm->avail_out == 0) return False; - if (s->state_out_len == 0) break; - *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; - BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); - s->state_out_len--; - s->strm->next_out++; - s->strm->avail_out--; - s->strm->total_out_lo32++; - if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; - } - - /* can a new run be started? */ - if (s->nblock_used == s->save_nblock+1) return False; - - /* Only caused by corrupt data stream? */ - if (s->nblock_used > s->save_nblock+1) - return True; - - s->state_out_len = 1; - s->state_out_ch = s->k0; - BZ_GET_SMALL(k1); s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 2; - BZ_GET_SMALL(k1); s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 3; - BZ_GET_SMALL(k1); s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - BZ_GET_SMALL(k1); s->nblock_used++; - s->state_out_len = ((Int32)k1) + 4; - BZ_GET_SMALL(s->k0); s->nblock_used++; - } - - } -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzDecompress) ( bz_stream *strm ) -{ - Bool corrupt; - DState* s; - if (strm == NULL) return BZ_PARAM_ERROR; - s = strm->state; - if (s == NULL) return BZ_PARAM_ERROR; - if (s->strm != strm) return BZ_PARAM_ERROR; - - while (True) { - if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR; - if (s->state == BZ_X_OUTPUT) { - if (s->smallDecompress) - corrupt = unRLE_obuf_to_output_SMALL ( s ); else - corrupt = unRLE_obuf_to_output_FAST ( s ); - if (corrupt) return BZ_DATA_ERROR; - if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) { - BZ_FINALISE_CRC ( s->calculatedBlockCRC ); - if (s->verbosity >= 3) - VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC, - s->calculatedBlockCRC ); - if (s->verbosity >= 2) VPrintf0 ( "]" ); - if (s->calculatedBlockCRC != s->storedBlockCRC) - return BZ_DATA_ERROR; - s->calculatedCombinedCRC - = (s->calculatedCombinedCRC << 1) | - (s->calculatedCombinedCRC >> 31); - s->calculatedCombinedCRC ^= s->calculatedBlockCRC; - s->state = BZ_X_BLKHDR_1; - } else { - return BZ_OK; - } - } - if (s->state >= BZ_X_MAGIC_1) { - Int32 r = BZ2_decompress ( s ); - if (r == BZ_STREAM_END) { - if (s->verbosity >= 3) - VPrintf2 ( "\n combined CRCs: stored = 0x%08x, computed = 0x%08x", - s->storedCombinedCRC, s->calculatedCombinedCRC ); - if (s->calculatedCombinedCRC != s->storedCombinedCRC) - return BZ_DATA_ERROR; - return r; - } - if (s->state != BZ_X_OUTPUT) return r; - } - } - - AssertH ( 0, 6001 ); - - return 0; /*NOTREACHED*/ -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzDecompressEnd) ( bz_stream *strm ) -{ - DState* s; - if (strm == NULL) return BZ_PARAM_ERROR; - s = strm->state; - if (s == NULL) return BZ_PARAM_ERROR; - if (s->strm != strm) return BZ_PARAM_ERROR; - - if (s->tt != NULL) BZFREE(s->tt); - if (s->ll16 != NULL) BZFREE(s->ll16); - if (s->ll4 != NULL) BZFREE(s->ll4); - - BZFREE(strm->state); - strm->state = NULL; - - return BZ_OK; -} - - -#ifndef BZ_NO_STDIO -/*---------------------------------------------------*/ -/*--- File I/O stuff ---*/ -/*---------------------------------------------------*/ - -#define BZ_SETERR(eee) \ -{ \ - if (bzerror != NULL) *bzerror = eee; \ - if (bzf != NULL) bzf->lastErr = eee; \ -} - -typedef - struct { - FILE* handle; - Char buf[BZ_MAX_UNUSED]; - Int32 bufN; - Bool writing; - bz_stream strm; - Int32 lastErr; - Bool initialisedOk; - } - bzFile; - - -/*---------------------------------------------*/ -static Bool myfeof ( FILE* f ) -{ - Int32 c = fgetc ( f ); - if (c == EOF) return True; - ungetc ( c, f ); - return False; -} - - -/*---------------------------------------------------*/ -BZFILE* BZ_API(BZ2_bzWriteOpen) - ( int* bzerror, - FILE* f, - int blockSize100k, - int verbosity, - int workFactor ) -{ - Int32 ret; - bzFile* bzf = NULL; - - BZ_SETERR(BZ_OK); - - if (f == NULL || - (blockSize100k < 1 || blockSize100k > 9) || - (workFactor < 0 || workFactor > 250) || - (verbosity < 0 || verbosity > 4)) - { BZ_SETERR(BZ_PARAM_ERROR); return NULL; }; - - if (ferror(f)) - { BZ_SETERR(BZ_IO_ERROR); return NULL; }; - - bzf = malloc ( sizeof(bzFile) ); - if (bzf == NULL) - { BZ_SETERR(BZ_MEM_ERROR); return NULL; }; - - BZ_SETERR(BZ_OK); - bzf->initialisedOk = False; - bzf->bufN = 0; - bzf->handle = f; - bzf->writing = True; - bzf->strm.bzalloc = NULL; - bzf->strm.bzfree = NULL; - bzf->strm.opaque = NULL; - - if (workFactor == 0) workFactor = 30; - ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k, - verbosity, workFactor ); - if (ret != BZ_OK) - { BZ_SETERR(ret); free(bzf); return NULL; }; - - bzf->strm.avail_in = 0; - bzf->initialisedOk = True; - return bzf; -} - - - -/*---------------------------------------------------*/ -void BZ_API(BZ2_bzWrite) - ( int* bzerror, - BZFILE* b, - void* buf, - int len ) -{ - Int32 n, n2, ret; - bzFile* bzf = (bzFile*)b; - - BZ_SETERR(BZ_OK); - if (bzf == NULL || buf == NULL || len < 0) - { BZ_SETERR(BZ_PARAM_ERROR); return; }; - if (!(bzf->writing)) - { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; - if (ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return; }; - - if (len == 0) - { BZ_SETERR(BZ_OK); return; }; - - bzf->strm.avail_in = len; - bzf->strm.next_in = buf; - - while (True) { - bzf->strm.avail_out = BZ_MAX_UNUSED; - bzf->strm.next_out = bzf->buf; - ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN ); - if (ret != BZ_RUN_OK) - { BZ_SETERR(ret); return; }; - - if (bzf->strm.avail_out < BZ_MAX_UNUSED) { - n = BZ_MAX_UNUSED - bzf->strm.avail_out; - n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), - n, bzf->handle ); - if (n != n2 || ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return; }; - } - - if (bzf->strm.avail_in == 0) - { BZ_SETERR(BZ_OK); return; }; - } -} - - -/*---------------------------------------------------*/ -void BZ_API(BZ2_bzWriteClose) - ( int* bzerror, - BZFILE* b, - int abandon, - unsigned int* nbytes_in, - unsigned int* nbytes_out ) -{ - BZ2_bzWriteClose64 ( bzerror, b, abandon, - nbytes_in, NULL, nbytes_out, NULL ); -} - - -void BZ_API(BZ2_bzWriteClose64) - ( int* bzerror, - BZFILE* b, - int abandon, - unsigned int* nbytes_in_lo32, - unsigned int* nbytes_in_hi32, - unsigned int* nbytes_out_lo32, - unsigned int* nbytes_out_hi32 ) -{ - Int32 n, n2, ret; - bzFile* bzf = (bzFile*)b; - - if (bzf == NULL) - { BZ_SETERR(BZ_OK); return; }; - if (!(bzf->writing)) - { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; - if (ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return; }; - - if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0; - if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0; - if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0; - if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0; - - if ((!abandon) && bzf->lastErr == BZ_OK) { - while (True) { - bzf->strm.avail_out = BZ_MAX_UNUSED; - bzf->strm.next_out = bzf->buf; - ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH ); - if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END) - { BZ_SETERR(ret); return; }; - - if (bzf->strm.avail_out < BZ_MAX_UNUSED) { - n = BZ_MAX_UNUSED - bzf->strm.avail_out; - n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), - n, bzf->handle ); - if (n != n2 || ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return; }; - } - - if (ret == BZ_STREAM_END) break; - } - } - - if ( !abandon && !ferror ( bzf->handle ) ) { - fflush ( bzf->handle ); - if (ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return; }; - } - - if (nbytes_in_lo32 != NULL) - *nbytes_in_lo32 = bzf->strm.total_in_lo32; - if (nbytes_in_hi32 != NULL) - *nbytes_in_hi32 = bzf->strm.total_in_hi32; - if (nbytes_out_lo32 != NULL) - *nbytes_out_lo32 = bzf->strm.total_out_lo32; - if (nbytes_out_hi32 != NULL) - *nbytes_out_hi32 = bzf->strm.total_out_hi32; - - BZ_SETERR(BZ_OK); - BZ2_bzCompressEnd ( &(bzf->strm) ); - free ( bzf ); -} - - -/*---------------------------------------------------*/ -BZFILE* BZ_API(BZ2_bzReadOpen) - ( int* bzerror, - FILE* f, - int verbosity, - int small, - void* unused, - int nUnused ) -{ - bzFile* bzf = NULL; - int ret; - - BZ_SETERR(BZ_OK); - - if (f == NULL || - (small != 0 && small != 1) || - (verbosity < 0 || verbosity > 4) || - (unused == NULL && nUnused != 0) || - (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED))) - { BZ_SETERR(BZ_PARAM_ERROR); return NULL; }; - - if (ferror(f)) - { BZ_SETERR(BZ_IO_ERROR); return NULL; }; - - bzf = malloc ( sizeof(bzFile) ); - if (bzf == NULL) - { BZ_SETERR(BZ_MEM_ERROR); return NULL; }; - - BZ_SETERR(BZ_OK); - - bzf->initialisedOk = False; - bzf->handle = f; - bzf->bufN = 0; - bzf->writing = False; - bzf->strm.bzalloc = NULL; - bzf->strm.bzfree = NULL; - bzf->strm.opaque = NULL; - - while (nUnused > 0) { - bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++; - unused = ((void*)( 1 + ((UChar*)(unused)) )); - nUnused--; - } - - ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small ); - if (ret != BZ_OK) - { BZ_SETERR(ret); free(bzf); return NULL; }; - - bzf->strm.avail_in = bzf->bufN; - bzf->strm.next_in = bzf->buf; - - bzf->initialisedOk = True; - return bzf; -} - - -/*---------------------------------------------------*/ -void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b ) -{ - bzFile* bzf = (bzFile*)b; - - BZ_SETERR(BZ_OK); - if (bzf == NULL) - { BZ_SETERR(BZ_OK); return; }; - - if (bzf->writing) - { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; - - if (bzf->initialisedOk) - (void)BZ2_bzDecompressEnd ( &(bzf->strm) ); - free ( bzf ); -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzRead) - ( int* bzerror, - BZFILE* b, - void* buf, - int len ) -{ - Int32 n, ret; - bzFile* bzf = (bzFile*)b; - - BZ_SETERR(BZ_OK); - - if (bzf == NULL || buf == NULL || len < 0) - { BZ_SETERR(BZ_PARAM_ERROR); return 0; }; - - if (bzf->writing) - { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; }; - - if (len == 0) - { BZ_SETERR(BZ_OK); return 0; }; - - bzf->strm.avail_out = len; - bzf->strm.next_out = buf; - - while (True) { - - if (ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return 0; }; - - if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) { - n = fread ( bzf->buf, sizeof(UChar), - BZ_MAX_UNUSED, bzf->handle ); - if (ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return 0; }; - bzf->bufN = n; - bzf->strm.avail_in = bzf->bufN; - bzf->strm.next_in = bzf->buf; - } - - ret = BZ2_bzDecompress ( &(bzf->strm) ); - - if (ret != BZ_OK && ret != BZ_STREAM_END) - { BZ_SETERR(ret); return 0; }; - - if (ret == BZ_OK && myfeof(bzf->handle) && - bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0) - { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; }; - - if (ret == BZ_STREAM_END) - { BZ_SETERR(BZ_STREAM_END); - return len - bzf->strm.avail_out; }; - if (bzf->strm.avail_out == 0) - { BZ_SETERR(BZ_OK); return len; }; - - } - - return 0; /*not reached*/ -} - - -/*---------------------------------------------------*/ -void BZ_API(BZ2_bzReadGetUnused) - ( int* bzerror, - BZFILE* b, - void** unused, - int* nUnused ) -{ - bzFile* bzf = (bzFile*)b; - if (bzf == NULL) - { BZ_SETERR(BZ_PARAM_ERROR); return; }; - if (bzf->lastErr != BZ_STREAM_END) - { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; - if (unused == NULL || nUnused == NULL) - { BZ_SETERR(BZ_PARAM_ERROR); return; }; - - BZ_SETERR(BZ_OK); - *nUnused = bzf->strm.avail_in; - *unused = bzf->strm.next_in; -} -#endif - - -/*---------------------------------------------------*/ -/*--- Misc convenience stuff ---*/ -/*---------------------------------------------------*/ - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzBuffToBuffCompress) - ( char* dest, - unsigned int* destLen, - char* source, - unsigned int sourceLen, - int blockSize100k, - int verbosity, - int workFactor ) -{ - bz_stream strm; - int ret; - - if (dest == NULL || destLen == NULL || - source == NULL || - blockSize100k < 1 || blockSize100k > 9 || - verbosity < 0 || verbosity > 4 || - workFactor < 0 || workFactor > 250) - return BZ_PARAM_ERROR; - - if (workFactor == 0) workFactor = 30; - strm.bzalloc = NULL; - strm.bzfree = NULL; - strm.opaque = NULL; - ret = BZ2_bzCompressInit ( &strm, blockSize100k, - verbosity, workFactor ); - if (ret != BZ_OK) return ret; - - strm.next_in = source; - strm.next_out = dest; - strm.avail_in = sourceLen; - strm.avail_out = *destLen; - - ret = BZ2_bzCompress ( &strm, BZ_FINISH ); - if (ret == BZ_FINISH_OK) goto output_overflow; - if (ret != BZ_STREAM_END) goto errhandler; - - /* normal termination */ - *destLen -= strm.avail_out; - BZ2_bzCompressEnd ( &strm ); - return BZ_OK; - - output_overflow: - BZ2_bzCompressEnd ( &strm ); - return BZ_OUTBUFF_FULL; - - errhandler: - BZ2_bzCompressEnd ( &strm ); - return ret; -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzBuffToBuffDecompress) - ( char* dest, - unsigned int* destLen, - char* source, - unsigned int sourceLen, - int small, - int verbosity ) -{ - bz_stream strm; - int ret; - - if (dest == NULL || destLen == NULL || - source == NULL || - (small != 0 && small != 1) || - verbosity < 0 || verbosity > 4) - return BZ_PARAM_ERROR; - - strm.bzalloc = NULL; - strm.bzfree = NULL; - strm.opaque = NULL; - ret = BZ2_bzDecompressInit ( &strm, verbosity, small ); - if (ret != BZ_OK) return ret; - - strm.next_in = source; - strm.next_out = dest; - strm.avail_in = sourceLen; - strm.avail_out = *destLen; - - ret = BZ2_bzDecompress ( &strm ); - if (ret == BZ_OK) goto output_overflow_or_eof; - if (ret != BZ_STREAM_END) goto errhandler; - - /* normal termination */ - *destLen -= strm.avail_out; - BZ2_bzDecompressEnd ( &strm ); - return BZ_OK; - - output_overflow_or_eof: - if (strm.avail_out > 0) { - BZ2_bzDecompressEnd ( &strm ); - return BZ_UNEXPECTED_EOF; - } else { - BZ2_bzDecompressEnd ( &strm ); - return BZ_OUTBUFF_FULL; - }; - - errhandler: - BZ2_bzDecompressEnd ( &strm ); - return ret; -} - - -/*---------------------------------------------------*/ -/*-- - Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp) - to support better zlib compatibility. - This code is not _officially_ part of libbzip2 (yet); - I haven't tested it, documented it, or considered the - threading-safeness of it. - If this code breaks, please contact both Yoshioka and me. ---*/ -/*---------------------------------------------------*/ - -/*---------------------------------------------------*/ -/*-- - return version like "0.9.5d, 4-Sept-1999". ---*/ -const char * BZ_API(BZ2_bzlibVersion)(void) -{ - return BZ_VERSION; -} - - -#ifndef BZ_NO_STDIO -/*---------------------------------------------------*/ - -#if defined(_WIN32) || defined(OS2) || defined(MSDOS) -# include <fcntl.h> -# include <io.h> -# define SET_BINARY_MODE(file) _setmode(_fileno(file),O_BINARY) -#else -# define SET_BINARY_MODE(file) -#endif -static -BZFILE * bzopen_or_bzdopen - ( const char *path, /* no use when bzdopen */ - int fd, /* no use when bzdopen */ - const char *mode, - int open_mode) /* bzopen: 0, bzdopen:1 */ -{ - int bzerr; - char unused[BZ_MAX_UNUSED]; - int blockSize100k = 9; - int writing = 0; - char mode2[10] = ""; - FILE *fp = NULL; - BZFILE *bzfp = NULL; - int verbosity = 0; - int workFactor = 30; - int smallMode = 0; - int nUnused = 0; - - if (mode == NULL) return NULL; - while (*mode) { - switch (*mode) { - case 'r': - writing = 0; break; - case 'w': - writing = 1; break; - case 's': - smallMode = 1; break; - default: - if (isdigit((int)(*mode))) { - blockSize100k = *mode-BZ_HDR_0; - } - } - mode++; - } - strcat(mode2, writing ? "w" : "r" ); - strcat(mode2,"b"); /* binary mode */ - - if (open_mode==0) { - if (path==NULL || strcmp(path,"")==0) { - fp = (writing ? stdout : stdin); - SET_BINARY_MODE(fp); - } else { - fp = fopen(path,mode2); - } - } else { -#ifdef BZ_STRICT_ANSI - fp = NULL; -#else - fp = _fdopen(fd,mode2); -#endif - } - if (fp == NULL) return NULL; - - if (writing) { - /* Guard against total chaos and anarchy -- JRS */ - if (blockSize100k < 1) blockSize100k = 1; - if (blockSize100k > 9) blockSize100k = 9; - bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k, - verbosity,workFactor); - } else { - bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode, - unused,nUnused); - } - if (bzfp == NULL) { - if (fp != stdin && fp != stdout) fclose(fp); - return NULL; - } - return bzfp; -} - - -/*---------------------------------------------------*/ -/*-- - open file for read or write. - ex) bzopen("file","w9") - case path="" or NULL => use stdin or stdout. ---*/ -BZFILE * BZ_API(BZ2_bzopen) - ( const char *path, - const char *mode ) -{ - return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0); -} - - -/*---------------------------------------------------*/ -BZFILE * BZ_API(BZ2_bzdopen) - ( int fd, - const char *mode ) -{ - return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1); -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len ) -{ - int bzerr, nread; - if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0; - nread = BZ2_bzRead(&bzerr,b,buf,len); - if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) { - return nread; - } else { - return -1; - } -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len ) -{ - int bzerr; - - BZ2_bzWrite(&bzerr,b,buf,len); - if(bzerr == BZ_OK){ - return len; - }else{ - return -1; - } -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzflush) (BZFILE *b) -{ - /* do nothing now... */ - return 0; -} - - -/*---------------------------------------------------*/ -void BZ_API(BZ2_bzclose) (BZFILE* b) -{ - int bzerr; - FILE *fp; - - if (b==NULL) {return;} - fp = ((bzFile *)b)->handle; - if(((bzFile*)b)->writing){ - BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL); - if(bzerr != BZ_OK){ - BZ2_bzWriteClose(NULL,b,1,NULL,NULL); - } - }else{ - BZ2_bzReadClose(&bzerr,b); - } - if(fp!=stdin && fp!=stdout){ - fclose(fp); - } -} - - -/*---------------------------------------------------*/ -/*-- - return last error code ---*/ -static const char *bzerrorstrings[] = { - "OK" - ,"SEQUENCE_ERROR" - ,"PARAM_ERROR" - ,"MEM_ERROR" - ,"DATA_ERROR" - ,"DATA_ERROR_MAGIC" - ,"IO_ERROR" - ,"UNEXPECTED_EOF" - ,"OUTBUFF_FULL" - ,"CONFIG_ERROR" - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ -}; - - -const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum) -{ - int err = ((bzFile *)b)->lastErr; - - if(err>0) err = 0; - *errnum = err; - return bzerrorstrings[err*-1]; -} -#endif - - -/*-------------------------------------------------------------*/ -/*--- end bzlib.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/rbutil/bzip2/bzlib.h b/rbutil/bzip2/bzlib.h deleted file mode 100644 index 8277123da8..0000000000 --- a/rbutil/bzip2/bzlib.h +++ /dev/null @@ -1,282 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Public header file for the library. ---*/ -/*--- bzlib.h ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org> - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#ifndef _BZLIB_H -#define _BZLIB_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define BZ_RUN 0 -#define BZ_FLUSH 1 -#define BZ_FINISH 2 - -#define BZ_OK 0 -#define BZ_RUN_OK 1 -#define BZ_FLUSH_OK 2 -#define BZ_FINISH_OK 3 -#define BZ_STREAM_END 4 -#define BZ_SEQUENCE_ERROR (-1) -#define BZ_PARAM_ERROR (-2) -#define BZ_MEM_ERROR (-3) -#define BZ_DATA_ERROR (-4) -#define BZ_DATA_ERROR_MAGIC (-5) -#define BZ_IO_ERROR (-6) -#define BZ_UNEXPECTED_EOF (-7) -#define BZ_OUTBUFF_FULL (-8) -#define BZ_CONFIG_ERROR (-9) - -typedef - struct { - char *next_in; - unsigned int avail_in; - unsigned int total_in_lo32; - unsigned int total_in_hi32; - - char *next_out; - unsigned int avail_out; - unsigned int total_out_lo32; - unsigned int total_out_hi32; - - void *state; - - void *(*bzalloc)(void *,int,int); - void (*bzfree)(void *,void *); - void *opaque; - } - bz_stream; - - -#ifndef BZ_IMPORT -#define BZ_EXPORT -#endif - -#ifndef BZ_NO_STDIO -/* Need a definitition for FILE */ -#include <stdio.h> -#endif - -#ifdef _WIN32 -# include <windows.h> -# ifdef small - /* windows.h define small to char */ -# undef small -# endif -# ifdef BZ_EXPORT -# define BZ_API(func) WINAPI func -# define BZ_EXTERN extern -# else - /* import windows dll dynamically */ -# define BZ_API(func) (WINAPI * func) -# define BZ_EXTERN -# endif -#else -# define BZ_API(func) func -# define BZ_EXTERN extern -#endif - - -/*-- Core (low-level) library functions --*/ - -BZ_EXTERN int BZ_API(BZ2_bzCompressInit) ( - bz_stream* strm, - int blockSize100k, - int verbosity, - int workFactor - ); - -BZ_EXTERN int BZ_API(BZ2_bzCompress) ( - bz_stream* strm, - int action - ); - -BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) ( - bz_stream* strm - ); - -BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) ( - bz_stream *strm, - int verbosity, - int small - ); - -BZ_EXTERN int BZ_API(BZ2_bzDecompress) ( - bz_stream* strm - ); - -BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) ( - bz_stream *strm - ); - - - -/*-- High(er) level library functions --*/ - -#ifndef BZ_NO_STDIO -#define BZ_MAX_UNUSED 5000 - -typedef void BZFILE; - -BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) ( - int* bzerror, - FILE* f, - int verbosity, - int small, - void* unused, - int nUnused - ); - -BZ_EXTERN void BZ_API(BZ2_bzReadClose) ( - int* bzerror, - BZFILE* b - ); - -BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) ( - int* bzerror, - BZFILE* b, - void** unused, - int* nUnused - ); - -BZ_EXTERN int BZ_API(BZ2_bzRead) ( - int* bzerror, - BZFILE* b, - void* buf, - int len - ); - -BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) ( - int* bzerror, - FILE* f, - int blockSize100k, - int verbosity, - int workFactor - ); - -BZ_EXTERN void BZ_API(BZ2_bzWrite) ( - int* bzerror, - BZFILE* b, - void* buf, - int len - ); - -BZ_EXTERN void BZ_API(BZ2_bzWriteClose) ( - int* bzerror, - BZFILE* b, - int abandon, - unsigned int* nbytes_in, - unsigned int* nbytes_out - ); - -BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) ( - int* bzerror, - BZFILE* b, - int abandon, - unsigned int* nbytes_in_lo32, - unsigned int* nbytes_in_hi32, - unsigned int* nbytes_out_lo32, - unsigned int* nbytes_out_hi32 - ); -#endif - - -/*-- Utility functions --*/ - -BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) ( - char* dest, - unsigned int* destLen, - char* source, - unsigned int sourceLen, - int blockSize100k, - int verbosity, - int workFactor - ); - -BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) ( - char* dest, - unsigned int* destLen, - char* source, - unsigned int sourceLen, - int small, - int verbosity - ); - - -/*-- - Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp) - to support better zlib compatibility. - This code is not _officially_ part of libbzip2 (yet); - I haven't tested it, documented it, or considered the - threading-safeness of it. - If this code breaks, please contact both Yoshioka and me. ---*/ - -BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) ( - void - ); - -#ifndef BZ_NO_STDIO -BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) ( - const char *path, - const char *mode - ); - -BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) ( - int fd, - const char *mode - ); - -BZ_EXTERN int BZ_API(BZ2_bzread) ( - BZFILE* b, - void* buf, - int len - ); - -BZ_EXTERN int BZ_API(BZ2_bzwrite) ( - BZFILE* b, - void* buf, - int len - ); - -BZ_EXTERN int BZ_API(BZ2_bzflush) ( - BZFILE* b - ); - -BZ_EXTERN void BZ_API(BZ2_bzclose) ( - BZFILE* b - ); - -BZ_EXTERN const char * BZ_API(BZ2_bzerror) ( - BZFILE *b, - int *errnum - ); -#endif - -#ifdef __cplusplus -} -#endif - -#endif - -/*-------------------------------------------------------------*/ -/*--- end bzlib.h ---*/ -/*-------------------------------------------------------------*/ diff --git a/rbutil/bzip2/bzlib_private.h b/rbutil/bzip2/bzlib_private.h deleted file mode 100644 index d2b1a97ccb..0000000000 --- a/rbutil/bzip2/bzlib_private.h +++ /dev/null @@ -1,512 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Private header file for the library. ---*/ -/*--- bzlib_private.h ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org> - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#ifndef _BZLIB_PRIVATE_H -#define _BZLIB_PRIVATE_H - -#include <stdlib.h> - -#ifndef BZ_NO_STDIO -#include <stdio.h> -#include <ctype.h> -#include <string.h> -#endif - -#include "bzlib.h" - - - -/*-- General stuff. --*/ - -#define BZ_VERSION "1.0.6, 6-Sept-2010" - -typedef char Char; -typedef unsigned char Bool; -typedef unsigned char UChar; -typedef int Int32; -typedef unsigned int UInt32; -typedef short Int16; -typedef unsigned short UInt16; - -#define True ((Bool)1) -#define False ((Bool)0) - -#ifndef __GNUC__ -#define __inline__ /* */ -#endif - -#ifndef BZ_NO_STDIO - -extern void BZ2_bz__AssertH__fail ( int errcode ); -#define AssertH(cond,errcode) \ - { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); } - -#if BZ_DEBUG -#define AssertD(cond,msg) \ - { if (!(cond)) { \ - fprintf ( stderr, \ - "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\ - exit(1); \ - }} -#else -#define AssertD(cond,msg) /* */ -#endif - -#define VPrintf0(zf) \ - fprintf(stderr,zf) -#define VPrintf1(zf,za1) \ - fprintf(stderr,zf,za1) -#define VPrintf2(zf,za1,za2) \ - fprintf(stderr,zf,za1,za2) -#define VPrintf3(zf,za1,za2,za3) \ - fprintf(stderr,zf,za1,za2,za3) -#define VPrintf4(zf,za1,za2,za3,za4) \ - fprintf(stderr,zf,za1,za2,za3,za4) -#define VPrintf5(zf,za1,za2,za3,za4,za5) \ - fprintf(stderr,zf,za1,za2,za3,za4,za5) - -#else - -extern void bz_internal_error ( int errcode ); -#define AssertH(cond,errcode) \ - { if (!(cond)) bz_internal_error ( errcode ); } -#define AssertD(cond,msg) do { } while (0) -#define VPrintf0(zf) do { } while (0) -#define VPrintf1(zf,za1) do { } while (0) -#define VPrintf2(zf,za1,za2) do { } while (0) -#define VPrintf3(zf,za1,za2,za3) do { } while (0) -#define VPrintf4(zf,za1,za2,za3,za4) do { } while (0) -#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0) - -#endif - - -#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1) -#define BZFREE(ppp) (strm->bzfree)(strm->opaque,(ppp)) - - -/*-- Header bytes. --*/ - -#define BZ_HDR_B 0x42 /* 'B' */ -#define BZ_HDR_Z 0x5a /* 'Z' */ -#define BZ_HDR_h 0x68 /* 'h' */ -#define BZ_HDR_0 0x30 /* '0' */ - -/*-- Constants for the back end. --*/ - -#define BZ_MAX_ALPHA_SIZE 258 -#define BZ_MAX_CODE_LEN 23 - -#define BZ_RUNA 0 -#define BZ_RUNB 1 - -#define BZ_N_GROUPS 6 -#define BZ_G_SIZE 50 -#define BZ_N_ITERS 4 - -#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE)) - - - -/*-- Stuff for randomising repetitive blocks. --*/ - -extern Int32 BZ2_rNums[512]; - -#define BZ_RAND_DECLS \ - Int32 rNToGo; \ - Int32 rTPos \ - -#define BZ_RAND_INIT_MASK \ - s->rNToGo = 0; \ - s->rTPos = 0 \ - -#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0) - -#define BZ_RAND_UPD_MASK \ - if (s->rNToGo == 0) { \ - s->rNToGo = BZ2_rNums[s->rTPos]; \ - s->rTPos++; \ - if (s->rTPos == 512) s->rTPos = 0; \ - } \ - s->rNToGo--; - - - -/*-- Stuff for doing CRCs. --*/ - -extern UInt32 BZ2_crc32Table[256]; - -#define BZ_INITIALISE_CRC(crcVar) \ -{ \ - crcVar = 0xffffffffL; \ -} - -#define BZ_FINALISE_CRC(crcVar) \ -{ \ - crcVar = ~(crcVar); \ -} - -#define BZ_UPDATE_CRC(crcVar,cha) \ -{ \ - crcVar = (crcVar << 8) ^ \ - BZ2_crc32Table[(crcVar >> 24) ^ \ - ((UChar)cha)]; \ -} - - - -/*-- States and modes for compression. --*/ - -#define BZ_M_IDLE 1 -#define BZ_M_RUNNING 2 -#define BZ_M_FLUSHING 3 -#define BZ_M_FINISHING 4 - -#define BZ_S_OUTPUT 1 -#define BZ_S_INPUT 2 - -#define BZ_N_RADIX 2 -#define BZ_N_QSORT 12 -#define BZ_N_SHELL 18 -#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2) - - - - -/*-- Structure holding all the compression-side stuff. --*/ - -typedef - struct { - /* pointer back to the struct bz_stream */ - bz_stream* strm; - - /* mode this stream is in, and whether inputting */ - /* or outputting data */ - Int32 mode; - Int32 state; - - /* remembers avail_in when flush/finish requested */ - UInt32 avail_in_expect; - - /* for doing the block sorting */ - UInt32* arr1; - UInt32* arr2; - UInt32* ftab; - Int32 origPtr; - - /* aliases for arr1 and arr2 */ - UInt32* ptr; - UChar* block; - UInt16* mtfv; - UChar* zbits; - - /* for deciding when to use the fallback sorting algorithm */ - Int32 workFactor; - - /* run-length-encoding of the input */ - UInt32 state_in_ch; - Int32 state_in_len; - BZ_RAND_DECLS; - - /* input and output limits and current posns */ - Int32 nblock; - Int32 nblockMAX; - Int32 numZ; - Int32 state_out_pos; - - /* map of bytes used in block */ - Int32 nInUse; - Bool inUse[256]; - UChar unseqToSeq[256]; - - /* the buffer for bit stream creation */ - UInt32 bsBuff; - Int32 bsLive; - - /* block and combined CRCs */ - UInt32 blockCRC; - UInt32 combinedCRC; - - /* misc administratium */ - Int32 verbosity; - Int32 blockNo; - Int32 blockSize100k; - - /* stuff for coding the MTF values */ - Int32 nMTF; - Int32 mtfFreq [BZ_MAX_ALPHA_SIZE]; - UChar selector [BZ_MAX_SELECTORS]; - UChar selectorMtf[BZ_MAX_SELECTORS]; - - UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - /* second dimension: only 3 needed; 4 makes index calculations faster */ - UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4]; - - } - EState; - - - -/*-- externs for compression. --*/ - -extern void -BZ2_blockSort ( EState* ); - -extern void -BZ2_compressBlock ( EState*, Bool ); - -extern void -BZ2_bsInitWrite ( EState* ); - -extern void -BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 ); - -extern void -BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 ); - - - -/*-- states for decompression. --*/ - -#define BZ_X_IDLE 1 -#define BZ_X_OUTPUT 2 - -#define BZ_X_MAGIC_1 10 -#define BZ_X_MAGIC_2 11 -#define BZ_X_MAGIC_3 12 -#define BZ_X_MAGIC_4 13 -#define BZ_X_BLKHDR_1 14 -#define BZ_X_BLKHDR_2 15 -#define BZ_X_BLKHDR_3 16 -#define BZ_X_BLKHDR_4 17 -#define BZ_X_BLKHDR_5 18 -#define BZ_X_BLKHDR_6 19 -#define BZ_X_BCRC_1 20 -#define BZ_X_BCRC_2 21 -#define BZ_X_BCRC_3 22 -#define BZ_X_BCRC_4 23 -#define BZ_X_RANDBIT 24 -#define BZ_X_ORIGPTR_1 25 -#define BZ_X_ORIGPTR_2 26 -#define BZ_X_ORIGPTR_3 27 -#define BZ_X_MAPPING_1 28 -#define BZ_X_MAPPING_2 29 -#define BZ_X_SELECTOR_1 30 -#define BZ_X_SELECTOR_2 31 -#define BZ_X_SELECTOR_3 32 -#define BZ_X_CODING_1 33 -#define BZ_X_CODING_2 34 -#define BZ_X_CODING_3 35 -#define BZ_X_MTF_1 36 -#define BZ_X_MTF_2 37 -#define BZ_X_MTF_3 38 -#define BZ_X_MTF_4 39 -#define BZ_X_MTF_5 40 -#define BZ_X_MTF_6 41 -#define BZ_X_ENDHDR_2 42 -#define BZ_X_ENDHDR_3 43 -#define BZ_X_ENDHDR_4 44 -#define BZ_X_ENDHDR_5 45 -#define BZ_X_ENDHDR_6 46 -#define BZ_X_CCRC_1 47 -#define BZ_X_CCRC_2 48 -#define BZ_X_CCRC_3 49 -#define BZ_X_CCRC_4 50 - - - -/*-- Constants for the fast MTF decoder. --*/ - -#define MTFA_SIZE 4096 -#define MTFL_SIZE 16 - - - -/*-- Structure holding all the decompression-side stuff. --*/ - -typedef - struct { - /* pointer back to the struct bz_stream */ - bz_stream* strm; - - /* state indicator for this stream */ - Int32 state; - - /* for doing the final run-length decoding */ - UChar state_out_ch; - Int32 state_out_len; - Bool blockRandomised; - BZ_RAND_DECLS; - - /* the buffer for bit stream reading */ - UInt32 bsBuff; - Int32 bsLive; - - /* misc administratium */ - Int32 blockSize100k; - Bool smallDecompress; - Int32 currBlockNo; - Int32 verbosity; - - /* for undoing the Burrows-Wheeler transform */ - Int32 origPtr; - UInt32 tPos; - Int32 k0; - Int32 unzftab[256]; - Int32 nblock_used; - Int32 cftab[257]; - Int32 cftabCopy[257]; - - /* for undoing the Burrows-Wheeler transform (FAST) */ - UInt32 *tt; - - /* for undoing the Burrows-Wheeler transform (SMALL) */ - UInt16 *ll16; - UChar *ll4; - - /* stored and calculated CRCs */ - UInt32 storedBlockCRC; - UInt32 storedCombinedCRC; - UInt32 calculatedBlockCRC; - UInt32 calculatedCombinedCRC; - - /* map of bytes used in block */ - Int32 nInUse; - Bool inUse[256]; - Bool inUse16[16]; - UChar seqToUnseq[256]; - - /* for decoding the MTF values */ - UChar mtfa [MTFA_SIZE]; - Int32 mtfbase[256 / MTFL_SIZE]; - UChar selector [BZ_MAX_SELECTORS]; - UChar selectorMtf[BZ_MAX_SELECTORS]; - UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - - Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 minLens[BZ_N_GROUPS]; - - /* save area for scalars in the main decompress code */ - Int32 save_i; - Int32 save_j; - Int32 save_t; - Int32 save_alphaSize; - Int32 save_nGroups; - Int32 save_nSelectors; - Int32 save_EOB; - Int32 save_groupNo; - Int32 save_groupPos; - Int32 save_nextSym; - Int32 save_nblockMAX; - Int32 save_nblock; - Int32 save_es; - Int32 save_N; - Int32 save_curr; - Int32 save_zt; - Int32 save_zn; - Int32 save_zvec; - Int32 save_zj; - Int32 save_gSel; - Int32 save_gMinlen; - Int32* save_gLimit; - Int32* save_gBase; - Int32* save_gPerm; - - } - DState; - - - -/*-- Macros for decompression. --*/ - -#define BZ_GET_FAST(cccc) \ - /* c_tPos is unsigned, hence test < 0 is pointless. */ \ - if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \ - s->tPos = s->tt[s->tPos]; \ - cccc = (UChar)(s->tPos & 0xff); \ - s->tPos >>= 8; - -#define BZ_GET_FAST_C(cccc) \ - /* c_tPos is unsigned, hence test < 0 is pointless. */ \ - if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \ - c_tPos = c_tt[c_tPos]; \ - cccc = (UChar)(c_tPos & 0xff); \ - c_tPos >>= 8; - -#define SET_LL4(i,n) \ - { if (((i) & 0x1) == 0) \ - s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \ - s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \ - } - -#define GET_LL4(i) \ - ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF) - -#define SET_LL(i,n) \ - { s->ll16[i] = (UInt16)(n & 0x0000ffff); \ - SET_LL4(i, n >> 16); \ - } - -#define GET_LL(i) \ - (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16)) - -#define BZ_GET_SMALL(cccc) \ - /* c_tPos is unsigned, hence test < 0 is pointless. */ \ - if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \ - cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \ - s->tPos = GET_LL(s->tPos); - - -/*-- externs for decompression. --*/ - -extern Int32 -BZ2_indexIntoF ( Int32, Int32* ); - -extern Int32 -BZ2_decompress ( DState* ); - -extern void -BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*, - Int32, Int32, Int32 ); - - -#endif - - -/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/ - -#ifdef BZ_NO_STDIO -#ifndef NULL -#define NULL 0 -#endif -#endif - -#ifndef WIN32 -#define _fdopen fdopen -#endif - -/*-------------------------------------------------------------*/ -/*--- end bzlib_private.h ---*/ -/*-------------------------------------------------------------*/ diff --git a/rbutil/bzip2/compress.c b/rbutil/bzip2/compress.c deleted file mode 100644 index caf7696011..0000000000 --- a/rbutil/bzip2/compress.c +++ /dev/null @@ -1,672 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Compression machinery (not incl block sorting) ---*/ -/*--- compress.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org> - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -/* CHANGES - 0.9.0 -- original version. - 0.9.0a/b -- no changes in this file. - 0.9.0c -- changed setting of nGroups in sendMTFValues() - so as to do a bit better on small files -*/ - -#include "bzlib_private.h" - - -/*---------------------------------------------------*/ -/*--- Bit stream I/O ---*/ -/*---------------------------------------------------*/ - -/*---------------------------------------------------*/ -void BZ2_bsInitWrite ( EState* s ) -{ - s->bsLive = 0; - s->bsBuff = 0; -} - - -/*---------------------------------------------------*/ -static -void bsFinishWrite ( EState* s ) -{ - while (s->bsLive > 0) { - s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24); - s->numZ++; - s->bsBuff <<= 8; - s->bsLive -= 8; - } -} - - -/*---------------------------------------------------*/ -#define bsNEEDW(nz) \ -{ \ - while (s->bsLive >= 8) { \ - s->zbits[s->numZ] \ - = (UChar)(s->bsBuff >> 24); \ - s->numZ++; \ - s->bsBuff <<= 8; \ - s->bsLive -= 8; \ - } \ -} - - -/*---------------------------------------------------*/ -static -__inline__ -void bsW ( EState* s, Int32 n, UInt32 v ) -{ - bsNEEDW ( n ); - s->bsBuff |= (v << (32 - s->bsLive - n)); - s->bsLive += n; -} - - -/*---------------------------------------------------*/ -static -void bsPutUInt32 ( EState* s, UInt32 u ) -{ - bsW ( s, 8, (u >> 24) & 0xffL ); - bsW ( s, 8, (u >> 16) & 0xffL ); - bsW ( s, 8, (u >> 8) & 0xffL ); - bsW ( s, 8, u & 0xffL ); -} - - -/*---------------------------------------------------*/ -static -void bsPutUChar ( EState* s, UChar c ) -{ - bsW( s, 8, (UInt32)c ); -} - - -/*---------------------------------------------------*/ -/*--- The back end proper ---*/ -/*---------------------------------------------------*/ - -/*---------------------------------------------------*/ -static -void makeMaps_e ( EState* s ) -{ - Int32 i; - s->nInUse = 0; - for (i = 0; i < 256; i++) - if (s->inUse[i]) { - s->unseqToSeq[i] = s->nInUse; - s->nInUse++; - } -} - - -/*---------------------------------------------------*/ -static -void generateMTFValues ( EState* s ) -{ - UChar yy[256]; - Int32 i, j; - Int32 zPend; - Int32 wr; - Int32 EOB; - - /* - After sorting (eg, here), - s->arr1 [ 0 .. s->nblock-1 ] holds sorted order, - and - ((UChar*)s->arr2) [ 0 .. s->nblock-1 ] - holds the original block data. - - The first thing to do is generate the MTF values, - and put them in - ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ]. - Because there are strictly fewer or equal MTF values - than block values, ptr values in this area are overwritten - with MTF values only when they are no longer needed. - - The final compressed bitstream is generated into the - area starting at - (UChar*) (&((UChar*)s->arr2)[s->nblock]) - - These storage aliases are set up in bzCompressInit(), - except for the last one, which is arranged in - compressBlock(). - */ - UInt32* ptr = s->ptr; - UChar* block = s->block; - UInt16* mtfv = s->mtfv; - - makeMaps_e ( s ); - EOB = s->nInUse+1; - - for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0; - - wr = 0; - zPend = 0; - for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i; - - for (i = 0; i < s->nblock; i++) { - UChar ll_i; - AssertD ( wr <= i, "generateMTFValues(1)" ); - j = ptr[i]-1; if (j < 0) j += s->nblock; - ll_i = s->unseqToSeq[block[j]]; - AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" ); - - if (yy[0] == ll_i) { - zPend++; - } else { - - if (zPend > 0) { - zPend--; - while (True) { - if (zPend & 1) { - mtfv[wr] = BZ_RUNB; wr++; - s->mtfFreq[BZ_RUNB]++; - } else { - mtfv[wr] = BZ_RUNA; wr++; - s->mtfFreq[BZ_RUNA]++; - } - if (zPend < 2) break; - zPend = (zPend - 2) / 2; - }; - zPend = 0; - } - { - register UChar rtmp; - register UChar* ryy_j; - register UChar rll_i; - rtmp = yy[1]; - yy[1] = yy[0]; - ryy_j = &(yy[1]); - rll_i = ll_i; - while ( rll_i != rtmp ) { - register UChar rtmp2; - ryy_j++; - rtmp2 = rtmp; - rtmp = *ryy_j; - *ryy_j = rtmp2; - }; - yy[0] = rtmp; - j = ryy_j - &(yy[0]); - mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++; - } - - } - } - - if (zPend > 0) { - zPend--; - while (True) { - if (zPend & 1) { - mtfv[wr] = BZ_RUNB; wr++; - s->mtfFreq[BZ_RUNB]++; - } else { - mtfv[wr] = BZ_RUNA; wr++; - s->mtfFreq[BZ_RUNA]++; - } - if (zPend < 2) break; - zPend = (zPend - 2) / 2; - }; - zPend = 0; - } - - mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++; - - s->nMTF = wr; -} - - -/*---------------------------------------------------*/ -#define BZ_LESSER_ICOST 0 -#define BZ_GREATER_ICOST 15 - -static -void sendMTFValues ( EState* s ) -{ - Int32 v, t, i, j, gs, ge, totc, bt, bc, iter; - Int32 nSelectors, alphaSize, minLen, maxLen, selCtr; - Int32 nGroups, nBytes; - - /*-- - UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - is a global since the decoder also needs it. - - Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - are also globals only used in this proc. - Made global to keep stack frame size small. - --*/ - - - UInt16 cost[BZ_N_GROUPS]; - Int32 fave[BZ_N_GROUPS]; - - UInt16* mtfv = s->mtfv; - - if (s->verbosity >= 3) - VPrintf3( " %d in block, %d after MTF & 1-2 coding, " - "%d+2 syms in use\n", - s->nblock, s->nMTF, s->nInUse ); - - alphaSize = s->nInUse+2; - for (t = 0; t < BZ_N_GROUPS; t++) - for (v = 0; v < alphaSize; v++) - s->len[t][v] = BZ_GREATER_ICOST; - - /*--- Decide how many coding tables to use ---*/ - AssertH ( s->nMTF > 0, 3001 ); - if (s->nMTF < 200) nGroups = 2; else - if (s->nMTF < 600) nGroups = 3; else - if (s->nMTF < 1200) nGroups = 4; else - if (s->nMTF < 2400) nGroups = 5; else - nGroups = 6; - - /*--- Generate an initial set of coding tables ---*/ - { - Int32 nPart, remF, tFreq, aFreq; - - nPart = nGroups; - remF = s->nMTF; - gs = 0; - while (nPart > 0) { - tFreq = remF / nPart; - ge = gs-1; - aFreq = 0; - while (aFreq < tFreq && ge < alphaSize-1) { - ge++; - aFreq += s->mtfFreq[ge]; - } - - if (ge > gs - && nPart != nGroups && nPart != 1 - && ((nGroups-nPart) % 2 == 1)) { - aFreq -= s->mtfFreq[ge]; - ge--; - } - - if (s->verbosity >= 3) - VPrintf5( " initial group %d, [%d .. %d], " - "has %d syms (%4.1f%%)\n", - nPart, gs, ge, aFreq, - (100.0 * (float)aFreq) / (float)(s->nMTF) ); - - for (v = 0; v < alphaSize; v++) - if (v >= gs && v <= ge) - s->len[nPart-1][v] = BZ_LESSER_ICOST; else - s->len[nPart-1][v] = BZ_GREATER_ICOST; - - nPart--; - gs = ge+1; - remF -= aFreq; - } - } - - /*--- - Iterate up to BZ_N_ITERS times to improve the tables. - ---*/ - for (iter = 0; iter < BZ_N_ITERS; iter++) { - - for (t = 0; t < nGroups; t++) fave[t] = 0; - - for (t = 0; t < nGroups; t++) - for (v = 0; v < alphaSize; v++) - s->rfreq[t][v] = 0; - - /*--- - Set up an auxiliary length table which is used to fast-track - the common case (nGroups == 6). - ---*/ - if (nGroups == 6) { - for (v = 0; v < alphaSize; v++) { - s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v]; - s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v]; - s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v]; - } - } - - nSelectors = 0; - totc = 0; - gs = 0; - while (True) { - - /*--- Set group start & end marks. --*/ - if (gs >= s->nMTF) break; - ge = gs + BZ_G_SIZE - 1; - if (ge >= s->nMTF) ge = s->nMTF-1; - - /*-- - Calculate the cost of this group as coded - by each of the coding tables. - --*/ - for (t = 0; t < nGroups; t++) cost[t] = 0; - - if (nGroups == 6 && 50 == ge-gs+1) { - /*--- fast track the common case ---*/ - register UInt32 cost01, cost23, cost45; - register UInt16 icv; - cost01 = cost23 = cost45 = 0; - -# define BZ_ITER(nn) \ - icv = mtfv[gs+(nn)]; \ - cost01 += s->len_pack[icv][0]; \ - cost23 += s->len_pack[icv][1]; \ - cost45 += s->len_pack[icv][2]; \ - - BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4); - BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9); - BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14); - BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19); - BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24); - BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29); - BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34); - BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39); - BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44); - BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49); - -# undef BZ_ITER - - cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16; - cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16; - cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16; - - } else { - /*--- slow version which correctly handles all situations ---*/ - for (i = gs; i <= ge; i++) { - UInt16 icv = mtfv[i]; - for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv]; - } - } - - /*-- - Find the coding table which is best for this group, - and record its identity in the selector table. - --*/ - bc = 999999999; bt = -1; - for (t = 0; t < nGroups; t++) - if (cost[t] < bc) { bc = cost[t]; bt = t; }; - totc += bc; - fave[bt]++; - s->selector[nSelectors] = bt; - nSelectors++; - - /*-- - Increment the symbol frequencies for the selected table. - --*/ - if (nGroups == 6 && 50 == ge-gs+1) { - /*--- fast track the common case ---*/ - -# define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++ - - BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4); - BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9); - BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14); - BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19); - BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24); - BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29); - BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34); - BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39); - BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44); - BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49); - -# undef BZ_ITUR - - } else { - /*--- slow version which correctly handles all situations ---*/ - for (i = gs; i <= ge; i++) - s->rfreq[bt][ mtfv[i] ]++; - } - - gs = ge+1; - } - if (s->verbosity >= 3) { - VPrintf2 ( " pass %d: size is %d, grp uses are ", - iter+1, totc/8 ); - for (t = 0; t < nGroups; t++) - VPrintf1 ( "%d ", fave[t] ); - VPrintf0 ( "\n" ); - } - - /*-- - Recompute the tables based on the accumulated frequencies. - --*/ - /* maxLen was changed from 20 to 17 in bzip2-1.0.3. See - comment in huffman.c for details. */ - for (t = 0; t < nGroups; t++) - BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]), - alphaSize, 17 /*20*/ ); - } - - - AssertH( nGroups < 8, 3002 ); - AssertH( nSelectors < 32768 && - nSelectors <= (2 + (900000 / BZ_G_SIZE)), - 3003 ); - - - /*--- Compute MTF values for the selectors. ---*/ - { - UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp; - for (i = 0; i < nGroups; i++) pos[i] = i; - for (i = 0; i < nSelectors; i++) { - ll_i = s->selector[i]; - j = 0; - tmp = pos[j]; - while ( ll_i != tmp ) { - j++; - tmp2 = tmp; - tmp = pos[j]; - pos[j] = tmp2; - }; - pos[0] = tmp; - s->selectorMtf[i] = j; - } - }; - - /*--- Assign actual codes for the tables. --*/ - for (t = 0; t < nGroups; t++) { - minLen = 32; - maxLen = 0; - for (i = 0; i < alphaSize; i++) { - if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; - if (s->len[t][i] < minLen) minLen = s->len[t][i]; - } - AssertH ( !(maxLen > 17 /*20*/ ), 3004 ); - AssertH ( !(minLen < 1), 3005 ); - BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]), - minLen, maxLen, alphaSize ); - } - - /*--- Transmit the mapping table. ---*/ - { - Bool inUse16[16]; - for (i = 0; i < 16; i++) { - inUse16[i] = False; - for (j = 0; j < 16; j++) - if (s->inUse[i * 16 + j]) inUse16[i] = True; - } - - nBytes = s->numZ; - for (i = 0; i < 16; i++) - if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0); - - for (i = 0; i < 16; i++) - if (inUse16[i]) - for (j = 0; j < 16; j++) { - if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0); - } - - if (s->verbosity >= 3) - VPrintf1( " bytes: mapping %d, ", s->numZ-nBytes ); - } - - /*--- Now the selectors. ---*/ - nBytes = s->numZ; - bsW ( s, 3, nGroups ); - bsW ( s, 15, nSelectors ); - for (i = 0; i < nSelectors; i++) { - for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1); - bsW(s,1,0); - } - if (s->verbosity >= 3) - VPrintf1( "selectors %d, ", s->numZ-nBytes ); - - /*--- Now the coding tables. ---*/ - nBytes = s->numZ; - - for (t = 0; t < nGroups; t++) { - Int32 curr = s->len[t][0]; - bsW ( s, 5, curr ); - for (i = 0; i < alphaSize; i++) { - while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ }; - while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ }; - bsW ( s, 1, 0 ); - } - } - - if (s->verbosity >= 3) - VPrintf1 ( "code lengths %d, ", s->numZ-nBytes ); - - /*--- And finally, the block data proper ---*/ - nBytes = s->numZ; - selCtr = 0; - gs = 0; - while (True) { - if (gs >= s->nMTF) break; - ge = gs + BZ_G_SIZE - 1; - if (ge >= s->nMTF) ge = s->nMTF-1; - AssertH ( s->selector[selCtr] < nGroups, 3006 ); - - if (nGroups == 6 && 50 == ge-gs+1) { - /*--- fast track the common case ---*/ - UInt16 mtfv_i; - UChar* s_len_sel_selCtr - = &(s->len[s->selector[selCtr]][0]); - Int32* s_code_sel_selCtr - = &(s->code[s->selector[selCtr]][0]); - -# define BZ_ITAH(nn) \ - mtfv_i = mtfv[gs+(nn)]; \ - bsW ( s, \ - s_len_sel_selCtr[mtfv_i], \ - s_code_sel_selCtr[mtfv_i] ) - - BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4); - BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9); - BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14); - BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19); - BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24); - BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29); - BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34); - BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39); - BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44); - BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49); - -# undef BZ_ITAH - - } else { - /*--- slow version which correctly handles all situations ---*/ - for (i = gs; i <= ge; i++) { - bsW ( s, - s->len [s->selector[selCtr]] [mtfv[i]], - s->code [s->selector[selCtr]] [mtfv[i]] ); - } - } - - - gs = ge+1; - selCtr++; - } - AssertH( selCtr == nSelectors, 3007 ); - - if (s->verbosity >= 3) - VPrintf1( "codes %d\n", s->numZ-nBytes ); -} - - -/*---------------------------------------------------*/ -void BZ2_compressBlock ( EState* s, Bool is_last_block ) -{ - if (s->nblock > 0) { - - BZ_FINALISE_CRC ( s->blockCRC ); - s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31); - s->combinedCRC ^= s->blockCRC; - if (s->blockNo > 1) s->numZ = 0; - - if (s->verbosity >= 2) - VPrintf4( " block %d: crc = 0x%08x, " - "combined CRC = 0x%08x, size = %d\n", - s->blockNo, s->blockCRC, s->combinedCRC, s->nblock ); - - BZ2_blockSort ( s ); - } - - s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]); - - /*-- If this is the first block, create the stream header. --*/ - if (s->blockNo == 1) { - BZ2_bsInitWrite ( s ); - bsPutUChar ( s, BZ_HDR_B ); - bsPutUChar ( s, BZ_HDR_Z ); - bsPutUChar ( s, BZ_HDR_h ); - bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) ); - } - - if (s->nblock > 0) { - - bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 ); - bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 ); - bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 ); - - /*-- Now the block's CRC, so it is in a known place. --*/ - bsPutUInt32 ( s, s->blockCRC ); - - /*-- - Now a single bit indicating (non-)randomisation. - As of version 0.9.5, we use a better sorting algorithm - which makes randomisation unnecessary. So always set - the randomised bit to 'no'. Of course, the decoder - still needs to be able to handle randomised blocks - so as to maintain backwards compatibility with - older versions of bzip2. - --*/ - bsW(s,1,0); - - bsW ( s, 24, s->origPtr ); - generateMTFValues ( s ); - sendMTFValues ( s ); - } - - - /*-- If this is the last block, add the stream trailer. --*/ - if (is_last_block) { - - bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 ); - bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 ); - bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 ); - bsPutUInt32 ( s, s->combinedCRC ); - if (s->verbosity >= 2) - VPrintf1( " final combined CRC = 0x%08x\n ", s->combinedCRC ); - bsFinishWrite ( s ); - } -} - - -/*-------------------------------------------------------------*/ -/*--- end compress.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/rbutil/bzip2/crctable.c b/rbutil/bzip2/crctable.c deleted file mode 100644 index 1fea7e946c..0000000000 --- a/rbutil/bzip2/crctable.c +++ /dev/null @@ -1,104 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Table for doing CRCs ---*/ -/*--- crctable.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org> - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#include "bzlib_private.h" - -/*-- - I think this is an implementation of the AUTODIN-II, - Ethernet & FDDI 32-bit CRC standard. Vaguely derived - from code by Rob Warnock, in Section 51 of the - comp.compression FAQ. ---*/ - -UInt32 BZ2_crc32Table[256] = { - - /*-- Ugly, innit? --*/ - - 0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L, - 0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L, - 0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L, - 0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL, - 0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L, - 0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L, - 0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L, - 0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL, - 0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L, - 0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L, - 0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L, - 0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL, - 0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L, - 0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L, - 0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L, - 0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL, - 0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL, - 0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L, - 0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L, - 0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL, - 0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL, - 0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L, - 0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L, - 0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL, - 0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL, - 0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L, - 0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L, - 0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL, - 0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL, - 0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L, - 0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L, - 0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL, - 0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L, - 0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL, - 0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL, - 0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L, - 0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L, - 0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL, - 0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL, - 0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L, - 0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L, - 0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL, - 0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL, - 0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L, - 0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L, - 0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL, - 0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL, - 0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L, - 0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L, - 0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL, - 0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L, - 0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L, - 0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L, - 0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL, - 0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L, - 0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L, - 0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L, - 0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL, - 0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L, - 0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L, - 0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L, - 0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL, - 0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L, - 0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L -}; - - -/*-------------------------------------------------------------*/ -/*--- end crctable.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/rbutil/bzip2/decompress.c b/rbutil/bzip2/decompress.c deleted file mode 100644 index 311f5668f9..0000000000 --- a/rbutil/bzip2/decompress.c +++ /dev/null @@ -1,646 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Decompression machinery ---*/ -/*--- decompress.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org> - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#include "bzlib_private.h" - - -/*---------------------------------------------------*/ -static -void makeMaps_d ( DState* s ) -{ - Int32 i; - s->nInUse = 0; - for (i = 0; i < 256; i++) - if (s->inUse[i]) { - s->seqToUnseq[s->nInUse] = i; - s->nInUse++; - } -} - - -/*---------------------------------------------------*/ -#define RETURN(rrr) \ - { retVal = rrr; goto save_state_and_return; }; - -#define GET_BITS(lll,vvv,nnn) \ - case lll: s->state = lll; \ - while (True) { \ - if (s->bsLive >= nnn) { \ - UInt32 v; \ - v = (s->bsBuff >> \ - (s->bsLive-nnn)) & ((1 << nnn)-1); \ - s->bsLive -= nnn; \ - vvv = v; \ - break; \ - } \ - if (s->strm->avail_in == 0) RETURN(BZ_OK); \ - s->bsBuff \ - = (s->bsBuff << 8) | \ - ((UInt32) \ - (*((UChar*)(s->strm->next_in)))); \ - s->bsLive += 8; \ - s->strm->next_in++; \ - s->strm->avail_in--; \ - s->strm->total_in_lo32++; \ - if (s->strm->total_in_lo32 == 0) \ - s->strm->total_in_hi32++; \ - } - -#define GET_UCHAR(lll,uuu) \ - GET_BITS(lll,uuu,8) - -#define GET_BIT(lll,uuu) \ - GET_BITS(lll,uuu,1) - -/*---------------------------------------------------*/ -#define GET_MTF_VAL(label1,label2,lval) \ -{ \ - if (groupPos == 0) { \ - groupNo++; \ - if (groupNo >= nSelectors) \ - RETURN(BZ_DATA_ERROR); \ - groupPos = BZ_G_SIZE; \ - gSel = s->selector[groupNo]; \ - gMinlen = s->minLens[gSel]; \ - gLimit = &(s->limit[gSel][0]); \ - gPerm = &(s->perm[gSel][0]); \ - gBase = &(s->base[gSel][0]); \ - } \ - groupPos--; \ - zn = gMinlen; \ - GET_BITS(label1, zvec, zn); \ - while (1) { \ - if (zn > 20 /* the longest code */) \ - RETURN(BZ_DATA_ERROR); \ - if (zvec <= gLimit[zn]) break; \ - zn++; \ - GET_BIT(label2, zj); \ - zvec = (zvec << 1) | zj; \ - }; \ - if (zvec - gBase[zn] < 0 \ - || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \ - RETURN(BZ_DATA_ERROR); \ - lval = gPerm[zvec - gBase[zn]]; \ -} - - -/*---------------------------------------------------*/ -Int32 BZ2_decompress ( DState* s ) -{ - UChar uc; - Int32 retVal; - Int32 minLen, maxLen; - bz_stream* strm = s->strm; - - /* stuff that needs to be saved/restored */ - Int32 i; - Int32 j; - Int32 t; - Int32 alphaSize; - Int32 nGroups; - Int32 nSelectors; - Int32 EOB; - Int32 groupNo; - Int32 groupPos; - Int32 nextSym; - Int32 nblockMAX; - Int32 nblock; - Int32 es; - Int32 N; - Int32 curr; - Int32 zt; - Int32 zn; - Int32 zvec; - Int32 zj; - Int32 gSel; - Int32 gMinlen; - Int32* gLimit; - Int32* gBase; - Int32* gPerm; - - if (s->state == BZ_X_MAGIC_1) { - /*initialise the save area*/ - s->save_i = 0; - s->save_j = 0; - s->save_t = 0; - s->save_alphaSize = 0; - s->save_nGroups = 0; - s->save_nSelectors = 0; - s->save_EOB = 0; - s->save_groupNo = 0; - s->save_groupPos = 0; - s->save_nextSym = 0; - s->save_nblockMAX = 0; - s->save_nblock = 0; - s->save_es = 0; - s->save_N = 0; - s->save_curr = 0; - s->save_zt = 0; - s->save_zn = 0; - s->save_zvec = 0; - s->save_zj = 0; - s->save_gSel = 0; - s->save_gMinlen = 0; - s->save_gLimit = NULL; - s->save_gBase = NULL; - s->save_gPerm = NULL; - } - - /*restore from the save area*/ - i = s->save_i; - j = s->save_j; - t = s->save_t; - alphaSize = s->save_alphaSize; - nGroups = s->save_nGroups; - nSelectors = s->save_nSelectors; - EOB = s->save_EOB; - groupNo = s->save_groupNo; - groupPos = s->save_groupPos; - nextSym = s->save_nextSym; - nblockMAX = s->save_nblockMAX; - nblock = s->save_nblock; - es = s->save_es; - N = s->save_N; - curr = s->save_curr; - zt = s->save_zt; - zn = s->save_zn; - zvec = s->save_zvec; - zj = s->save_zj; - gSel = s->save_gSel; - gMinlen = s->save_gMinlen; - gLimit = s->save_gLimit; - gBase = s->save_gBase; - gPerm = s->save_gPerm; - - retVal = BZ_OK; - - switch (s->state) { - - GET_UCHAR(BZ_X_MAGIC_1, uc); - if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC); - - GET_UCHAR(BZ_X_MAGIC_2, uc); - if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC); - - GET_UCHAR(BZ_X_MAGIC_3, uc) - if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC); - - GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8) - if (s->blockSize100k < (BZ_HDR_0 + 1) || - s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC); - s->blockSize100k -= BZ_HDR_0; - - if (s->smallDecompress) { - s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) ); - s->ll4 = BZALLOC( - ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar) - ); - if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR); - } else { - s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) ); - if (s->tt == NULL) RETURN(BZ_MEM_ERROR); - } - - GET_UCHAR(BZ_X_BLKHDR_1, uc); - - if (uc == 0x17) goto endhdr_2; - if (uc != 0x31) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_2, uc); - if (uc != 0x41) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_3, uc); - if (uc != 0x59) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_4, uc); - if (uc != 0x26) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_5, uc); - if (uc != 0x53) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_6, uc); - if (uc != 0x59) RETURN(BZ_DATA_ERROR); - - s->currBlockNo++; - if (s->verbosity >= 2) - VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo ); - - s->storedBlockCRC = 0; - GET_UCHAR(BZ_X_BCRC_1, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_BCRC_2, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_BCRC_3, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_BCRC_4, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - - GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1); - - s->origPtr = 0; - GET_UCHAR(BZ_X_ORIGPTR_1, uc); - s->origPtr = (s->origPtr << 8) | ((Int32)uc); - GET_UCHAR(BZ_X_ORIGPTR_2, uc); - s->origPtr = (s->origPtr << 8) | ((Int32)uc); - GET_UCHAR(BZ_X_ORIGPTR_3, uc); - s->origPtr = (s->origPtr << 8) | ((Int32)uc); - - if (s->origPtr < 0) - RETURN(BZ_DATA_ERROR); - if (s->origPtr > 10 + 100000*s->blockSize100k) - RETURN(BZ_DATA_ERROR); - - /*--- Receive the mapping table ---*/ - for (i = 0; i < 16; i++) { - GET_BIT(BZ_X_MAPPING_1, uc); - if (uc == 1) - s->inUse16[i] = True; else - s->inUse16[i] = False; - } - - for (i = 0; i < 256; i++) s->inUse[i] = False; - - for (i = 0; i < 16; i++) - if (s->inUse16[i]) - for (j = 0; j < 16; j++) { - GET_BIT(BZ_X_MAPPING_2, uc); - if (uc == 1) s->inUse[i * 16 + j] = True; - } - makeMaps_d ( s ); - if (s->nInUse == 0) RETURN(BZ_DATA_ERROR); - alphaSize = s->nInUse+2; - - /*--- Now the selectors ---*/ - GET_BITS(BZ_X_SELECTOR_1, nGroups, 3); - if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR); - GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15); - if (nSelectors < 1) RETURN(BZ_DATA_ERROR); - for (i = 0; i < nSelectors; i++) { - j = 0; - while (True) { - GET_BIT(BZ_X_SELECTOR_3, uc); - if (uc == 0) break; - j++; - if (j >= nGroups) RETURN(BZ_DATA_ERROR); - } - s->selectorMtf[i] = j; - } - - /*--- Undo the MTF values for the selectors. ---*/ - { - UChar pos[BZ_N_GROUPS], tmp, v; - for (v = 0; v < nGroups; v++) pos[v] = v; - - for (i = 0; i < nSelectors; i++) { - v = s->selectorMtf[i]; - tmp = pos[v]; - while (v > 0) { pos[v] = pos[v-1]; v--; } - pos[0] = tmp; - s->selector[i] = tmp; - } - } - - /*--- Now the coding tables ---*/ - for (t = 0; t < nGroups; t++) { - GET_BITS(BZ_X_CODING_1, curr, 5); - for (i = 0; i < alphaSize; i++) { - while (True) { - if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR); - GET_BIT(BZ_X_CODING_2, uc); - if (uc == 0) break; - GET_BIT(BZ_X_CODING_3, uc); - if (uc == 0) curr++; else curr--; - } - s->len[t][i] = curr; - } - } - - /*--- Create the Huffman decoding tables ---*/ - for (t = 0; t < nGroups; t++) { - minLen = 32; - maxLen = 0; - for (i = 0; i < alphaSize; i++) { - if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; - if (s->len[t][i] < minLen) minLen = s->len[t][i]; - } - BZ2_hbCreateDecodeTables ( - &(s->limit[t][0]), - &(s->base[t][0]), - &(s->perm[t][0]), - &(s->len[t][0]), - minLen, maxLen, alphaSize - ); - s->minLens[t] = minLen; - } - - /*--- Now the MTF values ---*/ - - EOB = s->nInUse+1; - nblockMAX = 100000 * s->blockSize100k; - groupNo = -1; - groupPos = 0; - - for (i = 0; i <= 255; i++) s->unzftab[i] = 0; - - /*-- MTF init --*/ - { - Int32 ii, jj, kk; - kk = MTFA_SIZE-1; - for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) { - for (jj = MTFL_SIZE-1; jj >= 0; jj--) { - s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj); - kk--; - } - s->mtfbase[ii] = kk + 1; - } - } - /*-- end MTF init --*/ - - nblock = 0; - GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym); - - while (True) { - - if (nextSym == EOB) break; - - if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) { - - es = -1; - N = 1; - do { - /* Check that N doesn't get too big, so that es doesn't - go negative. The maximum value that can be - RUNA/RUNB encoded is equal to the block size (post - the initial RLE), viz, 900k, so bounding N at 2 - million should guard against overflow without - rejecting any legitimate inputs. */ - if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR); - if (nextSym == BZ_RUNA) es = es + (0+1) * N; else - if (nextSym == BZ_RUNB) es = es + (1+1) * N; - N = N * 2; - GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym); - } - while (nextSym == BZ_RUNA || nextSym == BZ_RUNB); - - es++; - uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ]; - s->unzftab[uc] += es; - - if (s->smallDecompress) - while (es > 0) { - if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); - s->ll16[nblock] = (UInt16)uc; - nblock++; - es--; - } - else - while (es > 0) { - if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); - s->tt[nblock] = (UInt32)uc; - nblock++; - es--; - }; - - continue; - - } else { - - if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); - - /*-- uc = MTF ( nextSym-1 ) --*/ - { - Int32 ii, jj, kk, pp, lno, off; - UInt32 nn; - nn = (UInt32)(nextSym - 1); - - if (nn < MTFL_SIZE) { - /* avoid general-case expense */ - pp = s->mtfbase[0]; - uc = s->mtfa[pp+nn]; - while (nn > 3) { - Int32 z = pp+nn; - s->mtfa[(z) ] = s->mtfa[(z)-1]; - s->mtfa[(z)-1] = s->mtfa[(z)-2]; - s->mtfa[(z)-2] = s->mtfa[(z)-3]; - s->mtfa[(z)-3] = s->mtfa[(z)-4]; - nn -= 4; - } - while (nn > 0) { - s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--; - }; - s->mtfa[pp] = uc; - } else { - /* general case */ - lno = nn / MTFL_SIZE; - off = nn % MTFL_SIZE; - pp = s->mtfbase[lno] + off; - uc = s->mtfa[pp]; - while (pp > s->mtfbase[lno]) { - s->mtfa[pp] = s->mtfa[pp-1]; pp--; - }; - s->mtfbase[lno]++; - while (lno > 0) { - s->mtfbase[lno]--; - s->mtfa[s->mtfbase[lno]] - = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1]; - lno--; - } - s->mtfbase[0]--; - s->mtfa[s->mtfbase[0]] = uc; - if (s->mtfbase[0] == 0) { - kk = MTFA_SIZE-1; - for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) { - for (jj = MTFL_SIZE-1; jj >= 0; jj--) { - s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj]; - kk--; - } - s->mtfbase[ii] = kk + 1; - } - } - } - } - /*-- end uc = MTF ( nextSym-1 ) --*/ - - s->unzftab[s->seqToUnseq[uc]]++; - if (s->smallDecompress) - s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else - s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]); - nblock++; - - GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym); - continue; - } - } - - /* Now we know what nblock is, we can do a better sanity - check on s->origPtr. - */ - if (s->origPtr < 0 || s->origPtr >= nblock) - RETURN(BZ_DATA_ERROR); - - /*-- Set up cftab to facilitate generation of T^(-1) --*/ - /* Check: unzftab entries in range. */ - for (i = 0; i <= 255; i++) { - if (s->unzftab[i] < 0 || s->unzftab[i] > nblock) - RETURN(BZ_DATA_ERROR); - } - /* Actually generate cftab. */ - s->cftab[0] = 0; - for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1]; - for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1]; - /* Check: cftab entries in range. */ - for (i = 0; i <= 256; i++) { - if (s->cftab[i] < 0 || s->cftab[i] > nblock) { - /* s->cftab[i] can legitimately be == nblock */ - RETURN(BZ_DATA_ERROR); - } - } - /* Check: cftab entries non-descending. */ - for (i = 1; i <= 256; i++) { - if (s->cftab[i-1] > s->cftab[i]) { - RETURN(BZ_DATA_ERROR); - } - } - - s->state_out_len = 0; - s->state_out_ch = 0; - BZ_INITIALISE_CRC ( s->calculatedBlockCRC ); - s->state = BZ_X_OUTPUT; - if (s->verbosity >= 2) VPrintf0 ( "rt+rld" ); - - if (s->smallDecompress) { - - /*-- Make a copy of cftab, used in generation of T --*/ - for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i]; - - /*-- compute the T vector --*/ - for (i = 0; i < nblock; i++) { - uc = (UChar)(s->ll16[i]); - SET_LL(i, s->cftabCopy[uc]); - s->cftabCopy[uc]++; - } - - /*-- Compute T^(-1) by pointer reversal on T --*/ - i = s->origPtr; - j = GET_LL(i); - do { - Int32 tmp = GET_LL(j); - SET_LL(j, i); - i = j; - j = tmp; - } - while (i != s->origPtr); - - s->tPos = s->origPtr; - s->nblock_used = 0; - if (s->blockRandomised) { - BZ_RAND_INIT_MASK; - BZ_GET_SMALL(s->k0); s->nblock_used++; - BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; - } else { - BZ_GET_SMALL(s->k0); s->nblock_used++; - } - - } else { - - /*-- compute the T^(-1) vector --*/ - for (i = 0; i < nblock; i++) { - uc = (UChar)(s->tt[i] & 0xff); - s->tt[s->cftab[uc]] |= (i << 8); - s->cftab[uc]++; - } - - s->tPos = s->tt[s->origPtr] >> 8; - s->nblock_used = 0; - if (s->blockRandomised) { - BZ_RAND_INIT_MASK; - BZ_GET_FAST(s->k0); s->nblock_used++; - BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; - } else { - BZ_GET_FAST(s->k0); s->nblock_used++; - } - - } - - RETURN(BZ_OK); - - - - endhdr_2: - - GET_UCHAR(BZ_X_ENDHDR_2, uc); - if (uc != 0x72) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_3, uc); - if (uc != 0x45) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_4, uc); - if (uc != 0x38) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_5, uc); - if (uc != 0x50) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_6, uc); - if (uc != 0x90) RETURN(BZ_DATA_ERROR); - - s->storedCombinedCRC = 0; - GET_UCHAR(BZ_X_CCRC_1, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_CCRC_2, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_CCRC_3, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_CCRC_4, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - - s->state = BZ_X_IDLE; - RETURN(BZ_STREAM_END); - - default: AssertH ( False, 4001 ); - } - - AssertH ( False, 4002 ); - - save_state_and_return: - - s->save_i = i; - s->save_j = j; - s->save_t = t; - s->save_alphaSize = alphaSize; - s->save_nGroups = nGroups; - s->save_nSelectors = nSelectors; - s->save_EOB = EOB; - s->save_groupNo = groupNo; - s->save_groupPos = groupPos; - s->save_nextSym = nextSym; - s->save_nblockMAX = nblockMAX; - s->save_nblock = nblock; - s->save_es = es; - s->save_N = N; - s->save_curr = curr; - s->save_zt = zt; - s->save_zn = zn; - s->save_zvec = zvec; - s->save_zj = zj; - s->save_gSel = gSel; - s->save_gMinlen = gMinlen; - s->save_gLimit = gLimit; - s->save_gBase = gBase; - s->save_gPerm = gPerm; - - return retVal; -} - - -/*-------------------------------------------------------------*/ -/*--- end decompress.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/rbutil/bzip2/huffman.c b/rbutil/bzip2/huffman.c deleted file mode 100644 index 2283fdbc5a..0000000000 --- a/rbutil/bzip2/huffman.c +++ /dev/null @@ -1,205 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Huffman coding low-level stuff ---*/ -/*--- huffman.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org> - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#include "bzlib_private.h" - -/*---------------------------------------------------*/ -#define WEIGHTOF(zz0) ((zz0) & 0xffffff00) -#define DEPTHOF(zz1) ((zz1) & 0x000000ff) -#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3)) - -#define ADDWEIGHTS(zw1,zw2) \ - (WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \ - (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2))) - -#define UPHEAP(z) \ -{ \ - Int32 zz, tmp; \ - zz = z; tmp = heap[zz]; \ - while (weight[tmp] < weight[heap[zz >> 1]]) { \ - heap[zz] = heap[zz >> 1]; \ - zz >>= 1; \ - } \ - heap[zz] = tmp; \ -} - -#define DOWNHEAP(z) \ -{ \ - Int32 zz, yy, tmp; \ - zz = z; tmp = heap[zz]; \ - while (True) { \ - yy = zz << 1; \ - if (yy > nHeap) break; \ - if (yy < nHeap && \ - weight[heap[yy+1]] < weight[heap[yy]]) \ - yy++; \ - if (weight[tmp] < weight[heap[yy]]) break; \ - heap[zz] = heap[yy]; \ - zz = yy; \ - } \ - heap[zz] = tmp; \ -} - - -/*---------------------------------------------------*/ -void BZ2_hbMakeCodeLengths ( UChar *len, - Int32 *freq, - Int32 alphaSize, - Int32 maxLen ) -{ - /*-- - Nodes and heap entries run from 1. Entry 0 - for both the heap and nodes is a sentinel. - --*/ - Int32 nNodes, nHeap, n1, n2, i, j, k; - Bool tooLong; - - Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ]; - Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ]; - Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ]; - - for (i = 0; i < alphaSize; i++) - weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8; - - while (True) { - - nNodes = alphaSize; - nHeap = 0; - - heap[0] = 0; - weight[0] = 0; - parent[0] = -2; - - for (i = 1; i <= alphaSize; i++) { - parent[i] = -1; - nHeap++; - heap[nHeap] = i; - UPHEAP(nHeap); - } - - AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 ); - - while (nHeap > 1) { - n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1); - n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1); - nNodes++; - parent[n1] = parent[n2] = nNodes; - weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]); - parent[nNodes] = -1; - nHeap++; - heap[nHeap] = nNodes; - UPHEAP(nHeap); - } - - AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 ); - - tooLong = False; - for (i = 1; i <= alphaSize; i++) { - j = 0; - k = i; - while (parent[k] >= 0) { k = parent[k]; j++; } - len[i-1] = j; - if (j > maxLen) tooLong = True; - } - - if (! tooLong) break; - - /* 17 Oct 04: keep-going condition for the following loop used - to be 'i < alphaSize', which missed the last element, - theoretically leading to the possibility of the compressor - looping. However, this count-scaling step is only needed if - one of the generated Huffman code words is longer than - maxLen, which up to and including version 1.0.2 was 20 bits, - which is extremely unlikely. In version 1.0.3 maxLen was - changed to 17 bits, which has minimal effect on compression - ratio, but does mean this scaling step is used from time to - time, enough to verify that it works. - - This means that bzip2-1.0.3 and later will only produce - Huffman codes with a maximum length of 17 bits. However, in - order to preserve backwards compatibility with bitstreams - produced by versions pre-1.0.3, the decompressor must still - handle lengths of up to 20. */ - - for (i = 1; i <= alphaSize; i++) { - j = weight[i] >> 8; - j = 1 + (j / 2); - weight[i] = j << 8; - } - } -} - - -/*---------------------------------------------------*/ -void BZ2_hbAssignCodes ( Int32 *code, - UChar *length, - Int32 minLen, - Int32 maxLen, - Int32 alphaSize ) -{ - Int32 n, vec, i; - - vec = 0; - for (n = minLen; n <= maxLen; n++) { - for (i = 0; i < alphaSize; i++) - if (length[i] == n) { code[i] = vec; vec++; }; - vec <<= 1; - } -} - - -/*---------------------------------------------------*/ -void BZ2_hbCreateDecodeTables ( Int32 *limit, - Int32 *base, - Int32 *perm, - UChar *length, - Int32 minLen, - Int32 maxLen, - Int32 alphaSize ) -{ - Int32 pp, i, j, vec; - - pp = 0; - for (i = minLen; i <= maxLen; i++) - for (j = 0; j < alphaSize; j++) - if (length[j] == i) { perm[pp] = j; pp++; }; - - for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0; - for (i = 0; i < alphaSize; i++) base[length[i]+1]++; - - for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1]; - - for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0; - vec = 0; - - for (i = minLen; i <= maxLen; i++) { - vec += (base[i+1] - base[i]); - limit[i] = vec-1; - vec <<= 1; - } - for (i = minLen + 1; i <= maxLen; i++) - base[i] = ((limit[i-1] + 1) << 1) - base[i]; -} - - -/*-------------------------------------------------------------*/ -/*--- end huffman.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/rbutil/bzip2/randtable.c b/rbutil/bzip2/randtable.c deleted file mode 100644 index 6d62459906..0000000000 --- a/rbutil/bzip2/randtable.c +++ /dev/null @@ -1,84 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Table for randomising repetitive blocks ---*/ -/*--- randtable.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org> - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#include "bzlib_private.h" - - -/*---------------------------------------------*/ -Int32 BZ2_rNums[512] = { - 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, - 985, 724, 205, 454, 863, 491, 741, 242, 949, 214, - 733, 859, 335, 708, 621, 574, 73, 654, 730, 472, - 419, 436, 278, 496, 867, 210, 399, 680, 480, 51, - 878, 465, 811, 169, 869, 675, 611, 697, 867, 561, - 862, 687, 507, 283, 482, 129, 807, 591, 733, 623, - 150, 238, 59, 379, 684, 877, 625, 169, 643, 105, - 170, 607, 520, 932, 727, 476, 693, 425, 174, 647, - 73, 122, 335, 530, 442, 853, 695, 249, 445, 515, - 909, 545, 703, 919, 874, 474, 882, 500, 594, 612, - 641, 801, 220, 162, 819, 984, 589, 513, 495, 799, - 161, 604, 958, 533, 221, 400, 386, 867, 600, 782, - 382, 596, 414, 171, 516, 375, 682, 485, 911, 276, - 98, 553, 163, 354, 666, 933, 424, 341, 533, 870, - 227, 730, 475, 186, 263, 647, 537, 686, 600, 224, - 469, 68, 770, 919, 190, 373, 294, 822, 808, 206, - 184, 943, 795, 384, 383, 461, 404, 758, 839, 887, - 715, 67, 618, 276, 204, 918, 873, 777, 604, 560, - 951, 160, 578, 722, 79, 804, 96, 409, 713, 940, - 652, 934, 970, 447, 318, 353, 859, 672, 112, 785, - 645, 863, 803, 350, 139, 93, 354, 99, 820, 908, - 609, 772, 154, 274, 580, 184, 79, 626, 630, 742, - 653, 282, 762, 623, 680, 81, 927, 626, 789, 125, - 411, 521, 938, 300, 821, 78, 343, 175, 128, 250, - 170, 774, 972, 275, 999, 639, 495, 78, 352, 126, - 857, 956, 358, 619, 580, 124, 737, 594, 701, 612, - 669, 112, 134, 694, 363, 992, 809, 743, 168, 974, - 944, 375, 748, 52, 600, 747, 642, 182, 862, 81, - 344, 805, 988, 739, 511, 655, 814, 334, 249, 515, - 897, 955, 664, 981, 649, 113, 974, 459, 893, 228, - 433, 837, 553, 268, 926, 240, 102, 654, 459, 51, - 686, 754, 806, 760, 493, 403, 415, 394, 687, 700, - 946, 670, 656, 610, 738, 392, 760, 799, 887, 653, - 978, 321, 576, 617, 626, 502, 894, 679, 243, 440, - 680, 879, 194, 572, 640, 724, 926, 56, 204, 700, - 707, 151, 457, 449, 797, 195, 791, 558, 945, 679, - 297, 59, 87, 824, 713, 663, 412, 693, 342, 606, - 134, 108, 571, 364, 631, 212, 174, 643, 304, 329, - 343, 97, 430, 751, 497, 314, 983, 374, 822, 928, - 140, 206, 73, 263, 980, 736, 876, 478, 430, 305, - 170, 514, 364, 692, 829, 82, 855, 953, 676, 246, - 369, 970, 294, 750, 807, 827, 150, 790, 288, 923, - 804, 378, 215, 828, 592, 281, 565, 555, 710, 82, - 896, 831, 547, 261, 524, 462, 293, 465, 502, 56, - 661, 821, 976, 991, 658, 869, 905, 758, 745, 193, - 768, 550, 608, 933, 378, 286, 215, 979, 792, 961, - 61, 688, 793, 644, 986, 403, 106, 366, 905, 644, - 372, 567, 466, 434, 645, 210, 389, 550, 919, 135, - 780, 773, 635, 389, 707, 100, 626, 958, 165, 504, - 920, 176, 193, 713, 857, 265, 203, 50, 668, 108, - 645, 990, 626, 197, 510, 357, 358, 850, 858, 364, - 936, 638 -}; - - -/*-------------------------------------------------------------*/ -/*--- end randtable.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/rbutil/chinachippatcher/Makefile b/rbutil/chinachippatcher/Makefile deleted file mode 100644 index c8defcb5c4..0000000000 --- a/rbutil/chinachippatcher/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# __________ __ ___. -# Open \______ \ ____ ____ | | _\_ |__ _______ ___ -# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -# \/ \/ \/ \/ \/ -# $Id$ -# -CFLAGS += -g -Wall - -OUTPUT = chinachippatcher - -LIBSOURCES = chinachip.c -SOURCES = main.c - -include ../libtools.make - diff --git a/rbutil/chinachippatcher/chinachip.c b/rbutil/chinachippatcher/chinachip.c deleted file mode 100644 index 79b5acad66..0000000000 --- a/rbutil/chinachippatcher/chinachip.c +++ /dev/null @@ -1,258 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2009 by Maurus Cuelenaere - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include <stdio.h> -#include <stddef.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <time.h> -#include "chinachip.h" - -/* From http://www.rockbox.org/wiki/ChinaChip */ -struct header -{ - uint32_t signature; /* WADF */ - uint32_t unk; - int8_t timestamp[12]; /* 200805081100 */ - uint32_t size; - uint32_t checksum; - uint32_t unk2; - int8_t identifier[32]; /* Chinachip PMP firmware V1.0 */ -} __attribute__ ((packed)); - -static inline void int2le(unsigned char* addr, unsigned int val) -{ - addr[0] = val & 0xff; - addr[1] = (val >> 8) & 0xff; - addr[2] = (val >> 16) & 0xff; - addr[3] = (val >> 24) & 0xff; -} - -static inline unsigned int le2int(unsigned char* buf) -{ - return (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; -} - -static long int filesize(FILE* fd) -{ - long int len; - fseek(fd, 0, SEEK_END); - len = ftell(fd); - fseek(fd, 0, SEEK_SET); - return len; -} - -#define FCLOSE(fd) fclose(fd); fd = NULL; -#define CCPMPBIN_HEADER_SIZE (sizeof(uint32_t)*2 + sizeof(uint8_t) + 9) -#define TOTAL_SIZE (fsize + CCPMPBIN_HEADER_SIZE + bsize) -enum cc_error chinachip_patch(const char* firmware, const char* bootloader, - const char* output, const char* ccpmp_backup) -{ - char header_time[13]; - time_t cur_time; - struct tm* time_info; - unsigned char* buf = NULL; - FILE *fd = NULL, *bd = NULL, *od = NULL; - unsigned int ccpmp_size = 0, i, fsize, bsize; - signed int checksum = 0, ccpmp_pos; - int result = E_OK; - - fd = fopen(firmware, "rb"); - if(!fd) - { - fprintf(stderr, "[ERR] Can't open file %s!\n", firmware); - result = E_OPEN_FIRMWARE; - goto err; - } - bd = fopen(bootloader, "rb"); - if(!bd) - { - fprintf(stderr, "[ERR] Can't open file %s!\n", bootloader); - result = E_OPEN_BOOTLOADER; - goto err; - } - - bsize = filesize(bd); - fprintf(stderr, "[INFO] Bootloader size is %d bytes\n", bsize); - FCLOSE(bd); - - fsize = filesize(fd); - fprintf(stderr, "[INFO] Firmware size is %d bytes\n", fsize); - - buf = malloc(TOTAL_SIZE); - if(buf == NULL) - { - fprintf(stderr, "[ERR] Can't allocate %d bytes!\n", fsize); - result = E_MEMALLOC; - goto err; - } - memset(buf, 0, TOTAL_SIZE); - - fprintf(stderr, "[INFO] Reading %s into memory...\n", firmware); - if(fread(buf, fsize, 1, fd) != 1) - { - fprintf(stderr, "[ERR] Can't read file %s to memory!\n", firmware); - result = E_LOAD_FIRMWARE; - goto err; - } - FCLOSE(fd); - - if(memcmp(buf, "WADF", 4)) - { - fprintf(stderr, "[ERR] File %s isn't a valid ChinaChip firmware!\n", firmware); - result = E_INVALID_FILE; - goto err; - } - - ccpmp_pos = -1, i = 0x40; - do - { - int filenamesize = le2int(&buf[i]); - i += sizeof(uint32_t); - - if(!strncmp((char*) &buf[i], "ccpmp.bin", 9)) - { - ccpmp_pos = i; - ccpmp_size = le2int(&buf[i + sizeof(uint8_t) + filenamesize]); - } - else - i += filenamesize + le2int(&buf[i + sizeof(uint8_t) + filenamesize]) - + sizeof(uint32_t) + sizeof(uint8_t); - } while(ccpmp_pos < 0 && i < fsize); - - if(i >= fsize) - { - fprintf(stderr, "[ERR] Couldn't find ccpmp.bin in %s!\n", firmware); - result = E_NO_CCPMP; - goto err; - } - fprintf(stderr, "[INFO] Found ccpmp.bin at %d bytes\n", ccpmp_pos); - - if(ccpmp_backup) - { - int ccpmp_data_pos = ccpmp_pos + 9; - bd = fopen(ccpmp_backup, "wb"); - if(!bd) - { - fprintf(stderr, "[ERR] Can't open file %s!\n", ccpmp_backup); - result = E_OPEN_BACKUP; - goto err; - } - - fprintf(stderr, "[INFO] Writing %d bytes to %s...\n", ccpmp_size, ccpmp_backup); - if(fwrite(&buf[ccpmp_data_pos], ccpmp_size, 1, bd) != 1) - { - fprintf(stderr, "[ERR] Can't write to file %s!\n", ccpmp_backup); - result = E_WRITE_BACKUP; - goto err; - } - FCLOSE(bd); - } - - fprintf(stderr, "[INFO] Renaming it to ccpmp.old...\n"); - buf[ccpmp_pos + 6] = 'o'; - buf[ccpmp_pos + 7] = 'l'; - buf[ccpmp_pos + 8] = 'd'; - - bd = fopen(bootloader, "rb"); - if(!bd) - { - fprintf(stderr, "[ERR] Can't open file %s!\n", bootloader); - result = E_OPEN_BOOTLOADER; - goto err; - } - - /* Also include path size */ - ccpmp_pos -= sizeof(uint32_t); - - fprintf(stderr, "[INFO] Making place for ccpmp.bin...\n"); - memmove(&buf[ccpmp_pos + bsize + CCPMPBIN_HEADER_SIZE], - &buf[ccpmp_pos], fsize - ccpmp_pos); - - fprintf(stderr, "[INFO] Reading %s into memory...\n", bootloader); - if(fread(&buf[ccpmp_pos + CCPMPBIN_HEADER_SIZE], - bsize, 1, bd) != 1) - { - fprintf(stderr, "[ERR] Can't read file %s to memory!\n", bootloader); - result = E_LOAD_BOOTLOADER; - goto err; - } - FCLOSE(bd); - - fprintf(stderr, "[INFO] Adding header to %s...\n", bootloader); - int2le(&buf[ccpmp_pos ], 9); /* Pathname Size */ - memcpy(&buf[ccpmp_pos + 4 ], "ccpmp.bin", 9); /* Pathname */ - memset(&buf[ccpmp_pos + 4 + 9 ], 0x20, sizeof(uint8_t)); /* File Type */ - int2le(&buf[ccpmp_pos + 4 + 9 + 1], bsize); /* File Size */ - - time(&cur_time); - time_info = localtime(&cur_time); - if(time_info == NULL) - { - fprintf(stderr, "[ERR] Can't obtain current time!\n"); - result = E_GET_TIME; - goto err; - } - - snprintf(header_time, 13, "%04d%02d%02d%02d%02d", time_info->tm_year + 1900, - time_info->tm_mon, - time_info->tm_mday, - time_info->tm_hour, - time_info->tm_min); - - fprintf(stderr, "[INFO] Computing checksum...\n"); - for(i = sizeof(struct header); i < TOTAL_SIZE; i+=4) - checksum += le2int(&buf[i]); - - fprintf(stderr, "[INFO] Updating main header...\n"); - memcpy(&buf[offsetof(struct header, timestamp)], header_time, 12); - int2le(&buf[offsetof(struct header, size) ], TOTAL_SIZE); - int2le(&buf[offsetof(struct header, checksum) ], checksum); - - od = fopen(output, "wb"); - if(!od) - { - fprintf(stderr, "[ERR] Can't open file %s!\n", output); - result = E_OPEN_OUTFILE; - goto err; - } - - fprintf(stderr, "[INFO] Writing output to %s...\n", output); - if(fwrite(buf, TOTAL_SIZE, 1, od) != 1) - { - fprintf(stderr, "[ERR] Can't write to file %s!\n", output); - result = E_WRITE_OUTFILE; - goto err; - } - -err: - if(buf) - free(buf); - if(fd) - fclose(fd); - if(bd) - fclose(bd); - if(od) - fclose(od); - - return result; -} - diff --git a/rbutil/chinachippatcher/chinachip.h b/rbutil/chinachippatcher/chinachip.h deleted file mode 100644 index b92066bb8b..0000000000 --- a/rbutil/chinachippatcher/chinachip.h +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2009 by Maurus Cuelenaere - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#ifndef __INCLUDE_CHINACHIP_H_ -#define __INCLUDE_CHINACHIP_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -enum cc_error { - E_OK, - E_OPEN_FIRMWARE, - E_OPEN_BOOTLOADER, - E_MEMALLOC, - E_LOAD_FIRMWARE, - E_INVALID_FILE, - E_NO_CCPMP, - E_OPEN_BACKUP, - E_WRITE_BACKUP, - E_LOAD_BOOTLOADER, - E_GET_TIME, - E_OPEN_OUTFILE, - E_WRITE_OUTFILE, -}; - -enum cc_error chinachip_patch(const char* firmware, const char* bootloader, - const char* output, const char* ccpmp_backup); - -#ifdef __cplusplus -} -#endif - -#endif /* __INCLUDE_CHINACHIP_H_ */ diff --git a/rbutil/chinachippatcher/main.c b/rbutil/chinachippatcher/main.c deleted file mode 100644 index e7779774c9..0000000000 --- a/rbutil/chinachippatcher/main.c +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2009 by Maurus Cuelenaere - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include <stdio.h> -#include <stdarg.h> -#include "chinachip.h" - -#ifndef VERSION /* allow setting version from outside for svn builds */ -#define VERSION "0.1" -#endif -#define PRINT(fmt, ...) fprintf(stderr, fmt"\n", ##__VA_ARGS__) - -void usage(char* name) -{ - PRINT("Usage:"); - PRINT(" %s <firmware> <bootloader> <firmware_output> [backup]", name); - PRINT("\nExample:"); - PRINT(" %s VX747.HXF bootloader.bin output.HXF ccpmp.bak", name); - PRINT(" This will copy ccpmp.bin in VX747.HXF as ccpmp.old and replace it\n" - " with bootloader.bin, the output will get written to output.HXF.\n" - " The old ccpmp.bin will get written to ccpmp.bak.\n"); -} - -int main(int argc, char* argv[]) -{ - PRINT("ChinaChipPatcher v" VERSION " - (C) Maurus Cuelenaere 2009"); - PRINT("This is free software; see the source for copying conditions. There is NO"); - PRINT("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."); - - if(argc < 4) - { - usage(argv[0]); - return 1; - } - - return chinachip_patch(argv[1], argv[2], argv[3], argc > 4 ? argv[4] : NULL); -} - diff --git a/rbutil/e200rpatcher/Makefile b/rbutil/e200rpatcher/Makefile deleted file mode 100644 index dfe5c1e037..0000000000 --- a/rbutil/e200rpatcher/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -CFLAGS=-Wall -W - -ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN) -OUTPUT=e200rpatcher.exe -CROSS= -CFLAGS+=-mno-cygwin -else -OUTPUT=e200rpatcher -CROSS=i586-mingw32msvc- -endif - -LIBS = -lusb -WINLIBS = -I libusb-win32-device-bin-0.1.12.1/include libusb-win32-device-bin-0.1.12.1/lib/dynamic/libusb_dyn.c - -NATIVECC = gcc -CC = $(CROSS)gcc -WINDRES = $(CROSS)windres - -all: $(OUTPUT) - -e200rpatcher: e200rpatcher.c bootimg.c - gcc $(CFLAGS) $(LIBS) -o e200rpatcher e200rpatcher.c bootimg.c - strip e200rpatcher - -e200rpatcher.exe: e200rpatcher.c bootimg.c e200rpatcher-rc.o - $(CC) $(CFLAGS) $(WINLIBS) -o e200rpatcher.exe e200rpatcher.c bootimg.c e200rpatcher-rc.o - $(CROSS)strip e200rpatcher.exe - -e200rpatcher-rc.o: e200rpatcher.rc e200rpatcher.manifest - $(WINDRES) -i e200rpatcher.rc -o e200rpatcher-rc.o - -e200rpatcher-mac: e200rpatcher-i386 e200rpatcher-ppc - lipo -create e200rpatcher-ppc e200rpatcher-i386 -output e200rpatcher-mac - -e200rpatcher.dmg: e200rpatcher-mac - mkdir -p e200rpatcher-dmg - cp -p e200rpatcher-mac e200rpatcher-dmg - hdiutil create -srcfolder e200rpatcher-dmg e200rpatcher.dmg - -e200rpatcher-i386: e200rpatcher.c bootimg.c usb.h libusb-i386.a - gcc -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 -framework iokit -framework coreservices -arch i386 $(CFLAGS) -o e200rpatcher-i386 e200rpatcher.c bootimg.c -I. libusb-i386.a - strip e200rpatcher-i386 - -e200rpatcher-ppc: e200rpatcher.c bootimg.c usb.h libusb-ppc.a - gcc -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 -framework iokit -framework coreservices -arch ppc $(CFLAGS) -o e200rpatcher-ppc e200rpatcher.c bootimg.c -I. libusb-ppc.a - strip e200rpatcher-ppc - -bin2c: ../tools/bin2c.c - $(NATIVECC) $(CFLAGS) -o bin2c ../tools/bin2c.c - -bootimg.c: bootloader.bin bin2c - ./bin2c bootloader.bin bootimg - -clean: - rm -f e200rpatcher.exe e200rpatcher-mac e200rpatcher-i386 e200rpatcher-ppc e200rpatcher bin2c bootimg.c bootimg.h *~ e200rpatcher.dmg - rm -rf e200rpatcher-dmg diff --git a/rbutil/e200rpatcher/README b/rbutil/e200rpatcher/README deleted file mode 100644 index 1942b3aa7a..0000000000 --- a/rbutil/e200rpatcher/README +++ /dev/null @@ -1,48 +0,0 @@ -INTRODUCTION - -e200rpatcher is a tool for uploading and executing an application to -an E200R in manufacturing mode. It is intended to be used to upload -the patching application to allow Rockbox installs. - -e200rpatcher requires libusb (v0.1.2 has been tested successfully) for -cross-platform USB access. No-one has yet successfully installed -e200rpatcher on Windows, but it works on Linux and Mac OS X (and -should be fine on other Unix-like systems that libusb supports). - -GENERAL BUILD INSTRUCTIONS - -A pre-requisite for compiling e200rpatcher is a file called -"bootloader.bin" - this is the output of running an "I" (installer) -build for the E200R target. - -In the Rockbox source directory, do: - -mkdir build-e200rbootbin -cd build-e200rbootbin -../tools/configure -[Select E200R, then I for installer] -make - -This should give you a bootloader/bootloader/bin file which you should -copy to the e200rpatcher source directory. - -BUILDING ON LINUX - -The Makefile expects libusb (and the headers) to be installed on your -system and will link dynamically. Just type "make". - -BUILDING ON A MAC - -To build the mac version (target e200rpatcher-mac in the Makefile) -requires three files from libusb to be copied to the current -directory: - -usb.h (copied from your libusb build directory) -libusb-i386.a (copied and renamed from .libs/libusb.a in an i386 build) -libusb-ppc.a (copied and renamed from .libs/libusb.a in a PPC build) - -To build the required libusb.a files, just run ./configure && make for -libusb. If anyone knows how to cross-compile a static libusb.a please -make the information known - this is currently done by compiling -natively on the appropriate hardware. - diff --git a/rbutil/e200rpatcher/e200rpatcher.c b/rbutil/e200rpatcher/e200rpatcher.c deleted file mode 100644 index be09370997..0000000000 --- a/rbutil/e200rpatcher/e200rpatcher.c +++ /dev/null @@ -1,241 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2007 Dave Chapman - * - * USB code based on ifp-line - http://ifp-driver.sourceforge.net - * - * ifp-line is (C) Pavel Kriz, Jun Yamishiro and Joe Roback and - * licensed under the GPL (v2) - * - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - - -#include <stdio.h> -#include <inttypes.h> -#include <usb.h> -#include <string.h> -#include "stdbool.h" - -#include "bootimg.h" - -#define VERSION "0.2" - -/* USB IDs for Manufacturing Mode */ -#define E200R_VENDORID 0x0781 -#define E200R_PRODUCTID 0x0720 - -#define E200R_BULK_TO 1 -#define TOUT 5000 -#define MAX_TRANSFER 64 /* Number of bytes to send in one write */ - -#ifndef MAX -#define MAX(a,b) (((a)>(b))?(a):(b)) -#endif - -static void put_int32le(uint32_t x, char* p) -{ - p[0] = x & 0xff; - p[1] = (x >> 8) & 0xff; - p[2] = (x >> 16) & 0xff; - p[3] = (x >> 24) & 0xff; -} - -int upload_app(usb_dev_handle* dh) -{ - char buf[4]; - int err; - int tosend; - char* p = (char*)bootimg; - int bytesleft = LEN_bootimg; - - /* Write the data length */ - - put_int32le(LEN_bootimg, buf); - - err = usb_bulk_write(dh, E200R_BULK_TO, buf, 4, TOUT); - - if (err < 0) - { - fprintf(stderr,"[ERR] Error writing data length\n"); - fprintf(stderr,"[ERR] Bulk write error (%d, %s)\n", err, strerror(-err)); - return -1; - } - - /* Now send the data, MAX_TRANSFER bytes at a time. */ - - while (bytesleft > 0) - { - tosend = MAX(MAX_TRANSFER, bytesleft); - - err = usb_bulk_write(dh, E200R_BULK_TO, p, tosend, TOUT); - - if (err < 0) - { - fprintf(stderr,"[ERR] Error writing data\n"); - fprintf(stderr,"[ERR] Bulk write error (%d, %s)\n", err, strerror(-err)); - return -1; - } - - p += tosend; - bytesleft -= tosend; - } - - return 0; -} - - -/* The main function */ - -void do_patching(void) -{ - struct usb_bus *busses; - struct usb_bus *bus; - struct usb_device *tmp_dev; - struct usb_device *dev = NULL; - usb_dev_handle *dh; - int err; - - fprintf(stderr,"[INFO] Searching for E200R\n"); - - usb_init(); - - if(usb_find_busses() < 0) { - fprintf(stderr, "[ERR] Could not find any USB busses.\n"); - return; - } - - if (usb_find_devices() < 0) { - fprintf(stderr, "[ERR] USB devices not found(nor hubs!).\n"); - return; - } - - /* C calling convention, it's not nice to use global stuff */ - busses = usb_get_busses(); - - for (bus = busses; bus; bus = bus->next) { - for (tmp_dev = bus->devices; tmp_dev; tmp_dev = tmp_dev->next) { - if (tmp_dev->descriptor.idVendor == E200R_VENDORID && - tmp_dev->descriptor.idProduct == E200R_PRODUCTID ) { - - dev = tmp_dev; - goto found; - - } - } - } - - if (dev == NULL) { - fprintf(stderr, "[ERR] E200R device not found.\n"); - fprintf(stderr, "[ERR] Ensure your E200R is in manufacturing mode and run e200rpatcher again.\n"); - return; - } - -found: - if ( (dh = usb_open(dev)) == NULL) { - fprintf(stderr,"[ERR] Unable to open E200R device.\n"); - return; - } - - err = usb_set_configuration(dh, 1); - - if (err < 0) { - fprintf(stderr, "[ERR] usb_set_configuration failed (%d)\n", err); - usb_close(dh); - return; - } - - /* "must be called" written in the libusb documentation */ - err = usb_claim_interface(dh, dev->config->interface->altsetting->bInterfaceNumber); - if (err < 0) { - fprintf(stderr, "[ERR] Unable to claim interface (%d)\n", err); - usb_close(dh); - return; - } - - fprintf(stderr,"[INFO] Found E200R, uploading patching application.\n"); - - /* Now we can transfer the application to the device. */ - - if (upload_app(dh) < 0) - { - fprintf(stderr,"[ERR] Upload of application failed.\n"); - } - else - { - fprintf(stderr,"[INFO] Patching application uploaded successfully!\n"); - } - - /* release claimed interface */ - usb_release_interface(dh, dev->config->interface->altsetting->bInterfaceNumber); - - usb_close(dh); -} -void print_usage(void) -{ - fprintf(stderr,"Usage: e200rpatcher [options]\n"); - fprintf(stderr,"Options:\n"); - fprintf(stderr," -s, --silent\t\tDont display instructions\n"); -} - -int main(int argc, char* argv[]) -{ - char input[4]; - int silent = 0; - int i; - - /* check args */ - if ((argc > 1) && ((strcmp(argv[1],"-h")==0) || (strcmp(argv[1],"--help")==0))) { - print_usage(); - return 1; - } - for (i=1;i<argc;i++) - { - if (!strcmp(argv[i], "--silent") || !strcmp(argv[i], "-s")) - silent = 1; - } - - printf("e200rpatcher v" VERSION " - (C) 2007 Jonathan Gordon & Dave Chapman\n"); - printf("This is free software; see the source for copying conditions. There is NO\n"); - printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"); - - if (!silent) - { - printf("Attach your E200R in \"manufacturing mode\" as follows:\n"); - printf(" 1) Power-off your E200R\n"); - printf(" 2) Turn ON the lock/hold switch\n"); - printf(" 3) Press and hold the SELECT button and whilst it is held down,\n"); - printf(" attach your E200R to your computer via USB\n"); - printf(" 4) After attaching to USB, keep the SELECT button held for 10 seconds.\n"); - printf("\n"); - printf("NOTE: If your E200R starts in the normal Sansa firmware, you have\n"); - printf(" failed to enter manufacturing mode and should try again at step 1).\n\n"); - - printf("[INFO] Press Enter to continue:"); - fgets(input, 4, stdin); - } - do_patching(); - - if (!silent) - { - printf("[INFO] Press ENTER to exit: "); - fgets(input, 4, stdin); - } - - return 0; -} diff --git a/rbutil/e200rpatcher/e200rpatcher.manifest b/rbutil/e200rpatcher/e200rpatcher.manifest deleted file mode 100644 index ec0c49df33..0000000000 --- a/rbutil/e200rpatcher/e200rpatcher.manifest +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> - <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="e200rpatcher.exe" type="win32"/> - - <!-- Identify the application security requirements. --> - <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> - <security> - <requestedPrivileges> - <requestedExecutionLevel level="requireAdministrator"/> - </requestedPrivileges> - </security> - </trustInfo> -</assembly> diff --git a/rbutil/e200rpatcher/e200rpatcher.rc b/rbutil/e200rpatcher/e200rpatcher.rc deleted file mode 100644 index 4d80442d44..0000000000 --- a/rbutil/e200rpatcher/e200rpatcher.rc +++ /dev/null @@ -1 +0,0 @@ -1 24 MOVEABLE PURE "e200rpatcher.manifest" diff --git a/rbutil/ibassoboot/jni/Android.mk b/rbutil/ibassoboot/jni/Android.mk deleted file mode 100644 index 9cd667c5b9..0000000000 --- a/rbutil/ibassoboot/jni/Android.mk +++ /dev/null @@ -1,14 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE := MangoPlayer -LOCAL_SRC_FILES := ibassodualboot.c qdbmp.c - -TARGET_ARCH=arm -TARGET_PLATFORM=android-14 -TARGET_ARCH_ABI=armeabi - -#LOCAL_CFLAGS := -DDEBUG -#LOCAL_LDLIBS := -llog - -include $(BUILD_EXECUTABLE) diff --git a/rbutil/ibassoboot/jni/chooser.bmp b/rbutil/ibassoboot/jni/chooser.bmp Binary files differdeleted file mode 100644 index 3e6742d600..0000000000 --- a/rbutil/ibassoboot/jni/chooser.bmp +++ /dev/null diff --git a/rbutil/ibassoboot/jni/ibassodualboot.c b/rbutil/ibassoboot/jni/ibassodualboot.c deleted file mode 100644 index 0458ff1b71..0000000000 --- a/rbutil/ibassoboot/jni/ibassodualboot.c +++ /dev/null @@ -1,771 +0,0 @@ -/*************************************************************************** - * __________ __ ___ - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * - * Copyright (C) 2014 by Ilia Sergachev: Initial Rockbox port to iBasso DX50 - * Copyright (C) 2014 by Mario Basister: iBasso DX90 port - * Copyright (C) 2014 by Simon Rothen: Initial Rockbox repository submission, additional features - * Copyright (C) 2014 by Udo Schläpfer: Code clean up, additional features - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - - -#include <dirent.h> -#include <fcntl.h> -#include <pthread.h> -#include <stdbool.h> -#include <stdlib.h> -#include <unistd.h> -#include <linux/fb.h> -#include <linux/input.h> -#include <sys/mman.h> -#include <sys/poll.h> -#include <sys/reboot.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/wait.h> - -#include "qdbmp.h" - - -/*- Android logcat ------------------------------------------------------------------------------*/ - - -#ifdef DEBUG -#include <android/log.h> - - -static const char log_tag[] = "Rockbox Boot"; - - -void debugf(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - __android_log_vprint(ANDROID_LOG_DEBUG, log_tag, fmt, ap); - va_end(ap); -} - - -void ldebugf(const char* file, int line, const char *fmt, ...) -{ - va_list ap; - /* 13: 5 literal chars and 8 chars for the line number. */ - char buf[strlen(file) + strlen(fmt) + 13]; - snprintf(buf, sizeof(buf), "%s (%d): %s", file, line, fmt); - va_start(ap, fmt); - __android_log_vprint(ANDROID_LOG_DEBUG, log_tag, buf, ap); - va_end(ap); -} - - -void debug_trace(const char* function) -{ - static const char trace_tag[] = "TRACE: "; - char msg[strlen(trace_tag) + strlen(function) + 1]; - snprintf(msg, sizeof(msg), "%s%s", trace_tag, function); - __android_log_write(ANDROID_LOG_DEBUG, log_tag, msg); -} - - -#define DEBUGF debugf -#define TRACE debug_trace(__func__) -#else -#define DEBUGF(...) -#define TRACE -#endif /* DEBUG */ - - -/*- Vold monitor --------------------------------------------------------------------------------*/ - - -/* - Without this socket iBasso Vold will not start. - iBasso Vold uses this to send status messages about storage devices. -*/ -static const char VOLD_MONITOR_SOCKET_NAME[] = "UNIX_domain"; -static int _vold_monitor_socket_fd = -1; - - -static void vold_monitor_open_socket(void) -{ - TRACE; - - unlink(VOLD_MONITOR_SOCKET_NAME); - - _vold_monitor_socket_fd = socket(AF_UNIX, SOCK_STREAM, 0); - - if(_vold_monitor_socket_fd < 0) - { - _vold_monitor_socket_fd = -1; - return; - } - - struct sockaddr_un addr; - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, VOLD_MONITOR_SOCKET_NAME, sizeof(addr.sun_path) - 1); - - if(bind(_vold_monitor_socket_fd, (struct sockaddr*) &addr, sizeof(addr)) < 0) - { - close(_vold_monitor_socket_fd); - unlink(VOLD_MONITOR_SOCKET_NAME); - _vold_monitor_socket_fd = -1; - return; - } - - if(listen(_vold_monitor_socket_fd, 1) < 0) - { - close(_vold_monitor_socket_fd); - unlink(VOLD_MONITOR_SOCKET_NAME); - _vold_monitor_socket_fd = -1; - return; - } -} - - -/* - bionic does not have pthread_cancel. - 0: Vold monitor thread stopped/ending. - 1: Vold monitor thread started/running. -*/ -static volatile sig_atomic_t _vold_monitor_active = 0; - - -/* true: sdcard not mounted. */ -static bool _sdcard_not_mounted = true; - - -/* Mutex for sdcard mounted flag. */ -static pthread_mutex_t _sdcard_mount_mtx = PTHREAD_MUTEX_INITIALIZER; - - -/* Signal condition for sdcard mounted flag. */ -static pthread_cond_t _sdcard_mount_cond = PTHREAD_COND_INITIALIZER; - - -static void* vold_monitor_run(void* nothing) -{ - _vold_monitor_active = 1; - - (void) nothing; - - DEBUGF("DEBUG %s: Thread start.", __func__); - - vold_monitor_open_socket(); - if(_vold_monitor_socket_fd < 0) - { - DEBUGF("ERROR %s: Thread end: No socket.", __func__); - - _vold_monitor_active = 0; - return 0; - } - - struct pollfd fds[1]; - fds[0].fd = _vold_monitor_socket_fd; - fds[0].events = POLLIN; - - while(_vold_monitor_active == 1) - { - poll(fds, 1, 10); - if(! (fds[0].revents & POLLIN)) - { - continue; - } - - int socket_fd = accept(_vold_monitor_socket_fd, NULL, NULL); - - if(socket_fd < 0) - { - DEBUGF("ERROR %s: accept failed.", __func__); - - continue; - } - - while(true) - { - char msg[1024]; - memset(msg, 0, sizeof(msg)); - int length = read(socket_fd, msg, sizeof(msg)); - - if(length <= 0) - { - close(socket_fd); - break; - } - - DEBUGF("DEBUG %s: msg: %s", __func__, msg); - - if(strcmp(msg, "Volume flash /mnt/sdcard state changed from 3 (Checking) to 4 (Mounted)") == 0) - { - pthread_mutex_lock(&_sdcard_mount_mtx); - _sdcard_not_mounted = false; - pthread_cond_signal(&_sdcard_mount_cond); - pthread_mutex_unlock(&_sdcard_mount_mtx); - } - } - } - - close(_vold_monitor_socket_fd); - unlink(VOLD_MONITOR_SOCKET_NAME); - _vold_monitor_socket_fd = -1; - - DEBUGF("DEBUG %s: Thread end.", __func__); - - _vold_monitor_active = 0; - return 0; -} - - -/* Vold monitor thread. */ -static pthread_t _vold_monitor_thread; - - -static void vold_monitor_start(void) -{ - TRACE; - - if(_vold_monitor_active == 0) - { - pthread_create(&_vold_monitor_thread, NULL, vold_monitor_run, NULL); - } -} - - -static void vold_monitor_stop(void) -{ - TRACE; - - if(_vold_monitor_active == 1) - { - _vold_monitor_active = 0; - int ret = pthread_join(_vold_monitor_thread, NULL); - DEBUGF("DEBUG %s: Thread joined: ret: %d.", __func__, ret); - } -} - - -/*- Input handler -------------------------------------------------------------------------------*/ - - -/* Input devices monitored with poll API. */ -static struct pollfd* _fds = NULL; - - -/* Number of input devices monitored with poll API. */ -static nfds_t _nfds = 0; - - -/* The names of the devices in _fds. */ -static char** _device_names = NULL; - - -/* Open device device_name and add it to the list of polled devices. */ -static void open_device(const char* device_name) -{ - int fd = open(device_name, O_RDONLY); - if(fd == -1) - { - DEBUGF("ERROR %s: open failed on %s.", __func__, device_name); - exit(-1); - } - - struct pollfd* new_fds = realloc(_fds, sizeof(struct pollfd) * (_nfds + 1)); - if(new_fds == NULL) - { - DEBUGF("ERROR %s: realloc for _fds failed.", __func__); - exit(-1); - } - - _fds = new_fds; - _fds[_nfds].fd = fd; - _fds[_nfds].events = POLLIN; - - char** new_device_names = realloc(_device_names, sizeof(char*) * (_nfds + 1)); - if(new_device_names == NULL) - { - DEBUGF("ERROR %s: realloc for _device_names failed.", __func__); - exit(-1); - } - - _device_names = new_device_names; - _device_names[_nfds] = strdup(device_name); - if(_device_names[_nfds] == NULL) - { - DEBUGF("ERROR %s: strdup failed.", __func__); - exit(-1); - } - - ++_nfds; - - DEBUGF("DEBUG %s: Opened device %s.", __func__, device_name); -} - - -static void button_init_device(void) -{ - TRACE; - - if((_fds != NULL) || (_nfds != 0) || (_device_names != NULL)) - { - DEBUGF("ERROR %s: Allready initialized.", __func__); - return; - } - - /* The input device directory. */ - static const char device_path[] = "/dev/input"; - - /* Path delimeter. */ - static const char delimeter[] = "/"; - - /* Open all devices in device_path. */ - DIR* dir = opendir(device_path); - if(dir == NULL) - { - DEBUGF("ERROR %s: opendir failed: errno: %d.", __func__, errno); - exit(errno); - } - - char device_name[PATH_MAX]; - strcpy(device_name, device_path); - strcat(device_name, delimeter); - char* device_name_idx = device_name + strlen(device_name); - - struct dirent* dir_entry; - while((dir_entry = readdir(dir))) - { - if( ((dir_entry->d_name[0] == '.') && (dir_entry->d_name[1] == '\0')) - || ((dir_entry->d_name[0] == '.') && (dir_entry->d_name[1] == '.') && (dir_entry->d_name[2] == '\0'))) - { - continue; - } - - strcpy(device_name_idx, dir_entry->d_name); - - /* Open and add device to _fds. */ - open_device(device_name); - } - - closedir(dir); - - /* Sanity check. */ - if(_nfds < 2) - { - DEBUGF("ERROR %s: No input devices.", __func__); - exit(-1); - } -} - - -#define EVENT_TYPE_BUTTON 1 - - -#define EVENT_CODE_BUTTON_PWR_LONG 117 -#define EVENT_CODE_BUTTON_REV 160 -#define EVENT_CODE_BUTTON_NEXT 162 - - -#define EVENT_TYPE_TOUCHSCREEN 3 - - -#define EVENT_CODE_TOUCHSCREEN_X 53 - - -enum user_choice -{ - CHOICE_NONE = -1, - CHOICE_MANGO, - CHOICE_ROCKBOX, - CHOICE_POWEROFF -}; - - -static int get_user_choice(void) -{ - TRACE; - - button_init_device(); - - enum user_choice choice = CHOICE_NONE; - - while(choice == CHOICE_NONE) - { - /* Poll all input devices. */ - poll(_fds, _nfds, 0); - - nfds_t fds_idx = 0; - for( ; fds_idx < _nfds; ++fds_idx) - { - if(! (_fds[fds_idx].revents & POLLIN)) - { - continue; - } - - struct input_event event; - if(read(_fds[fds_idx].fd, &event, sizeof(event)) < (int) sizeof(event)) - { - DEBUGF("ERROR %s: Read of input devices failed.", __func__); - continue; - } - - DEBUGF("DEBUG %s: device: %s, event.type: %d, event.code: %d, event.value: %d", __func__, _device_names[fds_idx], event.type, event.code, event.value); - - if(event.type == EVENT_TYPE_BUTTON) - { - switch(event.code) - { - case EVENT_CODE_BUTTON_REV: - { - choice = CHOICE_MANGO; - break; - } - - case EVENT_CODE_BUTTON_NEXT: - { - choice = CHOICE_ROCKBOX; - break; - } - - case EVENT_CODE_BUTTON_PWR_LONG: - { - choice = CHOICE_POWEROFF; - break; - } - } - } - else if((event.type == EVENT_TYPE_TOUCHSCREEN) && (event.code == EVENT_CODE_TOUCHSCREEN_X)) - { - if(event.value < 160) - { - choice = CHOICE_MANGO; - } - else - { - choice = CHOICE_ROCKBOX; - } - } - } - } - - if(_fds) - { - nfds_t fds_idx = 0; - for( ; fds_idx < _nfds; ++fds_idx) - { - close(_fds[fds_idx].fd); - } - free(_fds); - _fds = NULL; - } - - if(_device_names) - { - nfds_t fds_idx = 0; - for( ; fds_idx < _nfds; ++fds_idx) - { - free(_device_names[fds_idx]); - } - free(_device_names); - _device_names = NULL; - } - - _nfds = 0; - - return choice; -} - - -/* - Changing bit, when hold switch is toggled. - Bit is off when hold switch is engaged. -*/ -#define HOLD_SWITCH_BIT 16 - - -static bool check_for_hold(void) -{ - TRACE; - - char hold_state; - - FILE* f = fopen("/sys/class/axppower/holdkey", "r"); - fscanf(f, "%c", &hold_state); - fclose(f); - - return(! (hold_state & HOLD_SWITCH_BIT)); -} - - -/*- Display -------------------------------------------------------------------------------------*/ - - -static void draw(const char* file) -{ - DEBUGF("DEBUG %s: file: %s.", __func__, file); - - int dev_fd = open("/dev/graphics/fb0", O_RDWR); - if(dev_fd == -1) - { - DEBUGF("ERROR %s: open failed on /dev/graphics/fb0, errno: %d.", __func__, errno); - exit(errno); - } - - /* Get fixed screen information. */ - struct fb_fix_screeninfo finfo; - if(ioctl(dev_fd, FBIOGET_FSCREENINFO, &finfo) < 0) - { - DEBUGF("ERROR %s: ioctl FBIOGET_FSCREENINFO failed on /dev/graphics/fb0, errno: %d.", __func__, errno); - exit(errno); - } - - /* Get the changeable information. */ - struct fb_var_screeninfo vinfo; - if(ioctl(dev_fd, FBIOGET_VSCREENINFO, &vinfo) < 0) - { - DEBUGF("ERROR %s: ioctl FBIOGET_VSCREENINFO failed on /dev/graphics/fb0, errno: %d.", __func__, errno); - exit(errno); - } - - DEBUGF("DEBUG %s: bits_per_pixel: %u, width: %u, height: %u.", __func__, vinfo.bits_per_pixel, vinfo.width, vinfo.height); - - size_t screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8; - - /* ToDo: Is this needed? */ - vinfo.xres = 320; - vinfo.xres_virtual = 320; - vinfo.width = 320; - vinfo.yres = 240; - vinfo.yres_virtual = 240; - vinfo.height = 240; - vinfo.xoffset = 0; - vinfo.yoffset = 0; - vinfo.sync = 0; - vinfo.vmode = 0; - vinfo.pixclock = 104377; - vinfo.left_margin = 20; - vinfo.right_margin = 50; - vinfo.upper_margin = 2; - vinfo.lower_margin = 4; - vinfo.hsync_len = 10; - vinfo.vsync_len = 2; - vinfo.red.offset = 11; - vinfo.red.length = 5; - vinfo.red.msb_right = 0; - vinfo.green.offset = 5; - vinfo.green.length = 6; - vinfo.green.msb_right = 0; - vinfo.blue.offset = 0; - vinfo.blue.length = 5; - vinfo.blue.msb_right = 0; - vinfo.transp.offset = 0; - vinfo.transp.length = 0; - vinfo.transp.msb_right = 0; - vinfo.nonstd = 4; - if(ioctl(dev_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0) - { - DEBUGF("ERROR %s: ioctl FBIOPUT_VSCREENINFO failed on /dev/graphics/fb0, errno: %d.", __func__, errno); - exit(errno); - } - - /* Map the device to memory. */ - char* dev_fb = (char*) mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, 0); - if(dev_fb == MAP_FAILED) - { - DEBUGF("ERROR %s: mmap failed on /dev/graphics/fb0, errno: %d.", __func__, errno); - exit(errno); - } - - BMP* bmp = BMP_ReadFile(file); - if(BMP_GetError() != BMP_OK ) - { - DEBUGF("ERROR %s: BMP_ReadFile failed on %s: %d.", __func__, file, BMP_GetError()); - exit(BMP_GetError()); - } - - int y = 0; - for( ; y < 240; ++y) - { - int x = 0; - for( ; x < 320; ++x) - { - long int position = (x + vinfo.xoffset) * (vinfo.bits_per_pixel / 8 ) - + (y + vinfo.yoffset) * finfo.line_length; - UCHAR r, g, b; - BMP_GetPixelRGB(bmp, x, y, &r, &g, &b); - unsigned short int pixel = (r >> 3) << 11 | (g >> 2) << 5 | (b >> 3); - *((unsigned short int*)(dev_fb + position)) = pixel; - } - } - - BMP_Free(bmp); - munmap(dev_fb, screensize); - close(dev_fd); -} - - -/*-----------------------------------------------------------------------------------------------*/ - - -static const char ROCKBOX_BIN[] = "/mnt/sdcard/.rockbox/rockbox"; -static const char OF_PLAYER_BIN[] = "/system/bin/MangoPlayer_original"; -static const char PLAYER_FILE[] = "/data/chosen_player"; - - -int main(int argc, char **argv) -{ - TRACE; - - /* - Create the iBasso Vold socket and monitor it. - Do this early to not block Vold. - */ - vold_monitor_start(); - - int last_chosen_player = CHOICE_NONE; - - FILE* f = fopen(PLAYER_FILE, "r"); - if(f != NULL) - { - fscanf(f, "%d", &last_chosen_player); - fclose(f); - } - - DEBUGF("DEBUG %s: Current player choice: %d.", __func__, last_chosen_player); - - if(check_for_hold() || (last_chosen_player == CHOICE_NONE)) - { - draw("/system/chooser.bmp"); - - enum user_choice choice = get_user_choice(); - - if(choice == CHOICE_POWEROFF) - { - reboot(RB_POWER_OFF); - while(true) - { - sleep(1); - } - } - - if(choice != last_chosen_player) - { - last_chosen_player = choice; - - f = fopen(PLAYER_FILE, "w"); - fprintf(f, "%d", last_chosen_player); - fclose(f); - } - - DEBUGF("DEBUG %s: New player choice: %d.", __func__, last_chosen_player); - } - - /* true, Rockbox was started at least once. */ - bool rockboxStarted = false; - - while(true) - { - /* Excecute OF MangoPlayer or Rockbox and restart it if it crashes. */ - - if(last_chosen_player == CHOICE_ROCKBOX) - { - if(rockboxStarted) - { - /* - At this point it is assumed, that Rockbox has exited due to a USB connection - triggering a remount of the internal storage for mass storage access. - Rockbox will eventually restart, when /mnt/sdcard becomes available again. - */ - draw("/system/usb.bmp"); - } - - pthread_mutex_lock(&_sdcard_mount_mtx); - while(_sdcard_not_mounted) - { - DEBUGF("DEBUG %s: Waiting on /mnt/sdcard/.", __func__); - - pthread_cond_wait(&_sdcard_mount_cond, &_sdcard_mount_mtx); - - DEBUGF("DEBUG %s: /mnt/sdcard/ available.", __func__); - } - pthread_mutex_unlock(&_sdcard_mount_mtx); - - /* To be able to execute rockbox. */ - system("mount -o remount,exec /mnt/sdcard"); - - /* This symlink is needed mainly to keep themes functional. */ - system("ln -s /mnt/sdcard/.rockbox /.rockbox"); - - if(access(ROCKBOX_BIN, X_OK) != -1) - { - /* Start Rockbox. */ - - /* Rockbox has its own vold monitor. */ - vold_monitor_stop(); - - DEBUGF("DEBUG %s: Excecuting %s.", __func__, ROCKBOX_BIN); - - int ret_code = system(ROCKBOX_BIN); - rockboxStarted = true; - - DEBUGF("DEBUG %s: ret_code: %d.", __func__, ret_code); - - if(WIFEXITED(ret_code) && (WEXITSTATUS(ret_code) == 42)) - { - /* - Rockbox terminated to prevent a froced shutdown due to a USB connection - triggering a remount of the internal storage for mass storage access. - */ - _sdcard_not_mounted = true; - } - /* else Rockbox crashed ... */ - - vold_monitor_start(); - } - else - { - /* Rockbox executable missing. Show info screen for 30 seconds. */ - draw("/system/rbmissing.bmp"); - sleep(30); - - /* Do not block Vold, so stop after sleep. */ - vold_monitor_stop(); - -#ifdef DEBUG - system("setprop persist.sys.usb.config adb"); - system("setprop persist.usb.debug 1"); -#endif - - DEBUGF("DEBUG %s: Rockbox missing, excecuting %s.", __func__, OF_PLAYER_BIN); - - /* Start OF MangoPlayer. */ - int ret_code = system(OF_PLAYER_BIN); - - DEBUGF("DEBUG %s: ret_code: %d.", __func__, ret_code); - } - } - else /* if(last_chosen_player == CHOICE_MANGO) */ - { - vold_monitor_stop(); - - DEBUGF("DEBUG %s: Excecuting %s.", __func__, OF_PLAYER_BIN); - - int ret_code = system(OF_PLAYER_BIN); - - DEBUGF("DEBUG %s: ret_code: %d.", __func__, ret_code); - } - } - - return 0; -} diff --git a/rbutil/ibassoboot/jni/qdbmp.c b/rbutil/ibassoboot/jni/qdbmp.c deleted file mode 100644 index fd1337277d..0000000000 --- a/rbutil/ibassoboot/jni/qdbmp.c +++ /dev/null @@ -1,798 +0,0 @@ -#include "qdbmp.h" -#include <stdlib.h> -#include <string.h> - - -/* Bitmap header */ -typedef struct _BMP_Header -{ - USHORT Magic; /* Magic identifier: "BM" */ - UINT FileSize; /* Size of the BMP file in bytes */ - USHORT Reserved1; /* Reserved */ - USHORT Reserved2; /* Reserved */ - UINT DataOffset; /* Offset of image data relative to the file's start */ - UINT HeaderSize; /* Size of the header in bytes */ - UINT Width; /* Bitmap's width */ - UINT Height; /* Bitmap's height */ - USHORT Planes; /* Number of color planes in the bitmap */ - USHORT BitsPerPixel; /* Number of bits per pixel */ - UINT CompressionType; /* Compression type */ - UINT ImageDataSize; /* Size of uncompressed image's data */ - UINT HPixelsPerMeter; /* Horizontal resolution (pixels per meter) */ - UINT VPixelsPerMeter; /* Vertical resolution (pixels per meter) */ - UINT ColorsUsed; /* Number of color indexes in the color table that are actually used by the bitmap */ - UINT ColorsRequired; /* Number of color indexes that are required for displaying the bitmap */ -} BMP_Header; - - -/* Private data structure */ -struct _BMP -{ - BMP_Header Header; - UCHAR* Palette; - UCHAR* Data; -}; - - -/* Holds the last error code */ -static BMP_STATUS BMP_LAST_ERROR_CODE = 0; - - -/* Error description strings */ -static const char* BMP_ERROR_STRING[] = -{ - "", - "General error", - "Could not allocate enough memory to complete the operation", - "File input/output error", - "File not found", - "File is not a supported BMP variant (must be uncompressed 8, 24 or 32 BPP)", - "File is not a valid BMP image", - "An argument is invalid or out of range", - "The requested action is not compatible with the BMP's type" -}; - - -/* Size of the palette data for 8 BPP bitmaps */ -#define BMP_PALETTE_SIZE ( 256 * 4 ) - - - -/*********************************** Forward declarations **********************************/ -int ReadHeader ( BMP* bmp, FILE* f ); -int WriteHeader ( BMP* bmp, FILE* f ); - -int ReadUINT ( UINT* x, FILE* f ); -int ReadUSHORT ( USHORT *x, FILE* f ); - -int WriteUINT ( UINT x, FILE* f ); -int WriteUSHORT ( USHORT x, FILE* f ); - - - - - - -/*********************************** Public methods **********************************/ - - -/************************************************************** - Creates a blank BMP image with the specified dimensions - and bit depth. -**************************************************************/ -BMP* BMP_Create( UINT width, UINT height, USHORT depth ) -{ - BMP* bmp; - int bytes_per_pixel = depth >> 3; - UINT bytes_per_row; - - if ( height <= 0 || width <= 0 ) - { - BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT; - return NULL; - } - - if ( depth != 8 && depth != 24 && depth != 32 ) - { - BMP_LAST_ERROR_CODE = BMP_FILE_NOT_SUPPORTED; - return NULL; - } - - - /* Allocate the bitmap data structure */ - bmp = calloc( 1, sizeof( BMP ) ); - if ( bmp == NULL ) - { - BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY; - return NULL; - } - - - /* Set header' default values */ - bmp->Header.Magic = 0x4D42; - bmp->Header.Reserved1 = 0; - bmp->Header.Reserved2 = 0; - bmp->Header.HeaderSize = 40; - bmp->Header.Planes = 1; - bmp->Header.CompressionType = 0; - bmp->Header.HPixelsPerMeter = 0; - bmp->Header.VPixelsPerMeter = 0; - bmp->Header.ColorsUsed = 0; - bmp->Header.ColorsRequired = 0; - - - /* Calculate the number of bytes used to store a single image row. This is always - rounded up to the next multiple of 4. */ - bytes_per_row = width * bytes_per_pixel; - bytes_per_row += ( bytes_per_row % 4 ? 4 - bytes_per_row % 4 : 0 ); - - - /* Set header's image specific values */ - bmp->Header.Width = width; - bmp->Header.Height = height; - bmp->Header.BitsPerPixel = depth; - bmp->Header.ImageDataSize = bytes_per_row * height; - bmp->Header.FileSize = bmp->Header.ImageDataSize + 54 + ( depth == 8 ? BMP_PALETTE_SIZE : 0 ); - bmp->Header.DataOffset = 54 + ( depth == 8 ? BMP_PALETTE_SIZE : 0 ); - - - /* Allocate palette */ - if ( bmp->Header.BitsPerPixel == 8 ) - { - bmp->Palette = (UCHAR*) calloc( BMP_PALETTE_SIZE, sizeof( UCHAR ) ); - if ( bmp->Palette == NULL ) - { - BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY; - free( bmp ); - return NULL; - } - } - else - { - bmp->Palette = NULL; - } - - - /* Allocate pixels */ - bmp->Data = (UCHAR*) calloc( bmp->Header.ImageDataSize, sizeof( UCHAR ) ); - if ( bmp->Data == NULL ) - { - BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY; - free( bmp->Palette ); - free( bmp ); - return NULL; - } - - - BMP_LAST_ERROR_CODE = BMP_OK; - - return bmp; -} - - -/************************************************************** - Frees all the memory used by the specified BMP image. -**************************************************************/ -void BMP_Free( BMP* bmp ) -{ - if ( bmp == NULL ) - { - return; - } - - if ( bmp->Palette != NULL ) - { - free( bmp->Palette ); - } - - if ( bmp->Data != NULL ) - { - free( bmp->Data ); - } - - free( bmp ); - - BMP_LAST_ERROR_CODE = BMP_OK; -} - - -/************************************************************** - Reads the specified BMP image file. -**************************************************************/ -BMP* BMP_ReadFile( const char* filename ) -{ - BMP* bmp; - FILE* f; - - if ( filename == NULL ) - { - BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT; - return NULL; - } - - - /* Allocate */ - bmp = calloc( 1, sizeof( BMP ) ); - if ( bmp == NULL ) - { - BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY; - return NULL; - } - - - /* Open file */ - f = fopen( filename, "rb" ); - if ( f == NULL ) - { - BMP_LAST_ERROR_CODE = BMP_FILE_NOT_FOUND; - free( bmp ); - return NULL; - } - - - /* Read header */ - if ( ReadHeader( bmp, f ) != BMP_OK || bmp->Header.Magic != 0x4D42 ) - { - BMP_LAST_ERROR_CODE = BMP_FILE_INVALID; - fclose( f ); - free( bmp ); - return NULL; - } - - - /* Verify that the bitmap variant is supported */ - if ( ( bmp->Header.BitsPerPixel != 32 && bmp->Header.BitsPerPixel != 24 && bmp->Header.BitsPerPixel != 8 ) - || bmp->Header.CompressionType != 0 || bmp->Header.HeaderSize != 40 ) - { - BMP_LAST_ERROR_CODE = BMP_FILE_NOT_SUPPORTED; - fclose( f ); - free( bmp ); - return NULL; - } - - - /* Allocate and read palette */ - if ( bmp->Header.BitsPerPixel == 8 ) - { - bmp->Palette = (UCHAR*) malloc( BMP_PALETTE_SIZE * sizeof( UCHAR ) ); - if ( bmp->Palette == NULL ) - { - BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY; - fclose( f ); - free( bmp ); - return NULL; - } - - if ( fread( bmp->Palette, sizeof( UCHAR ), BMP_PALETTE_SIZE, f ) != BMP_PALETTE_SIZE ) - { - BMP_LAST_ERROR_CODE = BMP_FILE_INVALID; - fclose( f ); - free( bmp->Palette ); - free( bmp ); - return NULL; - } - } - else /* Not an indexed image */ - { - bmp->Palette = NULL; - } - - - /* Allocate memory for image data */ - bmp->Data = (UCHAR*) malloc( bmp->Header.ImageDataSize ); - if ( bmp->Data == NULL ) - { - BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY; - fclose( f ); - free( bmp->Palette ); - free( bmp ); - return NULL; - } - - - /* Read image data */ - if ( fread( bmp->Data, sizeof( UCHAR ), bmp->Header.ImageDataSize, f ) != bmp->Header.ImageDataSize ) - { - BMP_LAST_ERROR_CODE = BMP_FILE_INVALID; - fclose( f ); - free( bmp->Data ); - free( bmp->Palette ); - free( bmp ); - return NULL; - } - - - fclose( f ); - - BMP_LAST_ERROR_CODE = BMP_OK; - - return bmp; -} - - -/************************************************************** - Writes the BMP image to the specified file. -**************************************************************/ -void BMP_WriteFile( BMP* bmp, const char* filename ) -{ - FILE* f; - - if ( filename == NULL ) - { - BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT; - return; - } - - - /* Open file */ - f = fopen( filename, "wb" ); - if ( f == NULL ) - { - BMP_LAST_ERROR_CODE = BMP_FILE_NOT_FOUND; - return; - } - - - /* Write header */ - if ( WriteHeader( bmp, f ) != BMP_OK ) - { - BMP_LAST_ERROR_CODE = BMP_IO_ERROR; - fclose( f ); - return; - } - - - /* Write palette */ - if ( bmp->Palette ) - { - if ( fwrite( bmp->Palette, sizeof( UCHAR ), BMP_PALETTE_SIZE, f ) != BMP_PALETTE_SIZE ) - { - BMP_LAST_ERROR_CODE = BMP_IO_ERROR; - fclose( f ); - return; - } - } - - - /* Write data */ - if ( fwrite( bmp->Data, sizeof( UCHAR ), bmp->Header.ImageDataSize, f ) != bmp->Header.ImageDataSize ) - { - BMP_LAST_ERROR_CODE = BMP_IO_ERROR; - fclose( f ); - return; - } - - - BMP_LAST_ERROR_CODE = BMP_OK; - fclose( f ); -} - - -/************************************************************** - Returns the image's width. -**************************************************************/ -UINT BMP_GetWidth( BMP* bmp ) -{ - if ( bmp == NULL ) - { - BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT; - return -1; - } - - BMP_LAST_ERROR_CODE = BMP_OK; - - return ( bmp->Header.Width ); -} - - -/************************************************************** - Returns the image's height. -**************************************************************/ -UINT BMP_GetHeight( BMP* bmp ) -{ - if ( bmp == NULL ) - { - BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT; - return -1; - } - - BMP_LAST_ERROR_CODE = BMP_OK; - - return ( bmp->Header.Height ); -} - - -/************************************************************** - Returns the image's color depth (bits per pixel). -**************************************************************/ -USHORT BMP_GetDepth( BMP* bmp ) -{ - if ( bmp == NULL ) - { - BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT; - return -1; - } - - BMP_LAST_ERROR_CODE = BMP_OK; - - return ( bmp->Header.BitsPerPixel ); -} - - -/************************************************************** - Populates the arguments with the specified pixel's RGB - values. -**************************************************************/ -void BMP_GetPixelRGB( BMP* bmp, UINT x, UINT y, UCHAR* r, UCHAR* g, UCHAR* b ) -{ - UCHAR* pixel; - UINT bytes_per_row; - UCHAR bytes_per_pixel; - - if ( bmp == NULL || x < 0 || x >= bmp->Header.Width || y < 0 || y >= bmp->Header.Height ) - { - BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT; - } - else - { - BMP_LAST_ERROR_CODE = BMP_OK; - - bytes_per_pixel = bmp->Header.BitsPerPixel >> 3; - - /* Row's size is rounded up to the next multiple of 4 bytes */ - bytes_per_row = bmp->Header.ImageDataSize / bmp->Header.Height; - - /* Calculate the location of the relevant pixel (rows are flipped) */ - pixel = bmp->Data + ( ( bmp->Header.Height - y - 1 ) * bytes_per_row + x * bytes_per_pixel ); - - - /* In indexed color mode the pixel's value is an index within the palette */ - if ( bmp->Header.BitsPerPixel == 8 ) - { - pixel = bmp->Palette + *pixel * 4; - } - - /* Note: colors are stored in BGR order */ - if ( r ) *r = *( pixel + 2 ); - if ( g ) *g = *( pixel + 1 ); - if ( b ) *b = *( pixel + 0 ); - } -} - - -/************************************************************** - Sets the specified pixel's RGB values. -**************************************************************/ -void BMP_SetPixelRGB( BMP* bmp, UINT x, UINT y, UCHAR r, UCHAR g, UCHAR b ) -{ - UCHAR* pixel; - UINT bytes_per_row; - UCHAR bytes_per_pixel; - - if ( bmp == NULL || x < 0 || x >= bmp->Header.Width || y < 0 || y >= bmp->Header.Height ) - { - BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT; - } - - else if ( bmp->Header.BitsPerPixel != 24 && bmp->Header.BitsPerPixel != 32 ) - { - BMP_LAST_ERROR_CODE = BMP_TYPE_MISMATCH; - } - - else - { - BMP_LAST_ERROR_CODE = BMP_OK; - - bytes_per_pixel = bmp->Header.BitsPerPixel >> 3; - - /* Row's size is rounded up to the next multiple of 4 bytes */ - bytes_per_row = bmp->Header.ImageDataSize / bmp->Header.Height; - - /* Calculate the location of the relevant pixel (rows are flipped) */ - pixel = bmp->Data + ( ( bmp->Header.Height - y - 1 ) * bytes_per_row + x * bytes_per_pixel ); - - /* Note: colors are stored in BGR order */ - *( pixel + 2 ) = r; - *( pixel + 1 ) = g; - *( pixel + 0 ) = b; - } -} - - -/************************************************************** - Gets the specified pixel's color index. -**************************************************************/ -void BMP_GetPixelIndex( BMP* bmp, UINT x, UINT y, UCHAR* val ) -{ - UCHAR* pixel; - UINT bytes_per_row; - - if ( bmp == NULL || x < 0 || x >= bmp->Header.Width || y < 0 || y >= bmp->Header.Height ) - { - BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT; - } - - else if ( bmp->Header.BitsPerPixel != 8 ) - { - BMP_LAST_ERROR_CODE = BMP_TYPE_MISMATCH; - } - - else - { - BMP_LAST_ERROR_CODE = BMP_OK; - - /* Row's size is rounded up to the next multiple of 4 bytes */ - bytes_per_row = bmp->Header.ImageDataSize / bmp->Header.Height; - - /* Calculate the location of the relevant pixel */ - pixel = bmp->Data + ( ( bmp->Header.Height - y - 1 ) * bytes_per_row + x ); - - - if ( val ) *val = *pixel; - } -} - - -/************************************************************** - Sets the specified pixel's color index. -**************************************************************/ -void BMP_SetPixelIndex( BMP* bmp, UINT x, UINT y, UCHAR val ) -{ - UCHAR* pixel; - UINT bytes_per_row; - - if ( bmp == NULL || x < 0 || x >= bmp->Header.Width || y < 0 || y >= bmp->Header.Height ) - { - BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT; - } - - else if ( bmp->Header.BitsPerPixel != 8 ) - { - BMP_LAST_ERROR_CODE = BMP_TYPE_MISMATCH; - } - - else - { - BMP_LAST_ERROR_CODE = BMP_OK; - - /* Row's size is rounded up to the next multiple of 4 bytes */ - bytes_per_row = bmp->Header.ImageDataSize / bmp->Header.Height; - - /* Calculate the location of the relevant pixel */ - pixel = bmp->Data + ( ( bmp->Header.Height - y - 1 ) * bytes_per_row + x ); - - *pixel = val; - } -} - - -/************************************************************** - Gets the color value for the specified palette index. -**************************************************************/ -void BMP_GetPaletteColor( BMP* bmp, UCHAR index, UCHAR* r, UCHAR* g, UCHAR* b ) -{ - if ( bmp == NULL ) - { - BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT; - } - - else if ( bmp->Header.BitsPerPixel != 8 ) - { - BMP_LAST_ERROR_CODE = BMP_TYPE_MISMATCH; - } - - else - { - if ( r ) *r = *( bmp->Palette + index * 4 + 2 ); - if ( g ) *g = *( bmp->Palette + index * 4 + 1 ); - if ( b ) *b = *( bmp->Palette + index * 4 + 0 ); - - BMP_LAST_ERROR_CODE = BMP_OK; - } -} - - -/************************************************************** - Sets the color value for the specified palette index. -**************************************************************/ -void BMP_SetPaletteColor( BMP* bmp, UCHAR index, UCHAR r, UCHAR g, UCHAR b ) -{ - if ( bmp == NULL ) - { - BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT; - } - - else if ( bmp->Header.BitsPerPixel != 8 ) - { - BMP_LAST_ERROR_CODE = BMP_TYPE_MISMATCH; - } - - else - { - *( bmp->Palette + index * 4 + 2 ) = r; - *( bmp->Palette + index * 4 + 1 ) = g; - *( bmp->Palette + index * 4 + 0 ) = b; - - BMP_LAST_ERROR_CODE = BMP_OK; - } -} - - -/************************************************************** - Returns the last error code. -**************************************************************/ -BMP_STATUS BMP_GetError() -{ - return BMP_LAST_ERROR_CODE; -} - - -/************************************************************** - Returns a description of the last error code. -**************************************************************/ -const char* BMP_GetErrorDescription() -{ - if ( BMP_LAST_ERROR_CODE > 0 && BMP_LAST_ERROR_CODE < BMP_ERROR_NUM ) - { - return BMP_ERROR_STRING[ BMP_LAST_ERROR_CODE ]; - } - else - { - return NULL; - } -} - - - - - -/*********************************** Private methods **********************************/ - - -/************************************************************** - Reads the BMP file's header into the data structure. - Returns BMP_OK on success. -**************************************************************/ -int ReadHeader( BMP* bmp, FILE* f ) -{ - if ( bmp == NULL || f == NULL ) - { - return BMP_INVALID_ARGUMENT; - } - - /* The header's fields are read one by one, and converted from the format's - little endian to the system's native representation. */ - if ( !ReadUSHORT( &( bmp->Header.Magic ), f ) ) return BMP_IO_ERROR; - if ( !ReadUINT( &( bmp->Header.FileSize ), f ) ) return BMP_IO_ERROR; - if ( !ReadUSHORT( &( bmp->Header.Reserved1 ), f ) ) return BMP_IO_ERROR; - if ( !ReadUSHORT( &( bmp->Header.Reserved2 ), f ) ) return BMP_IO_ERROR; - if ( !ReadUINT( &( bmp->Header.DataOffset ), f ) ) return BMP_IO_ERROR; - if ( !ReadUINT( &( bmp->Header.HeaderSize ), f ) ) return BMP_IO_ERROR; - if ( !ReadUINT( &( bmp->Header.Width ), f ) ) return BMP_IO_ERROR; - if ( !ReadUINT( &( bmp->Header.Height ), f ) ) return BMP_IO_ERROR; - if ( !ReadUSHORT( &( bmp->Header.Planes ), f ) ) return BMP_IO_ERROR; - if ( !ReadUSHORT( &( bmp->Header.BitsPerPixel ), f ) ) return BMP_IO_ERROR; - if ( !ReadUINT( &( bmp->Header.CompressionType ), f ) ) return BMP_IO_ERROR; - if ( !ReadUINT( &( bmp->Header.ImageDataSize ), f ) ) return BMP_IO_ERROR; - if ( !ReadUINT( &( bmp->Header.HPixelsPerMeter ), f ) ) return BMP_IO_ERROR; - if ( !ReadUINT( &( bmp->Header.VPixelsPerMeter ), f ) ) return BMP_IO_ERROR; - if ( !ReadUINT( &( bmp->Header.ColorsUsed ), f ) ) return BMP_IO_ERROR; - if ( !ReadUINT( &( bmp->Header.ColorsRequired ), f ) ) return BMP_IO_ERROR; - - return BMP_OK; -} - - -/************************************************************** - Writes the BMP file's header into the data structure. - Returns BMP_OK on success. -**************************************************************/ -int WriteHeader( BMP* bmp, FILE* f ) -{ - if ( bmp == NULL || f == NULL ) - { - return BMP_INVALID_ARGUMENT; - } - - /* The header's fields are written one by one, and converted to the format's - little endian representation. */ - if ( !WriteUSHORT( bmp->Header.Magic, f ) ) return BMP_IO_ERROR; - if ( !WriteUINT( bmp->Header.FileSize, f ) ) return BMP_IO_ERROR; - if ( !WriteUSHORT( bmp->Header.Reserved1, f ) ) return BMP_IO_ERROR; - if ( !WriteUSHORT( bmp->Header.Reserved2, f ) ) return BMP_IO_ERROR; - if ( !WriteUINT( bmp->Header.DataOffset, f ) ) return BMP_IO_ERROR; - if ( !WriteUINT( bmp->Header.HeaderSize, f ) ) return BMP_IO_ERROR; - if ( !WriteUINT( bmp->Header.Width, f ) ) return BMP_IO_ERROR; - if ( !WriteUINT( bmp->Header.Height, f ) ) return BMP_IO_ERROR; - if ( !WriteUSHORT( bmp->Header.Planes, f ) ) return BMP_IO_ERROR; - if ( !WriteUSHORT( bmp->Header.BitsPerPixel, f ) ) return BMP_IO_ERROR; - if ( !WriteUINT( bmp->Header.CompressionType, f ) ) return BMP_IO_ERROR; - if ( !WriteUINT( bmp->Header.ImageDataSize, f ) ) return BMP_IO_ERROR; - if ( !WriteUINT( bmp->Header.HPixelsPerMeter, f ) ) return BMP_IO_ERROR; - if ( !WriteUINT( bmp->Header.VPixelsPerMeter, f ) ) return BMP_IO_ERROR; - if ( !WriteUINT( bmp->Header.ColorsUsed, f ) ) return BMP_IO_ERROR; - if ( !WriteUINT( bmp->Header.ColorsRequired, f ) ) return BMP_IO_ERROR; - - return BMP_OK; -} - - -/************************************************************** - Reads a little-endian unsigned int from the file. - Returns non-zero on success. -**************************************************************/ -int ReadUINT( UINT* x, FILE* f ) -{ - UCHAR little[ 4 ]; /* BMPs use 32 bit ints */ - - if ( x == NULL || f == NULL ) - { - return 0; - } - - if ( fread( little, 4, 1, f ) != 1 ) - { - return 0; - } - - *x = ( little[ 3 ] << 24 | little[ 2 ] << 16 | little[ 1 ] << 8 | little[ 0 ] ); - - return 1; -} - - -/************************************************************** - Reads a little-endian unsigned short int from the file. - Returns non-zero on success. -**************************************************************/ -int ReadUSHORT( USHORT *x, FILE* f ) -{ - UCHAR little[ 2 ]; /* BMPs use 16 bit shorts */ - - if ( x == NULL || f == NULL ) - { - return 0; - } - - if ( fread( little, 2, 1, f ) != 1 ) - { - return 0; - } - - *x = ( little[ 1 ] << 8 | little[ 0 ] ); - - return 1; -} - - -/************************************************************** - Writes a little-endian unsigned int to the file. - Returns non-zero on success. -**************************************************************/ -int WriteUINT( UINT x, FILE* f ) -{ - UCHAR little[ 4 ]; /* BMPs use 32 bit ints */ - - little[ 3 ] = (UCHAR)( ( x & 0xff000000 ) >> 24 ); - little[ 2 ] = (UCHAR)( ( x & 0x00ff0000 ) >> 16 ); - little[ 1 ] = (UCHAR)( ( x & 0x0000ff00 ) >> 8 ); - little[ 0 ] = (UCHAR)( ( x & 0x000000ff ) >> 0 ); - - return ( f && fwrite( little, 4, 1, f ) == 1 ); -} - - -/************************************************************** - Writes a little-endian unsigned short int to the file. - Returns non-zero on success. -**************************************************************/ -int WriteUSHORT( USHORT x, FILE* f ) -{ - UCHAR little[ 2 ]; /* BMPs use 16 bit shorts */ - - little[ 1 ] = (UCHAR)( ( x & 0xff00 ) >> 8 ); - little[ 0 ] = (UCHAR)( ( x & 0x00ff ) >> 0 ); - - return ( f && fwrite( little, 2, 1, f ) == 1 ); -} - diff --git a/rbutil/ibassoboot/jni/qdbmp.h b/rbutil/ibassoboot/jni/qdbmp.h deleted file mode 100644 index d6c0e6c452..0000000000 --- a/rbutil/ibassoboot/jni/qdbmp.h +++ /dev/null @@ -1,133 +0,0 @@ -#ifndef _BMP_H_ -#define _BMP_H_ - - -/************************************************************** - - QDBMP - Quick n' Dirty BMP - - v1.0.0 - 2007-04-07 - http://qdbmp.sourceforge.net - - - The library supports the following BMP variants: - 1. Uncompressed 32 BPP (alpha values are ignored) - 2. Uncompressed 24 BPP - 3. Uncompressed 8 BPP (indexed color) - - QDBMP is free and open source software, distributed - under the MIT licence. - - Copyright (c) 2007 Chai Braudo (braudo@users.sourceforge.net) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - -**************************************************************/ - -#include <stdio.h> - - - -/* Type definitions */ -#ifndef UINT - #define UINT unsigned long int -#endif - -#ifndef USHORT - #define USHORT unsigned short -#endif - -#ifndef UCHAR - #define UCHAR unsigned char -#endif - - -/* Version */ -#define QDBMP_VERSION_MAJOR 1 -#define QDBMP_VERSION_MINOR 0 -#define QDBMP_VERSION_PATCH 1 - - -/* Error codes */ -typedef enum -{ - BMP_OK = 0, /* No error */ - BMP_ERROR, /* General error */ - BMP_OUT_OF_MEMORY, /* Could not allocate enough memory to complete the operation */ - BMP_IO_ERROR, /* General input/output error */ - BMP_FILE_NOT_FOUND, /* File not found */ - BMP_FILE_NOT_SUPPORTED, /* File is not a supported BMP variant */ - BMP_FILE_INVALID, /* File is not a BMP image or is an invalid BMP */ - BMP_INVALID_ARGUMENT, /* An argument is invalid or out of range */ - BMP_TYPE_MISMATCH, /* The requested action is not compatible with the BMP's type */ - BMP_ERROR_NUM -} BMP_STATUS; - - -/* Bitmap image */ -typedef struct _BMP BMP; - - - - -/*********************************** Public methods **********************************/ - - -/* Construction/destruction */ -BMP* BMP_Create ( UINT width, UINT height, USHORT depth ); -void BMP_Free ( BMP* bmp ); - - -/* I/O */ -BMP* BMP_ReadFile ( const char* filename ); -void BMP_WriteFile ( BMP* bmp, const char* filename ); - - -/* Meta info */ -UINT BMP_GetWidth ( BMP* bmp ); -UINT BMP_GetHeight ( BMP* bmp ); -USHORT BMP_GetDepth ( BMP* bmp ); - - -/* Pixel access */ -void BMP_GetPixelRGB ( BMP* bmp, UINT x, UINT y, UCHAR* r, UCHAR* g, UCHAR* b ); -void BMP_SetPixelRGB ( BMP* bmp, UINT x, UINT y, UCHAR r, UCHAR g, UCHAR b ); -void BMP_GetPixelIndex ( BMP* bmp, UINT x, UINT y, UCHAR* val ); -void BMP_SetPixelIndex ( BMP* bmp, UINT x, UINT y, UCHAR val ); - - -/* Palette handling */ -void BMP_GetPaletteColor ( BMP* bmp, UCHAR index, UCHAR* r, UCHAR* g, UCHAR* b ); -void BMP_SetPaletteColor ( BMP* bmp, UCHAR index, UCHAR r, UCHAR g, UCHAR b ); - - -/* Error handling */ -BMP_STATUS BMP_GetError (); -const char* BMP_GetErrorDescription (); - - -/* Useful macro that may be used after each BMP operation to check for an error */ -#define BMP_CHECK_ERROR( output_file, return_value ) \ - if ( BMP_GetError() != BMP_OK ) \ - { \ - fprintf( ( output_file ), "BMP error: %s\n", BMP_GetErrorDescription() ); \ - return( return_value ); \ - } \ - -#endif diff --git a/rbutil/ibassoboot/jni/rbmissing.bmp b/rbutil/ibassoboot/jni/rbmissing.bmp Binary files differdeleted file mode 100644 index 1e97066d8c..0000000000 --- a/rbutil/ibassoboot/jni/rbmissing.bmp +++ /dev/null diff --git a/rbutil/ibassoboot/jni/usb.bmp b/rbutil/ibassoboot/jni/usb.bmp Binary files differdeleted file mode 100644 index c462de2236..0000000000 --- a/rbutil/ibassoboot/jni/usb.bmp +++ /dev/null diff --git a/rbutil/ipodpatcher/Makefile b/rbutil/ipodpatcher/Makefile deleted file mode 100644 index 4254995d22..0000000000 --- a/rbutil/ipodpatcher/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# __________ __ ___. -# Open \______ \ ____ ____ | | _\_ |__ _______ ___ -# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -# \/ \/ \/ \/ \/ -# $Id$ -# - -CFLAGS += -Wall -W - -# Build with "make BOOTOBJS=1" to build with embedded bootloaders and the -# --install option and interactive mode. You need the full set of Rockbox -# bootloaders in this directory - download them from -# http://download.rockbox.org/bootloader/ipod/bootloaders.zip - -# Releases of ipodpatcher are created with "make RELEASE=1". This -# enables BOOTOBJS and uses the VERSION string defined in main.c -ifdef RELEASE -CFLAGS += -DRELEASE -BOOTOBJS=1 -endif - -ifdef BOOTOBJS -BOOTSRC = ipod1g2g.c ipod3g.c ipod4g.c ipodcolor.c ipodmini1g.c \ - ipodmini2g.c ipodnano1g.c ipodvideo.c ipodnano2g.c -CFLAGS += -DWITH_BOOTOBJS -endif - -# additional frameworks to link on on OS X -LDOPTS_OSX = -framework CoreFoundation -framework IOKit - -LIBSOURCES = ipodpatcher.c fat32format.c arc4.c \ - ipodio-posix.c ipodio-win32-scsi.c ipodio-win32.c -SOURCES = main.c $(BOOTSRC) -ipodpatcher: SOURCES+= ipodio-posix.c - -OUTPUT = ipodpatcher -include ../libtools.make - -ipodpatcher.exe: $(OBJDIR)ipodpatcher-rc.o -$(OBJDIR)ipodpatcher-rc.o: ipodpatcher.rc ipodpatcher.manifest - @echo WINDRES $(notdir $<) - $(SILENT)$(CROSS)$(WINDRES) -i $< -o $@ - -%.c: bootloader-%.ipod $(BIN2C) - @echo BIN2C $< - $(SILENT)$(BIN2C) -i $< $* - -%.c: bootloader-%.ipodx $(BIN2C) - @echo BIN2C $< - $(SILENT)$(BIN2C) -i $< $* - diff --git a/rbutil/ipodpatcher/arc4.c b/rbutil/ipodpatcher/arc4.c deleted file mode 100644 index 75b1862b89..0000000000 --- a/rbutil/ipodpatcher/arc4.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * arc4.c - * Release $Name: MATRIXSSL_1_8_3_OPEN $ - * - * ARC4 stream cipher implementation - */ -/* - * Copyright (c) PeerSec Networks, 2002-2007. All Rights Reserved. - * The latest version of this code is available at http://www.matrixssl.org - * - * This software is open source; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This General Public License does NOT permit incorporating this software - * into proprietary programs. If you are unable to comply with the GPL, a - * commercial license for this software may be purchased from PeerSec Networks - * at http://www.peersec.com - * - * This program is distributed in WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * http://www.gnu.org/copyleft/gpl.html - */ -/******************************************************************************/ - -#include "arc4.h" - -/* - Some accounts, such as O'Reilly's Secure Programming Cookbook say that no - more than 2^30 bytes should be processed without rekeying, so we - enforce that limit here. FYI, this is equal to 1GB of data transferred. -*/ -#define ARC4_MAX_BYTES 0x40000000 - -/******************************************************************************/ -/* - SSL_RSA_WITH_RC4_* cipher callbacks - */ -void matrixArc4Init(struct rc4_key_t *ctx, unsigned char *key, int32_t keylen) -{ - unsigned char index1, index2, tmp, *state; - int16_t counter; - - ctx->byteCount = 0; - state = &ctx->state[0]; - - for (counter = 0; counter < 256; counter++) { - state[counter] = (unsigned char)counter; - } - ctx->x = 0; - ctx->y = 0; - index1 = 0; - index2 = 0; - - for (counter = 0; counter < 256; counter++) { - index2 = (key[index1] + state[counter] + index2) & 0xff; - - tmp = state[counter]; - state[counter] = state[index2]; - state[index2] = tmp; - - index1 = (index1 + 1) % keylen; - } -} - -int32_t matrixArc4(struct rc4_key_t *ctx, unsigned char *in, - unsigned char *out, int32_t len) -{ - unsigned char x, y, *state, xorIndex, tmp; - int counter; /* NOTE BY DAVE CHAPMAN: This was a short in - the original code, which caused a segfault - when attempting to process data > 32767 - bytes. */ - - ctx->byteCount += len; - if (ctx->byteCount > ARC4_MAX_BYTES) { - return -1; - } - - x = ctx->x; - y = ctx->y; - state = &ctx->state[0]; - for (counter = 0; counter < len; counter++) { - x = (x + 1) & 0xff; - y = (state[x] + y) & 0xff; - - tmp = state[x]; - state[x] = state[y]; - state[y] = tmp; - - xorIndex = (state[x] + state[y]) & 0xff; - - tmp = in[counter]; - tmp ^= state[xorIndex]; - out[counter] = tmp; - } - ctx->x = x; - ctx->y = y; - return len; -} - -/*****************************************************************************/ diff --git a/rbutil/ipodpatcher/arc4.h b/rbutil/ipodpatcher/arc4.h deleted file mode 100644 index 8bff0e2dc1..0000000000 --- a/rbutil/ipodpatcher/arc4.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - arc4.h - based on matrixssl-1-8-3-open - -*/ - -/* - * Copyright (c) PeerSec Networks, 2002-2007. All Rights Reserved. - * The latest version of this code is available at http://www.matrixssl.org - * - * This software is open source; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This General Public License does NOT permit incorporating this software - * into proprietary programs. If you are unable to comply with the GPL, a - * commercial license for this software may be purchased from PeerSec Networks - * at http://www.peersec.com - * - * This program is distributed in WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * http://www.gnu.org/copyleft/gpl.html - */ -/*****************************************************************************/ - -#ifndef _ARC4_H - -#include <stdint.h> - -struct rc4_key_t -{ - unsigned char state[256]; - uint32_t byteCount; - unsigned char x; - unsigned char y; -}; - -void matrixArc4Init(struct rc4_key_t *ctx, unsigned char *key, int32_t keylen); -int32_t matrixArc4(struct rc4_key_t *ctx, unsigned char *in, - unsigned char *out, int32_t len); - -#endif diff --git a/rbutil/ipodpatcher/fat32format.c b/rbutil/ipodpatcher/fat32format.c deleted file mode 100644 index 7ee8021cbf..0000000000 --- a/rbutil/ipodpatcher/fat32format.c +++ /dev/null @@ -1,530 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * - * FAT32 formatting functions. Based on: - * - * Fat32 formatter version 1.03 - * (c) Tom Thornhill 2005 - * This software is covered by the GPL. - * By using this tool, you agree to absolve Ridgecrop of an liabilities for - * lost data. - * Please backup any data you value before using this tool. - * - * - * Modified June 2007 by Dave Chapman for use in ipodpatcher - * - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdbool.h> -#include <stdint.h> -#include <inttypes.h> - -#include "ipodio.h" - -static inline uint16_t swap16(uint16_t value) -{ - return (value >> 8) | (value << 8); -} - -static inline uint32_t swap32(uint32_t value) -{ - uint32_t hi = swap16(value >> 16); - uint32_t lo = swap16(value & 0xffff); - return (lo << 16) | hi; -} - -/* The following functions are not the most efficient, but are - self-contained and don't require needing to know endianness of CPU - at compile-time. - - Note that htole16/htole32 exist on some platforms, so for - simplicity we use different names. - -*/ - -static uint16_t rb_htole16(uint16_t x) -{ - uint16_t test = 0x1234; - unsigned char* p = (unsigned char*)&test; - - if (p[0]==0x12) { - /* Big-endian */ - return swap16(x); - } else { - return x; - } -} - -static uint32_t rb_htole32(uint32_t x) -{ - uint32_t test = 0x12345678; - unsigned char* p = (unsigned char*)&test; - - if (p[0]==0x12) { - /* Big-endian */ - return swap32(x); - } else { - return x; - } -} - - -/* TODO: Pass these as parameters to the various create_ functions */ - -/* can be zero for default or 1,2,4,8,16,32 or 64 */ -static int sectors_per_cluster = 0; - -/* Recommended values */ -static uint32_t ReservedSectCount = 32; -static uint32_t NumFATs = 2; -static uint32_t BackupBootSect = 6; -static uint32_t VolumeId=0; /* calculated before format */ - -/* Calculated later */ -static uint32_t FatSize=0; -static uint32_t BytesPerSect=0; -static uint32_t SectorsPerCluster=0; -static uint32_t TotalSectors=0; -static uint32_t SystemAreaSize=0; -static uint32_t UserAreaSize=0; -static uint8_t VolId[12] = "NO NAME "; - - -struct FAT_BOOTSECTOR32 -{ - /* Common fields. */ - uint8_t sJmpBoot[3]; - char sOEMName[8]; - uint16_t wBytsPerSec; - uint8_t bSecPerClus; - uint16_t wRsvdSecCnt; - uint8_t bNumFATs; - uint16_t wRootEntCnt; - uint16_t wTotSec16; /* if zero, use dTotSec32 instead */ - uint8_t bMedia; - uint16_t wFATSz16; - uint16_t wSecPerTrk; - uint16_t wNumHeads; - uint32_t dHiddSec; - uint32_t dTotSec32; - - /* Fat 32/16 only */ - uint32_t dFATSz32; - uint16_t wExtFlags; - uint16_t wFSVer; - uint32_t dRootClus; - uint16_t wFSInfo; - uint16_t wBkBootSec; - uint8_t Reserved[12]; - uint8_t bDrvNum; - uint8_t Reserved1; - uint8_t bBootSig; /* == 0x29 if next three fields are ok */ - uint32_t dBS_VolID; - uint8_t sVolLab[11]; - uint8_t sBS_FilSysType[8]; -} __attribute__((packed)); - -struct FAT_FSINFO { - uint32_t dLeadSig; // 0x41615252 - uint8_t sReserved1[480]; // zeros - uint32_t dStrucSig; // 0x61417272 - uint32_t dFree_Count; // 0xFFFFFFFF - uint32_t dNxt_Free; // 0xFFFFFFFF - uint8_t sReserved2[12]; // zeros - uint32_t dTrailSig; // 0xAA550000 -} __attribute__((packed)); - - -/* Write "count" zero sectors, starting at sector "sector" */ -static int zero_sectors(struct ipod_t* ipod, uint64_t sector, int count) -{ - int n; - - if (ipod_seek(ipod, sector * ipod->sector_size) < 0) { - fprintf(stderr,"[ERR] Seek failed\n"); - return -1; - } - - memset(ipod->sectorbuf, 0, 128 * ipod->sector_size); - - /* Write 128 sectors at a time */ - while (count) { - if (count >= 128) - n = 128; - else - n = count; - - if (ipod_write(ipod,n * ipod->sector_size) < 0) { - perror("[ERR] Write failed in zero_sectors\n"); - return -1; - } - - count -= n; - } - - return 0; -} - - -/* -28.2 CALCULATING THE VOLUME SERIAL NUMBER - -For example, say a disk was formatted on 26 Dec 95 at 9:55 PM and 41.94 -seconds. DOS takes the date and time just before it writes it to the -disk. - -Low order word is calculated: Volume Serial Number is: - Month & Day 12/26 0c1ah - Sec & Hundrenths 41:94 295eh 3578:1d02 - ----- - 3578h - -High order word is calculated: - Hours & Minutes 21:55 1537h - Year 1995 07cbh - ----- - 1d02h -*/ -static uint32_t get_volume_id ( ) -{ - /* TODO */ -#if 0 - SYSTEMTIME s; - uint32_t d; - uint16_t lo,hi,tmp; - - GetLocalTime( &s ); - - lo = s.wDay + ( s.wMonth << 8 ); - tmp = (s.wMilliseconds/10) + (s.wSecond << 8 ); - lo += tmp; - - hi = s.wMinute + ( s.wHour << 8 ); - hi += s.wYear; - - d = lo + (hi << 16); - return(d); -#endif - return(0); -} - -/* -This is the Microsoft calculation from FATGEN - - uint32_t RootDirSectors = 0; - uint32_t TmpVal1, TmpVal2, FATSz; - - TmpVal1 = DskSize - ( ReservedSecCnt + RootDirSectors); - TmpVal2 = (256 * SecPerClus) + NumFATs; - TmpVal2 = TmpVal2 / 2; - FATSz = (TmpVal1 + (TmpVal2 - 1)) / TmpVal2; - - return( FatSz ); -*/ - - -static uint32_t get_fat_size_sectors(uint32_t DskSize, uint32_t ReservedSecCnt, - uint32_t SecPerClus, uint32_t NumFATs, - uint32_t BytesPerSect) -{ - uint64_t Numerator, Denominator; - uint64_t FatElementSize = 4; - uint64_t FatSz; - - /* This is based on - http://hjem.get2net.dk/rune_moeller_barnkob/filesystems/fat.html - I've made the obvious changes for FAT32 - */ - - Numerator = FatElementSize * ( DskSize - ReservedSecCnt ); - Denominator = ( SecPerClus * BytesPerSect ) + ( FatElementSize * NumFATs ); - FatSz = Numerator / Denominator; - - /* round up */ - FatSz += 1; - - return((uint32_t)FatSz); -} - -static uint8_t get_spc(uint32_t ClusterSizeKB, uint32_t BytesPerSect) -{ - uint32_t spc = ( ClusterSizeKB * 1024 ) / BytesPerSect; - return( (uint8_t) spc ); -} - -static uint8_t get_sectors_per_cluster(uint32_t DiskSizeSectors, - uint32_t BytesPerSect) -{ - uint8_t ret = 0x01; /* 1 sector per cluster */ - uint64_t DiskSizeBytes = (uint64_t)DiskSizeSectors * (uint64_t)BytesPerSect; - int64_t DiskSizeMB = DiskSizeBytes / ( 1024*1024 ); - - /* 512 MB to 8,191 MB 4 KB */ - if ( DiskSizeMB > 512 ) - ret = get_spc( 4, BytesPerSect ); /* ret = 0x8; */ - - /* 8,192 MB to 16,383 MB 8 KB */ - if ( DiskSizeMB > 8192 ) - ret = get_spc( 8, BytesPerSect ); /* ret = 0x10; */ - - /* 16,384 MB to 32,767 MB 16 KB */ - if ( DiskSizeMB > 16384 ) - ret = get_spc( 16, BytesPerSect ); /* ret = 0x20; */ - - /* Larger than 32,768 MB 32 KB */ - if ( DiskSizeMB > 32768 ) - ret = get_spc( 32, BytesPerSect ); /* ret = 0x40; */ - - return( ret ); - -} - -static void create_boot_sector(unsigned char* buf, - struct ipod_t* ipod, int partition) -{ - struct FAT_BOOTSECTOR32* pFAT32BootSect = (struct FAT_BOOTSECTOR32*)buf; - - /* fill out the boot sector and fs info */ - pFAT32BootSect->sJmpBoot[0]=0xEB; - pFAT32BootSect->sJmpBoot[1]=0x5A; - pFAT32BootSect->sJmpBoot[2]=0x90; - memcpy(pFAT32BootSect->sOEMName, "MSWIN4.1", 8 ); - pFAT32BootSect->wBytsPerSec = rb_htole16(BytesPerSect); - pFAT32BootSect->bSecPerClus = SectorsPerCluster ; - pFAT32BootSect->wRsvdSecCnt = rb_htole16(ReservedSectCount); - pFAT32BootSect->bNumFATs = NumFATs; - pFAT32BootSect->wRootEntCnt = rb_htole16(0); - pFAT32BootSect->wTotSec16 = rb_htole16(0); - pFAT32BootSect->bMedia = 0xF8; - pFAT32BootSect->wFATSz16 = rb_htole16(0); - pFAT32BootSect->wSecPerTrk = rb_htole16(ipod->sectors_per_track); - pFAT32BootSect->wNumHeads = rb_htole16(ipod->num_heads); - pFAT32BootSect->dHiddSec = rb_htole16(ipod->pinfo[partition].start); - pFAT32BootSect->dTotSec32 = rb_htole32(TotalSectors); - pFAT32BootSect->dFATSz32 = rb_htole32(FatSize); - pFAT32BootSect->wExtFlags = rb_htole16(0); - pFAT32BootSect->wFSVer = rb_htole16(0); - pFAT32BootSect->dRootClus = rb_htole32(2); - pFAT32BootSect->wFSInfo = rb_htole16(1); - pFAT32BootSect->wBkBootSec = rb_htole16(BackupBootSect); - pFAT32BootSect->bDrvNum = 0x80; - pFAT32BootSect->Reserved1 = 0; - pFAT32BootSect->bBootSig = 0x29; - pFAT32BootSect->dBS_VolID = rb_htole32(VolumeId); - memcpy(pFAT32BootSect->sVolLab, VolId, 11); - memcpy(pFAT32BootSect->sBS_FilSysType, "FAT32 ", 8 ); - - buf[510] = 0x55; - buf[511] = 0xaa; -} - -static void create_fsinfo(unsigned char* buf) -{ - struct FAT_FSINFO* pFAT32FsInfo = (struct FAT_FSINFO*)buf; - - /* FSInfo sect */ - pFAT32FsInfo->dLeadSig = rb_htole32(0x41615252); - pFAT32FsInfo->dStrucSig = rb_htole32(0x61417272); - pFAT32FsInfo->dFree_Count = rb_htole32((uint32_t) -1); - pFAT32FsInfo->dNxt_Free = rb_htole32((uint32_t) -1); - pFAT32FsInfo->dTrailSig = rb_htole32(0xaa550000); - pFAT32FsInfo->dFree_Count = rb_htole32((UserAreaSize/SectorsPerCluster)-1); - - /* clusters 0-1 reserved, we used cluster 2 for the root dir */ - pFAT32FsInfo->dNxt_Free = rb_htole32(3); -} - -static void create_firstfatsector(unsigned char* buf) -{ - uint32_t* p = (uint32_t*)buf; /* We know the buffer is aligned */ - - /* First FAT Sector */ - p[0] = rb_htole32(0x0ffffff8); /* Reserved cluster 1 media id in low byte */ - p[1] = rb_htole32(0x0fffffff); /* Reserved cluster 2 EOC */ - p[2] = rb_htole32(0x0fffffff); /* end of cluster chain for root dir */ -} - -int format_partition(struct ipod_t* ipod, int partition) -{ - uint32_t i; - uint64_t qTotalSectors=0; - uint64_t FatNeeded; - - VolumeId = get_volume_id( ); - - /* Only support hard disks at the moment */ - if ( ipod->sector_size != 512 ) - { - fprintf(stderr,"[ERR] Only disks with 512 bytes per sector are supported.\n"); - return -1; - } - BytesPerSect = ipod->sector_size; - - /* Checks on Disk Size */ - qTotalSectors = ipod->pinfo[partition].size; - - /* low end limit - 65536 sectors */ - if ( qTotalSectors < 65536 ) - { - /* I suspect that most FAT32 implementations would mount this - volume just fine, but the spec says that we shouldn't do - this, so we won't */ - - fprintf(stderr,"[ERR] This drive is too small for FAT32 - there must be at least 64K clusters\n" ); - return -1; - } - - if ( qTotalSectors >= 0xffffffff ) - { - /* This is a more fundamental limitation on FAT32 - the total - sector count in the root dir is 32bit. With a bit of - creativity, FAT32 could be extended to handle at least 2^28 - clusters There would need to be an extra field in the - FSInfo sector, and the old sector count could be set to - 0xffffffff. This is non standard though, the Windows FAT - driver FASTFAT.SYS won't understand this. Perhaps a future - version of FAT32 and FASTFAT will handle this. */ - - fprintf(stderr,"[ERR] This drive is too big for FAT32 - max 2TB supported\n"); - } - - if ( sectors_per_cluster ) { - SectorsPerCluster = sectors_per_cluster; - } else { - SectorsPerCluster = get_sectors_per_cluster(ipod->pinfo[partition].size, - BytesPerSect ); - } - - TotalSectors = (uint32_t) qTotalSectors; - - FatSize = get_fat_size_sectors(TotalSectors, ReservedSectCount, - SectorsPerCluster, NumFATs, BytesPerSect ); - - UserAreaSize = TotalSectors - ReservedSectCount - (NumFATs*FatSize); - - /* First zero out ReservedSect + FatSize * NumFats + SectorsPerCluster */ - SystemAreaSize = (ReservedSectCount+(NumFATs*FatSize) + SectorsPerCluster); - - /* Work out the Cluster count */ - FatNeeded = UserAreaSize/SectorsPerCluster; - - /* check for a cluster count of >2^28, since the upper 4 bits of - the cluster values in the FAT are reserved. */ - if (FatNeeded > 0x0FFFFFFF) { - fprintf(stderr,"[ERR] This drive has more than 2^28 clusters, try to specify a larger cluster size\n" ); - return -1; - } - - /* Sanity check, make sure the fat is big enough. - Convert the cluster count into a Fat sector count, and check - the fat size value we calculated earlier is OK. */ - - FatNeeded *=4; - FatNeeded += (BytesPerSect-1); - FatNeeded /= BytesPerSect; - - if ( FatNeeded > FatSize ) { - fprintf(stderr,"[ERR] Drive too big to format\n"); - return -1; - } - - /* - Write boot sector, fats - Sector 0 Boot Sector - Sector 1 FSInfo - Sector 2 More boot code - we write zeros here - Sector 3 unused - Sector 4 unused - Sector 5 unused - Sector 6 Backup boot sector - Sector 7 Backup FSInfo sector - Sector 8 Backup 'more boot code' - zero'd sectors upto ReservedSectCount - FAT1 ReservedSectCount to ReservedSectCount + FatSize - ... - FATn ReservedSectCount to ReservedSectCount + FatSize - RootDir - allocated to cluster2 - */ - - fprintf(stderr,"[INFO] Heads - %d, sectors/track = %d\n",ipod->num_heads,ipod->sectors_per_track); - fprintf(stderr,"[INFO] Size : %" PRIu64 "GB %u sectors\n", - ((uint64_t)ipod->pinfo[partition].size * (uint64_t)ipod->sector_size) / (1000*1000*1000), TotalSectors ); - fprintf(stderr,"[INFO] %d Bytes Per Sector, Cluster size %d bytes\n", BytesPerSect, SectorsPerCluster*BytesPerSect ); - fprintf(stderr,"[INFO] Volume ID is %x:%x\n", VolumeId>>16, VolumeId&0xffff ); - fprintf(stderr,"[INFO] %d Reserved Sectors, %d Sectors per FAT, %d fats\n", ReservedSectCount, FatSize, NumFATs ); - fprintf (stderr,"[INFO] %d Total clusters\n", UserAreaSize/SectorsPerCluster ); - - fprintf(stderr,"[INFO] Formatting partition %d:...\n",partition); - - /* Once zero_sectors has run, any data on the drive is basically lost... */ - fprintf(stderr,"[INFO] Clearing out %d sectors for Reserved sectors, fats and root cluster...\n", SystemAreaSize ); - - zero_sectors(ipod, ipod->pinfo[partition].start, SystemAreaSize); - - fprintf(stderr,"[INFO] Initialising reserved sectors and FATs...\n" ); - - /* Create the boot sector structure */ - create_boot_sector(ipod->sectorbuf, ipod, partition); - create_fsinfo(ipod->sectorbuf + 512); - - /* Write boot sector and fsinfo at start of partition */ - if (ipod_seek(ipod, ipod->pinfo[partition].start * ipod->sector_size) < 0) { - fprintf(stderr,"[ERR] Seek failed\n"); - return -1; - } - if (ipod_write(ipod,512 * 2) < 0) { - perror("[ERR] Write failed (first copy of bootsect/fsinfo)\n"); - return -1; - } - - /* Write backup copy of boot sector and fsinfo */ - if (ipod_seek(ipod, (ipod->pinfo[partition].start + BackupBootSect) * ipod->sector_size) < 0) { - fprintf(stderr,"[ERR] Seek failed\n"); - return -1; - } - if (ipod_write(ipod,512 * 2) < 0) { - perror("[ERR] Write failed (first copy of bootsect/fsinfo)\n"); - return -1; - } - - /* Create the first FAT sector */ - create_firstfatsector(ipod->sectorbuf); - - /* Write the first fat sector in the right places */ - for ( i=0; i<NumFATs; i++ ) { - int SectorStart = ReservedSectCount + (i * FatSize ); - - if (ipod_seek(ipod, (ipod->pinfo[partition].start + SectorStart) * ipod->sector_size) < 0) { - fprintf(stderr,"[ERR] Seek failed\n"); - return -1; - } - - if (ipod_write(ipod,512) < 0) { - perror("[ERR] Write failed (first copy of bootsect/fsinfo)\n"); - return -1; - } - } - - fprintf(stderr,"[INFO] Format successful\n"); - - return 0; -} diff --git a/rbutil/ipodpatcher/ipodio-posix.c b/rbutil/ipodpatcher/ipodio-posix.c deleted file mode 100644 index 9b386d994f..0000000000 --- a/rbutil/ipodpatcher/ipodio-posix.c +++ /dev/null @@ -1,409 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2006-2007 Dave Chapman - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#if !defined(_WIN32) /* all non-Windows platforms are considered POSIX. */ - -#include <stdio.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <errno.h> - -#include "ipodio.h" - -#if defined(linux) || defined (__linux) -#include <sys/mount.h> -#include <linux/hdreg.h> -#include <scsi/scsi_ioctl.h> -#include <scsi/sg.h> - -#define IPOD_SECTORSIZE_IOCTL BLKSSZGET - -static void get_geometry(struct ipod_t* ipod) -{ - struct hd_geometry geometry; - - if (!ioctl(ipod->dh, HDIO_GETGEO, &geometry)) { - /* never use geometry.cylinders - it is truncated */ - ipod->num_heads = geometry.heads; - ipod->sectors_per_track = geometry.sectors; - } else { - ipod->num_heads = 0; - ipod->sectors_per_track = 0; - } -} - -/* Linux SCSI Inquiry code based on the documentation and example code from - http://www.ibm.com/developerworks/linux/library/l-scsi-api/index.html -*/ - -int ipod_scsi_inquiry(struct ipod_t* ipod, int page_code, - unsigned char* buf, int bufsize) -{ - unsigned char cdb[6]; - struct sg_io_hdr hdr; - unsigned char sense_buffer[255]; - - memset(&hdr, 0, sizeof(hdr)); - - hdr.interface_id = 'S'; /* this is the only choice we have! */ - hdr.flags = SG_FLAG_LUN_INHIBIT; /* this would put the LUN to 2nd byte of cdb*/ - - /* Set xfer data */ - hdr.dxferp = buf; - hdr.dxfer_len = bufsize; - - /* Set sense data */ - hdr.sbp = sense_buffer; - hdr.mx_sb_len = sizeof(sense_buffer); - - /* Set the cdb format */ - cdb[0] = 0x12; - cdb[1] = 1; /* Enable Vital Product Data (EVPD) */ - cdb[2] = page_code & 0xff; - cdb[3] = 0; - cdb[4] = 0xff; - cdb[5] = 0; /* For control filed, just use 0 */ - - hdr.dxfer_direction = SG_DXFER_FROM_DEV; - hdr.cmdp = cdb; - hdr.cmd_len = 6; - - int ret = ioctl(ipod->dh, SG_IO, &hdr); - - if (ret < 0) { - return -1; - } else { - return 0; - } -} - -#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) \ - || defined(__bsdi__) || defined(__DragonFly__) -#include <sys/disk.h> -#define IPOD_SECTORSIZE_IOCTL DIOCGSECTORSIZE - -/* TODO: Implement this function for BSD */ -static void get_geometry(struct ipod_t* ipod) -{ - /* Are these universal for all ipods? */ - ipod->num_heads = 255; - ipod->sectors_per_track = 63; -} - -int ipod_scsi_inquiry(struct ipod_t* ipod, int page_code, - unsigned char* buf, int bufsize) -{ - /* TODO: Implement for BSD */ - (void)ipod; - (void)page_code; - (void)buf; - (void)bufsize; - return -1; -} - -#elif defined(__APPLE__) && defined(__MACH__) -/* OS X IOKit includes don't like VERSION being defined! */ -#undef VERSION -#include <sys/disk.h> -#include <CoreFoundation/CoreFoundation.h> -#include <IOKit/IOKitLib.h> -#include <IOKit/scsi/SCSITaskLib.h> -#include <IOKit/scsi/SCSICommandOperationCodes.h> -#define IPOD_SECTORSIZE_IOCTL DKIOCGETBLOCKSIZE - -/* TODO: Implement this function for Mac OS X */ -static void get_geometry(struct ipod_t* ipod) -{ - /* Are these universal for all ipods? */ - ipod->num_heads = 255; - ipod->sectors_per_track = 63; -} - -int ipod_scsi_inquiry(struct ipod_t* ipod, int page_code, - unsigned char* buf, int bufsize) -{ - /* OS X doesn't allow to simply send out a SCSI inquiry request but - * requires registering an interface handler first. - * Currently this is done on each inquiry request which is somewhat - * inefficient but the current ipodpatcher API doesn't really fit here. - * Based on the documentation in Apple's document - * "SCSI Architecture Model Device Interface Guide". - * - * WARNING: this code currently doesn't take the selected device into - * account. It simply looks for an Ipod on the system and uses - * the first match. - */ - (void)ipod; - int result = 0; - /* first, create a dictionary to match the device. This is needed to get the - * service. */ - CFMutableDictionaryRef match_dict; - match_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL); - if(match_dict == NULL) - return -1; - - /* set value to match. In case of the Ipod this is "iPodUserClientDevice". */ - CFMutableDictionaryRef sub_dict; - sub_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL); - if(sub_dict == NULL) - return -1; - CFDictionarySetValue(sub_dict, CFSTR(kIOPropertySCSITaskDeviceCategory), - CFSTR("iPodUserClientDevice")); - CFDictionarySetValue(match_dict, CFSTR(kIOPropertyMatchKey), sub_dict); - - /* get an iterator for searching for the service. */ - kern_return_t kr; - io_iterator_t iterator = IO_OBJECT_NULL; - /* get matching services from IO registry. Consumes one reference to - * the dictionary, so no need to release that. */ - kr = IOServiceGetMatchingServices(kIOMasterPortDefault, match_dict, &iterator); - - if(!iterator | (kr != kIOReturnSuccess)) - return -1; - - /* get interface and obtain exclusive access */ - SInt32 score; - HRESULT herr; - kern_return_t err; - IOCFPlugInInterface **plugin_interface = NULL; - SCSITaskDeviceInterface **interface = NULL; - io_service_t device = IO_OBJECT_NULL; - device = IOIteratorNext(iterator); - - err = IOCreatePlugInInterfaceForService(device, kIOSCSITaskDeviceUserClientTypeID, - kIOCFPlugInInterfaceID, &plugin_interface, - &score); - - if(err != noErr) { - return -1; - } - /* query the plugin interface for task interface */ - herr = (*plugin_interface)->QueryInterface(plugin_interface, - CFUUIDGetUUIDBytes(kIOSCSITaskDeviceInterfaceID), (LPVOID*)&interface); - if(herr != S_OK) { - IODestroyPlugInInterface(plugin_interface); - return -1; - } - - err = (*interface)->ObtainExclusiveAccess(interface); - if(err != noErr) { - (*interface)->Release(interface); - IODestroyPlugInInterface(plugin_interface); - return -1; - } - - /* do the inquiry */ - SCSITaskInterface **task = NULL; - - task = (*interface)->CreateSCSITask(interface); - if(task != NULL) { - kern_return_t err; - SCSITaskStatus task_status; - IOVirtualRange* range; - SCSI_Sense_Data sense_data; - SCSICommandDescriptorBlock cdb; - UInt64 transfer_count = 0; - memset(buf, 0, bufsize); - /* allocate virtual range for buffer. */ - range = (IOVirtualRange*) malloc(sizeof(IOVirtualRange)); - memset(&sense_data, 0, sizeof(sense_data)); - memset(cdb, 0, sizeof(cdb)); - /* set up range. address is buffer address, length is request size. */ - range->address = (IOVirtualAddress)buf; - range->length = bufsize; - /* setup CDB */ - cdb[0] = 0x12; /* inquiry */ - cdb[1] = 1; - cdb[2] = page_code; - cdb[4] = bufsize; - - /* set cdb in task */ - err = (*task)->SetCommandDescriptorBlock(task, cdb, kSCSICDBSize_6Byte); - if(err != kIOReturnSuccess) { - result = -1; - goto cleanup; - } - err = (*task)->SetScatterGatherEntries(task, range, 1, bufsize, - kSCSIDataTransfer_FromTargetToInitiator); - if(err != kIOReturnSuccess) { - result = -1; - goto cleanup; - } - /* set timeout */ - err = (*task)->SetTimeoutDuration(task, 10000); - if(err != kIOReturnSuccess) { - result = -1; - goto cleanup; - } - - /* request data */ - err = (*task)->ExecuteTaskSync(task, &sense_data, &task_status, &transfer_count); - if(err != kIOReturnSuccess) { - result = -1; - goto cleanup; - } - /* cleanup */ - free(range); - - /* release task interface */ - (*task)->Release(task); - } - else { - result = -1; - } -cleanup: - /* cleanup interface */ - (*interface)->ReleaseExclusiveAccess(interface); - (*interface)->Release(interface); - IODestroyPlugInInterface(plugin_interface); - - return result; -} - -#else - #error No sector-size detection implemented for this platform -#endif - -#if defined(__APPLE__) && defined(__MACH__) -static int ipod_unmount(struct ipod_t* ipod) -{ - char cmd[4096]; - int res; - - sprintf(cmd, "/usr/sbin/diskutil unmount \"%ss2\"",ipod->diskname); - fprintf(stderr,"[INFO] "); - res = system(cmd); - - if (res==0) { - return 0; - } else { - perror("Unmount failed"); - return -1; - } -} -#endif - -void ipod_print_error(char* msg) -{ - perror(msg); -} - -int ipod_open(struct ipod_t* ipod, int silent) -{ - ipod->dh=open(ipod->diskname,O_RDONLY); - if (ipod->dh < 0) { - if (!silent) perror(ipod->diskname); - if(errno == EACCES) return -2; - else return -1; - } - - /* Read information about the disk */ - - if(ioctl(ipod->dh,IPOD_SECTORSIZE_IOCTL,&ipod->sector_size) < 0) { - ipod->sector_size=512; - if (!silent) { - fprintf(stderr,"[ERR] ioctl() call to get sector size failed, defaulting to %d\n" - ,ipod->sector_size); - } - } - - get_geometry(ipod); - - return 0; -} - - -int ipod_reopen_rw(struct ipod_t* ipod) -{ -#if defined(__APPLE__) && defined(__MACH__) - if (ipod_unmount(ipod) < 0) - return -1; -#endif - - close(ipod->dh); - ipod->dh=open(ipod->diskname,O_RDWR); - if (ipod->dh < 0) { - perror(ipod->diskname); - return -1; - } - return 0; -} - -int ipod_close(struct ipod_t* ipod) -{ - close(ipod->dh); - return 0; -} - -int ipod_alloc_buffer(struct ipod_t* ipod, int bufsize) -{ - ipod->sectorbuf = malloc(bufsize); - if (ipod->sectorbuf== NULL) { - return -1; - } - return 0; -} - -int ipod_dealloc_buffer(struct ipod_t* ipod) -{ - if (ipod->sectorbuf == NULL) { - return -1; - } - free(ipod->sectorbuf); - ipod->sectorbuf = NULL; - return 0; -} - -int ipod_seek(struct ipod_t* ipod, unsigned long pos) -{ - off_t res; - - res = lseek(ipod->dh, pos, SEEK_SET); - - if (res == -1) { - return -1; - } - return 0; -} - -ssize_t ipod_read(struct ipod_t* ipod, int nbytes) -{ - if(ipod->sectorbuf == NULL) { - return -1; - } - return read(ipod->dh, ipod->sectorbuf, nbytes); -} - -ssize_t ipod_write(struct ipod_t* ipod, int nbytes) -{ - if(ipod->sectorbuf == NULL) { - return -1; - } - return write(ipod->dh, ipod->sectorbuf, nbytes); -} - -#endif - diff --git a/rbutil/ipodpatcher/ipodio-win32-scsi.c b/rbutil/ipodpatcher/ipodio-win32-scsi.c deleted file mode 100644 index 16460cfba3..0000000000 --- a/rbutil/ipodpatcher/ipodio-win32-scsi.c +++ /dev/null @@ -1,147 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2009 Dave Chapman - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * - * Based on the getCapsUsingSCSIPassThrough() function from "cddrv.cpp": - * - http://www.farmanager.com/svn/trunk/unicode_far/cddrv.cpp - * - * Copyright (c) 1996 Eugene Roshal - * Copyright (c) 2000 Far Group - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the authors may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -#if defined(_WIN32) -#include <windows.h> -#include <stddef.h> -#include <stdio.h> - -#include "ipodio.h" - -/* from ddk/ntddscsi.h */ -#define SCSI_IOCTL_DATA_OUT 0 -#define SCSI_IOCTL_DATA_IN 1 -#define SCSI_IOCTL_DATA_UNSPECIFIED 2 - -#define IOCTL_SCSI_PASS_THROUGH \ - CTL_CODE(FILE_DEVICE_CONTROLLER, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) - -typedef struct _SCSI_PASS_THROUGH { - USHORT Length; - UCHAR ScsiStatus; - UCHAR PathId; - UCHAR TargetId; - UCHAR Lun; - UCHAR CdbLength; - UCHAR SenseInfoLength; - UCHAR DataIn; - ULONG DataTransferLength; - ULONG TimeOutValue; - ULONG_PTR DataBufferOffset; - ULONG SenseInfoOffset; - UCHAR Cdb[16]; -} SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH; - -typedef struct _SCSI_PASS_THROUGH_WITH_BUFFERS { - SCSI_PASS_THROUGH Spt; - ULONG Filler; /* realign buffers to double word boundary */ - UCHAR SenseBuf[32]; - UCHAR DataBuf[512]; -} SCSI_PASS_THROUGH_WITH_BUFFERS, *PSCSI_PASS_THROUGH_WITH_BUFFERS; - -int ipod_scsi_inquiry(struct ipod_t* ipod, int page_code, - unsigned char* buf, int bufsize) -{ - SCSI_PASS_THROUGH_WITH_BUFFERS sptwb; - ULONG length; - DWORD returned; - BOOL status; - - if (bufsize > 255) { - fprintf(stderr,"[ERR] Invalid bufsize in ipod_scsi_inquiry\n"); - return -1; - } - - memset(&sptwb, 0, sizeof(sptwb)); - - sptwb.Spt.Length = sizeof(SCSI_PASS_THROUGH); - sptwb.Spt.PathId = 0; - sptwb.Spt.TargetId = 1; - sptwb.Spt.Lun = 0; - sptwb.Spt.CdbLength = 6; - sptwb.Spt.SenseInfoLength = 32; /* sbuf size */; - sptwb.Spt.DataIn = SCSI_IOCTL_DATA_IN; - sptwb.Spt.DataTransferLength = bufsize; - sptwb.Spt.TimeOutValue = 2; /* 2 seconds */ - sptwb.Spt.DataBufferOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, DataBuf); - sptwb.Spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, SenseBuf); - length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, DataBuf) + - sptwb.Spt.DataTransferLength; - - /* Set cdb info */ - sptwb.Spt.Cdb[0] = 0x12; /* SCSI Inquiry */ - sptwb.Spt.Cdb[1] = 1; - sptwb.Spt.Cdb[2] = page_code; - sptwb.Spt.Cdb[3] = 0; - sptwb.Spt.Cdb[4] = bufsize; - sptwb.Spt.Cdb[5] = 0; - - status = DeviceIoControl(ipod->dh, - IOCTL_SCSI_PASS_THROUGH, - &sptwb, - sizeof(SCSI_PASS_THROUGH), - &sptwb, - length, - &returned, - FALSE); - - if (status) { - /* W32 sometimes returns more bytes with additional garbage. - * Make sure to not copy that garbage. */ - memcpy(buf, sptwb.DataBuf, - (DWORD)bufsize >= returned ? returned : (DWORD)bufsize); - return 0; - } else { - return -1; - } -} -#endif - diff --git a/rbutil/ipodpatcher/ipodio-win32.c b/rbutil/ipodpatcher/ipodio-win32.c deleted file mode 100644 index cea218774a..0000000000 --- a/rbutil/ipodpatcher/ipodio-win32.c +++ /dev/null @@ -1,226 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2006-2007 Dave Chapman - * - * error(), lock_volume() and unlock_volume() functions and inspiration taken - * from: - * RawDisk - Direct Disk Read/Write Access for NT/2000/XP - * Copyright (c) 2003 Jan Kiszka - * http://www.stud.uni-hannover.de/user/73174/RawDisk/ - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#if defined(_WIN32) - -#include <stdio.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <windows.h> -#include <stddef.h> -#include <winioctl.h> - -#include "ipodio.h" - -static int lock_volume(HANDLE hDisk) -{ - DWORD dummy; - - return DeviceIoControl(hDisk, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, - &dummy, NULL); -} - -static int unlock_volume(HANDLE hDisk) -{ - DWORD dummy; - - return DeviceIoControl(hDisk, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, - &dummy, NULL); -} - -void ipod_print_error(char* msg) -{ - LPSTR pMsgBuf = NULL; - - printf(msg); - FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), pMsgBuf, - 0, NULL); - printf(pMsgBuf); - LocalFree(pMsgBuf); -} - -int ipod_open(struct ipod_t* ipod, int silent) -{ - DISK_GEOMETRY_EX diskgeometry_ex; - DISK_GEOMETRY diskgeometry; - unsigned long n; - - ipod->dh = CreateFileA(ipod->diskname, GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, - FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, NULL); - - if (ipod->dh == INVALID_HANDLE_VALUE) { - if (!silent) ipod_print_error(" Error opening disk: "); - if(GetLastError() == ERROR_ACCESS_DENIED) - return -2; - else - return -1; - } - - if (!lock_volume(ipod->dh)) { - if (!silent) ipod_print_error(" Error locking disk: "); - return -1; - } - - /* Defaults */ - ipod->num_heads = 0; - ipod->sectors_per_track = 0; - - if (!DeviceIoControl(ipod->dh, - IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, - NULL, - 0, - &diskgeometry_ex, - sizeof(diskgeometry_ex), - &n, - NULL)) { - if (!DeviceIoControl(ipod->dh, - IOCTL_DISK_GET_DRIVE_GEOMETRY, - NULL, - 0, - &diskgeometry, - sizeof(diskgeometry), - &n, - NULL)) { - if (!silent) ipod_print_error(" Error reading disk geometry: "); - return -1; - } else { - ipod->sector_size = diskgeometry.BytesPerSector; - ipod->num_heads = diskgeometry.TracksPerCylinder; - ipod->sectors_per_track = diskgeometry.SectorsPerTrack; - } - } else { - ipod->sector_size = diskgeometry_ex.Geometry.BytesPerSector; - ipod->num_heads = diskgeometry_ex.Geometry.TracksPerCylinder; - ipod->sectors_per_track = diskgeometry_ex.Geometry.SectorsPerTrack; - } - - return 0; -} - -int ipod_reopen_rw(struct ipod_t* ipod) -{ - /* Close existing file and re-open for writing */ - unlock_volume(ipod->dh); - CloseHandle(ipod->dh); - - ipod->dh = CreateFileA(ipod->diskname, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, - FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, NULL); - - if (ipod->dh == INVALID_HANDLE_VALUE) { - ipod_print_error(" Error opening disk: "); - return -1; - } - - if (!lock_volume(ipod->dh)) { - ipod_print_error(" Error locking disk: "); - return -1; - } - - return 0; -} - -int ipod_close(struct ipod_t* ipod) -{ - unlock_volume(ipod->dh); - CloseHandle(ipod->dh); - return 0; -} - -int ipod_alloc_buffer(struct ipod_t* ipod, int bufsize) -{ - /* The ReadFile function requires a memory buffer aligned to a multiple of - the disk sector size. */ - ipod->sectorbuf = (unsigned char*)VirtualAlloc(NULL, bufsize, MEM_COMMIT, PAGE_READWRITE); - if (ipod->sectorbuf== NULL) { - ipod_print_error(" Error allocating a buffer: "); - return -1; - } - return 0; -} - -int ipod_dealloc_buffer(struct ipod_t* ipod) -{ - if (ipod->sectorbuf == NULL) { - return -1; - } - if(!VirtualFree(ipod->sectorbuf, 0, MEM_RELEASE)) { - ipod_print_error(" Error releasing buffer "); - return -1; - } - ipod->sectorbuf = NULL; - return 0; -} - -int ipod_seek(struct ipod_t* ipod, unsigned long pos) -{ - if (SetFilePointer(ipod->dh, pos, NULL, FILE_BEGIN)==0xffffffff) { - ipod_print_error(" Seek error "); - return -1; - } - return 0; -} - -ssize_t ipod_read(struct ipod_t* ipod, int nbytes) -{ - unsigned long count; - - if(ipod->sectorbuf == NULL) { - return -1; - } - if (!ReadFile(ipod->dh, ipod->sectorbuf, nbytes, &count, NULL)) { - ipod_print_error(" Error reading from disk: "); - return -1; - } - - return count; -} - -ssize_t ipod_write(struct ipod_t* ipod, int nbytes) -{ - unsigned long count; - - if(ipod->sectorbuf == NULL) { - return -1; - } - if (!WriteFile(ipod->dh, ipod->sectorbuf, nbytes, &count, NULL)) { - ipod_print_error(" Error writing to disk: "); - return -1; - } - - return count; -} - -#endif - diff --git a/rbutil/ipodpatcher/ipodio.h b/rbutil/ipodpatcher/ipodio.h deleted file mode 100644 index 4f1a35dd09..0000000000 --- a/rbutil/ipodpatcher/ipodio.h +++ /dev/null @@ -1,115 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2006-2007 Dave Chapman - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#ifndef __IPODIO_H -#define __IPODIO_H - -#include <stdint.h> -#if !defined(_WIN32) -#include <unistd.h> -#elif defined(_MSC_VER) -/* MSVC uses a different name for ssize_t */ -#define ssize_t SSIZE_T -#endif - -#if defined(__WIN32__) || defined(_WIN32) -#include <windows.h> -#else -#define HANDLE int -#define O_BINARY 0 -#endif - -/* The maximum number of images in a firmware partition - a guess... */ -#define MAX_IMAGES 10 - -enum firmwaretype_t { - FTYPE_OSOS = 0, - FTYPE_RSRC, - FTYPE_AUPD, - FTYPE_HIBE, - FTYPE_OSBK -}; - -struct ipod_directory_t { - enum firmwaretype_t ftype; - int id; - uint32_t devOffset; /* Offset of image relative to one sector into bootpart*/ - uint32_t len; - uint32_t addr; - uint32_t entryOffset; - uint32_t chksum; - uint32_t vers; - uint32_t loadAddr; -}; - -/* A fake partition type - DOS partition tables can't include HFS partitions */ -#define PARTTYPE_HFS 0xffff - -struct partinfo_t { - uint32_t start; /* first sector (LBA) */ - uint32_t size; /* number of sectors */ - uint32_t type; -}; - -struct ipod_t { - unsigned char* sectorbuf; - HANDLE dh; - char diskname[4096]; - int sector_size; - int sectors_per_track; - int num_heads; - struct ipod_directory_t ipod_directory[MAX_IMAGES]; - int nimages; - int ososimage; - off_t diroffset; - off_t start; /* Offset in bytes of firmware partition from start of disk */ - off_t fwoffset; /* Offset in bytes of start of firmware images from start of disk */ - struct partinfo_t pinfo[4]; - int modelnum; - char* modelname; - char* modelstr; - char* targetname; - int macpod; - char* xmlinfo; /* The XML Device Information (if available) */ - int xmlinfo_len; - int ramsize; /* The amount of RAM in the ipod (if available) */ -#ifdef WITH_BOOTOBJS - unsigned char* bootloader; - int bootloader_len; -#endif -}; - -void ipod_print_error(char* msg); -int ipod_open(struct ipod_t* ipod, int silent); -int ipod_reopen_rw(struct ipod_t* ipod); -int ipod_close(struct ipod_t* ipod); -int ipod_seek(struct ipod_t* ipod, unsigned long pos); -int ipod_scsi_inquiry(struct ipod_t* ipod, int page_code, - unsigned char* buf, int bufsize); -ssize_t ipod_read(struct ipod_t* ipod, int nbytes); -ssize_t ipod_write(struct ipod_t* ipod, int nbytes); -int ipod_alloc_buffer(struct ipod_t* ipod, int bufsize); -int ipod_dealloc_buffer(struct ipod_t* ipod); - -/* In fat32format.c */ -int format_partition(struct ipod_t* ipod, int partition); - -#endif diff --git a/rbutil/ipodpatcher/ipodpatcher.c b/rbutil/ipodpatcher/ipodpatcher.c deleted file mode 100644 index e047e52abe..0000000000 --- a/rbutil/ipodpatcher/ipodpatcher.c +++ /dev/null @@ -1,2350 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2006-2007 Dave Chapman - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include <stdio.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> -#include <stdlib.h> -#include <inttypes.h> -#include <stdbool.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include "parttypes.h" -#include "ipodio.h" -#include "ipodpatcher.h" - -#ifdef WITH_BOOTOBJS -#include "ipod1g2g.h" -#include "ipod3g.h" -#include "ipod4g.h" -#include "ipodmini1g.h" -#include "ipodmini2g.h" -#include "ipodcolor.h" -#include "ipodnano1g.h" -#include "ipodvideo.h" -#include "ipodnano2g.h" -#endif - -#ifndef RBUTIL -#include "arc4.h" -#endif - -int ipod_verbose = 0; - - -/* The following string appears at the start of the firmware partition */ -static const char apple_stop_sign[] = "{{~~ /-----\\ "\ - "{{~~ / \\ "\ - "{{~~| | "\ - "{{~~| S T O P | "\ - "{{~~| | "\ - "{{~~ \\ / "\ - "{{~~ \\-----/ "\ - "Copyright(C) 200"\ - "1 Apple Computer"\ - ", Inc.----------"\ - "----------------"\ - "----------------"\ - "----------------"\ - "----------------"\ - "----------------"\ - "---------------"; - -/* Windows requires the buffer for disk I/O to be aligned in memory on a - multiple of the disk volume size - so we use a single global variable - and initialise it with ipod_alloc_buf() -*/ - -char* get_parttype(unsigned int pt) -{ - int i; - static char unknown[]="Unknown"; - - if (pt == PARTTYPE_HFS) { - return "HFS/HFS+"; - } - - i=0; - while (parttypes[i].name != NULL) { - if (parttypes[i].type == pt) { - return (parttypes[i].name); - } - i++; - } - - return unknown; -} - -off_t filesize(int fd) { - struct stat buf; - - if (fstat(fd,&buf) < 0) { - perror("[ERR] Checking filesize of input file"); - return -1; - } else { - return(buf.st_size); - } -} - -/* Partition table parsing code taken from Rockbox */ - -#define MAX_SECTOR_SIZE 2048 -#define SECTOR_SIZE 512 - -static inline unsigned short le2ushort(unsigned char* buf) -{ - unsigned short res = (buf[1] << 8) | buf[0]; - - return res; -} - -static inline int le2int(unsigned char* buf) -{ - int32_t res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; - - return res; -} - -static inline int be2int(unsigned char* buf) -{ - int32_t res = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; - - return res; -} - -static inline int getint16le(char* buf) -{ - int16_t res = (buf[1] << 8) | buf[0]; - - return res; -} - -static inline void short2le(unsigned short val, unsigned char* addr) -{ - addr[0] = val & 0xFF; - addr[1] = (val >> 8) & 0xff; -} - -static inline void int2le(unsigned int val, unsigned char* addr) -{ - addr[0] = val & 0xFF; - addr[1] = (val >> 8) & 0xff; - addr[2] = (val >> 16) & 0xff; - addr[3] = (val >> 24) & 0xff; -} - -static inline void int2be(unsigned int val, unsigned char* addr) -{ - addr[0] = (val >> 24) & 0xff; - addr[1] = (val >> 16) & 0xff; - addr[2] = (val >> 8) & 0xff; - addr[3] = val & 0xFF; -} - - -#define BYTES2INT32(array,pos)\ - ((long)array[pos] | ((long)array[pos+1] << 8 ) |\ - ((long)array[pos+2] << 16 ) | ((long)array[pos+3] << 24 )) - -int read_partinfo(struct ipod_t* ipod, int silent) -{ - int i; - unsigned long count; - - if(ipod->sectorbuf == NULL) { - fprintf(stderr,"[ERR] Buffer not initialized."); - return -1; - } - - count = ipod_read(ipod,ipod->sector_size); - - if (count <= 0) { - ipod_print_error(" Error reading from disk: "); - return -1; - } - - memset(ipod->pinfo, 0, sizeof(ipod->pinfo)); - - if ((ipod->sectorbuf[510] == 0x55) && (ipod->sectorbuf[511] == 0xaa)) { - /* DOS partition table */ - ipod->macpod = 0; - /* parse partitions */ - for ( i = 0; i < 4; i++ ) { - unsigned char* ptr = ipod->sectorbuf + 0x1be + 16*i; - ipod->pinfo[i].type = ptr[4]; - ipod->pinfo[i].start = BYTES2INT32(ptr, 8); - ipod->pinfo[i].size = BYTES2INT32(ptr, 12); - - /* extended? */ - if ( ipod->pinfo[i].type == 5 ) { - /* not handled yet */ - } - } - } else if ((ipod->sectorbuf[0] == 'E') && (ipod->sectorbuf[1] == 'R')) { - /* Apple Partition Map */ - - /* APM parsing code based on the check_mac_partitions() function in - ipodloader2 - written by Thomas Tempelmann and released - under the GPL. */ - - int blkNo = 1; - int partBlkCount = 1; - int partBlkSizMul = ipod->sectorbuf[2] / 2; - - int pmMapBlkCnt; /* # of blks in partition map */ - int pmPyPartStart; /* physical start blk of partition */ - int pmPartBlkCnt; /* # of blks in this partition */ - int i = 0; - - ipod->macpod = 1; - - memset(ipod->pinfo,0,sizeof(ipod->pinfo)); - - while (blkNo <= partBlkCount) { - if (ipod_seek(ipod, blkNo * partBlkSizMul * 512) < 0) { - fprintf(stderr,"[ERR] Seek failed whilst reading APM\n"); - return -1; - } - - count = ipod_read(ipod, ipod->sector_size); - - if (count <= 0) { - ipod_print_error(" Error reading from disk: "); - return -1; - } - - /* see if it's a partition entry */ - if ((ipod->sectorbuf[0] != 'P') || (ipod->sectorbuf[1] != 'M')) { - /* end of partition table -> leave the loop */ - break; - } - - /* Extract the interesting entries */ - pmMapBlkCnt = be2int(ipod->sectorbuf + 4); - pmPyPartStart = be2int(ipod->sectorbuf + 8); - pmPartBlkCnt = be2int(ipod->sectorbuf + 12); - - /* update the number of part map blocks */ - partBlkCount = pmMapBlkCnt; - - if (strncmp((char*)(ipod->sectorbuf + 48), "Apple_MDFW", 32)==0) { - /* A Firmware partition */ - ipod->pinfo[i].start = pmPyPartStart; - ipod->pinfo[i].size = pmPartBlkCnt; - ipod->pinfo[i].type = 0; - i++; - } else if (strncmp((char*)(ipod->sectorbuf + 48), "Apple_HFS", 32)==0) { - /* A HFS partition */ - ipod->pinfo[i].start = pmPyPartStart; - ipod->pinfo[i].size = pmPartBlkCnt; - ipod->pinfo[i].type = PARTTYPE_HFS; - i++; - } - - blkNo++; /* read next partition map entry */ - } - } else { - if (!silent) fprintf(stderr,"[ERR] Bad boot sector signature\n"); - return -1; - } - - /* Check that the partition table looks like an ipod: - 1) Partition 1 is of type 0 (Empty) but isn't empty. - 2) Partition 2 is of type 0xb or 0xc (winpod) or -1 (macpod) - */ - if ((ipod->pinfo[0].type != 0) || (ipod->pinfo[0].size == 0) || - ((ipod->pinfo[1].type != 0xb) && (ipod->pinfo[1].type != 0xc) && - (ipod->pinfo[1].type != PARTTYPE_HFS))) { - if (!silent) fprintf(stderr,"[ERR] Partition layout is not an ipod\n"); - return -1; - } - - ipod->start = ipod->pinfo[0].start*ipod->sector_size; - return 0; -} - -int read_partition(struct ipod_t* ipod, int outfile) -{ - int res; - ssize_t n; - int bytesleft; - int chunksize; - int count = ipod->pinfo[0].size; - - if (ipod_seek(ipod, ipod->start) < 0) { - return -1; - } - if(ipod->sectorbuf == NULL) { - fprintf(stderr,"[ERR] Buffer not initialized."); - return -1; - } - - fprintf(stderr,"[INFO] Writing %d sectors to output file\n",count); - - bytesleft = count * ipod->sector_size; - while (bytesleft > 0) { - if (bytesleft > BUFFER_SIZE) { - chunksize = BUFFER_SIZE; - } else { - chunksize = bytesleft; - } - - n = ipod_read(ipod, chunksize); - - if (n < 0) { - return -1; - } - - if (n < chunksize) { - fprintf(stderr, - "[ERR] Short read in disk_read() - requested %d, got %d\n", - chunksize,(int)n); - return -1; - } - - bytesleft -= n; - - res = write(outfile,ipod->sectorbuf,n); - - if (res < 0) { - perror("[ERR] write in disk_read"); - return -1; - } - - if (res != n) { - fprintf(stderr, - "Short write - requested %d, received %d - aborting.\n",(int)n,res); - return -1; - } - } - - fprintf(stderr,"[INFO] Done.\n"); - return 0; -} - -int write_partition(struct ipod_t* ipod, int infile) -{ - ssize_t res; - int n; - int bytesread; - int byteswritten = 0; - int eof; - int padding = 0; - - if (ipod_seek(ipod, ipod->start) < 0) { - return -1; - } - if(ipod->sectorbuf == NULL) { - fprintf(stderr,"[ERR] Buffer not initialized."); - return -1; - } - - fprintf(stderr,"[INFO] Writing input file to device\n"); - bytesread = 0; - eof = 0; - while (!eof) { - n = read(infile,ipod->sectorbuf,BUFFER_SIZE); - - if (n < 0) { - perror("[ERR] read in disk_write"); - return -1; - } - - if (n < BUFFER_SIZE) { - eof = 1; - /* We need to pad the last write to a multiple of SECTOR_SIZE */ - if ((n % ipod->sector_size) != 0) { - padding = (ipod->sector_size-(n % ipod->sector_size)); - n += padding; - } - } - - bytesread += n; - - res = ipod_write(ipod, n); - - if (res < 0) { - ipod_print_error(" Error writing to disk: "); - fprintf(stderr,"Bytes written: %d\n",byteswritten); - return -1; - } - - if (res != n) { - fprintf(stderr,"[ERR] Short write - requested %d, received %d - aborting.\n",n,(int)res); - return -1; - } - - byteswritten += res; - } - - fprintf(stderr,"[INFO] Wrote %d bytes plus %d bytes padding.\n", - byteswritten-padding,padding); - return 0; -} - -char* ftypename[] = { "OSOS", "RSRC", "AUPD", "HIBE", "OSBK" }; - -int diskmove(struct ipod_t* ipod, int delta) -{ - int src_start; - int src_end; - int bytesleft; - int chunksize; - int n; - - src_start = ipod->ipod_directory[1].devOffset; - src_end = (ipod->ipod_directory[ipod->nimages-1].devOffset + ipod->sector_size + - ipod->ipod_directory[ipod->nimages-1].len + - (ipod->sector_size-1)) & ~(ipod->sector_size-1); - bytesleft = src_end - src_start; - - if (ipod_verbose) { - fprintf(stderr,"[INFO] Need to move images 2-%d forward %08x bytes\n", ipod->nimages,delta); - fprintf(stderr,"[VERB] src_start = %08x\n",src_start); - fprintf(stderr,"[VERB] src_end = %08x\n",src_end); - fprintf(stderr,"[VERB] dest_start = %08x\n",src_start+delta); - fprintf(stderr,"[VERB] dest_end = %08x\n",src_end+delta); - fprintf(stderr,"[VERB] bytes to copy = %08x\n",bytesleft); - } - - while (bytesleft > 0) { - if (bytesleft <= BUFFER_SIZE) { - chunksize = bytesleft; - } else { - chunksize = BUFFER_SIZE; - } - - if (ipod_verbose) { - fprintf(stderr,"[VERB] Copying %08x bytes from %08x to %08x (absolute %08x to %08x)\n", - chunksize, - src_end-chunksize, - src_end-chunksize+delta, - (unsigned int)(ipod->start+src_end-chunksize), - (unsigned int)(ipod->start+src_end-chunksize+delta)); - } - - - if (ipod_seek(ipod, ipod->start+src_end-chunksize) < 0) { - fprintf(stderr,"[ERR] Seek failed\n"); - return -1; - } - - if ((n = ipod_read(ipod,chunksize)) < 0) { - perror("[ERR] Write failed\n"); - return -1; - } - - if (n < chunksize) { - fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n", - chunksize,n); - return -1; - } - - if (ipod_seek(ipod, ipod->start+src_end-chunksize+delta) < 0) { - fprintf(stderr,"[ERR] Seek failed\n"); - return -1; - } - - if ((n = ipod_write(ipod,chunksize)) < 0) { - perror("[ERR] Write failed\n"); - return -1; - } - - if (n < chunksize) { - fprintf(stderr,"[ERR] Short write - requested %d bytes, received %d\n" - ,chunksize,n); - return -1; - } - - src_end -= chunksize; - bytesleft -= chunksize; - } - - return 0; -} - -static int rename_image(struct ipod_t* ipod, char* from, char* to) -{ - int n; - int x; - int found; - int i; - unsigned char* p; - - /* diroffset may not be sector-aligned */ - x = ipod->diroffset % ipod->sector_size; - - if(ipod->sectorbuf == NULL) { - fprintf(stderr,"[ERR] Buffer not initialized."); - return -1; - } - /* Read directory */ - if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { - fprintf(stderr,"[ERR] Seek to diroffset (%08x) failed.\n",(unsigned)ipod->diroffset); - return -1; - } - - n=ipod_read(ipod, ipod->sector_size); - if (n < 0) { - fprintf(stderr,"[ERR] Read of directory failed.\n"); - return -1; - } - - p = ipod->sectorbuf + x; - - /* A hack to detect 2nd gen Nanos - maybe there is a better way? */ - if (p[0] == 0) - { - /* Adjust diroffset */ - ipod->diroffset += ipod->sector_size - x; - - n=ipod_read(ipod, ipod->sector_size); - if (n < 0) { - fprintf(stderr,"[ERR] Read of directory failed.\n"); - return -1; - } - p = ipod->sectorbuf; - } - - found = 0; - for (i=0 ; !found && i < MAX_IMAGES; i++) { - if (memcmp(p + 4, from, 4) == 0) { - memcpy(p + 4, to, 4); - - found = 1; - } - p += 40; - } - - if (!found) { - fprintf(stderr,"[ERR] Unexpected error - no \"%s\" image!\n", from); - return -1; - } - - /* Write directory back to disk */ - if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { - fprintf(stderr,"[ERR] Seek to diroffset (%08x) failed.\n",(unsigned)ipod->diroffset); - return -1; - } - - n=ipod_write(ipod, ipod->sector_size); - if (n < 0) { - fprintf(stderr,"[ERR] Write of directory failed in rename_image.\n"); - return -1; - } - - return 0; -} - -static int delete_image(struct ipod_t* ipod, char* name) -{ - int n; - int x; - int found; - int i; - unsigned char* p; - - /* diroffset may not be sector-aligned */ - x = ipod->diroffset % ipod->sector_size; - - /* Read directory */ - if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { - fprintf(stderr,"[ERR] Seek to diroffset (%08x) failed.\n",(unsigned)ipod->diroffset); - return -1; - } - - n=ipod_read(ipod, ipod->sector_size); - if (n < 0) { - fprintf(stderr,"[ERR] Read of directory failed.\n"); - return -1; - } - - p = ipod->sectorbuf + x; - - /* A hack to detect 2nd gen Nanos - maybe there is a better way? */ - if (p[0] == 0) - { - /* Adjust diroffset */ - ipod->diroffset += ipod->sector_size - x; - - n=ipod_read(ipod, ipod->sector_size); - if (n < 0) { - fprintf(stderr,"[ERR] Read of directory failed.\n"); - return -1; - } - p = ipod->sectorbuf; - } - - found = 0; - for (i=0 ; !found && i < MAX_IMAGES; i++) { - if (memcmp(p + 4, name, 4) == 0) { - memset(p, 0, 40); /* Delete directory entry */ - found = 1; - } - p += 40; - } - - if (!found) { - fprintf(stderr,"[ERR] Unexpected error - no \"%s\" image!\n", name); - return -1; - } - - /* Write directory back to disk */ - if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { - fprintf(stderr,"[ERR] Seek to diroffset (%08x) failed.\n",(unsigned)ipod->diroffset); - return -1; - } - - n=ipod_write(ipod, ipod->sector_size); - if (n < 0) { - fprintf(stderr,"[ERR] Write of directory failed in delete_image.\n"); - return -1; - } - - return 0; -} - -int add_new_image(struct ipod_t* ipod, char* imagename, char* filename, int type) -{ - int length; - int found; - int i; - int x; - int n; - int infile; - int newsize; - unsigned long chksum=0; - unsigned long filechksum=0; - unsigned long offset; - unsigned char header[8]; /* Header for .ipod file */ - unsigned char* p; - - if(ipod->sectorbuf == NULL) { - fprintf(stderr,"[ERR] Buffer not initialized."); - return -1; - } -#ifdef WITH_BOOTOBJS - if (type == FILETYPE_INTERNAL) { - fprintf(stderr,"[INFO] Using internal bootloader - %d bytes\n",ipod->bootloader_len); - length = ipod->bootloader_len; - infile = -1; - } - else -#endif - { - /* First check that the input file is the correct type for this ipod. */ - infile=open(filename,O_RDONLY); - if (infile < 0) { - fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename); - return -1; - } - - if (type==FILETYPE_DOT_IPOD) { - n = read(infile,header,8); - if (n < 8) { - fprintf(stderr,"[ERR] Failed to read header from %s\n",filename); - close(infile); - return -1; - } - - if (memcmp(header+4, ipod->modelname,4)!=0) { - fprintf(stderr,"[ERR] Model name in input file (%c%c%c%c) doesn't match ipod model (%s)\n", - header[4],header[5],header[6],header[7], ipod->modelname); - close(infile); - return -1; - } - - filechksum = be2int(header); - - length = filesize(infile)-8; - } else { - length = filesize(infile); - } - } - - newsize=(length+ipod->sector_size-1)&~(ipod->sector_size-1); - - fprintf(stderr,"[INFO] Padding input file from 0x%08x to 0x%08x bytes\n", - length,newsize); - - if (newsize > BUFFER_SIZE) { - fprintf(stderr,"[ERR] Input file too big for buffer\n"); - if (infile >= 0) close(infile); - return -1; - } - - /* TODO: Check if we have enough space in the partition for the new image */ - -#ifdef WITH_BOOTOBJS - if (type == FILETYPE_INTERNAL) { - memcpy(ipod->sectorbuf,ipod->bootloader,ipod->bootloader_len); - } - else -#endif - { - fprintf(stderr,"[INFO] Reading input file...\n"); - - n = read(infile,ipod->sectorbuf,length); - if (n < 0) { - fprintf(stderr,"[ERR] Couldn't read input file\n"); - close(infile); - return -1; - } - close(infile); - } - - /* Pad the data with zeros */ - memset(ipod->sectorbuf+length,0,newsize-length); - - if (type==FILETYPE_DOT_IPOD) { - chksum = ipod->modelnum; - for (i = 0; i < length; i++) { - /* add 8 unsigned bits but keep a 32 bit sum */ - chksum += ipod->sectorbuf[i]; - } - - if (chksum == filechksum) { - fprintf(stderr,"[INFO] Checksum OK in %s\n",filename); - } else { - fprintf(stderr,"[ERR] Checksum in %s failed check\n",filename); - return -1; - } - } - - - offset = ipod->fwoffset + ipod->ipod_directory[ipod->nimages - 1].devOffset + - ipod->ipod_directory[ipod->nimages - 1].len + ipod->sector_size; - - /* 2nd Gen Nano has encrypted firmware, and the sector - preceeding the firmware contains hashes that need to be - preserved. Nano 2G images include these extra 2048 (0x800) - bytes - */ - if (ipod_seek(ipod, offset - (ipod->modelnum == 62 ? 0x800 : 0)) < 0) { - fprintf(stderr,"[ERR] Seek failed\n"); - return -1; - } - - if ((n = ipod_write(ipod,newsize)) < 0) { - perror("[ERR] Write failed\n"); - return -1; - } - - if (n < newsize) { - fprintf(stderr,"[ERR] Short write - requested %d bytes, received %d\n" - ,newsize,n); - return -1; - } - fprintf(stderr,"[INFO] Wrote %d bytes to firmware partition\n",n); - - /* Now we need to create a new directory entry - - NOTE: On the Nano 2G, the checksum is the checksum of the - unencrypted firmware. But this isn't checked by the NOR - bootloader (there are cryptographic hashes in the - firmware itself), so it doesn't matter that this is - wrong. - */ - chksum = 0; - for (i = 0; i < length; i++) { - /* add 8 unsigned bits but keep a 32 bit sum */ - chksum += ipod->sectorbuf[i]; - } - - x = ipod->diroffset % ipod->sector_size; - - /* Read directory */ - if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } - - n=ipod_read(ipod, ipod->sector_size); - if (n < 0) { return -1; } - - /* Create a new directory entry */ - - /* Copy OSOS or OSBK details - we assume one of them exists */ - p = ipod->sectorbuf + x; - found = 0; - for (i = 0; !found && i < ipod->nimages; i++) { - if ((memcmp(p + 4, "soso", 4)==0) || (memcmp(p + 4, "kbso", 4)==0)) { - found = 1; - } else { - p += 40; - } - } - - if (!found) { - fprintf(stderr,"[ERR] No OSOS or OSBK image to copy directory from\n"); - return -1; - } - - /* Copy directory image */ - memcpy(ipod->sectorbuf + x + (ipod->nimages * 40), p, 40); - p = ipod->sectorbuf + x + (ipod->nimages * 40); - - /* Modify directory. */ - memcpy(p + 4, imagename, 4); - int2le(offset - ipod->fwoffset, p + 12); /* devOffset */ - int2le(length - (ipod->modelnum==62 ? 0x800: 0), p + 16); /* len */ - int2le(chksum, p + 28); /* checksum */ - - /* Write directory */ - if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } - n=ipod_write(ipod, ipod->sector_size); - if (n < 0) { return -1; } - - return 0; -} - - -int ipod_has_bootloader(struct ipod_t* ipod) -{ - /* The 2nd gen Nano is installed differently */ - if (ipod->modelnum == 62) { - int i; - int has_osbk = 0; - /* Check if we have an OSBK image */ - for (i = 0; i < ipod->nimages; i++) { - if (ipod->ipod_directory[i].ftype==FTYPE_OSBK) { - has_osbk = 1; - } - } - return has_osbk; - } - else { - return (ipod->ipod_directory[0].entryOffset != 0); - } -} - - -/* - Bootloader installation on the Nano2G consists of renaming the - OSOS image to OSBK and then writing the Rockbox bootloader as a - new OSOS image. - - Maybe this approach can/should be adapted for other ipods, as it - prevents the Apple bootloader loading the original firmware into - RAM along with the Rockbox bootloader (and hence will give a - faster boot when the user just wants to start Rockbox). - -*/ - -static int add_bootloader_nano2g(struct ipod_t* ipod, char* filename, int type) -{ - /* Check if we already have an OSBK image */ - if (ipod_has_bootloader(ipod) == 0) { - /* First-time install - rename OSOS to OSBK and create new OSOS for bootloader */ - fprintf(stderr,"[INFO] Creating OSBK backup image of original firmware\n"); - - if (rename_image(ipod, "soso", "kbso") < 0) { - fprintf(stderr,"[ERR] Could not rename OSOS image\n"); - return -1; - } - - /* Add our bootloader as a brand new image */ - return add_new_image(ipod, "soso", filename, type); - } else { - /* This is an update, just replace OSOS with our bootloader */ - - return write_firmware(ipod, filename, type); - } -} - - -static int delete_bootloader_nano2g(struct ipod_t* ipod) -{ - /* Check if we have an OSBK image */ - if (ipod_has_bootloader(ipod) == 0) { - fprintf(stderr,"[ERR] No OSBK image found - nothing to uninstall\n"); - return -1; - } else { - /* Delete our bootloader image */ - if (delete_image(ipod, "soso") < 0) { - fprintf(stderr,"[WARN] Could not delete OSOS image\n"); - } else { - fprintf(stderr,"[INFO] OSOS image deleted\n"); - } - - if (rename_image(ipod, "kbso", "soso") < 0) { - fprintf(stderr,"[ERR] Could not rename OSBK image\n"); - return -1; - } - - - fprintf(stderr,"[INFO] OSBK image renamed to OSOS - bootloader uninstalled.\n"); - return 0; - } -} - - -int add_bootloader(struct ipod_t* ipod, char* filename, int type) -{ - int length; - int i; - int x; - int n; - int infile; - int paddedlength; - int entryOffset; - int delta = 0; - unsigned long chksum=0; - unsigned long filechksum=0; - unsigned char header[8]; /* Header for .ipod file */ - unsigned char* bootloader_buf; - - /* The 2nd gen Nano is installed differently */ - if (ipod->modelnum == 62) { - return add_bootloader_nano2g(ipod, filename, type); - } - if(ipod->sectorbuf == NULL) { - fprintf(stderr,"[ERR] Buffer not initialized."); - return -1; - } - - /* Calculate the position in the OSOS image where our bootloader will go. */ - if (ipod->ipod_directory[0].entryOffset>0) { - /* Keep the same entryOffset */ - entryOffset = ipod->ipod_directory[0].entryOffset; - } else { - entryOffset = (ipod->ipod_directory[0].len+ipod->sector_size-1)&~(ipod->sector_size-1); - } - -#ifdef WITH_BOOTOBJS - if (type == FILETYPE_INTERNAL) { - fprintf(stderr,"[INFO] Using internal bootloader - %d bytes\n",ipod->bootloader_len); - memcpy(ipod->sectorbuf+entryOffset,ipod->bootloader,ipod->bootloader_len); - length = ipod->bootloader_len; - paddedlength=(ipod->bootloader_len+ipod->sector_size-1)&~(ipod->sector_size-1); - } - else -#endif - { - infile=open(filename,O_RDONLY); - if (infile < 0) { - fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename); - return -1; - } - - if (type==FILETYPE_DOT_IPOD) { - /* First check that the input file is the correct type for this ipod. */ - n = read(infile,header,8); - if (n < 8) { - fprintf(stderr,"[ERR] Failed to read header from %s\n",filename); - close(infile); - return -1; - } - - if (memcmp(header+4, ipod->modelname,4)!=0) { - fprintf(stderr,"[ERR] Model name in input file (%c%c%c%c) doesn't match ipod model (%s)\n", - header[4],header[5],header[6],header[7], ipod->modelname); - close(infile); - return -1; - } - - filechksum = be2int(header); - - length=filesize(infile)-8; - } else { - length=filesize(infile); - } - paddedlength=(length+ipod->sector_size-1)&~(ipod->sector_size-1); - - bootloader_buf = malloc(length); - if (bootloader_buf == NULL) { - fprintf(stderr,"[ERR] Can not allocate memory for bootloader\n"); - return -1; - } - /* Now read our bootloader - we need to check it before modifying the partition*/ - n = read(infile,bootloader_buf,length); - close(infile); - - if (n < 0) { - fprintf(stderr,"[ERR] Couldn't read input file\n"); - return -1; - } - - if (type==FILETYPE_DOT_IPOD) { - /* Calculate and confirm bootloader checksum */ - chksum = ipod->modelnum; - for (i = 0; i < length; i++) { - /* add 8 unsigned bits but keep a 32 bit sum */ - chksum += bootloader_buf[i]; - } - - if (chksum == filechksum) { - fprintf(stderr,"[INFO] Checksum OK in %s\n",filename); - } else { - fprintf(stderr,"[ERR] Checksum in %s failed check\n",filename); - return -1; - } - } - } - - if (entryOffset+paddedlength > BUFFER_SIZE) { - fprintf(stderr,"[ERR] Input file too big for buffer\n"); - return -1; - } - - if (ipod_verbose) { - fprintf(stderr,"[VERB] Original firmware begins at 0x%08x\n", ipod->ipod_directory[0].devOffset + ipod->sector_size); - fprintf(stderr,"[VERB] New entryOffset will be 0x%08x\n",entryOffset); - fprintf(stderr,"[VERB] End of bootloader will be at 0x%08x\n",entryOffset+paddedlength); - } - - /* Check if we have enough space */ - /* TODO: Check the size of the partition. */ - if (ipod->nimages > 1) { - if ((ipod->ipod_directory[0].devOffset+entryOffset+paddedlength) > - ipod->ipod_directory[1].devOffset) { - fprintf(stderr,"[INFO] Moving images to create room for new firmware...\n"); - delta = ipod->ipod_directory[0].devOffset + entryOffset+paddedlength - - ipod->ipod_directory[1].devOffset + ipod->sector_size; - - if (diskmove(ipod, delta) < 0) { - fprintf(stderr,"[ERR] Image movement failed.\n"); - return -1; - } - } - } - - - /* We have moved the partitions, now we can write our bootloader */ - - /* Firstly read the original firmware into ipod->sectorbuf */ - fprintf(stderr,"[INFO] Reading original firmware...\n"); - if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[0].devOffset) < 0) { - fprintf(stderr,"[ERR] Seek failed\n"); - return -1; - } - - if ((n = ipod_read(ipod,entryOffset)) < 0) { - perror("[ERR] Read failed\n"); - return -1; - } - - if (n < entryOffset) { - fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n" - ,entryOffset,n); - return -1; - } - -#ifdef WITH_BOOTOBJS - if (type == FILETYPE_INTERNAL) { - memcpy(ipod->sectorbuf+entryOffset,ipod->bootloader,ipod->bootloader_len); - } - else -#endif - { - memcpy(ipod->sectorbuf+entryOffset,bootloader_buf,length); - free(bootloader_buf); - } - - /* Calculate new checksum for combined image */ - chksum = 0; - for (i=0;i<entryOffset + length; i++) { - chksum += ipod->sectorbuf[i]; - } - - /* Now write the combined firmware image to the disk */ - - if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[0].devOffset) < 0) { - fprintf(stderr,"[ERR] Seek failed\n"); - return -1; - } - - if ((n = ipod_write(ipod,entryOffset+paddedlength)) < 0) { - perror("[ERR] Write failed\n"); - return -1; - } - - if (n < (entryOffset+paddedlength)) { - fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n" - ,entryOffset+paddedlength,n); - return -1; - } - - fprintf(stderr,"[INFO] Wrote %d bytes to firmware partition\n",entryOffset+paddedlength); - - x = ipod->diroffset % ipod->sector_size; - - /* Read directory */ - if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { - fprintf(stderr,"[ERR] Seek failed\n"); - return -1; - } - - n=ipod_read(ipod, ipod->sector_size); - if (n < 0) { - fprintf(stderr,"[ERR] Directory read failed\n"); - return -1; - } - - /* Update entries for image 0 */ - int2le(entryOffset+length,ipod->sectorbuf+x+16); - int2le(entryOffset,ipod->sectorbuf+x+24); - int2le(chksum,ipod->sectorbuf+x+28); - int2le(0xffffffff,ipod->sectorbuf+x+36); /* loadAddr */ - - /* Update devOffset entries for other images, if we have moved them */ - if (delta > 0) { - for (i=1;i<ipod->nimages;i++) { - int2le(le2int(ipod->sectorbuf+x+i*40+12)+delta,ipod->sectorbuf+x+i*40+12); - } - } - - /* Write directory */ - if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { - fprintf(stderr,"[ERR] Seek to %d failed\n", (int)(ipod->start+ipod->diroffset-x)); - return -1; - } - n=ipod_write(ipod, ipod->sector_size); - if (n < 0) { - fprintf(stderr,"[ERR] Directory write failed\n"); - return -1; - } - - return 0; -} - -int delete_bootloader(struct ipod_t* ipod) -{ - int length; - int i; - int x; - int n; - unsigned long chksum=0; /* 32 bit checksum - Rockbox .ipod style*/ - - /* The 2nd gen Nano is installed differently */ - if (ipod->modelnum == 62) { - return delete_bootloader_nano2g(ipod); - } - if(ipod->sectorbuf == NULL) { - fprintf(stderr,"[ERR] Buffer not initialized."); - return -1; - } - - /* Removing the bootloader involves adjusting the "length", - "chksum" and "entryOffset" values in the osos image's directory - entry. */ - - /* Firstly check we have a bootloader... */ - - if (ipod_has_bootloader(ipod) == 0) { - fprintf(stderr,"[ERR] No bootloader found.\n"); - return -1; - } - - length = ipod->ipod_directory[0].entryOffset; - - /* Read the firmware so we can calculate the checksum */ - fprintf(stderr,"[INFO] Reading firmware (%d bytes)\n",length); - - if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[0].devOffset) < 0) { - return -1; - } - - i = (length+ipod->sector_size-1) & ~(ipod->sector_size-1); - fprintf(stderr,"[INFO] Padding read from 0x%08x to 0x%08x bytes\n", - length,i); - - if ((n = ipod_read(ipod,i)) < 0) { - return -1; - } - - if (n < i) { - fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n", - i,n); - return -1; - } - - chksum = 0; - for (i = 0; i < length; i++) { - /* add 8 unsigned bits but keep a 32 bit sum */ - chksum += ipod->sectorbuf[i]; - } - - /* Now write back the updated directory entry */ - - fprintf(stderr,"[INFO] Updating firmware checksum\n"); - - x = ipod->diroffset % ipod->sector_size; - - /* Read directory */ - if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } - - n=ipod_read(ipod, ipod->sector_size); - if (n < 0) { return -1; } - - /* Update entries for image 0 */ - int2le(length,ipod->sectorbuf+x+16); - int2le(0,ipod->sectorbuf+x+24); - int2le(chksum,ipod->sectorbuf+x+28); - - /* Write directory */ - if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } - n=ipod_write(ipod, ipod->sector_size); - if (n < 0) { return -1; } - - return 0; -} - -int write_firmware(struct ipod_t* ipod, char* filename, int type) -{ - int length; - int i; - int x; - int n; - int infile; - int newsize; - int bytesavailable; - unsigned long chksum=0; - unsigned long filechksum=0; - unsigned long offset; - unsigned char header[8]; /* Header for .ipod file */ - unsigned char* p; - - if(ipod->sectorbuf == NULL) { - fprintf(stderr,"[ERR] Buffer not initialized."); - return -1; - } -#ifdef WITH_BOOTOBJS - if (type == FILETYPE_INTERNAL) { - fprintf(stderr,"[INFO] Using internal bootloader - %d bytes\n",ipod->bootloader_len); - length = ipod->bootloader_len; - infile = -1; - } - else -#endif - { - /* First check that the input file is the correct type for this ipod. */ - infile=open(filename,O_RDONLY); - if (infile < 0) { - fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename); - return -1; - } - - if (type==FILETYPE_DOT_IPOD) { - n = read(infile,header,8); - if (n < 8) { - fprintf(stderr,"[ERR] Failed to read header from %s\n",filename); - close(infile); - return -1; - } - - if (memcmp(header+4, ipod->modelname,4)!=0) { - fprintf(stderr,"[ERR] Model name in input file (%c%c%c%c) doesn't match ipod model (%s)\n", - header[4],header[5],header[6],header[7], ipod->modelname); - close(infile); - return -1; - } - - filechksum = be2int(header); - - length = filesize(infile)-8; - } else { - length = filesize(infile); - } - } - - newsize=(length+ipod->sector_size-1)&~(ipod->sector_size-1); - - fprintf(stderr,"[INFO] Padding input file from 0x%08x to 0x%08x bytes\n", - length,newsize); - - if (newsize > BUFFER_SIZE) { - fprintf(stderr,"[ERR] Input file too big for buffer\n"); - if (infile >= 0) close(infile); - return -1; - } - - /* Check if we have enough space */ - /* TODO: Check the size of the partition. */ - if (ipod->nimages > 1) { - bytesavailable=ipod->ipod_directory[1].devOffset-ipod->ipod_directory[0].devOffset; - if (bytesavailable < newsize) { - fprintf(stderr,"[INFO] Moving images to create room for new firmware...\n"); - - /* TODO: Implement image movement */ - fprintf(stderr,"[ERR] Image movement not yet implemented.\n"); - close(infile); - return -1; - } - } - -#ifdef WITH_BOOTOBJS - if (type == FILETYPE_INTERNAL) { - memcpy(ipod->sectorbuf,ipod->bootloader,ipod->bootloader_len); - } - else -#endif - { - fprintf(stderr,"[INFO] Reading input file...\n"); - /* We now know we have enough space, so write it. */ - n = read(infile,ipod->sectorbuf,length); - if (n < 0) { - fprintf(stderr,"[ERR] Couldn't read input file\n"); - close(infile); - return -1; - } - close(infile); - } - - /* Pad the data with zeros */ - memset(ipod->sectorbuf+length,0,newsize-length); - - if (type==FILETYPE_DOT_IPOD) { - chksum = ipod->modelnum; - for (i = 0; i < length; i++) { - /* add 8 unsigned bits but keep a 32 bit sum */ - chksum += ipod->sectorbuf[i]; - } - - if (chksum == filechksum) { - fprintf(stderr,"[INFO] Checksum OK in %s\n",filename); - } else { - fprintf(stderr,"[ERR] Checksum in %s failed check\n",filename); - return -1; - } - } - - - offset = ipod->fwoffset+ipod->ipod_directory[ipod->ososimage].devOffset; - - if (ipod->modelnum==62) { - - /* 2nd Gen Nano has encrypted firmware, and the sector - preceeding the firmware contains hashes that need to be - preserved. Nano 2G images include these extra 2048 (0x800) - bytes - */ - - offset -= 0x800; - - /* TODO: The above checks need to take into account this 0x800 bytes */ - } - - if (ipod_seek(ipod, offset) < 0) { - fprintf(stderr,"[ERR] Seek failed\n"); - return -1; - } - - if ((n = ipod_write(ipod,newsize)) < 0) { - perror("[ERR] Write failed\n"); - return -1; - } - - if (n < newsize) { - fprintf(stderr,"[ERR] Short write - requested %d bytes, received %d\n" - ,newsize,n); - return -1; - } - fprintf(stderr,"[INFO] Wrote %d bytes to firmware partition\n",n); - - /* Now we need to update the "len", "entryOffset" and "chksum" fields - - NOTE: On the Nano 2G, the checksum is the checksum of the - unencrypted firmware. But this isn't checked by the NOR - bootloader (there are cryptographic hashes in the - firmware itself), so it doesn't matter that this is - wrong. - */ - chksum = 0; - for (i = 0; i < length; i++) { - /* add 8 unsigned bits but keep a 32 bit sum */ - chksum += ipod->sectorbuf[i]; - } - - x = ipod->diroffset % ipod->sector_size; - - /* Read directory */ - if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } - - n=ipod_read(ipod, ipod->sector_size); - if (n < 0) { return -1; } - - /* Update entries for image */ - p = ipod->sectorbuf + x + (ipod->ososimage * 40); - int2le(length - (ipod->modelnum==62 ? 0x800: 0), p + 16); - int2le(0, p + 24); - int2le(chksum, p + 28); - - /* Write directory */ - if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } - n=ipod_write(ipod, ipod->sector_size); - if (n < 0) { return -1; } - - return 0; -} - -int read_firmware(struct ipod_t* ipod, char* filename, int type) -{ - int length; - int i; - int outfile; - int n; - unsigned long offset; - unsigned long chksum=0; /* 32 bit checksum - Rockbox .ipod style*/ - unsigned char header[8]; /* Header for .ipod file */ - - if(ipod->sectorbuf == NULL) { - fprintf(stderr,"[ERR] Buffer not initialized."); - return -1; - } - if (ipod->ipod_directory[ipod->ososimage].entryOffset != 0) { - /* We have a bootloader... */ - length = ipod->ipod_directory[ipod->ososimage].entryOffset; - } else { - length = ipod->ipod_directory[ipod->ososimage].len; - } - - fprintf(stderr,"[INFO] Reading firmware (%d bytes)\n",length); - - offset = ipod->fwoffset + ipod->ipod_directory[ipod->ososimage].devOffset; - i = (length+ipod->sector_size-1) & ~(ipod->sector_size-1); - fprintf(stderr,"[INFO] Padding read from 0x%08x to 0x%08x bytes\n", - length,i); - - if (ipod->modelnum==62) { - /* 2nd Gen Nano has encrypted firmware, and we need to dump the - sector preceeding the image - it contains hashes */ - offset -= 0x800; - length += 0x800; - i += 0x800; - } - - if (ipod_seek(ipod, offset)) { - return -1; - } - - if ((n = ipod_read(ipod,i)) < 0) { - return -1; - } - - if (n < i) { - fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n", - i,n); - return -1; - } - - outfile = open(filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666); - if (outfile < 0) { - fprintf(stderr,"[ERR] Couldn't open file %s\n",filename); - return -1; - } - - if (type == FILETYPE_DOT_IPOD) { - chksum = ipod->modelnum; - for (i = 0; i < length; i++) { - /* add 8 unsigned bits but keep a 32 bit sum */ - chksum += ipod->sectorbuf[i]; - } - - int2be(chksum,header); - memcpy(header+4, ipod->modelname,4); - - n = write(outfile,header,8); - if (n != 8) { - fprintf(stderr,"[ERR] Write error - %d\n",n); - } - } - - n = write(outfile,ipod->sectorbuf,length); - if (n != length) { - fprintf(stderr,"[ERR] Write error - %d\n",n); - } - close(outfile); - - return 0; -} - -int read_directory(struct ipod_t* ipod) -{ - ssize_t n; - int x; - unsigned char* p; - unsigned short version; - - ipod->nimages=0; - - /* Read firmware partition header (first 512 bytes of disk - but - let's read a whole sector) */ - - if (ipod_seek(ipod, ipod->start) < 0) { - fprintf(stderr,"[ERR] Seek to 0x%08x in read_directory() failed.\n", - (unsigned int)(ipod->start)); - return -1; - } - - n=ipod_read(ipod, ipod->sector_size); - if (n < 0) { - fprintf(stderr,"[ERR] ipod_read(ipod,0x%08x) failed in read_directory()\n", ipod->sector_size); - return -1; - } - - if (memcmp(ipod->sectorbuf,apple_stop_sign,sizeof(apple_stop_sign))!=0) { - fprintf(stderr,"[ERR] Firmware partition doesn't contain Apple copyright, aborting.\n"); - return -1; - } - - if (memcmp(ipod->sectorbuf+0x100,"]ih[",4)!=0) { - fprintf(stderr,"[ERR] Bad firmware directory\n"); - return -1; - } - - version = le2ushort(ipod->sectorbuf+0x10a); - if ((version != 2) && (version != 3)) { - fprintf(stderr,"[ERR] Unknown firmware format version %04x\n", - version); - } - ipod->diroffset=le2int(ipod->sectorbuf+0x104) + 0x200; - - /* diroffset may not be sector-aligned */ - x = ipod->diroffset % ipod->sector_size; - - /* Read directory */ - if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { - fprintf(stderr,"[ERR] Seek to diroffset (%08x) failed.\n",(unsigned)ipod->diroffset); - return -1; - } - - n=ipod_read(ipod, ipod->sector_size); - if (n < 0) { - fprintf(stderr,"[ERR] Read of directory failed.\n"); - return -1; - } - - p = ipod->sectorbuf + x; - - /* A hack to detect 2nd gen Nanos - maybe there is a better way? */ - if (p[0] == 0) - { - /* Adjust diroffset */ - ipod->diroffset += ipod->sector_size - x; - - n=ipod_read(ipod, ipod->sector_size); - if (n < 0) { - fprintf(stderr,"[ERR] Read of directory failed.\n"); - return -1; - } - p = ipod->sectorbuf; - } - - ipod->ososimage = -1; - while ((ipod->nimages < MAX_IMAGES) && (p < (ipod->sectorbuf + x + 400)) && - ((memcmp(p,"!ATA",4)==0) || (memcmp(p,"DNAN",4)==0))) { - p+=4; - if (memcmp(p,"soso",4)==0) { - ipod->ipod_directory[ipod->nimages].ftype=FTYPE_OSOS; - ipod->ososimage = ipod->nimages; - } else if (memcmp(p,"crsr",4)==0) { - ipod->ipod_directory[ipod->nimages].ftype=FTYPE_RSRC; - } else if (memcmp(p,"dpua",4)==0) { - ipod->ipod_directory[ipod->nimages].ftype=FTYPE_AUPD; - } else if (memcmp(p,"kbso",4)==0) { - ipod->ipod_directory[ipod->nimages].ftype=FTYPE_OSBK; - } else if (memcmp(p,"ebih",4)==0) { - ipod->ipod_directory[ipod->nimages].ftype=FTYPE_HIBE; - } else { - fprintf(stderr,"[ERR] Unknown image type %c%c%c%c\n", - p[0],p[1],p[2],p[3]); - } - p+=4; - ipod->ipod_directory[ipod->nimages].id=le2int(p); - p+=4; - ipod->ipod_directory[ipod->nimages].devOffset=le2int(p); - p+=4; - ipod->ipod_directory[ipod->nimages].len=le2int(p); - p+=4; - ipod->ipod_directory[ipod->nimages].addr=le2int(p); - p+=4; - ipod->ipod_directory[ipod->nimages].entryOffset=le2int(p); - p+=4; - ipod->ipod_directory[ipod->nimages].chksum=le2int(p); - p+=4; - ipod->ipod_directory[ipod->nimages].vers=le2int(p); - p+=4; - ipod->ipod_directory[ipod->nimages].loadAddr=le2int(p); - p+=4; - ipod->nimages++; - } - - if (ipod->ososimage < 0) { - fprintf(stderr,"[ERR] No OSOS image found.\n"); - return -1; - } - - if ((ipod->nimages > 1) && (version==2)) { - /* The 3g firmware image doesn't appear to have a version, so - let's make one up... Note that this is never written back to the - ipod, so it's OK to do. */ - - if (ipod->ipod_directory[ipod->ososimage].vers == 0) { ipod->ipod_directory[ipod->ososimage].vers = 3; } - - ipod->fwoffset = ipod->start; - } else { - ipod->fwoffset = ipod->start + ipod->sector_size; - } - - return 0; -} - -int list_images(struct ipod_t* ipod) -{ - int i; - - if (ipod_verbose) { - printf(" Type id devOffset len addr entryOffset chksum vers loadAddr devOffset+len\n"); - for (i = 0 ; i < ipod->nimages; i++) { - printf("%d - %s 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",i, - ftypename[ipod->ipod_directory[i].ftype], - ipod->ipod_directory[i].id, - ipod->ipod_directory[i].devOffset, - ipod->ipod_directory[i].len, - ipod->ipod_directory[i].addr, - ipod->ipod_directory[i].entryOffset, - ipod->ipod_directory[i].chksum, - ipod->ipod_directory[i].vers, - ipod->ipod_directory[i].loadAddr, - ipod->ipod_directory[i].devOffset+((ipod->ipod_directory[i].len+ipod->sector_size-1)&~(ipod->sector_size-1))); - } - } - - printf("\n"); - printf("Listing firmware partition contents:\n"); - printf("\n"); - - for (i = 0 ; i < ipod->nimages; i++) { - printf("Image %d:\n",i+1); - switch(ipod->ipod_directory[i].ftype) { - case FTYPE_OSOS: - if (ipod->ipod_directory[i].entryOffset==0) { - printf(" Main firmware - %d bytes\n", - ipod->ipod_directory[i].len); - } else { - printf(" Main firmware - %d bytes\n", - ipod->ipod_directory[i].entryOffset); - printf(" Third-party bootloader - %d bytes\n", - ipod->ipod_directory[i].len-ipod->ipod_directory[i].entryOffset); - } - break; - default: - printf(" %s - %d bytes\n", - ftypename[ipod->ipod_directory[i].ftype], - ipod->ipod_directory[i].len); - } - } - printf("\n"); - - return 0; -} - -int getmodel(struct ipod_t* ipod, int ipod_version) -{ - switch (ipod_version) { - case 0x01: - ipod->modelstr="1st or 2nd Generation"; - ipod->modelnum = 19; - ipod->modelname = "1g2g"; - ipod->targetname = "ipod1g2g"; -#ifdef WITH_BOOTOBJS - ipod->bootloader = ipod1g2g; - ipod->bootloader_len = LEN_ipod1g2g; -#endif - break; - case 0x02: - ipod->modelstr="3rd Generation"; - ipod->modelnum = 7; - ipod->modelname = "ip3g"; - ipod->targetname = "ipod3g"; -#ifdef WITH_BOOTOBJS - ipod->bootloader = ipod3g; - ipod->bootloader_len = LEN_ipod3g; -#endif - break; - case 0x40: - ipod->modelstr="1st Generation Mini"; - ipod->modelnum = 9; - ipod->modelname = "mini"; - ipod->targetname = "ipodmini1g"; -#ifdef WITH_BOOTOBJS - ipod->bootloader = ipodmini1g; - ipod->bootloader_len = LEN_ipodmini1g; -#endif - break; - case 0x50: - ipod->modelstr="4th Generation"; - ipod->modelnum = 8; - ipod->modelname = "ip4g"; - ipod->targetname = "ipod4gray"; -#ifdef WITH_BOOTOBJS - ipod->bootloader = ipod4g; - ipod->bootloader_len = LEN_ipod4g; -#endif - break; - case 0x60: - ipod->modelstr="Photo/Color"; - ipod->modelnum = 3; - ipod->modelname = "ipco"; - ipod->targetname = "ipodcolor"; -#ifdef WITH_BOOTOBJS - ipod->bootloader = ipodcolor; - ipod->bootloader_len = LEN_ipodcolor; -#endif - break; - case 0x70: - ipod->modelstr="2nd Generation Mini"; - ipod->modelnum = 11; - ipod->modelname = "mn2g"; - ipod->targetname = "ipodmini2g"; -#ifdef WITH_BOOTOBJS - ipod->bootloader = ipodmini2g; - ipod->bootloader_len = LEN_ipodmini2g; -#endif - break; - case 0xc0: - ipod->modelstr="1st Generation Nano"; - ipod->modelnum = 4; - ipod->modelname = "nano"; - ipod->targetname = "ipodnano1g"; -#ifdef WITH_BOOTOBJS - ipod->bootloader = ipodnano1g; - ipod->bootloader_len = LEN_ipodnano1g; -#endif - break; - case 0xb0: - ipod->modelstr="Video (aka 5th Generation)"; - ipod->modelnum = 5; - ipod->modelname = "ipvd"; - ipod->targetname = "ipodvideo"; -#ifdef WITH_BOOTOBJS - ipod->bootloader = ipodvideo; - ipod->bootloader_len = LEN_ipodvideo; -#endif - break; - case 0x100: - ipod->modelstr="2nd Generation Nano"; - ipod->modelnum = 62; - ipod->modelname = "nn2x"; - ipod->targetname = "ipodnano2g"; -#ifdef WITH_BOOTOBJS - ipod->bootloader = ipodnano2g; - ipod->bootloader_len = LEN_ipodnano2g; -#endif - break; - default: - ipod->modelname = NULL; - ipod->modelnum = 0; - ipod->targetname = NULL; -#ifdef WITH_BOOTOBJS - ipod->bootloader = NULL; - ipod->bootloader_len = 0; -#endif - return -1; - } - return 0; -} - -/* returns number of found ipods or -1 if no ipods found and permission - * for raw disc access was denied. */ -int ipod_scan(struct ipod_t* ipod) -{ - int i; - int n = 0; - int ipod_version; - struct ipod_t ipod_found; - int denied = 0; - int result; - - printf("[INFO] Scanning disk devices...\n"); - - for (i = 0; i <= 25 ; i++) { -#ifdef __WIN32__ - sprintf(ipod->diskname,"\\\\.\\PhysicalDrive%d",i); -#elif defined(linux) || defined (__linux) - sprintf(ipod->diskname,"/dev/sd%c",'a'+i); -#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) \ - || defined(__bsdi__) || defined(__DragonFly__) - sprintf(ipod->diskname,"/dev/da%d",i); -#elif defined(__APPLE__) && defined(__MACH__) - sprintf(ipod->diskname,"/dev/disk%d",i); -#else - #error No disk paths defined for this platform -#endif - if ((result = ipod_open(ipod, 1)) < 0) { - if(result == -2) { - denied++; - } - ipod_close(ipod); - continue; - } - - if (read_partinfo(ipod,1) < 0) { - ipod_close(ipod); - continue; - } - - if ((ipod->pinfo[0].start==0) || (ipod->pinfo[0].type != 0)) { - ipod_close(ipod); - continue; - } - - if (read_directory(ipod) < 0) { - ipod_close(ipod); - continue; - } - - ipod_version=(ipod->ipod_directory[ipod->ososimage].vers>>8); - ipod->ramsize = 0; -#ifdef __WIN32__ - /* Windows requires the ipod in R/W mode for SCSI Inquiry. - * ipod_reopen_rw does unmount the player on OS X so do this on - * W32 only during scanning. */ - ipod_reopen_rw(ipod); -#endif - ipod_get_xmlinfo(ipod); - ipod_get_ramsize(ipod); - if (getmodel(ipod,ipod_version) < 0) { - ipod_close(ipod); - continue; - } - -#ifdef __WIN32__ - printf("[INFO] Ipod found - %s (\"%s\") - disk device %d\n", - ipod->modelstr,ipod->macpod ? "macpod" : "winpod",i); -#else - printf("[INFO] Ipod found - %s (\"%s\") - %s\n", - ipod->modelstr,ipod->macpod ? "macpod" : "winpod",ipod->diskname); -#endif - n++; - /* save the complete ipod_t structure for match. The for loop might - * overwrite it, so we need to restore it later if only one found. */ - memcpy(&ipod_found, ipod, sizeof(struct ipod_t)); - ipod_close(ipod); - } - - if (n==1) { - /* restore the ipod_t structure, it might have been overwritten */ - memcpy(ipod, &ipod_found, sizeof(struct ipod_t)); - } - else if(n == 0 && denied) { - printf("[ERR] FATAL: Permission denied on %d device(s) and no ipod detected.\n", denied); -#ifdef __WIN32__ - printf("[ERR] You need to run this program with administrator priviledges!\n"); -#else - printf("[ERR] You need permissions for raw disc access for this program to work!\n"); -#endif - } - return (n == 0 && denied) ? -1 : n; -} - -static void put_int32le(uint32_t x, unsigned char* p) -{ - p[0] = x & 0xff; - p[1] = (x >> 8) & 0xff; - p[2] = (x >> 16) & 0xff; - p[3] = (x >> 24) & 0xff; -} - -int write_dos_partition_table(struct ipod_t* ipod) -{ - unsigned char* p; - int i, n; - uint32_t type; - - /* Only support 512-byte sectors at the moment */ - if ( ipod->sector_size != 512 ) - { - fprintf(stderr,"[ERR] Only ipods with 512 bytes per sector are supported.\n"); - return -1; - } - if(ipod->sectorbuf == NULL) { - fprintf(stderr,"[ERR] Buffer not initialized."); - return -1; - } - - /* Firstly zero the entire MBR */ - memset(ipod->sectorbuf, 0, ipod->sector_size); - - /* Now add the partition info */ - for (i=0; i < 4 ; i++) - { - p = ipod->sectorbuf + 0x1be + i*16; - - /* Ensure first partition is type 0, and second is 0xb */ - if (i==0) { type = 0; } - else if (i==1) { type = 0xb; } - else { type = ipod->pinfo[i].type; } - - put_int32le(type, p + 4); - put_int32le(ipod->pinfo[i].start, p + 8); - put_int32le(ipod->pinfo[i].size, p + 12); - } - - /* Finally add the magic */ - ipod->sectorbuf[0x1fe] = 0x55; - ipod->sectorbuf[0x1ff] = 0xaa; - - if (ipod_seek(ipod, 0) < 0) { - fprintf(stderr,"[ERR] Seek failed writing MBR\n"); - return -1; - } - - /* Write MBR */ - if ((n = ipod_write(ipod, ipod->sector_size)) < 0) { - perror("[ERR] Write failed\n"); - return -1; - } - - return 0; -} - -/* Get the XML Device Information, as documented here: - - http://www.ipodlinux.org/wiki/Device_Information -*/ - -int ipod_get_xmlinfo(struct ipod_t* ipod) -{ - unsigned char hdr[255]; - unsigned char buf[255]; - char* p; - int psize; - int npages; - int i; - - if (ipod_scsi_inquiry(ipod, 0xc0, buf, sizeof(buf)) < 0) - { - fprintf(stderr,"[ERR] Sending SCSI Command failed.\n"); - return -1; - } - - /* Reading directly into hdr[] causes problems (for an unknown reason) on - win32 */ - memcpy(hdr, buf, sizeof(hdr)); - - npages = hdr[3]; - - psize = npages * 0xf8; /* Hopefully this is enough. */ - - ipod->xmlinfo = malloc(psize); - ipod->xmlinfo_len = 0; - - if (ipod->xmlinfo == NULL) { - fprintf(stderr,"[ERR] Could not allocate RAM for xmlinfo\n"); - return -1; - } - - p = ipod->xmlinfo; - - for (i=0; i < npages; i++) { - if (ipod_scsi_inquiry(ipod, hdr[i+4], buf, sizeof(buf)) < 0) { - fprintf(stderr,"[ERR] Sending SCSI Command failed.\n"); - return -1; - } - - if ((buf[3] + ipod->xmlinfo_len) > psize) { - fprintf(stderr,"[ERR] Ran out of memory reading xmlinfo\n"); - free(ipod->xmlinfo); - ipod->xmlinfo = NULL; - ipod->xmlinfo_len = 0; - return -1; - } - - memcpy(p, buf + 4, buf[3]); - p += buf[3]; - ipod->xmlinfo_len += buf[3]; - } - - /* NULL-terminate the XML info */ - *p = 0; - - fprintf(stderr,"[INFO] Read XML info (%d bytes)\n",ipod->xmlinfo_len); - - return 0; -} - -void ipod_get_ramsize(struct ipod_t* ipod) -{ - const char needle[] = "<key>RAM</key>\n<integer>"; - char* p; - - if (ipod->xmlinfo == NULL) - return; - - p = strstr(ipod->xmlinfo, needle); - - if (p) { - ipod->ramsize = atoi(p + sizeof(needle) - 1); - } -} - -#ifndef RBUTIL - -static inline uint32_t getuint32le(unsigned char* buf) -{ - int32_t res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; - - return res; -} - -/* testMarker and GetSecurityBlockKey based on code from BadBlocks and - Kingstone, posted at http://ipodlinux.org/Flash_Decryption - -*/ - -static bool testMarker(int marker) -{ - int mask, decrypt, temp1, temp2; - - mask = (marker&0xff)|((marker&0xff)<<8)|((marker&0xff)<<16)|((marker&0xff)<<24); - decrypt = marker ^ mask; - temp1=(int)((unsigned int)decrypt>>24); - temp2=decrypt<<8; - - if (temp1==0) - return false; - - temp2=(int)((unsigned int)temp2>>24); - decrypt=decrypt<<16; - decrypt=(int)((unsigned int)decrypt>>24); - - if ((temp1 < temp2) && (temp2 < decrypt)) - { - temp1 = temp1 & 0xf; - temp2 = temp2 & 0xf; - decrypt = decrypt & 0xf; - - if ((temp1 > temp2) && (temp2 > decrypt) && (decrypt != 0)) - { - return true; - } - } - return false; -} - -static int GetSecurityBlockKey(unsigned char *data, unsigned char* this_key) -{ - int constant = 0x54c3a298; - int key=0; - int nkeys = 0; - int aMarker=0; - int pos=0; - int c, count; - int temp1; - static const int offset[8]={0x5,0x25,0x6f,0x69,0x15,0x4d,0x40,0x34}; - - for (c = 0; c < 8; c++) - { - pos = offset[c]*4; - aMarker = getuint32le(data + pos); - - if (testMarker(aMarker)) - { - if (c<7) - pos =(offset[c+1]*4)+4; - else - pos =(offset[0]*4)+4; - - key=0; - - temp1=aMarker; - - for (count=0;count<2;count++){ - int word = getuint32le(data + pos); - temp1 = aMarker; - temp1 = temp1^word; - temp1 = temp1^constant; - key = temp1; - pos = pos+4; - } - int r1=0x6f; - int r2=0; - int r12; - int r14; - unsigned int r_tmp; - - for (count=2;count<128;count=count+2){ - r2=getuint32le(data+count*4); - r12=getuint32le(data+(count*4)+4); - r_tmp=(unsigned int)r12>>16; - r14=r2 | ((int)r_tmp); - r2=r2&0xffff; - r2=r2 | r12; - r1=r1^r14; - r1=r1+r2; - } - key=key^r1; - - // Invert key, little endian - this_key[0] = key & 0xff; - this_key[1] = (key >> 8) & 0xff; - this_key[2] = (key >> 16) & 0xff; - this_key[3] = (key >> 24) & 0xff; - nkeys++; - } - } - return nkeys; -} - -static int find_key(struct ipod_t* ipod, int aupd, unsigned char* key) -{ - int n; - - /* Firstly read the security block and find the RC4 key. This is - in the sector preceeding the AUPD image. */ - - if(ipod->sectorbuf == NULL) { - fprintf(stderr,"[ERR] Buffer not initialized."); - return -1; - } - fprintf(stderr, "[INFO] Reading security block at offset 0x%08x\n",ipod->ipod_directory[aupd].devOffset-ipod->sector_size); - if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[aupd].devOffset-ipod->sector_size) < 0) { - return -1; - } - - if ((n = ipod_read(ipod, 512)) < 0) { - return -1; - } - - n = GetSecurityBlockKey(ipod->sectorbuf, key); - - if (n != 1) - { - fprintf(stderr, "[ERR] %d keys found in security block, can not continue\n",n); - return -1; - } - - return 0; -} - -int read_aupd(struct ipod_t* ipod, char* filename) -{ - int length; - int i; - int outfile; - int n; - int aupd; - struct rc4_key_t rc4; - unsigned char key[4]; - unsigned long chksum=0; - - if(ipod->sectorbuf == NULL) { - fprintf(stderr,"[ERR] Buffer not initialized."); - return -1; - } - aupd = 0; - while ((aupd < ipod->nimages) && (ipod->ipod_directory[aupd].ftype != FTYPE_AUPD)) - { - aupd++; - } - - if (aupd == ipod->nimages) - { - fprintf(stderr,"[ERR] No AUPD image in firmware partition.\n"); - return -1; - } - - length = ipod->ipod_directory[aupd].len; - - fprintf(stderr,"[INFO] Reading firmware (%d bytes)\n",length); - - if (find_key(ipod, aupd, key) < 0) - { - return -1; - } - - fprintf(stderr, "[INFO] Decrypting AUPD image with key %02x%02x%02x%02x\n",key[0],key[1],key[2],key[3]); - - if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[aupd].devOffset) < 0) { - return -1; - } - - i = (length+ipod->sector_size-1) & ~(ipod->sector_size-1); - - if ((n = ipod_read(ipod,i)) < 0) { - return -1; - } - - if (n < i) { - fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n", - i,n); - return -1; - } - - /* Perform the decryption - this is standard (A)RC4 */ - matrixArc4Init(&rc4, key, 4); - matrixArc4(&rc4, ipod->sectorbuf, ipod->sectorbuf, length); - - chksum = 0; - for (i = 0; i < (int)length; i++) { - /* add 8 unsigned bits but keep a 32 bit sum */ - chksum += ipod->sectorbuf[i]; - } - - if (chksum != ipod->ipod_directory[aupd].chksum) - { - fprintf(stderr,"[ERR] Decryption failed - checksum error\n"); - return -1; - } - fprintf(stderr,"[INFO] Decrypted OK (checksum matches header)\n"); - - outfile = open(filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666); - if (outfile < 0) { - fprintf(stderr,"[ERR] Couldn't open file %s\n",filename); - return -1; - } - - n = write(outfile,ipod->sectorbuf,length); - if (n != length) { - fprintf(stderr,"[ERR] Write error - %d\n",n); - } - close(outfile); - - return 0; -} - -int write_aupd(struct ipod_t* ipod, char* filename) -{ - unsigned int length; - int i; - int x; - int n; - int infile; - int newsize; - int aupd; - unsigned long chksum=0; - struct rc4_key_t rc4; - unsigned char key[4]; - - if(ipod->sectorbuf == NULL) { - fprintf(stderr,"[ERR] Buffer not initialized."); - return -1; - } - /* First check that the input file is the correct type for this ipod. */ - infile=open(filename,O_RDONLY); - if (infile < 0) { - fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename); - return -1; - } - - length = filesize(infile); - newsize=(length+ipod->sector_size-1)&~(ipod->sector_size-1); - - fprintf(stderr,"[INFO] Padding input file from 0x%08x to 0x%08x bytes\n", - length,newsize); - - if (newsize > BUFFER_SIZE) { - fprintf(stderr,"[ERR] Input file too big for buffer\n"); - if (infile >= 0) close(infile); - return -1; - } - - /* Find aupd image number */ - aupd = 0; - while ((aupd < ipod->nimages) && (ipod->ipod_directory[aupd].ftype != FTYPE_AUPD)) - { - aupd++; - } - - if (aupd == ipod->nimages) - { - fprintf(stderr,"[ERR] No AUPD image in firmware partition.\n"); - return -1; - } - - if (length != ipod->ipod_directory[aupd].len) - { - fprintf(stderr,"[ERR] AUPD image (%d bytes) differs in size to %s (%d bytes).\n", - ipod->ipod_directory[aupd].len, filename, length); - return -1; - } - - if (find_key(ipod, aupd, key) < 0) - { - return -1; - } - - fprintf(stderr, "[INFO] Encrypting AUPD image with key %02x%02x%02x%02x\n",key[0],key[1],key[2],key[3]); - - /* We now know we have enough space, so write it. */ - - fprintf(stderr,"[INFO] Reading input file...\n"); - n = read(infile,ipod->sectorbuf,length); - if (n < 0) { - fprintf(stderr,"[ERR] Couldn't read input file\n"); - close(infile); - return -1; - } - close(infile); - - /* Pad the data with zeros */ - memset(ipod->sectorbuf+length,0,newsize-length); - - /* Calculate the new checksum (before we encrypt) */ - chksum = 0; - for (i = 0; i < (int)length; i++) { - /* add 8 unsigned bits but keep a 32 bit sum */ - chksum += ipod->sectorbuf[i]; - } - - /* Perform the encryption - this is standard (A)RC4 */ - matrixArc4Init(&rc4, key, 4); - matrixArc4(&rc4, ipod->sectorbuf, ipod->sectorbuf, length); - - if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[aupd].devOffset) < 0) { - fprintf(stderr,"[ERR] Seek failed\n"); - return -1; - } - - if ((n = ipod_write(ipod,newsize)) < 0) { - perror("[ERR] Write failed\n"); - return -1; - } - - if (n < newsize) { - fprintf(stderr,"[ERR] Short write - requested %d bytes, received %d\n" - ,newsize,n); - return -1; - } - fprintf(stderr,"[INFO] Wrote %d bytes to firmware partition\n",n); - - x = ipod->diroffset % ipod->sector_size; - - /* Read directory */ - if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } - - n=ipod_read(ipod, ipod->sector_size); - if (n < 0) { return -1; } - - /* Update checksum */ - fprintf(stderr,"[INFO] Updating checksum to 0x%08x (was 0x%08x)\n",(unsigned int)chksum,le2int(ipod->sectorbuf + x + aupd*40 + 28)); - int2le(chksum,ipod->sectorbuf+x+aupd*40+28); - - /* Write directory */ - if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } - n=ipod_write(ipod, ipod->sector_size); - if (n < 0) { return -1; } - - return 0; -} - -#endif diff --git a/rbutil/ipodpatcher/ipodpatcher.h b/rbutil/ipodpatcher/ipodpatcher.h deleted file mode 100644 index 2cd2331666..0000000000 --- a/rbutil/ipodpatcher/ipodpatcher.h +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2006-2007 Dave Chapman - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#ifndef IPODPATCHER_H -#define IPODPATCHER_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "ipodio.h" - -/* exit codes */ -#define IPOD_OK 0 -#define IPOD_WRONG_ARGUMENTS 1 -#define IPOD_OPEN_INFILE_FAILED 2 -#define IPOD_PARTITION_ERROR 3 -#define IPOD_OPEN_OUTFILE_FAILED 4 -#define IPOD_CANNOT_REOPEN 5 -#define IPOD_ACCESS_DENIED 10 -#define IPOD_NOT_FOUND 11 -#define IPOD_WRONG_DEVICE_COUNT 12 -#define IPOD_IMAGE_ERROR 13 -#define IPOD_DUMP_FAILED 14 -#define IPOD_MULTIPLE_DEVICES 15 -#define IPOD_WRONG_TYPE 16 -#define IPOD_UNKNOWN_FW_VERSION -1 - -/* Size of buffer for disk I/O - 8MB is large enough for any version - of the Apple firmware, but not the Nano's RSRC image. */ -#define BUFFER_SIZE 8*1024*1024 - -extern int ipod_verbose; - -#define FILETYPE_DOT_IPOD 0 -#define FILETYPE_DOT_BIN 1 -#ifdef WITH_BOOTOBJS - #define FILETYPE_INTERNAL 2 -#endif - -char* get_parttype(unsigned int pt); -int read_partinfo(struct ipod_t* ipod, int silent); -int read_partition(struct ipod_t* ipod, int outfile); -int write_partition(struct ipod_t* ipod, int infile); -int diskmove(struct ipod_t* ipod, int delta); -int add_bootloader(struct ipod_t* ipod, char* filename, int type); -int delete_bootloader(struct ipod_t* ipod); -int write_firmware(struct ipod_t* ipod, char* filename, int type); -int read_firmware(struct ipod_t* ipod, char* filename, int type); -int read_directory(struct ipod_t* ipod); -int list_images(struct ipod_t* ipod); -int getmodel(struct ipod_t* ipod, int ipod_version); -int ipod_scan(struct ipod_t* ipod); -int write_dos_partition_table(struct ipod_t* ipod); -int ipod_get_xmlinfo(struct ipod_t* ipod); -void ipod_get_ramsize(struct ipod_t* ipod); -int read_aupd(struct ipod_t* ipod, char* filename); -int write_aupd(struct ipod_t* ipod, char* filename); -off_t filesize(int fd); -int ipod_has_bootloader(struct ipod_t* ipod); - -#ifdef __cplusplus -} -#endif -#endif - diff --git a/rbutil/ipodpatcher/ipodpatcher.manifest b/rbutil/ipodpatcher/ipodpatcher.manifest deleted file mode 100644 index 695ecb26ea..0000000000 --- a/rbutil/ipodpatcher/ipodpatcher.manifest +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> - <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="ipodpatcher.exe" type="win32"/> - - <!-- Identify the application security requirements. --> - <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> - <security> - <requestedPrivileges> - <requestedExecutionLevel level="requireAdministrator"/> - </requestedPrivileges> - </security> - </trustInfo> -</assembly> diff --git a/rbutil/ipodpatcher/ipodpatcher.pro b/rbutil/ipodpatcher/ipodpatcher.pro deleted file mode 100644 index fac1e35f00..0000000000 --- a/rbutil/ipodpatcher/ipodpatcher.pro +++ /dev/null @@ -1,47 +0,0 @@ -# -# __________ __ ___. -# Open \______ \ ____ ____ | | _\_ |__ _______ ___ -# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -# \/ \/ \/ \/ \/ -# -# All files in this archive are subject to the GNU General Public License. -# See the file COPYING in the source tree root for full license agreement. -# -# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -# KIND, either express or implied. -# - -TEMPLATE = app -TARGET = ipodpatcher -QT -= core - -SOURCES += \ - main.c \ - ipodpatcher.c \ - ipodio-posix.c \ - ipodio-win32-scsi.c \ - ipodio-win32.c \ - fat32format.c \ - arc4.c \ - -HEADERS += \ - arc4.h \ - ipodio.h \ - ipodpatcher.h \ - parttypes.h \ - -DEFINES += RELEASE=1 _LARGEFILE64_SOURCE - -RC_FILE = ipodpatcher.rc - -macx { - LIBS += -framework CoreFoundation -framework IOKit -} - - -unix { - target.path = /usr/local/bin - INSTALLS += target -} diff --git a/rbutil/ipodpatcher/ipodpatcher.rc b/rbutil/ipodpatcher/ipodpatcher.rc deleted file mode 100644 index e440b51271..0000000000 --- a/rbutil/ipodpatcher/ipodpatcher.rc +++ /dev/null @@ -1 +0,0 @@ -1 24 MOVEABLE PURE "ipodpatcher.manifest" diff --git a/rbutil/ipodpatcher/main.c b/rbutil/ipodpatcher/main.c deleted file mode 100644 index 7b0a909178..0000000000 --- a/rbutil/ipodpatcher/main.c +++ /dev/null @@ -1,622 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2006-2007 Dave Chapman - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include <stdio.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> -#include <stdlib.h> -#include <inttypes.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include "ipodpatcher.h" -#include "ipodio.h" - -#ifdef RELEASE -#undef VERSION -#define VERSION "5.0 with v4.0 bootloaders (v1.0 for 2nd Gen Nano)" -#endif - - -enum { - NONE, -#ifdef WITH_BOOTOBJS - INSTALL, -#endif - INTERACTIVE, - SHOW_INFO, - LIST_IMAGES, - DELETE_BOOTLOADER, - ADD_BOOTLOADER, - READ_FIRMWARE, - WRITE_FIRMWARE, - READ_AUPD, - WRITE_AUPD, - READ_PARTITION, - WRITE_PARTITION, - FORMAT_PARTITION, - DUMP_XML, - CONVERT_TO_FAT32 -}; - -void print_macpod_warning(void) -{ - printf("[INFO] ************************************************************************\n"); - printf("[INFO] *** WARNING FOR ROCKBOX USERS\n"); - printf("[INFO] *** You must convert this ipod to FAT32 format (aka a \"winpod\")\n"); - printf("[INFO] *** if you want to run Rockbox. Rockbox WILL NOT work on this ipod.\n"); - printf("[INFO] *** See http://www.rockbox.org/wiki/IpodConversionToFAT32\n"); - printf("[INFO] ************************************************************************\n"); -} - -void print_usage(void) -{ - fprintf(stderr,"Usage: ipodpatcher --scan\n"); -#ifdef __WIN32__ - fprintf(stderr," or ipodpatcher [DISKNO] [action]\n"); -#else - fprintf(stderr," or ipodpatcher [device] [action]\n"); -#endif - fprintf(stderr,"\n"); - fprintf(stderr,"Where [action] is one of the following options:\n"); -#ifdef WITH_BOOTOBJS - fprintf(stderr," --install\n"); -#endif - fprintf(stderr," -l, --list\n"); - fprintf(stderr," -r, --read-partition bootpartition.bin\n"); - fprintf(stderr," -w, --write-partition bootpartition.bin\n"); - fprintf(stderr," -rf, --read-firmware filename.ipod[x]\n"); - fprintf(stderr," -rfb, --read-firmware-bin filename.bin\n"); - fprintf(stderr," -wf, --write-firmware filename.ipod[x]\n"); - fprintf(stderr," -wfb, --write-firmware-bin filename.bin\n"); -#ifdef WITH_BOOTOBJS - fprintf(stderr," -we, --write-embedded\n"); -#endif - fprintf(stderr," -a, --add-bootloader filename.ipod[x]\n"); - fprintf(stderr," -ab, --add-bootloader-bin filename.bin\n"); - fprintf(stderr," -d, --delete-bootloader\n"); - fprintf(stderr," -f, --format\n"); - fprintf(stderr," -c, --convert\n"); - fprintf(stderr," --read-aupd filename.bin\n"); - fprintf(stderr," --write-aupd filename.bin\n"); - fprintf(stderr," -x --dump-xml filename.xml\n"); - fprintf(stderr,"\n"); - - fprintf(stderr,"The .ipodx extension is used for encrypted images for the 2nd Gen Nano.\n\n"); - -#ifdef __WIN32__ - fprintf(stderr,"DISKNO is the number (e.g. 2) Windows has assigned to your ipod's hard disk.\n"); - fprintf(stderr,"The first hard disk in your computer (i.e. C:\\) will be disk 0, the next disk\n"); - fprintf(stderr,"will be disk 1 etc. ipodpatcher will refuse to access a disk unless it\n"); - fprintf(stderr,"can identify it as being an ipod.\n"); - fprintf(stderr,"\n"); -#else -#if defined(linux) || defined (__linux) - fprintf(stderr,"\"device\" is the device node (e.g. /dev/sda) assigned to your ipod.\n"); -#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) - fprintf(stderr,"\"device\" is the device node (e.g. /dev/da1) assigned to your ipod.\n"); -#elif defined(__APPLE__) && defined(__MACH__) - fprintf(stderr,"\"device\" is the device node (e.g. /dev/disk1) assigned to your ipod.\n"); -#endif - fprintf(stderr,"ipodpatcher will refuse to access a disk unless it can identify it as being\n"); - fprintf(stderr,"an ipod.\n"); -#endif -} - -void display_partinfo(struct ipod_t* ipod) -{ - int i; - double sectors_per_MB = (1024.0*1024.0)/ipod->sector_size; - - printf("[INFO] Part Start Sector End Sector Size (MB) Type\n"); - for ( i = 0; i < 4; i++ ) { - if (ipod->pinfo[i].start != 0) { - printf("[INFO] %d %10ld %10ld %10.1f %s (0x%02x)\n", - i, - (long int)ipod->pinfo[i].start, - (long int)ipod->pinfo[i].start+ipod->pinfo[i].size-1, - ipod->pinfo[i].size/sectors_per_MB, - get_parttype(ipod->pinfo[i].type), - (int)ipod->pinfo[i].type); - } - } -} - - -int main(int argc, char* argv[]) -{ - char yesno[4]; - int i; - int n; - int infile, outfile; - unsigned int inputsize; - char* filename; - int action = SHOW_INFO; - int type; - struct ipod_t ipod; - - fprintf(stderr,"ipodpatcher " VERSION "\n"); - fprintf(stderr,"(C) Dave Chapman 2006-2009\n"); - fprintf(stderr,"This is free software; see the source for copying conditions. There is NO\n"); - fprintf(stderr,"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"); - - if ((argc > 1) && ((strcmp(argv[1],"-h")==0) || (strcmp(argv[1],"--help")==0))) { - print_usage(); - return IPOD_OK; - } - - if (ipod_alloc_buffer(&ipod,BUFFER_SIZE) < 0) { - fprintf(stderr,"Failed to allocate memory buffer\n"); - } - - if ((argc > 1) && (strcmp(argv[1],"--scan")==0)) { - if (ipod_scan(&ipod) == 0) - fprintf(stderr,"[ERR] No ipods found.\n"); - return IPOD_NOT_FOUND; - } - - /* If the first parameter doesn't start with -, then we interpret it as a device */ - if ((argc > 1) && (argv[1][0] != '-')) { - ipod.diskname[0]=0; -#ifdef __WIN32__ - snprintf(ipod.diskname,sizeof(ipod.diskname),"\\\\.\\PhysicalDrive%s",argv[1]); -#else - strncpy(ipod.diskname,argv[1],sizeof(ipod.diskname)); -#endif - i = 2; - } else { - /* Autoscan for ipods */ - n = ipod_scan(&ipod); - if (n==0) { - fprintf(stderr,"[ERR] No ipods found, aborting\n"); - fprintf(stderr,"[ERR] Please connect your ipod and ensure it is in disk mode\n"); -#if defined(__APPLE__) && defined(__MACH__) - fprintf(stderr,"[ERR] Also ensure that itunes is closed, and that your ipod is not mounted.\n"); -#elif !defined(__WIN32__) - if (geteuid()!=0) { - fprintf(stderr,"[ERR] You may also need to run ipodpatcher as root.\n"); - } -#endif - fprintf(stderr,"[ERR] Please refer to the Rockbox manual if you continue to have problems.\n"); - } else if (n > 1) { - fprintf(stderr,"[ERR] %d ipods found, aborting\n",n); - fprintf(stderr,"[ERR] Please connect only one ipod and re-run ipodpatcher.\n"); - return IPOD_MULTIPLE_DEVICES; - } else if (n == 1 && ipod.macpod) { - return IPOD_WRONG_TYPE; - } - - if (n != 1) { -#ifdef WITH_BOOTOBJS - if (argc==1) { - printf("\nPress ENTER to exit ipodpatcher :"); - fgets(yesno,4,stdin); - } -#endif - return IPOD_NOT_FOUND; - } - - i = 1; - } - -#ifdef WITH_BOOTOBJS - action = INTERACTIVE; -#else - action = NONE; -#endif - - while (i < argc) { - if ((strcmp(argv[i],"-l")==0) || (strcmp(argv[i],"--list")==0)) { - action = LIST_IMAGES; - i++; -#ifdef WITH_BOOTOBJS - } else if (strcmp(argv[i],"--install")==0) { - action = INSTALL; - i++; -#endif - } else if ((strcmp(argv[i],"-d")==0) || - (strcmp(argv[i],"--delete-bootloader")==0)) { - action = DELETE_BOOTLOADER; - i++; - } else if ((strcmp(argv[i],"-a")==0) || - (strcmp(argv[i],"--add-bootloader")==0)) { - action = ADD_BOOTLOADER; - type = FILETYPE_DOT_IPOD; - i++; - if (i == argc) { print_usage(); return IPOD_WRONG_ARGUMENTS; } - filename=argv[i]; - i++; - } else if ((strcmp(argv[i],"-ab")==0) || - (strcmp(argv[i],"--add-bootloader-bin")==0)) { - action = ADD_BOOTLOADER; - type = FILETYPE_DOT_BIN; - i++; - if (i == argc) { print_usage(); return IPOD_WRONG_ARGUMENTS; } - filename=argv[i]; - i++; - } else if ((strcmp(argv[i],"-rf")==0) || - (strcmp(argv[i],"--read-firmware")==0)) { - action = READ_FIRMWARE; - type = FILETYPE_DOT_IPOD; - i++; - if (i == argc) { print_usage(); return IPOD_WRONG_ARGUMENTS; } - filename=argv[i]; - i++; - } else if ((strcmp(argv[i],"-rfb")==0) || - (strcmp(argv[i],"--read-firmware-bin")==0)) { - action = READ_FIRMWARE; - type = FILETYPE_DOT_BIN; - i++; - if (i == argc) { print_usage(); return IPOD_WRONG_ARGUMENTS; } - filename=argv[i]; - i++; -#ifdef WITH_BOOTOBJS - } else if ((strcmp(argv[i],"-we")==0) || - (strcmp(argv[i],"--write-embedded")==0)) { - action = WRITE_FIRMWARE; - type = FILETYPE_INTERNAL; - filename="[embedded bootloader]"; /* Only displayed for user */ - i++; -#endif - } else if ((strcmp(argv[i],"-wf")==0) || - (strcmp(argv[i],"--write-firmware")==0)) { - action = WRITE_FIRMWARE; - type = FILETYPE_DOT_IPOD; - i++; - if (i == argc) { print_usage(); return IPOD_WRONG_ARGUMENTS; } - filename=argv[i]; - i++; - } else if ((strcmp(argv[i],"-wfb")==0) || - (strcmp(argv[i],"--write-firmware-bin")==0)) { - action = WRITE_FIRMWARE; - type = FILETYPE_DOT_BIN; - i++; - if (i == argc) { print_usage(); return IPOD_WRONG_ARGUMENTS; } - filename=argv[i]; - i++; - } else if ((strcmp(argv[i],"-r")==0) || - (strcmp(argv[i],"--read-partition")==0)) { - action = READ_PARTITION; - i++; - if (i == argc) { print_usage(); return IPOD_WRONG_ARGUMENTS; } - filename=argv[i]; - i++; - } else if ((strcmp(argv[i],"-w")==0) || - (strcmp(argv[i],"--write-partition")==0)) { - action = WRITE_PARTITION; - i++; - if (i == argc) { print_usage(); return IPOD_WRONG_ARGUMENTS; } - filename=argv[i]; - i++; - } else if ((strcmp(argv[i],"-v")==0) || - (strcmp(argv[i],"--verbose")==0)) { - ipod_verbose++; - i++; - } else if ((strcmp(argv[i],"-f")==0) || - (strcmp(argv[i],"--format")==0)) { - action = FORMAT_PARTITION; - i++; - } else if (strcmp(argv[i],"--read-aupd")==0) { - action = READ_AUPD; - i++; - if (i == argc) { print_usage(); return IPOD_WRONG_ARGUMENTS; } - filename=argv[i]; - i++; - } else if (strcmp(argv[i],"--write-aupd")==0) { - action = WRITE_AUPD; - i++; - if (i == argc) { print_usage(); return IPOD_WRONG_ARGUMENTS; } - filename=argv[i]; - i++; - } else if ((strcmp(argv[i],"-x")==0) || - (strcmp(argv[i],"--dump-xml")==0)) { - action = DUMP_XML; - i++; - if (i == argc) { print_usage(); return IPOD_WRONG_ARGUMENTS; } - filename=argv[i]; - i++; - } else if ((strcmp(argv[i],"-c")==0) || - (strcmp(argv[i],"--convert")==0)) { - action = CONVERT_TO_FAT32; - i++; - } else { - print_usage(); return IPOD_WRONG_ARGUMENTS; - } - } - - if (ipod.diskname[0]==0) { - print_usage(); - return 1; - } - - if (ipod_open(&ipod, 0) < 0) { - return IPOD_ACCESS_DENIED; - } - - fprintf(stderr,"[INFO] Reading partition table from %s\n",ipod.diskname); - fprintf(stderr,"[INFO] Sector size is %d bytes\n",ipod.sector_size); - - if (read_partinfo(&ipod,0) < 0) { - return IPOD_PARTITION_ERROR; - } - - display_partinfo(&ipod); - - if (ipod.pinfo[0].start==0) { - fprintf(stderr,"[ERR] No partition 0 on disk:\n"); - display_partinfo(&ipod); - return IPOD_PARTITION_ERROR; - } - - read_directory(&ipod); - - if (ipod.nimages <= 0) { - fprintf(stderr,"[ERR] Failed to read firmware directory - nimages=%d\n",ipod.nimages); - return IPOD_IMAGE_ERROR; - } - - if (getmodel(&ipod,(ipod.ipod_directory[ipod.ososimage].vers>>8)) < 0) { - fprintf(stderr,"[ERR] Unknown version number in firmware (%08x)\n", - ipod.ipod_directory[ipod.ososimage].vers); - return IPOD_UNKNOWN_FW_VERSION; - } - -#ifdef __WIN32__ - /* Windows requires the ipod in R/W mode for SCSI Inquiry */ - if (ipod_reopen_rw(&ipod) < 0) { - return IPOD_CANNOT_REOPEN; - } -#endif - - - /* Read the XML info, and if successful, look for the ramsize - (only available for some models - set to 0 if not known) */ - - ipod.ramsize = 0; - - if (ipod_get_xmlinfo(&ipod) == 0) { - ipod_get_ramsize(&ipod); - } - - printf("[INFO] Ipod model: %s ",ipod.modelstr); - if (ipod.ramsize > 0) { printf("(%dMB RAM) ",ipod.ramsize); } - printf("(\"%s\")\n",ipod.macpod ? "macpod" : "winpod"); - - if (ipod.macpod) { - print_macpod_warning(); - } - - if (action==LIST_IMAGES) { - list_images(&ipod); -#ifdef WITH_BOOTOBJS - } else if (action==INTERACTIVE) { - - printf("Enter i to install the Rockbox bootloader, u to uninstall\n or c to cancel and do nothing (i/u/c) :"); - - if (fgets(yesno,4,stdin)) { - if (yesno[0]=='i') { - if (ipod_reopen_rw(&ipod) < 0) { - return IPOD_CANNOT_REOPEN; - } - - if (add_bootloader(&ipod, NULL, FILETYPE_INTERNAL)==0) { - fprintf(stderr,"[INFO] Bootloader installed successfully.\n"); - } else { - fprintf(stderr,"[ERR] --install failed.\n"); - } - } else if (yesno[0]=='u') { - if (ipod_reopen_rw(&ipod) < 0) { - return IPOD_CANNOT_REOPEN; - } - - if (delete_bootloader(&ipod)==0) { - fprintf(stderr,"[INFO] Bootloader removed.\n"); - } else { - fprintf(stderr,"[ERR] Bootloader removal failed.\n"); - } - } - } -#endif - } else if (action==DELETE_BOOTLOADER) { - if (ipod_reopen_rw(&ipod) < 0) { - return IPOD_CANNOT_REOPEN; - } - - if (ipod.ipod_directory[0].entryOffset==0) { - fprintf(stderr,"[ERR] No bootloader detected.\n"); - } else { - if (delete_bootloader(&ipod)==0) { - fprintf(stderr,"[INFO] Bootloader removed.\n"); - } else { - fprintf(stderr,"[ERR] --delete-bootloader failed.\n"); - } - } - } else if (action==ADD_BOOTLOADER) { - if (ipod_reopen_rw(&ipod) < 0) { - return IPOD_CANNOT_REOPEN; - } - - if (add_bootloader(&ipod, filename, type)==0) { - fprintf(stderr,"[INFO] Bootloader %s written to device.\n",filename); - } else { - fprintf(stderr,"[ERR] --add-bootloader failed.\n"); - } -#ifdef WITH_BOOTOBJS - } else if (action==INSTALL) { - if (ipod_reopen_rw(&ipod) < 0) { - return IPOD_CANNOT_REOPEN; - } - - if (add_bootloader(&ipod, NULL, FILETYPE_INTERNAL)==0) { - fprintf(stderr,"[INFO] Bootloader installed successfully.\n"); - } else { - fprintf(stderr,"[ERR] --install failed.\n"); - } -#endif - } else if (action==WRITE_FIRMWARE) { - if (ipod_reopen_rw(&ipod) < 0) { - return IPOD_CANNOT_REOPEN; - } - - if (write_firmware(&ipod, filename,type)==0) { - fprintf(stderr,"[INFO] Firmware %s written to device.\n",filename); - } else { - fprintf(stderr,"[ERR] --write-firmware failed.\n"); - } - } else if (action==READ_FIRMWARE) { - if (read_firmware(&ipod, filename, type)==0) { - fprintf(stderr,"[INFO] Firmware read to file %s.\n",filename); - } else { - fprintf(stderr,"[ERR] --read-firmware failed.\n"); - } - } else if (action==READ_AUPD) { - if (read_aupd(&ipod, filename)==0) { - fprintf(stderr,"[INFO] AUPD image read to file %s.\n",filename); - } else { - fprintf(stderr,"[ERR] --read-aupd failed.\n"); - } - } else if (action==WRITE_AUPD) { - if (ipod_reopen_rw(&ipod) < 0) { - return IPOD_CANNOT_REOPEN; - } - - if (write_aupd(&ipod, filename)==0) { - fprintf(stderr,"[INFO] AUPD image %s written to device.\n",filename); - } else { - fprintf(stderr,"[ERR] --write-aupd failed.\n"); - } - } else if (action==DUMP_XML) { - if (ipod.xmlinfo == NULL) { - fprintf(stderr,"[ERR] No XML to write\n"); - return IPOD_DUMP_FAILED; - } - - outfile = open(filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IREAD|S_IWRITE); - if (outfile < 0) { - perror(filename); - return IPOD_OPEN_OUTFILE_FAILED; - } - - if (write(outfile, ipod.xmlinfo, ipod.xmlinfo_len) < 0) { - fprintf(stderr,"[ERR] --dump-xml failed.\n"); - } else { - fprintf(stderr,"[INFO] XML info written to %s.\n",filename); - } - close(outfile); - } else if (action==READ_PARTITION) { - outfile = open(filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IREAD|S_IWRITE); - if (outfile < 0) { - perror(filename); - return IPOD_OPEN_OUTFILE_FAILED; - } - - if (read_partition(&ipod, outfile) < 0) { - fprintf(stderr,"[ERR] --read-partition failed.\n"); - } else { - fprintf(stderr,"[INFO] Partition extracted to %s.\n",filename); - } - close(outfile); - } else if (action==WRITE_PARTITION) { - if (ipod_reopen_rw(&ipod) < 0) { - return IPOD_CANNOT_REOPEN; - } - - infile = open(filename,O_RDONLY|O_BINARY); - if (infile < 0) { - perror(filename); - return IPOD_OPEN_INFILE_FAILED; - } - - /* Check filesize is <= partition size */ - inputsize=filesize(infile); - if (inputsize > 0) { - if (inputsize <= (ipod.pinfo[0].size*ipod.sector_size)) { - fprintf(stderr,"[INFO] Input file is %u bytes\n",inputsize); - if (write_partition(&ipod,infile) < 0) { - fprintf(stderr,"[ERR] --write-partition failed.\n"); - } else { - fprintf(stderr,"[INFO] %s restored to partition\n",filename); - } - } else { - fprintf(stderr,"[ERR] File is too large for firmware partition, aborting.\n"); - } - } - - close(infile); - } else if (action==FORMAT_PARTITION) { - printf("WARNING!!! YOU ARE ABOUT TO USE AN EXPERIMENTAL FEATURE.\n"); - printf("ALL DATA ON YOUR IPOD WILL BE ERASED.\n"); - printf("Are you sure you want to format your ipod? (y/n):"); - - if (fgets(yesno,4,stdin)) { - if (yesno[0]=='y') { - if (ipod_reopen_rw(&ipod) < 0) { - return IPOD_CANNOT_REOPEN; - } - - if (format_partition(&ipod,1) < 0) { - fprintf(stderr,"[ERR] Format failed.\n"); - } - } else { - fprintf(stderr,"[INFO] Format cancelled.\n"); - } - } - } else if (action==CONVERT_TO_FAT32) { - if (!ipod.macpod) { - printf("[ERR] Ipod is already FAT32, aborting\n"); - } else { - printf("WARNING!!! YOU ARE ABOUT TO USE AN EXPERIMENTAL FEATURE.\n"); - printf("ALL DATA ON YOUR IPOD WILL BE ERASED.\n"); - printf("Are you sure you want to convert your ipod to FAT32? (y/n):"); - - if (fgets(yesno,4,stdin)) { - if (yesno[0]=='y') { - if (ipod_reopen_rw(&ipod) < 0) { - return IPOD_CANNOT_REOPEN; - } - - if (write_dos_partition_table(&ipod) < 0) { - fprintf(stderr,"[ERR] Partition conversion failed.\n"); - } - - if (format_partition(&ipod,1) < 0) { - fprintf(stderr,"[ERR] Format failed.\n"); - } - } else { - fprintf(stderr,"[INFO] Format cancelled.\n"); - } - } - } - } - - ipod_close(&ipod); - -#ifdef WITH_BOOTOBJS - if (action==INTERACTIVE) { - printf("Press ENTER to exit ipodpatcher :"); - fgets(yesno,4,stdin); - } -#endif - - ipod_dealloc_buffer(&ipod); - return IPOD_OK; -} diff --git a/rbutil/ipodpatcher/parttypes.h b/rbutil/ipodpatcher/parttypes.h deleted file mode 100644 index f8de303553..0000000000 --- a/rbutil/ipodpatcher/parttypes.h +++ /dev/null @@ -1,109 +0,0 @@ -/* DOS partition types - taken from fdisk */ - -struct parttype { - unsigned char type; - char *name; -}; - -struct parttype parttypes[] = { - {0x00, "Empty"}, - {0x01, "FAT12"}, - {0x02, "XENIX root"}, - {0x03, "XENIX usr"}, - {0x04, "FAT16 <32M"}, - {0x05, "Extended"}, /* DOS 3.3+ extended partition */ - {0x06, "FAT16"}, /* DOS 16-bit >=32M */ - {0x07, "HPFS/NTFS"}, /* OS/2 IFS, eg, HPFS or NTFS or QNX */ - {0x08, "AIX"}, /* AIX boot (AIX -- PS/2 port) or SplitDrive */ - {0x09, "AIX bootable"}, /* AIX data or Coherent */ - {0x0a, "OS/2 Boot Manager"},/* OS/2 Boot Manager */ - {0x0b, "W95 FAT32"}, - {0x0c, "W95 FAT32 (LBA)"},/* LBA really is `Extended Int 13h' */ - {0x0e, "W95 FAT16 (LBA)"}, - {0x0f, "W95 Ext'd (LBA)"}, - {0x10, "OPUS"}, - {0x11, "Hidden FAT12"}, - {0x12, "Compaq diagnostics"}, - {0x14, "Hidden FAT16 <32M"}, - {0x16, "Hidden FAT16"}, - {0x17, "Hidden HPFS/NTFS"}, - {0x18, "AST SmartSleep"}, - {0x1b, "Hidden W95 FAT32"}, - {0x1c, "Hidden W95 FAT32 (LBA)"}, - {0x1e, "Hidden W95 FAT16 (LBA)"}, - {0x24, "NEC DOS"}, - {0x39, "Plan 9"}, - {0x3c, "PartitionMagic recovery"}, - {0x40, "Venix 80286"}, - {0x41, "PPC PReP Boot"}, - {0x42, "SFS"}, - {0x4d, "QNX4.x"}, - {0x4e, "QNX4.x 2nd part"}, - {0x4f, "QNX4.x 3rd part"}, - {0x50, "OnTrack DM"}, - {0x51, "OnTrack DM6 Aux1"}, /* (or Novell) */ - {0x52, "CP/M"}, /* CP/M or Microport SysV/AT */ - {0x53, "OnTrack DM6 Aux3"}, - {0x54, "OnTrackDM6"}, - {0x55, "EZ-Drive"}, - {0x56, "Golden Bow"}, - {0x5c, "Priam Edisk"}, - {0x61, "SpeedStor"}, - {0x63, "GNU HURD or SysV"}, /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */ - {0x64, "Novell Netware 286"}, - {0x65, "Novell Netware 386"}, - {0x70, "DiskSecure Multi-Boot"}, - {0x75, "PC/IX"}, - {0x80, "Old Minix"}, /* Minix 1.4a and earlier */ - {0x81, "Minix / old Linux"},/* Minix 1.4b and later */ - {0x82, "Linux swap / Solaris"}, - {0x83, "Linux"}, - {0x84, "OS/2 hidden C: drive"}, - {0x85, "Linux extended"}, - {0x86, "NTFS volume set"}, - {0x87, "NTFS volume set"}, - {0x88, "Linux plaintext"}, - {0x8e, "Linux LVM"}, - {0x93, "Amoeba"}, - {0x94, "Amoeba BBT"}, /* (bad block table) */ - {0x9f, "BSD/OS"}, /* BSDI */ - {0xa0, "IBM Thinkpad hibernation"}, - {0xa5, "FreeBSD"}, /* various BSD flavours */ - {0xa6, "OpenBSD"}, - {0xa7, "NeXTSTEP"}, - {0xa8, "Darwin UFS"}, - {0xa9, "NetBSD"}, - {0xab, "Darwin boot"}, - {0xb7, "BSDI fs"}, - {0xb8, "BSDI swap"}, - {0xbb, "Boot Wizard hidden"}, - {0xbe, "Solaris boot"}, - {0xbf, "Solaris"}, - {0xc1, "DRDOS/sec (FAT-12)"}, - {0xc4, "DRDOS/sec (FAT-16 < 32M)"}, - {0xc6, "DRDOS/sec (FAT-16)"}, - {0xc7, "Syrinx"}, - {0xda, "Non-FS data"}, - {0xdb, "CP/M / CTOS / ..."},/* CP/M or Concurrent CP/M or - Concurrent DOS or CTOS */ - {0xde, "Dell Utility"}, /* Dell PowerEdge Server utilities */ - {0xdf, "BootIt"}, /* BootIt EMBRM */ - {0xe1, "DOS access"}, /* DOS access or SpeedStor 12-bit FAT - extended partition */ - {0xe3, "DOS R/O"}, /* DOS R/O or SpeedStor */ - {0xe4, "SpeedStor"}, /* SpeedStor 16-bit FAT extended - partition < 1024 cyl. */ - {0xeb, "BeOS fs"}, - {0xee, "EFI GPT"}, /* Intel EFI GUID Partition Table */ - {0xef, "EFI (FAT-12/16/32)"},/* Intel EFI System Partition */ - {0xf0, "Linux/PA-RISC boot"},/* Linux/PA-RISC boot loader */ - {0xf1, "SpeedStor"}, - {0xf4, "SpeedStor"}, /* SpeedStor large partition */ - {0xf2, "DOS secondary"}, /* DOS 3.3+ secondary */ - {0xfd, "Linux raid autodetect"},/* New (2.2.x) raid partition with - autodetect using persistent - superblock */ - {0xfe, "LANstep"}, /* SpeedStor >1024 cyl. or LANstep */ - {0xff, "BBT"}, /* Xenix Bad Block Table */ - { 0, 0 } -}; diff --git a/rbutil/jztool/Makefile b/rbutil/jztool/Makefile deleted file mode 100644 index d1bbae578c..0000000000 --- a/rbutil/jztool/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# __________ __ ___. -# Open \______ \ ____ ____ | | _\_ |__ _______ ___ -# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -# \/ \/ \/ \/ \/ - -CFLAGS += -Wall -Wextra -Iinclude -I../../tools/ucl/include -I../../lib/microtar/src -OUTPUT = jztool - -ifdef RELEASE -CFLAGS += -Os -DNDEBUG -else -CFLAGS += -O0 -ggdb -endif - -LIBSOURCES := src/buffer.c src/context.c src/device_info.c \ - src/identify_file.c src/ucl_unpack.c src/usb.c src/x1000.c -SOURCES := $(LIBSOURCES) jztool.c -EXTRADEPS := libucl.a libmicrotar.a - -CPPDEFINES := $(shell echo foo | $(CROSS)$(CC) -dM -E -) - -ifeq ($(findstring WIN32,$(CPPDEFINES)),WIN32) -# TODO: support Windows -else -ifeq ($(findstring APPLE,$(CPPDEFINES)),APPLE) -# Mac, tested on x86 only -- may need to adjust paths if building on ARM. -# paths should work with homebrew libusb. -LIBUSB_CFLAGS ?= -I/usr/local/include/libusb-1.0 -ifdef STATIC -LIBUSB_LDOPTS ?= /usr/local/lib/libusb-1.0.a -framework IOKit -framework CoreFoundation -else -LIBUSB_LDOPTS ?= -L/usr/local/lib -lusb-1.0 -endif -else -# Linux; note for static builds you need to build a copy of libusb without -# udev support and specify the includes / libs manually -LIBUSB_CFLAGS ?= `pkg-config --cflags libusb-1.0` -LIBUSB_LDOPTS ?= `pkg-config --libs libusb-1.0` -endif -endif - -CFLAGS += $(LIBUSB_CFLAGS) -LDOPTS += $(LIBUSB_LDOPTS) - -include ../libtools.make diff --git a/rbutil/jztool/README.md b/rbutil/jztool/README.md deleted file mode 100644 index 72c630c6c3..0000000000 --- a/rbutil/jztool/README.md +++ /dev/null @@ -1,135 +0,0 @@ -# jztool -- Ingenic device utility & bootloader installer - -The `jztool` utility can help install, backup, and restore the bootloader on -Rockbox players based on a supported Ingenic SoC (currently only the X1000). - -## Running jztool - -### Getting a bootloader - -To use `jztool` you need to compile or download a bootloader for your player. -It's recommended to use only official released bootloaders, since bootloaders -compiled from Git are not tested and might be buggy. - -You can download released bootloaders from <https://download.rockbox.org/>. - -The bootloader file is named after the target: for example, the FiiO M3K -bootloader is called `bootloader.m3k`. The FiiO M3K is used as an example -here, but the instructions apply to all X1000-based players. - -Use `jztool --help` to find out the model name of your player. - -### Entering USB boot mode - -USB boot mode is a low-level mode provided by the CPU which allows a computer -to load firmware onto the device. You need to put your player into this mode -manually before using `jztool` (unfortunately, it can't be done automatically.) - -To connect the player in USB boot mode, follow these steps: - -1. Ensure the player is fully powered off. -2. Plug one end of the USB cable into your player. -3. Hold down your player's USB boot key (see below). -4. Plug the other end of the USB cable into your computer. -5. Let go of the USB boot key. - -The USB boot key depends on your player: - -- FiiO M3K: Volume Down -- Shanling Q1: Play -- Eros Q: Menu - -### Linux/Mac - -Run the following command in a terminal. Note that on Linux, you will need to -have root access to allow libusb to access the USB device. - -```sh -# Linux / Mac -# NOTE: root permissions are required on Linux to access the USB device -# eg. with 'sudo' or 'su -c' depending on your distro. -$ ./jztool fiiom3k load bootloader.m3k -``` - -### Windows - -To allow `jztool` access to your player in USB boot mode, you need to install -the WinUSB driver. The recommended way to install it is using Zadig, which -may be downloaded from its homepage <https://zadig.akeo.ie>. Please note -this is 3rd party software not maintained or supported by Rockbox developers. -(Zadig will require administrator access on the machine you are using.) - -When running Zadig you must select the WinUSB driver; the other driver options -will not work properly with `jztool`. You will have to select the correct USB -device in Zadig. All X1000-based players use the same USB ID while in USB boot -mode, listed below. NOTE: the device name may show only as "X" and a hollow -square in Zadig. The IDs will not change, so those are the most reliable way -to confirm you have selected the correct device. - -``` -Name: Ingenic Semiconductor Co.,Ltd X1000 -USB ID: A108 1000 -``` - -Assuming you installed the WinUSB driver successfully, open a command prompt -in the folder containing `jztool`. Administrator access is not required for -this step. - -Type the following command to load the Rockbox bootloader: - -```sh -# Windows -$ jztool.exe fiiom3k load bootloader.m3k -``` - -## Using the recovery menu - -If `jztool` runs successfully your player will display the Rockbox bootloader's -recovery menu. If you want to permanently install Rockbox to your device, copy -the bootloader file you downloaded to the root of your SD card, insert the SD -card to your player, and choose "Install/update bootloader" from the menu. - -It is _highly_ recommended that you take a backup of your existing bootloader -in case of any trouble -- choose "Backup bootloader" from the recovery menu. -The backup file is called `PLAYER-boot.bin`, where `PLAYER` is the model name. -(Example: `fiiom3k-boot.bin`.) - -You can restore the backup later by putting it on the root of your SD card and -selecting "Restor bootloader" in the recovery menu. - -After installing the Rockbox bootloader, you can access the recovery menu by -holding a key while booting: - -- FiiO M3K: Volume Up -- Shanling Q1: Next (button on the lower left) -- Eros Q: Volume Up - -### Known issues - -- When using the bootloader's USB mode, you may get stuck on "Waiting for USB" - even though the cable is already plugged in. If this occurs, unplug the USB - cable and plug it back in to trigger the connection. - - -## TODO list - -### Add better documentation and logging - -There's only a bare minimum of documentation, and logging is sparse, not -really enough to debug problems. - -Some of the error messages could be friendlier too. - -### Integration with the Rockbox utility - -Adding support to the Rockbox utility should be mostly boilerplate since the -jztool library wraps all the troublesome details. - -Permissions are an issue on Linux because by default only root can access -"raw" USB devices. If we want to package rbutil for distro we can install -a udev rule to allow access to the specific USB IDs we need, eg. allowing -users in the "wheel" group to access the device. - -On Windows and Mac, no special permissions are needed to access USB devices -assuming the drivers are set up. (Zadig does require administrator access -to run, but that's external to the Rockbox utility.) diff --git a/rbutil/jztool/include/jztool.h b/rbutil/jztool/include/jztool.h deleted file mode 100644 index 9d3c08c5bc..0000000000 --- a/rbutil/jztool/include/jztool.h +++ /dev/null @@ -1,202 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#ifndef JZTOOL_H -#define JZTOOL_H - -#include <stdint.h> -#include <stddef.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/****************************************************************************** - * Types, enumerations, etc - */ - -#define JZ_CPUINFO_BUFLEN 9 - -typedef struct jz_context jz_context; -typedef struct jz_usbdev jz_usbdev; -typedef struct jz_device_info jz_device_info; -typedef struct jz_cpu_info jz_cpu_info; -typedef struct jz_buffer jz_buffer; - -typedef enum jz_error jz_error; -typedef enum jz_identify_error jz_identify_error; -typedef enum jz_log_level jz_log_level; -typedef enum jz_device_type jz_device_type; -typedef enum jz_cpu_type jz_cpu_type; - -typedef void(*jz_log_cb)(jz_log_level, const char*); - -enum jz_error { - JZ_SUCCESS = 0, - JZ_ERR_OUT_OF_MEMORY = -1, - JZ_ERR_OPEN_FILE = -2, - JZ_ERR_FILE_IO = -3, - JZ_ERR_USB = -4, - JZ_ERR_NO_DEVICE = -5, - JZ_ERR_BAD_FILE_FORMAT = -6, - JZ_ERR_FLASH_ERROR = -7, - JZ_ERR_OTHER = -99, -}; - -enum jz_identify_error { - JZ_IDERR_OTHER = -1, - JZ_IDERR_WRONG_SIZE = -2, - JZ_IDERR_BAD_HEADER = -3, - JZ_IDERR_BAD_CHECKSUM = -4, - JZ_IDERR_UNRECOGNIZED_MODEL = -5, -}; - -enum jz_log_level { - JZ_LOG_IGNORE = -1, - JZ_LOG_ERROR = 0, - JZ_LOG_WARNING = 1, - JZ_LOG_NOTICE = 2, - JZ_LOG_DETAIL = 3, - JZ_LOG_DEBUG = 4, -}; - -enum jz_device_type { - JZ_DEVICE_FIIOM3K, - JZ_DEVICE_SHANLINGQ1, - JZ_DEVICE_EROSQ, - JZ_NUM_DEVICES, -}; - -enum jz_cpu_type { - JZ_CPU_X1000, - JZ_NUM_CPUS, -}; - -struct jz_device_info { - /* internal device name and file extension */ - const char* name; - const char* file_ext; - - /* human-readable name */ - const char* description; - - /* device and CPU type */ - jz_device_type device_type; - jz_cpu_type cpu_type; - - /* USB IDs of the device in mass storage mode */ - uint16_t vendor_id; - uint16_t product_id; -}; - -struct jz_cpu_info { - /* CPU info string, as reported by the boot ROM */ - const char* info_str; - - /* USB IDs of the boot ROM */ - uint16_t vendor_id; - uint16_t product_id; - - /* default addresses for running binaries */ - uint32_t stage1_load_addr; - uint32_t stage1_exec_addr; - uint32_t stage2_load_addr; - uint32_t stage2_exec_addr; -}; - -struct jz_buffer { - size_t size; - uint8_t* data; -}; - -/****************************************************************************** - * Library context and general functions - */ - -jz_context* jz_context_create(void); -void jz_context_destroy(jz_context* jz); - -void jz_context_set_user_data(jz_context* jz, void* ptr); -void* jz_context_get_user_data(jz_context* jz); - -void jz_context_set_log_cb(jz_context* jz, jz_log_cb cb); -void jz_context_set_log_level(jz_context* jz, jz_log_level lev); - -void jz_log(jz_context* jz, jz_log_level lev, const char* fmt, ...); -void jz_log_cb_stderr(jz_log_level lev, const char* msg); - -void jz_sleepms(int ms); - -/****************************************************************************** - * Device and file info - */ - -const jz_device_info* jz_get_device_info(jz_device_type type); -const jz_device_info* jz_get_device_info_named(const char* name); -const jz_device_info* jz_get_device_info_indexed(int index); - -const jz_cpu_info* jz_get_cpu_info(jz_cpu_type type); -const jz_cpu_info* jz_get_cpu_info_named(const char* info_str); - -int jz_identify_x1000_spl(const void* data, size_t len); -int jz_identify_scramble_image(const void* data, size_t len); - -/****************************************************************************** - * USB boot ROM protocol - */ - -int jz_usb_open(jz_context* jz, jz_usbdev** devptr, uint16_t vend_id, uint16_t prod_id); -void jz_usb_close(jz_usbdev* dev); - -int jz_usb_send(jz_usbdev* dev, uint32_t addr, size_t len, const void* data); -int jz_usb_recv(jz_usbdev* dev, uint32_t addr, size_t len, void* data); -int jz_usb_start1(jz_usbdev* dev, uint32_t addr); -int jz_usb_start2(jz_usbdev* dev, uint32_t addr); -int jz_usb_flush_caches(jz_usbdev* dev); -int jz_usb_get_cpu_info(jz_usbdev* dev, char* buffer, size_t buflen); - -/****************************************************************************** - * Rockbox loader (all functions are model-specific, see docs) - */ - -int jz_x1000_boot(jz_usbdev* dev, jz_device_type type, const char* filename); - -/****************************************************************************** - * Buffer API and other functions - */ - -jz_buffer* jz_buffer_alloc(size_t size, const void* data); -void jz_buffer_free(jz_buffer* buf); - -int jz_buffer_load(jz_buffer** buf, const char* filename); -int jz_buffer_save(jz_buffer* buf, const char* filename); - -jz_buffer* jz_ucl_unpack(const uint8_t* src, uint32_t src_len, uint32_t* dst_len); - -/****************************************************************************** - * END - */ - -#ifdef __cplusplus -} -#endif - -#endif /* JZTOOL_H */ diff --git a/rbutil/jztool/jztool.c b/rbutil/jztool/jztool.c deleted file mode 100644 index dcd78137b3..0000000000 --- a/rbutil/jztool/jztool.c +++ /dev/null @@ -1,212 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "jztool.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdbool.h> - -jz_context* jz = NULL; -jz_usbdev* usbdev = NULL; -const jz_device_info* dev_info = NULL; -const jz_cpu_info* cpu_info = NULL; - -void usage_x1000(void) -{ - printf( -"Usage:\n" -" jztool fiiom3k load <bootloader.m3k>\n" -" jztool shanlingq1 load <bootloader.q1>\n" -" jztool erosq load <bootloader.erosq>\n" -"\n" -"The 'load' command is used to boot the Rockbox bootloader in recovery\n" -"mode, which allows you to install the Rockbox bootloader and backup or\n" -"restore bootloader images. You need to connect your player in USB boot\n" -"mode in order to use this tool.\n" -"\n" -"To connect the player in USB boot mode, follow these steps:\n" -"\n" -"1. Ensure the player is fully powered off.\n" -"2. Plug one end of the USB cable into your player.\n" -"3. Hold down your player's USB boot key (see below).\n" -"4. Plug the other end of the USB cable into your computer.\n" -"5. Let go of the USB boot key.\n" -"\n" -"USB boot keys:\n" -"\n" -" FiiO M3K - Volume Down\n" -" Shanling Q1 - Play\n" -" Eros Q - Menu\n" -"\n" -"Not all players give a visible indication that they are in USB boot mode.\n" -"If you're having trouble connecting your player, try resetting it by\n" -"holding the power button for 10 seconds, and try the above steps again.\n" -"\n" -"Note for Windows users: you need to install the WinUSB driver using a\n" -"3rd-party tool such as Zadig <https://zadig.akeo.ie> before this tool\n" -"can access your player in USB boot mode. You need to run Zadig while the\n" -"player is plugged in and in USB boot mode. For more details check the\n" -"jztool README.md file or visit <https://rockbox.org/wiki/IngenicX1000>.\n" -"\n"); - - exit(4); -} - -int cmdline_x1000(int argc, char** argv) -{ - if(argc < 2 || strcmp(argv[0], "load")) { - usage_x1000(); - return 2; - } - - int rc = jz_usb_open(jz, &usbdev, cpu_info->vendor_id, cpu_info->product_id); - if(rc < 0) { - jz_log(jz, JZ_LOG_ERROR, "Cannot open USB device: %d", rc); - return 1; - } - - rc = jz_x1000_boot(usbdev, dev_info->device_type, argv[1]); - if(rc < 0) { - jz_log(jz, JZ_LOG_ERROR, "Boot failed: %d", rc); - return 1; - } - - return 0; -} - -void usage(void) -{ - printf("Usage:\n" - " jztool [global options] <device> <command> [command arguments]\n" - "\n" - "Global options:\n" - " -h, --help Display this help\n" - " -q, --quiet Don't log anything except errors\n" - " -v, --verbose Display detailed logging output\n\n"); - - printf("Supported devices:\n\n"); - for(int i = 0; i < JZ_NUM_DEVICES; ++i) { - const jz_device_info* info = jz_get_device_info_indexed(i); - printf(" %s - %s\n", info->name, info->description); - } - - printf("\n" - "For device-specific help run 'jztool DEVICE' without arguments,\n" - "eg. 'jztool fiiom3k' will display help for the FiiO M3K.\n"); - - exit(4); -} - -void cleanup(void) -{ - if(usbdev) - jz_usb_close(usbdev); - if(jz) - jz_context_destroy(jz); -} - -int main(int argc, char** argv) -{ - if(argc < 2) - usage(); - - /* Library initialization */ - jz = jz_context_create(); - if(!jz) { - fprintf(stderr, "ERROR: Can't create context"); - return 1; - } - - atexit(cleanup); - jz_context_set_log_cb(jz, jz_log_cb_stderr); - jz_context_set_log_level(jz, JZ_LOG_NOTICE); - - /* Parse global options */ - --argc, ++argv; - while(argc > 0 && argv[0][0] == '-') { - if(!strcmp(*argv, "-h") || !strcmp(*argv, "--help")) - usage(); - else if(!strcmp(*argv, "-q") || !strcmp(*argv, "--quiet")) - jz_context_set_log_level(jz, JZ_LOG_ERROR); - else if(!strcmp(*argv, "-v") || !strcmp(*argv, "--verbose")) - jz_context_set_log_level(jz, JZ_LOG_DETAIL); - else if(!strcmp(*argv, "-l") || !strcmp(*argv, "--loglevel")) { - ++argv; - if(--argc == 0) { - jz_log(jz, JZ_LOG_ERROR, "Missing argument to option %s", *argv); - exit(2); - } - - enum jz_log_level level; - if(!strcmp(*argv, "ignore")) - level = JZ_LOG_IGNORE; - else if(!strcmp(*argv, "error")) - level = JZ_LOG_ERROR; - else if(!strcmp(*argv, "warning")) - level = JZ_LOG_WARNING; - else if(!strcmp(*argv, "notice")) - level = JZ_LOG_NOTICE; - else if(!strcmp(*argv, "detail")) - level = JZ_LOG_DETAIL; - else if(!strcmp(*argv, "debug")) - level = JZ_LOG_DEBUG; - else { - jz_log(jz, JZ_LOG_ERROR, "Invalid log level '%s'", *argv); - exit(2); - } - - jz_context_set_log_level(jz, level); - } else { - jz_log(jz, JZ_LOG_ERROR, "Invalid global option '%s'", *argv); - exit(2); - } - - --argc, ++argv; - } - - /* Read the device type */ - if(argc == 0) { - jz_log(jz, JZ_LOG_ERROR, "No device specified (try jztool --help)"); - exit(2); - } - - dev_info = jz_get_device_info_named(*argv); - if(!dev_info) { - jz_log(jz, JZ_LOG_ERROR, "Unknown device '%s' (try jztool --help)", *argv); - exit(2); - } - - cpu_info = jz_get_cpu_info(dev_info->cpu_type); - - /* Dispatch to device handler */ - --argc, ++argv; - switch(dev_info->device_type) { - case JZ_DEVICE_FIIOM3K: - case JZ_DEVICE_SHANLINGQ1: - case JZ_DEVICE_EROSQ: - return cmdline_x1000(argc, argv); - - default: - jz_log(jz, JZ_LOG_ERROR, "INTERNAL ERROR: unhandled device type"); - return 1; - } -} diff --git a/rbutil/jztool/src/buffer.c b/rbutil/jztool/src/buffer.c deleted file mode 100644 index 9e9c9ff5d1..0000000000 --- a/rbutil/jztool/src/buffer.c +++ /dev/null @@ -1,134 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "jztool.h" -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -/** \brief Allocate a buffer, optionally providing its contents. - * \param size Number of bytes to allocate - * \param data Initial contents of the buffer, must be at least `size` bytes - * \return Pointer to buffer or NULL if out of memory. - * \note The buffer will not take ownership of the `data` pointer, instead it - * allocates a fresh buffer and copies the contents of `data` into it. - */ -jz_buffer* jz_buffer_alloc(size_t size, const void* data) -{ - jz_buffer* buf = malloc(sizeof(struct jz_buffer)); - if(!buf) - return NULL; - - buf->data = malloc(size); - if(!buf->data) { - free(buf); - return NULL; - } - - if(data) - memcpy(buf->data, data, size); - - buf->size = size; - return buf; -} - -/** \brief Free a buffer - */ -void jz_buffer_free(jz_buffer* buf) -{ - if(buf) { - free(buf->data); - free(buf); - } -} - -/** \brief Load a buffer from a file - * \param buf Returns loaded buffer on success, unmodified on error - * \param filename Path to the file - * \return either JZ_SUCCESS, or one of the following errors - * \retval JZ_ERR_OPEN_FILE file cannot be opened - * \retval JZ_ERR_OUT_OF_MEMORY cannot allocate buffer to hold file contents - * \retval JZ_ERR_FILE_IO problem reading file data - */ -int jz_buffer_load(jz_buffer** buf, const char* filename) -{ - FILE* f; - jz_buffer* b; - int rc; - - f = fopen(filename, "rb"); - if(!f) - return JZ_ERR_OPEN_FILE; - - fseek(f, 0, SEEK_END); - int size = ftell(f); - fseek(f, 0, SEEK_SET); - - b = jz_buffer_alloc(size, NULL); - if(!b) { - rc = JZ_ERR_OUT_OF_MEMORY; - goto err_fclose; - } - - if(fread(b->data, size, 1, f) != 1) { - rc = JZ_ERR_FILE_IO; - goto err_free_buf; - } - - rc = JZ_SUCCESS; - *buf = b; - - err_fclose: - fclose(f); - return rc; - - err_free_buf: - jz_buffer_free(b); - goto err_fclose; -} - -/** \brief Save a buffer to a file - * \param buf Buffer to be written out - * \param filename Path to the file - * \return either JZ_SUCCESS, or one of the following errors - * \retval JZ_ERR_OPEN_FILE file cannot be opened - * \retval JZ_ERR_FILE_IO problem writing file data - */ -int jz_buffer_save(jz_buffer* buf, const char* filename) -{ - int rc; - FILE* f; - - f = fopen(filename, "wb"); - if(!f) - return JZ_ERR_OPEN_FILE; - - if(fwrite(buf->data, buf->size, 1, f) != 1) { - rc = JZ_ERR_FILE_IO; - goto err_fclose; - } - - rc = JZ_SUCCESS; - - err_fclose: - fclose(f); - return rc; -} diff --git a/rbutil/jztool/src/context.c b/rbutil/jztool/src/context.c deleted file mode 100644 index d269d1eece..0000000000 --- a/rbutil/jztool/src/context.c +++ /dev/null @@ -1,177 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "jztool_private.h" -#include <string.h> -#include <stdlib.h> -#include <stddef.h> -#include <stdarg.h> -#include <stdio.h> -#include <time.h> - -#ifdef WIN32 -# include <windows.h> -#endif - -/** \brief Allocate a library context - * \returns New context or NULL if out of memory - */ -jz_context* jz_context_create(void) -{ - jz_context* jz = malloc(sizeof(struct jz_context)); - if(!jz) - return NULL; - - memset(jz, 0, sizeof(struct jz_context)); - jz->log_level = JZ_LOG_ERROR; - return jz; -} - -/** \brief Destroy the context and free its memory */ -void jz_context_destroy(jz_context* jz) -{ - if(jz->usb_ctx) { - jz_log(jz, JZ_LOG_ERROR, "BUG: USB was not cleaned up properly"); - libusb_exit(jz->usb_ctx); - } - - free(jz); -} - -/** \brief Set a user data pointer. Useful for callbacks. */ -void jz_context_set_user_data(jz_context* jz, void* ptr) -{ - jz->user_data = ptr; -} - -/** \brief Get the user data pointer */ -void* jz_context_get_user_data(jz_context* jz) -{ - return jz->user_data; -} - -/** \brief Set the log message callback. - * \note By default, no message callback is set! No messages will be logged - * in this case, so ensure you set a callback if messages are desired. - */ -void jz_context_set_log_cb(jz_context* jz, jz_log_cb cb) -{ - jz->log_cb = cb; -} - -/** \brief Set the log level. - * - * Messages of less importance than the set log level are not logged. - * The default log level is `JZ_LOG_WARNING`. The special log level - * `JZ_LOG_IGNORE` can be used to disable all logging temporarily. - * - * The `JZ_LOG_DEBUG` log level is extremely verbose and will log all calls, - * normally it's only useful for catching bugs. - */ -void jz_context_set_log_level(jz_context* jz, jz_log_level lev) -{ - jz->log_level = lev; -} - -/** \brief Log an informational message. - * \param lev Log level for this message - * \param fmt `printf` style message format string - */ -void jz_log(jz_context* jz, jz_log_level lev, const char* fmt, ...) -{ - if(!jz->log_cb) - return; - if(lev == JZ_LOG_IGNORE) - return; - if(lev > jz->log_level) - return; - - va_list ap; - - va_start(ap, fmt); - int n = vsnprintf(NULL, 0, fmt, ap); - va_end(ap); - - if(n < 0) - return; - - char* buf = malloc(n + 1); - if(!buf) - return; - - va_start(ap, fmt); - n = vsnprintf(buf, n + 1, fmt, ap); - va_end(ap); - - if(n >= 0) - jz->log_cb(lev, buf); - - free(buf); -} - -/** \brief Log callback which writes messages to `stderr`. - */ -void jz_log_cb_stderr(jz_log_level lev, const char* msg) -{ - static const char* const tags[] = - {"ERROR", "WARNING", "NOTICE", "DETAIL", "DEBUG"}; - fprintf(stderr, "[%7s] %s\n", tags[lev], msg); - fflush(stderr); -} - -/** \brief Sleep for `ms` milliseconds. - */ -void jz_sleepms(int ms) -{ -#ifdef WIN32 - Sleep(ms); -#else - struct timespec ts; - long ns = ms % 1000; - ts.tv_nsec = ns * 1000 * 1000; - ts.tv_sec = ms / 1000; - nanosleep(&ts, NULL); -#endif -} - -/** \brief Add reference to libusb context, allocating it if necessary */ -int jz_context_ref_libusb(jz_context* jz) -{ - if(jz->usb_ctxref == 0) { - int rc = libusb_init(&jz->usb_ctx); - if(rc < 0) { - jz_log(jz, JZ_LOG_ERROR, "libusb_init: %s", libusb_strerror(rc)); - return JZ_ERR_USB; - } - } - - jz->usb_ctxref += 1; - return JZ_SUCCESS; -} - -/** \brief Remove reference to libusb context, freeing if it hits zero */ -void jz_context_unref_libusb(jz_context* jz) -{ - if(--jz->usb_ctxref == 0) { - libusb_exit(jz->usb_ctx); - jz->usb_ctx = NULL; - } -} diff --git a/rbutil/jztool/src/device_info.c b/rbutil/jztool/src/device_info.c deleted file mode 100644 index cc431959ca..0000000000 --- a/rbutil/jztool/src/device_info.c +++ /dev/null @@ -1,109 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "jztool.h" -#include <string.h> - -static const jz_device_info infotable[JZ_NUM_DEVICES] = { - [JZ_DEVICE_FIIOM3K] = { - .name = "fiiom3k", - .file_ext = "m3k", - .description = "FiiO M3K", - .device_type = JZ_DEVICE_FIIOM3K, - .cpu_type = JZ_CPU_X1000, - .vendor_id = 0x2972, - .product_id = 0x0003, - }, - [JZ_DEVICE_SHANLINGQ1] = { - .name = "shanlingq1", - .file_ext = "q1", - .description = "Shanling Q1", - .device_type = JZ_DEVICE_SHANLINGQ1, - .cpu_type = JZ_CPU_X1000, - .vendor_id = 0x0525, - .product_id = 0xa4a5, - }, - [JZ_DEVICE_EROSQ] = { - .name = "erosq", - .file_ext = "erosq", - .description = "AIGO Eros Q", - .device_type = JZ_DEVICE_EROSQ, - .cpu_type = JZ_CPU_X1000, - .vendor_id = 0xc502, - .product_id = 0x0023, - }, -}; - -static const jz_cpu_info cputable[JZ_NUM_CPUS] = { - [JZ_CPU_X1000] = { - .info_str = "X1000_v1", - .vendor_id = 0xa108, - .product_id = 0x1000, - .stage1_load_addr = 0xf4001000, - .stage1_exec_addr = 0xf4001800, - .stage2_load_addr = 0x80004000, - .stage2_exec_addr = 0x80004000, - }, -}; - -/** \brief Lookup info for a device by type, returns NULL if not found. */ -const jz_device_info* jz_get_device_info(jz_device_type type) -{ - return jz_get_device_info_indexed(type); -} - -/** \brief Lookup info for a device by name, returns NULL if not found. */ -const jz_device_info* jz_get_device_info_named(const char* name) -{ - for(int i = 0; i < JZ_NUM_DEVICES; ++i) - if(!strcmp(infotable[i].name, name)) - return &infotable[i]; - - return NULL; -} - -/** \brief Get a device info entry by index, returns NULL if out of range. */ -const jz_device_info* jz_get_device_info_indexed(int index) -{ - if(index < JZ_NUM_DEVICES) - return &infotable[index]; - else - return NULL; -} - -/** \brief Lookup info for a CPU, returns NULL if not found. */ -const jz_cpu_info* jz_get_cpu_info(jz_cpu_type type) -{ - if(type < JZ_NUM_CPUS) - return &cputable[type]; - else - return NULL; -} - -/** \brief Lookup info for a CPU by info string, returns NULL if not found. */ -const jz_cpu_info* jz_get_cpu_info_named(const char* info_str) -{ - for(int i = 0; i < JZ_NUM_CPUS; ++i) - if(!strcmp(cputable[i].info_str, info_str)) - return &cputable[i]; - - return NULL; -} diff --git a/rbutil/jztool/src/identify_file.c b/rbutil/jztool/src/identify_file.c deleted file mode 100644 index e475d98a3b..0000000000 --- a/rbutil/jztool/src/identify_file.c +++ /dev/null @@ -1,170 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "jztool.h" -#include <string.h> - -/* Following is copied from mkspl-x1000, basically */ -struct x1000_spl_header { - uint8_t magic[8]; - uint8_t type; - uint8_t crc7; - uint8_t ppb; - uint8_t bpp; - uint32_t length; -}; - -static const uint8_t x1000_spl_header_magic[8] = - {0x06, 0x05, 0x04, 0x03, 0x02, 0x55, 0xaa, 0x55}; - -static const size_t X1000_SPL_HEADER_SIZE = 2 * 1024; - -static uint8_t crc7(const uint8_t* buf, size_t len) -{ - /* table-based computation of CRC7 */ - static const uint8_t t[256] = { - 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, - 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, - 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26, - 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e, - 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d, - 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45, - 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14, - 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c, - 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b, - 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13, - 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42, - 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a, - 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69, - 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21, - 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70, - 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38, - 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e, - 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36, - 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67, - 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f, - 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, - 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, - 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55, - 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d, - 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a, - 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52, - 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03, - 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b, - 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28, - 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60, - 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31, - 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79 - }; - - uint8_t crc = 0; - while(len--) - crc = t[(crc << 1) ^ *buf++]; - return crc; -} - -/** \brief Identify a file as an SPL for X1000 CPUs - * \param data File data buffer - * \param len Length of file - * \return JZ_SUCCESS if file looks correct, or one of the following errors - * \retval JZ_IDERR_WRONG_SIZE file too small or size doesn't match header - * \retval JZ_IDERR_BAD_HEADER missing magic bytes from header - * \retval JZ_IDERR_BAD_CHECKSUM CRC7 mismatch - */ -int jz_identify_x1000_spl(const void* data, size_t len) -{ - /* Use <= check because a header-only file is not really valid, - * it should have at least one byte in it... */ - if(len <= X1000_SPL_HEADER_SIZE) - return JZ_IDERR_WRONG_SIZE; - - /* Look for header magic bytes */ - const struct x1000_spl_header* header = (const struct x1000_spl_header*)data; - if(memcmp(header->magic, x1000_spl_header_magic, 8)) - return JZ_IDERR_BAD_HEADER; - - /* Length stored in the header should equal the length of the file */ - if(header->length != len) - return JZ_IDERR_WRONG_SIZE; - - /* Compute the CRC7 checksum; it only covers the SPL code */ - const uint8_t* dat = (const uint8_t*)data; - uint8_t sum = crc7(&dat[X1000_SPL_HEADER_SIZE], len - X1000_SPL_HEADER_SIZE); - if(header->crc7 != sum) - return JZ_IDERR_BAD_CHECKSUM; - - return JZ_SUCCESS; - -} - -static const struct scramble_model_info { - const char* name; - int model_num; - size_t offset_crc; - size_t offset_name; - size_t offset_data; -} scramble_models[] = { - {"fiio", 114, 0, 4, 8}, - {"shq1", 115, 0, 4, 8}, - {"eros", 116, 0, 4, 8}, - {NULL, 0, 0, 0, 0}, -}; - -/** \brief Identify a file as a Rockbox `scramble` image - * \param data File data buffer - * \param len Length of file - * \return JZ_SUCCESS if file looks correct, or one of the following errors - * \retval JZ_IDERR_UNRECOGNIZED_MODEL unsupported/unknown model type - * \retval JZ_IDERR_BAD_CHECKSUM checksum mismatch - */ -int jz_identify_scramble_image(const void* data, size_t len) -{ - const uint8_t* dat; - const struct scramble_model_info* model_info; - uint32_t sum, file_sum; - - dat = (const uint8_t*)data; - model_info = &scramble_models[0]; - - /* Look up the model number */ - for(; model_info->name != NULL; ++model_info) { - if(model_info->offset_name + 4 > len) - continue; - if(!memcmp(&dat[model_info->offset_name], model_info->name, 4)) - break; - } - - if(model_info->name == NULL) - return JZ_IDERR_UNRECOGNIZED_MODEL; - - /* Compute the checksum */ - sum = model_info->model_num; - for(size_t i = model_info->offset_data; i < len; ++i) - sum += dat[i]; - - /* Compare with file's checksum, it's stored in big-endian form */ - dat += model_info->offset_crc; - file_sum = (dat[0] << 24) | (dat[1] << 16) | (dat[2] << 8) | dat[3]; - if(sum != file_sum) - return JZ_IDERR_BAD_CHECKSUM; - - return JZ_SUCCESS; -} diff --git a/rbutil/jztool/src/jztool_private.h b/rbutil/jztool/src/jztool_private.h deleted file mode 100644 index 11299f21f9..0000000000 --- a/rbutil/jztool/src/jztool_private.h +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#ifndef JZTOOL_PRIVATE_H -#define JZTOOL_PRIVATE_H - -#include "jztool.h" -#include <libusb.h> - -struct jz_context { - void* user_data; - jz_log_cb log_cb; - jz_log_level log_level; - libusb_context* usb_ctx; - int usb_ctxref; -}; - -struct jz_usbdev { - jz_context* jz; - libusb_device_handle* handle; -}; - -int jz_context_ref_libusb(jz_context* jz); -void jz_context_unref_libusb(jz_context* jz); - -#endif /* JZTOOL_PRIVATE_H */ diff --git a/rbutil/jztool/src/ucl_unpack.c b/rbutil/jztool/src/ucl_unpack.c deleted file mode 100644 index 3b199c7008..0000000000 --- a/rbutil/jztool/src/ucl_unpack.c +++ /dev/null @@ -1,128 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "jztool.h" -#include "ucl/ucl.h" - -static uint32_t xread32(const uint8_t* d) -{ - uint32_t r = 0; - r |= d[0] << 24; - r |= d[1] << 16; - r |= d[2] << 8; - r |= d[3] << 0; - return r; -} - -/* adapted from firmware/common/ucl_decompress.c */ -jz_buffer* jz_ucl_unpack(const uint8_t* src, uint32_t src_len, uint32_t* dst_len) -{ - static const uint8_t magic[8] = - {0x00, 0xe9, 0x55, 0x43, 0x4c, 0xff, 0x01, 0x1a}; - - jz_buffer* buffer = NULL; - - /* make sure there are enough bytes for the header */ - if(src_len < 18) - goto error; - - /* avoid memcmp for reasons of code size */ - for(size_t i = 0; i < sizeof(magic); ++i) - if(src[i] != magic[i]) - goto error; - - /* read the other header fields */ - /* uint32_t flags = xread32(&src[8]); */ - uint8_t method = src[12]; - /* uint8_t level = src[13]; */ - uint32_t block_size = xread32(&src[14]); - - /* check supported compression method */ - if(method != 0x2e) - goto error; - - /* validate */ - if(block_size < 1024 || block_size > 8*1024*1024) - goto error; - - src += 18; - src_len -= 18; - - /* Calculate amount of space that we might need & allocate a buffer: - * - subtract 4 to account for end of file marker - * - each block is block_size bytes + 8 bytes of header - * - add one to nr_blocks to account for case where file size < block size - * - total size = max uncompressed size of block * nr_blocks - */ - uint32_t nr_blocks = (src_len - 4) / (8 + block_size) + 1; - uint32_t max_size = nr_blocks * (block_size + block_size/8 + 256); - buffer = jz_buffer_alloc(max_size, NULL); - if(!buffer) - goto error; - - /* perform the decompression */ - uint32_t dst_ilen = buffer->size; - uint8_t* dst = buffer->data; - while(1) { - if(src_len < 4) - goto error; - - uint32_t out_len = xread32(src); src += 4, src_len -= 4; - if(out_len == 0) - break; - - if(src_len < 4) - goto error; - - uint32_t in_len = xread32(src); src += 4, src_len -= 4; - if(in_len > block_size || out_len > block_size || - in_len == 0 || in_len > out_len) - goto error; - - if(src_len < in_len) - goto error; - - if(in_len < out_len) { - uint32_t actual_out_len = dst_ilen; - int rc = ucl_nrv2e_decompress_safe_8(src, in_len, dst, &actual_out_len, NULL); - if(rc != UCL_E_OK) - goto error; - if(actual_out_len != out_len) - goto error; - } else { - for(size_t i = 0; i < in_len; ++i) - dst[i] = src[i]; - } - - src += in_len; - src_len -= in_len; - dst += out_len; - dst_ilen -= out_len; - } - - /* subtract leftover number of bytes to get size of compressed output */ - *dst_len = buffer->size - dst_ilen; - return buffer; - - error: - jz_buffer_free(buffer); - return NULL; -} diff --git a/rbutil/jztool/src/usb.c b/rbutil/jztool/src/usb.c deleted file mode 100644 index cfc3ba60cb..0000000000 --- a/rbutil/jztool/src/usb.c +++ /dev/null @@ -1,291 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "jztool_private.h" -#include <stdlib.h> -#include <stdbool.h> -#include <string.h> - -#define VR_GET_CPU_INFO 0 -#define VR_SET_DATA_ADDRESS 1 -#define VR_SET_DATA_LENGTH 2 -#define VR_FLUSH_CACHES 3 -#define VR_PROGRAM_START1 4 -#define VR_PROGRAM_START2 5 - -/** \brief Open a USB device - * \param jz Context - * \param devptr Returns pointer to the USB device upon success - * \param vend_id USB vendor ID - * \param prod_id USB product ID - * \return either JZ_SUCCESS if device was opened, or an error below - * \retval JZ_ERR_OUT_OF_MEMORY malloc failed - * \retval JZ_ERR_USB libusb error (details are logged) - * \retval JZ_ERR_NO_DEVICE can't unambiguously find the device - */ -int jz_usb_open(jz_context* jz, jz_usbdev** devptr, uint16_t vend_id, uint16_t prod_id) -{ - int rc; - jz_usbdev* dev = NULL; - libusb_device_handle* usb_handle = NULL; - libusb_device** dev_list = NULL; - ssize_t dev_index = -1, dev_count; - - rc = jz_context_ref_libusb(jz); - if(rc < 0) - return rc; - - dev = malloc(sizeof(struct jz_usbdev)); - if(!dev) { - rc = JZ_ERR_OUT_OF_MEMORY; - goto error; - } - - dev_count = libusb_get_device_list(jz->usb_ctx, &dev_list); - if(dev_count < 0) { - jz_log(jz, JZ_LOG_ERROR, "libusb_get_device_list: %s", libusb_strerror(dev_count)); - rc = JZ_ERR_USB; - goto error; - } - - for(ssize_t i = 0; i < dev_count; ++i) { - struct libusb_device_descriptor desc; - rc = libusb_get_device_descriptor(dev_list[i], &desc); - if(rc < 0) { - jz_log(jz, JZ_LOG_WARNING, "libusb_get_device_descriptor: %s", - libusb_strerror(rc)); - continue; - } - - if(desc.idVendor != vend_id || desc.idProduct != prod_id) - continue; - - if(dev_index >= 0) { - /* not the best, but it is the safest thing */ - jz_log(jz, JZ_LOG_ERROR, "Multiple devices match ID %04x:%04x", - (unsigned int)vend_id, (unsigned int)prod_id); - jz_log(jz, JZ_LOG_ERROR, "Please ensure only one player is plugged in, and try again"); - rc = JZ_ERR_NO_DEVICE; - goto error; - } - - dev_index = i; - } - - if(dev_index < 0) { - jz_log(jz, JZ_LOG_ERROR, "No device with ID %04x:%04x found", - (unsigned int)vend_id, (unsigned int)prod_id); - rc = JZ_ERR_NO_DEVICE; - goto error; - } - - rc = libusb_open(dev_list[dev_index], &usb_handle); - if(rc < 0) { - jz_log(jz, JZ_LOG_ERROR, "libusb_open: %s", libusb_strerror(rc)); - rc = JZ_ERR_USB; - goto error; - } - - rc = libusb_claim_interface(usb_handle, 0); - if(rc < 0) { - jz_log(jz, JZ_LOG_ERROR, "libusb_claim_interface: %s", libusb_strerror(rc)); - rc = JZ_ERR_USB; - goto error; - } - - jz_log(jz, JZ_LOG_DEBUG, "Opened device (%p, ID %04x:%04x)", - dev, (unsigned int)vend_id, (unsigned int)prod_id); - dev->jz = jz; - dev->handle = usb_handle; - *devptr = dev; - rc = JZ_SUCCESS; - - exit: - if(dev_list) - libusb_free_device_list(dev_list, true); - return rc; - - error: - if(dev) - free(dev); - if(usb_handle) - libusb_close(usb_handle); - jz_context_unref_libusb(jz); - goto exit; -} - -/** \brief Close a USB device - * \param dev Device to close; memory will be freed automatically - */ -void jz_usb_close(jz_usbdev* dev) -{ - jz_log(dev->jz, JZ_LOG_DEBUG, "Closing device (%p)", dev); - libusb_release_interface(dev->handle, 0); - libusb_close(dev->handle); - jz_context_unref_libusb(dev->jz); - free(dev); -} - -// Does an Ingenic-specific vendor request -// Written with X1000 in mind but other Ingenic CPUs have the same commands -static int jz_usb_vendor_req(jz_usbdev* dev, int req, uint32_t arg, - void* buffer, int buflen) -{ - int rc = libusb_control_transfer(dev->handle, - LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, - req, arg >> 16, arg & 0xffff, buffer, buflen, 1000); - - if(rc < 0) { - jz_log(dev->jz, JZ_LOG_ERROR, "libusb_control_transfer: %s", libusb_strerror(rc)); - rc = JZ_ERR_USB; - } else { - static const char* req_names[] = { - "GET_CPU_INFO", - "SET_DATA_ADDRESS", - "SET_DATA_LENGTH", - "FLUSH_CACHES", - "PROGRAM_START1", - "PROGRAM_START2", - }; - - jz_log(dev->jz, JZ_LOG_DEBUG, "Issued %s %08lu", - req_names[req], (unsigned long)arg); - rc = JZ_SUCCESS; - } - - return rc; -} - -// Bulk transfer wrapper -static int jz_usb_transfer(jz_usbdev* dev, bool write, size_t len, void* buf) -{ - int xfered = 0; - int ep = write ? LIBUSB_ENDPOINT_OUT|1 : LIBUSB_ENDPOINT_IN|1; - int rc = libusb_bulk_transfer(dev->handle, ep, buf, len, &xfered, 10000); - - if(rc < 0) { - jz_log(dev->jz, JZ_LOG_ERROR, "libusb_bulk_transfer: %s", libusb_strerror(rc)); - rc = JZ_ERR_USB; - } else if(xfered != (int)len) { - jz_log(dev->jz, JZ_LOG_ERROR, "libusb_bulk_transfer: incorrect amount of data transfered"); - rc = JZ_ERR_USB; - } else { - jz_log(dev->jz, JZ_LOG_DEBUG, "Transferred %zu bytes %s", - len, write ? "to device" : "from device"); - rc = JZ_SUCCESS; - } - - return rc; -} - -// Memory send/receive primitive, performs the necessary vendor requests -// and then tranfers data using the bulk endpoint -static int jz_usb_sendrecv(jz_usbdev* dev, bool write, uint32_t addr, - size_t len, void* data) -{ - int rc; - rc = jz_usb_vendor_req(dev, VR_SET_DATA_ADDRESS, addr, NULL, 0); - if(rc < 0) - return rc; - - rc = jz_usb_vendor_req(dev, VR_SET_DATA_LENGTH, len, NULL, 0); - if(rc < 0) - return rc; - - return jz_usb_transfer(dev, write, len, data); -} - -/** \brief Write data to device memory - * \param dev USB device - * \param addr Address where data should be written - * \param len Length of the data, in bytes, should be positive - * \param data Data buffer - * \return either JZ_SUCCESS on success or a failure code - */ -int jz_usb_send(jz_usbdev* dev, uint32_t addr, size_t len, const void* data) -{ - return jz_usb_sendrecv(dev, true, addr, len, (void*)data); -} - -/** \brief Read data to device memory - * \param dev USB device - * \param addr Address to read from - * \param len Length of the data, in bytes, should be positive - * \param data Data buffer - * \return either JZ_SUCCESS on success or a failure code - */ -int jz_usb_recv(jz_usbdev* dev, uint32_t addr, size_t len, void* data) -{ - return jz_usb_sendrecv(dev, false, addr, len, data); -} - -/** \brief Execute stage1 program jumping to the specified address - * \param dev USB device - * \param addr Address to begin execution at - * \return either JZ_SUCCESS on success or a failure code - */ -int jz_usb_start1(jz_usbdev* dev, uint32_t addr) -{ - return jz_usb_vendor_req(dev, VR_PROGRAM_START1, addr, NULL, 0); -} - -/** \brief Execute stage2 program jumping to the specified address - * \param dev USB device - * \param addr Address to begin execution at - * \return either JZ_SUCCESS on success or a failure code - */ -int jz_usb_start2(jz_usbdev* dev, uint32_t addr) -{ - return jz_usb_vendor_req(dev, VR_PROGRAM_START2, addr, NULL, 0); -} - -/** \brief Ask device to flush CPU caches - * \param dev USB device - * \return either JZ_SUCCESS on success or a failure code - */ -int jz_usb_flush_caches(jz_usbdev* dev) -{ - return jz_usb_vendor_req(dev, VR_FLUSH_CACHES, 0, NULL, 0); -} - -/** \brief Ask device for CPU info string - * \param dev USB device - * \param buffer Buffer to hold the info string - * \param buflen Size of the buffer, in bytes - * \return either JZ_SUCCESS on success or a failure code - * - * The buffer will always be null terminated, but to ensure the info string is - * not truncated the buffer needs to be at least `JZ_CPUINFO_BUFLEN` byes long. - */ -int jz_usb_get_cpu_info(jz_usbdev* dev, char* buffer, size_t buflen) -{ - char tmpbuf[JZ_CPUINFO_BUFLEN]; - int rc = jz_usb_vendor_req(dev, VR_GET_CPU_INFO, 0, tmpbuf, 8); - if(rc != JZ_SUCCESS) - return rc; - - if(buflen > 0) { - strncpy(buffer, tmpbuf, buflen); - buffer[buflen - 1] = 0; - } - - return JZ_SUCCESS; -} diff --git a/rbutil/jztool/src/x1000.c b/rbutil/jztool/src/x1000.c deleted file mode 100644 index f59727a2ca..0000000000 --- a/rbutil/jztool/src/x1000.c +++ /dev/null @@ -1,180 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "jztool.h" -#include "jztool_private.h" -#include "microtar-stdio.h" -#include <stdbool.h> -#include <string.h> - -/* TODO: these functions could be refactored to be CPU-agnostic */ -static int run_stage1(jz_usbdev* dev, jz_buffer* buf) -{ - int rc = jz_usb_send(dev, 0xf4001000, buf->size, buf->data); - if(rc < 0) - return rc; - - return jz_usb_start1(dev, 0xf4001800); -} - -static int run_stage2(jz_usbdev* dev, jz_buffer* buf) -{ - int rc = jz_usb_send(dev, 0x80004000, buf->size, buf->data); - if(rc < 0) - return rc; - - rc = jz_usb_flush_caches(dev); - if(rc < 0) - return rc; - - return jz_usb_start2(dev, 0x80004000); -} - -static int get_file(jz_context* jz, mtar_t* tar, const char* file, - bool decompress, jz_buffer** buf) -{ - jz_buffer* buffer = NULL; - const mtar_header_t* h; - int rc; - - rc = mtar_find(tar, file); - if(rc != MTAR_ESUCCESS) { - jz_log(jz, JZ_LOG_ERROR, "can't find %s in boot file, tar error %d", file, rc); - return JZ_ERR_BAD_FILE_FORMAT; - } - - h = mtar_get_header(tar); - buffer = jz_buffer_alloc(h->size, NULL); - if(!buffer) - return JZ_ERR_OUT_OF_MEMORY; - - rc = mtar_read_data(tar, buffer->data, buffer->size); - if(rc < 0 || (unsigned)rc != buffer->size) { - jz_buffer_free(buffer); - jz_log(jz, JZ_LOG_ERROR, "can't read %s in boot file, tar error %d", file, rc); - return JZ_ERR_BAD_FILE_FORMAT; - } - - if(decompress) { - uint32_t dst_len; - jz_buffer* nbuf = jz_ucl_unpack(buffer->data, buffer->size, &dst_len); - jz_buffer_free(buffer); - if(!nbuf) { - jz_log(jz, JZ_LOG_ERROR, "error decompressing %s in boot file", file); - return JZ_ERR_BAD_FILE_FORMAT; - } - - /* for simplicity just forget original size of buffer */ - nbuf->size = dst_len; - buffer = nbuf; - } - - *buf = buffer; - return JZ_SUCCESS; -} - -static int show_version(jz_context* jz, jz_buffer* info_file) -{ - /* Extract the version string and log it for informational purposes */ - char* boot_version = (char*)info_file->data; - char* endpos = memchr(boot_version, '\n', info_file->size); - if(!endpos) { - jz_log(jz, JZ_LOG_ERROR, "invalid metadata in boot file"); - return JZ_ERR_BAD_FILE_FORMAT; - } - - *endpos = 0; - jz_log(jz, JZ_LOG_NOTICE, "Rockbox bootloader version: %s", boot_version); - return JZ_SUCCESS; -} - -/** \brief Load the Rockbox bootloader on an X1000 device - * \param dev USB device freshly returned by jz_usb_open() - * \param filename Path to the "bootloader.target" file - * \return either JZ_SUCCESS or an error code - */ -int jz_x1000_boot(jz_usbdev* dev, jz_device_type type, const char* filename) -{ - const jz_device_info* dev_info; - char spl_filename[32]; - jz_buffer* spl = NULL, *bootloader = NULL, *info_file = NULL; - mtar_t tar; - int rc; - - /* In retrospect using a model-dependent archive format was not a good - * idea, but it's not worth fixing just yet... */ - dev_info = jz_get_device_info(type); - if(!dev_info) - return JZ_ERR_OTHER; - /* use of sprintf is safe since file_ext is short */ - sprintf(spl_filename, "spl.%s", dev_info->file_ext); - - /* Now open the archive */ - rc = mtar_open(&tar, filename, "rb"); - if(rc != MTAR_ESUCCESS) { - jz_log(dev->jz, JZ_LOG_ERROR, "cannot open file %s (tar error: %d)", filename, rc); - return JZ_ERR_OPEN_FILE; - } - - /* Extract all necessary files */ - rc = get_file(dev->jz, &tar, spl_filename, false, &spl); - if(rc != JZ_SUCCESS) - goto error; - - rc = get_file(dev->jz, &tar, "bootloader.ucl", true, &bootloader); - if(rc != JZ_SUCCESS) - goto error; - - rc = get_file(dev->jz, &tar, "bootloader-info.txt", false, &info_file); - if(rc != JZ_SUCCESS) - goto error; - - /* Display the version string */ - rc = show_version(dev->jz, info_file); - if(rc != JZ_SUCCESS) - goto error; - - /* Stage1 boot of SPL to set up hardware */ - rc = run_stage1(dev, spl); - if(rc != JZ_SUCCESS) - goto error; - - /* Need a bit of time for SPL to handle init */ - jz_sleepms(500); - - /* Stage2 boot into the bootloader's recovery menu - * User has to take manual action from there */ - rc = run_stage2(dev, bootloader); - if(rc != JZ_SUCCESS) - goto error; - - rc = JZ_SUCCESS; - - error: - if(spl) - jz_buffer_free(spl); - if(bootloader) - jz_buffer_free(bootloader); - if(info_file) - jz_buffer_free(info_file); - mtar_close(&tar); - return rc; -} diff --git a/rbutil/libtools.make b/rbutil/libtools.make deleted file mode 100644 index 3ab150e876..0000000000 --- a/rbutil/libtools.make +++ /dev/null @@ -1,183 +0,0 @@ -# __________ __ ___. -# Open \______ \ ____ ____ | | _\_ |__ _______ ___ -# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -# \/ \/ \/ \/ \/ - -# libtools.make -# -# Common Makefile for tools used by Rockbox Utility. -# Provides rules for building as library, universal library (OS X) and -# standalone binary. -# -# LIBSOURCES is a list of files to build the lib -# SOURCES is a list of files to build for the main binary -# EXTRADEPS is a list of make targets dependencies -# -ifndef V -SILENT = @ -endif - -# Get directory this Makefile is in for relative paths. -TOP := $(dir $(lastword $(MAKEFILE_LIST))) -ifeq ($(OS),Windows_NT) -SHELL = cmd.exe -mkdir = if not exist $(subst /,\,$(1)) mkdir $(subst /,\,$(1)) -rm = if exist $(subst /,\,$(1)) del /q /s $(subst /,\,$(1)) -else -mkdir = mkdir -p $(1) -rm = rm -rf $(1) -endif - -# overwrite for releases -APPVERSION ?= $(shell $(TOP)/../tools/version.sh $(TOP)/..) -GCCFLAGS += -DVERSION=\"$(APPVERSION)\" -TARGET_DIR ?= $(abspath .)/ - -CC := gcc -CXX := g++ -# use either CC or CXX to link: this makes sure the compiler knows about its -# internal dependencies. Use CXX if we have at least one c++ file, since we -# then need to link the c++ standard library (which CXX does for us). -ifeq ($(strip $(filter %.cpp,$(SOURCES) $(LIBSOURCES))),) -LD := $(CC) -else -LD := $(CXX) -endif -CPPDEFINES := $(shell echo foo | $(CROSS)$(CC) -dM -E -) - -BINARY = $(OUTPUT) -# when building a Windows binary add the correct file suffix -ifeq ($(findstring CYGWIN,$(CPPDEFINES)),CYGWIN) -BINARY = $(OUTPUT).exe -GCCFLAGS += -mno-cygwin -COMPILETARGET = cygwin -else -ifeq ($(findstring MINGW,$(CPPDEFINES)),MINGW) -BINARY = $(OUTPUT).exe -COMPILETARGET = mingw -# use POSIX/C99 printf on windows -GCCFLAGS += -D__USE_MINGW_ANSI_STDIO=1 -else -ifeq ($(findstring APPLE,$(CPPDEFINES)),APPLE) -COMPILETARGET = darwin -LDOPTS += $(LDOPTS_OSX) -else -COMPILETARGET = posix -endif -endif -endif -$(info Compiler creates $(COMPILETARGET) binaries) - -# OS X specifics. Needs to consider cross compiling for Windows. -ifeq ($(findstring APPLE,$(CPPDEFINES)),APPLE) -# When building for 10.4+ we need to use gcc. Otherwise clang is used, so use -# that to determine if we need to set arch and isysroot. -ifeq ($(findstring __clang__,$(CPPDEFINES)),__clang__) -GCCFLAGS += -mmacosx-version-min=10.5 -ifneq ($(ISYSROOT),) -GCCFLAGS += -isysroot $(ISYSROOT) -endif -else -# when building libs for OS X 10.4+ build for both i386 and ppc at the same time. -# This creates fat objects, and ar can only create the archive but not operate -# on it. As a result the ar call must NOT use the u (update) flag. -ARCHFLAGS += -arch ppc -arch i386 -# building against SDK 10.4 is not compatible with gcc-4.2 (default on newer Xcode) -# might need adjustment for older Xcode. -CC = gcc-4.0 -GCCFLAGS += -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 -endif -endif - -BUILD_DIR ?= $(TARGET_DIR)build$(COMPILETARGET) -OBJDIR = $(abspath $(BUILD_DIR))/ - -all: $(BINARY) - -OBJS := $(addsuffix .o,$(addprefix $(OBJDIR),$(notdir $(SOURCES)))) -LIBOBJS := $(addsuffix .o,$(addprefix $(OBJDIR),$(notdir $(LIBSOURCES)))) - -# create dependency files. Make sure to use the same prefix as with OBJS! -$(foreach src,$(SOURCES) $(LIBSOURCES),$(eval $(addprefix $(OBJDIR),$(notdir $(src).o)): $(src))) -$(foreach src,$(SOURCES) $(LIBSOURCES),$(eval $(addprefix $(OBJDIR),$(notdir $(src).d)): $(src))) -DEPS = $(addprefix $(OBJDIR),$(addsuffix .d,$(notdir $(SOURCES) $(LIBSOURCES)))) --include $(DEPS) - -# additional link dependencies for the standalone executable -# extra dependencies: libucl -LIBUCL = libucl.a -$(LIBUCL): $(OBJDIR)$(LIBUCL) - -$(OBJDIR)$(LIBUCL): - $(SILENT)$(MAKE) -C $(TOP)/../tools/ucl/src TARGET_DIR=$(OBJDIR) CC=$(CC) $@ - -LIBBZIP2 = libbz2.a -$(LIBBZIP2): $(OBJDIR)$(LIBBZIP2) -$(OBJDIR)$(LIBBZIP2): - $(SILENT)$(MAKE) -C $(TOP)/bzip2 TARGET_DIR=$(OBJDIR) CC=$(CC) $@ - -LIBMICROTAR = libmicrotar.a -$(LIBMICROTAR): $(OBJDIR)$(LIBMICROTAR) - -$(OBJDIR)$(LIBMICROTAR): - $(SILENT)$(MAKE) -C $(TOP)/../lib/microtar/src TARGET_DIR=$(OBJDIR) CC=$(CC) $@ - -# building the standalone executable -$(BINARY): $(OBJS) $(EXTRADEPS) $(addprefix $(OBJDIR),$(EXTRALIBOBJS)) $(TARGET_DIR)lib$(OUTPUT).a - $(info LD $@) - $(SILENT)$(call mkdir,$(dir $@)) -# EXTRADEPS need to be built into OBJDIR. - $(SILENT)$(CROSS)$(LD) $(ARCHFLAGS) $(LDFLAGS) -o $(BINARY) \ - $(OBJS) $(addprefix $(OBJDIR),$(EXTRADEPS)) \ - $(addprefix $(OBJDIR),$(EXTRALIBOBJS)) lib$(OUTPUT).a $(addprefix $(OBJDIR),$(EXTRADEPS)) $(LDOPTS) - -# common rules -$(OBJDIR)%.c.o: - $(info CC $<) - $(SILENT)$(call mkdir,$(dir $@)) - $(SILENT)$(CROSS)$(CC) $(ARCHFLAGS) $(GCCFLAGS) $(CFLAGS) -MMD -c -o $@ $< - -$(OBJDIR)%.cpp.o: - $(info CXX $<) - $(SILENT)$(call mkdir,$(dir $@)) - $(SILENT)$(CROSS)$(CXX) $(ARCHFLAGS) $(GCCFLAGS) $(CXXFLAGS) -MMD -c -o $@ $< - -# lib rules -lib$(OUTPUT).a: $(TARGET_DIR)lib$(OUTPUT).a -lib$(OUTPUT): $(TARGET_DIR)lib$(OUTPUT).a - -$(TARGET_DIR)lib$(OUTPUT).a: $(LIBOBJS) \ - $(addprefix $(OBJDIR),$(EXTRALIBOBJS)) -# rules to build a DLL. Only works for W32 as target (i.e. MinGW toolchain) -dll: $(OUTPUT).dll -$(OUTPUT).dll: $(TARGET_DIR)$(OUTPUT).dll -$(TARGET_DIR)$(OUTPUT).dll: $(LIBOBJS) $(addprefix $(OBJDIR),$(EXTRALIBOBJS)) - $(info DLL $(notdir $@)) - $(SILENT)$(call mkdir,$(dir $@)) - $(SILENT)$(CROSS)$(CC) $(ARCHFLAGS) $(GCCFLAGS) -shared -o $@ $^ \ - -Wl,--output-def,$(TARGET_DIR)$(OUTPUT).def - -# create lib file from objects -$(TARGET_DIR)lib$(OUTPUT).a: $(LIBOBJS) $(addprefix $(OBJDIR),$(EXTRALIBOBJS)) - $(info AR $(notdir $@)) - $(SILENT)$(call mkdir,$(dir $@)) - $(SILENT)$(call rm,$@) - $(SILENT)$(CROSS)$(AR) rcs $@ $^ - -clean: - $(call rm, $(OBJS) $(OUTPUT) $(TARGET_DIR)lib$(OUTPUT)*.a $(OUTPUT).dmg) - $(call rm, $(OUTPUT)-* i386 ppc $(OBJDIR)) - -# extra tools -BIN2C = $(TOP)/tools/bin2c -$(BIN2C): - $(MAKE) -C $(TOP)/tools - -# OS X specifics -$(OUTPUT).dmg: $(OUTPUT) - $(info DMG $@) - $(SILENT)$(call mkdir,"$(OUTPUT)-$(APPVERSION)") - $(SILENT)cp -p $(OUTPUT) "$(OUTPUT)-$(APPVERSION)" - $(SILENT)hdiutil create -srcfolder "$(OUTPUT)-$(APPVERSION)" $@ diff --git a/rbutil/mkamsboot/.gitignore b/rbutil/mkamsboot/.gitignore deleted file mode 100644 index 568b1d5a87..0000000000 --- a/rbutil/mkamsboot/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build/ -mkamsboot diff --git a/rbutil/mkamsboot/Makefile b/rbutil/mkamsboot/Makefile deleted file mode 100644 index 7100bd9512..0000000000 --- a/rbutil/mkamsboot/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -# __________ __ ___. -# Open \______ \ ____ ____ | | _\_ |__ _______ ___ -# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -# \/ \/ \/ \/ \/ - -# We use the UCL code available in the Rockbox tools/ directory -CFLAGS += -I../../tools/ucl/include -Wall - -OUTPUT = mkamsboot -LIBUCL = libucl.a - -# inputs -LIBSOURCES := dualboot.c md5.c mkamsboot.c -SOURCES := main.c -# additional link dependencies for the standalone executable -EXTRADEPS := $(LIBUCL) - -include ../libtools.make -# explicit dependencies on dualboot.{c,h} and mkamsboot.h -$(OBJDIR)mkamsboot.o: dualboot.h dualboot.c mkamsboot.c mkamsboot.h -$(OBJDIR)main.o: dualboot.h dualboot.c main.c mkamsboot.h - - -$(TARGET_DIR)$(OUTPUT).dll: EXTRALIBOBJS += $(TARGET_DIR)ucl.dll -$(TARGET_DIR)$(OUTPUT).dll: $(TARGET_DIR)ucl.dll -$(TARGET_DIR)ucl.dll: - $(SILENT)$(MAKE) -C ../../tools/ucl/src/ \ - BUILD_DIR=$(BUILD_DIR) CC=$(CC) CROSS=$(CROSS) \ - TARGET_DIR=$(TARGET_DIR)/ ucl.dll diff --git a/rbutil/mkamsboot/README b/rbutil/mkamsboot/README deleted file mode 100644 index 8e3f202f38..0000000000 --- a/rbutil/mkamsboot/README +++ /dev/null @@ -1,67 +0,0 @@ -mkamsboot ---------- - -A tool to inject a bootloader into a Sansa V2 (AMS) firmware file. - - -Usage ------ - -mkamsboot <firmware file> <boot file> <output file> - -<firmware file> is an original Sansa firmware file obtained from the Sansa - forums for example : http://forums.sandisk.com/sansa/?category.id=devices - -<boot file> is the code you want to execute (a rockbox bootloader), previously - scrambled with tools/scramble utility. - -<output file> is the resulting firmware file which you'll have to copy on your - Sansa player. See "Firmware filenames". - - -Supported models ----------------- - -Sansa Clip : firmware version starting with "01." -Sansa Clip+ : firmware version starting with "01." -Sansa Clipv2: firmware version starting with "02." -Sansa ClipZip: firmware version starting with "01." -Sansa Fuze : firmware version starting with "01." -Sansa Fuzev2: firmware version starting with "02." -Sansa E200v2: firmware version starting with "03." -Sansa C200v2: firmware version starting with "03." -Sansa M200v4: firmware version starting with "4." - - -Firmware filenames ------------------- - -For the firmware upgrade to happen, the firmware has to be named specially: - -clip v2 : m30pa.bin -clip : m300a.bin -clip+ : clppa.bin -clip zip: clpza.bin -fuze : fuzea.bin -fuzev2 : fuzpa.bin -e200v2 : e200pa.bin -c200v2 : c200pa.bin -m200v4 : m200a.bin - - -Dual-Boot ---------- - - The purpose of this program is to provide dual-boot between the original -firmware and the new (rockbox) firmware. - - By default the player will boot into the new firmware. - - To boot into the Original Firmware, you need to press the Left key. - ***Note : on the Clip+ you can alternatively press the Home key. - ***Note : on the Clip Zip you can alternatively press the Vol- key. - -Hacking -------- - -See comments in mkamsboot.c and dualboot/dualboot.S for more information. diff --git a/rbutil/mkamsboot/dualboot.c b/rbutil/mkamsboot/dualboot.c deleted file mode 100644 index d97ab0e95b..0000000000 --- a/rbutil/mkamsboot/dualboot.c +++ /dev/null @@ -1,152 +0,0 @@ -/* Generated by bin2c */ - -#include "dualboot.h" - -unsigned char nrv2e_d8[168] = { - 0x0f, 0x18, 0x01, 0x24, 0x65, 0x42, 0xe4, 0x07, 0x05, 0x26, 0x36, 0x02, 0x0a, 0xe0, 0x00, 0x20, - 0x00, 0x47, 0x04, 0x78, 0x64, 0x41, 0x01, 0x30, 0x24, 0x06, 0xf7, 0x46, 0x03, 0x78, 0x01, 0x30, - 0x13, 0x70, 0x01, 0x32, 0x24, 0x19, 0xfe, 0x46, 0xf3, 0xd0, 0xf7, 0xd2, 0x01, 0x21, 0x04, 0xe0, - 0x01, 0x39, 0x24, 0x19, 0xfe, 0x46, 0xec, 0xd0, 0x49, 0x41, 0x24, 0x19, 0xfe, 0x46, 0xe8, 0xd0, - 0x49, 0x41, 0x24, 0x19, 0xfe, 0x46, 0xe4, 0xd0, 0xf2, 0xd3, 0xcb, 0x1e, 0x00, 0x21, 0x08, 0xd3, - 0x1b, 0x02, 0x05, 0x78, 0x01, 0x30, 0x1d, 0x43, 0xed, 0x43, 0xd8, 0xd0, 0x6d, 0x10, 0x13, 0xd2, - 0x03, 0xe0, 0x24, 0x19, 0xfe, 0x46, 0xd4, 0xd0, 0x0e, 0xd2, 0x01, 0x21, 0x24, 0x19, 0xfe, 0x46, - 0xcf, 0xd0, 0x09, 0xd2, 0x24, 0x19, 0xfe, 0x46, 0xcb, 0xd0, 0x49, 0x41, 0x24, 0x19, 0xfe, 0x46, - 0xc7, 0xd0, 0xf7, 0xd3, 0x04, 0x31, 0x04, 0xe0, 0x24, 0x19, 0xfe, 0x46, 0xc1, 0xd0, 0x49, 0x41, - 0x02, 0x31, 0xee, 0x42, 0x00, 0xd2, 0x01, 0x31, 0x13, 0x78, 0x53, 0x5d, 0x13, 0x70, 0x01, 0x32, - 0x01, 0x39, 0xfa, 0xd1, 0xbe, 0xe7, 0x00, 0x00 -}; -unsigned char dualboot_clip[196] = { - 0x06, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x24, 0x00, 0x1f, 0xe5, 0x24, 0x10, 0x1f, 0xe5, 0x01, 0x20, 0x40, 0xe0, 0x18, 0x30, 0x1f, 0xe5, - 0x01, 0x40, 0x50, 0xe4, 0x01, 0x40, 0x43, 0xe4, 0x00, 0x00, 0x52, 0xe1, 0xfb, 0xff, 0xff, 0x1a, - 0x2c, 0x30, 0x0f, 0xe5, 0x6c, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0x90, 0xe5, 0x01, 0x18, 0x81, 0xe3, - 0x00, 0x10, 0x80, 0xe5, 0x60, 0x00, 0x9f, 0xe5, 0x20, 0x10, 0xa0, 0xe3, 0x00, 0x14, 0x80, 0xe5, - 0x80, 0x10, 0x80, 0xe5, 0x54, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x14, 0x80, 0xe5, - 0x04, 0x10, 0x90, 0xe5, 0x00, 0x00, 0x51, 0xe3, 0x02, 0x00, 0x00, 0x1a, 0x70, 0x00, 0x1f, 0xe5, - 0x70, 0x10, 0x1f, 0xe5, 0x01, 0x00, 0x00, 0xea, 0x84, 0x00, 0x1f, 0xe5, 0x84, 0x10, 0x1f, 0xe5, - 0x7c, 0x30, 0x1f, 0xe5, 0x02, 0x50, 0x83, 0xe2, 0x01, 0x40, 0x43, 0xe0, 0x01, 0x20, 0x50, 0xe4, - 0x01, 0x20, 0x43, 0xe4, 0x04, 0x00, 0x53, 0xe1, 0xfb, 0xff, 0xff, 0x1a, 0x01, 0x00, 0x83, 0xe2, - 0x00, 0x20, 0xa0, 0xe3, 0x15, 0xff, 0x2f, 0xe1, 0x14, 0x00, 0x0f, 0xc8, 0x00, 0x00, 0x0d, 0xc8, - 0x00, 0x00, 0x0c, 0xc8 -}; -unsigned char dualboot_e200v2[176] = { - 0x06, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x24, 0x00, 0x1f, 0xe5, 0x24, 0x10, 0x1f, 0xe5, 0x01, 0x20, 0x40, 0xe0, 0x18, 0x30, 0x1f, 0xe5, - 0x01, 0x40, 0x50, 0xe4, 0x01, 0x40, 0x43, 0xe4, 0x00, 0x00, 0x52, 0xe1, 0xf |