*Fixed booting games for huge ext2/3/4 drives

*Rewrote complete main menu function
*Moved ext2/3/4 disc cache to mem2 as on FAT/NTFS (added ext2 as custom lib due to that)
*Added missing header files from R1011 for ext support
*Fixed crash on Numpad when pressing a button
*Fixed boot of WiiMC
*Changed SVN line ending to LF (Unix style)
This commit is contained in:
dimok321 2010-12-12 16:31:13 +00:00
parent 2213b45351
commit 18a26d7e1a
62 changed files with 8844 additions and 7585 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
#
# to use this file rename Make.config.default to Make.config
# or create a new Make.config
#
# you can here add defines
#
# in example i have included a switch to diseble
# the gecko-debug stuff. so also in source gecko.c+gecko.h
#
# NOTE when add, remove or change a define here then a "make clean" is needed
#
CFLAGS += -DNO_DEBUG DDEBUG_WBFS
#
# to use this file rename Make.config.default to Make.config
# or create a new Make.config
#
# you can here add defines
#
# in example i have included a switch to diseble
# the gecko-debug stuff. so also in source gecko.c+gecko.h
#
# NOTE when add, remove or change a define here then a "make clean" is needed
#
CFLAGS += -DNO_DEBUG DDEBUG_WBFS

View File

@ -64,7 +64,8 @@ LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map,--section-start,.init=0x80B00
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lpngu -lpng -lgd -lm -lz -lwiiuse -lbte -lasnd -logc -lfreetype -lvorbisidec -lmad -lmxml -ljpeg -lzip -lext2fs
LIBS := -lpngu -lpng -lgd -lm -lz -lwiiuse -lbte -lasnd -logc -lfreetype -lvorbisidec \
-lmad -lmxml -ljpeg -lzip -lcustomext2fs
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
@ -99,7 +100,7 @@ PCMFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pcm)))
WAVFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.wav)))
DOLFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.dol)))
MP3FILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.mp3)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
@ -127,7 +128,7 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
#---------------------------------------------------------------------------------
# build a list of library paths
#---------------------------------------------------------------------------------
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) -L$(CURDIR)/source/libs/libext2fs/ \
-L$(LIBOGC_LIB)
export OUTPUT := $(CURDIR)/$(TARGET)
@ -167,15 +168,15 @@ run:
$(MAKE)
@echo Done building ...
@echo Now Run That Shit ...
wiiload $(OUTPUT).dol
#---------------------------------------------------------------------------------
reload:
wiiload -r $(OUTPUT).dol
#---------------------------------------------------------------------------------
release:
#---------------------------------------------------------------------------------
release:
$(MAKE)
cp boot.dol ./hbc/boot.dol
@ -183,7 +184,7 @@ release:
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
@ -211,15 +212,15 @@ language: $(wildcard $(PROJECTDIR)/Languages/*.lang)
%.png.o : %.png
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
%.ogg.o : %.ogg
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
%.pcm.o : %.pcm
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
%.wav.o : %.wav
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
@ -227,7 +228,7 @@ language: $(wildcard $(PROJECTDIR)/Languages/*.lang)
%.mp3.o : %.mp3
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
%.certs.o : %.certs
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 103 KiB

File diff suppressed because one or more lines are too long

View File

@ -1,58 +1,58 @@
/***************************************************************************
* Copyright (C) 2009
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. 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.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
* ZipFile.cpp
*
* for Wii-FileXplorer 2009
***************************************************************************/
#ifndef _ZIPFILE_H_
#define _ZIPFILE_H_
#include <zip/unzip.h>
typedef struct
{
u64 offset; // ZipFile offset
u64 length; // uncompressed file length in 64 bytes for sizes higher than 4GB
bool isdir; // 0 - file, 1 - directory
char filename[256]; // full filename
} FileStructure;
class ZipFile
{
public:
//!Constructor
ZipFile(const char *filepath);
//!Destructor
~ZipFile();
//!Extract all files from a zip file to a directory
//!\param dest Destination path to where to extract
bool ExtractAll(const char *dest);
protected:
bool LoadList();
unzFile File;
unz_file_info cur_file_info;
FileStructure *FileList;
};
#endif
/***************************************************************************
* Copyright (C) 2009
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. 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.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
* ZipFile.cpp
*
* for Wii-FileXplorer 2009
***************************************************************************/
#ifndef _ZIPFILE_H_
#define _ZIPFILE_H_
#include <zip/unzip.h>
typedef struct
{
u64 offset; // ZipFile offset
u64 length; // uncompressed file length in 64 bytes for sizes higher than 4GB
bool isdir; // 0 - file, 1 - directory
char filename[256]; // full filename
} FileStructure;
class ZipFile
{
public:
//!Constructor
ZipFile(const char *filepath);
//!Destructor
~ZipFile();
//!Extract all files from a zip file to a directory
//!\param dest Destination path to where to extract
bool ExtractAll(const char *dest);
protected:
bool LoadList();
unzFile File;
unz_file_info cur_file_info;
FileStructure *FileList;
};
#endif

View File

@ -1,241 +1,241 @@
#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 $
*
* Modifications and additions 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
*
* ========================================================================== **
*/
/* -------------------------------------------------------------------------- **
* Typedefs:
*/
typedef struct
{
unsigned int len;
unsigned int 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()>
*
* ------------------------------------------------------------------------ **
*/
const char * MD5ToString(const unsigned char *hash, char *dst);
unsigned char * StringToMD5(const char * hash, unsigned char * dst);
/* ========================================================================== */
#ifdef __cplusplus
}
#endif
#endif /* AUTH_MD5_H */
#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 $
*
* Modifications and additions 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
*
* ========================================================================== **
*/
/* -------------------------------------------------------------------------- **
* Typedefs:
*/
typedef struct
{
unsigned int len;
unsigned int 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()>
*
* ------------------------------------------------------------------------ **
*/
const char * MD5ToString(const unsigned char *hash, char *dst);
unsigned char * StringToMD5(const char * hash, unsigned char * dst);
/* ========================================================================== */
#ifdef __cplusplus
}
#endif
#endif /* AUTH_MD5_H */

View File

@ -1,6 +1,6 @@
#ifndef BANNERSOUND_H
#define BANNERSOUND_H
const u8 *LoadBannerSound(const u8 *discid, u32 *size);
#endif /* BANNERSOUND_H */
#ifndef BANNERSOUND_H
#define BANNERSOUND_H
const u8 *LoadBannerSound(const u8 *discid, u32 *size);
#endif /* BANNERSOUND_H */

View File

@ -21,7 +21,7 @@ void gprintf(const char *format, ...)
if((vasprintf(&tmp, format, va) >= 0) && tmp)
{
u32 level = IRQ_Disable();
usb_sendbuffer(1, tmp, strlen(tmp));
usb_sendbuffer_safe(1, tmp, strlen(tmp));
IRQ_Restore(level);
}
va_end(va);

View File

@ -8,52 +8,57 @@
#include "dolloader.h"
typedef struct _dolheader
{
u32 text_pos[7];
u32 data_pos[11];
u32 text_start[7];
u32 data_start[11];
u32 text_size[7];
u32 data_size[11];
u32 bss_start;
u32 bss_size;
u32 entry_point;
typedef struct _dolheader {
u32 text_pos[7];
u32 data_pos[11];
u32 text_start[7];
u32 data_start[11];
u32 text_size[7];
u32 data_size[11];
u32 bss_start;
u32 bss_size;
u32 entry_point;
} dolheader;
u32 load_dol(const void *dolstart, struct __argv *argv)
{
u32 i;
dolheader *dolfile;
u32 i;
dolheader *dolfile;
if (dolstart)
{
dolfile = (dolheader *) dolstart;
for (i = 0; i < 7; i++)
{
if ((!dolfile->text_size[i]) || (dolfile->text_start[i] < 0x100)) continue;
ICInvalidateRange((void *) dolfile->text_start[i], dolfile->text_size[i]);
memcpy((void *) dolfile->text_start[i], dolstart + dolfile->text_pos[i], dolfile->text_size[i]);
}
if (dolstart)
{
dolfile = (dolheader *) dolstart;
for (i = 0; i < 7; i++)
{
if ((!dolfile->text_size[i]) || (dolfile->text_start[i] < 0x100))
continue;
for (i = 0; i < 11; i++)
{
if ((!dolfile->data_size[i]) || (dolfile->data_start[i] < 0x100)) continue;
memcpy((void *) dolfile->data_start[i], dolstart + dolfile->data_pos[i], dolfile->data_size[i]);
DCFlushRangeNoSync((void *) dolfile->data_start[i], dolfile->data_size[i]);
}
memmove((void *) dolfile->text_start[i], dolstart
+ dolfile->text_pos[i], dolfile->text_size[i]);
memset((void *) dolfile->bss_start, 0, dolfile->bss_size);
DCFlushRange((void *) dolfile->bss_start, dolfile->bss_size);
DCFlushRange ((void *) dolfile->text_start[i], dolfile->text_size[i]);
ICInvalidateRange((void *) dolfile->text_start[i], dolfile->text_size[i]);
}
if (argv && argv->argvMagic == ARGV_MAGIC)
{
void *new_argv = (void *) (dolfile->entry_point + 8);
memcpy(new_argv, argv, sizeof(*argv));
DCFlushRange(new_argv, sizeof(*argv));
}
for (i = 0; i < 11; i++)
{
if ((!dolfile->data_size[i]) || (dolfile->data_start[i] < 0x100))
continue;
return dolfile->entry_point;
}
return 0;
memmove((void *) dolfile->data_start[i], dolstart
+ dolfile->data_pos[i], dolfile->data_size[i]);
DCFlushRange((void *) dolfile->data_start[i],
dolfile->data_size[i]);
}
if (argv && argv->argvMagic == ARGV_MAGIC)
{
void *new_argv = (void *) (dolfile->entry_point + 8);
memmove(new_argv, argv, sizeof(*argv));
DCFlushRange(new_argv, sizeof(*argv));
}
return dolfile->entry_point;
}
return 0;
}

View File

@ -2,14 +2,14 @@
#define _DOLLOADER_H_
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
extern void __exception_closeall();
typedef void (*entrypoint)(void);
extern void __exception_closeall();
typedef void (*entrypoint) (void);
u32 load_dol(const void *dolstart, struct __argv *argv);
u32 load_dol(const void *dolstart, struct __argv *argv);
#ifdef __cplusplus
}

View File

@ -0,0 +1,638 @@
/*
* bitops.h --- Bitmap frobbing code. The byte swapping routines are
* also included here.
*
* Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#ifndef _BITOPS_H_
#define _BITOPS_H_
extern int ext2fs_set_bit(unsigned int nr,void * addr);
extern int ext2fs_clear_bit(unsigned int nr, void * addr);
extern int ext2fs_test_bit(unsigned int nr, const void * addr);
extern void ext2fs_fast_set_bit(unsigned int nr,void * addr);
extern void ext2fs_fast_clear_bit(unsigned int nr, void * addr);
extern int ext2fs_set_bit64(__u64 nr,void * addr);
extern int ext2fs_clear_bit64(__u64 nr, void * addr);
extern int ext2fs_test_bit64(__u64 nr, const void * addr);
extern void ext2fs_fast_set_bit64(__u64 nr,void * addr);
extern void ext2fs_fast_clear_bit64(__u64 nr, void * addr);
extern __u16 ext2fs_swab16(__u16 val);
extern __u32 ext2fs_swab32(__u32 val);
extern __u64 ext2fs_swab64(__u64 val);
#ifdef WORDS_BIGENDIAN
#define ext2fs_cpu_to_le64(x) ext2fs_swab64((x))
#define ext2fs_le64_to_cpu(x) ext2fs_swab64((x))
#define ext2fs_cpu_to_le32(x) ext2fs_swab32((x))
#define ext2fs_le32_to_cpu(x) ext2fs_swab32((x))
#define ext2fs_cpu_to_le16(x) ext2fs_swab16((x))
#define ext2fs_le16_to_cpu(x) ext2fs_swab16((x))
#define ext2fs_cpu_to_be32(x) ((__u32)(x))
#define ext2fs_be32_to_cpu(x) ((__u32)(x))
#define ext2fs_cpu_to_be16(x) ((__u16)(x))
#define ext2fs_be16_to_cpu(x) ((__u16)(x))
#else
#define ext2fs_cpu_to_le64(x) ((__u64)(x))
#define ext2fs_le64_to_cpu(x) ((__u64)(x))
#define ext2fs_cpu_to_le32(x) ((__u32)(x))
#define ext2fs_le32_to_cpu(x) ((__u32)(x))
#define ext2fs_cpu_to_le16(x) ((__u16)(x))
#define ext2fs_le16_to_cpu(x) ((__u16)(x))
#define ext2fs_cpu_to_be32(x) ext2fs_swab32((x))
#define ext2fs_be32_to_cpu(x) ext2fs_swab32((x))
#define ext2fs_cpu_to_be16(x) ext2fs_swab16((x))
#define ext2fs_be16_to_cpu(x) ext2fs_swab16((x))
#endif
/*
* EXT2FS bitmap manipulation routines.
*/
/* Support for sending warning messages from the inline subroutines */
extern const char *ext2fs_block_string;
extern const char *ext2fs_inode_string;
extern const char *ext2fs_mark_string;
extern const char *ext2fs_unmark_string;
extern const char *ext2fs_test_string;
extern void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
const char *description);
extern void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
int code, unsigned long arg);
extern int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
extern int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
blk_t block);
extern int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
extern int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
extern int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode);
extern int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
extern void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
blk_t block);
extern void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
blk_t block);
extern int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
blk_t block);
extern void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode);
extern void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode);
extern int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode);
extern blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap);
extern ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap);
extern blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap);
extern ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap);
extern void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
blk_t block, int num);
extern void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
blk_t block, int num);
extern int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
blk_t block, int num);
extern int ext2fs_test_inode_bitmap_range(ext2fs_inode_bitmap bitmap,
ino_t inode, int num);
extern void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
blk_t block, int num);
extern void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
blk_t block, int num);
extern int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
blk_t block, int num);
extern void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map);
/* These routines moved to gen_bitmap.c (actually, some of the above, too) */
extern int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
__u32 bitno);
extern int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
blk_t bitno);
extern int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
blk_t bitno);
extern int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
blk_t block, int num);
extern __u32 ext2fs_get_generic_bitmap_start(ext2fs_generic_bitmap bitmap);
extern __u32 ext2fs_get_generic_bitmap_end(ext2fs_generic_bitmap bitmap);
/* 64-bit versions */
extern int ext2fs_mark_block_bitmap2(ext2fs_block_bitmap bitmap,
blk64_t block);
extern int ext2fs_unmark_block_bitmap2(ext2fs_block_bitmap bitmap,
blk64_t block);
extern int ext2fs_test_block_bitmap2(ext2fs_block_bitmap bitmap,
blk64_t block);
extern int ext2fs_mark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode);
extern int ext2fs_unmark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode);
extern int ext2fs_test_inode_bitmap2(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode);
extern void ext2fs_fast_mark_block_bitmap2(ext2fs_block_bitmap bitmap,
blk64_t block);
extern void ext2fs_fast_unmark_block_bitmap2(ext2fs_block_bitmap bitmap,
blk64_t block);
extern int ext2fs_fast_test_block_bitmap2(ext2fs_block_bitmap bitmap,
blk64_t block);
extern void ext2fs_fast_mark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode);
extern void ext2fs_fast_unmark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode);
extern int ext2fs_fast_test_inode_bitmap2(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode);
extern blk64_t ext2fs_get_block_bitmap_start2(ext2fs_block_bitmap bitmap);
extern ext2_ino_t ext2fs_get_inode_bitmap_start2(ext2fs_inode_bitmap bitmap);
extern blk64_t ext2fs_get_block_bitmap_end2(ext2fs_block_bitmap bitmap);
extern ext2_ino_t ext2fs_get_inode_bitmap_end2(ext2fs_inode_bitmap bitmap);
extern int ext2fs_fast_test_block_bitmap_range2(ext2fs_block_bitmap bitmap,
blk64_t block,
unsigned int num);
extern void ext2fs_fast_mark_block_bitmap_range2(ext2fs_block_bitmap bitmap,
blk64_t block,
unsigned int num);
extern void ext2fs_fast_unmark_block_bitmap_range2(ext2fs_block_bitmap bitmap,
blk64_t block,
unsigned int num);
/* These routines moved to gen_bitmap64.c */
extern void ext2fs_clear_generic_bmap(ext2fs_generic_bitmap bitmap);
extern errcode_t ext2fs_compare_generic_bmap(errcode_t neq,
ext2fs_generic_bitmap bm1,
ext2fs_generic_bitmap bm2);
extern void ext2fs_set_generic_bmap_padding(ext2fs_generic_bitmap bmap);
extern int ext2fs_mark_generic_bmap(ext2fs_generic_bitmap bitmap,
blk64_t bitno);
extern int ext2fs_unmark_generic_bmap(ext2fs_generic_bitmap bitmap,
blk64_t bitno);
extern int ext2fs_test_generic_bmap(ext2fs_generic_bitmap bitmap,
blk64_t bitno);
extern int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap bitmap,
blk64_t block, unsigned int num);
extern __u64 ext2fs_get_generic_bmap_start(ext2fs_generic_bitmap bitmap);
extern __u64 ext2fs_get_generic_bmap_end(ext2fs_generic_bitmap bitmap);
extern int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap bitmap,
blk64_t block, unsigned int num);
extern void ext2fs_mark_block_bitmap_range2(ext2fs_block_bitmap bitmap,
blk64_t block, unsigned int num);
extern void ext2fs_unmark_block_bitmap_range2(ext2fs_block_bitmap bitmap,
blk64_t block, unsigned int num);
/*
* The inline routines themselves...
*
* If NO_INLINE_FUNCS is defined, then we won't try to do inline
* functions at all; they will be included as normal functions in
* inline.c
*/
#ifdef NO_INLINE_FUNCS
#if (defined(__GNUC__) && (defined(__i386__) || defined(__i486__) || \
defined(__i586__) || defined(__mc68000__)))
/* This prevents bitops.c from trying to include the C */
/* function version of these functions */
#define _EXT2_HAVE_ASM_BITOPS_
#endif
#endif /* NO_INLINE_FUNCS */
#if (defined(INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
#ifdef INCLUDE_INLINE_FUNCS
#define _INLINE_ extern
#else
#ifdef __GNUC__
#define _INLINE_ extern __inline__
#else /* For Watcom C */
#define _INLINE_ extern inline
#endif
#endif
/*
* Fast bit set/clear functions that doesn't need to return the
* previous bit value.
*/
_INLINE_ void ext2fs_fast_set_bit(unsigned int nr,void * addr)
{
unsigned char *ADDR = (unsigned char *) addr;
ADDR += nr >> 3;
*ADDR |= (1 << (nr & 0x07));
}
_INLINE_ void ext2fs_fast_clear_bit(unsigned int nr, void * addr)
{
unsigned char *ADDR = (unsigned char *) addr;
ADDR += nr >> 3;
*ADDR &= ~(1 << (nr & 0x07));
}
_INLINE_ void ext2fs_fast_set_bit64(__u64 nr, void * addr)
{
unsigned char *ADDR = (unsigned char *) addr;
ADDR += nr >> 3;
*ADDR |= (1 << (nr & 0x07));
}
_INLINE_ void ext2fs_fast_clear_bit64(__u64 nr, void * addr)
{
unsigned char *ADDR = (unsigned char *) addr;
ADDR += nr >> 3;
*ADDR &= ~(1 << (nr & 0x07));
}
#if ((defined __GNUC__) && !defined(_EXT2_USE_C_VERSIONS_) && \
(defined(__i386__) || defined(__i486__) || defined(__i586__)))
#define _EXT2_HAVE_ASM_BITOPS_
#define _EXT2_HAVE_ASM_SWAB_
/*
* These are done by inline assembly for speed reasons.....
*
* All bitoperations return 0 if the bit was cleared before the
* operation and != 0 if it was not. Bit 0 is the LSB of addr; bit 32
* is the LSB of (addr+1).
*/
/*
* Some hacks to defeat gcc over-optimizations..
*/
struct __dummy_h { unsigned long a[100]; };
#define EXT2FS_ADDR (*(struct __dummy_h *) addr)
#define EXT2FS_CONST_ADDR (*(const struct __dummy_h *) addr)
_INLINE_ int ext2fs_set_bit(unsigned int nr, void * addr)
{
int oldbit;
addr = (void *) (((unsigned char *) addr) + (nr >> 3));
__asm__ __volatile__("btsl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"+m" (EXT2FS_ADDR)
:"r" (nr & 7));
return oldbit;
}
_INLINE_ int ext2fs_clear_bit(unsigned int nr, void * addr)
{
int oldbit;
addr = (void *) (((unsigned char *) addr) + (nr >> 3));
__asm__ __volatile__("btrl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"+m" (EXT2FS_ADDR)
:"r" (nr & 7));
return oldbit;
}
_INLINE_ int ext2fs_test_bit(unsigned int nr, const void * addr)
{
int oldbit;
addr = (const void *) (((const unsigned char *) addr) + (nr >> 3));
__asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit)
:"m" (EXT2FS_CONST_ADDR),"r" (nr & 7));
return oldbit;
}
_INLINE_ __u32 ext2fs_swab32(__u32 val)
{
#ifdef EXT2FS_REQUIRE_486
__asm__("bswap %0" : "=r" (val) : "0" (val));
#else
__asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */
"rorl $16,%0\n\t" /* swap words */
"xchgb %b0,%h0" /* swap higher bytes */
:"=q" (val)
: "0" (val));
#endif
return val;
}
_INLINE_ __u16 ext2fs_swab16(__u16 val)
{
__asm__("xchgb %b0,%h0" /* swap bytes */ \
: "=q" (val) \
: "0" (val)); \
return val;
}
#undef EXT2FS_ADDR
#endif /* i386 */
#if ((defined __GNUC__) && !defined(_EXT2_USE_C_VERSIONS_) && \
(defined(__mc68000__)))
#define _EXT2_HAVE_ASM_BITOPS_
_INLINE_ int ext2fs_set_bit(unsigned int nr,void * addr)
{
char retval;
__asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0"
: "=d" (retval) : "d" (nr^7), "a" (addr));
return retval;
}
_INLINE_ int ext2fs_clear_bit(unsigned int nr, void * addr)
{
char retval;
__asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0"
: "=d" (retval) : "d" (nr^7), "a" (addr));
return retval;
}
_INLINE_ int ext2fs_test_bit(unsigned int nr, const void * addr)
{
char retval;
__asm__ __volatile__ ("bftst %2@{%1:#1}; sne %0"
: "=d" (retval) : "d" (nr^7), "a" (addr));
return retval;
}
#endif /* __mc68000__ */
#if !defined(_EXT2_HAVE_ASM_SWAB_)
_INLINE_ __u16 ext2fs_swab16(__u16 val)
{
return (val >> 8) | (val << 8);
}
_INLINE_ __u32 ext2fs_swab32(__u32 val)
{
return ((val>>24) | ((val>>8)&0xFF00) |
((val<<8)&0xFF0000) | (val<<24));
}
#endif /* !_EXT2_HAVE_ASM_SWAB */
_INLINE_ __u64 ext2fs_swab64(__u64 val)
{
return (ext2fs_swab32(val >> 32) |
(((__u64)ext2fs_swab32(val & 0xFFFFFFFFUL)) << 32));
}
_INLINE_ int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap,
blk_t block)
{
return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
block);
}
_INLINE_ int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
blk_t block)
{
return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
block);
}
_INLINE_ int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
blk_t block)
{
return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
block);
}
_INLINE_ int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode)
{
return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
inode);
}
_INLINE_ int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode)
{
return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
inode);
}
_INLINE_ int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode)
{
return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
inode);
}
_INLINE_ void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
blk_t block)
{
ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, block);
}
_INLINE_ void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
blk_t block)
{
ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, block);
}
_INLINE_ int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
blk_t block)
{
return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
block);
}
_INLINE_ void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode)
{
ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, inode);
}
_INLINE_ void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode)
{
ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, inode);
}
_INLINE_ int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode)
{
return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
inode);
}
_INLINE_ blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap)
{
return ext2fs_get_generic_bitmap_start((ext2fs_generic_bitmap) bitmap);
}
_INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap)
{
return ext2fs_get_generic_bitmap_start((ext2fs_generic_bitmap) bitmap);
}
_INLINE_ blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap)
{
return ext2fs_get_generic_bitmap_end((ext2fs_generic_bitmap) bitmap);
}
_INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap)
{
return ext2fs_get_generic_bitmap_end((ext2fs_generic_bitmap) bitmap);
}
_INLINE_ int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
blk_t block, int num)
{
return ext2fs_test_block_bitmap_range(bitmap, block, num);
}
_INLINE_ void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
blk_t block, int num)
{
ext2fs_mark_block_bitmap_range(bitmap, block, num);
}
_INLINE_ void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
blk_t block, int num)
{
ext2fs_unmark_block_bitmap_range(bitmap, block, num);
}
/* 64-bit versions */
_INLINE_ int ext2fs_mark_block_bitmap2(ext2fs_block_bitmap bitmap,
blk64_t block)
{
return ext2fs_mark_generic_bmap((ext2fs_generic_bitmap) bitmap,
block);
}
_INLINE_ int ext2fs_unmark_block_bitmap2(ext2fs_block_bitmap bitmap,
blk64_t block)
{
return ext2fs_unmark_generic_bmap((ext2fs_generic_bitmap) bitmap, block);
}
_INLINE_ int ext2fs_test_block_bitmap2(ext2fs_block_bitmap bitmap,
blk64_t block)
{
return ext2fs_test_generic_bmap((ext2fs_generic_bitmap) bitmap,
block);
}
_INLINE_ int ext2fs_mark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode)
{
return ext2fs_mark_generic_bmap((ext2fs_generic_bitmap) bitmap,
inode);
}
_INLINE_ int ext2fs_unmark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode)
{
return ext2fs_unmark_generic_bmap((ext2fs_generic_bitmap) bitmap,
inode);
}
_INLINE_ int ext2fs_test_inode_bitmap2(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode)
{
return ext2fs_test_generic_bmap((ext2fs_generic_bitmap) bitmap,
inode);
}
_INLINE_ void ext2fs_fast_mark_block_bitmap2(ext2fs_block_bitmap bitmap,
blk64_t block)
{
ext2fs_mark_generic_bmap((ext2fs_generic_bitmap) bitmap, block);
}
_INLINE_ void ext2fs_fast_unmark_block_bitmap2(ext2fs_block_bitmap bitmap,
blk64_t block)
{
ext2fs_unmark_generic_bmap((ext2fs_generic_bitmap) bitmap, block);
}
_INLINE_ int ext2fs_fast_test_block_bitmap2(ext2fs_block_bitmap bitmap,
blk64_t block)
{
return ext2fs_test_generic_bmap((ext2fs_generic_bitmap) bitmap,
block);
}
_INLINE_ void ext2fs_fast_mark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode)
{
ext2fs_mark_generic_bmap((ext2fs_generic_bitmap) bitmap, inode);
}
_INLINE_ void ext2fs_fast_unmark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode)
{
ext2fs_unmark_generic_bmap((ext2fs_generic_bitmap) bitmap, inode);
}
_INLINE_ int ext2fs_fast_test_inode_bitmap2(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode)
{
return ext2fs_test_generic_bmap((ext2fs_generic_bitmap) bitmap,
inode);
}
_INLINE_ blk64_t ext2fs_get_block_bitmap_start2(ext2fs_block_bitmap bitmap)
{
return ext2fs_get_generic_bmap_start((ext2fs_generic_bitmap) bitmap);
}
_INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_start2(ext2fs_inode_bitmap bitmap)
{
return ext2fs_get_generic_bmap_start((ext2fs_generic_bitmap) bitmap);
}
_INLINE_ blk64_t ext2fs_get_block_bitmap_end2(ext2fs_block_bitmap bitmap)
{
return ext2fs_get_generic_bmap_end((ext2fs_generic_bitmap) bitmap);
}
_INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_end2(ext2fs_inode_bitmap bitmap)
{
return ext2fs_get_generic_bmap_end((ext2fs_generic_bitmap) bitmap);
}
_INLINE_ int ext2fs_fast_test_block_bitmap_range2(ext2fs_block_bitmap bitmap,
blk64_t block,
unsigned int num)
{
return ext2fs_test_block_bitmap_range2(bitmap, block, num);
}
_INLINE_ void ext2fs_fast_mark_block_bitmap_range2(ext2fs_block_bitmap bitmap,
blk64_t block,
unsigned int num)
{
ext2fs_mark_block_bitmap_range2(bitmap, block, num);
}
_INLINE_ void ext2fs_fast_unmark_block_bitmap_range2(ext2fs_block_bitmap bitmap,
blk64_t block,
unsigned int num)
{
ext2fs_unmark_block_bitmap_range2(bitmap, block, num);
}
#undef _INLINE_
#endif
#endif

