Пример #1
0
DSTATUS disk_initialize(BYTE drv)
{
	s32 retval = 0;
	#ifdef HW_RVL
	fstats *stats = (fstats*)memalign(32, sizeof(fstats));
	#endif	
	struct stat filestats;
	if((int)drv >= vff_totalmountedfs)return STA_NOINIT;
	#ifdef HW_RVL
	if(vff_types[(int)drv]==0)retval = ISFS_GetFileStats((s32)disk_vff_handles[(int)drv], stats);
	#endif
	if(vff_types[(int)drv]==1)
	{
		retval = fstat(fileno((FILE*)disk_vff_handles[(int)drv]), &filestats);
	}
	if(retval<0)
	{
		printf("getfilestats returned %d\n", retval);
		return STA_NOINIT;
	}
	#ifdef HW_RVL
	if(vff_types[(int)drv]==0)vff_filesizes[(int)drv] = stats->file_length;
	free(stats);
	#endif
	if(vff_types[(int)drv]==1)vff_filesizes[(int)drv] = filestats.st_size;
	//vff_filesizes[(int)drv] = (unsigned int)GetFileLength(disk_vff_handles[(int)drv]);
	vff_fatsizes[(int)drv] = VFF_GetFATSize(vff_filesizes[(int)drv]);
	vff_fat_types[(int)drv] = VFF_GetFATType(vff_filesizes[(int)drv]);
	printf("disk_init ok: filesize %x fatsize %x fat_type %d\n", vff_filesizes[(int)drv], vff_fatsizes[(int)drv], vff_fat_types[(int)drv]);

	return 0;
}
Пример #2
0
int fileBrowser_WiiFS_readDir(fileBrowser_file* file, fileBrowser_file** dir){
	static char dirents[32*(8+1+3+1)] __attribute__((aligned(32)));
	unsigned int numDirents = 32;
	// Call the corresponding ISFS function
	char* name = getAlignedName(&file->name);
	int ret = ISFS_ReadDir(name, dirents, &numDirents);
	
	// If it was not successful, just return the error
	if(ret < 0) return ret;
	
	// Convert the ISFS data to fileBrowser_files
	*dir = malloc( numDirents * sizeof(fileBrowser_file) );
	int i; char* dirent = &dirents[0];
	for(i=0; i<numDirents; ++i){
		sprintf((*dir)[i].name, "%s/%s", name, dirent);
		// Collect info about this file
		int fd = ISFS_Open( getAlignedName((*dir)[i].name), 1 );
		if(fd >= 0){
			fstats* stats = memalign( 32, sizeof(fstats) );
			ISFS_GetFileStats(fd, stats);
			(*dir)[i].attr = 0;
			(*dir)[i].size = stats->file_length;
			free(stats);
			ISFS_Close(fd);
		} else {
			(*dir)[i].attr = FILE_BROWSER_ATTR_DIR;
			(*dir)[i].size = 0;
		}
		(*dir)[i].offset = 0;
		
		while(*(dirent++)); // Advance to the next dirent
	}
	
	return numDirents;
}
Пример #3
0
s32 read_file(char *filepath, u8 **buffer, u32 *filesize){
	s32 Fd;
	int ret;

	if(buffer == NULL){
		printf("NULL Pointer\n");
		return -1;
	}

	Fd = ISFS_Open(filepath, ISFS_OPEN_READ);
	if (Fd < 0){
		//printf("\n   * ISFS_Open %s failed %d", filepath, Fd);
		//Pad_WaitButtons();
		return Fd;
	}

	fstats *status;
	status = allocate_memory(sizeof(fstats));
	if (status == NULL){
		printf("Out of memory for status\n");
		return -1;
	}
	
	ret = ISFS_GetFileStats(Fd, status);
	if (ret < 0){
		printf("ISFS_GetFileStats failed %d\n", ret);
		ISFS_Close(Fd);
		free(status);
		return -1;
	}
	
	*buffer = allocate_memory(status->file_length);
	if (*buffer == NULL){
		printf("Out of memory for buffer\n");
		ISFS_Close(Fd);
		free(status);
		return -1;
	}
		
	ret = ISFS_Read(Fd, *buffer, status->file_length);
	if (ret < 0){
		printf("ISFS_Read failed %d\n", ret);
		ISFS_Close(Fd);
		free(status);
		free(*buffer);
		return ret;
	}
	ISFS_Close(Fd);

	*filesize = status->file_length;
	free(status);

	return 0;
}
int NandTitle::LoadFileFromNand(const char *filepath, u8 **outbuffer, u32 *outfilesize)
{
	if(!filepath)
		return -1;

	fstats *stats = (fstats *) memalign(32, ALIGN32(sizeof(fstats)));
	if(!stats)
		return IPC_ENOMEM;

	int fd = ISFS_Open(filepath, ISFS_OPEN_READ);
	if(fd < 0)
	{
		free(stats);
		return fd;
	}

	int ret = ISFS_GetFileStats(fd, stats);
	if (ret < 0)
	{
		free(stats);
		ISFS_Close(fd);
		return ret;
	}

	u32 filesize = stats->file_length;

	free(stats);

	u8 *buffer = (u8 *) memalign(32, ALIGN32(filesize));
	if(!buffer)
	{
		ISFS_Close(fd);
		return IPC_ENOMEM;
	}

	ret = ISFS_Read(fd, buffer, filesize);

	ISFS_Close(fd);

	if (ret < 0)
	{
		free(buffer);
		return ret;
	}

	*outbuffer = buffer;
	*outfilesize = filesize;

	return 0;
}
Пример #5
0
u8 *ISFS_GetFile(u8 *path, u32 *size, s32 length)
{
	*size = 0;

	s32 fd = ISFS_Open((const char *) path, ISFS_OPEN_READ);
	u8 *buf = NULL;
	static fstats stats ATTRIBUTE_ALIGN(32);

	if(fd >= 0)
	{
		if(ISFS_GetFileStats(fd, &stats) >= 0)
		{
			if(length <= 0)
				length = stats.file_length;
			if(length > 0)
				buf = (u8 *)MEM2_memalign(32, length);

			if(buf)
			{
				*size = stats.file_length;
				if(ISFS_Read(fd, (char*)buf, length) != length)
				{
					*size = 0;
					MEM2_free(buf);
				}
			}
		}
		ISFS_Close(fd);
	}

	if(*size > 0)
	{
		DCFlushRange(buf, *size);
		ICInvalidateRange(buf, *size);
	}
	return buf;
}
Пример #6
0
bool U8NandArchive::SetFile( const char* nandPath )
{
	if(fst)
		free(fst);
	if(name_table)
		free(name_table);
	CloseFile();

	// open file
	if( (fd = ISFS_Open( nandPath, ISFS_OPEN_READ ) ) < 0 )
	{
		gprintf( "U8NandArchive:  ISFS_Open( \"%s\" ) failed\n", nandPath );
		return false;
	}

	// get file size
	fstats stats __attribute__(( aligned( 32 ) ));
	int ret = ISFS_GetFileStats( fd, &stats );
	if( ret < 0 )
	{
		CloseFile();
		gprintf( "U8NandArchive:  ISFS_GetFileStats( \"%s\" ) failed\n", nandPath );
		return false;
	}

	// buffer for reading the header and stuff
	u8* buffer = (u8*)memalign( 32, 0x800 );
	if( !buffer )
	{
		CloseFile();
		gprintf( "U8NandArchive: enomem\n" );
		return false;
	}

	// read a chunk big enough that it should contain the U8 header if there is going to be one
	if( (ret = ISFS_Read( fd, buffer, 0x800 )) != 0x800 )
	{
		free( buffer );
		CloseFile();
		gprintf( "U8NandArchive: ISFS_Read( 0x800 ) = %i\n", ret );
		return false;
	}

	// find the start of the U8 data
	U8Header* tagStart = (U8Header*)FindU8Tag( buffer, ret );
	if( !tagStart )
	{
		free( buffer );
		CloseFile();
		gprintf( "U8NandArchive: didn't see a U8 tag\n" );
		return false;
	}

	// remember where in the file the U8 starts
	dataOffset = ( (u8*)tagStart - buffer );

	// allocate memory and read the fst
	if( !(fst = (FstEntry *)memalign( 32, RU( tagStart->dataOffset - dataOffset, 32 ) ) )
			|| ( ISFS_Seek( fd, dataOffset + tagStart->rootNodeOffset, SEEK_SET ) != (s32)( dataOffset + tagStart->rootNodeOffset ) )
			|| ( ISFS_Read( fd, fst, tagStart->dataOffset - dataOffset ) != (s32)( tagStart->dataOffset - dataOffset ) )
			|| ( fst->filelen * 0xC > tagStart->dataOffset ) )
	{
		dataOffset = 0;
		free( buffer );
		if( fst )
			free( fst );
		CloseFile();
		gprintf( "U8NandArchive: error reading fst\n" );
	}

	// set name table pointer
	u32 name_table_offset = fst->filelen * 0xC;
	name_table = ((char *)fst) + name_table_offset;

	free( buffer );
	return true;
}
Пример #7
0
void load()
{
	u32 file_size;
	static fstats filestats_settings	ATTRIBUTE_ALIGN(32);
	static fstats filestats_appios		ATTRIBUTE_ALIGN(32);
	static u8 filearray_settings[1024]	ATTRIBUTE_ALIGN(32);
	static u8 filearray_appios[1024]	ATTRIBUTE_ALIGN(32);

#if defined(STBOOT) || defined(STBOOTVWII)
	Settings.ios_dat		= "/title/00010001/48424630/data/appios.dat";
	Settings.dir_dat		= "/title/00010001/48424630/data/list.dat";
	Settings.settings_dat		= "/title/00010001/48424630/data/settings.dat";
#else
	Settings.ios_dat		= "/title/00010001/54484246/data/appios.dat";
	Settings.dir_dat		= "/title/00010001/54484246/data/list.dat";
	Settings.settings_dat		= "/title/00010001/54484246/data/settings.dat";
#endif

	AvailableCategoryLoad(Settings.dir_dat);

	// get settings
	s32 fd;
	fd = ISFS_Open(Settings.settings_dat.c_str(), ISFS_OPEN_READ);
	if (fd <= 0)
		ISFS_Close(fd);

	ISFS_GetFileStats(fd, &filestats_settings);

	file_size = ISFS_Read(fd, filearray_settings, filestats_settings.file_length);

	ISFS_Close(fd);

	if(file_size >= 0)
	{
		string source = (char*)filearray_settings;

		if(get_setting(source, "device_dat") != "")
			Settings.device_dat = get_setting(source, "device_dat");

		if (get_setting(source, "theme") != "")
		{
			sprintf (Options.theme, get_setting(source, "theme").c_str());
			theme(check_path(Settings.device_dat + ":/config/HBF/themes/") + Options.theme + "/");
		}

		if(get_setting(source, "language") != "")
		{
			sprintf (Options.language, get_setting(source, "language").c_str());
			ini_Open(check_path(Settings.device_dat + ":/config/HBF/languages/") + Options.language + ".lang");
			AvailableCategory.categories[0] = tr(Settings.category_name_all);
		}

		if(get_setting(source, "font") != "")
			sprintf (Options.font, get_setting(source, "font").c_str());

		if(get_setting(source, "slide_effect") != "")
			Options.slide_effect = atoi(get_setting(source, "slide_effect").c_str());

		if(get_setting(source, "last_category_name") != "")
		{
			if(KategorieNr(get_setting(source, "last_category_name")) != -1)
				Settings.current_category = KategorieNr(get_setting(source, "last_category_name").c_str());
		}

		if(get_setting(source, "last_category") != "")
		{
			Options.last_category = atoi(get_setting(source, "last_category").c_str());
			if(Options.last_category == 1)
				Options.last_category = Settings.current_category +1;
		}

		if(get_setting(source, "last_app_name") != "")
			Settings.startingAppName = get_setting(source, "last_app_name");

		if(get_setting(source, "apps_nr") != "")
		{
			Options.apps = atoi(get_setting(source, "apps_nr").c_str());
			if(Options.apps > 5)
				Options.apps = 5;
			else if(Options.apps < 4)
				Options.apps = 4;
		}

		if(get_setting(source, "quick_start") != "")
			Options.quick_start = atoi(get_setting(source, "quick_start").c_str());

		if(get_setting(source, "show_all") != "")
			Options.show_all = atoi(get_setting(source, "show_all").c_str());

		if(get_setting(source, "navigation") != "")
			Options.navigation = atoi(get_setting(source, "navigation").c_str());

		if(get_setting(source, "sdgecko") != "")
			Options.sdgecko = atoi(get_setting(source, "sdgecko").c_str());
#ifndef VWII
		if(get_setting(source, "bootmii_boot2") != "")
			Options.bootmii_boot2 =  atoi(get_setting(source, "bootmii_boot2").c_str());
#endif
		if(get_setting(source, "network") != "")
		{
			Options.network = atoi(get_setting(source, "network").c_str());
			Options.temp_network = Options.network;
		}

		if(get_setting(source, "wifigecko") != "")
		{
			Options.wifigecko = atoi(get_setting(source, "wifigecko").c_str());
			Options.temp_wifigecko = Options.wifigecko;
		}

		if(get_setting(source, "newrevtext") != "")
		{
			Options.newrevtext = atoi(get_setting(source, "newrevtext").c_str());
			Options.temp_newrevtext = Options.newrevtext;
		}

		if(get_setting(source, "code") != "")
		{
			sprintf (Settings.code, get_setting(source, "code").c_str());
			strcpy (Options.temp_code, Settings.code);
		}

		if(get_setting(source, "grid") != "")
			Settings.grid = atoi(get_setting(source, "grid").c_str());

		if(get_setting(source, "device") != "")
			Settings.device = get_setting(source, "device");

		if(get_setting(source, "device_icon") != "")
			Options.device_icon = atoi(get_setting(source, "device_icon").c_str());

		if(get_setting(source, "wiiload_ahb") != "")
			Options.wiiload_ahb = atoi(get_setting(source, "wiiload_ahb").c_str());

		if(get_setting(source, "wiiload_ios") != "")
			Options.wiiload_ios = atoi(get_setting(source, "wiiload_ios").c_str());

		if(get_setting(source, "system") != "")
			Settings.system = atoi(get_setting(source, "system").c_str());

		if(get_setting(source, "top") != "")
			Settings.top = atoi(get_setting(source, "top").c_str());

		if(get_setting(source, "bottom") != "")
			Settings.bottom = atoi(get_setting(source, "bottom").c_str());

		if(get_setting(source, "left") != "")
			Settings.left = atoi(get_setting(source, "left").c_str());

		if(get_setting(source, "right") != "")
			Settings.right = atoi(get_setting(source, "right").c_str());
	}

	// 	get appios
	fd = ISFS_Open(Settings.ios_dat.c_str(), ISFS_OPEN_READ);
	if (fd <= 0)
		ISFS_Close(fd);

	ISFS_GetFileStats(fd, &filestats_appios);

	file_size = ISFS_Read(fd, filearray_appios,  filestats_appios.file_length);

	ISFS_Close(fd);

	if(file_size >= 0)
	{
		string line;
		istringstream in((char*)filearray_appios);
		while(getline(in, line))
			appios.push_back(app_ios(line.substr(0, line.find(" = ")), atoi(line.substr(line.find(" = ") +3).c_str())));
	}
}
Пример #8
0
static int _ISFS_open_r(struct _reent *r, void *fileStruct, const char *path, int flags, int mode) {
	FILE_STRUCT *file = (FILE_STRUCT *)fileStruct;

	char *abspath = malloc(ISFS_MAXPATHLEN);
	if(!abspath) {
		r->_errno = ENOMEM;
		return -1;
	}

	char *ptr = strchr(path, ':');
	if (ptr != NULL)
		snprintf(abspath, ISFS_MAXPATHLEN, "%s", ptr + 1);
	else
		snprintf(abspath, ISFS_MAXPATHLEN, "%s/%s", current->entry->abspath, path);

	RemoveDoubleSlash(abspath);

	if (!READ_ONLY && (flags & O_CREAT)) {
		int iOwnerPerm  = 0;
		int iGroupPerm = 0;
		int iOtherPerm = 0;

		if (flags & S_IRUSR)
			iOwnerPerm |= ISFS_OPEN_READ;
		if (flags & S_IWUSR)
			iOwnerPerm |= ISFS_OPEN_WRITE;
		if (flags & S_IRGRP)
			iGroupPerm |= ISFS_OPEN_READ;
		if (flags & S_IWGRP)
			iGroupPerm |= ISFS_OPEN_WRITE;
		if (iGroupPerm & S_IROTH)
			iOtherPerm |= ISFS_OPEN_READ;
		if (flags & S_IWOTH)
			iOtherPerm |= ISFS_OPEN_WRITE;

		ISFS_CreateFile(abspath, 0, iOwnerPerm, iGroupPerm, iOtherPerm);
	}

	int iOpenMode = 0;

	if ((flags & 0x03) == O_RDONLY)
		iOpenMode |= ISFS_OPEN_READ;
	if (!READ_ONLY && ((flags & 0x03) == O_WRONLY))
		iOpenMode |= ISFS_OPEN_WRITE;
	if ((flags & 0x03) == O_RDWR)
		iOpenMode |= READ_ONLY ? ISFS_OPEN_READ : ISFS_OPEN_RW;

	file->fd = ISFS_Open(abspath, iOpenMode);

	free(abspath);

	if (file->fd < 0) {
		if (file->fd == ISFS_EINVAL)
			r->_errno = EACCES;
		else
			r->_errno = -file->fd;
		return -1;
	}

	file->flags = flags;
	file->mode = mode;

	if (ISFS_GetFileStats(file->fd, &filest) == ISFS_OK)
		file->size = filest.file_length;

	if (!READ_ONLY && (flags & O_APPEND))
		ISFS_Seek(file->fd, 0, SEEK_END);

	return (int)file;
}
Пример #9
0
static bool read_directory(DIR_ENTRY *parent) {
	if(!parent || !parent->abspath)
		return false;

	u32 fileCount;
	if(parent->size != 0 && is_dir(parent))
	{
		fileCount = parent->size;
	}
	else
	{
		s32 ret = ISFS_ReadDir(parent->abspath, NULL, &fileCount);
		if (ret != ISFS_OK) {
			return false;
		}
	}
	parent->flags = FLAG_DIR;
	parent->size = fileCount;
	parent->childCount = 0;

	if(strcmp(parent->abspath, "/") != 0)
	{
		DIR_ENTRY *child = add_child_entry(parent, ".");
		if (!child) return false;
		child->flags = FLAG_DIR;
		child->size = 0;
		child = add_child_entry(parent, "..");
		if (!child) return false;
		child->flags = FLAG_DIR;
		child->size = 0;
	}

	if (fileCount > 0)
	{
		char *buffer = (char *) memalign(32, ISFS_MAXPATHLEN * fileCount);
		if(!buffer) return false;

		s32 ret = ISFS_ReadDir(parent->abspath, buffer, &fileCount);
		if (ret != ISFS_OK)
		{
			free(buffer);
			return false;
		}

		u32 fileNum;
		char *name = buffer;
		for (fileNum = 0; fileNum < fileCount; fileNum++)
		{
			DIR_ENTRY *child = add_child_entry(parent, name);
			if (!child)
			{
				free(buffer);
				return false;
			}
			name += strlen(name) + 1;

			u32 childFileCount;
			ret = ISFS_ReadDir(child->abspath, NULL, &childFileCount);
			if (ret == ISFS_OK)
			{
				child->flags = FLAG_DIR;
				child->size = childFileCount;
			}
			else
			{
				s32 fd = ISFS_Open(child->abspath, ISFS_OPEN_READ);
				if (fd >= 0) {
					if (ISFS_GetFileStats(fd, &filest) == ISFS_OK)
						child->size = filest.file_length;
					ISFS_Close(fd);
				}
			}
		}
		free(buffer);
	}
	return true;
}
Пример #10
0
s8 PatchTMD( u8 delete_mode )
{
    Nand_Permissions Perm;
    memset(&Perm,0,sizeof(Nand_Permissions));
    u8 SaveTmd = 0;
    SHA1 sha; // SHA-1 class
    sha.Reset();
    u32 FileHash[5];
    u8 *TMD_chk = NULL;
    s32 fd = 0;
    s32 r = 0;
#ifdef _DEBUG
    gprintf("Path : %s\n",TMD_Path);
#endif
    r = ISFS_GetAttr(TMD_Path, &Perm.owner, &Perm.group, &Perm.attributes, &Perm.ownerperm, &Perm.groupperm, &Perm.otherperm);
    if(r < 0 )
    {
        //attribute getting failed. returning to default
        printf("\x1b[%u;%dm", 33, 1);
        printf("\nWARNING : failed to get file's permissions. using defaults\n");
        printf("\x1b[%u;%dm", 37, 1);
        gprintf("permission failure on desination! error %d\n",r);
        gprintf("writing with max permissions\n");
        Perm.ownerperm = 3;
        Perm.groupperm = 3;
        Perm.otherperm = 0;
    }
    else
    {
        gprintf("r %d owner %d group %d attributes %X perm:%X-%X-%X\n", r, Perm.owner, Perm.group, Perm.attributes, Perm.ownerperm, Perm.groupperm, Perm.otherperm);
    }
    if(delete_mode == 0)
    {
        gprintf("patching TMD...\n");
        printf("Patching TMD...");

    }
    else
    {
        //return 1;
        gprintf("restoring TMD...\n");
        printf("Restoring System Menu TMD...\n");
    }

    fd = ISFS_Open(TMD_Path2,ISFS_OPEN_READ);
    if(fd < 0)
    {
        if(delete_mode)
        {
            printf("TMD backup not found. leaving TMD alone...\n");
            return 1;
        }
        else
        {
            //got to make tmd copy :)
            gprintf("Making tmd backup...\n");
            r = nand_copy(TMD_Path2,tmd_buf,tmd_size,Perm);
            if ( r < 0)
            {
                gprintf("Failure making TMD backup.error %d\n",r);
                printf("TMD backup/Patching Failure : error %d",r);
                goto _return;
            }
        }
        fd = 0;
    }
    ISFS_Close(fd);
    gprintf("TMD backup found\n");
    //not so sure why we'd want to delete the tmd modification but ok...
    if(delete_mode)
    {
        if ( nand_copy(TMD_Path2,TMD_Path,Perm) < 0)
        {
            if(r == -80)
            {
                //checksum issues
                printf("\x1b[%u;%dm", 33, 1);
                printf("\nWARNING!!\nInstaller could not calculate the Checksum when restoring the TMD back!\n");
                printf("the TMD however was copied...\n");
                printf("Do you want to Continue ?\n");
                printf("A = Yes       B = No\n  ");
                printf("\x1b[%u;%dm", 37, 1);
                if(!UserYesNoStop())
                {
                    nand_copy(TMD_Path,TMD_Path2,Perm);
                    abort("TMD restoring failure.");
                }
            }
            else
            {
                printf("\x1b[%u;%dm", 33, 1);
                printf("UNABLE TO RESTORE THE SYSTEM MENU TMD!!!\n\nTHIS COULD BRICK THE WII SO PLEASE REINSTALL SYSTEM MENU\nWHEN RETURNING TO THE HOMEBREW CHANNEL!!!\n\n");
                printf("\x1b[%u;%dm", 37, 1);
                printf("press A to return to the homebrew channel\n");
                nand_copy(TMD_Path,TMD_Path2,Perm);
                UserYesNoStop();
                exit(0);
            }
        }
        else
            ISFS_Delete(TMD_Path2);
        return 1;
    }
    else
    {
        //check if version is the same
        STACK_ALIGN(fstats,TMDb_status,sizeof(fstats),32);
        static u8 tmdb_buf[MAX_SIGNED_TMD_SIZE] ATTRIBUTE_ALIGN(32);
        static signed_blob *mbTMD;
        static tmd* pbTMD;

        fd = ISFS_Open(TMD_Path2,ISFS_OPEN_READ);
        if (fd < 0)
        {
            gprintf("TMD bCheck : failed to open source : %s\n",TMD_Path2);
            goto patch_tmd;
        }
        r = ISFS_GetFileStats(fd,TMDb_status);
        if (r < 0)
        {
            gprintf("TMD bCheck : Failed to get information about %s!\n",TMD_Path2);
            ISFS_Close(fd);
            goto patch_tmd;
        }
        memset(tmdb_buf,0,MAX_SIGNED_TMD_SIZE);

        r = ISFS_Read(fd,tmdb_buf,TMDb_status->file_length);
        if (r < 0)
        {
            gprintf("TMD bCheck : Failed to Read Data from %s!\n",TMD_Path2);
            ISFS_Close(fd);
            goto patch_tmd;
        }
        ISFS_Close(fd);
        mbTMD = (signed_blob *)tmdb_buf;
        pbTMD = (tmd*)SIGNATURE_PAYLOAD(mbTMD);
        if (pbTMD->title_version != rTMD->title_version)
        {
            gprintf("TMD bCheck : backup TMD version mismatch: %d & %d\n",rTMD->title_version,pbTMD->title_version);
            //got to make tmd copy :)
            r = nand_copy(TMD_Path2,tmd_buf,tmd_size,Perm);
            if ( r < 0)
            {
                gprintf("TMD bCheck : Failure making TMD backup.error %d\n",r);
                printf("TMD backup/Patching Failure : error %d",r);
                goto _return;
            }
        }
        else
            gprintf("TMD bCheck : backup TMD is correct\n");
        r = 0;
    }
patch_tmd:
    gprintf("detected access rights : 0x%08X\n",rTMD->access_rights);
    if(rTMD->access_rights == 0x03)
    {
        gprintf("no AHBPROT modification needed\n");
    }
    else
    {
        rTMD->access_rights = 0x03;
        DCFlushRange(rTMD,sizeof(tmd));
        if(rTMD->access_rights != 0x03)
        {
            gprintf("rights change failure.\n");
            goto _return;
        }
        SaveTmd++;
    }
    gprintf("checking Boot app SHA1 hash...\n");
    gprintf("bootapp ( %d ) SHA1 hash = %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x\n",rTMD->boot_index
            ,rTMD->contents[rTMD->boot_index].hash[0],rTMD->contents[rTMD->boot_index].hash[1],rTMD->contents[rTMD->boot_index].hash[2],rTMD->contents[rTMD->boot_index].hash[3]
            ,rTMD->contents[rTMD->boot_index].hash[4],rTMD->contents[rTMD->boot_index].hash[5],rTMD->contents[rTMD->boot_index].hash[6],rTMD->contents[rTMD->boot_index].hash[7]
            ,rTMD->contents[rTMD->boot_index].hash[8],rTMD->contents[rTMD->boot_index].hash[9],rTMD->contents[rTMD->boot_index].hash[10],rTMD->contents[rTMD->boot_index].hash[11]
            ,rTMD->contents[rTMD->boot_index].hash[12],rTMD->contents[rTMD->boot_index].hash[13],rTMD->contents[rTMD->boot_index].hash[14],rTMD->contents[rTMD->boot_index].hash[15]
            ,rTMD->contents[rTMD->boot_index].hash[16],rTMD->contents[rTMD->boot_index].hash[17],rTMD->contents[rTMD->boot_index].hash[18],rTMD->contents[rTMD->boot_index].hash[19]);
    gprintf("generated priiloader SHA1 : ");
    sha.Reset();
    sha.Input(priiloader_app,priiloader_app_size);
    if (!sha.Result(FileHash))
    {
        gprintf("could not compute Hash of Priiloader!\n");
        r = -1;
        goto _return;
    }
    if (!memcmp(rTMD->contents[rTMD->boot_index].hash, FileHash, sizeof(FileHash) ) )
    {
        gprintf("no SHA hash change needed\n");
    }
    else
    {
        memcpy(rTMD->contents[rTMD->boot_index].hash,FileHash,sizeof(FileHash));
        gprintf("%08x %08x %08x %08x %08x\n",FileHash[0],FileHash[1],FileHash[2],FileHash[3],FileHash[4]);
        DCFlushRange(rTMD,sizeof(tmd));
        SaveTmd++;
    }
    if(SaveTmd > 0)
    {
        gprintf("saving TMD\n");
        r = nand_copy(TMD_Path,tmd_buf,tmd_size,Perm);
        if(r < 0 )
        {
            gprintf("nand_copy failure. error %d\n",r);
            if(r == -80)
                goto _checkreturn;
            else
                goto _return;
        }
    }
    else
    {
        gprintf("no TMD mod's needed\n");
        printf("no TMD modifications needed\n");
        goto _return;
    }
    printf("Done\n");
_return:
    if (fd < r)
    {
        r = fd;
    }
    if(fd)
    {
        ISFS_Close(fd);
    }
    if (r < 0)
    {
        printf("\x1b[%u;%dm", 33, 1);
        printf("\nWARNING!!\nInstaller couldn't Patch the system menu TMD.\n");
        printf("Priiloader could still end up being installed but could end up working differently\n");
        printf("Do you want the Continue ?\n");
        printf("A = Yes       B = No\n  ");
        printf("\x1b[%u;%dm", 37, 1);
        if(!UserYesNoStop())
        {
            fd = ISFS_Open(TMD_Path2,ISFS_OPEN_RW);
            if(fd >= 0)
            {
                //the backup is there. as safety lets copy it back.
                ISFS_Close(fd);
                nand_copy(TMD_Path2,TMD_Path,Perm);
            }
            abort("TMD failure");
            return -1;
        }
        else
        {
            nand_copy(TMD_Path2,TMD_Path,Perm);
            printf("\nDone!\n");
            return 1;
        }
        return r;
    }
    else
        return 1;
_checkreturn:
    if(fd)
    {
        ISFS_Close(fd);
    }
    if(TMD_chk)
    {
        free(TMD_chk);
        TMD_chk = NULL;
    }
    printf("\x1b[%u;%dm", 33, 1);
    printf("\nWARNING!!\n  Installer could not calculate the Checksum for the TMD!");
    printf("\nbut Patch write was successfull.\n");
    printf("Do you want the Continue ?\n");
    printf("A = Yes       B = No\n  ");
    printf("\x1b[%u;%dm", 37, 1);
    if(!UserYesNoStop())
    {
        printf("reverting changes...\n");
        nand_copy(TMD_Path2,TMD_Path,Perm);
        abort("TMD Patch failure\n");
    }
    else
    {
        printf("\nDone!\n");
    }
    return -80;
}
Пример #11
0
s32 nand_copy(const char *source, const char *destination,Nand_Permissions src_perm)
{
    //variables
    u8 *buffer = NULL;
    STACK_ALIGN(fstats,status,sizeof(fstats),32);
    s32 file_handler, ret;
    u32 FileHash_D1[5];
    memset(FileHash_D1,0,5);
    u32 FileHash_D2[5];
    memset(FileHash_D2,0xFF,5); //place different data in D2 so that if something goes wrong later on, the comparison will fail
    SHA1 sha;
    sha.Reset();

    //variables - temp dir & SHA1 check
    char temp_dest[ISFS_MAXPATH];
    memset(temp_dest,0,ISFS_MAXPATH);
    char *ptemp = NULL;
    u8 temp = 0;

    //get temp filename
    ptemp = strstr(destination,"/");
    while(ptemp != NULL && strstr(ptemp+1,"/") != NULL)
    {
        ptemp = strstr(ptemp+1,"/");
    }
    if(ptemp[0] == '/')
    {
        ptemp = ptemp+1;
    }
    memset(temp_dest,0,ISFS_MAXPATH);
    sprintf(temp_dest,"/tmp/%s",ptemp);

    //get data into pointer from original file
    file_handler = ISFS_Open(source,ISFS_OPEN_READ);
    if (file_handler < 0)
    {
        gprintf("failed to open source : %s\n",source);
        return file_handler;
    }

    ret = ISFS_GetFileStats(file_handler,status);
    if (ret < 0)
    {
        printf("\n\nFailed to get information about %s!\n",source);
        sleepx(2);
        ISFS_Close(file_handler);
        return ret;
    }

    buffer = (u8 *)memalign(32,ALIGN32(status->file_length));
    if (buffer == NULL)
    {
        gprintf("buffer failed to align\n");
        sleepx(2);
        ISFS_Close(file_handler);
        return 0;
    }
    memset(buffer,0,status->file_length);
    ret = ISFS_Read(file_handler,buffer,status->file_length);
    if (ret < 0)
    {
        printf("\n\nFailed to Read Data from %s!\n",source);
        sleepx(2);
        ISFS_Close(file_handler);
        free(buffer);
        buffer = NULL;
        return ret;
    }
    ISFS_Close(file_handler);
    //everything read into buffer. generate SHA1 hash of the buffer
    sha.Input(buffer,status->file_length);
    if (!sha.Result(FileHash_D1))
    {
        gprintf("could not compute Hash of D1!\n");
        free(buffer);
        buffer = NULL;
        return -80;
    }
    sha.Reset();
    //done, lets create temp file and write :')

    ISFS_Delete(temp_dest);
    ISFS_CreateFile(temp_dest,src_perm.attributes,src_perm.ownerperm,src_perm.groupperm,src_perm.otherperm);
    //created. opening it...
    file_handler = ISFS_Open(temp_dest,ISFS_OPEN_RW);
    if (file_handler < 0)
    {
        gprintf("failed to open destination : %s\n",temp_dest);
        ISFS_Delete(temp_dest);
        free(buffer);
        buffer = NULL;
        return file_handler;
    }
    ret = ISFS_Write(file_handler,buffer,status->file_length);
    if (ret < 0)
    {
        gprintf("failed to write destination : %s\n",destination);
        ISFS_Close(file_handler);
        ISFS_Delete(temp_dest);
        free(buffer);
        buffer = NULL;
        return ret;
    }
    //write done. reopen file for reading and compare SHA1 hash
    ISFS_Close(file_handler);
    free(buffer);
    buffer = NULL;
    memset(status,0,sizeof(fstats));
    file_handler = ISFS_Open(temp_dest,ISFS_OPEN_READ);
    if(!file_handler)
    {
        temp = -1;
        goto free_and_Return;
    }
    ret = ISFS_GetFileStats(file_handler,status);
    if (ret < 0)
    {
        ISFS_Close(file_handler);
        temp = -2;
        goto free_and_Return;
    }
    buffer = (u8 *)memalign(32,ALIGN32(status->file_length));
    if (buffer == NULL)
    {
        gprintf("buffer failed to align\n");
        ISFS_Close(file_handler);
        temp = -3;
        goto free_and_Return;
    }
    memset(buffer,0,status->file_length);
    if( ISFS_Read(file_handler,buffer,status->file_length) < 0 )
    {
        temp = -4;
        goto free_and_Return;
    }
    ISFS_Close(file_handler);
    sha.Reset();
    sha.Input(buffer,status->file_length);
    free(buffer);
    buffer = NULL;
    if (!sha.Result(FileHash_D2))
    {
        gprintf("could not compute Hash of D2!\n");
        return -80;
    }
    sha.Reset();
    /*gprintf("sha1 original : %x %x %x %x %x\nsha1 written : %x %x %x %x %x\n",
    																	  FileHash_D1[0],FileHash_D1[1],FileHash_D1[2],FileHash_D1[3],FileHash_D1[4],
    																	  FileHash_D2[0],FileHash_D2[1],FileHash_D2[2],FileHash_D2[3],FileHash_D2[4]);*/
    if (!memcmp(FileHash_D1,FileHash_D2,sizeof(FileHash_D1)))
    {
        gprintf("nand_copy : SHA1 hash success\n");
        ISFS_Delete(destination);
        ret = ISFS_Rename(temp_dest,destination);
        gprintf("ISFS_Rename ret %d\n",ret);
        if ( ret < 0)
            temp = -5;
        goto free_and_Return;
    }
    else
    {
        temp = -6;
        goto free_and_Return;
    }
free_and_Return:
    if(buffer)
    {
        free(buffer);
        buffer = NULL;
    }
    if (temp < 0)
    {
        gprintf("nand_copy temp %d fail o.o;\n",temp);
        ISFS_Delete(temp_dest);
        return -80;
    }
    return 1;
}
Пример #12
0
s32 nand_copy(const char *destination,u8* Buf_To_Write_to_Copy, u32 buf_size,Nand_Permissions src_perm)
{
    if( Buf_To_Write_to_Copy == NULL || buf_size < 1 )
    {
        return -1;
    }
    s32 ret, dest_handler;
    gprintf("owner %d group %d attributes %X perm:%X-%X-%X\n", src_perm.owner, (u32)src_perm.group, (u32)src_perm.attributes, (u32)src_perm.ownerperm, (u32)src_perm.groupperm, (u32)src_perm.otherperm);

    //extract filename from destination
    char temp_dest[ISFS_MAXPATH];
    memset(temp_dest,0,ISFS_MAXPATH);
    char *ptemp = NULL;
    ptemp = strstr(destination,"/");
    while(ptemp != NULL && strstr(ptemp+1,"/") != NULL)
    {
        ptemp = strstr(ptemp+1,"/");
    }
    if(ptemp[0] == '/')
    {
        ptemp = ptemp+1;
    }

    //create temp path
    memset(temp_dest,0,ISFS_MAXPATH);
    sprintf(temp_dest,"/tmp/%s",ptemp);
    ISFS_Delete(temp_dest);

    //and go for it
    ret = ISFS_CreateFile(temp_dest,src_perm.attributes,src_perm.ownerperm,src_perm.groupperm,src_perm.otherperm);
    if (ret != ISFS_OK)
    {
        printf("Failed to create file %s. ret = %d\n",temp_dest,ret);
        gprintf("Failed to create file %s. ret = %d\n",temp_dest,ret);
        return ret;
    }
    dest_handler = ISFS_Open(temp_dest,ISFS_OPEN_RW);
    if (dest_handler < 0)
    {
        gprintf("failed to open destination : %s\n",temp_dest);
        ISFS_Delete(temp_dest);
        return dest_handler;
    }

    ret = ISFS_Write(dest_handler,Buf_To_Write_to_Copy,buf_size);
    if (ret < 0)
    {
        gprintf("failed to write destination : %s\n",temp_dest);
        ISFS_Close(dest_handler);
        ISFS_Delete(temp_dest);
        return ret;
    }
    ISFS_Close(dest_handler);
    s32 temp = 0;
    u8 *Data2 = NULL;
    STACK_ALIGN(fstats,D2stat,sizeof(fstats),32);
    /*if (D2stat == NULL)
    {
    	temp = -1;
    	goto free_and_Return;
    }*/
    dest_handler = ISFS_Open(temp_dest,ISFS_OPEN_RW);
    if(dest_handler < 0)
    {
        gprintf("temp_dest open error %d\n",dest_handler);
        temp = -2;
        goto free_and_Return;
    }
    temp = ISFS_GetFileStats(dest_handler,D2stat);
    if(temp < 0)
    {
        goto free_and_Return;
    }
    Data2 = (u8*)memalign(32,ALIGN32(D2stat->file_length));
    if (Data2 == NULL)
    {
        temp = -3;
        goto free_and_Return;
    }
    if( ISFS_Read(dest_handler,Data2,D2stat->file_length) > 0 )
    {
        if( !CompareSha1Hash(Buf_To_Write_to_Copy,buf_size,Data2,D2stat->file_length))
        {
            temp = -4;
            goto free_and_Return;
        }
    }
    else
    {
        temp = -5;
        goto free_and_Return;
    }
    if(Data2)
    {
        free(Data2);
        Data2 = NULL;
    }
    ISFS_Close(dest_handler);
    //so it was written to /tmp correctly. lets call ISFS_Rename and compare AGAIN
    ISFS_Delete(destination);
    ret = ISFS_Rename(temp_dest,destination);
    if(ret < 0 )
    {
        gprintf("nand_copy(buf) : rename returned %d\n",ret);
        temp = -6;
        goto free_and_Return;
    }
free_and_Return:
    if(Data2 != NULL)
    {
        free(Data2);
        Data2 = NULL;
    }
    ISFS_Close(dest_handler);
    if (temp < 0)
    {
        gprintf("temp %d\n",temp);
        //ISFS_Delete(destination);
        return -80;
    }
    return 1;
}
Пример #13
0
s8 WritePriiloader( bool priiloader_found )
{
    s32 ret = 0;
    s32 fd = 0;
    Nand_Permissions SysPerm;
    if(priiloader_found == false)
    {
        memset(&SysPerm,0,sizeof(Nand_Permissions));
        SysPerm.otherperm = 3;
        SysPerm.groupperm = 3;
        SysPerm.ownerperm = 3;
        //system menu coping
        printf("Moving System Menu app...");
        ret = nand_copy(original_app,copy_app,SysPerm);
        if (ret < 0)
        {
            if (ret == -80)
            {
                //checksum issues
                printf("\x1b[%u;%dm", 33, 1);
                printf("\nWARNING!!\n  Installer could not calculate the Checksum for the System menu app");
                printf("\nbut Copy was successfull.\n");
                printf("Do you want the Continue ?\n");
                printf("A = Yes       B = No\n  ");
                printf("\x1b[%u;%dm", 37, 1);
                if(!UserYesNoStop())
                {
                    printf("reverting changes...\n");
                    ISFS_Delete(copy_app);
                    abort("System Menu Copying Failure");
                }
                else
                    printf("\nDone!\n");
            }
            else
                abort("\nUnable to move the system menu. error %d",ret);
        }
        else
        {
            gprintf("Moving System Menu Done\n");
            printf("Done!\n");
        }
    }
    ret = 0;
    //sys_menu app moved. lets write priiloader
    STACK_ALIGN(fstats,status,sizeof(fstats),32);
    memset(&SysPerm,0,sizeof(Nand_Permissions));
    SysPerm.otherperm = 3;
    SysPerm.groupperm = 3;
    SysPerm.ownerperm = 3;

    printf("Writing Priiloader app...");
    gprintf("Writing Priiloader\n");

    char temp_dest[ISFS_MAXPATH];
    memset(temp_dest,0,ISFS_MAXPATH);
    char *ptemp = NULL;
    ptemp = strstr(original_app,"/");
    while(ptemp != NULL && strstr(ptemp+1,"/") != NULL)
    {
        ptemp = strstr(ptemp+1,"/");
    }
    if(ptemp[0] == '/')
    {
        ptemp = ptemp+1;
    }
    memset(temp_dest,0,ISFS_MAXPATH);
    sprintf(temp_dest,"/tmp/%s",ptemp);
    ISFS_Delete(temp_dest);
    ret = ISFS_CreateFile(temp_dest,SysPerm.attributes,SysPerm.ownerperm,SysPerm.groupperm,SysPerm.otherperm);

    fd = ISFS_Open(temp_dest,ISFS_OPEN_RW);
    if (fd < 0)
    {
        gprintf("error %d\n",fd);
        abort("\nFailed to open file for Priiloader writing");
    }
    ret = ISFS_Write(fd,priiloader_app,priiloader_app_size);
    if (ret < 0 ) //check if the app was writen correctly
    {
        ISFS_Close(fd);
        ISFS_Delete(copy_app);
        ISFS_Delete(temp_dest);
        gprintf("Write failed. ret %d\n",ret);
        abort("\nWrite of Priiloader app failed");
    }
    ISFS_Close(fd);

    //SHA1 check here
    fd = ISFS_Open(temp_dest,ISFS_OPEN_READ);
    if (fd < 0)
    {
        ISFS_Delete(copy_app);
        abort("\nFailed to open file for Priiloader checking");
    }
    if (ISFS_GetFileStats(fd,status) < 0)
    {
        ISFS_Close(fd);
        ISFS_Delete(copy_app);
        abort("Failed to get stats of %s. System Menu Recovered",temp_dest);
    }
    else
    {
        if ( status->file_length != priiloader_app_size )
        {
            ISFS_Close(fd);
            ISFS_Delete(copy_app);
            abort("Written Priiloader app isn't the correct size.System Menu Recovered");
        }
        else
        {
            gprintf("Size Check Success\n");
            printf("Size Check Success!\n");
        }
    }
    u8 *AppData = (u8 *)memalign(32,ALIGN32(status->file_length));
    if (AppData)
        ret = ISFS_Read(fd,AppData,status->file_length);
    else
    {
        ISFS_Close(fd);
        ISFS_Delete(copy_app);
        abort("Checksum comparison Failure! MemAlign Failure of AppData\n");
    }
    ISFS_Close(fd);
    if (ret < 0)
    {
        if (AppData)
        {
            free(AppData);
            AppData = NULL;
        }
        ISFS_Delete(copy_app);
        abort("Checksum comparison Failure! read of priiloader app returned %u\n",ret);
    }
    if(CompareSha1Hash((u8*)priiloader_app,priiloader_app_size,AppData,status->file_length))
        printf("Checksum comparison Success!\n");
    else
    {
        if (AppData)
        {
            free(AppData);
            AppData = NULL;
        }
        ISFS_Delete(copy_app);
        abort("Checksum comparison Failure!\n");
    }
    if (AppData)
    {
        free(AppData);
        AppData = NULL;
    }
    // rename and do a final SHA1 chezck
    ISFS_Delete(original_app);
    ret = ISFS_Rename(temp_dest,original_app);
    if(ret < 0 )
    {
        gprintf("WritePriiloader : rename returned %d\n",ret);
        nand_copy(copy_app,original_app,SysPerm);
        ISFS_Delete(copy_app);
        abort("\nFailed to Write Priiloader : error Ren %d",ret);
    }
    printf("Done!!\n");
    gprintf("Wrote Priiloader App.Checking Installation\n");
    printf("\nChecking Priiloader Installation...\n");
    memset(status,0,sizeof(fstats));
    fd = ISFS_Open(original_app,ISFS_OPEN_READ);
    if (fd < 0)
    {
        nand_copy(copy_app,original_app,SysPerm);
        ISFS_Delete(copy_app);
        abort("\nFailed to open file for Priiloader checking");
    }
    if (ISFS_GetFileStats(fd,status) < 0)
    {
        ISFS_Close(fd);
        nand_copy(copy_app,original_app,SysPerm);
        abort("Failed to get stats of %s. System Menu Recovered",original_app);
    }
    else
    {
        if ( status->file_length != priiloader_app_size )
        {
            ISFS_Close(fd);
            nand_copy(copy_app,original_app,SysPerm);
            ISFS_Delete(copy_app);
            abort("Written Priiloader app isn't the correct size.System Menu Recovered");
        }
        else
        {
            gprintf("Size Check Success\n");
            printf("Size Check Success!\n");
        }
    }
    AppData = (u8 *)memalign(32,ALIGN32(status->file_length));
    if (AppData != NULL)
        ret = ISFS_Read(fd,AppData,status->file_length);
    else
    {
        ISFS_Close(fd);
        nand_copy(copy_app,original_app,SysPerm);
        ISFS_Delete(copy_app);
        abort("Checksum comparison Failure! MemAlign Failure of AppData\n");
    }
    ISFS_Close(fd);
    if (ret < 0)
    {
        if (AppData)
        {
            free(AppData);
            AppData = NULL;
        }
        nand_copy(copy_app,original_app,SysPerm);
        ISFS_Delete(copy_app);
        abort("Checksum comparison Failure! read of priiloader app returned %u\n",ret);
    }
    if(CompareSha1Hash((u8*)priiloader_app,priiloader_app_size,AppData,status->file_length))
        printf("Checksum comparison Success!\n");
    else
    {
        if (AppData)
        {
            free(AppData);
            AppData = NULL;
        }
        nand_copy(copy_app,original_app,SysPerm);
        ISFS_Delete(copy_app);
        abort("Checksum comparison Failure!\n");
    }
    if (AppData)
    {
        free(AppData);
        AppData = NULL;
    }
    gprintf("Priiloader Update Complete\n");
    printf("Done!\n\n");
    return 1;
}
Пример #14
0
int NandTitle::ExtractFile(const char *nandPath, const char *filepath)
{
	if(!nandPath || !filepath)
		return -1;

	char *strDup = strdup(filepath);
	if(!strDup)
		return -666;

	char *ptr = strrchr(strDup, '/');
	if(!ptr)
	{
		free(strDup);
		return -333;
	}
	else
	{
		*ptr = 0;
		CreateSubfolder(strDup);
		free(strDup);
	}

	int done = 0;
	int fd = -1;
	int blocksize = 32*1024;
	u8 *buffer = (u8 *) memalign(32, ALIGN32(blocksize));
	if(!buffer)
		return -666;

	fstats *stats = (fstats *) memalign(32, ALIGN32(sizeof(fstats)));
	if(!stats)
	{
		free(buffer);
		return -666;
	}

	do
	{
		fd = ISFS_Open(nandPath, ISFS_OPEN_READ);
		if(fd < 0)
			break;

		int ret = ISFS_GetFileStats(fd, stats);
		if (ret < 0)
			break;

		int filesize = stats->file_length;

		FILE *pFile = fopen(filepath, "wb");
		if(!pFile)
			break;

		while(done < filesize)
		{
			if(filesize-done < blocksize)
				blocksize = filesize-done;

			ret = ISFS_Read(fd, buffer, blocksize);
			if(ret < 0)
			{
				done = ret;
				break;
			}

			fwrite(buffer, 1, ret, pFile);

			done += ret;
		}

		fclose(pFile);

	} while(0);

	free(buffer);
	free(stats);

	if(fd >= 0)
		ISFS_Close(fd);

	return done;

}