Exemple #1
0
int readPrx( const char * file, int heap_id, u8 ** outbuf )
{
	log( "read %s to memory!\n", file );
	int fd = sceIoOpen( file, PSP_O_RDONLY, 0644 );
	if ( fd < 0 )
	{
		log( "failed in opening %s\n", file );
		return -1;
	}
	u8 * inbuf = ( u8 * )sceKernelAllocHeapMemory( heap_id, CXMB_MKCTF_BUF_SIZE / 2 );
	int size = sceIoRead( fd, inbuf, CXMB_MKCTF_BUF_SIZE / 2 );
	if ( inbuf[0x150] == 0x1F && inbuf[0x151] == 0x8B )
	{
		log( "uncompress gzip file!\n" );
		*outbuf = ( u8 * )sceKernelAllocHeapMemory( heap_id, CXMB_MKCTF_BUF_SIZE / 2 );
		int size = sceKernelGzipDecompress( *outbuf, CXMB_MKCTF_BUF_SIZE / 2, &inbuf[0x150], 0 );
		log( "uncompressed size %08x!\n", size );
		sceKernelFreeHeapMemory( heap_id, inbuf );
		if ( size > 0 && size < CXMB_MAX_FILE_SIZE )
		{
			return size;
		}
		else
		{
			sceKernelFreeHeapMemory( heap_id, outbuf );
			return -1;
		}
	}
	else
	{
		*outbuf = inbuf;
		return size;
	}
	return -1;
}
Exemple #2
0
/*
 * Initialize the System Call table.  It is initialized the very
 * first time a SCE_LIB_SYSCALL_EXPORT resident library is 
 * registered to the system.  The table makes room for
 * SYSCALL_TABLE_FUNCTION_TABLE_ENTRIES functions to be stored
 * in it.  These function pointer slots are initialized to the 
 * address of the function "UndefSyscall", which simply returns an 
 * error, marking a slot as currently being unused.
 * 
 * In addition, the internal SyscallEntryTable linked list is initialized
 * and g_pSysEntControl is set to the top member of it.
 * 
 * @param seed Used to set the start address of the system call table.
 * @param lcSyscallTable Receive a pointer to the allocated system
 *                       call table.
 * 
 * @return 0 on success.
 */