View File

@ -0,0 +1,70 @@
/*
* Header file for common error description library.
*
* Copyright 1988, Student Information Processing Board of the
* Massachusetts Institute of Technology.
*
* For copyright and distribution info, see the documentation supplied
* with this package.
*/
#if !defined(__COM_ERR_H) && !defined(__COM_ERR_H__)
#ifdef __GNUC__
#define COM_ERR_ATTR(x) __attribute__(x)
#else
#define COM_ERR_ATTR(x)
#endif
#ifndef DEBUG_GEKKO
#define OMIT_COM_ERR
#endif
#include <stddef.h>
#include <stdarg.h>
typedef long errcode_t;
struct error_table {
char const * const * msgs;
long base;
int n_msgs;
};
struct et_list;
extern void com_err (const char *, long, const char *, ...)
COM_ERR_ATTR((format(printf, 3, 4)));
extern void com_err_va (const char *whoami, errcode_t code, const char *fmt,
va_list args)
COM_ERR_ATTR((format(printf, 3, 0)));
extern char const *error_message (long);
extern void (*com_err_hook) (const char *, long, const char *, va_list);
extern void (*set_com_err_hook (void (*) (const char *, long,
const char *, va_list)))
(const char *, long, const char *, va_list);
extern void (*reset_com_err_hook (void)) (const char *, long,
const char *, va_list);
extern int init_error_table(const char * const *msgs, long base, int count);
extern errcode_t add_error_table(const struct error_table * et);
extern errcode_t remove_error_table(const struct error_table * et);
extern void add_to_error_table(struct et_list *new_table);
/* Provided for Heimdall compatibility */
extern const char *com_right(struct et_list *list, long code);
extern const char *com_right_r(struct et_list *list, long code, char *str, size_t len);
extern void initialize_error_table_r(struct et_list **list,
const char **messages,
int num_errors,
long base);
extern void free_error_table(struct et_list *et);
/* Provided for compatibility with other com_err libraries */
extern int et_list_lock(void);
extern int et_list_unlock(void);
#define __COM_ERR_H
#define __COM_ERR_H__
#endif /* !defined(__COM_ERR_H) && !defined(__COM_ERR_H__)*/

View File

@ -0,0 +1,152 @@
//
// Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
//
// This file may be redistributed under the terms of the GNU Public
// License.
#ifndef EXT2_ERR_H_
#define EXT2_ERR_H_
#define EXT2_ET_OK 0
#define EXT2_ET_BASE -1
#define EXT2_ET_MAGIC_EXT2FS_FILSYS -2
#define EXT2_ET_MAGIC_BADBLOCKS_LIST -3
#define EXT2_ET_MAGIC_BADBLOCKS_ITERATE -4
#define EXT2_ET_MAGIC_INODE_SCAN -5
#define EXT2_ET_MAGIC_IO_CHANNEL -6
#define EXT2_ET_MAGIC_UNIX_IO_CHANNEL -7
#define EXT2_ET_MAGIC_IO_MANAGER -8
#define EXT2_ET_MAGIC_BLOCK_BITMAP -9
#define EXT2_ET_MAGIC_INODE_BITMAP -10
#define EXT2_ET_MAGIC_GENERIC_BITMAP -11
#define EXT2_ET_MAGIC_TEST_IO_CHANNEL -12
#define EXT2_ET_MAGIC_DBLIST -13
#define EXT2_ET_MAGIC_ICOUNT -14
#define EXT2_ET_MAGIC_PQ_IO_CHANNEL -15
#define EXT2_ET_MAGIC_EXT2_FILE -16
#define EXT2_ET_MAGIC_E2IMAGE -17
#define EXT2_ET_MAGIC_INODE_IO_CHANNEL -18
#define EXT2_ET_MAGIC_EXTENT_HANDLE -19
#define EXT2_ET_BAD_MAGIC -20
#define EXT2_ET_REV_TOO_HIGH -21
#define EXT2_ET_RO_FILSYS -22
#define EXT2_ET_GDESC_READ -23
#define EXT2_ET_GDESC_WRITE -24
#define EXT2_ET_GDESC_BAD_BLOCK_MAP -25
#define EXT2_ET_GDESC_BAD_INODE_MAP -26
#define EXT2_ET_GDESC_BAD_INODE_TABLE -27
#define EXT2_ET_INODE_BITMAP_WRITE -28
#define EXT2_ET_INODE_BITMAP_READ -29
#define EXT2_ET_BLOCK_BITMAP_WRITE -30
#define EXT2_ET_BLOCK_BITMAP_READ -31
#define EXT2_ET_INODE_TABLE_WRITE -32
#define EXT2_ET_INODE_TABLE_READ -33
#define EXT2_ET_NEXT_INODE_READ -34
#define EXT2_ET_UNEXPECTED_BLOCK_SIZE -35
#define EXT2_ET_DIR_CORRUPTED -36
#define EXT2_ET_SHORT_READ -37
#define EXT2_ET_SHORT_WRITE -38
#define EXT2_ET_DIR_NO_SPACE -39
#define EXT2_ET_NO_INODE_BITMAP -40
#define EXT2_ET_NO_BLOCK_BITMAP -41
#define EXT2_ET_BAD_INODE_NUM -42
#define EXT2_ET_BAD_BLOCK_NUM -45
#define EXT2_ET_EXPAND_DIR_ERR -46
#define EXT2_ET_TOOSMALL -47
#define EXT2_ET_BAD_BLOCK_MARK -48
#define EXT2_ET_BAD_BLOCK_UNMARK -49
#define EXT2_ET_BAD_BLOCK_TEST -50
#define EXT2_ET_BAD_INODE_MARK -51
#define EXT2_ET_BAD_INODE_UNMARK -52
#define EXT2_ET_BAD_INODE_TEST -53
#define EXT2_ET_FUDGE_BLOCK_BITMAP_END -54
#define EXT2_ET_FUDGE_INODE_BITMAP_END -55
#define EXT2_ET_BAD_IND_BLOCK -56
#define EXT2_ET_BAD_DIND_BLOCK -57
#define EXT2_ET_BAD_TIND_BLOCK -58
#define EXT2_ET_NEQ_BLOCK_BITMAP -59
#define EXT2_ET_NEQ_INODE_BITMAP -60
#define EXT2_ET_BAD_DEVICE_NAME -61
#define EXT2_ET_MISSING_INODE_TABLE -62
#define EXT2_ET_CORRUPT_SUPERBLOCK -63
#define EXT2_ET_BAD_GENERIC_MARK -64
#define EXT2_ET_BAD_GENERIC_UNMARK -65
#define EXT2_ET_BAD_GENERIC_TEST -66
#define EXT2_ET_SYMLINK_LOOP -67
#define EXT2_ET_CALLBACK_NOTHANDLED -68
#define EXT2_ET_BAD_BLOCK_IN_INODE_TABLE -69
#define EXT2_ET_UNSUPP_FEATURE -70
#define EXT2_ET_RO_UNSUPP_FEATURE -71
#define EXT2_ET_LLSEEK_FAILED -72
#define EXT2_ET_NO_MEMORY -73
#define EXT2_ET_INVALID_ARGUMENT -74
#define EXT2_ET_BLOCK_ALLOC_FAIL -75
#define EXT2_ET_INODE_ALLOC_FAIL -76
#define EXT2_ET_NO_DIRECTORY -77
#define EXT2_ET_TOO_MANY_REFS -78
#define EXT2_ET_FILE_NOT_FOUND -79
#define EXT2_ET_FILE_RO -80
#define EXT2_ET_DB_NOT_FOUND -81
#define EXT2_ET_DIR_EXISTS -82
#define EXT2_ET_UNIMPLEMENTED -83
#define EXT2_ET_CANCEL_REQUESTED -84
#define EXT2_ET_FILE_TOO_BIG -85
#define EXT2_ET_JOURNAL_NOT_BLOCK -86
#define EXT2_ET_NO_JOURNAL_SB -87
#define EXT2_ET_JOURNAL_TOO_SMALL -88
#define EXT2_ET_JOURNAL_UNSUPP_VERSION -89
#define EXT2_ET_LOAD_EXT_JOURNAL -90
#define EXT2_ET_NO_JOURNAL -91
#define EXT2_ET_DIRHASH_UNSUPP -92
#define EXT2_ET_BAD_EA_BLOCK_NUM -93
#define EXT2_ET_TOO_MANY_INODES -94
#define EXT2_ET_NOT_IMAGE_FILE -95
#define EXT2_ET_RES_GDT_BLOCKS -96
#define EXT2_ET_RESIZE_INODE_CORRUPT -97
#define EXT2_ET_SET_BMAP_NO_IND -98
#define EXT2_ET_TDB_SUCCESS -99
#define EXT2_ET_TDB_ERR_CORRUPT -100
#define EXT2_ET_TDB_ERR_IO -101
#define EXT2_ET_TDB_ERR_LOCK -102
#define EXT2_ET_TDB_ERR_OOM -103
#define EXT2_ET_TDB_ERR_EXISTS -104
#define EXT2_ET_TDB_ERR_NOLOCK -105
#define EXT2_ET_TDB_ERR_EINVAL -106
#define EXT2_ET_TDB_ERR_NOEXIST -107
#define EXT2_ET_TDB_ERR_RDONLY -108
#define EXT2_ET_DBLIST_EMPTY -109
#define EXT2_ET_RO_BLOCK_ITERATE -110
#define EXT2_ET_MAGIC_EXTENT_PATH -111
#define EXT2_ET_MAGIC_RESERVED_10 -112
#define EXT2_ET_MAGIC_RESERVED_11 -113
#define EXT2_ET_MAGIC_RESERVED_12 -114
#define EXT2_ET_MAGIC_RESERVED_13 -115
#define EXT2_ET_MAGIC_RESERVED_14 -116
#define EXT2_ET_MAGIC_RESERVED_15 -117
#define EXT2_ET_MAGIC_RESERVED_16 -118
#define EXT2_ET_MAGIC_RESERVED_17 -119
#define EXT2_ET_MAGIC_RESERVED_18 -120
#define EXT2_ET_MAGIC_RESERVED_19 -121
#define EXT2_ET_EXTENT_HEADER_BAD -122
#define EXT2_ET_EXTENT_INDEX_BAD -123
#define EXT2_ET_EXTENT_LEAF_BAD -124
#define EXT2_ET_EXTENT_NO_SPACE -125
#define EXT2_ET_INODE_NOT_EXTENT -126
#define EXT2_ET_EXTENT_NO_NEXT -127
#define EXT2_ET_EXTENT_NO_PREV -128
#define EXT2_ET_EXTENT_NO_UP -129
#define EXT2_ET_EXTENT_NO_DOWN -130
#define EXT2_ET_NO_CURRENT_NODE -131
#define EXT2_ET_OP_NOT_SUPPORTED -132
#define EXT2_ET_CANT_INSERT_EXTENT -133
#define EXT2_ET_CANT_SPLIT_EXTENT -134
#define EXT2_ET_EXTENT_NOT_FOUND -135
#define EXT2_ET_EXTENT_NOT_SUPPORTED -136
#define EXT2_ET_EXTENT_INVALID_LENGTH -137
#define EXT2_ET_IO_CHANNEL_NO_SUPPORT_64 -138
#define EXT2_NO_MTAB_FILE -139
#define EXT2_ET_MAGIC_GENERIC_BITMAP64 -140
#define EXT2_ET_MAGIC_BLOCK_BITMAP64 -141
#define EXT2_ET_MAGIC_INODE_BITMAP64 -142
#define EXT2_ET_CANT_USE_LEGACY_BITMAPS -143
#endif

View File

@ -0,0 +1,71 @@
/*
File: linux/ext2_ext_attr.h
On-disk format of extended attributes for the ext2 filesystem.
(C) 2000 Andreas Gruenbacher, <a.gruenbacher@computer.org>
*/
#ifndef _EXT2_EXT_ATTR_H
#define _EXT2_EXT_ATTR_H
/* Magic value in attribute blocks */
#define EXT2_EXT_ATTR_MAGIC_v1 0xEA010000
#define EXT2_EXT_ATTR_MAGIC 0xEA020000
/* Maximum number of references to one attribute block */
#define EXT2_EXT_ATTR_REFCOUNT_MAX 1024
struct ext2_ext_attr_header {
__u32 h_magic; /* magic number for identification */
__u32 h_refcount; /* reference count */
__u32 h_blocks; /* number of disk blocks used */
__u32 h_hash; /* hash value of all attributes */
__u32 h_reserved[4]; /* zero right now */
};
struct ext2_ext_attr_entry {
__u8 e_name_len; /* length of name */
__u8 e_name_index; /* attribute name index */
__u16 e_value_offs; /* offset in disk block of value */
__u32 e_value_block; /* disk block attribute is stored on (n/i) */
__u32 e_value_size; /* size of attribute value */
__u32 e_hash; /* hash value of name and value */
#if 0
char e_name[0]; /* attribute name */
#endif
};
#define EXT2_EXT_ATTR_PAD_BITS 2
#define EXT2_EXT_ATTR_PAD ((unsigned) 1<<EXT2_EXT_ATTR_PAD_BITS)
#define EXT2_EXT_ATTR_ROUND (EXT2_EXT_ATTR_PAD-1)
#define EXT2_EXT_ATTR_LEN(name_len) \
(((name_len) + EXT2_EXT_ATTR_ROUND + \
sizeof(struct ext2_ext_attr_entry)) & ~EXT2_EXT_ATTR_ROUND)
#define EXT2_EXT_ATTR_NEXT(entry) \
( (struct ext2_ext_attr_entry *)( \
(char *)(entry) + EXT2_EXT_ATTR_LEN((entry)->e_name_len)) )
#define EXT2_EXT_ATTR_SIZE(size) \
(((size) + EXT2_EXT_ATTR_ROUND) & ~EXT2_EXT_ATTR_ROUND)
#define EXT2_EXT_IS_LAST_ENTRY(entry) (*((__u32 *)(entry)) == 0UL)
#define EXT2_EXT_ATTR_NAME(entry) \
(((char *) (entry)) + sizeof(struct ext2_ext_attr_entry))
#define EXT2_XATTR_LEN(name_len) \
(((name_len) + EXT2_EXT_ATTR_ROUND + \
sizeof(struct ext2_xattr_entry)) & ~EXT2_EXT_ATTR_ROUND)
#define EXT2_XATTR_SIZE(size) \
(((size) + EXT2_EXT_ATTR_ROUND) & ~EXT2_EXT_ATTR_ROUND)
#ifdef __KERNEL__
# ifdef CONFIG_EXT2_FS_EXT_ATTR
extern int ext2_get_ext_attr(struct inode *, const char *, char *, size_t, int);
extern int ext2_set_ext_attr(struct inode *, const char *, char *, size_t, int);
extern void ext2_ext_attr_free_inode(struct inode *inode);
extern void ext2_ext_attr_put_super(struct super_block *sb);
extern int ext2_ext_attr_init(void);
extern void ext2_ext_attr_done(void);
# else
# define ext2_get_ext_attr NULL
# define ext2_set_ext_attr NULL
# endif
#endif /* __KERNEL__ */
#endif /* _EXT2_EXT_ATTR_H */

