usbloadergx/source/usbloader/alternatedol.c

276 lines
6.7 KiB
C
Raw Normal View History

2009-07-31 14:45:14 +02:00
#include <ogcsys.h>
#include <stdio.h>
#include <gccore.h>
#include <string.h>
#include <malloc.h>
#include "fatmounter.h"
#include "apploader.h"
#include "wdvd.h"
#include "fstfile.h"
#include "../patches/dvd_broadway.h"
extern u8 mountMethod;
2009-07-31 14:45:14 +02:00
/** Alternate dolloader made by WiiPower modified by dimok **/
bool Load_Dol( void **buffer, int* dollen, char * filepath )
{
2009-07-31 14:45:14 +02:00
int ret;
FILE* file;
void* dol_buffer;
char fullpath[200];
char gameidbuffer6[7];
memset( gameidbuffer6, 0, 7 );
memcpy( gameidbuffer6, ( char* )0x80000000, 6 );
snprintf( fullpath, 200, "%s%s.dol", filepath, gameidbuffer6 );
2009-07-31 14:45:14 +02:00
// SDCard_Init();
// USBDevice_Init();
file = fopen( fullpath, "rb" );
2009-07-31 14:45:14 +02:00
if ( file == NULL )
{
fclose( file );
// SDCard_deInit();
// USBDevice_deInit();
2009-07-31 14:45:14 +02:00
return false;
}
int filesize;
fseek( file, 0, SEEK_END );
filesize = ftell( file );
fseek( file, 0, SEEK_SET );
dol_buffer = malloc( filesize );
if ( dol_buffer == NULL )
{
fclose( file );
// SDCard_deInit();
// USBDevice_deInit();
return false;
2009-07-31 14:45:14 +02:00
}
ret = fread( dol_buffer, 1, filesize, file );
if ( ret != filesize )
{
free( dol_buffer );
fclose( file );
// SDCard_deInit();
// USBDevice_deInit();
return false;
2009-07-31 14:45:14 +02:00
}
fclose( file );
2009-07-31 14:45:14 +02:00
// SDCard_deInit();
// USBDevice_deInit();
2009-07-31 14:45:14 +02:00
*buffer = dol_buffer;
*dollen = filesize;
return true;
}
bool Remove_001_Protection( void *Address, int Size )
{
u8 SearchPattern[16] = { 0x40, 0x82, 0x00, 0x0C, 0x38, 0x60, 0x00, 0x01, 0x48, 0x00, 0x02, 0x44, 0x38, 0x61, 0x00, 0x18 };
u8 PatchData[16] = { 0x40, 0x82, 0x00, 0x04, 0x38, 0x60, 0x00, 0x01, 0x48, 0x00, 0x02, 0x44, 0x38, 0x61, 0x00, 0x18 };
2009-07-31 14:45:14 +02:00
void *Addr = Address;
void *Addr_end = Address + Size;
2009-07-31 14:45:14 +02:00
while ( Addr <= Addr_end - sizeof( SearchPattern ) )
{
if ( memcmp( Addr, SearchPattern, sizeof( SearchPattern ) ) == 0 )
{
memcpy( Addr, PatchData, sizeof( PatchData ) );
2009-07-31 14:45:14 +02:00
return true;
}
Addr += 4;
}
return false;
}
typedef struct _dolheader
{
2009-07-31 14:45:14 +02:00
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;
static dolheader *dolfile;
u32 load_dol_image( void *dolstart, u8 videoSelected, u8 patchcountrystring, u8 vipatch, u8 cheat )
{
2009-07-31 14:45:14 +02:00
u32 i;
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] );
memmove ( ( void * ) dolfile->text_start[i], dolstart + dolfile->text_pos[i], dolfile->text_size[i] );
gamepatches( ( void * ) dolfile->text_start[i], dolfile->text_size[i], videoSelected, patchcountrystring, vipatch, cheat );
Remove_001_Protection( ( void * ) dolfile->data_start[i], dolfile->data_size[i] );
2009-07-31 14:45:14 +02:00
}
for ( i = 0; i < 11; i++ )
{
if ( ( !dolfile->data_size[i] ) || ( dolfile->data_start[i] < 0x100 ) ) continue;
memmove ( ( void * ) dolfile->data_start[i], dolstart + dolfile->data_pos[i], dolfile->data_size[i] );
gamepatches( ( void * ) dolfile->data_start[i], dolfile->data_size[i], videoSelected, patchcountrystring, vipatch, cheat );
Remove_001_Protection( ( void * ) dolfile->data_start[i], dolfile->data_size[i] );
DCFlushRangeNoSync ( ( void * ) dolfile->data_start[i], dolfile->data_size[i] );
2009-07-31 14:45:14 +02:00
}
/*
memset ((void *) dolfile->bss_start, 0, dolfile->bss_size);
DCFlushRange((void *) dolfile->bss_start, dolfile->bss_size);
*/
return dolfile->entry_point;
}
return 0;
}
static int i;
static int phase;
u32 load_dol_start( void *dolstart )
{
if ( dolstart )
{
dolfile = ( dolheader * )dolstart;
2009-07-31 14:45:14 +02:00
return dolfile->entry_point;
}
else
{
2009-07-31 14:45:14 +02:00
return 0;
}
memset( ( void * )dolfile->bss_start, 0, dolfile->bss_size );
DCFlushRange( ( void * )dolfile->bss_start, dolfile->bss_size );
2009-07-31 14:45:14 +02:00
phase = 0;
i = 0;
}
bool load_dol_image_modified( void **offset, u32 *pos, u32 *len )
{
if ( phase == 0 )
{
if ( i == 7 )
{
2009-07-31 14:45:14 +02:00
phase = 1;
i = 0;
}
else
{
if ( ( !dolfile->text_size[i] ) || ( dolfile->text_start[i] < 0x100 ) )
{
2009-07-31 14:45:14 +02:00
*offset = 0;
*pos = 0;
*len = 0;
}
else
{
*offset = ( void * )dolfile->text_start[i];
2009-07-31 14:45:14 +02:00
*pos = dolfile->text_pos[i];
*len = dolfile->text_size[i];
}
i++;
return true;
}
}
if ( phase == 1 )
{
if ( i == 11 )
{
2009-07-31 14:45:14 +02:00
phase = 2;
return false;
}
if ( ( !dolfile->data_size[i] ) || ( dolfile->data_start[i] < 0x100 ) )
{
2009-07-31 14:45:14 +02:00
*offset = 0;
*pos = 0;
*len = 0;
}
else
{
*offset = ( void * )dolfile->data_start[i];
2009-07-31 14:45:14 +02:00
*pos = dolfile->data_pos[i];
*len = dolfile->data_size[i];
}
i++;
return true;
}
return false;
}
static vu32 dvddone = 0;
void __dvd_readidcb( s32 result )
{
dvddone = result;
}
u32 Load_Dol_from_disc( u32 doloffset, u8 videoSelected, u8 patchcountrystring, u8 vipatch, u8 cheat )
{
2009-07-31 14:45:14 +02:00
int ret;
void *dol_header;
u32 entrypoint;
dol_header = memalign( 32, sizeof( dolheader ) );
if ( dol_header == NULL )
{
2009-07-31 14:45:14 +02:00
return -1;
}
if ( !mountMethod )ret = WDVD_Read( dol_header, sizeof( dolheader ), ( doloffset << 2 ) );
else
{
dvddone = 0;
ret = bwDVD_LowRead( dol_header, sizeof( dolheader ), doloffset, __dvd_readidcb );
while ( ret >= 0 && dvddone == 0 );
}
entrypoint = load_dol_start( dol_header );
2009-07-31 14:45:14 +02:00
if ( entrypoint == 0 )
{
free( dol_header );
2009-07-31 14:45:14 +02:00
return -1;
}
void *offset;
u32 pos;
u32 len;
while ( load_dol_image_modified( &offset, &pos, &len ) )
{
if ( len != 0 )
{
ret = WDVD_Read( offset, len, ( doloffset << 2 ) + pos );
2009-07-31 14:45:14 +02:00
gamepatches( offset, len, videoSelected, patchcountrystring, vipatch, cheat );
2009-07-31 14:45:14 +02:00
Remove_001_Protection( offset, len );
DCFlushRange( offset, len );
2009-07-31 14:45:14 +02:00
}
}
free( dol_header );
2009-07-31 14:45:14 +02:00
return entrypoint;
2009-07-31 14:45:14 +02:00
}