s32 SyscallTableInit(u32 seed, SceSyscallTable **syscallTable) 
{
   u32 i;
   s32 status;
   SceSyscallTable *sysCallTable;  
     
   sysCallTable = sceKernelAllocHeapMemory(g_loadCoreHeap(), SYSCALL_TABLE_SIZE); 
   if (sysCallTable == NULL)
       return SCE_ERROR_KERNEL_ERROR;

   sysCallTable->next = NULL;
   sysCallTable->seed = seed << 2;
   sysCallTable->funcTableSize = SYSCALL_TABLE_FUNCTION_TABLE_SIZE;
   sysCallTable->tableSize = SYSCALL_TABLE_SIZE;
   
   //0x000003B0 - 0x000003C8
   for (i = 0; i < SYSCALL_TABLE_FUNCTION_TABLE_ENTRIES; i++) 
        sysCallTable->syscalls[i] = (void (*)())UndefSyscall;
    
   //0x000003D0 - 0x000003F8
   initialSysEntTable[0].next = NULL;      
   for (i = 0; i < TOP_SYSCALL_ENTRY_TABLE; i++)
        initialSysEntTable[i + 1].next = &initialSysEntTable[i];
   
   g_pFreeSysEnt = &initialSysEntTable[TOP_SYSCALL_ENTRY_TABLE]; //0x0000040C 
   if (g_pFreeSysEnt == NULL) { //0x00000410
       g_pSysEntControl = (SceSysCallEntryTable *)sceKernelAllocHeapMemory(g_loadCoreHeap(), sizeof(SceSysCallEntryTable)); //0x00000498 & 0x000004A4
   }
   else {
       g_pSysEntControl = g_pFreeSysEnt; //0x00000420
       g_pFreeSysEnt = g_pFreeSysEnt->next; //0x0000041C
   }
    
   //0x00000424 - 0x00000440
   /* Initialize the first SYSCALL table entry. */
   g_pSysEntControl->next = NULL; 
   g_pSysEntControl->inUse = SCE_FALSE;
   g_pSysEntControl->numEntries = SYSCALL_TABLE_DEFAULT_ENTRIES;
   g_pSysEntControl->startAddr = 0;
   
   status = sceKernelRegisterSystemCallTable(sysCallTable); //0x0000043C
   if (status != SCE_ERROR_OK) { //0x00000444
       sceKernelFreeHeapMemory(g_loadCoreHeap(), sysCallTable); //0x00000478 & 0x00000484
       return status;
   }
   *syscallTable = sysCallTable;
   return SCE_ERROR_OK; 
}
Exemple #3
0
int IoOpen_new( PspIoDrvFileArg * arg, char * file, int flags, SceMode mode )
{
	PspIoDrvArg * drv = arg->drv;
	if( ctf_handler && arg->fs_num == 0 )
	{
		ctf_handler[handler_count].num = inCtf( file );
		if ( ctf_handler[handler_count].num >= 0 )
		{
			log( "replace %s\n", file );
			arg->drv = ms_drv;
			int ret = fatms_drv->funcs->IoOpen( arg, theme_file, flags, mode);
			if ( ret < 0 )
			{
				arg->drv = drv;
			}
			else
			{
				ctf_handler[handler_count].offset = fatms_drv->funcs->IoLseek( arg, ctf_header[ctf_handler[handler_count].num].start, PSP_SEEK_SET );
				ctf_handler[handler_count].arg = arg->arg;
				handler_count ++;
				if ( handler_count % 32 == 0 )
				{
					CtfHandler * tmp = sceKernelAllocHeapMemory( mem_id, sizeof( CtfHandler ) * ( handler_count + 32 ) );
					memcpy( tmp, ctf_handler, sizeof( CtfHandler ) * handler_count );
					sceKernelFreeHeapMemory( mem_id, ctf_handler );
					ctf_handler = tmp;
				}
				arg->drv = drv;
				return ret;
			}
		}
	}
	int ret = IoOpen( arg, file, flags, mode );
	if ( strcmp( file, "/vsh/theme/custom_theme.dat" ) == 0 && flags == ( PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC ) )
	{
		t_record = arg->arg;
		log( "open %s flags %08x\ntheme file selected: %s\n", file, flags, selected_theme_file );
	}
	return ret;
}
Exemple #4
0
/*
 * Allocate a system-call-entry-table for a resident library exporting 
 * its functions via the SYSCALL_EXPORT technique.  In order to allocate 
 * such a table, we start at the object pointed to by g_pSysEntControl 
 * (normally the top member of the initialSysEntTable linked list).  
 * We scroll through that data structure until we find an object which 
 * is not already being used and which is big enough to hold the amount 
 * of exported functions.  
 * 
 * @param numEntry The amount of exported functions of a
 *                 resident library.
 * 
 * Returns 0 on success.
 *   
 */