View File

@ -7,10 +7,10 @@ typedef struct _PrivData
void * callback_data;
} PrivDataST;
static int block_iter_callback(ext2_filsys fs, blk_t *blocknr, int blockcnt, void *privateData)
static int block_iter_callback(ext2_filsys fs, blk64_t *blocknr, e2_blkcnt_t blockcnt, blk64_t ref_block, int ref_offset, void *privateData)
{
PrivDataST *priv = (PrivDataST *) privateData;
blk_t block;
blk64_t block;
block = *blocknr;
return priv->append_fragment(priv->callback_data, blockcnt*fs->io->block_size/512, block*fs->io->block_size/512, fs->io->block_size/512);
@ -47,9 +47,10 @@ int _EXT2_get_fragments(const char *in_path, _ext2_frag_append_t append_fragment
priv.callback_data = callback_data;
priv.append_fragment = append_fragment;
ext2fs_block_iterate(vd->fs, ni->ino, 0, NULL, block_iter_callback, &priv);
int ret = ext2fs_block_iterate3(vd->fs, ni->ino, BLOCK_FLAG_DATA_ONLY, NULL, block_iter_callback, &priv);
int ret = priv.append_fragment(callback_data, EXT2_I_SIZE(&ni->ni) >> 9, 0, 0);
if(ret == 0)
ret = priv.append_fragment(callback_data, EXT2_I_SIZE(&ni->ni) >> 9, 0, 0);
ext2UpdateTimes(vd, ni, EXT2_UPDATE_ATIME);

View File

@ -0,0 +1,107 @@
#include "ext2_internal.h"
#include "ext2_frag.h"
#include "mem_allocate.h"
typedef struct _DataBlocks
{
u32 block;
u32 blockcnt;
} DataBlocks;
typedef struct _PrivData
{
DataBlocks * blocks;
u32 blocksCnt;
} PrivDataST;
static int block_iter_callback(ext2_filsys fs, blk_t *blocknr, int blockcnt, void *privateData)
{
PrivDataST *priv = (PrivDataST *) privateData;
if(!priv->blocks)
priv->blocks = (DataBlocks *) mem_alloc(sizeof(DataBlocks));
priv->blocksCnt++;
DataBlocks * tmp = (DataBlocks *) mem_realloc(priv->blocks, priv->blocksCnt*sizeof(DataBlocks));
if(!tmp)
{
free(priv->blocks);
priv->blocks = NULL;
return -1;
}
priv->blocks = tmp;
priv->blocks[priv->blocksCnt-1].block = *blocknr;
priv->blocks[priv->blocksCnt-1].blockcnt = blockcnt;
return 0;
}
int _EXT2_get_fragments(const char *in_path, _ext2_frag_append_t append_fragment, void *callback_data)
{
ext2_inode_t *ni = NULL;
ext2_vd *vd;
vd = ext2GetVolume(in_path);
if(!vd)
{
errno = EXDEV;
return -1;
}
// Get the actual path of the entry
const char * path = ext2RealPath(in_path);
if (!path) {
errno = EINVAL;
return -1;
}
// Find the entry
ni = ext2OpenEntry(vd, path);
if (!ni) {
errno = ENOENT;
return -1;
}
PrivDataST priv;
priv.blocks = NULL;
priv.blocksCnt = 0;
int ret = ext2fs_block_iterate(vd->fs, ni->ino, BLOCK_FLAG_DATA_ONLY, NULL, block_iter_callback, &priv);
if(ret == 0 && priv.blocksCnt > 0)
{
int i = 0;
u32 size = 1;
u32 block_size = vd->fs->io->block_size/512;
int printfs = 30;
for(i = 0; i < priv.blocksCnt-1; ++i)
{
//size = priv.blocks[i+1].blockcnt-priv.blocks[i].blockcnt;
ret = append_fragment(callback_data, priv.blocks[i].blockcnt*block_size, priv.blocks[i].block*block_size, size*block_size);
if(ret)
break;
if(printfs > 0)
{
printfs--;
}
}
if(ret == 0)
ret = append_fragment(callback_data, priv.blocks[i].blockcnt*block_size, priv.blocks[i].block*block_size, block_size);
}
if(ret == 0)
ret = append_fragment(callback_data, EXT2_I_SIZE(&ni->ni) >> 9, 0, 0);
if(priv.blocks)
mem_free(priv.blocks);
ext2UpdateTimes(vd, ni, EXT2_UPDATE_ATIME);
ext2CloseEntry(vd, ni);
return ret;
}

View File

@ -0,0 +1,136 @@
/*
* io.h --- the I/O manager abstraction
*
* Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#ifndef _EXT2FS_EXT2_IO_H
#define _EXT2FS_EXT2_IO_H
#include "ext2fs.h"
/*
* ext2_loff_t is defined here since unix_io.c needs it.
*/
typedef long long ext2_loff_t;
/* llseek.c */
ext2_loff_t ext2fs_llseek (int, ext2_loff_t, int);
typedef struct struct_io_manager *io_manager;
typedef struct struct_io_channel *io_channel;
typedef struct struct_io_stats *io_stats;
#define CHANNEL_FLAGS_WRITETHROUGH 0x01
struct struct_io_channel {
errcode_t magic;
io_manager manager;
char *name;
int block_size;
errcode_t (*read_error)(io_channel channel,
unsigned long block,
int count,
void *data,
size_t size,
int actual_bytes_read,
errcode_t error);
errcode_t (*write_error)(io_channel channel,
unsigned long block,
int count,
const void *data,
size_t size,
int actual_bytes_written,
errcode_t error);
int refcount;
int flags;
long reserved[14];
void *private_data;
void *app_data;
};
struct struct_io_stats {
int num_fields;
int reserved;
unsigned long long bytes_read;
unsigned long long bytes_written;
};
struct struct_io_manager {
errcode_t magic;
const char *name;
errcode_t (*open)(const char *name, int flags, io_channel *channel);
errcode_t (*close)(io_channel channel);
errcode_t (*set_blksize)(io_channel channel, int blksize);
errcode_t (*read_blk)(io_channel channel, unsigned long block,
int count, void *data);
errcode_t (*write_blk)(io_channel channel, unsigned long block,
int count, const void *data);
errcode_t (*flush)(io_channel channel);
errcode_t (*write_byte)(io_channel channel, unsigned long offset,
int count, const void *data);
errcode_t (*set_option)(io_channel channel, const char *option,
const char *arg);
errcode_t (*get_stats)(io_channel channel, io_stats *io_stats);
errcode_t (*read_blk64)(io_channel channel, unsigned long long block,
int count, void *data);
errcode_t (*write_blk64)(io_channel channel, unsigned long long block,
int count, const void *data);
long reserved[16];
};
#define IO_FLAG_RW 0x0001
#define IO_FLAG_EXCLUSIVE 0x0002
#define IO_FLAG_DIRECT_IO 0x0004
/*
* Convenience functions....
*/
#define io_channel_close(c) ((c)->manager->close((c)))
#define io_channel_set_blksize(c,s) ((c)->manager->set_blksize((c),s))
#define io_channel_read_blk(c,b,n,d) ((c)->manager->read_blk((c),b,n,d))
#define io_channel_write_blk(c,b,n,d) ((c)->manager->write_blk((c),b,n,d))
#define io_channel_flush(c) ((c)->manager->flush((c)))
#define io_channel_bumpcount(c) ((c)->refcount++)
/* io_manager.c */
extern errcode_t io_channel_set_options(io_channel channel,
const char *options);
extern errcode_t io_channel_write_byte(io_channel channel,
unsigned long offset,
int count, const void *data);
extern errcode_t io_channel_read_blk64(io_channel channel,
unsigned long long block,
int count, void *data);
extern errcode_t io_channel_write_blk64(io_channel channel,
unsigned long long block,
int count, const void *data);
/* unix_io.c */
extern io_manager unix_io_manager;
/* undo_io.c */
extern io_manager undo_io_manager;
extern errcode_t set_undo_io_backing_manager(io_manager manager);
extern errcode_t set_undo_io_backup_file(char *file_name);
/* test_io.c */
extern io_manager test_io_manager, test_io_backing_manager;
extern void (*test_io_cb_read_blk)
(unsigned long block, int count, errcode_t err);
extern void (*test_io_cb_write_blk)
(unsigned long block, int count, errcode_t err);
extern void (*test_io_cb_read_blk64)
(unsigned long long block, int count, errcode_t err);
extern void (*test_io_cb_write_blk64)
(unsigned long long block, int count, errcode_t err);
extern void (*test_io_cb_set_blksize)
(int blksize, errcode_t err);
#endif /* _EXT2FS_EXT2_IO_H */

View File

@ -0,0 +1,18 @@
/*
* If linux/types.h is already been included, assume it has defined
* everything we need. (cross fingers) Other header files may have
* also defined the types that we need.
*/
#ifndef _EXT2_TYPES_H
#define _EXT2_TYPES_H
typedef unsigned char __u8;
typedef signed char __s8;
typedef unsigned short __u16;
typedef short __s16;
typedef unsigned int __u32;
typedef int __s32;
typedef unsigned long long __u64;
typedef signed long long __s64;
#endif /* _EXT2_TYPES_H */

View File

@ -1356,6 +1356,7 @@ extern __u64 ext2fs_div64_ceil(__u64 a, __u64 b);
#ifndef EXT2_CUSTOM_MEMORY_ROUTINES
#include <string.h>
#include "mem_allocate.h"
/*
* Allocate memory
*/
@ -1363,7 +1364,7 @@ _INLINE_ errcode_t ext2fs_get_mem(unsigned long size, void *ptr)
{
void *pp;
pp = malloc(size);
pp = mem_alloc(size);
if (!pp)
return EXT2_ET_NO_MEMORY;
memcpy(ptr, &pp, sizeof (pp));
@ -1376,9 +1377,9 @@ _INLINE_ errcode_t ext2fs_get_memalign(unsigned long size,
void *pp;
#ifdef HWRVL
pp = memalign(32, size);
pp = mem_align(32, size);
#else
pp = malloc(size);
pp = mem_alloc(size);
#endif
if (!pp)
return EXT2_ET_NO_MEMORY;
@ -1402,7 +1403,7 @@ _INLINE_ errcode_t ext2fs_free_mem(void *ptr)
void *p;
memcpy(&p, ptr, sizeof(p));
free(p);
mem_free(p);
p = 0;
memcpy(ptr, &p, sizeof(p));
return 0;
@ -1419,7 +1420,7 @@ _INLINE_ errcode_t ext2fs_resize_mem(unsigned long EXT2FS_ATTR((unused)) old_siz
/* Use "memcpy" for pointer assignments here to avoid problems
* with C99 strict type aliasing rules. */
memcpy(&p, ptr, sizeof(p));
p = realloc(p, size);
p = mem_realloc(p, size);
if (!p)
return EXT2_ET_NO_MEMORY;
memcpy(ptr, &p, sizeof(p));

View File

@ -0,0 +1,109 @@
/*
* Copyright (c) 2003,2004 Cluster File Systems, Inc, info@clusterfs.com
* Written by Alex Tomas <alex@clusterfs.com>
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#ifndef _LINUX_EXT3_EXTENTS
#define _LINUX_EXT3_EXTENTS
/*
* ext3_inode has i_block array (total 60 bytes)
* first 4 bytes are used to store:
* - tree depth (0 mean there is no tree yet. all extents in the inode)
* - number of alive extents in the inode
*/
/*
* this is extent on-disk structure
* it's used at the bottom of the tree
*/
struct ext3_extent {
__u32 ee_block; /* first logical block extent covers */
__u16 ee_len; /* number of blocks covered by extent */
__u16 ee_start_hi; /* high 16 bits of physical block */
__u32 ee_start; /* low 32 bigs of physical block */
};
/*
* this is index on-disk structure
* it's used at all the levels, but the bottom
*/
struct ext3_extent_idx {
__u32 ei_block; /* index covers logical blocks from 'block' */
__u32 ei_leaf; /* pointer to the physical block of the next *
* level. leaf or next index could bet here */
__u16 ei_leaf_hi; /* high 16 bits of physical block */
__u16 ei_unused;
};
/*
* each block (leaves and indexes), even inode-stored has header
*/
struct ext3_extent_header {
__u16 eh_magic; /* probably will support different formats */
__u16 eh_entries; /* number of valid entries */
__u16 eh_max; /* capacity of store in entries */
__u16 eh_depth; /* has tree real underlaying blocks? */
__u32 eh_generation; /* generation of the tree */
};
#define EXT3_EXT_MAGIC 0xf30a
/*
* array of ext3_ext_path contains path to some extent
* creation/lookup routines use it for traversal/splitting/etc
* truncate uses it to simulate recursive walking
*/
struct ext3_ext_path {
__u32 p_block;
__u16 p_depth;
struct ext3_extent *p_ext;
struct ext3_extent_idx *p_idx;
struct ext3_extent_header *p_hdr;
struct buffer_head *p_bh;
};
/*
* EXT_INIT_MAX_LEN is the maximum number of blocks we can have in an
* initialized extent. This is 2^15 and not (2^16 - 1), since we use the
* MSB of ee_len field in the extent datastructure to signify if this
* particular extent is an initialized extent or an uninitialized (i.e.
* preallocated).
* EXT_UNINIT_MAX_LEN is the maximum number of blocks we can have in an
* uninitialized extent.
* If ee_len is <= 0x8000, it is an initialized extent. Otherwise, it is an
* uninitialized one. In other words, if MSB of ee_len is set, it is an
* uninitialized extent with only one special scenario when ee_len = 0x8000.
* In this case we can not have an uninitialized extent of zero length and
* thus we make it as a special case of initialized extent with 0x8000 length.
* This way we get better extent-to-group alignment for initialized extents.
* Hence, the maximum number of blocks we can have in an *initialized*
* extent is 2^15 (32768) and in an *uninitialized* extent is 2^15-1 (32767).
*/
#define EXT_INIT_MAX_LEN (1UL << 15)
#define EXT_UNINIT_MAX_LEN (EXT_INIT_MAX_LEN - 1)
#define EXT_FIRST_EXTENT(__hdr__) \
((struct ext3_extent *) (((char *) (__hdr__)) + \
sizeof(struct ext3_extent_header)))
#define EXT_FIRST_INDEX(__hdr__) \
((struct ext3_extent_idx *) (((char *) (__hdr__)) + \
sizeof(struct ext3_extent_header)))
#define EXT_HAS_FREE_INDEX(__path__) \
((__path__)->p_hdr->eh_entries < (__path__)->p_hdr->eh_max)
#define EXT_LAST_EXTENT(__hdr__) \
(EXT_FIRST_EXTENT((__hdr__)) + (__hdr__)->eh_entries - 1)
#define EXT_LAST_INDEX(__hdr__) \
(EXT_FIRST_INDEX((__hdr__)) + (__hdr__)->eh_entries - 1)
#define EXT_MAX_EXTENT(__hdr__) \
(EXT_FIRST_EXTENT((__hdr__)) + (__hdr__)->eh_max - 1)
#define EXT_MAX_INDEX(__hdr__) \
(EXT_FIRST_INDEX((__hdr__)) + (__hdr__)->eh_max - 1)
#endif /* _LINUX_EXT3_EXTENTS */

Binary file not shown.

View File

@ -2,25 +2,22 @@
#define _MEM_ALLOCATE_H
#include <malloc.h>
#include "memory/mem2.h"
static inline void* mem_alloc (size_t size) {
return malloc(size);
extern __inline__ void* mem_alloc (size_t size) {
return MEM2_alloc(size);
}
static inline void* mem_realloc (void *p, size_t size) {
return realloc(p, size);
extern __inline__ void* mem_realloc (void *p, size_t size) {
return MEM2_realloc(p, size);
}
static inline void* mem_align (size_t size) {
#ifdef __wii__
return memalign(32, size);
#else
return malloc(size);
#endif
extern __inline__ void* mem_align (size_t a, size_t size) {
return MEM2_alloc(size);
}
static inline void mem_free (void* mem) {
free(mem);
extern __inline__ void mem_free (void* mem) {
MEM2_free(mem);
}
#endif /* _MEM_ALLOCATE_H */

View File

@ -1,432 +1,432 @@
/* Rijndael Block Cipher - rijndael.c
Written by Mike Scott 21st April 1999
mike@compapp.dcu.ie
Permission for free direct or derivative use is granted subject
to compliance with any conditions that the originators of the
algorithm place on its exploitation.
*/
#include <stdio.h>
#include <string.h>
#define u8 unsigned char /* 8 bits */
#define u32 unsigned long /* 32 bits */
#define u64 unsigned long long
/* rotates x one bit to the left */
#define ROTL(x) (((x)>>7)|((x)<<1))
/* Rotates 32-bit word left by 1, 2 or 3 byte */
#define ROTL8(x) (((x)<<8)|((x)>>24))
#define ROTL16(x) (((x)<<16)|((x)>>16))
#define ROTL24(x) (((x)<<24)|((x)>>8))
/* Fixed Data */
static u8 InCo[4] = { 0xB, 0xD, 0x9, 0xE }; /* Inverse Coefficients */
static u8 fbsub[256];
static u8 rbsub[256];
static u8 ptab[256], ltab[256];
static u32 ftable[256];
static u32 rtable[256];
static u32 rco[30];
/* Parameter-dependent data */
int Nk, Nb, Nr;
u8 fi[24], ri[24];
u32 fkey[120];
u32 rkey[120];
static u32 pack(u8 *b)
{ /* pack bytes into a 32-bit Word */
return ((u32 ) b[3] << 24) | ((u32 ) b[2] << 16) | ((u32 ) b[1] << 8) | (u32 ) b[0];
}
static void unpack(u32 a, u8 *b)
{ /* unpack bytes from a word */
b[0] = (u8 ) a;
b[1] = (u8 ) (a >> 8);
b[2] = (u8 ) (a >> 16);
b[3] = (u8 ) (a >> 24);
}
static u8 xtime(u8 a)
{
u8 b;
if (a & 0x80)
b = 0x1B;
else b = 0;
a <<= 1;
a ^= b;
return a;
}
static u8 bmul(u8 x, u8 y)
{ /* x.y= AntiLog(Log(x) + Log(y)) */
if (x && y)
return ptab[(ltab[x] + ltab[y]) % 255];
else return 0;
}
static u32 SubByte(u32 a)
{
u8 b[4];
unpack(a, b);
b[0] = fbsub[b[0]];
b[1] = fbsub[b[1]];
b[2] = fbsub[b[2]];
b[3] = fbsub[b[3]];
return pack(b);
}
static u8 product(u32 x, u32 y)
{ /* dot product of two 4-byte arrays */
u8 xb[4], yb[4];
unpack(x, xb);
unpack(y, yb);
return bmul(xb[0], yb[0]) ^ bmul(xb[1], yb[1]) ^ bmul(xb[2], yb[2]) ^ bmul(xb[3], yb[3]);
}
static u32 InvMixCol(u32 x)
{ /* matrix Multiplication */
u32 y, m;
u8 b[4];
m = pack(InCo);
b[3] = product(m, x);
m = ROTL24( m );
b[2] = product(m, x);
m = ROTL24( m );
b[1] = product(m, x);
m = ROTL24( m );
b[0] = product(m, x);
y = pack(b);
return y;
}
u8 ByteSub(u8 x)
{
u8 y = ptab[255 - ltab[x]]; /* multiplicative inverse */
x = y;
x = ROTL( x );
y ^= x;
x = ROTL( x );
y ^= x;
x = ROTL( x );
y ^= x;
x = ROTL( x );
y ^= x;
y ^= 0x63;
return y;
}
void gentables(void)
{ /* generate tables */
int i;
u8 y, b[4];
/* use 3 as primitive root to generate power and log tables */
ltab[0] = 0;
ptab[0] = 1;
ltab[1] = 0;
ptab[1] = 3;
ltab[3] = 1;
for (i = 2; i < 256; i++)
{
ptab[i] = ptab[i - 1] ^ xtime(ptab[i - 1]);
ltab[ptab[i]] = i;
}
/* affine transformation:- each bit is xored with itself shifted one bit */
fbsub[0] = 0x63;
rbsub[0x63] = 0;
for (i = 1; i < 256; i++)
{
y = ByteSub((u8 ) i);
fbsub[i] = y;
rbsub[y] = i;
}
for (i = 0, y = 1; i < 30; i++)
{
rco[i] = y;
y = xtime(y);
}
/* calculate forward and reverse tables */
for (i = 0; i < 256; i++)
{
y = fbsub[i];
b[3] = y ^ xtime(y);
b[2] = y;
b[1] = y;
b[0] = xtime(y);
ftable[i] = pack(b);
y = rbsub[i];
b[3] = bmul(InCo[0], y);
b[2] = bmul(InCo[1], y);
b[1] = bmul(InCo[2], y);
b[0] = bmul(InCo[3], y);
rtable[i] = pack(b);
}
}
void gkey(int nb, int nk, char *key)
{ /* blocksize=32*nb bits. Key=32*nk bits */
/* currently nb,bk = 4, 6 or 8 */
/* key comes as 4*Nk bytes */
/* Key Scheduler. Create expanded encryption key */
int i, j, k, m, N;
int C1, C2, C3;
u32 CipherKey[8];
Nb = nb;
Nk = nk;
/* Nr is number of rounds */
if (Nb >= Nk)
Nr = 6 + Nb;
else Nr = 6 + Nk;
C1 = 1;
if (Nb < 8)
{
C2 = 2;
C3 = 3;
}
else
{
C2 = 3;
C3 = 4;
}
/* pre-calculate forward and reverse increments */
for (m = j = 0; j < nb; j++, m += 3)
{
fi[m] = (j + C1) % nb;
fi[m + 1] = (j + C2) % nb;
fi[m + 2] = (j + C3) % nb;
ri[m] = (nb + j - C1) % nb;
ri[m + 1] = (nb + j - C2) % nb;
ri[m + 2] = (nb + j - C3) % nb;
}
N = Nb * (Nr + 1);
for (i = j = 0; i < Nk; i++, j += 4)
{
CipherKey[i] = pack((u8 *) &key[j]);
}
for (i = 0; i < Nk; i++)
fkey[i] = CipherKey[i];
for (j = Nk, k = 0; j < N; j += Nk, k++)
{
fkey[j] = fkey[j - Nk] ^ SubByte(ROTL24( fkey[j-1] )) ^ rco[k];
if (Nk <= 6)
{
for (i = 1; i < Nk && (i + j) < N; i++)
fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1];
}
else
{
for (i = 1; i < 4 && (i + j) < N; i++)
fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1];
if ((j + 4) < N) fkey[j + 4] = fkey[j + 4 - Nk] ^ SubByte(fkey[j + 3]);
for (i = 5; i < Nk && (i + j) < N; i++)
fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1];
}
}
/* now for the expanded decrypt key in reverse order */
for (j = 0; j < Nb; j++)
rkey[j + N - Nb] = fkey[j];
for (i = Nb; i < N - Nb; i += Nb)
{
k = N - Nb - i;
for (j = 0; j < Nb; j++)
rkey[k + j] = InvMixCol(fkey[i + j]);
}
for (j = N - Nb; j < N; j++)
rkey[j - N + Nb] = fkey[j];
}
/* There is an obvious time/space trade-off possible here. *
* Instead of just one ftable[], I could have 4, the other *
* 3 pre-rotated to save the ROTL8, ROTL16 and ROTL24 overhead */
void encrypt(char *buff)
{
int i, j, k, m;
u32 a[8], b[8], *x, *y, *t;
for (i = j = 0; i < Nb; i++, j += 4)
{
a[i] = pack((u8 *) &buff[j]);
a[i] ^= fkey[i];
}
k = Nb;
x = a;
y = b;
/* State alternates between a and b */
for (i = 1; i < Nr; i++)
{ /* Nr is number of rounds. May be odd. */
/* if Nb is fixed - unroll this next
loop and hard-code in the values of fi[] */
for (m = j = 0; j < Nb; j++, m += 3)
{ /* deal with each 32-bit element of the State */
/* This is the time-critical bit */
y[j] = fkey[k++] ^ ftable[(u8 ) x[j]] ^ ROTL8( ftable[( u8 )( x[fi[m]] >> 8 )] )
^ ROTL16( ftable[( u8 )( x[fi[m+1]] >> 16 )] ) ^ ROTL24( ftable[x[fi[m+2]] >> 24] );
}
t = x;
x = y;
y = t; /* swap pointers */
}
/* Last Round - unroll if possible */
for (m = j = 0; j < Nb; j++, m += 3)
{
y[j] = fkey[k++] ^ (u32 ) fbsub[(u8 ) x[j]] ^ ROTL8( ( u32 )fbsub[( u8 )( x[fi[m]] >> 8 )] )
^ ROTL16( ( u32 )fbsub[( u8 )( x[fi[m+1]] >> 16 )] ) ^ ROTL24( ( u32 )fbsub[x[fi[m+2]] >> 24] );
}
for (i = j = 0; i < Nb; i++, j += 4)
{
unpack(y[i], (u8 *) &buff[j]);
x[i] = y[i] = 0; /* clean up stack */
}
return;
}
void decrypt(char *buff)
{
int i, j, k, m;
u32 a[8], b[8], *x, *y, *t;
for (i = j = 0; i < Nb; i++, j += 4)
{
a[i] = pack((u8 *) &buff[j]);
a[i] ^= rkey[i];
}
k = Nb;
x = a;
y = b;
/* State alternates between a and b */
for (i = 1; i < Nr; i++)
{ /* Nr is number of rounds. May be odd. */
/* if Nb is fixed - unroll this next
loop and hard-code in the values of ri[] */
for (m = j = 0; j < Nb; j++, m += 3)
{ /* This is the time-critical bit */
y[j] = rkey[k++] ^ rtable[(u8 ) x[j]] ^ ROTL8( rtable[( u8 )( x[ri[m]] >> 8 )] )
^ ROTL16( rtable[( u8 )( x[ri[m+1]] >> 16 )] ) ^ ROTL24( rtable[x[ri[m+2]] >> 24] );
}
t = x;
x = y;
y = t; /* swap pointers */
}
/* Last Round - unroll if possible */
for (m = j = 0; j < Nb; j++, m += 3)
{
y[j] = rkey[k++] ^ (u32 ) rbsub[(u8 ) x[j]] ^ ROTL8( ( u32 )rbsub[( u8 )( x[ri[m]] >> 8 )] )
^ ROTL16( ( u32 )rbsub[( u8 )( x[ri[m+1]] >> 16 )] ) ^ ROTL24( ( u32 )rbsub[x[ri[m+2]] >> 24] );
}
for (i = j = 0; i < Nb; i++, j += 4)
{
unpack(y[i], (u8 *) &buff[j]);
x[i] = y[i] = 0; /* clean up stack */
}
return;
}
void aes_set_key(u8 *key)
{
gentables();
gkey(4, 4, (char*) key);
}
// CBC mode decryption
void aes_decrypt(u8 *iv, u8 *inbuf, u8 *outbuf, unsigned long long len)
{
u8 block[16];
unsigned int blockno = 0, i;
//printf("aes_decrypt(%p, %p, %p, %lld)\n", iv, inbuf, outbuf, len);
for (blockno = 0; blockno <= (len / sizeof(block)); blockno++)
{
unsigned int fraction;
if (blockno == (len / sizeof(block))) // last block
{
fraction = len % sizeof(block);
if (fraction == 0) break;
memset(block, 0, sizeof(block));
}
else fraction = 16;
// debug_printf("block %d: fraction = %d\n", blockno, fraction);
memcpy(block, inbuf + blockno * sizeof(block), fraction);
decrypt((char*) block);
u8 *ctext_ptr;
if (blockno == 0)
ctext_ptr = iv;
else ctext_ptr = inbuf + (blockno - 1) * sizeof(block);
for (i = 0; i < fraction; i++)
outbuf[blockno * sizeof(block) + i] = ctext_ptr[i] ^ block[i];
// debug_printf("Block %d output: ", blockno);
// hexdump(outbuf + blockno*sizeof(block), 16);
}
}
// CBC mode encryption
void aes_encrypt(u8 *iv, u8 *inbuf, u8 *outbuf, unsigned long long len)
{
u8 block[16];
unsigned int blockno = 0, i;
// debug_printf("aes_decrypt(%p, %p, %p, %lld)\n", iv, inbuf, outbuf, len);
for (blockno = 0; blockno <= (len / sizeof(block)); blockno++)
{
unsigned int fraction;
if (blockno == (len / sizeof(block))) // last block
{
fraction = len % sizeof(block);
if (fraction == 0) break;
memset(block, 0, sizeof(block));
}
else fraction = 16;
// debug_printf("block %d: fraction = %d\n", blockno, fraction);
memcpy(block, inbuf + blockno * sizeof(block), fraction);
for (i = 0; i < fraction; i++)
block[i] = inbuf[blockno * sizeof(block) + i] ^ iv[i];
encrypt((char*) block);
memcpy(iv, block, sizeof(block));
memcpy(outbuf + blockno * sizeof(block), block, sizeof(block));
// debug_printf("Block %d output: ", blockno);
// hexdump(outbuf + blockno*sizeof(block), 16);
}
}
/* Rijndael Block Cipher - rijndael.c
Written by Mike Scott 21st April 1999
mike@compapp.dcu.ie
Permission for free direct or derivative use is granted subject
to compliance with any conditions that the originators of the
algorithm place on its exploitation.
*/
#include <stdio.h>
#include <string.h>
#define u8 unsigned char /* 8 bits */
#define u32 unsigned long /* 32 bits */
#define u64 unsigned long long
/* rotates x one bit to the left */
#define ROTL(x) (((x)>>7)|((x)<<1))
/* Rotates 32-bit word left by 1, 2 or 3 byte */
#define ROTL8(x) (((x)<<8)|((x)>>24))
#define ROTL16(x) (((x)<<16)|((x)>>16))
#define ROTL24(x) (((x)<<24)|((x)>>8))
/* Fixed Data */
static u8 InCo[4] = { 0xB, 0xD, 0x9, 0xE }; /* Inverse Coefficients */
static u8 fbsub[256];
static u8 rbsub[256];
static u8 ptab[256], ltab[256];
static u32 ftable[256];
static u32 rtable[256];
static u32 rco[30];
/* Parameter-dependent data */
int Nk, Nb, Nr;
u8 fi[24], ri[24];
u32 fkey[120];
u32 rkey[120];
static u32 pack(u8 *b)
{ /* pack bytes into a 32-bit Word */
return ((u32 ) b[3] << 24) | ((u32 ) b[2] << 16) | ((u32 ) b[1] << 8) | (u32 ) b[0];
}
static void unpack(u32 a, u8 *b)
{ /* unpack bytes from a word */
b[0] = (u8 ) a;
b[1] = (u8 ) (a >> 8);
b[2] = (u8 ) (a >> 16);
b[3] = (u8 ) (a >> 24);
}
static u8 xtime(u8 a)
{
u8 b;
if (a & 0x80)
b = 0x1B;
else b = 0;
a <<= 1;
a ^= b;
return a;
}
static u8 bmul(u8 x, u8 y)
{ /* x.y= AntiLog(Log(x) + Log(y)) */
if (x && y)
return ptab[(ltab[x] + ltab[y]) % 255];
else return 0;
}
static u32 SubByte(u32 a)
{
u8 b[4];
unpack(a, b);
b[0] = fbsub[b[0]];
b[1] = fbsub[b[1]];
b[2] = fbsub[b[2]];
b[3] = fbsub[b[3]];
return pack(b);
}
static u8 product(u32 x, u32 y)
{ /* dot product of two 4-byte arrays */
u8 xb[4], yb[4];
unpack(x, xb);
unpack(y, yb);
return bmul(xb[0], yb[0]) ^ bmul(xb[1], yb[1]) ^ bmul(xb[2], yb[2]) ^ bmul(xb[3], yb[3]);
}
static u32 InvMixCol(u32 x)
{ /* matrix Multiplication */
u32 y, m;
u8 b[4];
m = pack(InCo);
b[3] = product(m, x);
m = ROTL24( m );
b[2] = product(m, x);
m = ROTL24( m );
b[1] = product(m, x);
m = ROTL24( m );
b[0] = product(m, x);
y = pack(b);
return y;
}
u8 ByteSub(u8 x)
{
u8 y = ptab[255 - ltab[x]]; /* multiplicative inverse */
x = y;
x = ROTL( x );
y ^= x;
x = ROTL( x );
y ^= x;
x = ROTL( x );
y ^= x;
x = ROTL( x );
y ^= x;
y ^= 0x63;
return y;
}
void gentables(void)
{ /* generate tables */
int i;
u8 y, b[4];
/* use 3 as primitive root to generate power and log tables */
ltab[0] = 0;
ptab[0] = 1;
ltab[1] = 0;
ptab[1] = 3;
ltab[3] = 1;
for (i = 2; i < 256; i++)
{
ptab[i] = ptab[i - 1] ^ xtime(ptab[i - 1]);
ltab[ptab[i]] = i;
}
/* affine transformation:- each bit is xored with itself shifted one bit */
fbsub[0] = 0x63;
rbsub[0x63] = 0;
for (i = 1; i < 256; i++)
{
y = ByteSub((u8 ) i);
fbsub[i] = y;
rbsub[y] = i;
}
for (i = 0, y = 1; i < 30; i++)
{
rco[i] = y;
y = xtime(y);
}
/* calculate forward and reverse tables */
for (i = 0; i < 256; i++)
{
y = fbsub[i];
b[3] = y ^ xtime(y);
b[2] = y;
b[1] = y;
b[0] = xtime(y);
ftable[i] = pack(b);
y = rbsub[i];
b[3] = bmul(InCo[0], y);
b[2] = bmul(InCo[1], y);
b[1] = bmul(InCo[2], y);
b[0] = bmul(InCo[3], y);
rtable[i] = pack(b);
}
}
void gkey(int nb, int nk, char *key)
{ /* blocksize=32*nb bits. Key=32*nk bits */
/* currently nb,bk = 4, 6 or 8 */
/* key comes as 4*Nk bytes */
/* Key Scheduler. Create expanded encryption key */
int i, j, k, m, N;
int C1, C2, C3;
u32 CipherKey[8];
Nb = nb;
Nk = nk;
/* Nr is number of rounds */
if (Nb >= Nk)
Nr = 6 + Nb;
else Nr = 6 + Nk;
C1 = 1;
if (Nb < 8)
{
C2 = 2;
C3 = 3;
}
else
{
C2 = 3;
C3 = 4;
}
/* pre-calculate forward and reverse increments */
for (m = j = 0; j < nb; j++, m += 3)
{
fi[m] = (j + C1) % nb;
fi[m + 1] = (j + C2) % nb;
fi[m + 2] = (j + C3) % nb;
ri[m] = (nb + j - C1) % nb;
ri[m + 1] = (nb + j - C2) % nb;
ri[m + 2] = (nb + j - C3) % nb;
}
N = Nb * (Nr + 1);
for (i = j = 0; i < Nk; i++, j += 4)
{
CipherKey[i] = pack((u8 *) &key[j]);
}
for (i = 0; i < Nk; i++)
fkey[i] = CipherKey[i];
for (j = Nk, k = 0; j < N; j += Nk, k++)
{
fkey[j] = fkey[j - Nk] ^ SubByte(ROTL24( fkey[j-1] )) ^ rco[k];
if (Nk <= 6)
{
for (i = 1; i < Nk && (i + j) < N; i++)
fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1];
}
else
{
for (i = 1; i < 4 && (i + j) < N; i++)
fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1];
if ((j + 4) < N) fkey[j + 4] = fkey[j + 4 - Nk] ^ SubByte(fkey[j + 3]);
for (i = 5; i < Nk && (i + j) < N; i++)
fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1];
}
}
/* now for the expanded decrypt key in reverse order */
for (j = 0; j < Nb; j++)
rkey[j + N - Nb] = fkey[j];
for (i = Nb; i < N - Nb; i += Nb)
{
k = N - Nb - i;
for (j = 0; j < Nb; j++)
rkey[k + j] = InvMixCol(fkey[i + j]);
}
for (j = N - Nb; j < N; j++)
rkey[j - N + Nb] = fkey[j];
}
/* There is an obvious time/space trade-off possible here. *
* Instead of just one ftable[], I could have 4, the other *
* 3 pre-rotated to save the ROTL8, ROTL16 and ROTL24 overhead */
void encrypt(char *buff)
{
int i, j, k, m;
u32 a[8], b[8], *x, *y, *t;
for (i = j = 0; i < Nb; i++, j += 4)
{
a[i] = pack((u8 *) &buff[j]);
a[i] ^= fkey[i];
}
k = Nb;
x = a;
y = b;
/* State alternates between a and b */
for (i = 1; i < Nr; i++)
{ /* Nr is number of rounds. May be odd. */
/* if Nb is fixed - unroll this next
loop and hard-code in the values of fi[] */
for (m = j = 0; j < Nb; j++, m += 3)
{ /* deal with each 32-bit element of the State */
/* This is the time-critical bit */
y[j] = fkey[k++] ^ ftable[(u8 ) x[j]] ^ ROTL8( ftable[( u8 )( x[fi[m]] >> 8 )] )
^ ROTL16( ftable[( u8 )( x[fi[m+1]] >> 16 )] ) ^ ROTL24( ftable[x[fi[m+2]] >> 24] );
}
t = x;
x = y;
y = t; /* swap pointers */
}
/* Last Round - unroll if possible */
for (m = j = 0; j < Nb; j++, m += 3)
{
y[j] = fkey[k++] ^ (u32 ) fbsub[(u8 ) x[j]] ^ ROTL8( ( u32 )fbsub[( u8 )( x[fi[m]] >> 8 )] )
^ ROTL16( ( u32 )fbsub[( u8 )( x[fi[m+1]] >> 16 )] ) ^ ROTL24( ( u32 )fbsub[x[fi[m+2]] >> 24] );
}
for (i = j = 0; i < Nb; i++, j += 4)
{
unpack(y[i], (u8 *) &buff[j]);
x[i] = y[i] = 0; /* clean up stack */
}
return;
}
void decrypt(char *buff)
{
int i, j, k, m;
u32 a[8], b[8], *x, *y, *t;
for (i = j = 0; i < Nb; i++, j += 4)
{
a[i] = pack((u8 *) &buff[j]);
a[i] ^= rkey[i];
}
k = Nb;
x = a;
y = b;
/* State alternates between a and b */
for (i = 1; i < Nr; i++)
{ /* Nr is number of rounds. May be odd. */
/* if Nb is fixed - unroll this next
loop and hard-code in the values of ri[] */
for (m = j = 0; j < Nb; j++, m += 3)
{ /* This is the time-critical bit */
y[j] = rkey[k++] ^ rtable[(u8 ) x[j]] ^ ROTL8( rtable[( u8 )( x[ri[m]] >> 8 )] )
^ ROTL16( rtable[( u8 )( x[ri[m+1]] >> 16 )] ) ^ ROTL24( rtable[x[ri[m+2]] >> 24] );
}
t = x;
x = y;
y = t; /* swap pointers */
}
/* Last Round - unroll if possible */
for (m = j = 0; j < Nb; j++, m += 3)
{
y[j] = rkey[k++] ^ (u32 ) rbsub[(u8 ) x[j]] ^ ROTL8( ( u32 )rbsub[( u8 )( x[ri[m]] >> 8 )] )
^ ROTL16( ( u32 )rbsub[( u8 )( x[ri[m+1]] >> 16 )] ) ^ ROTL24( ( u32 )rbsub[x[ri[m+2]] >> 24] );
}
for (i = j = 0; i < Nb; i++, j += 4)
{
unpack(y[i], (u8 *) &buff[j]);
x[i] = y[i] = 0; /* clean up stack */
}
return;
}
void aes_set_key(u8 *key)
{
gentables();
gkey(4, 4, (char*) key);
}
// CBC mode decryption
void aes_decrypt(u8 *iv, u8 *inbuf, u8 *outbuf, unsigned long long len)
{
u8 block[16];
unsigned int blockno = 0, i;
//printf("aes_decrypt(%p, %p, %p, %lld)\n", iv, inbuf, outbuf, len);
for (blockno = 0; blockno <= (len / sizeof(block)); blockno++)
{
unsigned int fraction;
if (blockno == (len / sizeof(block))) // last block
{
fraction = len % sizeof(block);
if (fraction == 0) break;
memset(block, 0, sizeof(block));
}
else fraction = 16;
// debug_printf("block %d: fraction = %d\n", blockno, fraction);
memcpy(block, inbuf + blockno * sizeof(block), fraction);
decrypt((char*) block);
u8 *ctext_ptr;
if (blockno == 0)
ctext_ptr = iv;
else ctext_ptr = inbuf + (blockno - 1) * sizeof(block);
for (i = 0; i < fraction; i++)
outbuf[blockno * sizeof(block) + i] = ctext_ptr[i] ^ block[i];
// debug_printf("Block %d output: ", blockno);
// hexdump(outbuf + blockno*sizeof(block), 16);
}
}
// CBC mode encryption
void aes_encrypt(u8 *iv, u8 *inbuf, u8 *outbuf, unsigned long long len)
{
u8 block[16];
unsigned int blockno = 0, i;
// debug_printf("aes_decrypt(%p, %p, %p, %lld)\n", iv, inbuf, outbuf, len);
for (blockno = 0; blockno <= (len / sizeof(block)); blockno++)
{
unsigned int fraction;
if (blockno == (len / sizeof(block))) // last block
{
fraction = len % sizeof(block);
if (fraction == 0) break;
memset(block, 0, sizeof(block));
}
else fraction = 16;
// debug_printf("block %d: fraction = %d\n", blockno, fraction);
memcpy(block, inbuf + blockno * sizeof(block), fraction);
for (i = 0; i < fraction; i++)
block[i] = inbuf[blockno * sizeof(block) + i] ^ iv[i];
encrypt((char*) block);
memcpy(iv, block, sizeof(block));
memcpy(outbuf + blockno * sizeof(block), block, sizeof(block));
// debug_printf("Block %d output: ", blockno);
// hexdump(outbuf + blockno*sizeof(block), 16);
}
}

View File

@ -1,68 +1,68 @@
#ifndef WIIDISC_H
#define WIIDISC_H
#include <stdio.h>
#include "libwbfs_os.h" // this file is provided by the project wanting to compile libwbfs and wiidisc
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#if 0 //removes extra automatic indentation by editors
}
#endif
// callback definition. Return 1 on fatal error (callback is supposed to make retries until no hopes..)
// offset points 32bit words, count counts bytes
typedef int (*read_wiidisc_callback_t)(void*fp, u32 offset, u32 count, void*iobuf);
typedef enum
{
UPDATE_PARTITION_TYPE = 0, GAME_PARTITION_TYPE, OTHER_PARTITION_TYPE,
// value in between selects partition types of that value
ALL_PARTITIONS = 0xffffffff - 3,
REMOVE_UPDATE_PARTITION, // keeps game + channel installers
ONLY_GAME_PARTITION,
} partition_selector_t;
typedef struct wiidisc_s
{
read_wiidisc_callback_t read;
void *fp;
u8 *sector_usage_table;
// everything points 32bit words.
u32 disc_raw_offset;
u32 partition_raw_offset;
u32 partition_data_offset;
u32 partition_data_size;
u32 partition_block;
u8 *tmp_buffer;
u8 *tmp_buffer2;
u8 disc_key[16];
int dont_decrypt;
partition_selector_t part_sel;
char *extract_pathname;
u8 *extracted_buffer;
int extracted_size;
} wiidisc_t;
wiidisc_t *wd_open_disc(read_wiidisc_callback_t read, void*fp);
void wd_close_disc(wiidisc_t *);
// returns a buffer allocated with wbfs_ioalloc() or NULL if not found of alloc error
u8 * wd_extract_file(wiidisc_t *d, partition_selector_t partition_type, char *pathname);
void wd_build_disc_usage(wiidisc_t *d, partition_selector_t selector, u8* usage_table);
// effectively remove not copied partition from the partition table.
void wd_fix_partition_table(wiidisc_t *d, partition_selector_t selector, u8* partition_table);
u8 * wd_get_fst(wiidisc_t *d, partition_selector_t partition_type);
#if 0
{
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
#ifndef WIIDISC_H
#define WIIDISC_H
#include <stdio.h>
#include "libwbfs_os.h" // this file is provided by the project wanting to compile libwbfs and wiidisc
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#if 0 //removes extra automatic indentation by editors
}
#endif
// callback definition. Return 1 on fatal error (callback is supposed to make retries until no hopes..)
// offset points 32bit words, count counts bytes
typedef int (*read_wiidisc_callback_t)(void*fp, u32 offset, u32 count, void*iobuf);
typedef enum
{
UPDATE_PARTITION_TYPE = 0, GAME_PARTITION_TYPE, OTHER_PARTITION_TYPE,
// value in between selects partition types of that value
ALL_PARTITIONS = 0xffffffff - 3,
REMOVE_UPDATE_PARTITION, // keeps game + channel installers
ONLY_GAME_PARTITION,
} partition_selector_t;
typedef struct wiidisc_s
{
read_wiidisc_callback_t read;
void *fp;
u8 *sector_usage_table;
// everything points 32bit words.
u32 disc_raw_offset;
u32 partition_raw_offset;
u32 partition_data_offset;
u32 partition_data_size;
u32 partition_block;
u8 *tmp_buffer;
u8 *tmp_buffer2;
u8 disc_key[16];
int dont_decrypt;
partition_selector_t part_sel;
char *extract_pathname;
u8 *extracted_buffer;
int extracted_size;
} wiidisc_t;
wiidisc_t *wd_open_disc(read_wiidisc_callback_t read, void*fp);
void wd_close_disc(wiidisc_t *);
// returns a buffer allocated with wbfs_ioalloc() or NULL if not found of alloc error
u8 * wd_extract_file(wiidisc_t *d, partition_selector_t partition_type, char *pathname);
void wd_build_disc_usage(wiidisc_t *d, partition_selector_t selector, u8* usage_table);
// effectively remove not copied partition from the partition table.
void wd_fix_partition_table(wiidisc_t *d, partition_selector_t selector, u8* partition_table);
u8 * wd_get_fst(wiidisc_t *d, partition_selector_t partition_type);
#if 0
{
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

View File

@ -968,8 +968,6 @@ class GuiNumpad: public GuiWindow
GuiImageData * keyTextbox;
GuiImageData * keyMedium;
GuiImageData * keyMediumOver;
GuiSound * keySoundOver;
GuiSound * keySoundClick;
GuiTrigger * trigA;
GuiTrigger * trigB;
};
@ -1026,8 +1024,6 @@ class GuiOptionBrowser: public GuiElement
GuiImageData * scrollbarBox;
GuiImageData * scrollbarBoxOver;
GuiSound * btnSoundOver;
GuiSound * btnSoundClick;
GuiTrigger * trigA;
GuiTrigger * trigB;
GuiTrigger * trigHeldA;
@ -1088,8 +1084,6 @@ class GuiFileBrowser: public GuiElement
GuiImageData * arrowUp;
GuiImageData * scrollbarBox;
GuiSound * btnSoundOver;
GuiSound * btnSoundClick;
GuiTrigger * trigA;
GuiTrigger * trigHeldA;
};

File diff suppressed because it is too large Load Diff

View File

@ -27,15 +27,15 @@ int txtscroll = 0;
/**
* Constructor for the GuiGameBrowser class.
*/
GuiGameBrowser::GuiGameBrowser(int w, int h, int selected, int offset)
GuiGameBrowser::GuiGameBrowser(int w, int h, int selectedGame)
{
width = w;
height = h;
pagesize = Theme.pagesize;
scrollbaron = (gameList.size() > pagesize) ? 1 : 0;
selectable = true;
listOffset = MAX( 0, MIN( offset, ( gameList.size() - pagesize ) ) );
selectedItem = selected - offset;
listOffset = selectedGame - (selectedGame % pagesize);
selectedItem = selectedGame - listOffset;
focus = 1; // allow focus
trigA = new GuiTrigger;

View File

@ -7,7 +7,7 @@
class GuiGameBrowser: public GuiElement
{
public:
GuiGameBrowser(int w, int h, int selected = 0, int offset = 0);
GuiGameBrowser(int w, int h, int selectedGame = 0);
~GuiGameBrowser();
int FindMenuItem(int c, int d);
int GetClickedOption();

View File

@ -45,13 +45,13 @@ static GuiImageData *GameCarouselLoadCoverImage(void * Arg)
/**
* Constructor for the GuiGameCarousel class.
*/
GuiGameCarousel::GuiGameCarousel(int w, int h, const char *themePath, const u8 *imagebg, int imagebgsize, int selected, int offset) :
GuiGameCarousel::GuiGameCarousel(int w, int h, const char *themePath, const u8 *imagebg, int imagebgsize, int selectedGame) :
noCover(nocover_png, nocover_png_size)
{
width = w;
height = h;
pagesize = (gameList.size() < 11) ? gameList.size() : 11;
listOffset = 0;
listOffset = (selectedGame >= 0 && selectedGame < gameList.size()) ? selectedGame : 0;
selectable = true;
selectedItem = -1;
focus = 1; // allow focus

View File

@ -7,7 +7,7 @@ class GuiImageAsync;
class GuiGameCarousel: public GuiElement
{
public:
GuiGameCarousel(int w, int h, const char *themePath, const u8 *imagebg, int imagebgsize, int selected = 0, int offset = 0);
GuiGameCarousel(int w, int h, const char *themePath, const u8 *imagebg, int imagebgsize, int selectedGame = 0);
~GuiGameCarousel();
int FindMenuItem(int c, int d);
int GetClickedOption();

View File

@ -201,7 +201,7 @@ static GuiImageData *GameGridLoadCoverImage(void * Arg)
/**
* Constructor for the GuiGamegrid class.
*/
GuiGameGrid::GuiGameGrid(int w, int h, const char *themePath, const u8 *imagebg, int selected, int offset) :
GuiGameGrid::GuiGameGrid(int w, int h, const char *themePath, const u8 *imagebg, int selectedGame) :
noCover(nocoverFlat_png, nocoverFlat_png_size)
{
width = w;

View File

@ -7,7 +7,7 @@ class GuiImageAsync;
class GuiGameGrid: public GuiElement
{
public:
GuiGameGrid(int w, int h, const char *themePath, const u8 *imagebg, int selected = 0, int offset = 0);
GuiGameGrid(int w, int h, const char *themePath, const u8 *imagebg, int selectedGame = 0);
~GuiGameGrid();
int FindMenuItem(int c, int d);
int GetClickedOption();

View File

@ -61,8 +61,7 @@ GuiNumpad::GuiNumpad(char * t, u32 max)
keyBackText = new GuiText("Back", 20, ( GXColor )
{ 0, 0, 0, 0xff});
keyBack = new GuiButton(keyBackImg, keyBackOverImg, ALIGN_CENTRE, ALIGN_MIDDLE, 90, 80, trigA, keySoundOver,
keySoundClick, 1);
keyBack = new GuiButton(keyBackImg, keyBackOverImg, ALIGN_CENTRE, ALIGN_MIDDLE, 90, 80, trigA, btnSoundOver, btnSoundClick, 1);
keyBack->SetLabel(keyBackText);
keyBack->SetTrigger(trigB);
this->Append(keyBack);
@ -71,8 +70,7 @@ GuiNumpad::GuiNumpad(char * t, u32 max)
keyClearOverImg = new GuiImage(keyMediumOver);
keyClearText = new GuiText("Clear", 20, ( GXColor )
{ 0, 0, 0, 0xff});
keyClear = new GuiButton(keyClearImg, keyClearOverImg, ALIGN_CENTRE, ALIGN_MIDDLE, -90, 80, trigA, keySoundOver,
keySoundClick, 1);
keyClear = new GuiButton(keyClearImg, keyClearOverImg, ALIGN_CENTRE, ALIGN_MIDDLE, -90, 80, trigA, btnSoundOver, btnSoundClick, 1);
keyClear->SetLabel(keyClearText);
this->Append(keyClear);
@ -92,7 +90,7 @@ GuiNumpad::GuiNumpad(char * t, u32 max)
keyTxt[i]->SetAlignment(ALIGN_CENTRE, ALIGN_BOTTOM);
keyTxt[i]->SetPosition(0, -10);
keyBtn[i] = new GuiButton(keyImg[i], keyImgOver[i], ALIGN_CENTRE, ALIGN_MIDDLE, -90 + 90 * col, -70 + 50
* row, trigA, keySoundOver, keySoundClick, 1);
* row, trigA, btnSoundOver, btnSoundClick, 1);
keyBtn[i]->SetLabel(keyTxt[i]);
this->Append(keyBtn[i]);

View File

@ -1,3 +1,5 @@
#ifndef GUI_SEARCHBAR_H_
#define GUI_SEARCHBAR_H_
#include "gui.h"
class cSearchButton;
@ -32,3 +34,5 @@ class GuiSearchBar: public GuiWindow
GuiTrigger trig;
};
#endif

View File

@ -1,100 +1,100 @@
//functions for manipulating the HBC stub by giantpune
#include <string.h>
#include <ogcsys.h>
#include <malloc.h>
#include <stdio.h>
#include "lstub.h"
#include "filelist.h"
#include "gecko.h"
#include "wad/nandtitle.h"
static char* determineStubTIDLocation()
{
u32 *stubID = (u32*) 0x80001818;
//HBC stub 1.0.6 and lower, and stub.bin
if (stubID[0] == 0x480004c1 && stubID[1] == 0x480004f5)
return (char *) 0x800024C6;
//HBC stub changed @ version 1.0.7. this file was last updated for HBC 1.0.8
else if (stubID[0] == 0x48000859 && stubID[1] == 0x4800088d) return (char *) 0x8000286A;
//hexdump( stubID, 0x20 );
return NULL;
}
s32 Set_Stub(u64 reqID)
{
if (NandTitles.IndexOf(reqID) < 0) return WII_EINSTALL;
char *stub = determineStubTIDLocation();
if (!stub) return -68;
stub[0] = TITLE_7( reqID );
stub[1] = TITLE_6( reqID );
stub[8] = TITLE_5( reqID );
stub[9] = TITLE_4( reqID );
stub[4] = TITLE_3( reqID );
stub[5] = TITLE_2( reqID );
stub[12] = TITLE_1( reqID );
stub[13] = ((u8) (reqID));
DCFlushRange(stub, 0x10);
return 1;
}
s32 Set_Stub_Split(u32 type, const char* reqID)
{
char tmp[4];
u32 lower;
sprintf(tmp, "%c%c%c%c", reqID[0], reqID[1], reqID[2], reqID[3]);
memcpy(&lower, tmp, 4);
u64 reqID64 = TITLE_ID( type, lower );
return Set_Stub(reqID64);
}
void loadStub()
{
char *stubLoc = (char *) 0x80001800;
memcpy(stubLoc, stub_bin, stub_bin_size);
DCFlushRange(stubLoc, stub_bin_size);
}
u64 getStubDest()
{
if (!hbcStubAvailable()) return 0;
char ret[8];
u64 retu = 0;
char *stub = determineStubTIDLocation();
if (!stub) return 0;
ret[0] = stub[0];
ret[1] = stub[1];
ret[2] = stub[8];
ret[3] = stub[9];
ret[4] = stub[4];
ret[5] = stub[5];
ret[6] = stub[12];
ret[7] = stub[13];
memcpy(&retu, ret, 8);
return retu;
}
u8 hbcStubAvailable()
{
char * sig = (char *) 0x80001804;
return (sig[0] == 'S' && sig[1] == 'T' && sig[2] == 'U' && sig[3] == 'B' && sig[4] == 'H' && sig[5] == 'A'
&& sig[6] == 'X' && sig[7] == 'X') ? 1 : 0;
}
//functions for manipulating the HBC stub by giantpune
#include <string.h>
#include <ogcsys.h>
#include <malloc.h>
#include <stdio.h>
#include "lstub.h"
#include "filelist.h"
#include "gecko.h"
#include "wad/nandtitle.h"
static char* determineStubTIDLocation()
{
u32 *stubID = (u32*) 0x80001818;
//HBC stub 1.0.6 and lower, and stub.bin
if (stubID[0] == 0x480004c1 && stubID[1] == 0x480004f5)
return (char *) 0x800024C6;
//HBC stub changed @ version 1.0.7. this file was last updated for HBC 1.0.8
else if (stubID[0] == 0x48000859 && stubID[1] == 0x4800088d) return (char *) 0x8000286A;
//hexdump( stubID, 0x20 );
return NULL;
}
s32 Set_Stub(u64 reqID)
{
if (NandTitles.IndexOf(reqID) < 0) return WII_EINSTALL;
char *stub = determineStubTIDLocation();
if (!stub) return -68;
stub[0] = TITLE_7( reqID );
stub[1] = TITLE_6( reqID );
stub[8] = TITLE_5( reqID );
stub[9] = TITLE_4( reqID );
stub[4] = TITLE_3( reqID );
stub[5] = TITLE_2( reqID );
stub[12] = TITLE_1( reqID );
stub[13] = ((u8) (reqID));
DCFlushRange(stub, 0x10);
return 1;
}
s32 Set_Stub_Split(u32 type, const char* reqID)
{
char tmp[4];
u32 lower;
sprintf(tmp, "%c%c%c%c", reqID[0], reqID[1], reqID[2], reqID[3]);
memcpy(&lower, tmp, 4);
u64 reqID64 = TITLE_ID( type, lower );
return Set_Stub(reqID64);
}
void loadStub()
{
char *stubLoc = (char *) 0x80001800;
memcpy(stubLoc, stub_bin, stub_bin_size);
DCFlushRange(stubLoc, stub_bin_size);
}
u64 getStubDest()
{
if (!hbcStubAvailable()) return 0;
char ret[8];
u64 retu = 0;
char *stub = determineStubTIDLocation();
if (!stub) return 0;
ret[0] = stub[0];
ret[1] = stub[1];
ret[2] = stub[8];
ret[3] = stub[9];
ret[4] = stub[4];
ret[5] = stub[5];
ret[6] = stub[12];
ret[7] = stub[13];
memcpy(&retu, ret, 8);
return retu;
}
u8 hbcStubAvailable()
{
char * sig = (char *) 0x80001804;
return (sig[0] == 'S' && sig[1] == 'T' && sig[2] == 'U' && sig[3] == 'B' && sig[4] == 'H' && sig[5] == 'A'
&& sig[6] == 'X' && sig[7] == 'X') ? 1 : 0;
}

View File

@ -1,36 +1,36 @@
#ifndef __MEMORY_H_
#define __MEMORY_H_
#ifdef __cplusplus
extern "C"
{
#endif
#define Disc_ID ((u32*) 0x80000000)
#define Disc_Region ((u32*) 0x80000003)
#define Disc_Magic ((u32*) 0x80000018)
#define Sys_Magic ((u32*) 0x80000020)
#define Version ((u32*) 0x80000024)
#define Mem_Size ((u32*) 0x80000028)
#define Board_Model ((u32*) 0x8000002C)
#define Arena_L ((u32*) 0x80000030)
#define Arena_H ((u32*) 0x80000034)
#define FST ((u32*) 0x80000038)
#define Max_FST ((u32*) 0x8000003C)
#define Assembler ((u32*) 0x80000060)
#define Video_Mode ((u32*) 0x800000CC)
#define Dev_Debugger ((u32*) 0x800000EC)
#define Simulated_Mem ((u32*) 0x800000F0)
#define BI2 ((u32*) 0x800000F4)
#define Bus_Speed ((u32*) 0x800000F8)
#define CPU_Speed ((u32*) 0x800000FC)
#define Online_Check ((u32*) 0x80003180)
#define GameID_Address ((u32*) 0x80003184)
#define allocate_memory(size) memalign(32, (size+31)&(~31))
#ifdef __cplusplus
}
#endif
#endif
#ifndef __MEMORY_H_
#define __MEMORY_H_
#ifdef __cplusplus
extern "C"
{
#endif
#define Disc_ID ((u32*) 0x80000000)
#define Disc_Region ((u32*) 0x80000003)
#define Disc_Magic ((u32*) 0x80000018)
#define Sys_Magic ((u32*) 0x80000020)
#define Version ((u32*) 0x80000024)
#define Mem_Size ((u32*) 0x80000028)
#define Board_Model ((u32*) 0x8000002C)
#define Arena_L ((u32*) 0x80000030)
#define Arena_H ((u32*) 0x80000034)
#define FST ((u32*) 0x80000038)
#define Max_FST ((u32*) 0x8000003C)
#define Assembler ((u32*) 0x80000060)
#define Video_Mode ((u32*) 0x800000CC)
#define Dev_Debugger ((u32*) 0x800000EC)
#define Simulated_Mem ((u32*) 0x800000F0)
#define BI2 ((u32*) 0x800000F4)
#define Bus_Speed ((u32*) 0x800000F8)
#define CPU_Speed ((u32*) 0x800000FC)
#define Online_Check ((u32*) 0x80003180)
#define GameID_Address ((u32*) 0x80003184)
#define allocate_memory(size) memalign(32, (size+31)&(~31))
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,155 @@
#ifndef GAMEBROWSEMENU_HPP_
#define GAMEBROWSEMENU_HPP_
#include "libwiigui/gui.h"
#include "libwiigui/gui_gamebrowser.h"
#include "libwiigui/gui_gamegrid.h"
#include "libwiigui/gui_gamecarousel.h"
#include "libwiigui/gui_searchbar.h"
class GameBrowseMenu : public GuiWindow
{
public:
GameBrowseMenu();
~GameBrowseMenu();
int Show();
protected:
int MainLoop();
void ReloadBrowser();
int OpenClickedGame();
int GetSelectedGame();
int GetClickedGame();
void UpdateGameInfoText(const u8 * gameId);
void LoadCover(struct discHdr *header);
void CheckAlternativeDOL(const char * IDfull);
void CheckOcarina(const char * IDfull);
void CoverDownload();
static void UpdateCallback(void * e);
GuiImageData * btnInstall;
GuiImageData * btnInstallOver;
GuiImageData * btnSettings;
GuiImageData * btnSettingsOver;
GuiImageData * btnpwroff;
GuiImageData * btnpwroffOver;
GuiImageData * btnhome;
GuiImageData * btnhomeOver;
GuiImageData * btnsdcardOver;
GuiImageData * btnsdcard;
GuiImageData * imgfavIcon;
GuiImageData * imgfavIcon_gray;
GuiImageData * imgsearchIcon;
GuiImageData * imgsearchIcon_gray;
GuiImageData * imgabcIcon;
GuiImageData * imgrankIcon;
GuiImageData * imgplayCountIcon;
GuiImageData * imgarrangeGrid;
GuiImageData * imgarrangeGrid_gray;
GuiImageData * imgarrangeCarousel;
GuiImageData * imgarrangeCarousel_gray;
GuiImageData * imgarrangeList;
GuiImageData * imgarrangeList_gray;
GuiImageData * imgdvd;
GuiImageData * imgdvd_gray;
GuiImageData * imgLock;
GuiImageData * imgLock_gray;
GuiImageData * imgUnlock;
GuiImageData * imgUnlock_gray;
GuiImageData * homebrewImgData;
GuiImageData * homebrewImgDataOver;
GuiImageData * gameCover;
GuiTrigger * trigA;
GuiTrigger * trigHome;
GuiTrigger * trig1;
GuiTrigger * trig2;
GuiImage * installBtnImg;
GuiImage * installBtnImgOver;
GuiImage * settingsBtnImg;
GuiImage * settingsBtnImgOver;
GuiImage * homeBtnImg;
GuiImage * homeBtnImgOver;
GuiImage * poweroffBtnImg;
GuiImage * poweroffBtnImgOver;
GuiImage * sdcardImg;
GuiImage * sdcardImgOver;
GuiImage * favoriteBtnImg;
GuiImage * favoriteBtnImg_g;
GuiImage * searchBtnImg;
GuiImage * searchBtnImg_g;
GuiImage * sortBtnImg;
GuiImage * listBtnImg;
GuiImage * listBtnImg_g;
GuiImage * gridBtnImg;
GuiImage * gridBtnImg_g;
GuiImage * carouselBtnImg;
GuiImage * carouselBtnImg_g;
GuiImage * lockBtnImg;
GuiImage * lockBtnImg_g;
GuiImage * unlockBtnImg;
GuiImage * unlockBtnImg_g;
GuiImage * dvdBtnImg;
GuiImage * dvdBtnImg_g;
GuiImage * homebrewImg;
GuiImage * homebrewImgOver;
GuiImage * gameCoverImg;
GuiText * usedSpaceTxt;
GuiText * gamecntTxt;
GuiText * clockTimeBack;
GuiText * clockTime;
GuiButton * gamecntBtn;
GuiButton * installBtn;
GuiButton * settingsBtn;
GuiButton * homeBtn;
GuiButton * poweroffBtn;
GuiButton * sdcardBtn;
GuiButton * gameInfo;
GuiButton * favoriteBtn;
GuiButton * searchBtn;
GuiButton * sortBtn;
GuiButton * listBtn;
GuiButton * gridBtn;
GuiButton * carouselBtn;
GuiButton * lockBtn;
GuiButton * dvdBtn;
GuiButton * homebrewBtn;
GuiButton * DownloadBtn;
GuiButton * idBtn;
GuiTooltip * installBtnTT;
GuiTooltip * settingsBtnTT;
GuiTooltip * homeBtnTT;
GuiTooltip * poweroffBtnTT;
GuiTooltip * sdcardBtnTT;
GuiTooltip * favoriteBtnTT;
GuiTooltip * searchBtnTT;
GuiTooltip * sortBtnTT;
GuiTooltip * listBtnTT;
GuiTooltip * gridBtnTT;
GuiTooltip * carouselBtnTT;
GuiTooltip * lockBtnTT;
GuiTooltip * dvdBtnTT;
GuiTooltip * homebrewBtnTT;
GuiTooltip * DownloadBtnTT;
GuiTooltip * IDBtnTT;
GuiGameBrowser * gameBrowser;
GuiGameGrid * gameGrid;
GuiGameCarousel * gameCarousel;
GuiSearchBar * searchBar;
char theTime[50];
u32 DiscDriveCover;
u32 DiscDriveCoverOld;
int gameSelectedOld;
int gameClicked;
time_t lastrawtime;
time_t ScreensaverTimer;
bool show_searchwindow;
wchar_t searchChar;
std::vector<GuiButton *> ToolBar;
};
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,261 +1,261 @@
#include "http.h"
#include "../svnrev.h"
extern char incommingIP[50];
/**
* Emptyblock is a statically defined variable for functions to return if they are unable
* to complete a request
*/
const struct block emptyblock = { 0, NULL };
//The maximum amount of bytes to send per net_write() call
//#define NET_BUFFER_SIZE 1024
#define NET_BUFFER_SIZE 3600
// Write our message to the server
static s32 send_message(s32 server, char *msg)
{
s32 bytes_transferred = 0;
s32 remaining = strlen(msg);
while (remaining)
{
if ((bytes_transferred = net_write(server, msg, remaining > NET_BUFFER_SIZE ? NET_BUFFER_SIZE : remaining)) > 0)
{
remaining -= bytes_transferred;
usleep(20 * 1000);
}
else if (bytes_transferred < 0)
{
return bytes_transferred;
}
else
{
return -ENODATA;
}
}
return 0;
}
/**
* Connect to a remote server via TCP on a specified port
*
* @param u32 ip address of the server to connect to
* @param u32 the port to connect to on the server
* @return s32 The connection to the server (negative number if connection could not be established)
*/
static s32 server_connect(u32 ipaddress, u32 socket_port)
{
//Initialize socket
s32 connection = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (connection < 0) return connection;
struct sockaddr_in connect_addr;
memset(&connect_addr, 0, sizeof(connect_addr));
connect_addr.sin_family = AF_INET;
connect_addr.sin_port = socket_port;
connect_addr.sin_addr.s_addr = ipaddress;
sprintf(incommingIP, "%s", inet_ntoa(connect_addr.sin_addr));
//Attemt to open the socket
if (net_connect(connection, (struct sockaddr*) &connect_addr, sizeof(connect_addr)) == -1)
{
net_close(connection);
return -1;
}
return connection;
}
//The amount of memory in bytes reserved initially to store the HTTP response in
//Be careful in increasing this number, reading from a socket on the Wii
//will fail if you request more than 20k or so
#define HTTP_BUFFER_SIZE 1024 * 5
//The amount of memory the buffer should expanded with if the buffer is full
#define HTTP_BUFFER_GROWTH 1024 * 5
/**
* This function reads all the data from a connection into a buffer which it returns.
* It will return an empty buffer if something doesn't go as planned
*
* @param s32 connection The connection identifier to suck the response out of
* @return block A 'block' struct (see http.h) in which the buffer is located
*/
struct block read_message(s32 connection)
{
//Create a block of memory to put in the response
struct block buffer;
buffer.data = malloc(HTTP_BUFFER_SIZE);
buffer.size = HTTP_BUFFER_SIZE;
if (buffer.data == NULL)
{
return emptyblock;
}
//The offset variable always points to the first byte of memory that is free in the buffer
u32 offset = 0;
while (1)
{
//Fill the buffer with a new batch of bytes from the connection,
//starting from where we left of in the buffer till the end of the buffer
s32 bytes_read = net_read(connection, buffer.data + offset, buffer.size - offset);
//Anything below 0 is an error in the connection
if (bytes_read < 0)
{
//printf("Connection error from net_read() Errorcode: %i\n", bytes_read);
return emptyblock;
}
//No more bytes were read into the buffer,
//we assume this means the HTTP response is done
if (bytes_read == 0)
{
break;
}
offset += bytes_read;
//Check if we have enough buffer left over,
//if not expand it with an additional HTTP_BUFFER_GROWTH worth of bytes
if (offset >= buffer.size)
{
buffer.size += HTTP_BUFFER_GROWTH;
buffer.data = realloc(buffer.data, buffer.size);
if (buffer.data == NULL)
{
return emptyblock;
}
}
}
//At the end of above loop offset should be precisely the amount of bytes that were read from the connection
buffer.size = offset;
//Shrink the size of the buffer so the data fits exactly in it
buffer.data = realloc(buffer.data, buffer.size);
return buffer;
}
/**
* Downloads the contents of a URL to memory
* This method is not threadsafe (because networking is not threadsafe on the Wii)
*/
struct block downloadfile(const char *url)
{
//Check if the url starts with "http://", if not it is not considered a valid url
if (strncmp(url, "http://", strlen("http://")) != 0)
{
//printf("URL '%s' doesn't start with 'http://'\n", url);
return emptyblock;
}
//Locate the path part of the url by searching for '/' past "http://"
char *path = strchr(url + strlen("http://"), '/');
//At the very least the url has to end with '/', ending with just a domain is invalid
if (path == NULL)
{
//printf("URL '%s' has no PATH part\n", url);
return emptyblock;
}
//Extract the domain part out of the url
int domainlength = path - url - strlen("http://");
if (domainlength == 0)
{
//printf("No domain part in URL '%s'\n", url);
return emptyblock;
}
char domain[domainlength + 1];
strlcpy(domain, url + strlen("http://"), domainlength + 1);
//Parsing of the URL is done, start making an actual connection
u32 ipaddress = getipbynamecached(domain);
if (ipaddress == 0)
{
//printf("\ndomain %s could not be resolved", domain);
return emptyblock;
}
s32 connection = server_connect(ipaddress, 80);
if (connection < 0)
{
//printf("Error establishing connection");
return emptyblock;
}
//Form a nice request header to send to the webserver
char* headerformat = "GET %s HTTP/1.0\r\nHost: %s\r\nReferer: %s\r\nUser-Agent: USBLoaderGX r%s\r\n\r\n";
;
char header[strlen(headerformat) + strlen(path) + strlen(domain) + strlen(domain)];
sprintf(header, headerformat, path, domain, domain, GetRev());
//Do the request and get the response
send_message(connection, header);
struct block response = read_message(connection);
net_close(connection);
//Search for the 4-character sequence \r\n\r\n in the response which signals the start of the http payload (file)
unsigned char *filestart = NULL;
u32 filesize = 0;
int i;
for (i = 3; i < response.size; i++)
{
if (response.data[i] == '\n' && response.data[i - 1] == '\r' && response.data[i - 2] == '\n' && response.data[i
- 3] == '\r')
{
filestart = response.data + i + 1;
filesize = response.size - i - 1;
break;
}
}
if (filestart == NULL)
{
//printf("HTTP Response was without a file\n");
free(response.data);
return emptyblock;
}
//Copy the file part of the response into a new memoryblock to return
struct block file;
file.data = malloc(filesize);
file.size = filesize;
if (file.data == NULL)
{
//printf("No more memory to copy file from HTTP response\n");
free(response.data);
return emptyblock;
}
memcpy(file.data, filestart, filesize);
//Dispose of the original response
free(response.data);
return file;
}
s32 GetConnection(char * domain)
{
u32 ipaddress = getipbynamecached(domain);
if (ipaddress == 0)
{
return -1;
}
s32 connection = server_connect(ipaddress, 80);
return connection;
}
#include "http.h"
#include "../svnrev.h"
extern char incommingIP[50];
/**
* Emptyblock is a statically defined variable for functions to return if they are unable
* to complete a request
*/
const struct block emptyblock = { 0, NULL };
//The maximum amount of bytes to send per net_write() call
//#define NET_BUFFER_SIZE 1024
#define NET_BUFFER_SIZE 3600
// Write our message to the server
static s32 send_message(s32 server, char *msg)
{
s32 bytes_transferred = 0;
s32 remaining = strlen(msg);
while (remaining)
{
if ((bytes_transferred = net_write(server, msg, remaining > NET_BUFFER_SIZE ? NET_BUFFER_SIZE : remaining)) > 0)
{
remaining -= bytes_transferred;
usleep(20 * 1000);
}
else if (bytes_transferred < 0)
{
return bytes_transferred;
}
else
{
return -ENODATA;
}
}
return 0;
}
/**
* Connect to a remote server via TCP on a specified port
*
* @param u32 ip address of the server to connect to
* @param u32 the port to connect to on the server
* @return s32 The connection to the server (negative number if connection could not be established)
*/
static s32 server_connect(u32 ipaddress, u32 socket_port)
{
//Initialize socket
s32 connection = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (connection < 0) return connection;
struct sockaddr_in connect_addr;
memset(&connect_addr, 0, sizeof(connect_addr));
connect_addr.sin_family = AF_INET;
connect_addr.sin_port = socket_port;
connect_addr.sin_addr.s_addr = ipaddress;
sprintf(incommingIP, "%s", inet_ntoa(connect_addr.sin_addr));
//Attemt to open the socket
if (net_connect(connection, (struct sockaddr*) &connect_addr, sizeof(connect_addr)) == -1)
{
net_close(connection);
return -1;
}
return connection;
}
//The amount of memory in bytes reserved initially to store the HTTP response in
//Be careful in increasing this number, reading from a socket on the Wii
//will fail if you request more than 20k or so
#define HTTP_BUFFER_SIZE 1024 * 5
//The amount of memory the buffer should expanded with if the buffer is full
#define HTTP_BUFFER_GROWTH 1024 * 5
/**
* This function reads all the data from a connection into a buffer which it returns.
* It will return an empty buffer if something doesn't go as planned
*
* @param s32 connection The connection identifier to suck the response out of
* @return block A 'block' struct (see http.h) in which the buffer is located
*/
struct block read_message(s32 connection)
{
//Create a block of memory to put in the response
struct block buffer;
buffer.data = malloc(HTTP_BUFFER_SIZE);
buffer.size = HTTP_BUFFER_SIZE;
if (buffer.data == NULL)
{
return emptyblock;
}
//The offset variable always points to the first byte of memory that is free in the buffer
u32 offset = 0;
while (1)
{
//Fill the buffer with a new batch of bytes from the connection,
//starting from where we left of in the buffer till the end of the buffer
s32 bytes_read = net_read(connection, buffer.data + offset, buffer.size - offset);
//Anything below 0 is an error in the connection
if (bytes_read < 0)
{
//printf("Connection error from net_read() Errorcode: %i\n", bytes_read);
return emptyblock;
}
//No more bytes were read into the buffer,
//we assume this means the HTTP response is done
if (bytes_read == 0)
{
break;
}
offset += bytes_read;
//Check if we have enough buffer left over,
//if not expand it with an additional HTTP_BUFFER_GROWTH worth of bytes
if (offset >= buffer.size)
{
buffer.size += HTTP_BUFFER_GROWTH;
buffer.data = realloc(buffer.data, buffer.size);
if (buffer.data == NULL)
{
return emptyblock;
}
}
}
//At the end of above loop offset should be precisely the amount of bytes that were read from the connection
buffer.size = offset;
//Shrink the size of the buffer so the data fits exactly in it
buffer.data = realloc(buffer.data, buffer.size);
return buffer;
}
/**
* Downloads the contents of a URL to memory
* This method is not threadsafe (because networking is not threadsafe on the Wii)
*/
struct block downloadfile(const char *url)
{
//Check if the url starts with "http://", if not it is not considered a valid url
if (strncmp(url, "http://", strlen("http://")) != 0)
{
//printf("URL '%s' doesn't start with 'http://'\n", url);
return emptyblock;
}
//Locate the path part of the url by searching for '/' past "http://"
char *path = strchr(url + strlen("http://"), '/');
//At the very least the url has to end with '/', ending with just a domain is invalid
if (path == NULL)
{
//printf("URL '%s' has no PATH part\n", url);
return emptyblock;
}
//Extract the domain part out of the url
int domainlength = path - url - strlen("http://");
if (domainlength == 0)
{
//printf("No domain part in URL '%s'\n", url);
return emptyblock;
}
char domain[domainlength + 1];
strlcpy(domain, url + strlen("http://"), domainlength + 1);
//Parsing of the URL is done, start making an actual connection
u32 ipaddress = getipbynamecached(domain);
if (ipaddress == 0)
{
//printf("\ndomain %s could not be resolved", domain);
return emptyblock;
}
s32 connection = server_connect(ipaddress, 80);
if (connection < 0)
{
//printf("Error establishing connection");
return emptyblock;
}
//Form a nice request header to send to the webserver
char* headerformat = "GET %s HTTP/1.0\r\nHost: %s\r\nReferer: %s\r\nUser-Agent: USBLoaderGX r%s\r\n\r\n";
;
char header[strlen(headerformat) + strlen(path) + strlen(domain) + strlen(domain)];
sprintf(header, headerformat, path, domain, domain, GetRev());
//Do the request and get the response
send_message(connection, header);
struct block response = read_message(connection);
net_close(connection);
//Search for the 4-character sequence \r\n\r\n in the response which signals the start of the http payload (file)
unsigned char *filestart = NULL;
u32 filesize = 0;
int i;
for (i = 3; i < response.size; i++)
{
if (response.data[i] == '\n' && response.data[i - 1] == '\r' && response.data[i - 2] == '\n' && response.data[i
- 3] == '\r')
{
filestart = response.data + i + 1;
filesize = response.size - i - 1;
break;
}
}
if (filestart == NULL)
{
//printf("HTTP Response was without a file\n");
free(response.data);
return emptyblock;
}
//Copy the file part of the response into a new memoryblock to return
struct block file;
file.data = malloc(filesize);
file.size = filesize;
if (file.data == NULL)
{
//printf("No more memory to copy file from HTTP response\n");
free(response.data);
return emptyblock;
}
memcpy(file.data, filestart, filesize);
//Dispose of the original response
free(response.data);
return file;
}
s32 GetConnection(char * domain)
{
u32 ipaddress = getipbynamecached(domain);
if (ipaddress == 0)
{
return -1;
}
s32 connection = server_connect(ipaddress, 80);
return connection;
}

View File

@ -52,7 +52,7 @@ int cntMissFiles = 0;
static char missingFiles[500][12];
/*** Extern variables ***/
s32 gameSelected = 0, gameStart = 0;
s32 gameStart = 0;
extern float gamesize;
extern u8 shutdown;
extern u8 reset;
@ -445,7 +445,6 @@ void WindowCredits()
int WindowScreensaver()
{
gprintf("WindowScreenSaver()\n");
int i = 0;
bool exit = false;
/* initialize random seed: */
@ -473,18 +472,15 @@ int WindowScreensaver()
while (!exit)
{
i++;
if (IsWpadConnected())
{
exit = true;
break;
}
/* Set position only every 400000th loop */
if ((i % 8000000) == 0)
{
/* Set random position */
GXlogoImg.SetPosition((rand() % 345), (rand() % 305));
}
GXlogoImg.SetPosition((rand() % 345), (rand() % 305));
sleep(4);
}
HaltGui();
@ -1127,7 +1123,7 @@ void SetFavoriteImages(const u8 * gameid, GuiImage *b1, GuiImage *b2, GuiImage *
* Displays a prompt window to user, with information, an error message, or
* presenting a user with a choice
***************************************************************************/
int GameWindowPrompt()
int GameWindowPrompt(int gameSelected)
{
int choice = -1, angle = 0;
f32 size = 0.0;
@ -1531,8 +1527,32 @@ int GameWindowPrompt()
else if (nameBtn.GetState() == STATE_CLICKED) //rename
{
nameBtn.ResetState();
if(mountMethod == 3)
{
WindowPrompt(tr("ERROR:"), tr("You can't rename this game"), tr("OK"));
continue;
}
choice = 3;
promptWindow.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_OUT, 50);
while(promptWindow.GetEffect() > 0) usleep(100);
wiilight(0);
//re-evaluate header now in case they changed games while on the game prompt
struct discHdr *header = gameList[gameSelected];
//enter new game title
char entered[60];
snprintf(entered, sizeof(entered), "%s", GameTitles.GetTitle(header));
int result = OnScreenKeyboard(entered, 60, 0);
if (result == 1)
{
WBFS_RenameGame(header->id, entered);
wString oldFilter(gameList.GetCurrentFilter());
gameList.ReadGameList();
gameList.FilterList(oldFilter.c_str());
}
}
else if (btnFavorite1.GetState() == STATE_CLICKED) //switch favorite
{

View File

@ -18,7 +18,7 @@ void WindowCredits();
int OnScreenKeyboard(char * var, u32 maxlen, int min);
int OnScreenNumpad(char * var, u32 maxlen);
int WindowExitPrompt();
int GameWindowPrompt();
int GameWindowPrompt(int gameSelected);
int DiscWait(const char *title, const char *msg, const char *btn1Label, const char *btn2Label, int IsDeviceWait);
int FormatingPartition(const char *title, partitionEntry *entry);
bool SearchMissingImages(int choice2);

View File

@ -101,7 +101,7 @@ FlyingButtonsMenu::~FlyingButtonsMenu()
ResumeGui();
SetEffect(EFFECT_FADE, -FADE_SPEED);
while(this->GetEffect() > 0) usleep(100);
while(parentElement && this->GetEffect() > 0) usleep(100);
HaltGui();
if(parentElement)
@ -321,9 +321,8 @@ void FlyingButtonsMenu::AddMainButtons()
void FlyingButtonsMenu::ShowButtonsEffects(int effect, int effect_speed)
{
int FirstItem = currentPage*DISPLAY_BUTTONS;
if(FirstItem >= (int) MainButton.size())
return;
if(FirstItem < 0)
FirstItem = 0;
HaltGui();
@ -335,11 +334,14 @@ void FlyingButtonsMenu::ShowButtonsEffects(int effect, int effect_speed)
ResumeGui();
if(FirstItem < 0 || FirstItem >= (int) MainButton.size())
return;
//! Don't lock on fade in for initiation purpose
if(effect & EFFECT_FADE && effect_speed > 0)
return;
while (MainButton[FirstItem]->GetEffect() > 0)
while (parentElement && MainButton[FirstItem]->GetEffect() > 0)
usleep(100);
}

View File

@ -225,7 +225,11 @@ int GuiSettingsMenu::GetMenuInternal()
returnhere = MenuLanguageSelect();
if (returnhere == 2)
{
//! Language changed. Reload game titles with new lang code.
GameTitles.LoadTitlesFromWiiTDB(Settings.titlestxt_path);
return MENU_SETTINGS;
}
HaltGui();
if(parentElement)

View File

@ -31,6 +31,8 @@
#include "prompts/PromptWindows.h"
#include "language/gettext.h"
#include "usbloader/wbfs.h"
#include "usbloader/GameList.h"
#include "wstring.hpp"
extern int mountMethod;
@ -97,6 +99,14 @@ int UninstallSM::GetMenuInternal()
int ret = 0;
if(!mountMethod)
ret = WBFS_RemoveGame(DiscHeader->id);
if(ret >= 0)
{
wString oldFilter(gameList.GetCurrentFilter());
gameList.ReadGameList();
gameList.FilterList(oldFilter.c_str());
}
if (ret < 0)
WindowPrompt(tr( "Can't delete:" ), Title.c_str(), tr( "OK" ));
else

View File

@ -1,36 +1,36 @@
#ifndef _NEWTITLES_H
#define _NEWTITLES_H
#include <time.h>
class NewTitles
{
public:
static NewTitles *Instance();
static void DestroyInstance();
void Save();
void CheckGame(u8 *titleid);
bool IsNew(u8 *titleid);
void Remove(u8 *titleid);
private:
NewTitles();
~NewTitles();
static NewTitles *instance;
class Title
{
public:
u8 titleId[6];
time_t timestamp;
void *next;
};
Title *firstTitle;
Title *lastTitle;
bool isDirty;
bool isNewFile;
};
#endif //_NEWTITLES_H
#ifndef _NEWTITLES_H
#define _NEWTITLES_H
#include <time.h>
class NewTitles
{
public:
static NewTitles *Instance();
static void DestroyInstance();
void Save();
void CheckGame(u8 *titleid);
bool IsNew(u8 *titleid);
void Remove(u8 *titleid);
private:
NewTitles();
~NewTitles();
static NewTitles *instance;
class Title
{
public:
u8 titleId[6];
time_t timestamp;
void *next;
};
Title *firstTitle;
Title *lastTitle;
bool isDirty;
bool isNewFile;
};
#endif //_NEWTITLES_H

View File

@ -142,7 +142,7 @@ void Sys_Shutdown(void)
_Sys_Shutdown(ShutdownToDefault);
}
void Sys_ShutdownToIdel(void)
void Sys_ShutdownToIdle(void)
{
_Sys_Shutdown(ShutdownToIdle);
}

View File

@ -9,7 +9,7 @@ void ExitApp(void); //! Like AppCleanUp() and additional device unmount
void Sys_Init(void);
void Sys_Reboot(void);
void Sys_Shutdown(void);
void Sys_ShutdownToIdel(void);
void Sys_ShutdownToIdle(void);
void Sys_ShutdownToStandby(void);
void Sys_LoadMenu(void);
void Sys_BackToLoader(void);

View File

@ -1,15 +1,15 @@
/****************************************************************************
* Theme_Downloader
* USB Loader GX 2009
*
* Theme downloader for USB Loader GX
*
* Theme_Downloader.h
***************************************************************************/
#ifndef _THEME_DOWNLOADER_H_
#define _THEME_DOWNLOADER_H_
int Theme_Downloader();
#endif
/****************************************************************************
* Theme_Downloader
* USB Loader GX 2009
*
* Theme downloader for USB Loader GX
*
* Theme_Downloader.h
***************************************************************************/
#ifndef _THEME_DOWNLOADER_H_
#define _THEME_DOWNLOADER_H_
int Theme_Downloader();
#endif

View File

@ -257,6 +257,7 @@ out:
SAFE_FREE(fs);
SAFE_FREE(fa);
SAFE_FREE(fw);
return ret_val;
}

View File

@ -1,348 +1,348 @@
// by oggzee
#include <ogcsys.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include "splits.h"
#define off64_t off_t
#define FMT_llu "%llu"
#define FMT_lld "%lld"
#define split_error(x) do { printf("\nsplit error: %s\n\n",x); } while(0)
// 1 cluster less than 4gb
u64 OPT_split_size = (u64) 4LL * 1024 * 1024 * 1024 - 32 * 1024;
// 1 cluster less than 2gb
//u64 OPT_split_size = (u64)2LL * 1024 * 1024 * 1024 - 32 * 1024;
//split_info_t split;
void split_get_fname(split_info_t *s, int idx, char *fname)
{
strcpy(fname, s->fname);
if (idx == 0 && s->create_mode)
{
strcat(fname, ".tmp");
}
else if (idx > 0)
{
char *c = fname + strlen(fname) - 1;
*c = '0' + idx;
}
}
int split_open_file(split_info_t *s, int idx)
{
int fd = s->fd[idx];
if (fd >= 0) return fd;
char fname[1024];
split_get_fname(s, idx, fname);
//char *mode = s->create_mode ? "wb+" : "rb+";
int mode = s->create_mode ? (O_CREAT | O_RDWR) : O_RDWR;
//printf("SPLIT OPEN %s %s %d\n", fname, mode, idx); //Wpad_WaitButtons();
//f = fopen(fname, mode);
fd = open(fname, mode);
if (fd < 0) return -1;
if (idx > 0 && s->create_mode)
{
printf("%s Split: %d %s \n", s->create_mode ? "Create" : "Read", idx, fname);
}
s->fd[idx] = fd;
return fd;
}
// faster as it uses larger chunks than ftruncate internally
int write_zero(int fd, off_t size)
{
int buf[0x4000]; //64kb
int chunk;
int ret;
memset(buf, 0, sizeof(buf));
while (size)
{
chunk = size;
if (chunk > sizeof(buf)) chunk = sizeof(buf);
ret = write(fd, buf, chunk);
//printf("WZ %d %d / %lld \n", ret, chunk, size);
size -= chunk;
if (ret < 0) return ret;
}
return 0;
}
int split_fill(split_info_t *s, int idx, u64 size)
{
int fd = split_open_file(s, idx);
off64_t fsize = lseek(fd, 0, SEEK_END);
if (fsize < size)
{
//printf("TRUNC %d "FMT_lld"\n", idx, size); Wpad_WaitButtons();
//ftruncate(fd, size);
write_zero(fd, size - fsize);
return 1;
}
return 0;
}
int split_get_file(split_info_t *s, u32 lba, u32 *sec_count, int fill)
{
int fd;
if (lba >= s->total_sec)
{
fprintf(stderr, "SPLIT: invalid sector %u / %u\n", lba, (u32) s->total_sec);
return -1;
}
int idx;
idx = lba / s->split_sec;
if (idx >= s->max_split)
{
fprintf(stderr, "SPLIT: invalid split %d / %d\n", idx, s->max_split - 1);
return -1;
}
fd = s->fd[idx];
if (fd < 0)
{
// opening new, make sure all previous are full
int i;
for (i = 0; i < idx; i++)
{
if (split_fill(s, i, s->split_size))
{
printf("FILL %d\n", i);
}
}
fd = split_open_file(s, idx);
}
if (fd < 0)
{
fprintf(stderr, "SPLIT %d: no file\n", idx);
return -1;
}
u32 sec = lba % s->split_sec; // inside file
off64_t off = (off64_t ) sec * 512;
// num sectors till end of file
u32 to_end = s->split_sec - sec;
if (*sec_count > to_end) *sec_count = to_end;
if (s->create_mode)
{
if (fill)
{
// extend, so that read will be succesfull
split_fill(s, idx, off + 512 * (*sec_count));
}
else
{
// fill up so that write continues from end of file
// shouldn't be necessary, but libfat looks buggy
// and this is faster
split_fill(s, idx, off);
}
}
lseek(fd, off, SEEK_SET);
return fd;
}
int split_read_sector(void *_fp, u32 lba, u32 count, void*buf)
{
split_info_t *s = _fp;
int fd;
u64 off = lba;
off *= 512ULL;
int i;
u32 chunk;
size_t ret;
//fprintf(stderr,"READ %d %d\n", lba, count);
for (i = 0; i < (int) count; i += chunk)
{
chunk = count - i;
fd = split_get_file(s, lba + i, &chunk, 1);
if (fd < 0)
{
fprintf(stderr, "\n\n"FMT_lld" %d %p\n", off, count, _fp);
split_error( "error seeking in disc partition" );
return 1;
}
void *ptr = ((u8 *) buf) + (i * 512);
ret = read(fd, ptr, chunk * 512);
if (ret != chunk * 512)
{
fprintf(stderr, "error reading %u %u [%u] %u = %u\n", lba, count, i, chunk, ret);
split_error( "error reading disc" );
return 1;
}
}
return 0;
}
int split_write_sector(void *_fp, u32 lba, u32 count, void*buf)
{
split_info_t *s = _fp;
int fd;
u64 off = lba;
off *= 512ULL;
int i;
u32 chunk;
size_t ret;
//printf("WRITE %d %d %p \n", lba, count, buf);
for (i = 0; i < (int) count; i += chunk)
{
chunk = count - i;
fd = split_get_file(s, lba + i, &chunk, 0);
//if (chunk != count)
// fprintf(stderr, "WRITE CHUNK %d %d/%d\n", lba+i, chunk, count);
if (fd < 0 || !chunk)
{
fprintf(stderr, "\n\n"FMT_lld" %d %p\n", off, count, _fp);
split_error( "error seeking in disc partition" );
return 1;
}
//if (fwrite(buf+i*512, 512ULL, chunk, f) != chunk) {
//printf("write %d %p %d \n", fd, buf+i*512, chunk * 512);
void *ptr = ((u8 *) buf) + (i * 512);
ret = write(fd, ptr, chunk * 512);
//printf("write ret = %d \n", ret);
if (ret != chunk * 512)
{
split_error( "error writing disc" );
return 1;
}
}
return 0;
}
void split_init(split_info_t *s, char *fname)
{
int i;
char *p;
//fprintf(stderr, "SPLIT_INIT %s\n", fname);
memset(s, 0, sizeof(*s));
for (i = 0; i < MAX_SPLIT; i++)
{
s->fd[i] = -1;
}
strcpy(s->fname, fname);
s->max_split = 1;
p = strrchr(fname, '.');
if (p && (strcasecmp(p, ".wbfs") == 0))
{
s->max_split = MAX_SPLIT;
}
}
void split_set_size(split_info_t *s, u64 split_size, u64 total_size)
{
s->total_size = total_size;
s->split_size = split_size;
s->total_sec = total_size / 512;
s->split_sec = split_size / 512;
}
void split_close(split_info_t *s)
{
int i;
char fname[1024];
char tmpname[1024];
for (i = 0; i < s->max_split; i++)
{
if (s->fd[i] >= 0)
{
close(s->fd[i]);
}
}
if (s->create_mode)
{
split_get_fname(s, -1, fname);
split_get_fname(s, 0, tmpname);
rename(tmpname, fname);
}
memset(s, 0, sizeof(*s));
}
int split_create(split_info_t *s, char *fname, u64 split_size, u64 total_size, bool overwrite)
{
int i;
int fd;
char sname[1024];
int error = 0;
split_init(s, fname);
s->create_mode = 1;
// check if any file already exists
for (i = -1; i < s->max_split; i++)
{
split_get_fname(s, i, sname);
if (overwrite)
{
remove(sname);
}
else
{
fd = open(sname, O_RDONLY);
if (fd >= 0)
{
fprintf(stderr, "Error: file already exists: %s\n", sname);
close(fd);
error = 1;
}
}
}
if (error)
{
split_init(s, "");
return -1;
}
split_set_size(s, split_size, total_size);
return 0;
}
int split_open(split_info_t *s, char *fname)
{
int i;
u64 size = 0;
u64 total_size = 0;
u64 split_size = 0;
int fd;
split_init(s, fname);
for (i = 0; i < s->max_split; i++)
{
fd = split_open_file(s, i);
if (fd < 0)
{
if (i == 0) goto err;
break;
}
// check previous size - all splits except last must be same size
if (i > 0 && size != split_size)
{
fprintf(stderr, "split %d: invalid size "FMT_lld"", i, size);
goto err;
}
// get size
//fseeko(f, 0, SEEK_END);
//size = ftello(f);
size = lseek(fd, 0, SEEK_END);
// check sector alignment
if (size % 512)
{
fprintf(stderr, "split %d: size ("FMT_lld") not sector (512) aligned!", i, size);
}
// first sets split size
if (i == 0)
{
split_size = size;
}
total_size += size;
}
split_set_size(s, split_size, total_size);
return 0;
err: split_close(s);
return -1;
}
// by oggzee
#include <ogcsys.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include "splits.h"
#define off64_t off_t
#define FMT_llu "%llu"
#define FMT_lld "%lld"
#define split_error(x) do { printf("\nsplit error: %s\n\n",x); } while(0)
// 1 cluster less than 4gb
u64 OPT_split_size = (u64) 4LL * 1024 * 1024 * 1024 - 32 * 1024;
// 1 cluster less than 2gb
//u64 OPT_split_size = (u64)2LL * 1024 * 1024 * 1024 - 32 * 1024;
//split_info_t split;
void split_get_fname(split_info_t *s, int idx, char *fname)
{
strcpy(fname, s->fname);
if (idx == 0 && s->create_mode)
{
strcat(fname, ".tmp");
}
else if (idx > 0)
{
char *c = fname + strlen(fname) - 1;
*c = '0' + idx;
}
}
int split_open_file(split_info_t *s, int idx)
{
int fd = s->fd[idx];
if (fd >= 0) return fd;
char fname[1024];
split_get_fname(s, idx, fname);
//char *mode = s->create_mode ? "wb+" : "rb+";
int mode = s->create_mode ? (O_CREAT | O_RDWR) : O_RDWR;
//printf("SPLIT OPEN %s %s %d\n", fname, mode, idx); //Wpad_WaitButtons();
//f = fopen(fname, mode);
fd = open(fname, mode);
if (fd < 0) return -1;
if (idx > 0 && s->create_mode)
{
printf("%s Split: %d %s \n", s->create_mode ? "Create" : "Read", idx, fname);
}
s->fd[idx] = fd;
return fd;
}
// faster as it uses larger chunks than ftruncate internally
int write_zero(int fd, off_t size)
{
int buf[0x4000]; //64kb
int chunk;
int ret;
memset(buf, 0, sizeof(buf));
while (size)
{
chunk = size;
if (chunk > sizeof(buf)) chunk = sizeof(buf);
ret = write(fd, buf, chunk);
//printf("WZ %d %d / %lld \n", ret, chunk, size);
size -= chunk;
if (ret < 0) return ret;
}
return 0;
}
int split_fill(split_info_t *s, int idx, u64 size)
{
int fd = split_open_file(s, idx);
off64_t fsize = lseek(fd, 0, SEEK_END);
if (fsize < size)
{
//printf("TRUNC %d "FMT_lld"\n", idx, size); Wpad_WaitButtons();
//ftruncate(fd, size);
write_zero(fd, size - fsize);
return 1;
}
return 0;
}
int split_get_file(split_info_t *s, u32 lba, u32 *sec_count, int fill)
{
int fd;
if (lba >= s->total_sec)
{
fprintf(stderr, "SPLIT: invalid sector %u / %u\n", lba, (u32) s->total_sec);
return -1;
}
int idx;
idx = lba / s->split_sec;
if (idx >= s->max_split)
{
fprintf(stderr, "SPLIT: invalid split %d / %d\n", idx, s->max_split - 1);
return -1;
}
fd = s->fd[idx];
if (fd < 0)
{
// opening new, make sure all previous are full
int i;
for (i = 0; i < idx; i++)
{
if (split_fill(s, i, s->split_size))
{
printf("FILL %d\n", i);
}
}
fd = split_open_file(s, idx);
}
if (fd < 0)
{
fprintf(stderr, "SPLIT %d: no file\n", idx);
return -1;
}
u32 sec = lba % s->split_sec; // inside file
off64_t off = (off64_t ) sec * 512;
// num sectors till end of file
u32 to_end = s->split_sec - sec;
if (*sec_count > to_end) *sec_count = to_end;
if (s->create_mode)
{
if (fill)
{
// extend, so that read will be succesfull
split_fill(s, idx, off + 512 * (*sec_count));
}
else
{
// fill up so that write continues from end of file
// shouldn't be necessary, but libfat looks buggy
// and this is faster
split_fill(s, idx, off);
}
}
lseek(fd, off, SEEK_SET);
return fd;
}
int split_read_sector(void *_fp, u32 lba, u32 count, void*buf)
{
split_info_t *s = _fp;
int fd;
u64 off = lba;
off *= 512ULL;
int i;
u32 chunk;
size_t ret;
//fprintf(stderr,"READ %d %d\n", lba, count);
for (i = 0; i < (int) count; i += chunk)
{
chunk = count - i;
fd = split_get_file(s, lba + i, &chunk, 1);
if (fd < 0)
{
fprintf(stderr, "\n\n"FMT_lld" %d %p\n", off, count, _fp);
split_error( "error seeking in disc partition" );
return 1;
}
void *ptr = ((u8 *) buf) + (i * 512);
ret = read(fd, ptr, chunk * 512);
if (ret != chunk * 512)
{
fprintf(stderr, "error reading %u %u [%u] %u = %u\n", lba, count, i, chunk, ret);
split_error( "error reading disc" );
return 1;
}
}
return 0;
}
int split_write_sector(void *_fp, u32 lba, u32 count, void*buf)
{
split_info_t *s = _fp;
int fd;
u64 off = lba;
off *= 512ULL;
int i;
u32 chunk;
size_t ret;
//printf("WRITE %d %d %p \n", lba, count, buf);
for (i = 0; i < (int) count; i += chunk)
{
chunk = count - i;
fd = split_get_file(s, lba + i, &chunk, 0);
//if (chunk != count)
// fprintf(stderr, "WRITE CHUNK %d %d/%d\n", lba+i, chunk, count);
if (fd < 0 || !chunk)
{
fprintf(stderr, "\n\n"FMT_lld" %d %p\n", off, count, _fp);
split_error( "error seeking in disc partition" );
return 1;
}
//if (fwrite(buf+i*512, 512ULL, chunk, f) != chunk) {
//printf("write %d %p %d \n", fd, buf+i*512, chunk * 512);
void *ptr = ((u8 *) buf) + (i * 512);
ret = write(fd, ptr, chunk * 512);
//printf("write ret = %d \n", ret);
if (ret != chunk * 512)
{
split_error( "error writing disc" );
return 1;
}
}
return 0;
}
void split_init(split_info_t *s, char *fname)
{
int i;
char *p;
//fprintf(stderr, "SPLIT_INIT %s\n", fname);
memset(s, 0, sizeof(*s));
for (i = 0; i < MAX_SPLIT; i++)
{
s->fd[i] = -1;
}
strcpy(s->fname, fname);
s->max_split = 1;
p = strrchr(fname, '.');
if (p && (strcasecmp(p, ".wbfs") == 0))
{
s->max_split = MAX_SPLIT;
}
}
void split_set_size(split_info_t *s, u64 split_size, u64 total_size)
{
s->total_size = total_size;
s->split_size = split_size;
s->total_sec = total_size / 512;
s->split_sec = split_size / 512;
}
void split_close(split_info_t *s)
{
int i;
char fname[1024];
char tmpname[1024];
for (i = 0; i < s->max_split; i++)
{
if (s->fd[i] >= 0)
{
close(s->fd[i]);
}
}
if (s->create_mode)
{
split_get_fname(s, -1, fname);
split_get_fname(s, 0, tmpname);
rename(tmpname, fname);
}
memset(s, 0, sizeof(*s));
}
int split_create(split_info_t *s, char *fname, u64 split_size, u64 total_size, bool overwrite)
{
int i;
int fd;
char sname[1024];
int error = 0;
split_init(s, fname);
s->create_mode = 1;
// check if any file already exists
for (i = -1; i < s->max_split; i++)
{
split_get_fname(s, i, sname);
if (overwrite)
{
remove(sname);
}
else
{
fd = open(sname, O_RDONLY);
if (fd >= 0)
{
fprintf(stderr, "Error: file already exists: %s\n", sname);
close(fd);
error = 1;
}
}
}
if (error)
{
split_init(s, "");
return -1;
}
split_set_size(s, split_size, total_size);
return 0;
}
int split_open(split_info_t *s, char *fname)
{
int i;
u64 size = 0;
u64 total_size = 0;
u64 split_size = 0;
int fd;
split_init(s, fname);
for (i = 0; i < s->max_split; i++)
{
fd = split_open_file(s, i);
if (fd < 0)
{
if (i == 0) goto err;
break;
}
// check previous size - all splits except last must be same size
if (i > 0 && size != split_size)
{
fprintf(stderr, "split %d: invalid size "FMT_lld"", i, size);
goto err;
}
// get size
//fseeko(f, 0, SEEK_END);
//size = ftello(f);
size = lseek(fd, 0, SEEK_END);
// check sector alignment
if (size % 512)
{
fprintf(stderr, "split %d: size ("FMT_lld") not sector (512) aligned!", i, size);
}
// first sets split size
if (i == 0)
{
split_size = size;
}
total_size += size;
}
split_set_size(s, split_size, total_size);
return 0;
err: split_close(s);
return -1;
}

View File

@ -1,46 +1,46 @@
#ifndef _SPLITS_H
#define _SPLITS_H
#ifdef __cplusplus
extern "C"
{
#endif
#define MAX_SPLIT 10
typedef struct split_info
{
char fname[1024];
//FILE *f[MAX_SPLIT];
int fd[MAX_SPLIT];
//u64 fsize[MAX_SPLIT];
u32 split_sec;
u32 total_sec;
u64 split_size;
u64 total_size;
int create_mode;
int max_split;
} split_info_t;
// 1 sector less than 4gb
extern u64 OPT_split_size;
void split_get_fname(split_info_t *s, int idx, char *fname);
//FILE *split_open_file(split_info_t *s, int idx);
//FILE *split_get_file(split_info_t *s, u32 lba, u32 *sec_count, int fill);
int split_open_file(split_info_t *s, int idx);
int split_get_file(split_info_t *s, u32 lba, u32 *sec_count, int fill);
int split_fill(split_info_t *s, int idx, u64 size);
int split_read_sector(void *_fp, u32 lba, u32 count, void*buf);
int split_write_sector(void *_fp, u32 lba, u32 count, void*buf);
void split_init(split_info_t *s, char *fname);
void split_set_size(split_info_t *s, u64 split_size, u64 total_size);
void split_close(split_info_t *s);
int split_open(split_info_t *s, char *fname);
int split_create(split_info_t *s, char *fname, u64 split_size, u64 total_size, bool overwrite);
#ifdef __cplusplus
}
#endif
#endif //_SPLITS_H
#ifndef _SPLITS_H
#define _SPLITS_H
#ifdef __cplusplus
extern "C"
{
#endif
#define MAX_SPLIT 10
typedef struct split_info
{
char fname[1024];
//FILE *f[MAX_SPLIT];
int fd[MAX_SPLIT];
//u64 fsize[MAX_SPLIT];
u32 split_sec;
u32 total_sec;
u64 split_size;
u64 total_size;
int create_mode;
int max_split;
} split_info_t;
// 1 sector less than 4gb
extern u64 OPT_split_size;
void split_get_fname(split_info_t *s, int idx, char *fname);
//FILE *split_open_file(split_info_t *s, int idx);
//FILE *split_get_file(split_info_t *s, u32 lba, u32 *sec_count, int fill);
int split_open_file(split_info_t *s, int idx);
int split_get_file(split_info_t *s, u32 lba, u32 *sec_count, int fill);
int split_fill(split_info_t *s, int idx, u64 size);
int split_read_sector(void *_fp, u32 lba, u32 count, void*buf);
int split_write_sector(void *_fp, u32 lba, u32 count, void*buf);
void split_init(split_info_t *s, char *fname);
void split_set_size(split_info_t *s, u64 split_size, u64 total_size);
void split_close(split_info_t *s);
int split_open(split_info_t *s, char *fname);
int split_create(split_info_t *s, char *fname, u64 split_size, u64 total_size, bool overwrite);
#ifdef __cplusplus
}
#endif
#endif //_SPLITS_H

View File

@ -1,144 +1,144 @@
#include <stdio.h>
#include <unistd.h>
#include <malloc.h>
#include <ogcsys.h>
#include <errno.h>
#include "usbloader/sdhc.h"
#include "usbloader/usbstorage2.h"
#include "fatmounter.h"
#include "wbfs_rw.h"
#include "wbfs_base.h"
s32 Wbfs::done = -1;
s32 Wbfs::total = -1;
u32 Wbfs::nb_sectors;
Wbfs::Wbfs(u32 device, u32 lba, u32 size) :
hdd(NULL)
{
this->device = device;
this->lba = lba;
this->size = size;
}
void Wbfs::GetProgressValue(s32 * d, s32 * m)
{
*d = done;
*m = total;
}
s32 Wbfs::Init(u32 device)
{
s32 ret;
switch (device)
{
case WBFS_DEVICE_USB:
/* Initialize USB storage */
ret = USBStorage2_Init();
if (ret >= 0)
{
/* Setup callbacks */
readCallback = __ReadUSB;
writeCallback = __WriteUSB;
/* Device info */
/* Get USB capacity */
nb_sectors = USBStorage2_GetCapacity(&sector_size);
if (!nb_sectors) return -1;
}
else return ret;
break;
case WBFS_DEVICE_SDHC:
/* Initialize SDHC */
ret = SDHC_Init();
if (ret)
{
/* Setup callbacks */
readCallback = __ReadSDHC;
writeCallback = __WriteSDHC;
/* Device info */
nb_sectors = 0;
sector_size = SDHC_SECTOR_SIZE;
}
else return -1;
break;
}
return 0;
}
void Wbfs::Close()
{
if (hdd)
{
wbfs_close(hdd);
hdd = NULL;
}
WBFSDevice_deInit();
}
// Default behavior: can't format
s32 Wbfs::Format()
{
return -1;
}
s32 Wbfs::CheckGame(u8 *discid)
{
wbfs_disc_t *disc = NULL;
/* Try to open game disc */
disc = OpenDisc(discid);
if (disc)
{
/* Close disc */
CloseDisc(disc);
return 1;
}
return 0;
}
s32 Wbfs::GameSize(u8 *discid, f32 *size)
{
wbfs_disc_t *disc = NULL;
u32 sectors;
/* Open disc */
disc = OpenDisc(discid);
if (!disc) return -2;
/* Get game size in sectors */
sectors = wbfs_sector_used(disc->p, disc->header);
/* Copy value */
*size = (disc->p->wbfs_sec_sz / GB_SIZE) * sectors;
/* Close disc */
CloseDisc(disc);
return 0;
}
wbfs_t *Wbfs::GetHddInfo()
{
return hdd;
}
bool Wbfs::Mounted()
{
return hdd == NULL;
}
bool Wbfs::ShowFreeSpace(void)
{
return true;
}
#include <stdio.h>
#include <unistd.h>
#include <malloc.h>
#include <ogcsys.h>
#include <errno.h>
#include "usbloader/sdhc.h"
#include "usbloader/usbstorage2.h"
#include "fatmounter.h"
#include "wbfs_rw.h"
#include "wbfs_base.h"
s32 Wbfs::done = -1;
s32 Wbfs::total = -1;
u32 Wbfs::nb_sectors;
Wbfs::Wbfs(u32 device, u32 lba, u32 size) :
hdd(NULL)
{
this->device = device;
this->lba = lba;
this->size = size;
}
void Wbfs::GetProgressValue(s32 * d, s32 * m)
{
*d = done;
*m = total;
}
s32 Wbfs::Init(u32 device)
{
s32 ret;
switch (device)
{
case WBFS_DEVICE_USB:
/* Initialize USB storage */
ret = USBStorage2_Init();
if (ret >= 0)
{
/* Setup callbacks */
readCallback = __ReadUSB;
writeCallback = __WriteUSB;
/* Device info */
/* Get USB capacity */
nb_sectors = USBStorage2_GetCapacity(&sector_size);
if (!nb_sectors) return -1;
}
else return ret;
break;
case WBFS_DEVICE_SDHC:
/* Initialize SDHC */
ret = SDHC_Init();
if (ret)
{
/* Setup callbacks */
readCallback = __ReadSDHC;
writeCallback = __WriteSDHC;
/* Device info */
nb_sectors = 0;
sector_size = SDHC_SECTOR_SIZE;
}
else return -1;
break;
}
return 0;
}
void Wbfs::Close()
{
if (hdd)
{
wbfs_close(hdd);
hdd = NULL;
}
WBFSDevice_deInit();
}
// Default behavior: can't format
s32 Wbfs::Format()
{
return -1;
}
s32 Wbfs::CheckGame(u8 *discid)
{
wbfs_disc_t *disc = NULL;
/* Try to open game disc */
disc = OpenDisc(discid);
if (disc)
{
/* Close disc */
CloseDisc(disc);
return 1;
}
return 0;
}
s32 Wbfs::GameSize(u8 *discid, f32 *size)
{
wbfs_disc_t *disc = NULL;
u32 sectors;
/* Open disc */
disc = OpenDisc(discid);
if (!disc) return -2;
/* Get game size in sectors */
sectors = wbfs_sector_used(disc->p, disc->header);
/* Copy value */
*size = (disc->p->wbfs_sec_sz / GB_SIZE) * sectors;
/* Close disc */
CloseDisc(disc);
return 0;
}
wbfs_t *Wbfs::GetHddInfo()
{
return hdd;
}
bool Wbfs::Mounted()
{
return hdd == NULL;
}
bool Wbfs::ShowFreeSpace(void)
{
return true;
}

View File

@ -1,168 +1,168 @@
#include <ogcsys.h>
#include <malloc.h>
#include <string.h>
#include "usbloader/sdhc.h"
#include "usbloader/usbstorage2.h"
#include "usbloader/wdvd.h"
#include "wbfs_rw.h"
/* Constants */
#define MAX_NB_SECTORS 32
u32 sector_size = 512;
rw_sector_callback_t readCallback = NULL;
rw_sector_callback_t writeCallback = NULL;
void SetSectorSize(u32 size)
{
sector_size = size;
}
s32 __ReadDVD(void *fp, u32 lba, u32 len, void *iobuf)
{
void *buffer = NULL;
u64 offset;
u32 mod, size;
s32 ret;
/* Calculate offset */
offset = ((u64) lba) << 2;
/* Calcualte sizes */
mod = len % 32;
size = len - mod;
/* Read aligned data */
if (size)
{
ret = WDVD_UnencryptedRead(iobuf, size, offset);
if (ret < 0) goto out;
}
/* Read non-aligned data */
if (mod)
{
/* Allocate memory */
buffer = memalign(32, 0x20);
if (!buffer) return -1;
/* Read data */
ret = WDVD_UnencryptedRead(buffer, 0x20, offset + size);
if (ret < 0) goto out;
/* Copy data */
void *ptr = ((u8 *) iobuf) + size;
memcpy(ptr, buffer, mod);
}
/* Success */
ret = 0;
out:
/* Free memory */
if (buffer) free(buffer);
return ret;
}
s32 __ReadUSB(void *fp, u32 lba, u32 count, void *iobuf)
{
u32 cnt = 0;
s32 ret;
/* Do reads */
while (cnt < count)
{
void *ptr = ((u8 *) iobuf) + (cnt * sector_size);
u32 sectors = (count - cnt);
/* Read sectors is too big */
if (sectors > MAX_NB_SECTORS) sectors = MAX_NB_SECTORS;
/* USB read */
ret = USBStorage2_ReadSectors(lba + cnt, sectors, ptr);
if (ret < 0) return ret;
/* Increment counter */
cnt += sectors;
}
return 0;
}
s32 __WriteUSB(void *fp, u32 lba, u32 count, void *iobuf)
{
u32 cnt = 0;
s32 ret;
/* Do writes */
while (cnt < count)
{
void *ptr = ((u8 *) iobuf) + (cnt * sector_size);
u32 sectors = (count - cnt);
/* Write sectors is too big */
if (sectors > MAX_NB_SECTORS) sectors = MAX_NB_SECTORS;
/* USB write */
ret = USBStorage2_WriteSectors(lba + cnt, sectors, ptr);
if (ret < 0) return ret;
/* Increment counter */
cnt += sectors;
}
return 0;
}
s32 __ReadSDHC(void *fp, u32 lba, u32 count, void *iobuf)
{
u32 cnt = 0;
s32 ret;
/* Do reads */
while (cnt < count)
{
void *ptr = ((u8 *) iobuf) + (cnt * sector_size);
u32 sectors = (count - cnt);
/* Read sectors is too big */
if (sectors > MAX_NB_SECTORS) sectors = MAX_NB_SECTORS;
/* SDHC read */
ret = SDHC_ReadSectors(lba + cnt, sectors, ptr);
if (!ret) return -1;
/* Increment counter */
cnt += sectors;
}
return 0;
}
s32 __WriteSDHC(void *fp, u32 lba, u32 count, void *iobuf)
{
u32 cnt = 0;
s32 ret;
/* Do writes */
while (cnt < count)
{
void *ptr = ((u8 *) iobuf) + (cnt * sector_size);
u32 sectors = (count - cnt);
/* Write sectors is too big */
if (sectors > MAX_NB_SECTORS) sectors = MAX_NB_SECTORS;
/* SDHC write */
ret = SDHC_WriteSectors(lba + cnt, sectors, ptr);
if (!ret) return -1;
/* Increment counter */
cnt += sectors;
}
return 0;
}
#include <ogcsys.h>
#include <malloc.h>
#include <string.h>
#include "usbloader/sdhc.h"
#include "usbloader/usbstorage2.h"
#include "usbloader/wdvd.h"
#include "wbfs_rw.h"
/* Constants */
#define MAX_NB_SECTORS 32
u32 sector_size = 512;
rw_sector_callback_t readCallback = NULL;
rw_sector_callback_t writeCallback = NULL;
void SetSectorSize(u32 size)
{
sector_size = size;
}
s32 __ReadDVD(void *fp, u32 lba, u32 len, void *iobuf)
{
void *buffer = NULL;
u64 offset;
u32 mod, size;
s32 ret;
/* Calculate offset */
offset = ((u64) lba) << 2;
/* Calcualte sizes */
mod = len % 32;
size = len - mod;
/* Read aligned data */
if (size)
{
ret = WDVD_UnencryptedRead(iobuf, size, offset);
if (ret < 0) goto out;
}
/* Read non-aligned data */
if (mod)
{
/* Allocate memory */
buffer = memalign(32, 0x20);
if (!buffer) return -1;
/* Read data */
ret = WDVD_UnencryptedRead(buffer, 0x20, offset + size);
if (ret < 0) goto out;
/* Copy data */
void *ptr = ((u8 *) iobuf) + size;
memcpy(ptr, buffer, mod);
}
/* Success */
ret = 0;
out:
/* Free memory */
if (buffer) free(buffer);
return ret;
}
s32 __ReadUSB(void *fp, u32 lba, u32 count, void *iobuf)
{
u32 cnt = 0;
s32 ret;
/* Do reads */
while (cnt < count)
{
void *ptr = ((u8 *) iobuf) + (cnt * sector_size);
u32 sectors = (count - cnt);
/* Read sectors is too big */
if (sectors > MAX_NB_SECTORS) sectors = MAX_NB_SECTORS;
/* USB read */
ret = USBStorage2_ReadSectors(lba + cnt, sectors, ptr);
if (ret < 0) return ret;
/* Increment counter */
cnt += sectors;
}
return 0;
}
s32 __WriteUSB(void *fp, u32 lba, u32 count, void *iobuf)
{
u32 cnt = 0;
s32 ret;
/* Do writes */
while (cnt < count)
{
void *ptr = ((u8 *) iobuf) + (cnt * sector_size);
u32 sectors = (count - cnt);
/* Write sectors is too big */
if (sectors > MAX_NB_SECTORS) sectors = MAX_NB_SECTORS;
/* USB write */
ret = USBStorage2_WriteSectors(lba + cnt, sectors, ptr);
if (ret < 0) return ret;
/* Increment counter */
cnt += sectors;
}
return 0;
}
s32 __ReadSDHC(void *fp, u32 lba, u32 count, void *iobuf)
{
u32 cnt = 0;
s32 ret;
/* Do reads */
while (cnt < count)
{
void *ptr = ((u8 *) iobuf) + (cnt * sector_size);
u32 sectors = (count - cnt);
/* Read sectors is too big */
if (sectors > MAX_NB_SECTORS) sectors = MAX_NB_SECTORS;
/* SDHC read */
ret = SDHC_ReadSectors(lba + cnt, sectors, ptr);
if (!ret) return -1;
/* Increment counter */
cnt += sectors;
}
return 0;
}
s32 __WriteSDHC(void *fp, u32 lba, u32 count, void *iobuf)
{
u32 cnt = 0;
s32 ret;
/* Do writes */
while (cnt < count)
{
void *ptr = ((u8 *) iobuf) + (cnt * sector_size);
u32 sectors = (count - cnt);
/* Write sectors is too big */
if (sectors > MAX_NB_SECTORS) sectors = MAX_NB_SECTORS;
/* SDHC write */
ret = SDHC_WriteSectors(lba + cnt, sectors, ptr);
if (!ret) return -1;
/* Increment counter */
cnt += sectors;
}
return 0;
}

View File

@ -1,25 +1,25 @@
#ifndef _WBFS_RW_H
#define _WBFS_RW_H
#ifdef __cplusplus
extern "C"
{
#endif
#include "libs/libwbfs/libwbfs.h"
extern u32 sector_size;
extern rw_sector_callback_t readCallback;
extern rw_sector_callback_t writeCallback;
s32 __ReadDVD(void *fp, u32 lba, u32 len, void *iobuf);
s32 __ReadUSB(void *fp, u32 lba, u32 count, void *iobuf);
s32 __WriteUSB(void *fp, u32 lba, u32 count, void *iobuf);
s32 __ReadSDHC(void *fp, u32 lba, u32 count, void *iobuf);
s32 __WriteSDHC(void *fp, u32 lba, u32 count, void *iobuf);
#ifdef __cplusplus
}
#endif
#endif //_WBFS_RW_H
#ifndef _WBFS_RW_H
#define _WBFS_RW_H
#ifdef __cplusplus
extern "C"
{
#endif
#include "libs/libwbfs/libwbfs.h"
extern u32 sector_size;
extern rw_sector_callback_t readCallback;
extern rw_sector_callback_t writeCallback;
s32 __ReadDVD(void *fp, u32 lba, u32 len, void *iobuf);
s32 __ReadUSB(void *fp, u32 lba, u32 count, void *iobuf);
s32 __WriteUSB(void *fp, u32 lba, u32 count, void *iobuf);
s32 __ReadSDHC(void *fp, u32 lba, u32 count, void *iobuf);
s32 __WriteSDHC(void *fp, u32 lba, u32 count, void *iobuf);
#ifdef __cplusplus
}
#endif
#endif //_WBFS_RW_H

View File

@ -1,34 +1,34 @@
#ifndef _WBFS_WBFS_H
#define _WBFS_WBFS_H
#include "wbfs_base.h"
#include "libs/libwbfs/libwbfs.h"
class Wbfs_Wbfs: public Wbfs
{
public:
Wbfs_Wbfs(u32 device, u32 lba, u32 size) :
Wbfs(device, lba, size)
{
}
s32 Open();
wbfs_disc_t* OpenDisc(u8 *);
void CloseDisc(wbfs_disc_t *);
s32 Format();
s32 GetCount(u32 *);
s32 GetHeaders(struct discHdr *, u32, u32);
s32 AddGame();
s32 RemoveGame(u8 *);
s32 DiskSpace(f32 *, f32 *);
s32 RenameGame(u8 *, const void *);
s32 ReIDGame(u8 *, const void *);
f32 EstimateGameSize();
};
#endif //_WBFS_WBFS_H
#ifndef _WBFS_WBFS_H
#define _WBFS_WBFS_H
#include "wbfs_base.h"
#include "libs/libwbfs/libwbfs.h"
class Wbfs_Wbfs: public Wbfs
{
public:
Wbfs_Wbfs(u32 device, u32 lba, u32 size) :
Wbfs(device, lba, size)
{
}
s32 Open();
wbfs_disc_t* OpenDisc(u8 *);
void CloseDisc(wbfs_disc_t *);
s32 Format();
s32 GetCount(u32 *);
s32 GetHeaders(struct discHdr *, u32, u32);
s32 AddGame();
s32 RemoveGame(u8 *);
s32 DiskSpace(f32 *, f32 *);
s32 RenameGame(u8 *, const void *);
s32 ReIDGame(u8 *, const void *);
f32 EstimateGameSize();
};
#endif //_WBFS_WBFS_H

35
source/utils/rockout.cpp Normal file
View File

@ -0,0 +1,35 @@
#include "libwiigui/gui.h"
#include "themes/CTheme.h"
#include "usbloader/GameList.h"
#include "settings/GameTitles.h"
#include "menu/menus.h"
extern GuiImageData * pointer[4];
void rockout(int gameSelected, int f)
{
HaltGui();
if (gameSelected >= 0 && gameSelected < gameList.size() && (strcasestr(GameTitles.GetTitle(gameList[gameSelected]), "guitar")
|| strcasestr(GameTitles.GetTitle(gameList[gameSelected]), "band") || strcasestr(GameTitles.GetTitle(gameList[gameSelected]),
"rock")))
{
for (int i = 0; i < 4; i++)
delete pointer[i];
pointer[0] = Resources::GetImageData("rplayer1_point.png");
pointer[1] = Resources::GetImageData("rplayer2_point.png");
pointer[2] = Resources::GetImageData("rplayer3_point.png");
pointer[3] = Resources::GetImageData("rplayer4_point.png");
}
else
{
for (int i = 0; i < 4; i++)
delete pointer[i];
pointer[0] = Resources::GetImageData("player1_point.png");
pointer[1] = Resources::GetImageData("player2_point.png");
pointer[2] = Resources::GetImageData("player3_point.png");
pointer[3] = Resources::GetImageData("player4_point.png");
}
ResumeGui();
}

6
source/utils/rockout.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef ROCKOUT_H_
#define ROCKOUT_H_
void rockout(int gameSelected, int f = 0);
#endif

6
source/utils/tools.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef TOOLS_H_
#define TOOLS_H_
#define cut_bounds(x, min, max) ( ((x) < (min)) ? (min) : ((x) > (max)) ? (max) : (x) )
#endif

View File

@ -1,23 +1,23 @@
#ifndef _UTILS_H_
#define _UTILS_H_
#ifdef __cplusplus
extern "C"
{
#endif
/* Constants */
#define KB_SIZE 1024.0
#define MB_SIZE 1048576.0
#define GB_SIZE 1073741824.0
/* Macros */
#define round_up(x,n) (-(-(x) & -(n)))
/* Prototypes */
u32 swap32(u32);
#ifdef __cplusplus
}
#endif
#endif
#ifndef _UTILS_H_
#define _UTILS_H_
#ifdef __cplusplus
extern "C"
{
#endif
/* Constants */
#define KB_SIZE 1024.0
#define MB_SIZE 1048576.0
#define GB_SIZE 1073741824.0
/* Macros */
#define round_up(x,n) (-(-(x) & -(n)))
/* Prototypes */
u32 swap32(u32);
#ifdef __cplusplus
}
#endif
#endif