mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-16 16:29:18 +01:00
Moved Banner stuff in own directory and added extraction
This commit is contained in:
parent
57f0ce0ed4
commit
6937ff5a51
2
Makefile
2
Makefile
@ -19,7 +19,7 @@ BUILD := build
|
|||||||
SOURCES := source source/libwiigui source/images source/fonts source/sounds \
|
SOURCES := source source/libwiigui source/images source/fonts source/sounds \
|
||||||
source/libwbfs source/unzip source/language source/mload source/patches \
|
source/libwbfs source/unzip source/language source/mload source/patches \
|
||||||
source/usbloader source/xml source/network source/settings source/prompts \
|
source/usbloader source/xml source/network source/settings source/prompts \
|
||||||
source/ramdisc source/wad
|
source/ramdisc source/wad source/banner
|
||||||
INCLUDES := source
|
INCLUDES := source
|
||||||
SVNDEV := -D'SVN_REV="$(shell svnversion -n ..)"'
|
SVNDEV := -D'SVN_REV="$(shell svnversion -n ..)"'
|
||||||
|
|
||||||
|
592
source/banner/MD5.c
Normal file
592
source/banner/MD5.c
Normal file
@ -0,0 +1,592 @@
|
|||||||
|
/* ========================================================================== **
|
||||||
|
*
|
||||||
|
* MD5.c
|
||||||
|
*
|
||||||
|
* Copyright:
|
||||||
|
* Copyright (C) 2003-2005 by Christopher R. Hertel
|
||||||
|
*
|
||||||
|
* Email: crh@ubiqx.mn.org
|
||||||
|
*
|
||||||
|
* $Id: MD5.c,v 0.6 2005/06/08 18:35:59 crh Exp $
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Modified by dimok
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------- **
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Implements the MD5 hash algorithm, as described in RFC 1321.
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------- **
|
||||||
|
*
|
||||||
|
* License:
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------- **
|
||||||
|
*
|
||||||
|
* Notes:
|
||||||
|
*
|
||||||
|
* None of this will make any sense unless you're studying RFC 1321 as you
|
||||||
|
* read the code.
|
||||||
|
*
|
||||||
|
* MD5 is described in RFC 1321.
|
||||||
|
* The MD*4* algorithm is described in RFC 1320 (that's 1321 - 1).
|
||||||
|
* MD5 is very similar to MD4, but not quite similar enough to justify
|
||||||
|
* putting the two into a single module. Besides, I wanted to add a few
|
||||||
|
* extra functions to this one to expand its usability.
|
||||||
|
*
|
||||||
|
* There are three primary motivations for this particular implementation.
|
||||||
|
* 1) Programmer's pride. I wanted to be able to say I'd done it, and I
|
||||||
|
* wanted to learn from the experience.
|
||||||
|
* 2) Portability. I wanted an implementation that I knew to be portable
|
||||||
|
* to a reasonable number of platforms. In particular, the algorithm is
|
||||||
|
* designed with little-endian platforms in mind, but I wanted an
|
||||||
|
* endian-agnostic implementation.
|
||||||
|
* 3) Compactness. While not an overriding goal, I thought it worth-while
|
||||||
|
* to see if I could reduce the overall size of the result. This is in
|
||||||
|
* keeping with my hopes that this library will be suitable for use in
|
||||||
|
* some embedded environments.
|
||||||
|
* Beyond that, cleanliness and clarity are always worth pursuing.
|
||||||
|
*
|
||||||
|
* As mentioned above, the code really only makes sense if you are familiar
|
||||||
|
* with the MD5 algorithm or are using RFC 1321 as a guide. This code is
|
||||||
|
* quirky, however, so you'll want to be reading carefully.
|
||||||
|
*
|
||||||
|
* Yeah...most of the comments are cut-and-paste from my MD4 implementation.
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------- **
|
||||||
|
*
|
||||||
|
* References:
|
||||||
|
* IETF RFC 1321: The MD5 Message-Digest Algorithm
|
||||||
|
* Ron Rivest. IETF, April, 1992
|
||||||
|
*
|
||||||
|
* ========================================================================== **
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <ogcsys.h>
|
||||||
|
|
||||||
|
#include "MD5.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- **
|
||||||
|
* Static Constants:
|
||||||
|
*
|
||||||
|
* K[][] - In round one, the values of k (which are used to index
|
||||||
|
* particular four-byte sequences in the input) are simply
|
||||||
|
* sequential. In later rounds, however, they are a bit more
|
||||||
|
* varied. Rather than calculate the values of k (which may
|
||||||
|
* or may not be possible--I haven't though about it) the
|
||||||
|
* values are stored in this array.
|
||||||
|
*
|
||||||
|
* S[][] - In each round there is a left rotate operation performed as
|
||||||
|
* part of the 16 permutations. The number of bits varies in
|
||||||
|
* a repeating patter. This array keeps track of the patterns
|
||||||
|
* used in each round.
|
||||||
|
*
|
||||||
|
* T[][] - There are four rounds of 16 permutations for a total of 64.
|
||||||
|
* In each of these 64 permutation operations, a different
|
||||||
|
* constant value is added to the mix. The constants are
|
||||||
|
* based on the sine function...read RFC 1321 for more detail.
|
||||||
|
* In any case, the correct constants are stored in the T[][]
|
||||||
|
* array. They're divided up into four groups of 16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const uint8_t K[3][16] =
|
||||||
|
{
|
||||||
|
/* Round 1: skipped (since it is simply sequential). */
|
||||||
|
{ 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12 }, /* R2 */
|
||||||
|
{ 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2 }, /* R3 */
|
||||||
|
{ 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 } /* R4 */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t S[4][4] =
|
||||||
|
{
|
||||||
|
{ 7, 12, 17, 22 }, /* Round 1 */
|
||||||
|
{ 5, 9, 14, 20 }, /* Round 2 */
|
||||||
|
{ 4, 11, 16, 23 }, /* Round 3 */
|
||||||
|
{ 6, 10, 15, 21 } /* Round 4 */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const uint32_t T[4][16] =
|
||||||
|
{
|
||||||
|
{ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, /* Round 1 */
|
||||||
|
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
|
||||||
|
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
|
||||||
|
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 },
|
||||||
|
|
||||||
|
{ 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, /* Round 2 */
|
||||||
|
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
|
||||||
|
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
|
||||||
|
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a },
|
||||||
|
|
||||||
|
{ 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, /* Round 3 */
|
||||||
|
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
|
||||||
|
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
|
||||||
|
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665 },
|
||||||
|
|
||||||
|
{ 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, /* Round 4 */
|
||||||
|
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
|
||||||
|
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
|
||||||
|
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- **
|
||||||
|
* Macros:
|
||||||
|
* md5F(), md5G(), md5H(), and md5I() are described in RFC 1321.
|
||||||
|
* All of these operations are bitwise, and so not impacted by endian-ness.
|
||||||
|
*
|
||||||
|
* GetLongByte()
|
||||||
|
* Extract one byte from a (32-bit) longword. A value of 0 for <idx>
|
||||||
|
* indicates the lowest order byte, while 3 indicates the highest order
|
||||||
|
* byte.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define md5F( X, Y, Z ) ( ((X) & (Y)) | ((~(X)) & (Z)) )
|
||||||
|
#define md5G( X, Y, Z ) ( ((X) & (Z)) | ((Y) & (~(Z))) )
|
||||||
|
#define md5H( X, Y, Z ) ( (X) ^ (Y) ^ (Z) )
|
||||||
|
#define md5I( X, Y, Z ) ( (Y) ^ ((X) | (~(Z))) )
|
||||||
|
|
||||||
|
#define GetLongByte( L, idx ) ((unsigned char)(( L >> (((idx) & 0x03) << 3) ) & 0xFF))
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- **
|
||||||
|
* Static Functions:
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void Permute( uint32_t ABCD[4], const unsigned char block[64] )
|
||||||
|
/* ------------------------------------------------------------------------ **
|
||||||
|
* Permute the ABCD "registers" using the 64-byte <block> as a driver.
|
||||||
|
*
|
||||||
|
* Input: ABCD - Pointer to an array of four unsigned longwords.
|
||||||
|
* block - An array of bytes, 64 bytes in size.
|
||||||
|
*
|
||||||
|
* Output: none.
|
||||||
|
*
|
||||||
|
* Notes: The MD5 algorithm operates on a set of four longwords stored
|
||||||
|
* (conceptually) in four "registers". It is easy to imagine a
|
||||||
|
* simple MD4/5 chip that would operate this way. In any case,
|
||||||
|
* the mangling of the contents of those registers is driven by
|
||||||
|
* the input message. The message is chopped and finally padded
|
||||||
|
* into 64-byte chunks and each chunk is used to manipulate the
|
||||||
|
* contents of the registers.
|
||||||
|
*
|
||||||
|
* The MD5 Algorithm calls for padding the input to ensure that
|
||||||
|
* it is a multiple of 64 bytes in length. The last 16 bytes
|
||||||
|
* of the padding space are used to store the message length
|
||||||
|
* (the length of the original message, before padding, expressed
|
||||||
|
* in terms of bits). If there is not enough room for 16 bytes
|
||||||
|
* worth of bitcount (eg., if the original message was 122 bytes
|
||||||
|
* long) then the block is padded to the end with zeros and
|
||||||
|
* passed to this function. Then *another* block is filled with
|
||||||
|
* zeros except for the last 16 bytes which contain the length.
|
||||||
|
*
|
||||||
|
* Oh... and the algorithm requires that there be at least one
|
||||||
|
* padding byte. The first padding byte has a value of 0x80,
|
||||||
|
* and any others are 0x00.
|
||||||
|
*
|
||||||
|
* ------------------------------------------------------------------------ **
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
int round;
|
||||||
|
int i, j;
|
||||||
|
uint8_t s;
|
||||||
|
uint32_t a, b, c, d;
|
||||||
|
uint32_t KeepABCD[4];
|
||||||
|
uint32_t X[16];
|
||||||
|
|
||||||
|
/* Store the current ABCD values for later re-use.
|
||||||
|
*/
|
||||||
|
for( i = 0; i < 4; i++ )
|
||||||
|
KeepABCD[i] = ABCD[i];
|
||||||
|
|
||||||
|
/* Convert the input block into an array of unsigned longs, taking care
|
||||||
|
* to read the block in Little Endian order (the algorithm assumes this).
|
||||||
|
* The uint32_t values are then handled in host order.
|
||||||
|
*/
|
||||||
|
for( i = 0, j = 0; i < 16; i++ )
|
||||||
|
{
|
||||||
|
X[i] = (uint32_t)block[j++];
|
||||||
|
X[i] |= ((uint32_t)block[j++] << 8);
|
||||||
|
X[i] |= ((uint32_t)block[j++] << 16);
|
||||||
|
X[i] |= ((uint32_t)block[j++] << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This loop performs the four rounds of permutations.
|
||||||
|
* The rounds are each very similar. The differences are in three areas:
|
||||||
|
* - The function (F, G, H, or I) used to perform bitwise permutations
|
||||||
|
* on the registers,
|
||||||
|
* - The order in which values from X[] are chosen.
|
||||||
|
* - Changes to the number of bits by which the registers are rotated.
|
||||||
|
* This implementation uses a switch statement to deal with some of the
|
||||||
|
* differences between rounds. Other differences are handled by storing
|
||||||
|
* values in arrays and using the round number to select the correct set
|
||||||
|
* of values.
|
||||||
|
*
|
||||||
|
* (My implementation appears to be a poor compromise between speed, size,
|
||||||
|
* and clarity. Ugh. [crh])
|
||||||
|
*/
|
||||||
|
for( round = 0; round < 4; round++ )
|
||||||
|
{
|
||||||
|
for( i = 0; i < 16; i++ )
|
||||||
|
{
|
||||||
|
j = (4 - (i % 4)) & 0x3; /* <j> handles the rotation of ABCD. */
|
||||||
|
s = S[round][i%4]; /* <s> is the bit shift for this iteration. */
|
||||||
|
|
||||||
|
b = ABCD[(j+1) & 0x3]; /* Copy the b,c,d values per ABCD rotation. */
|
||||||
|
c = ABCD[(j+2) & 0x3]; /* This isn't really necessary, it just looks */
|
||||||
|
d = ABCD[(j+3) & 0x3]; /* clean & will hopefully be optimized away. */
|
||||||
|
|
||||||
|
/* The actual perumation function.
|
||||||
|
* This is broken out to minimize the code within the switch().
|
||||||
|
*/
|
||||||
|
switch( round )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
/* round 1 */
|
||||||
|
a = md5F( b, c, d ) + X[i];
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
/* round 2 */
|
||||||
|
a = md5G( b, c, d ) + X[ K[0][i] ];
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
/* round 3 */
|
||||||
|
a = md5H( b, c, d ) + X[ K[1][i] ];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* round 4 */
|
||||||
|
a = md5I( b, c, d ) + X[ K[2][i] ];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
a = 0xFFFFFFFF & ( ABCD[j] + a + T[round][i] );
|
||||||
|
ABCD[j] = b + (0xFFFFFFFF & (( a << s ) | ( a >> (32 - s) )));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use the stored original A, B, C, D values to perform
|
||||||
|
* one last convolution.
|
||||||
|
*/
|
||||||
|
for( i = 0; i < 4; i++ )
|
||||||
|
ABCD[i] = 0xFFFFFFFF & ( ABCD[i] + KeepABCD[i] );
|
||||||
|
|
||||||
|
} /* Permute */
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- **
|
||||||
|
* Functions:
|
||||||
|
*/
|
||||||
|
|
||||||
|
auth_md5Ctx *auth_md5InitCtx( auth_md5Ctx *ctx )
|
||||||
|
/* ------------------------------------------------------------------------ **
|
||||||
|
* Initialize an MD5 context.
|
||||||
|
*
|
||||||
|
* Input: ctx - A pointer to the MD5 context structure to be initialized.
|
||||||
|
* Contexts are typically created thusly:
|
||||||
|
* ctx = (auth_md5Ctx *)malloc( sizeof(auth_md5Ctx) );
|
||||||
|
*
|
||||||
|
* Output: A pointer to the initialized context (same as <ctx>).
|
||||||
|
*
|
||||||
|
* Notes: The purpose of the context is to make it possible to generate
|
||||||
|
* an MD5 Message Digest in stages, rather than having to pass a
|
||||||
|
* single large block to a single MD5 function. The context
|
||||||
|
* structure keeps track of various bits of state information.
|
||||||
|
*
|
||||||
|
* Once the context is initialized, the blocks of message data
|
||||||
|
* are passed to the <auth_md5SumCtx()> function. Once the
|
||||||
|
* final bit of data has been handed to <auth_md5SumCtx()> the
|
||||||
|
* context can be closed out by calling <auth_md5CloseCtx()>,
|
||||||
|
* which also calculates the final MD5 result.
|
||||||
|
*
|
||||||
|
* Don't forget to free an allocated context structure when
|
||||||
|
* you've finished using it.
|
||||||
|
*
|
||||||
|
* See Also: <auth_md5SumCtx()>, <auth_md5CloseCtx()>
|
||||||
|
*
|
||||||
|
* ------------------------------------------------------------------------ **
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
ctx->len = 0;
|
||||||
|
ctx->b_used = 0;
|
||||||
|
|
||||||
|
ctx->ABCD[0] = 0x67452301; /* The array ABCD[] contains the four 4-byte */
|
||||||
|
ctx->ABCD[1] = 0xefcdab89; /* "registers" that are manipulated to */
|
||||||
|
ctx->ABCD[2] = 0x98badcfe; /* produce the MD5 digest. The input acts */
|
||||||
|
ctx->ABCD[3] = 0x10325476; /* upon the registers, not the other way */
|
||||||
|
/* 'round. The initial values are those */
|
||||||
|
/* given in RFC 1321 (pg. 4). Note, however, that RFC 1321 */
|
||||||
|
/* provides these values as bytes, not as longwords, and the */
|
||||||
|
/* bytes are arranged in little-endian order as if they were */
|
||||||
|
/* the bytes of (little endian) 32-bit ints. That's */
|
||||||
|
/* confusing as all getout (to me, anyway). The values given */
|
||||||
|
/* here are provided as 32-bit values in C language format, */
|
||||||
|
/* so they are endian-agnostic. */
|
||||||
|
return( ctx );
|
||||||
|
} /* auth_md5InitCtx */
|
||||||
|
|
||||||
|
|
||||||
|
auth_md5Ctx *auth_md5SumCtx( auth_md5Ctx *ctx,
|
||||||
|
const unsigned char *src,
|
||||||
|
const int len )
|
||||||
|
/* ------------------------------------------------------------------------ **
|
||||||
|
* Build an MD5 Message Digest within the given context.
|
||||||
|
*
|
||||||
|
* Input: ctx - Pointer to the context in which the MD5 sum is being
|
||||||
|
* built.
|
||||||
|
* src - A chunk of source data. This will be used to drive
|
||||||
|
* the MD5 algorithm.
|
||||||
|
* len - The number of bytes in <src>.
|
||||||
|
*
|
||||||
|
* Output: A pointer to the updated context (same as <ctx>).
|
||||||
|
*
|
||||||
|
* See Also: <auth_md5InitCtx()>, <auth_md5CloseCtx()>, <auth_md5Sum()>
|
||||||
|
*
|
||||||
|
* ------------------------------------------------------------------------ **
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Add the new block's length to the total length.
|
||||||
|
*/
|
||||||
|
ctx->len += (uint32_t)len;
|
||||||
|
|
||||||
|
/* Copy the new block's data into the context block.
|
||||||
|
* Call the Permute() function whenever the context block is full.
|
||||||
|
*/
|
||||||
|
for( i = 0; i < len; i++ )
|
||||||
|
{
|
||||||
|
ctx->block[ ctx->b_used ] = src[i];
|
||||||
|
(ctx->b_used)++;
|
||||||
|
if( 64 == ctx->b_used )
|
||||||
|
{
|
||||||
|
Permute( ctx->ABCD, ctx->block );
|
||||||
|
ctx->b_used = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the updated context.
|
||||||
|
*/
|
||||||
|
return( ctx );
|
||||||
|
} /* auth_md5SumCtx */
|
||||||
|
|
||||||
|
|
||||||
|
auth_md5Ctx *auth_md5CloseCtx( auth_md5Ctx *ctx, unsigned char *dst )
|
||||||
|
/* ------------------------------------------------------------------------ **
|
||||||
|
* Close an MD5 Message Digest context and generate the final MD5 sum.
|
||||||
|
*
|
||||||
|
* Input: ctx - Pointer to the context in which the MD5 sum is being
|
||||||
|
* built.
|
||||||
|
* dst - A pointer to at least 16 bytes of memory, which will
|
||||||
|
* receive the finished MD5 sum.
|
||||||
|
*
|
||||||
|
* Output: A pointer to the closed context (same as <ctx>).
|
||||||
|
* You might use this to free a malloc'd context structure. :)
|
||||||
|
*
|
||||||
|
* Notes: The context (<ctx>) is returned in an undefined state.
|
||||||
|
* It must be re-initialized before re-use.
|
||||||
|
*
|
||||||
|
* See Also: <auth_md5InitCtx()>, <auth_md5SumCtx()>
|
||||||
|
*
|
||||||
|
* ------------------------------------------------------------------------ **
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
uint32_t l;
|
||||||
|
|
||||||
|
/* Add the required 0x80 padding initiator byte.
|
||||||
|
* The auth_md5SumCtx() function always permutes and resets the context
|
||||||
|
* block when it gets full, so we know that there must be at least one
|
||||||
|
* free byte in the context block.
|
||||||
|
*/
|
||||||
|
ctx->block[ctx->b_used] = 0x80;
|
||||||
|
(ctx->b_used)++;
|
||||||
|
|
||||||
|
/* Zero out any remaining free bytes in the context block.
|
||||||
|
*/
|
||||||
|
for( i = ctx->b_used; i < 64; i++ )
|
||||||
|
ctx->block[i] = 0;
|
||||||
|
|
||||||
|
/* We need 8 bytes to store the length field.
|
||||||
|
* If we don't have 8, call Permute() and reset the context block.
|
||||||
|
*/
|
||||||
|
if( 56 < ctx->b_used )
|
||||||
|
{
|
||||||
|
Permute( ctx->ABCD, ctx->block );
|
||||||
|
for( i = 0; i < 64; i++ )
|
||||||
|
ctx->block[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the total length and perform the final perumation.
|
||||||
|
* Note: The 60'th byte is read from the *original* <ctx->len> value
|
||||||
|
* and shifted to the correct position. This neatly avoids
|
||||||
|
* any MAXINT numeric overflow issues.
|
||||||
|
*/
|
||||||
|
l = ctx->len << 3;
|
||||||
|
for( i = 0; i < 4; i++ )
|
||||||
|
ctx->block[56+i] |= GetLongByte( l, i );
|
||||||
|
ctx->block[60] = ((GetLongByte( ctx->len, 3 ) & 0xE0) >> 5); /* See Above! */
|
||||||
|
Permute( ctx->ABCD, ctx->block );
|
||||||
|
|
||||||
|
/* Now copy the result into the output buffer and we're done.
|
||||||
|
*/
|
||||||
|
for( i = 0; i < 4; i++ )
|
||||||
|
{
|
||||||
|
dst[ 0+i] = GetLongByte( ctx->ABCD[0], i );
|
||||||
|
dst[ 4+i] = GetLongByte( ctx->ABCD[1], i );
|
||||||
|
dst[ 8+i] = GetLongByte( ctx->ABCD[2], i );
|
||||||
|
dst[12+i] = GetLongByte( ctx->ABCD[3], i );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the context.
|
||||||
|
* This is done for compatibility with the other auth_md5*Ctx() functions.
|
||||||
|
*/
|
||||||
|
return( ctx );
|
||||||
|
} /* auth_md5CloseCtx */
|
||||||
|
|
||||||
|
|
||||||
|
unsigned char * MD5(unsigned char *dst, const unsigned char *src, const int len )
|
||||||
|
/* ------------------------------------------------------------------------ **
|
||||||
|
* Compute an MD5 message digest.
|
||||||
|
*
|
||||||
|
* Input: dst - Destination buffer into which the result will be written.
|
||||||
|
* Must be 16 bytes, minimum.
|
||||||
|
* src - Source data block to be MD5'd.
|
||||||
|
* len - The length, in bytes, of the source block.
|
||||||
|
* (Note that the length is given in bytes, not bits.)
|
||||||
|
*
|
||||||
|
* Output: A pointer to <dst>, which will contain the calculated 16-byte
|
||||||
|
* MD5 message digest.
|
||||||
|
*
|
||||||
|
* Notes: This function is a shortcut. It takes a single input block.
|
||||||
|
* For more drawn-out operations, see <auth_md5InitCtx()>.
|
||||||
|
*
|
||||||
|
* This function is interface-compatible with the
|
||||||
|
* <auth_md4Sum()> function in the MD4 module.
|
||||||
|
*
|
||||||
|
* The MD5 algorithm is designed to work on data with an
|
||||||
|
* arbitrary *bit* length. Most implementations, this one
|
||||||
|
* included, handle the input data in byte-sized chunks.
|
||||||
|
*
|
||||||
|
* The MD5 algorithm does much of its work using four-byte
|
||||||
|
* words, and so can be tuned for speed based on the endian-ness
|
||||||
|
* of the host. This implementation is intended to be
|
||||||
|
* endian-neutral, which may make it a teeny bit slower than
|
||||||
|
* others. ...maybe.
|
||||||
|
*
|
||||||
|
* See Also: <auth_md5InitCtx()>
|
||||||
|
*
|
||||||
|
* ------------------------------------------------------------------------ **
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
auth_md5Ctx ctx[1];
|
||||||
|
|
||||||
|
(void)auth_md5InitCtx( ctx ); /* Open a context. */
|
||||||
|
(void)auth_md5SumCtx( ctx, src, len ); /* Pass only one block. */
|
||||||
|
(void)auth_md5CloseCtx( ctx, dst ); /* Close the context. */
|
||||||
|
|
||||||
|
return( dst ); /* Makes life easy. */
|
||||||
|
} /* auth_md5Sum */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned char * MD5fromFile(unsigned char *dst, const char *src)
|
||||||
|
/* ------------------------------------------------------------------------ **
|
||||||
|
* Compute an MD5 message digest.
|
||||||
|
*
|
||||||
|
* Input: dst - Destination buffer into which the result will be written.
|
||||||
|
* Must be 16 bytes, minimum.
|
||||||
|
* src - filepath of the file to be checked
|
||||||
|
*
|
||||||
|
* Output: A pointer to <dst>, which will contain the calculated 16-byte
|
||||||
|
* MD5 message digest.
|
||||||
|
*
|
||||||
|
* Notes: This function is a shortcut. It takes a single input block.
|
||||||
|
* For more drawn-out operations, see <auth_md5InitCtx()>.
|
||||||
|
*
|
||||||
|
* This function is interface-compatible with the
|
||||||
|
* <auth_md4Sum()> function in the MD4 module.
|
||||||
|
*
|
||||||
|
* The MD5 algorithm is designed to work on data with an
|
||||||
|
* arbitrary *bit* length. Most implementations, this one
|
||||||
|
* included, handle the input data in byte-sized chunks.
|
||||||
|
*
|
||||||
|
* The MD5 algorithm does much of its work using four-byte
|
||||||
|
* words, and so can be tuned for speed based on the endian-ness
|
||||||
|
* of the host. This implementation is intended to be
|
||||||
|
* endian-neutral, which may make it a teeny bit slower than
|
||||||
|
* others. ...maybe.
|
||||||
|
*
|
||||||
|
* See Also: <auth_md5InitCtx()>
|
||||||
|
*
|
||||||
|
* ------------------------------------------------------------------------ **
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
auth_md5Ctx ctx[1];
|
||||||
|
|
||||||
|
FILE * file;
|
||||||
|
u32 blksize = 0;
|
||||||
|
u32 read = 0;
|
||||||
|
|
||||||
|
file = fopen(src, "rb");
|
||||||
|
|
||||||
|
if (file==NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)auth_md5InitCtx( ctx ); /* Open a context. */
|
||||||
|
|
||||||
|
fseek (file , 0 , SEEK_END);
|
||||||
|
u64 filesize = ftell(file);
|
||||||
|
rewind (file);
|
||||||
|
|
||||||
|
if(filesize < 1048576) //1MB cache for files bigger than 1 MB
|
||||||
|
blksize = filesize;
|
||||||
|
else
|
||||||
|
blksize = 1048576;
|
||||||
|
|
||||||
|
unsigned char * buffer = malloc(blksize);
|
||||||
|
|
||||||
|
if(buffer == NULL){
|
||||||
|
//no memory
|
||||||
|
fclose(file);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
read = fread(buffer, 1, blksize, file);
|
||||||
|
(void)auth_md5SumCtx( ctx, buffer, read ); /* Pass only one block. */
|
||||||
|
|
||||||
|
} while(read > 0);
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
free(buffer);
|
||||||
|
|
||||||
|
(void)auth_md5CloseCtx( ctx, dst ); /* Close the context. */
|
||||||
|
|
||||||
|
return( dst ); /* Makes life easy. */
|
||||||
|
} /* auth_md5Sum */
|
||||||
|
|
||||||
|
|
||||||
|
/* ========================================================================== */
|
242
source/banner/MD5.h
Normal file
242
source/banner/MD5.h
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
#ifndef MD5_H
|
||||||
|
#define MD5_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
/* ========================================================================== **
|
||||||
|
*
|
||||||
|
* MD5.h
|
||||||
|
*
|
||||||
|
* Copyright:
|
||||||
|
* Copyright (C) 2003-2005 by Christopher R. Hertel
|
||||||
|
*
|
||||||
|
* Email: crh@ubiqx.mn.org
|
||||||
|
*
|
||||||
|
* $Id: MD5.h,v 0.6 2005/06/08 18:35:59 crh Exp $
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------- **
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Implements the MD5 hash algorithm, as described in RFC 1321.
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------- **
|
||||||
|
*
|
||||||
|
* License:
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------- **
|
||||||
|
*
|
||||||
|
* Notes:
|
||||||
|
*
|
||||||
|
* None of this will make any sense unless you're studying RFC 1321 as you
|
||||||
|
* read the code.
|
||||||
|
*
|
||||||
|
* MD5 is described in RFC 1321.
|
||||||
|
* The MD*4* algorithm is described in RFC 1320 (that's 1321 - 1).
|
||||||
|
* MD5 is very similar to MD4, but not quite similar enough to justify
|
||||||
|
* putting the two into a single module. Besides, I wanted to add a few
|
||||||
|
* extra functions to this one to expand its usability.
|
||||||
|
*
|
||||||
|
* There are three primary motivations for this particular implementation.
|
||||||
|
* 1) Programmer's pride. I wanted to be able to say I'd done it, and I
|
||||||
|
* wanted to learn from the experience.
|
||||||
|
* 2) Portability. I wanted an implementation that I knew to be portable
|
||||||
|
* to a reasonable number of platforms. In particular, the algorithm is
|
||||||
|
* designed with little-endian platforms in mind, but I wanted an
|
||||||
|
* endian-agnostic implementation.
|
||||||
|
* 3) Compactness. While not an overriding goal, I thought it worth-while
|
||||||
|
* to see if I could reduce the overall size of the result. This is in
|
||||||
|
* keeping with my hopes that this library will be suitable for use in
|
||||||
|
* some embedded environments.
|
||||||
|
* Beyond that, cleanliness and clarity are always worth pursuing.
|
||||||
|
*
|
||||||
|
* As mentioned above, the code really only makes sense if you are familiar
|
||||||
|
* with the MD5 algorithm or are using RFC 1321 as a guide. This code is
|
||||||
|
* quirky, however, so you'll want to be reading carefully.
|
||||||
|
*
|
||||||
|
* Yeah...most of the comments are cut-and-paste from my MD4 implementation.
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------- **
|
||||||
|
*
|
||||||
|
* References:
|
||||||
|
* IETF RFC 1321: The MD5 Message-Digest Algorithm
|
||||||
|
* Ron Rivest. IETF, April, 1992
|
||||||
|
*
|
||||||
|
* ========================================================================== **
|
||||||
|
*/
|
||||||
|
/* -------------------------------------------------------------------------- **
|
||||||
|
* Typedefs:
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t len;
|
||||||
|
uint32_t ABCD[4];
|
||||||
|
int b_used;
|
||||||
|
unsigned char block[64];
|
||||||
|
} auth_md5Ctx;
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- **
|
||||||
|
* Functions:
|
||||||
|
*/
|
||||||
|
|
||||||
|
auth_md5Ctx *auth_md5InitCtx( auth_md5Ctx *ctx );
|
||||||
|
/* ------------------------------------------------------------------------ **
|
||||||
|
* Initialize an MD5 context.
|
||||||
|
*
|
||||||
|
* Input: ctx - A pointer to the MD5 context structure to be initialized.
|
||||||
|
* Contexts are typically created thusly:
|
||||||
|
* ctx = (auth_md5Ctx *)malloc( sizeof(auth_md5Ctx) );
|
||||||
|
*
|
||||||
|
* Output: A pointer to the initialized context (same as <ctx>).
|
||||||
|
*
|
||||||
|
* Notes: The purpose of the context is to make it possible to generate
|
||||||
|
* an MD5 Message Digest in stages, rather than having to pass a
|
||||||
|
* single large block to a single MD5 function. The context
|
||||||
|
* structure keeps track of various bits of state information.
|
||||||
|
*
|
||||||
|
* Once the context is initialized, the blocks of message data
|
||||||
|
* are passed to the <auth_md5SumCtx()> function. Once the
|
||||||
|
* final bit of data has been handed to <auth_md5SumCtx()> the
|
||||||
|
* context can be closed out by calling <auth_md5CloseCtx()>,
|
||||||
|
* which also calculates the final MD5 result.
|
||||||
|
*
|
||||||
|
* Don't forget to free an allocated context structure when
|
||||||
|
* you've finished using it.
|
||||||
|
*
|
||||||
|
* See Also: <auth_md5SumCtx()>, <auth_md5CloseCtx()>
|
||||||
|
*
|
||||||
|
* ------------------------------------------------------------------------ **
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
auth_md5Ctx *auth_md5SumCtx( auth_md5Ctx *ctx,
|
||||||
|
const unsigned char *src,
|
||||||
|
const int len );
|
||||||
|
/* ------------------------------------------------------------------------ **
|
||||||
|
* Build an MD5 Message Digest within the given context.
|
||||||
|
*
|
||||||
|
* Input: ctx - Pointer to the context in which the MD5 sum is being
|
||||||
|
* built.
|
||||||
|
* src - A chunk of source data. This will be used to drive
|
||||||
|
* the MD5 algorithm.
|
||||||
|
* len - The number of bytes in <src>.
|
||||||
|
*
|
||||||
|
* Output: A pointer to the updated context (same as <ctx>).
|
||||||
|
*
|
||||||
|
* See Also: <auth_md5InitCtx()>, <auth_md5CloseCtx()>, <auth_md5Sum()>
|
||||||
|
*
|
||||||
|
* ------------------------------------------------------------------------ **
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
auth_md5Ctx *auth_md5CloseCtx( auth_md5Ctx *ctx, unsigned char *dst );
|
||||||
|
/* ------------------------------------------------------------------------ **
|
||||||
|
* Close an MD5 Message Digest context and generate the final MD5 sum.
|
||||||
|
*
|
||||||
|
* Input: ctx - Pointer to the context in which the MD5 sum is being
|
||||||
|
* built.
|
||||||
|
* dst - A pointer to at least 16 bytes of memory, which will
|
||||||
|
* receive the finished MD5 sum.
|
||||||
|
*
|
||||||
|
* Output: A pointer to the closed context (same as <ctx>).
|
||||||
|
* You might use this to free a malloc'd context structure. :)
|
||||||
|
*
|
||||||
|
* Notes: The context (<ctx>) is returned in an undefined state.
|
||||||
|
* It must be re-initialized before re-use.
|
||||||
|
*
|
||||||
|
* See Also: <auth_md5InitCtx()>, <auth_md5SumCtx()>
|
||||||
|
*
|
||||||
|
* ------------------------------------------------------------------------ **
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
unsigned char * MD5(unsigned char * hash, const unsigned char *src, const int len );
|
||||||
|
/* ------------------------------------------------------------------------ **
|
||||||
|
* Compute an MD5 message digest.
|
||||||
|
*
|
||||||
|
* Input: dst - Destination buffer into which the result will be written.
|
||||||
|
* Must be 16 bytes, minimum.
|
||||||
|
* src - Source data block to be MD5'd.
|
||||||
|
* len - The length, in bytes, of the source block.
|
||||||
|
* (Note that the length is given in bytes, not bits.)
|
||||||
|
*
|
||||||
|
* Output: A pointer to <dst>, which will contain the calculated 16-byte
|
||||||
|
* MD5 message digest.
|
||||||
|
*
|
||||||
|
* Notes: This function is a shortcut. It takes a single input block.
|
||||||
|
* For more drawn-out operations, see <auth_md5InitCtx()>.
|
||||||
|
*
|
||||||
|
* This function is interface-compatible with the
|
||||||
|
* <auth_md4Sum()> function in the MD4 module.
|
||||||
|
*
|
||||||
|
* The MD5 algorithm is designed to work on data with an
|
||||||
|
* arbitrary *bit* length. Most implementations, this one
|
||||||
|
* included, handle the input data in byte-sized chunks.
|
||||||
|
*
|
||||||
|
* The MD5 algorithm does much of its work using four-byte
|
||||||
|
* words, and so can be tuned for speed based on the endian-ness
|
||||||
|
* of the host. This implementation is intended to be
|
||||||
|
* endian-neutral, which may make it a teeny bit slower than
|
||||||
|
* others. ...maybe.
|
||||||
|
*
|
||||||
|
* See Also: <auth_md5InitCtx()>
|
||||||
|
*
|
||||||
|
* ------------------------------------------------------------------------ **
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned char * MD5fromFile(unsigned char *dst, const char *src);
|
||||||
|
/* ------------------------------------------------------------------------ **
|
||||||
|
* Compute an MD5 message digest.
|
||||||
|
*
|
||||||
|
* Input: dst - Destination buffer into which the result will be written.
|
||||||
|
* Must be 16 bytes, minimum.
|
||||||
|
* src - filepath to the file to be MD5'd.
|
||||||
|
*
|
||||||
|
* Output: A pointer to <dst>, which will contain the calculated 16-byte
|
||||||
|
* MD5 message digest.
|
||||||
|
*
|
||||||
|
* Notes: This function is a shortcut. It takes a single input block.
|
||||||
|
* For more drawn-out operations, see <auth_md5InitCtx()>.
|
||||||
|
*
|
||||||
|
* This function is interface-compatible with the
|
||||||
|
* <auth_md4Sum()> function in the MD4 module.
|
||||||
|
*
|
||||||
|
* The MD5 algorithm is designed to work on data with an
|
||||||
|
* arbitrary *bit* length. Most implementations, this one
|
||||||
|
* included, handle the input data in byte-sized chunks.
|
||||||
|
*
|
||||||
|
* The MD5 algorithm does much of its work using four-byte
|
||||||
|
* words, and so can be tuned for speed based on the endian-ness
|
||||||
|
* of the host. This implementation is intended to be
|
||||||
|
* endian-neutral, which may make it a teeny bit slower than
|
||||||
|
* others. ...maybe.
|
||||||
|
*
|
||||||
|
* See Also: <auth_md5InitCtx()>
|
||||||
|
*
|
||||||
|
* ------------------------------------------------------------------------ **
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* ========================================================================== */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* AUTH_MD5_H */
|
140
source/banner/banner.c
Normal file
140
source/banner/banner.c
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* USB Loader GX Team
|
||||||
|
* banner.c
|
||||||
|
*
|
||||||
|
* Dump opening.bnr thanks to Wiipower
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <gctypes.h>
|
||||||
|
#include <gccore.h>
|
||||||
|
#include <ogcsys.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <fat.h>
|
||||||
|
|
||||||
|
#include "fatmounter.h"
|
||||||
|
#include "usbloader/wdvd.h"
|
||||||
|
#include "usbloader/disc.h"
|
||||||
|
#include "banner.h"
|
||||||
|
#include "patches/fst.h"
|
||||||
|
|
||||||
|
|
||||||
|
char *fstfilename(FST_ENTRY *fst, u32 index)
|
||||||
|
{
|
||||||
|
u32 count = fst[0].filelen;
|
||||||
|
u32 stringoffset;
|
||||||
|
if (index < count)
|
||||||
|
{
|
||||||
|
stringoffset = *(u32 *)&(fst[index]) % (256*256*256);
|
||||||
|
return (char *)((u32)fst + count*12 + stringoffset);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 dump_banner(const char * discid,const char * dest)
|
||||||
|
{
|
||||||
|
// Mount the disc
|
||||||
|
//Disc_SetWBFS(1, (u8*)discid);
|
||||||
|
Disc_SetUSB((u8*)discid);
|
||||||
|
|
||||||
|
Disc_Open();
|
||||||
|
|
||||||
|
u64 offset;
|
||||||
|
s32 ret;
|
||||||
|
|
||||||
|
ret = __Disc_FindPartition(&offset);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = WDVD_OpenPartition(offset);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
//printf("ERROR: OpenPartition(0x%llx) %d\n", offset, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read where to find the fst.bin
|
||||||
|
u32 *buffer = memalign(32, 0x20);
|
||||||
|
|
||||||
|
if (buffer == NULL)
|
||||||
|
{
|
||||||
|
//Out of memory
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = WDVD_Read(buffer, 0x20, 0x420);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
// Read fst.bin
|
||||||
|
void *fstbuffer = memalign(32, buffer[2]*4);
|
||||||
|
FST_ENTRY *fst = (FST_ENTRY *)fstbuffer;
|
||||||
|
|
||||||
|
if (fst == NULL)
|
||||||
|
{
|
||||||
|
//Out of memory
|
||||||
|
free(buffer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = WDVD_Read(fstbuffer, buffer[2]*4, buffer[1]*4);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
|
||||||
|
// Search the fst.bin
|
||||||
|
u32 count = fst[0].filelen;
|
||||||
|
int i;
|
||||||
|
u32 index = 0;
|
||||||
|
|
||||||
|
for (i=1;i<count;i++)
|
||||||
|
{
|
||||||
|
if (strstr(fstfilename(fst, i), "opening.bnr") != NULL)
|
||||||
|
{
|
||||||
|
index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index == 0)
|
||||||
|
{
|
||||||
|
//opening.bnr not found
|
||||||
|
free(fstbuffer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the .bnr
|
||||||
|
u8 *banner = memalign(32, fst[index].filelen);
|
||||||
|
|
||||||
|
if (banner == NULL)
|
||||||
|
{
|
||||||
|
//Out of memory
|
||||||
|
free(fstbuffer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = WDVD_Read((void *)banner, fst[index].filelen, fst[index].fileoffset * 4);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
//fatInitDefault();
|
||||||
|
//SDCard_Init();
|
||||||
|
|
||||||
|
FILE *fp = NULL;
|
||||||
|
fp = fopen(dest, "wb");
|
||||||
|
|
||||||
|
fwrite(banner, 1, fst[index].filelen, fp);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
free(fstbuffer);
|
||||||
|
free(banner);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
29
source/banner/banner.h
Normal file
29
source/banner/banner.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* USB Loader GX Team
|
||||||
|
* banner.h
|
||||||
|
*
|
||||||
|
* Dump opening.bnr thanks to Wiipower
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef BANNER_H
|
||||||
|
#define BANNER_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u8 filetype;
|
||||||
|
char name_offset[3];
|
||||||
|
u32 fileoffset;
|
||||||
|
u32 filelen;
|
||||||
|
} __attribute__((packed)) FST_ENTRY;
|
||||||
|
|
||||||
|
s32 dump_banner(const char * discid,const char * dest);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -1,3 +1,9 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* USB Loader GX Team
|
||||||
|
* gui_banner.cpp
|
||||||
|
*
|
||||||
|
* Shows TPL Banner images
|
||||||
|
***************************************************************************/
|
||||||
#include "gui_banner.h"
|
#include "gui_banner.h"
|
||||||
|
|
||||||
GuiBanner::GuiBanner()
|
GuiBanner::GuiBanner()
|
29
source/banner/gui_banner.h
Normal file
29
source/banner/gui_banner.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* USB Loader GX Team
|
||||||
|
* gui_banner.h
|
||||||
|
*
|
||||||
|
* Shows TPL Banner images
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _GUIBANNER_H_
|
||||||
|
#define _GUIBANNER_H_
|
||||||
|
|
||||||
|
#include "libwiigui/gui.h"
|
||||||
|
|
||||||
|
class GuiBanner : public GuiImage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GuiBanner();
|
||||||
|
GuiBanner(const char *tplfilepath);
|
||||||
|
GuiBanner(void *mem,u32 len,u16 w, u16 h);
|
||||||
|
~GuiBanner();
|
||||||
|
|
||||||
|
void Draw();
|
||||||
|
private:
|
||||||
|
f32 deg_beta;
|
||||||
|
const char *filepath;
|
||||||
|
const void *memory;
|
||||||
|
bool filecheck;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _GUIBANNER_H_ */
|
459
source/banner/openingbnr.c
Normal file
459
source/banner/openingbnr.c
Normal file
@ -0,0 +1,459 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* USB Loader GX Team
|
||||||
|
* openingbnr
|
||||||
|
*
|
||||||
|
* Extract opening.bnr/banner.bin/sound.bin/icon.bin
|
||||||
|
*
|
||||||
|
* Copyright 2008 Magicus <magicus@gmail.com>
|
||||||
|
* Licensed under the terms of the GNU GPL, version 2
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||||
|
* Version 1.0 Initial release
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <ogcsys.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fat.h>
|
||||||
|
|
||||||
|
#include "MD5.h"
|
||||||
|
#include "banner.h"
|
||||||
|
|
||||||
|
u16 be16(const u8 *p)
|
||||||
|
{
|
||||||
|
return (p[0] << 8) | p[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 be32(const u8 *p)
|
||||||
|
{
|
||||||
|
return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 be64(const u8 *p)
|
||||||
|
{
|
||||||
|
return ((u64)be32(p) << 32) | be32(p + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 be34(const u8 *p)
|
||||||
|
{
|
||||||
|
return 4 * (u64)be32(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wbe16(u8 *p, u16 x)
|
||||||
|
{
|
||||||
|
p[0] = x >> 8;
|
||||||
|
p[1] = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wbe32(u8 *p, u32 x)
|
||||||
|
{
|
||||||
|
wbe16(p, x >> 16);
|
||||||
|
wbe16(p + 2, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wbe64(u8 *p, u64 x)
|
||||||
|
{
|
||||||
|
wbe32(p, x >> 32);
|
||||||
|
wbe32(p + 4, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void md5(u8 *data, u32 len, u8 *hash)
|
||||||
|
{
|
||||||
|
MD5(hash, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static FILE *fp;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u8 zeroes[0x40];
|
||||||
|
u32 imet; // "IMET"
|
||||||
|
u8 zero_six_zero_three[8]; // fixed, unknown purpose
|
||||||
|
u32 sizes[3];
|
||||||
|
u32 flag1;
|
||||||
|
u16 name_jp[0x2a]; // might be empty
|
||||||
|
u16 name_en[0x2a];
|
||||||
|
u16 name_de[0x2a];
|
||||||
|
u16 name_fr[0x2a];
|
||||||
|
u16 name_es[0x2a];
|
||||||
|
u16 name_it[0x2a];
|
||||||
|
u16 name_nl[0x2a];
|
||||||
|
u8 zeroes_2[0x348];
|
||||||
|
u8 crypto[0x10];
|
||||||
|
} imet_data_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 imd5_tag; // 0x494D4435 "IMD5";
|
||||||
|
u32 size; // size of the rest of part B, starting from next field.
|
||||||
|
u8 zeroes[8];
|
||||||
|
u8 md5[16];
|
||||||
|
u32 payload_tag; // 0x4C5A3737 "LZ77" if this is lz77
|
||||||
|
u32 payload_data;
|
||||||
|
} imd5_header_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u16 type;
|
||||||
|
u16 name_offset;
|
||||||
|
u32 data_offset; // == absolut offset från U.8- headerns början
|
||||||
|
u32 size; // last included file num for directories
|
||||||
|
} U8_node;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u32 tag; // 0x55AA382D "U.8-"
|
||||||
|
u32 rootnode_offset; // offset to root_node, always 0x20.
|
||||||
|
u32 header_size; // size of header from root_node to end of string table.
|
||||||
|
u32 data_offset; // offset to data -- this is rootnode_offset + header_size, aligned to 0x40.
|
||||||
|
u8 zeroes[16];
|
||||||
|
} U8_archive_header;
|
||||||
|
|
||||||
|
static void write_file(void* data, size_t size, char* name)
|
||||||
|
{
|
||||||
|
FILE *out;
|
||||||
|
out = fopen(name, "wb");
|
||||||
|
fwrite(data, 1, size, out);
|
||||||
|
fclose(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8* decompress_lz77(u8 *data, size_t data_size, size_t* decompressed_size)
|
||||||
|
{
|
||||||
|
u8 *data_end;
|
||||||
|
u8 *decompressed_data;
|
||||||
|
size_t unpacked_size;
|
||||||
|
u8 *in_ptr;
|
||||||
|
u8 *out_ptr;
|
||||||
|
u8 *out_end;
|
||||||
|
|
||||||
|
in_ptr = data;
|
||||||
|
data_end = data + data_size;
|
||||||
|
|
||||||
|
// Assume this for now and grow when needed
|
||||||
|
unpacked_size = data_size;
|
||||||
|
|
||||||
|
decompressed_data = malloc(unpacked_size);
|
||||||
|
out_end = decompressed_data + unpacked_size;
|
||||||
|
|
||||||
|
out_ptr = decompressed_data;
|
||||||
|
|
||||||
|
while (in_ptr < data_end) {
|
||||||
|
int bit;
|
||||||
|
u8 bitmask = *in_ptr;
|
||||||
|
|
||||||
|
in_ptr++;
|
||||||
|
for (bit = 0x80; bit != 0; bit >>= 1) {
|
||||||
|
if (bitmask & bit) {
|
||||||
|
// Next section is compressed
|
||||||
|
u8 rep_length;
|
||||||
|
u16 rep_offset;
|
||||||
|
|
||||||
|
rep_length = (*in_ptr >> 4) + 3;
|
||||||
|
rep_offset = *in_ptr & 0x0f;
|
||||||
|
in_ptr++;
|
||||||
|
rep_offset = *in_ptr | (rep_offset << 8);
|
||||||
|
in_ptr++;
|
||||||
|
if (out_ptr-decompressed_data < rep_offset) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( ; rep_length > 0; rep_length--) {
|
||||||
|
*out_ptr = out_ptr[-rep_offset-1];
|
||||||
|
out_ptr++;
|
||||||
|
if (out_ptr >= out_end) {
|
||||||
|
// Need to grow buffer
|
||||||
|
decompressed_data = realloc(decompressed_data, unpacked_size*2);
|
||||||
|
out_ptr = decompressed_data + unpacked_size;
|
||||||
|
unpacked_size *= 2;
|
||||||
|
out_end = decompressed_data + unpacked_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Just copy byte
|
||||||
|
*out_ptr = *in_ptr;
|
||||||
|
out_ptr++;
|
||||||
|
if (out_ptr >= out_end) {
|
||||||
|
// Need to grow buffer
|
||||||
|
decompressed_data = realloc(decompressed_data, unpacked_size*2);
|
||||||
|
out_ptr = decompressed_data + unpacked_size;
|
||||||
|
unpacked_size *= 2;
|
||||||
|
out_end = decompressed_data + unpacked_size;
|
||||||
|
}
|
||||||
|
in_ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*decompressed_size = (out_ptr - decompressed_data);
|
||||||
|
return decompressed_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int write_imd5_lz77(u8* data, size_t size, char* outname)
|
||||||
|
{
|
||||||
|
imd5_header_t* header = (imd5_header_t*) data;
|
||||||
|
u32 tag;
|
||||||
|
u32 size_in_imd5;
|
||||||
|
u8 md5_calc[16];
|
||||||
|
u8 *decompressed_data;
|
||||||
|
size_t decompressed_size;
|
||||||
|
|
||||||
|
tag = be32((u8*) &header->imd5_tag);
|
||||||
|
if (tag != 0x494D4435) {
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
|
||||||
|
md5(data+32, size-32, md5_calc);
|
||||||
|
if (memcmp(&header->md5, md5_calc, 0x10)) {
|
||||||
|
return -5;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_in_imd5 = be32((u8*) &header->size);
|
||||||
|
if (size_in_imd5 != size - 32) {
|
||||||
|
return -6;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag = be32((u8*) &header->payload_tag);
|
||||||
|
if (tag == 0x4C5A3737) {
|
||||||
|
// "LZ77" - uncompress
|
||||||
|
decompressed_data = decompress_lz77(data + sizeof(imd5_header_t), size - sizeof(imd5_header_t), &decompressed_size);
|
||||||
|
if(decompressed_data == NULL)
|
||||||
|
return -7;
|
||||||
|
write_file(decompressed_data, decompressed_size, outname);
|
||||||
|
//printf(", uncompressed %d bytes, md5 ok", decompressed_size);
|
||||||
|
|
||||||
|
free(decompressed_data);
|
||||||
|
} else {
|
||||||
|
write_file(&header->payload_tag, size-32, outname);
|
||||||
|
//printf(", md5 ok");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_U8_archive(void)
|
||||||
|
{
|
||||||
|
U8_archive_header header;
|
||||||
|
U8_node root_node;
|
||||||
|
u32 tag;
|
||||||
|
u32 num_nodes;
|
||||||
|
U8_node* nodes;
|
||||||
|
u8* string_table;
|
||||||
|
size_t rest_size;
|
||||||
|
unsigned int i;
|
||||||
|
u32 data_offset;
|
||||||
|
u32 current_offset;
|
||||||
|
u16 dir_stack[16];
|
||||||
|
int dir_index = 0;
|
||||||
|
|
||||||
|
fread(&header, 1, sizeof header, fp);
|
||||||
|
tag = be32((u8*) &header.tag);
|
||||||
|
if (tag != 0x55AA382D) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fread(&root_node, 1, sizeof(root_node), fp);
|
||||||
|
num_nodes = be32((u8*) &root_node.size) - 1;
|
||||||
|
//printf("Number of files: %d\n", num_nodes);
|
||||||
|
|
||||||
|
nodes = malloc(sizeof(U8_node) * (num_nodes));
|
||||||
|
fread(nodes, 1, num_nodes * sizeof(U8_node), fp);
|
||||||
|
|
||||||
|
data_offset = be32((u8*) &header.data_offset);
|
||||||
|
rest_size = data_offset - sizeof(header) - (num_nodes+1)*sizeof(U8_node);
|
||||||
|
|
||||||
|
string_table = malloc(rest_size);
|
||||||
|
fread(string_table, 1, rest_size, fp);
|
||||||
|
current_offset = data_offset;
|
||||||
|
|
||||||
|
for (i = 0; i < num_nodes; i++) {
|
||||||
|
U8_node* node = &nodes[i];
|
||||||
|
u16 type = be16((u8*)&node->type);
|
||||||
|
u16 name_offset = be16((u8*)&node->name_offset);
|
||||||
|
u32 my_data_offset = be32((u8*)&node->data_offset);
|
||||||
|
u32 size = be32((u8*)&node->size);
|
||||||
|
char* name = (char*) &string_table[name_offset];
|
||||||
|
u8* file_data;
|
||||||
|
|
||||||
|
if (type == 0x0100) {
|
||||||
|
// Directory
|
||||||
|
mkdir(name, 0777);
|
||||||
|
chdir(name);
|
||||||
|
dir_stack[++dir_index] = size;
|
||||||
|
//printf("%*s%s/\n", dir_index, "", name);
|
||||||
|
} else {
|
||||||
|
// Normal file
|
||||||
|
u8 padding[32];
|
||||||
|
|
||||||
|
if (type != 0x0000) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_offset < my_data_offset) {
|
||||||
|
int diff = my_data_offset - current_offset;
|
||||||
|
|
||||||
|
if (diff > 32) {
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
fread(padding, 1, diff, fp);
|
||||||
|
current_offset += diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
file_data = malloc(size);
|
||||||
|
fread(file_data, 1, size, fp);
|
||||||
|
//printf("%*s %s (%d bytes", dir_index, "", name, size);
|
||||||
|
int result;
|
||||||
|
result = write_imd5_lz77(file_data, size, name);
|
||||||
|
if(result < 0)
|
||||||
|
return result;
|
||||||
|
//printf(")\n");
|
||||||
|
current_offset += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (dir_stack[dir_index] == i+2 && dir_index > 0) {
|
||||||
|
chdir("..");
|
||||||
|
dir_index--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_imet_header(void)
|
||||||
|
{
|
||||||
|
imet_data_t header;
|
||||||
|
|
||||||
|
fread(&header, 1, sizeof header, fp);
|
||||||
|
|
||||||
|
write_file(&header, sizeof(header), "header.imet");
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_U8_archivebanner(FILE *fp)
|
||||||
|
{
|
||||||
|
U8_archive_header header;
|
||||||
|
U8_node root_node;
|
||||||
|
u32 tag;
|
||||||
|
u32 num_nodes;
|
||||||
|
U8_node* nodes;
|
||||||
|
u8* string_table;
|
||||||
|
size_t rest_size;
|
||||||
|
unsigned int i;
|
||||||
|
u32 data_offset;
|
||||||
|
u16 dir_stack[16];
|
||||||
|
int dir_index = 0;
|
||||||
|
|
||||||
|
fread(&header, 1, sizeof header, fp);
|
||||||
|
tag = be32((u8*) &header.tag);
|
||||||
|
if (tag != 0x55AA382D) {
|
||||||
|
//printf("No U8 tag");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fread(&root_node, 1, sizeof(root_node), fp);
|
||||||
|
num_nodes = be32((u8*) &root_node.size) - 1;
|
||||||
|
printf("Number of files: %d\n", num_nodes);
|
||||||
|
|
||||||
|
nodes = malloc(sizeof(U8_node) * (num_nodes));
|
||||||
|
fread(nodes, 1, num_nodes * sizeof(U8_node), fp);
|
||||||
|
|
||||||
|
data_offset = be32((u8*) &header.data_offset);
|
||||||
|
rest_size = data_offset - sizeof(header) - (num_nodes+1)*sizeof(U8_node);
|
||||||
|
|
||||||
|
string_table = malloc(rest_size);
|
||||||
|
fread(string_table, 1, rest_size, fp);
|
||||||
|
|
||||||
|
for (i = 0; i < num_nodes; i++) {
|
||||||
|
U8_node* node = &nodes[i];
|
||||||
|
u16 type = be16((u8*)&node->type);
|
||||||
|
u16 name_offset = be16((u8*)&node->name_offset);
|
||||||
|
u32 my_data_offset = be32((u8*)&node->data_offset);
|
||||||
|
u32 size = be32((u8*)&node->size);
|
||||||
|
char* name = (char*) &string_table[name_offset];
|
||||||
|
u8* file_data;
|
||||||
|
|
||||||
|
if (type == 0x0100) {
|
||||||
|
// Directory
|
||||||
|
mkdir(name, 0777);
|
||||||
|
chdir(name);
|
||||||
|
dir_stack[++dir_index] = size;
|
||||||
|
//printf("%*s%s/\n", dir_index, "", name);
|
||||||
|
} else {
|
||||||
|
// Normal file
|
||||||
|
|
||||||
|
if (type != 0x0000) {
|
||||||
|
printf("Unknown type");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(fp, my_data_offset, SEEK_SET);
|
||||||
|
file_data = malloc(size);
|
||||||
|
fread(file_data, 1, size, fp);
|
||||||
|
write_file(file_data, size, name);
|
||||||
|
free(file_data);
|
||||||
|
//printf("%*s %s (%d bytes)\n", dir_index, "", name, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (dir_stack[dir_index] == i+2 && dir_index > 0) {
|
||||||
|
chdir("..");
|
||||||
|
dir_index--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int extractbnrfile(const char * filepath, const char * destpath)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
fp = fopen(filepath, "rb");
|
||||||
|
|
||||||
|
mkdir(destpath, 0777);
|
||||||
|
chdir(destpath);
|
||||||
|
|
||||||
|
do_imet_header();
|
||||||
|
ret = do_U8_archive();
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int unpackBin(const char * filename,const char * outdir)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
fp = fopen(filename,"rb");
|
||||||
|
|
||||||
|
if(fp!=NULL)
|
||||||
|
{
|
||||||
|
mkdir(outdir, 0777);
|
||||||
|
chdir(outdir);
|
||||||
|
|
||||||
|
do_U8_archivebanner(fp);
|
||||||
|
fclose(fp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int unpackBanner(char * gameid, char * outdir)
|
||||||
|
{
|
||||||
|
s32 ret = dump_banner(gameid,"SD:/opening.bnr");
|
||||||
|
if (ret != 1) return -1;
|
||||||
|
|
||||||
|
ret = extractbnrfile("SD:/opening.bnr","SD:/neu");
|
||||||
|
if (ret != 0) return -1;
|
||||||
|
remove("SD:/opening.bnr");
|
||||||
|
char iconpath[60];
|
||||||
|
snprintf(iconpath,sizeof(iconpath),"%s/meta/icon.bin",outdir);
|
||||||
|
ret = unpackBin(iconpath,"SD:/icon");
|
||||||
|
if (ret != 1) return -1;
|
||||||
|
|
||||||
|
if (unlink("/neu/meta/banner.bin") == -1) return -1;
|
||||||
|
if (unlink("/neu/meta/icon.bin") == -1) return -1;
|
||||||
|
if (unlink("/neu/meta/sound.bin") == -1) return -1;
|
||||||
|
if (unlink("/neu/header.imet") == -1) return -1;
|
||||||
|
if (unlink("/neu/meta") == -1) return -1;
|
||||||
|
if (unlink("/neu") == -1) return -1;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
41
source/banner/openingbnr.h
Normal file
41
source/banner/openingbnr.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* USB Loader GX Team
|
||||||
|
* openingbnr
|
||||||
|
*
|
||||||
|
* Extract opening.bnr/banner.bin/sound.bin/icon.bin
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _OPENINGBNR_H_
|
||||||
|
#define _OPENINGBNR_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* Error description:
|
||||||
|
* 0 Successfully extracted
|
||||||
|
* -1 No U8 tag
|
||||||
|
* -2 Unknown type
|
||||||
|
* -3 Archive inconsistency, too much padding
|
||||||
|
* -4 No IMD5 tag
|
||||||
|
* -5 MD5 mismatch
|
||||||
|
* -6 Size mismatch
|
||||||
|
* -7 Inconsistency in LZ77 encoding
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
//! Extract opening.bnr from filepath to destpath
|
||||||
|
//! Files extracted: banner.bin icon.bin and sound.bin
|
||||||
|
int extractbnrfile(char * filepath, char * destpath);
|
||||||
|
//int unpackBanner(const char * filename,const char * outdir);
|
||||||
|
int unpackBanner(const char * gameid, const char * outdir);
|
||||||
|
//! Extract the lz77 compressed banner, icon and sound .bin
|
||||||
|
u8* decompress_lz77(u8 *data, size_t data_size, size_t* decompressed_size);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -1,22 +0,0 @@
|
|||||||
#ifndef _GUIBANNER_H_
|
|
||||||
#define _GUIBANNER_H_
|
|
||||||
|
|
||||||
#include "gui.h"
|
|
||||||
|
|
||||||
class GuiBanner : public GuiImage
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
GuiBanner();
|
|
||||||
GuiBanner(const char *tplfilepath);
|
|
||||||
GuiBanner(void *mem,u32 len,u16 w, u16 h);
|
|
||||||
~GuiBanner();
|
|
||||||
|
|
||||||
void Draw();
|
|
||||||
private:
|
|
||||||
f32 deg_beta;
|
|
||||||
const char *filepath;
|
|
||||||
const void *memory;
|
|
||||||
bool filecheck;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _GUIDISCCOVER_H_ */
|
|
@ -49,6 +49,7 @@ s32 Disc_IsWii(void);
|
|||||||
s32 Disc_BootPartition(u64, u8, u8, u8, u8, u8, u8);
|
s32 Disc_BootPartition(u64, u8, u8, u8, u8, u8, u8);
|
||||||
s32 Disc_WiiBoot(u8, u8, u8, u8, u8, u8);
|
s32 Disc_WiiBoot(u8, u8, u8, u8, u8, u8);
|
||||||
void PatchCountryStrings(void *Address, int Size);
|
void PatchCountryStrings(void *Address, int Size);
|
||||||
|
s32 __Disc_FindPartition(u64 *outbuf);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user