s32 AllocSysTable(u16 numEntries)
{
    SceSysCallEntryTable *sysTableEntry = NULL;
    SceSysCallEntryTable *newSysTableEntry = NULL;
    
    for (sysTableEntry = g_pSysEntControl; sysTableEntry; sysTableEntry = sysTableEntry->next) {
         if (sysTableEntry->inUse)
             continue;
         
         /*
          * Here, the concept "first fit" is used.  We scan the list 
          * for an unused sysEntryTable object big-enough to hold the 
          * amount of exported functions.  If the object is exactly
          * the size requested, its start address will be returned
          * and marked as being in-use.
          * 
          * If the object can hold more than the requested numEntries, 
          * split into two new blocks.  The first block holds the exact 
          * number of requested entries and its start address will be returned. 
          * The second block will be unlinked from the free entry table stack.
          * It holds the remaining entries from the original block ready to be 
          * used by another request. 
          */ 
         if (sysTableEntry->numEntries == numEntries) { //0x000004F4
             sysTableEntry->inUse = SCE_TRUE;
             return sysTableEntry->startAddr;
         }
         /* 
          * Example: We want to allocate a new SysEntryTable object capable
          *          of holding 60 exported functions.
          * 
          * State of the list before the object is allocated.
          * 
          * +------------+   +------------+
          * |   A = 100  |-->|   B = 150  |-->...
          * +------------+   +------------+
          */
         if (sysTableEntry->numEntries > numEntries) { //0x000004FC
             if (g_pFreeSysEnt == NULL) {
                 newSysTableEntry = (SceSysCallEntryTable *)sceKernelAllocHeapMemory(g_loadCoreHeap(), sizeof(SceSysCallEntryTable));
             }
             else {
                 newSysTableEntry = g_pFreeSysEnt; //0x00000544
                 g_pFreeSysEnt = g_pFreeSysEnt->next;
             }
             newSysTableEntry->inUse = SCE_FALSE; //0x00000550
             newSysTableEntry->startAddr = sysTableEntry->startAddr + numEntries; //0x0000055C
             newSysTableEntry->numEntries = sysTableEntry->numEntries - numEntries;
             newSysTableEntry->next = sysTableEntry->next;
             
             sysTableEntry->inUse = SCE_TRUE; //0x00000578
             sysTableEntry->numEntries = numEntries;
             sysTableEntry->next = newSysTableEntry;
             
             /*
              * State of the list after the object is allocated.
              * 
              * +------------+   +------------+   +------------+
              * |###A = 60###|-->|   A' = 40  |-->|   B = 150  |-->...
              * +------------+   +------------+   +------------+
              */ 
             
             return sysTableEntry->startAddr;
         }
    }
    return SCE_ERROR_KERNEL_ERROR;
}
Exemple #5
0
int makeCxmbThemeFile( unsigned int cxmb_magic, const char * cxmb_theme_file )
{
	const char * folders_name[] = {
		"/data/cert",
		"/dic",
		"/font",
		"/kd",
		"/kd/resource",
		"/vsh/etc",
		"/vsh/module",
		"/vsh/resource"
	};
	int folders_count = 8;
	const char * support_exts[] = {
		".prx",
		".rco",
		".bmp",
		".pmf",
		".res",
		".pgf",
		".bwfon",
		".rsc",
		".dat",
		".img",
		".bin",
		".cet",
		".dic"
	};
	int exts_count = 13;
	int dfd, heap_id, fd, i, bytes, file_count = 0;
	unsigned int ptf_h[5];
	char path[128], file[128], preview[64];
	u8 * buf;
	// dectect if theme file in conf exist
	int ctf = sceIoOpen( cxmb_theme_file, PSP_O_RDONLY, 0644 );
	if ( ctf >= 0 )
	{
		log( "theme file exist!\n" );
		sceIoClose( ctf );
		return 0;
	}

	dfd = sceIoDopen( "ms0:/cxmb" );
	if ( dfd < 0 )
	{
		log( "no cxmb folder found!\n" );
		return 0;
	}
	sceIoDclose( dfd );

	sprintf( preview, "ms0:/cxmb%s", &cxmb_theme_file[14] );
	preview[strlen( preview ) - 3] = 'p';
	log( "preview: %s\n", preview );
	fd = sceIoOpen( preview, PSP_O_RDONLY, 0644 );
	if ( fd < 0 )
	{
		log( "no preview ptf file found!\n" );
		return 0;
	}
	sceIoLseek( fd, 0x100, PSP_SEEK_SET );
	sceIoRead( fd, ptf_h, 20 );

	// create CXMB_MKCTF_BUF_SIZE + 32kb heap
	heap_id = sceKernelCreateHeap( 2, CXMB_MKCTF_BUF_SIZE + 1024 * 32 , 1, "cxmb_tmp_heap");
	if ( heap_id < 0 )
	{
		log( "failed in create heap in making cxmb theme file!\n" );
		return -1;
	}

	CtfHeader * ch = ( CtfHeader * )sceKernelAllocHeapMemory( heap_id, sizeof( CtfHeader ) * 64 );
	memset( ch, 0, sizeof( CtfHeader ) * 64 );
	SceIoDirent * ent = ( SceIoDirent * )sceKernelAllocHeapMemory( heap_id, sizeof( SceIoDirent ) );
	memset( ent, 0, sizeof( SceIoDirent ) );

	sceIoMkdir( "ms0:/PSP/THEME", 0777 );
	ctf = sceIoOpen( cxmb_theme_file, PSP_O_RDWR | PSP_O_CREAT | PSP_O_TRUNC, 0777 );
	if ( ctf < 0 )
	{
		log( "failed in opening %s\n", cxmb_theme_file );
		sceKernelFreeHeapMemory( heap_id, ent );
		sceKernelFreeHeapMemory( heap_id, ch );
		sceKernelDeleteHeap( heap_id );
		return -1;
	}
	else
	{
		if ( ptf_h[2] == 0 )
			ptf_h[2] = sceIoLseek( fd, 0, PSP_SEEK_END );
		log( "ptf sections size %08x\n", ptf_h[2] );
		buf = sceKernelAllocHeapMemory( heap_id, ptf_h[2] );
		if ( buf )
		{
			sceIoLseek( fd, 0, PSP_SEEK_SET );
			sceIoRead( fd, buf, ptf_h[2] );
			sceIoWrite( ctf, buf, ptf_h[2] );
			sceIoClose( fd );
			sceKernelFreeHeapMemory( heap_id, buf );

			sceIoLseek( ctf, 0x10, PSP_SEEK_SET );
			sceIoWrite( ctf, &cxmb_magic, 4 );
			sceIoLseek( ctf, 0x1C, PSP_SEEK_SET );
			sceIoWrite( ctf, &ptf_h[2], 4 );

			memset( &ptf_h[2], 0, 12 );
			sceIoLseek( ctf, 0x100, PSP_SEEK_SET );
			sceIoWrite( ctf, ptf_h, 20 );
			sceIoLseek( ctf, 0, PSP_SEEK_END );

			for ( i = 0; i < folders_count; i ++ )
			{
				sprintf( path, "ms0:/cxmb%s", folders_name[i] );
				dfd = sceIoDopen( path );
				if ( dfd < 0 )
				{
					log( "folder %s not found!\n", path );
					continue;
				}
				log( "parsing %s\n", path );
				while ( sceIoDread( dfd, ent ) > 0 )
				{
					log( "found %s\n", ent->d_name );
					if ( ( ent->d_stat.st_attr & FIO_SO_IFDIR ) || ent->d_name[0] == '.' )
					{
						log( "ignore %s\n", ent->d_name );
						continue;
					}
					if ( endwithistrs( ent->d_name, support_exts, exts_count ) )
					{
						sprintf( file, "%s/%s", path, ent->d_name );
						sprintf( ch[file_count].name, "%s/%s", folders_name[i], ent->d_name );
						ch[file_count].start = sceIoLseek( ctf, 0, PSP_SEEK_CUR );
						ch[file_count].size = 0;
						if ( cmpistrs( ent->d_name, diff_files, diff_count ) )
						{
							char ori_file[128];
							sprintf( ori_file, "%s/%s", CXMB_SUPPORT_FOLDER, ent->d_name );
							ch[file_count].size = makeDiff( file, ori_file, heap_id, ctf );
						}
						else
						{
							log( "dealing with %s\n", ent->d_name );
							fd = sceIoOpen( file, PSP_O_RDONLY, 0644 );
							if ( fd < 0 )
							{
								log( "failed in opening %s\n", file );
								continue;
							}
							buf = ( u8 * )sceKernelAllocHeapMemory( heap_id, CXMB_MKCTF_BUF_SIZE );
							bytes = sceIoRead( fd, buf, CXMB_MKCTF_BUF_SIZE );
							while( bytes > 0 )
							{
								ch[file_count].size += sceIoWrite( ctf, buf, bytes );
								bytes = sceIoRead( fd, buf, CXMB_MKCTF_BUF_SIZE );
							}
							sceKernelFreeHeapMemory( heap_id, buf );
							sceIoClose( fd );
						}
						if ( ch[file_count].size > 0 && ch[file_count].size < CXMB_MAX_FILE_SIZE )
						{
							log( "start: %08x size: %08x\n", ch[file_count].start, ch[file_count].size );
							file_count ++;
						}
					}
					else
					{
						log( "ignore %s\n", ent->d_name );
					}
				}
				sceIoDclose( dfd );
			}
		}
		else
		{
			log( "failed in allocating %08x heap\n", ptf_h[2] );
		}
	}

	log( "file_count: %d\n", file_count );
	if ( file_count > 0 )
	{
		u8 sha1[20];
		sceKernelUtilsSha1Digest( ( u8 * )ch, sizeof( CtfHeader ) * file_count, sha1 );
		sceIoWrite( ctf, ch, sizeof( CtfHeader ) * file_count );
		sceIoLseek( ctf, 0x14, PSP_SEEK_SET );
		sceIoWrite( ctf, &sha1[0], 4 );
		sceIoWrite( ctf, &file_count, 4 );
		sceIoClose( ctf );
	}
	else
	{
		sceIoClose( ctf );
		sceIoRemove( cxmb_theme_file );
	}
	sceKernelFreeHeapMemory( heap_id, ent );
	sceKernelFreeHeapMemory( heap_id, ch );
	sceKernelDeleteHeap( heap_id );
	return 0;
}
Exemple #6
0
int install_cxmb( void )
{
	int fd = sceIoOpen( CXMB_CONF_FILE, PSP_O_RDONLY, 0644 );
	if ( fd < 0 )
	{
		log( "no conf file found!\n" );
		fd = sceIoOpen( CXMB_CONF_FILE, PSP_O_RDWR | PSP_O_CREAT | PSP_O_TRUNC, 0777 );
		if ( fd < 0 )
		{
			log( "failed in creating conf file!\n" );
			return -1;
		}
		strcpy( theme_file, CXMB_DEFAULT_THEME );
		sceIoWrite( fd, theme_file, strlen( theme_file ) + 1 );
	}
	readLine( fd, theme_file, 64 );
	if ( truncpath( theme_file, ".ctf" ) < 0 )
	{
		if ( truncpath( theme_file, ".CTF" ) < 0 )
		{
			strcpy( theme_file, CXMB_DEFAULT_THEME );
		}
	}
	sceIoClose( fd );
	
	if ( endwithistr( theme_file, "random.ctf" ) )
	{
		log( "random\n" );
		randomCtf( theme_file );
	}
	
	sprintf( cxmb_theme_file, "ms0:%s", theme_file );
	log( "Theme file: %s\n", theme_file );
	
	#if _CXMB_LITE == 0
	makeCxmbThemeFile( cxmb_magic, cxmb_theme_file );
	#endif
	
	lflash_drv = findDriver( "flashfat" );
	fatms_drv = findDriver( "fatms" );
	
	if ( !lflash_drv || !fatms_drv )
		return -1;
		
	msIoOpen	= fatms_drv->funcs->IoOpen;
	msIoGetstat	= fatms_drv->funcs->IoGetstat;
	IoOpen		= lflash_drv->funcs->IoOpen;
	IoRead		= lflash_drv->funcs->IoRead;
	IoLseek		= lflash_drv->funcs->IoLseek;
	IoIoctl		= lflash_drv->funcs->IoIoctl;
	IoClose		= lflash_drv->funcs->IoClose;
	IoGetstat	= lflash_drv->funcs->IoGetstat;
	
	int intr = sceKernelCpuSuspendIntr();
	
	fatms_drv->funcs->IoOpen	= msIoOpen_new;
	fatms_drv->funcs->IoGetstat	= msIoGetstat_new;
	lflash_drv->funcs->IoOpen	= IoOpen_new;
	lflash_drv->funcs->IoRead	= IoRead_new;
	lflash_drv->funcs->IoLseek	= IoLseek_new;
	lflash_drv->funcs->IoIoctl	= IoIoctl_new;
	lflash_drv->funcs->IoClose	= IoClose_new;
	lflash_drv->funcs->IoGetstat= IoGetstat_new;
	
	sceKernelCpuResumeIntr( intr );
	sceKernelIcacheInvalidateAll();
	sceKernelDcacheWritebackInvalidateAll();
	
	sceIoOpen( "ms0:/dummy.prx", PSP_O_RDONLY, 0644 );
	
	log( "redirected io_driver!\n" );
	log( "ms_drv_arg: %08x\n", ( unsigned int )ms_drv );

	previous = setStartModuleHandler( OnModuleStart );
	log("startModuleHandler setup!\n");
	
	fd = sceIoOpen( cxmb_theme_file, PSP_O_RDONLY, 0644 );
	if ( fd < 0 )
	{
		log( "no ctf file found!\n" );
		return 0;
	}
	
	mem_id = sceKernelCreateHeap( 2, 1024 * 5 , 1, "cxmb_heap");
	if ( mem_id < 0 )
	{
		log( "failed in creating cxmb_heap!\n" );
		sceIoClose( fd );
		return -1;
	}
	
	unsigned int magic;
	sceIoLseek( fd, 0x10, PSP_SEEK_SET );
	sceIoRead( fd, &magic, 4 );
	if ( magic != cxmb_magic )
	{
		log( "magic not match!\n" );
		sceIoClose( fd );
		return -1;
	}
	sceIoRead( fd, &ctf_sig, 4 );
	sceIoRead( fd, &header_size, 4 );
	log( "header size: %d\n", header_size );
	
	ctf_header = sceKernelAllocHeapMemory( mem_id, sizeof( CtfHeader ) * header_size );
	int offset = - sizeof( CtfHeader ) * header_size;
	sceIoLseek( fd, offset, PSP_SEEK_END );
	sceIoRead( fd, ctf_header, sizeof( CtfHeader ) * header_size );
	sceIoClose( fd );
	
	log( "read ctf_header!\n" );
	
	ctf_handler = sceKernelAllocHeapMemory( mem_id, sizeof( CtfHandler ) * 32 );
	memset( ctf_handler, 0, sizeof( CtfHandler ) * 32 );
	
	return 0;
}