Programm erstellt einen Ordner, aber kopiert den Inhalt des Ordners nicht - bitte mal drüberschauen. Danke!
Hallo, liebe Gemeinde!
Ich benutze ein Programm (makeps3iso.exe), um aus PS3-Files wieder ISOs zu erstellen. Dabei habe ich festgestellt, daß in den fertigen ISOs zwar der "PS3_UPDATE" vorhanden ist, aber dieser ist leer und enthält keine "PS3UPDAT.PUP". Also läßt makeps3iso beim Erstellen der ISOs einfach diese Datei weg - aber ich hätte sie gerne, denn ich möchte die ISOs exakt so, wie sie auf den Originalmedien bzw. als Files vorhanden sind.
Ich habe den Sourcecode von makeps3iso (s.u.), aber keinerlei Ahnung von Programmierung - vielleicht könnte ja mal jemand der programmieren kann drüber schauen und diesen Mißstand beheben.
Wäre grandios, wenn es eine kompilierte Version von makep3iso geben würde, die die Update-Files auch kopiert und nicht nur einen leeren Ordner erstellt!!! Makefile und makeIt.bat wären auch vorhanden, falls benötigt...
Vielen Dank im voraus!!!
Ich benutze ein Programm (makeps3iso.exe), um aus PS3-Files wieder ISOs zu erstellen. Dabei habe ich festgestellt, daß in den fertigen ISOs zwar der "PS3_UPDATE" vorhanden ist, aber dieser ist leer und enthält keine "PS3UPDAT.PUP". Also läßt makeps3iso beim Erstellen der ISOs einfach diese Datei weg - aber ich hätte sie gerne, denn ich möchte die ISOs exakt so, wie sie auf den Originalmedien bzw. als Files vorhanden sind.
Ich habe den Sourcecode von makeps3iso (s.u.), aber keinerlei Ahnung von Programmierung - vielleicht könnte ja mal jemand der programmieren kann drüber schauen und diesen Mißstand beheben.
Wäre grandios, wenn es eine kompilierte Version von makep3iso geben würde, die die Update-Files auch kopiert und nicht nur einen leeren Ordner erstellt!!! Makefile und makeIt.bat wären auch vorhanden, falls benötigt...
Vielen Dank im voraus!!!
/*
(c) 2013 Estwald/Hermes <www.elotrolado.net>
MAKEPS3ISO is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
MAKEPS3ISO 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 General Public License for more details.
You should have received a copy of the GNU General Public License
apayloadlong with MAKEPS3ISO. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <sys/stat.h>
#include <dirent.h>
#include <time.h>
#include <ctype.h>
int verbose = 1;
//#define ALIGNED32SECTORS 1
#define NOPS3_UPDATE 1
#if defined (__MSVCRT__)
#define stat _stati64
#endif
#define u8 unsigned char
#define u16 unsigned short
#define u32 unsigned int
#define u64 unsigned long long
static int get_input_char()
{
char c = getchar();
char c2 = c;
while (c != '\n' && c != EOF)
c = getchar();
return c2;
}
#ifdef __MSVCRT__
#include <windows.h>
#include <winbase.h>
#include <wincrypt.h>
// get_rand() method from ps3netsrv Cobra Sources...
static void get_rand(void *bfr, u32 size)
{
HCRYPTPROV hProv;
if (size == 0)
return;
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{fprintf(stderr, "Error aquiring crypt context.\n"); return;}
if (!CryptGenRandom(hProv, size, (BYTE *)bfr))
fprintf(stderr, "Errorgetting random numbers.\n");
CryptReleaseContext(hProv, 0);
}
static u64 get_disk_free_space(char *path)
{
DWORD SectorsPerCluster, BytesPerSector, NumberOfFreeClusters, TotalNumberOfClusters;
if(!GetDiskFreeSpace(path, &SectorsPerCluster, &BytesPerSector, &NumberOfFreeClusters, &TotalNumberOfClusters))
return (u64) (-1LL);
return ((u64) BytesPerSector) * ((u64) SectorsPerCluster) * ((u64) NumberOfFreeClusters);
}
#elif __unix__
#include <sys/statvfs.h>
// get_rand() method from ps3netsrv Cobra Sources...
static void get_rand(void *bfr, u32 size)
{
FILE *fp;
if (size == 0)
return;
fp = fopen("/dev/urandom", "r");
if (fp == NULL) {
fprintf(stderr, "Error aquiring crypt context.\n");
return;
}
if (fread(bfr, size, 1, fp) != 1)
fprintf(stderr, "Error getting random numbers.\n");
fclose(fp);
}
static u64 get_disk_free_space(char *path)
{
struct statvfs svfs;
if(statvfs((const char *) path, &svfs)!=0)
return (u64) (-1LL);
return ( ((u64)svfs.f_bsize * svfs.f_bfree));
}
#else
#error "include here your own method to get free disk space or remove this line"
static u64 get_disk_free_space(char *path)
{
return (u64) (-1LL);
}
#endif
///////////////////////////////////////////////////////////////////////////////////////////////////////////
#define ISODCL(from, to) (to - from + 1)
static void setdaterec(unsigned char *p,int dd,int mm,int aa,int ho,int mi,int se)
{
*p++=(unsigned char) ((aa-1900) & 255);*p++=(char) (mm & 15) ;*p++=(char) (dd & 31);*p++=(char) ho;*p++=(char) mi;*p++=(char) se;*p++=(char) 0;
}
static void set731(unsigned char *p,int n)
{
*p++=(n & 0xff);*p++=((n>>8) & 0xff);*p++=((n>>16) & 0xff);*p++=((n>>24) & 0xff);
}
static void set733(unsigned char *p,int n)
{
*p++=(n & 0xff);*p++=((n>>8) & 0xff);*p++=((n>>16) & 0xff);*p++=((n>>24) & 0xff);
*p++=((n>>24) & 0xff);*p++=((n>>16) & 0xff);*p++=((n>>8) & 0xff);*p++=(n & 0xff);
}
static void set732(unsigned char *p,int n)
{
*p++=((n>>24) & 0xff);*p++=((n>>16) & 0xff);*p++=((n>>8) & 0xff);*p++=(n & 0xff);
}
static void set721(unsigned char *p,int n)
{
*p++=(n & 0xff);*p++=((n>>8) & 0xff);
}
static void set722(unsigned char *p,int n)
{
*p++=((n>>8) & 0xff);*p++=(n & 0xff);
}
static void set723(unsigned char *p,int n)
{
*p++=(n & 0xff);*p++=((n>>8) & 0xff);*p++=((n>>8) & 0xff);*p++=(n & 0xff);
}
#if 0
static int isonum_731 (unsigned char * p)
{
return ((p & 0xff)
| ((p[1] & 0xff) << 8)
| ((p[2] & 0xff) << 16)
| ((p[3] & 0xff) << 24));
}
static int isonum_732 (unsigned char * p)
{
return ((p[3] & 0xff)
| ((p[2] & 0xff) << 8)
| ((p[1] & 0xff) << 16)
| ((p & 0xff) << 24));
}
static int isonum_733 (unsigned char * p)
{
return (isonum_731 (p));
}
static int isonum_721 (char * p)
{
return ((p & 0xff) | ((p[1] & 0xff) << 8));
}
static int isonum_723 (char * p)
{
return (isonum_721 (p));
}
#endif
struct iso_primary_descriptor {
unsigned char type [ISODCL ( 1, 1)]; /* 711 */
unsigned char id [ISODCL ( 2, 6)];
unsigned char version [ISODCL ( 7, 7)]; /* 711 */
unsigned char unused1 [ISODCL ( 8, 8)];
unsigned char system_id [ISODCL ( 9, 40)]; /* aunsigned chars */
unsigned char volume_id [ISODCL ( 41, 72)]; /* dunsigned chars */
unsigned char unused2 [ISODCL ( 73, 80)];
unsigned char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
unsigned char unused3 [ISODCL ( 89, 120)];
unsigned char volume_set_size [ISODCL (121, 124)]; /* 723 */
unsigned char volume_sequence_number [ISODCL (125, 128)]; /* 723 */
unsigned char logical_block_size [ISODCL (129, 132)]; /* 723 */
unsigned char path_table_size [ISODCL (133, 140)]; /* 733 */
unsigned char type_l_path_table [ISODCL (141, 144)]; /* 731 */
unsigned char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
unsigned char type_m_path_table [ISODCL (149, 152)]; /* 732 */
unsigned char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
unsigned char root_directory_record [ISODCL (157, 190)]; /* 9.1 */
unsigned char volume_set_id [ISODCL (191, 318)]; /* dunsigned chars */
unsigned char publisher_id [ISODCL (319, 446)]; /* achars */
unsigned char preparer_id [ISODCL (447, 574)]; /* achars */
unsigned char application_id [ISODCL (575, 702)]; /* achars */
unsigned char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
unsigned char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
unsigned char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
unsigned char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
unsigned char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
unsigned char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
unsigned char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
unsigned char file_structure_version [ISODCL (882, 882)]; /* 711 */
unsigned char unused4 [ISODCL (883, 883)];
unsigned char application_data [ISODCL (884, 1395)];
unsigned char unused5 [ISODCL (1396, 2048)];
};
struct iso_directory_record {
unsigned char length [ISODCL (1, 1)]; /* 711 */
unsigned char ext_attr_length [ISODCL (2, 2)]; /* 711 */
unsigned char extent [ISODCL (3, 10)]; /* 733 */
unsigned char size [ISODCL (11, 18)]; /* 733 */
unsigned char date [ISODCL (19, 25)]; /* 7 by 711 */
unsigned char flags [ISODCL (26, 26)];
unsigned char file_unit_size [ISODCL (27, 27)]; /* 711 */
unsigned char interleave [ISODCL (28, 28)]; /* 711 */
unsigned char volume_sequence_number [ISODCL (29, 32)]; /* 723 */
unsigned char name_len [1]; /* 711 */
unsigned char name [1];
};
struct iso_path_table{
unsigned char name_len[2]; /* 721 */
char extent[4]; /* 731 */
char parent[2]; /* 721 */
char name[1];
};
#define SWAP16(x) ((((u16)(x))>>8) | ((x) << 8))
static void UTF8_to_UTF16(u8 *stb, u16 *stw)
{
int n, m;
u32 UTF32;
while(*stb) {
if(*stb & 128) {
m = 1;
if((*stb & 0xf8)==0xf0) { // 4 bytes
UTF32 = (u32) (*(stb++) & 3);
m = 3;
} else if((*stb & 0xE0)==0xE0) { // 3 bytes
UTF32 = (u32) (*(stb++) & 0xf);
m = 2;
} else if((*stb & 0xE0)==0xC0) { // 2 bytes
UTF32 = (u32) (*(stb++) & 0x1f);
m = 1;
} else {stb++;continue;} // error!
for(n = 0; n < m; n++) {
if(!*stb) break; // error!
if((*stb & 0xc0) != 0x80) break; // error!
UTF32 = (UTF32 <<6) |((u32) (*(stb++) & 63));
}
if((n != m) && !*stb) break;
} else UTF32 = (u32) *(stb++);
if(UTF32<65536)
*stw++= SWAP16((u16) UTF32);
else {//110110ww wwzzzzyy 110111yy yyxxxxxx
*stw++= SWAP16((((u16) (UTF32>>10)) & 0x3ff) | 0xD800);
*stw++= SWAP16((((u16) (UTF32)) & 0x3ff) | 0xDC00);
}
}
*stw++ = 0;
}
static void utf8_to_ansiname(char *utf8, char *ansi, int len)
{
u8 *ch= (u8 *) utf8;
u8 c;
int is_space = 1;
char *a = ansi;
*ansi = 0;
while(*ch!=0 && len>0){
// 3, 4 bytes utf-8 code
if(((*ch & 0xF1)==0xF0 || (*ch & 0xF0)==0xe0) && (*(ch+1) & 0xc0) == 0x80){
if(!is_space) {
*ansi++=' '; // ignore
len--;
is_space = 1;
}
ch+= 2+1*((*ch & 0xF1) == 0xF0);
}
else
// 2 bytes utf-8 code
if((*ch & 0xE0)==0xc0 && (*(ch+1) & 0xc0)==0x80){
c= (((*ch & 3)<<6) | (*(ch+1) & 63));
if(c>=0xC0 && c<=0xC5) c='A';
else if(c==0xc7) c='C';
else if(c>=0xc8 && c<=0xcb) c='E';
else if(c>=0xcc && c<=0xcf) c='I';
else if(c==0xd1) c='N';
else if(c>=0xd2 && c<=0xd6) c='O';
else if(c>=0xd9 && c<=0xdc) c='U';
else if(c==0xdd) c='Y';
else if(c>=0xe0 && c<=0xe5) c='a';
else if(c==0xe7) c='c';
else if(c>=0xe8 && c<=0xeb) c='e';
else if(c>=0xec && c<=0xef) c='i';
else if(c==0xf1) c='n';
else if(c>=0xf2 && c<=0xf6) c='o';
else if(c>=0xf9 && c<=0xfc) c='u';
else if(c==0xfd || c==0xff) c='y';
else if(c>127) c=*(++ch+1); //' ';
if(!is_space || c!= 32) {
*ansi++=c;
len--;
if(c == 32) is_space = 1; else is_space = 0;
}
ch++;
} else {
if(*ch<32) *ch=32;
if(!is_space || *ch!= 32) {
*ansi++=*ch;
len--;
if(*ch == 32) is_space = 1; else is_space = 0;
}
}
ch++;
}
while(len>0) {
*ansi++=0;
len--;
}
if(a == 0 || a == ' ') strcpy(a, "PS3");
}
static int cur_isop = -1;
static int lpath;
static int wpath;
static u32 llba0 = 0; // directory path0
static u32 llba1 = 0; // directory path1
static u32 wlba0 = 0; // directory pathw0
static u32 wlba1 = 0; // directory pathw1
static u32 dllba = 0; // dir entries
static u32 dwlba = 0; // dir entriesw
static u32 dlsz = 0; // dir entries size (sectors)
static u32 dwsz = 0; // dir entriesw size (sectors)
static u32 flba = 0; // first lba for files
static u32 toc = 0; // TOC of the iso
static char iso_split = 0;
static char output_name[0x420];
static int pos_lpath0 = 0;
static int pos_lpath1 = 0;
static int pos_wpath0 = 0;
static int pos_wpath1 = 0;
static int dd = 1, mm = 1, aa = 2013, ho = 0, mi = 0, se = 2;
static u8 *sectors = NULL;
#define MAX_ISO_PATHS 4096
typedef struct {
u32 ldir;
u32 wdir;
u32 llba;
u32 wlba;
int parent;
char *name;
} _directory_iso;
static _directory_iso *directory_iso = NULL;
static u16 wstring[1024];
static char temp_string[1024];
static void memcapscpy(void *dest, void *src, int size)
{
char *d = dest;
char *s = src;
char c;
int n;
for(n = 0; n < size; n++) {c = *s++; *d++ =toupper(c);}
}
static int parse_param_sfo(char * file, char *title_id, char *title_name)
{
FILE *fp;
int bytes;
int ct = 0;
fp = fopen(file, "rb");
if(fp)
{
int len, pos, str;
unsigned char *mem=NULL;
fseek(fp, 0, SEEK_END);
len = ftell(fp);
mem= (unsigned char *) malloc(len+16);
if(!mem) {fclose(fp);return -2;}
memset(mem, 0, len+16);
fseek(fp, 0, SEEK_SET);
bytes = fread((void *) mem, 1, len, fp);
fclose(fp);
if(bytes != len) {
free(mem);
return -2;
}
str= (mem[8]+(mem[9]<<8));
pos=(mem[0xc]+(mem[0xd]<<8));
int indx=0;
while(str<len) {
if(mem[str]==0) break;
if(!strcmp((char *) &mem[str], "TITLE")) {
strncpy(title_name, (char *) &mem[pos], 63);
ct++;
}
else
if(!strcmp((char *) &mem[str], "TITLE_ID")) {
memcpy(title_id, (char *) &mem[pos], 4);
title_id[4] = '-';
strncpy(&title_id[5], (char *) &mem[pos + 4], 58);
ct++;
}
if(ct == 2) {
free(mem);
return 0;
}
while(mem[str]) str++;str++;
pos+=(mem[0x1c+indx]+(mem[0x1d+indx]<<8));
indx+=16;
}
if(mem) free(mem);
}
return -1;
}
int print_cycle = 0;
char cycle_str[4][2] = {"/", "-", "\\", "|" };
static int calc_entries(char *path, int parent)
{
DIR *dir;
int len_string;
struct stat s;
int cldir = 0;
int ldir = sizeof(struct iso_directory_record) + 6; // ..
ldir = (ldir + 7) & ~7;
ldir += sizeof(struct iso_directory_record) + 6; // .
ldir += ldir & 1;
int cwdir = 0;
int wdir = sizeof(struct iso_directory_record) + 6; // ..
wdir = (wdir + 7) & ~7;
wdir += sizeof(struct iso_directory_record) + 6; // .
wdir += wdir & 1;
cldir = ldir;
cwdir = wdir;
lpath+= (lpath & 1);
wpath+= (wpath & 1);
int cur = cur_isop;
if(cur >= MAX_ISO_PATHS) return -444;
directory_iso[cur].ldir = ldir;
directory_iso[cur].wdir = wdir;
directory_iso[cur].parent = parent;
if(!cur) {
directory_iso[cur].name = malloc(16);
if(!directory_iso[cur].name) return -1;
directory_iso[cur].name = 0;
}
int cur2 = cur;
cur_isop++;
// files
dir = opendir (path);
if(dir) {
while(1) {
struct dirent *entry = readdir (dir);
if(!entry) break;
if(entry->d_name=='.' && (entry->d_name[1]=='.' || entry->d_name[1]== 0)) continue;
int len = strlen(path);
strcat(path,"/");
strcat(path, entry->d_name);
if(stat(path, &s)<0) {closedir(dir); return -669;}
path[len] = 0;
if(verbose) printf("\r%s \r", &cycle_str[print_cycle]); print_cycle++; print_cycle&= 3;
if(!S_ISDIR(s.st_mode)) {
int lname = strlen(entry->d_name);
if(lname >=6 && !strcmp(&entry->d_name[lname -6], ".66600")) { // build size of .666xx files
u64 size = s.st_size;
lname -= 6;
int n;
memcpy(temp_string, entry->d_name, lname);
temp_string[lname] = 0;
if(lname > 222) {closedir(dir); return -555;}
UTF8_to_UTF16((u8 *) temp_string, wstring);
for(len_string = 0; len_string < 512; len_string++) if(wstring[len_string] == 0) break;
if(len_string > 222) {closedir(dir); return -555;}
path[len] = 0;
for(n = 1; n < 100; n++) {
int len2 = strlen(path);
strcat(path,"/");
int l = strlen(path);
memcpy(path + l, entry->d_name, lname);
sprintf(&path[l + lname], ".666%2.2u", n);
if(stat(path, &s)<0) {s.st_size = size; path[len2] = 0; break;}
path[len2] = 0;
size += s.st_size;
}
path[len] = 0;
} else {
if(lname >=6 && !strncmp(&entry->d_name[lname -6], ".666", 4)) continue; // ignore .666xx files
else {
if(strlen(entry->d_name) > 222) {closedir(dir); return -555;}
UTF8_to_UTF16((u8 *) entry->d_name, wstring);
for(len_string = 0; len_string < 512; len_string++) if(wstring[len_string] == 0) break;
if(len_string > 222) {closedir(dir); return -555;}
}
}
int parts = s.st_size ? (int) ((((u64) s.st_size) + 0xFFFFF7FFULL)/0xFFFFF800ULL) : 1;
int n;
for(n = 0; n < parts; n++) {
int add;
add = sizeof(struct iso_directory_record) + lname - 1 + 8; // add ";1"
add+= add & 1;
cldir += add;
if(cldir > 2048) {
ldir = (ldir & ~2047) + 2048;
cldir = add;
} else if(cldir == 2048){
cldir = 0;
}
ldir += add;
//ldir += ldir & 1;
add = sizeof(struct iso_directory_record) - 1 + len_string * 2 + 4 + 6; // add "\0;\01"
add+= add & 1;
cwdir += add;
if(cwdir > 2048) {
wdir= (wdir & ~2047) + 2048;
cwdir = add;
} else if(cwdir == 2048){
cwdir = 0;
}
wdir += add;
//wdir += wdir & 1;
}
}
}
closedir (dir);
// directories
dir = opendir (path);
if(dir) {
while(1) {
struct dirent *entry = readdir (dir);
if(!entry) break;
if(entry->d_name=='.' && (entry->d_name[1]=='.' || entry->d_name[1]== 0)) continue;
int len = strlen(path);
strcat(path,"/");
strcat(path, entry->d_name);
if(stat(path, &s)<0) {closedir(dir); return -669;}
path[len] = 0;
if(verbose) printf("\r%s \r", &cycle_str[print_cycle]); print_cycle++; print_cycle&= 3;
if(S_ISDIR(s.st_mode)) {
if(strlen(entry->d_name) > 222) {closedir(dir); return -555;}
UTF8_to_UTF16((u8 *) entry->d_name, wstring);
for(len_string = 0; len_string < 512; len_string++) if(wstring[len_string] == 0) break;
if(len_string > 222) {closedir(dir); return -555;}
lpath += sizeof(struct iso_path_table) + strlen(entry->d_name) - 1;
lpath += (lpath & 1);
int add;
add = sizeof(struct iso_directory_record) + strlen(entry->d_name) - 1 + 6;
add+= add & 1;
cldir += add;
if(cldir > 2048) {
ldir = (ldir & ~2047) + 2048;
cldir = add;
} else if(cldir == 2048){
cldir = 0;
}
ldir += add;
//ldir += ldir & 1;
wpath += sizeof(struct iso_path_table) + len_string * 2 - 1;
wpath += (wpath & 1);
add = sizeof(struct iso_directory_record) + len_string * 2 - 1 + 6;
add+= add & 1;
cwdir += add;
if(cwdir > 2048) {
wdir= (wdir & ~2047) + 2048;
cwdir = add;
} else if(cwdir == 2048){
cwdir = 0;
}
wdir += add;
//wdir += wdir & 1;
}
}
closedir (dir);
}
//if((2048 - (ldir & 2047)) < 256/*sizeof(struct iso_directory_record)*/) ldir += 2048; // increase an sector if not space for directory record
//if((2048 - (wdir & 2047)) < 256/*sizeof(struct iso_directory_record)*/) wdir += 2048; // increase an sector if not space for directory record
directory_iso[cur].ldir = (ldir + 2047)/2048;
directory_iso[cur].wdir = (wdir + 2047)/2048;
}
// directories add
dir = opendir (path);
if(dir) {
while(1) {
struct dirent *entry = readdir (dir);
if(!entry) break;
if(entry->d_name=='.' && (entry->d_name[1]=='.' || entry->d_name[1]== 0)) continue;
int len = strlen(path);
strcat(path,"/");
strcat(path, entry->d_name);
if(stat(path, &s)<0) {closedir(dir); return -669;}
if(!(S_ISDIR(s.st_mode))) {path[len] = 0; continue;}
//printf("ss %s\n", path);
directory_iso[cur_isop].name = malloc(strlen(entry->d_name) + 1);
if(!directory_iso[cur_isop].name) {closedir(dir); return -1;}
strcpy(directory_iso[cur_isop].name, entry->d_name);
int ret = calc_entries(path, cur2 + 1);
if(ret < 0) {closedir(dir); return ret;}
path[len] = 0;
}
closedir (dir);
}
if(cur == 0) {
llba0 = 20;
llba1 = llba0 + ((lpath + 2047)/2048);
wlba0 = llba1 + ((lpath + 2047)/2048);
wlba1 = wlba0 + ((wpath + 2047)/2048);
dllba = wlba1 + ((wpath + 2047)/2048);
if(dllba < 32) dllba = 32;
int n;
int m, l;
// searching...
for(n = 1; n < cur_isop - 1; n++)
for(m = n + 1; m < cur_isop; m++) {
if(directory_iso[n].parent > directory_iso[m].parent) {
directory_iso[cur_isop] = directory_iso[n]; directory_iso[n] = directory_iso[m]; directory_iso[m] = directory_iso[cur_isop];
for(l = n; l < cur_isop; l++) {
if(n + 1 == directory_iso[l].parent)
directory_iso[l].parent = m + 1;
else if(m + 1 == directory_iso[l].parent)
directory_iso[l].parent = n + 1;
}
}
}
/*for(n = 0; n < cur_isop; n++) {
printf("list %i %s\n", directory_iso[n].parent, directory_iso[n].name);
}*/
for(n = 0; n < cur_isop; n++) {
dlsz+= directory_iso[n].ldir;
dwsz+= directory_iso[n].wdir;
}
#ifdef ALIGNED32SECTORS
dwlba = ((dllba + dlsz) + 31) & ~31;
flba = ((dwlba + dwsz) + 31) & ~31;
#else
dwlba = (dllba + dlsz);
flba = (dwlba + dwsz);
#endif
u32 lba0 = dllba;
u32 lba1 = dwlba;
for(n = 0; n < cur_isop; n++) {
directory_iso[n].llba = lba0;
directory_iso[n].wlba = lba1;
lba0 += directory_iso[n].ldir;
lba1 += directory_iso[n].wdir;
}
if(verbose) printf("\r \r");;
}
/*
if(cur == 0) {
int n;
for(n = 0; n < cur_isop; n++) {
printf("list %i %s\n", directory_iso[n].parent, directory_iso[n].name);
}
}
*/
return 0;
}
static int fill_dirpath(void)
{
int n;
struct iso_path_table *iptl0;
struct iso_path_table *iptl1;
struct iso_path_table *iptw0;
struct iso_path_table *iptw1;
for(n = 0; n < cur_isop; n++) {
iptl0 = (void *) §ors[pos_lpath0];
iptl1 = (void *) §ors[pos_lpath1];
iptw0 = (void *) §ors[pos_wpath0];
iptw1 = (void *) §ors[pos_wpath1];
if(!n) {
set721((void *) iptl0->name_len, 1);
set731((void *) iptl0->extent, directory_iso[n].llba);
set721((void *) iptl0->parent, directory_iso[n].parent);
iptl0->name = 0;
pos_lpath0 += sizeof(struct iso_path_table) - 1 + 1;
pos_lpath0 += pos_lpath0 & 1;
iptl0 = (void *) §ors[pos_lpath0];
set721((void *) iptl1->name_len, 1);
set732((void *) iptl1->extent, directory_iso[n].llba);
set722((void *) iptl1->parent, directory_iso[n].parent);
iptl1->name = 0;
pos_lpath1 += sizeof(struct iso_path_table) - 1 + 1;
pos_lpath1 += pos_lpath1 & 1;
iptl1 = (void *) §ors[pos_lpath1];
set721((void *) iptw0->name_len, 1);
set731((void *) iptw0->extent, directory_iso[n].wlba);
set721((void *) iptw0->parent, directory_iso[n].parent);
iptw0->name = 0;
pos_wpath0 += sizeof(struct iso_path_table) - 1 + 1;
pos_wpath0 += pos_wpath0 & 1;
iptw0 = (void *) §ors[pos_wpath0];
set721((void *) iptw1->name_len, 1);
set732((void *) iptw1->extent, directory_iso[n].wlba);
set722((void *) iptw1->parent, directory_iso[n].parent);
iptw1->name = 0;
pos_wpath1 += sizeof(struct iso_path_table) - 1 + 1;
pos_wpath1 += pos_wpath1 & 1;
iptw1 = (void *) §ors[pos_wpath1];
continue;
}
//////
UTF8_to_UTF16((u8 *) directory_iso[n].name, wstring);
int len_string;
for(len_string = 0; len_string < 512; len_string++) if(wstring[len_string] == 0) break;
set721((void *) iptl0->name_len, strlen(directory_iso[n].name));
set731((void *) iptl0->extent, directory_iso[n].llba);
set721((void *) iptl0->parent, directory_iso[n].parent);
memcapscpy(&iptl0->name, directory_iso[n].name, strlen(directory_iso[n].name));
pos_lpath0 += sizeof(struct iso_path_table) - 1 + strlen(directory_iso[n].name);
pos_lpath0 += pos_lpath0 & 1;
iptl0 = (void *) §ors[pos_lpath0];
set721((void *) iptl1->name_len, strlen(directory_iso[n].name));
set732((void *) iptl1->extent, directory_iso[n].llba);
set722((void *) iptl1->parent, directory_iso[n].parent);
memcapscpy(&iptl1->name, directory_iso[n].name, strlen(directory_iso[n].name));
pos_lpath1 += sizeof(struct iso_path_table) - 1 + strlen(directory_iso[n].name);
pos_lpath1 += pos_lpath1 & 1;
iptl1 = (void *) §ors[pos_lpath1];
set721((void *) iptw0->name_len, len_string * 2);
set731((void *) iptw0->extent, directory_iso[n].wlba);
set721((void *) iptw0->parent, directory_iso[n].parent);
memcpy(&iptw0->name, wstring, len_string * 2);
pos_wpath0 += sizeof(struct iso_path_table) - 1 + len_string * 2;
pos_wpath0 += pos_wpath0 & 1;
iptw0 = (void *) §ors[pos_wpath0];
set721((void *) iptw1->name_len, len_string * 2);
set732((void *) iptw1->extent, directory_iso[n].wlba);
set722((void *) iptw1->parent, directory_iso[n].parent);
memcpy(&iptw1->name, wstring, len_string * 2);
pos_wpath1 += sizeof(struct iso_path_table) - 1 + len_string * 2;
pos_wpath1 += pos_wpath1 & 1;
iptw1 = (void *) §ors[pos_wpath1];
//////
}
return 0;
}
static int fill_entries(char *path1, char *path2, int level)
{
DIR *dir;
int n;
int len_string;
int len1 = strlen(path1);
int len2 = strlen(path2);
struct iso_directory_record *idrl = (void *) §ors[directory_iso[level].llba * 2048];
struct iso_directory_record *idrw = (void *) §ors[directory_iso[level].wlba * 2048];
struct iso_directory_record *idrl0 = idrl;
struct iso_directory_record *idrw0 = idrw;
struct tm *tm;
struct stat s;
memset((void *) idrl, 0, 2048);
memset((void *) idrw, 0, 2048);
u32 count_sec1 = 1, count_sec2 = 1, max_sec1, max_sec2;
int first_file = 1;
int aux_parent = directory_iso[level].parent - 1;
if(level!=0) {
strcat(path2, "/");
strcat(path2, directory_iso[level].name);
strcat(path1, path2);
} else {path2 = 0; fill_dirpath();}
//printf("q %s LBA %X\n", path2, directory_iso[level].llba);
if(stat(path1, &s)<0) {return -669;}
tm = localtime(&s.st_mtime);
dd = tm->tm_mday;
mm = tm->tm_mon + 1;
aa = tm->tm_year + 1900;
ho = tm->tm_hour;
mi = tm->tm_min;
se = tm->tm_sec;
idrl->length = sizeof(struct iso_directory_record) + 6;
idrl->length += idrl->length & 1;
idrl->ext_attr_length = 0;
set733((void *) idrl->extent, directory_iso[level].llba);
set733((void *) idrl->size, directory_iso[level].ldir * 2048);
setdaterec(idrl->date, dd, mm, aa, ho, mi, se);
idrl->flags = 0x2;
idrl->file_unit_size = 0x0;
idrl->interleave = 0x0;
set723((void *) idrl->volume_sequence_number, 1);
idrl->name_len = 1;
idrl->name = 0;
idrl = (void *) ((char *) idrl) + idrl->length;
max_sec1 = directory_iso[level].ldir;
idrw->length = sizeof(struct iso_directory_record) + 6;
idrw->length += idrw->length & 1;
idrw->ext_attr_length = 0;
set733((void *) idrw->extent, directory_iso[level].wlba);
set733((void *) idrw->size, directory_iso[level].wdir * 2048);
setdaterec(idrw->date, dd, mm, aa, ho, mi, se);
idrw->flags = 0x2;
idrw->file_unit_size = 0x0;
idrw->interleave = 0x0;
set723((void *) idrw->volume_sequence_number, 1);
idrw->name_len = 1;
idrw->name = 0;
idrw = (void *) ((char *) idrw) + idrw->length;
max_sec2 = directory_iso[level].wdir;
if(level) {
int len = strlen(path1);
strcat(path1,"/..");
if(stat(path1, &s)<0) {return -669;}
path1[len] = 0;
tm = localtime(&s.st_mtime);
dd = tm->tm_mday;
mm = tm->tm_mon + 1;
aa = tm->tm_year + 1900;
ho = tm->tm_hour;
mi = tm->tm_min;
se = tm->tm_sec;
}
idrl->length = sizeof(struct iso_directory_record) + 6;
idrl->length += idrl->length & 1;
idrl->ext_attr_length = 0;
set733((void *) idrl->extent, directory_iso[!level ? 0 : aux_parent].llba);
set733((void *) idrl->size, directory_iso[!level ? 0 : aux_parent].ldir * 2048);
setdaterec(idrl->date, dd, mm, aa, ho, mi, se);
idrl->flags = 0x2;
idrl->file_unit_size = 0x0;
idrl->interleave = 0x0;
set723((void *) idrl->volume_sequence_number, 1);
idrl->name_len = 1;
idrl->name = 1;
idrl = (void *) ((char *) idrl) + idrl->length;
idrw->length = sizeof(struct iso_directory_record) + 6;
idrw->length += idrw->length & 1;
idrw->ext_attr_length = 0;
set733((void *) idrw->extent, directory_iso[!level ? 0 : aux_parent].wlba);
set733((void *) idrw->size, directory_iso[!level ? 0 : aux_parent].wdir * 2048);
setdaterec(idrw->date, dd, mm, aa, ho, mi, se);
idrw->flags = 0x2;
idrw->file_unit_size = 0x0;
idrw->interleave = 0x0;
set723((void *) idrw->volume_sequence_number, 1);
idrw->name_len = 1;
idrw->name = 1;
idrw = (void *) ((char *) idrw) + idrw->length;
// files
dir = opendir (path1);
if(dir) {
while(1) {
struct dirent *entry = readdir (dir);
if(!entry) break;
if(entry->d_name=='.' && (entry->d_name[1]=='.' || entry->d_name[1]== 0)) continue;
int len = strlen(path1);
#ifdef NOPS3_UPDATE
if(!strcmp(&path1[len - 10], "PS3_UPDATE")) continue;
#endif
strcat(path1,"/");
strcat(path1, entry->d_name);
if(stat(path1, &s)<0) {closedir(dir); return -669;}
path1[len] = 0;
if(S_ISDIR(s.st_mode)) continue;
//printf("\r2 %s \r", &cycle_str[print_cycle]); print_cycle++; print_cycle&= 3;
int lname = strlen(entry->d_name);
if(lname >=6 && !strcmp(&entry->d_name[lname -6], ".66600")) { // build size of .666xx files
u64 size = s.st_size;
lname -= 6;
int n;
memcpy(temp_string, entry->d_name, lname);
temp_string[lname] = 0;
if(lname > 222) {closedir(dir); return -555;}
UTF8_to_UTF16((u8 *) temp_string, wstring);
for(len_string = 0; len_string < 512; len_string++) if(wstring[len_string] == 0) break;
if(len_string > 222) {closedir(dir); return -555;}
path1[len] = 0;
for(n = 1; n < 100; n++) {
int len2 = strlen(path1);
strcat(path1,"/");
int l = strlen(path1);
memcpy(path1 + l, entry->d_name, lname);
sprintf(&path1[l + lname], ".666%2.2u", n);
if(stat(path1, &s)<0) {s.st_size = size; path1[len2] = 0; break;}
path1[len2] = 0;
size += s.st_size;
}
path1[len] = 0;
} else
if(lname >=6 && !strncmp(&entry->d_name[lname -6], ".666", 4)) continue; // ignore .666xx files
else {
if(strlen(entry->d_name) > 222) {closedir(dir); return -555;}
UTF8_to_UTF16((u8 *) entry->d_name, wstring);
for(len_string = 0; len_string < 512; len_string++) if(wstring[len_string] == 0) break;
if(len_string > 222) {closedir(dir); return -555;}
}
#ifdef ALIGNED32SECTORS
if(first_file) flba= (flba + 31) & ~31;
#endif
first_file = 0;
int parts = s.st_size ? (u32) ((((u64) s.st_size) + 0xFFFFF7FFULL)/0xFFFFF800ULL) : 1;
int n;
tm = gmtime(&s.st_mtime);
time_t t = mktime(tm);
tm = localtime(&t);
dd = tm->tm_mday;
mm = tm->tm_mon + 1;
aa = tm->tm_year + 1900;
ho = tm->tm_hour;
mi = tm->tm_min;
se = tm->tm_sec;
for(n = 0; n < parts; n++) {
u32 fsize;
if(parts > 1 && (n + 1) != parts) {fsize = 0xFFFFF800; s.st_size-= fsize;}
else fsize = s.st_size;
int add;
add = sizeof(struct iso_directory_record) - 1 + (lname + 8);
add+= (add & 1);
// align entry data with sector
int cldir = (((int) idrl) - ((int) idrl0)) & 2047;
cldir += add;
if(cldir > 2048) {
//printf("gapl1 lba 0x%X %s/%s %i\n", directory_iso[level].llba, path1, entry->d_name, cldir);
//getchar();
count_sec1++;
if(count_sec1 > max_sec1) {
closedir (dir);
printf("Error!: too much entries in directory:\n%s\n", path1);
return -444;
}
idrl = (void *) ((char *) idrl) + (add - (cldir - 2048));
memset((void *) idrl, 0, 2048);
}
idrl->length = add;
idrl->length += idrl->length & 1;
idrl->ext_attr_length = 0;
set733((void *) idrl->extent, flba);
set733((void *) idrl->size, fsize);
//printf("a %i/%i/%i %i:%i:%i %s LBA: %X\n", dd, mm, aa, ho, mi, se, entry->d_name, flba);
setdaterec((void *) idrl->date, dd, mm, aa, ho, mi, se);
idrl->flags = ((n + 1) != parts) ? 0x80 : 0x0; // fichero
idrl->file_unit_size = 0x0;
idrl->interleave = 0x0;
set723((void *) idrl->volume_sequence_number, 1);
idrl->name_len = lname + 2;
memcapscpy(idrl->name, entry->d_name, lname);
idrl->name[lname + 0] = ';';
idrl->name[lname + 1] = '1';
idrl = (void *) ((char *) idrl) + idrl->length;
//
add = sizeof(struct iso_directory_record) - 1 + len_string * 2 + 4 + 6;
add+= (add & 1);
// align entry data with sector
int cwdir = (((int) idrw) - ((int) idrw0)) & 2047;
cwdir += add;
if(cwdir > 2048) {
//printf("gapw1 lba 0x%X %s/%s %i\n", directory_iso[level].wlba, path1, entry->d_name, cwdir);
//getchar();
count_sec2++;
if(count_sec2 > max_sec2) {
closedir (dir);
printf("Error!: too much entries in directory:\n%s\n", path1);
return -444;
}
idrw = (void *) ((char *) idrw) + (add - (cwdir - 2048));
memset((void *) idrw, 0, 2048);
}
idrw->length = add;
idrw->length += idrw->length & 1;
idrw->ext_attr_length = 0;
set733((void *) idrw->extent, flba);
set733((void *) idrw->size, fsize);
setdaterec((void *) idrw->date, dd, mm, aa, ho, mi, se);
idrw->flags = ((n + 1) != parts) ? 0x80 : 0x0; // fichero
idrw->file_unit_size = 0x0;
idrw->interleave = 0x0;
set723((void *) idrw->volume_sequence_number, 1);
idrw->name_len = len_string * 2 + 4;
memcpy(idrw->name, wstring, len_string * 2);
idrw->name[len_string * 2 + 0] = 0;
idrw->name[len_string * 2 + 1] = ';';
idrw->name[len_string * 2 + 2] = 0;
idrw->name[len_string * 2 + 3] = '1';
idrw = (void *) ((char *) idrw) + idrw->length;
flba+= ((fsize + 2047) & ~2047) / 2048;
}
}
closedir (dir);
}
// printf("\r \r");
// folders
for(n = 1; n < cur_isop; n++)
if(directory_iso[n].parent == level + 1) {
int len = strlen(path1);
strcat(path1,"/");
strcat(path1, directory_iso[n].name);
if(stat(path1, &s)<0) {return -669;}
path1[len] = 0;
tm = localtime(&s.st_mtime);
dd = tm->tm_mday;
mm = tm->tm_mon + 1;
aa = tm->tm_year + 1900;
ho = tm->tm_hour;
mi = tm->tm_min;
se = tm->tm_sec;
//printf("dir %i/%i/%i %i:%i:%i %s\n", dd, mm, aa, ho, mi, se, directory_iso[n].name);
int add;
add = sizeof(struct iso_directory_record) - 1 + (strlen(directory_iso[n].name) + 6);
add+= (add & 1);
// align entry data with sector
int cldir = (((int)idrl) - ((int) idrl0)) & 2047;
cldir += add;
if(cldir > 2048) {
//printf("gapl0 lba 0x%X %s/%s %i\n", directory_iso[level].llba, path1, directory_iso[n].name, cldir);
//getchar();
count_sec1++;
if(count_sec1 > max_sec1) {
closedir (dir);
printf("Error!: too much entries in directory:\n%s\n", path1);
return -444;
}
idrl = (void *) ((char *) idrl) + (add - (cldir - 2048));
memset((void *) idrl, 0, 2048);
}
idrl->length = add;
idrl->length += idrl->length & 1;
idrl->ext_attr_length = 0;
set733((void *) idrl->extent, directory_iso[n].llba);
set733((void *) idrl->size, directory_iso[n].ldir * 2048);
setdaterec((void *) idrl->date, dd, mm, aa, ho, mi, se);
idrl->flags = 0x2;
idrl->file_unit_size = 0x0;
idrl->interleave = 0x0;
set723((void *) idrl->volume_sequence_number, 1);
idrl->name_len = strlen(directory_iso[n].name);
memcapscpy(idrl->name, directory_iso[n].name, strlen(directory_iso[n].name));
idrl = (void *) ((char *) idrl) + idrl->length;
//
UTF8_to_UTF16((u8 *) directory_iso[n].name, wstring);
for(len_string = 0; len_string < 512; len_string++) if(wstring[len_string] == 0) break;
add = sizeof(struct iso_directory_record) - 1 + len_string * 2 + 6;
add+= (add & 1);
// align entry data with sector
int cwdir = (((int) idrw) - ((int) idrw0)) & 2047;
cwdir += add;
if(cwdir > 2048) {
//printf("gapw0 lba 0x%X %s/%s %i\n", directory_iso[level].wlba, path1, directory_iso[n].name, cwdir);
//getchar();
count_sec2++;
if(count_sec2 > max_sec2) {
closedir (dir);
printf("Error!: too much entries in directory:\n%s\n", path1);
return -444;
}
idrw = (void *) ((char *) idrw) + (add - (cwdir - 2048));
memset((void *) idrw, 0, 2048);
}
idrw->length = add;
idrw->length += idrw->length & 1;
idrw->ext_attr_length = 0;
set733((void *) idrw->extent, directory_iso[n].wlba);
set733((void *) idrw->size, directory_iso[n].wdir * 2048);
setdaterec((void *) idrw->date, dd, mm, aa, ho, mi, se);
idrw->flags = 0x2;
idrw->file_unit_size = 0x0;
idrw->interleave = 0x0;
set723((void *) idrw->volume_sequence_number, 1);
idrw->name_len = len_string * 2;
memcpy(idrw->name, wstring, len_string * 2);
idrw = (void *) ((char *) idrw) + idrw->length;
}
path1[len1] = 0;
// iteration
for(n = 1; n < cur_isop; n++)
if(directory_iso[n].parent == level + 1) {
int ret = fill_entries(path1, path2, n);
if(ret < 0) {path2[len2] = 0; return ret;}
}
path2[len2] = 0;
return 0;
}
#define SPLIT_LBA 0x1FFFE0
static int write_split(FILE *fp, u32 lba, u8 *mem, int sectors, int sel)
{
char filename[0x420];
if(!iso_split) {
if(fwrite((void *) mem, 1, (int) sectors * 2048, fp) != sectors * 2048) return -667;
return 0;
}
int cur = lba / SPLIT_LBA;
int cur2 = (lba + sectors) / SPLIT_LBA;
if(cur == cur2 && (iso_split - 1) == cur) {
if(fwrite((void *) mem, 1, (int) sectors * 2048, fp) != sectors * 2048) return -667;
return 0;
}
u32 lba2 = lba + sectors;
u32 pos = 0;
for(; lba < lba2; lba++) {
int cur = lba / SPLIT_LBA;
if(iso_split - 1 != cur) {
if(fp) fclose(fp); fp = NULL;
if(sel == 0) return 0;
if(iso_split == 1) {
sprintf(filename, "%s.0", output_name);
remove(filename); //unlink
rename(output_name, filename);
}
iso_split = cur + 1;
sprintf(filename, "%s.%i", output_name, iso_split - 1);
fp = fopen(filename, "wb");
if(!fp) return -1;
}
if(fwrite((void *) mem + pos, 1, 2048 , fp) != 2048) return -667;
pos += 2048;
}
return 0;
}
static int build_file_iso(FILE *fp, char *path1, char *path2, int level)
{
DIR *dir;
struct stat s;
int n;
int first_file = 1;
int len1 = strlen(path1);
int len2 = strlen(path2);
if(level!=0) {
strcat(path2, "/");
strcat(path2, directory_iso[level].name);
strcat(path1, path2);
} else path2 = 0;
if(level)
{if(verbose) printf("</%s>\n", directory_iso[level].name);}
else
{if(verbose) printf("</>\n");}
//printf("q %s LBA %X\n", path2, directory_iso[level].llba);
// files
dir = opendir (path1);
if(dir) {
while(1) {
struct dirent *entry=readdir (dir);
if(!entry) break;
if(entry->d_name=='.' && (entry->d_name[1]=='.' || entry->d_name[1]== 0)) continue;
int len = strlen(path1);
#ifdef NOPS3_UPDATE
if(!strcmp(&path1[len - 10], "PS3_UPDATE")) continue;
#endif
strcat(path1,"/");
strcat(path1, entry->d_name);
if(stat(path1, &s)<0) {path1[len] = 0;closedir(dir); return -669;}
if(S_ISDIR(s.st_mode)) {path1[len] = 0; continue;}
int is_file_split = 0;
int lname = strlen(entry->d_name);
if(lname >=6 && !strcmp(&entry->d_name[lname -6], ".66600")) { // build size of .666xx files
u64 size = s.st_size;
lname -= 6;
int n;
is_file_split = 1;
memcpy(temp_string, entry->d_name, lname);
temp_string[lname] = 0;
if(lname > 222) {path1[len] = 0;closedir(dir); return -555;}
path1[len] = 0;
for(n = 1; n < 100; n++) {
int len2 = strlen(path1);
strcat(path1,"/");
int l = strlen(path1);
memcpy(path1 + l, entry->d_name, lname);
sprintf(&path1[l + lname], ".666%2.2u", n);
if(stat(path1, &s)<0) {s.st_size = size; path1[len2] = 0; break;}
path1[len2] = 0;
size += s.st_size;
}
path1[len] = 0;
strcat(path1,"/");
strcat(path1, entry->d_name); // restore .66600 file
} else
if(lname >=6 && !strncmp(&entry->d_name[lname -6], ".666", 4)) {path1[len] = 0; continue;} // ignore .666xx files
else {
if(strlen(entry->d_name) > 222) {path1[len] = 0; closedir(dir); return -555;}
}
FILE * fp2 = fopen(path1, "rb");
path1[len] = 0;
if(!fp2) {closedir(dir); return -666;}
u32 flba0 = flba;
#ifdef ALIGNED32SECTORS
if(first_file) flba= (flba + 31) & ~31;
#endif
first_file = 0;
if(flba0 != flba) {
//printf("gap: %i\n", (flba - flba0));
int f = (flba - flba0);
int f2 = 0;
int z = 0;
memset(sectors, 0, ((f > 128) ? 128 : f ) * 2048);
while(f > 0) {
if(f > 128) f2 = 128; else f2 = f;
int ret = write_split(fp, flba + z, sectors, f2, 1);
if(ret < 0) {
fclose(fp2); closedir(dir); return ret;
}
f -= f2;
z += f2;
}
}
if(is_file_split) {
if(s.st_size < 1024ULL)
{if(verbose) printf(" -> %s LBA %u size %u Bytes\n", temp_string, flba, (u32) s.st_size);}
else if(s.st_size < 0x100000LL)
{if(verbose) printf(" -> %s LBA %u size %u KB\n", temp_string, flba, (u32) (s.st_size/1024));}
else
{if(verbose) printf(" -> %s LBA %u size %u MB\n", temp_string, flba, (u32) (s.st_size/0x100000LL));}
} else {
if(s.st_size < 1024ULL)
{if(verbose) printf(" -> %s LBA %u size %u Bytes\n", entry->d_name, flba, (u32) s.st_size);}
else if(s.st_size < 0x100000LL)
{if(verbose) printf(" -> %s LBA %u size %u KB\n", entry->d_name, flba, (u32) (s.st_size/1024));}
else
{if(verbose) printf(" -> %s LBA %u size %u MB\n", entry->d_name, flba, (u32) (s.st_size/0x100000LL));}
}
u32 count = 0, percent = (u32) (s.st_size / 0x40000ULL);
if(percent == 0) percent = 1;
clock_t t_one, t_two;
t_one = clock();
while(s.st_size > 0) {
u32 fsize;
u32 lsize;
t_two = clock();
if(((t_two - t_one) >= CLOCKS_PER_SEC/2)) {
t_one = t_two;
if(verbose) printf("\r*** Writing... %u %%", count * 100 / percent);
}
if(s.st_size > 0x40000) fsize = 0x40000;
else fsize = (u32) s.st_size;
count++;
if(fsize < 0x40000) memset(sectors, 0, 0x40000);
if(is_file_split) {
int read = fread((void *) sectors, 1, (int) fsize, fp2);
if(read < 0) {
fclose(fp2); closedir(dir); return -668;
} else if(read < fsize) {
fclose(fp2);
path1[len] = 0;
strcat(path1,"/");
int l = strlen(path1);
memcpy(path1 + l, entry->d_name, lname);
sprintf(&path1[l + lname], ".666%2.2u", is_file_split);
//printf("split: %s\n", path1);
is_file_split++;
fp2 = fopen(path1, "rb");
path1[len] = 0;
if(!fp2) {closedir(dir); return -666;}
if(fread((void *) (sectors + read), 1, (int) (fsize - read), fp2) != (fsize - read)) {
fclose(fp2); closedir(dir); return -668;
}
}
} else {
if(fread((void *) sectors, 1, (int) fsize, fp2) != fsize) {
fclose(fp2); closedir(dir); return -668;
}
}
lsize = (fsize + 2047) & ~2047;
int ret = write_split(fp, flba, sectors, lsize/2048, 1);
if(ret < 0) {
if(verbose) printf("\n");
fclose(fp2); closedir(dir); return ret;
}
flba += lsize/2048;
if(!verbose) printf("\rPercent done: %u%% \r", (u32) (((u64) flba) * 100ULL / ((u64) toc)));
//printf("flba %i\n", flba * 2048);
s.st_size-= fsize;
}
if(verbose) printf("\r \r");
fclose(fp2);
}
closedir (dir);
}
path1[len1] = 0;
// iteration
for(n = 1; n < cur_isop; n++)
if(directory_iso[n].parent == level + 1) {
int ret = build_file_iso(fp, path1, path2, n);
if(ret < 0) {path2[len2] = 0; return ret;}
}
path2[len2] = 0;
if(level == 0) {
if(toc != flba) {
//printf("End gap: %i\n", (toc - flba));
int f = (toc - flba);
int f2 = 0;
int z = 0;
memset(sectors, 0, ((f > 128) ? 128 : f ) * 2048);
while(f > 0) {
if(f > 128) f2 = 128; else f2 = f;
int ret = write_split(fp, flba + z, sectors, f2, 1);
if(ret < 0) {
return ret;
}
f-= f2;
z+= f2;
}
}
}
return 0;
}
static void fixpath(char *p)
{
u8 * pp = (u8 *) p;
if(*p == '"') {
p[strlen(p) -1] = 0;
memcpy(p, p + 1, strlen(p));
}
#ifdef __CYGWIN__
if(p!=0 && p[1] == ':') {
p[1] = p;
memmove(p + 9, p, strlen(p) + 1);
memcpy(p, "/cygdrive/", 10);
}
#endif
while(*pp) {
if(*pp == '"') {*pp = 0; break;}
else
if(*pp == '\\') *pp = '/';
else
if(*pp > 0 && *pp < 32) {*pp = 0; break;}
pp++;
}
}
static void fixtitle(char *p)
{
while(*p) {
if(*p & 128) *p = 0;
else
if(*p == ':' || *p == '?' || *p == '"' || *p == '<' || *p == '>' || *p == '|') *p = '_';
else
if(*p == '\\' || *p == '/') *p = '-';
else
if(((u8)*p) > 0 && ((u8)*p) < 32) {*p = 0; break;}
p++;
}
}
int main(int argc, const char* argv)
{
struct stat s;
char path1[0x420];
char path2[0x420];
char title_id[64];
clock_t t_start, t_finish;
int a = 0;
int arg_split = 'n';
// libc test
if(sizeof(s.st_size) != 8) {
printf("Error!: stat st_size must be a 64 bit number! (size %i)\n\nPress ENTER key to exit\n\n", sizeof(s.st_size));
get_input_char();
return -1;
}
if(argc > 1 && (!strcmp(argv[1], "/?") || !strcmp(argv[1], "--help"))) {
printf("\nMAKEPS3ISO (c) 2013, Estwald (Hermes)\n\n");
printf("%s", "Usage:\n\n"
" makeps3iso -> input datas from the program\n"
" makeps3iso <pathfiles> -> default ISO name\n"
" makeps3iso <pathfiles> <ISO file or folder> -> file or folder destination\n"
" makeps3iso -p0 <pathfiles> <ISO file or folder> -> file or folder destination (frontend)\n"
" makeps3iso -s <pathfiles> -> split files to 4GB\n"
" makeps3iso -s <pathfiles> <ISO file or folder> -> split files to 4GB\n"
" makeps3iso -p0 -s <pathfiles> <ISO file or folder> -> split files to 4GB (frontend)\n");
return 0;
}
if(argc > 1 && (!strcmp(argv[a + 1], "-s") || !strcmp(argv[a + 1], "-S"))) {a++; arg_split = 'y';}
if(argc > 1 && (!strcmp(argv[a + 1], "-p0") || !strcmp(argv[a + 1], "-P0"))) {a++; verbose = 0;}
if(argc > 1 && (!strcmp(argv[a + 1], "-s") || !strcmp(argv[a + 1], "-S"))) {a++; arg_split = 'y';}
if(verbose) printf("\nMAKEPS3ISO (c) 2013, Estwald (Hermes)\n\n");
if(argc == 1) {
printf("Enter Path Folder:\n");
if(fgets(path1, 0x420, stdin)==0) {
printf("Error Input Path Folder!\n\nPress ENTER key to exit\n"); get_input_char();return -1;
}
} else {if(argc >= (2 + a)) strcpy(path1, argv[1 + a]); else path1 = 0;}
fixpath(path1);
if(stat(path1, &s)<0 || !(S_ISDIR(s.st_mode))) {printf("Invalid Path Folder!\n\nPress ENTER key to exit\n"); get_input_char();return -1;}
strcpy(path2, path1);
strcat(path2, "/PS3_GAME/PARAM.SFO");
if(parse_param_sfo(path2, title_id, output_name)<0) {
printf("Error!: PARAM.SFO not found!\n");
printf("\nPress ENTER key to exit\n");
get_input_char();
return -1;
} else {
utf8_to_ansiname(output_name, path2, 32);
path2[32]= 0;
fixtitle(path2);
strcat(path2, "-");
strcat(path2, title_id);
}
if(argc == 1) {
printf("\nEnter ISO filename or path (press enter to default name):\n");
if(fgets(output_name, 0x420, stdin)==0) {
printf("Error Input ISO filename or path!\n\nPress ENTER key to exit\n"); get_input_char();return -1;
}
} else {
if(argc < 3 + a) output_name = 0; else strcpy(output_name, argv[2 + a]);
}
fixpath(output_name);
// create path for get free space from destination file
char dest_path[0x420];
strcpy(dest_path, output_name);
char *p = strrchr(dest_path , '/');
if(!p) {
strcpy(dest_path, argv); // try from argv
fixpath(dest_path);
p = strrchr(dest_path , '/');
if(!p) strcpy(dest_path, ".");
}
if(p) *p = 0;
u64 avail = get_disk_free_space(dest_path);
int nlen = strlen(output_name);
if(nlen < 1) {strcpy(output_name, path2);/*printf("ISO name too short!\n\nPress ENTER key to exit\n"); get_input_char();return -1;*/}
else {
if(stat(output_name, &s) == 0 && (S_ISDIR(s.st_mode))) {
strcat(output_name, "/"); strcat(output_name, path2);
}
}
nlen = strlen(output_name);
if(nlen < 4 || (strcmp(&output_name[nlen - 4], ".iso") && strcmp(&output_name[nlen - 4], ".ISO"))) {
strcat(output_name, ".iso");
}
if(argc < 2) printf("\nSplit in 4GB parts? (y/n):\n");
iso_split = (arg_split== 'y' || argc >= 2) ? arg_split : get_input_char();
if(iso_split == 'y' || iso_split == 'Y') iso_split = 1; else iso_split = 0;
if(iso_split) {if(verbose) printf("Using Split File Mode\n");}
if(verbose) printf("\n");
t_start = clock();
cur_isop = 0;
directory_iso = malloc((MAX_ISO_PATHS + 1) * sizeof(_directory_iso));
if(!directory_iso) {
printf("Out of Memory (directory_iso mem)\n");
printf("\nPress ENTER key to exit\n");
get_input_char();
return -1;
}
memset(directory_iso, 0, (MAX_ISO_PATHS + 1) * sizeof(_directory_iso));
lpath = sizeof(struct iso_path_table);
wpath = sizeof(struct iso_path_table);
llba0 = 0;
llba1 = 0;
wlba0 = 0;
wlba1 = 0;
dllba = 0; // dir entries
dwlba = 0; // dir entriesw
dlsz = 0; // dir entries size (sectors)
dwsz = 0; // dir entriesw size (sectors)
flba = 0; // first lba for files
u32 flba2 = 0;
int ret;
ret = calc_entries(path1, 1);
if(ret < 0 ) {
switch(ret) {
case -1:
printf("Out of Memory (calc_entries())\n");
goto err;
case -444:
printf("Too much folders (max %i) (calc_entries())\n", MAX_ISO_PATHS);
goto err;
case -555:
printf("Folder Name Too Long (calc_entries())\n");
goto err;
case -669:
printf("Error Input File Not Exists (calc_entries())\n");
case -666:
printf("Error Opening Input File (calc_entries())\n");
goto err;
case -667:
printf("Error Writing Output File (calc_entries())\n");
goto err;
case -668:
printf("Error Reading Input File (calc_entries())\n");
goto err;
case -777:
printf("Error Creating Split file (calc_entries())\n");
goto err;
}
}
/*
printf("llba0 0x%X - offset: 0x%X\n", llba0, llba0 * 2048);
printf("llba1 0x%X - offset: 0x%X\n", llba1, llba1 * 2048);
printf("wlba0 0x%X - offset: 0x%X\n", wlba0, wlba0 * 2048);
printf("wlba1 0x%X - offset: 0x%X\n", wlba1, wlba1 * 2048);
printf("\ndllba0 0x%X - offset: 0x%X, size 0x%X\n", dllba, dllba * 2048, dlsz * 2048);
printf("dwlba0 0x%X - offset: 0x%X, size 0x%X\n", dwlba, dwlba * 2048, dwsz * 2048);
printf("flba0 0x%X - offset: 0x%X\n", flba, flba * 2048);
*/
flba2 = flba;
sectors = malloc((flba > 128) ? flba * 2048 + 2048 : 128 * 2048 + 2048);
if(!sectors) {
printf("Out of Memory (sectors mem)\n");
printf("\nPress ENTER key to exit\n");
get_input_char();
goto err;
}
memset(sectors, 0, flba * 2048);
pos_lpath0 = llba0 * 2048;
pos_lpath1 = llba1 * 2048;
pos_wpath0 = wlba0 * 2048;
pos_wpath1 = wlba1 * 2048;
path2 = 0;
ret = fill_entries(path1, path2, 0);
if(ret < 0 ) {
switch(ret) {
case -1:
printf("Out of Memory (fill_entries())\n");
goto err;
case -555:
printf("File Name Too Long (fill_entries())\n");
goto err;
case -669:
printf("Error Input File Not Exists (fill_entries())\n");
case -666:
printf("Error Opening Input File (fill_entries())\n");
goto err;
case -667:
printf("Error Writing Output File (fill_entries())\n");
goto err;
case -668:
printf("Error Reading Input File (fill_entries())\n");
goto err;
case -777:
printf("Error Creating Split file (fill_entries())\n");
goto err;
case -444:
printf("Error in fill_entries()\n");
goto err;
}
}
#ifdef ALIGNED32SECTORS
flba= (flba + 31) & ~31;
#endif
toc = flba;
if((((u64)toc) * 2048ULL) > (avail - 0x100000ULL)) {
printf("Error!: Insufficient Disk Space in Destination\n");
goto err;
}
sectors[0x3] = 1; // one range
set732((void *) §ors[0x8], 0); // first unencrypted sector
set732((void *) §ors[0xC], toc - 1); // last unencrypted sector
strcpy((void *) §ors[0x800], "PlayStation3");
memset((void *) §ors[0x810], 32, 0x20);
memcpy((void *) §ors[0x810], title_id, 10);
get_rand(§ors[0x840], 0x1B0);
get_rand(§ors[0x9F0], 0x10);
struct iso_primary_descriptor *isd = (void *) §ors[0x8000];
struct iso_directory_record * idr;
isd->type=1;
memcpy(&isd->id,"CD001",5);
isd->version=1;
memset((void *) &isd->system_id,32, 32);
memcpy((void *) &isd->volume_id,"PS3VOLUME ",32);
set733((void *) &isd->volume_space_size, toc);
set723((void *) &isd->volume_set_size,1);
set723((void *) &isd->volume_sequence_number,1);
set723((void *) &isd->logical_block_size,2048);
set733((void *) &isd->path_table_size, lpath);
set731((void *) &isd->type_l_path_table, llba0); // lba
set731((void *) &isd->opt_type_l_path_table, 0); //lba
set732((void *) &isd->type_m_path_table, llba1); //lba
set732((void *) &isd->opt_type_m_path_table, 0);//lba
idr = (struct iso_directory_record *) &isd->root_directory_record;
idr->length=34;
idr->ext_attr_length=0;
set733(&idr->extent, directory_iso.llba); //lba
set733(&idr->size, directory_iso.ldir * 2048); // tamaño
//setdaterec(&idr->date,dd,mm,aa,ho,mi,se);
struct iso_directory_record * aisdr = (void *) §ors[directory_iso[0].llba * 2048];
memcpy(idr->date, aisdr->date, 7);
idr->flags=2;
idr->file_unit_size=0;
idr->interleave=0;
set723(&idr->volume_sequence_number,1); //lba
idr->name_len=1;
idr->name=0;
memset(&isd->volume_set_id,32,128);
memcpy(&isd->volume_set_id,"PS3VOLUME", 9);
memset(&isd->publisher_id,32,128);
memset(&isd->preparer_id,32,128);
memset(&isd->application_id,32,128);
memset(&isd->copyright_file_id,32,37);
memset(&isd->abstract_file_id,32,37);
memset(&isd->bibliographic_file_id,32,37);
unsigned dd1,mm1,aa1,ho1,mi1,se1;
time_t t;
struct tm *tm;
time(&t);
tm = localtime(&t);
dd = tm->tm_mday;
mm = tm->tm_mon + 1;
aa = tm->tm_year + 1900;
ho = tm->tm_hour;
mi = tm->tm_min;
se = tm->tm_sec;
dd1=dd;mm1=mm;aa1=aa;ho1=ho;mi1=mi;se1=se;
if(se1>59) {se1=0;mi1++;}
if(mi1>59) {mi1=0;ho1++;}
if(ho1>23) {ho1=0;dd1++;}
char fecha[64];
sprintf(fecha,"%4.4u%2.2u%2.2u%2.2u%2.2u%2.2u00",aa1,mm1,dd1,ho1,mi1,se1);
memcpy(&isd->creation_date, fecha,16);
memcpy(&isd->modification_date,"0000000000000000",16);
memcpy(&isd->expiration_date,"0000000000000000",16);
memcpy(&isd->effective_date,"0000000000000000",16);
isd->file_structure_version=1;
int len_string;
isd = (void *) §ors[0x8800];
isd->type = 2;
memcpy(&isd->id,"CD001",5);
isd->version=1;
UTF8_to_UTF16((u8 *) "PS3VOLUME", wstring);
for(len_string = 0; len_string < 512; len_string++) if(wstring[len_string] == 0) break;
memset(&isd->system_id,0, 32);
memset(&isd->volume_id,0, 32);
memcpy(&isd->volume_id, wstring, len_string * 2);
set733((void *) &isd->volume_space_size,toc);
set723((void *) &isd->volume_set_size,1);
isd->unused3 = 0x25;
isd->unused3[1] = 0x2f;
isd->unused3[2] = 0x40;
set723((void *) &isd->volume_sequence_number,1);
set723((void *) &isd->logical_block_size,2048);
set733((void *) &isd->path_table_size, wpath);
set731((void *) &isd->type_l_path_table, wlba0); // lba
set731((void *) &isd->opt_type_l_path_table, 0); //lba
set732((void *) &isd->type_m_path_table, wlba1); //lba
set732((void *) &isd->opt_type_m_path_table, 0);//lba
idr = (struct iso_directory_record *) &isd->root_directory_record;
idr->length=34;
idr->ext_attr_length=0;
set733(&idr->extent, directory_iso.wlba); //lba
set733(&idr->size, directory_iso.wdir * 2048); // tamaño
//setdaterec(&idr->date,dd,mm,aa,ho,mi,se);
aisdr = (void *) §ors[directory_iso[0].wlba * 2048];
memcpy(idr->date, aisdr->date, 7);
idr->flags=2;
idr->file_unit_size=0;
idr->interleave=0;
set723(&idr->volume_sequence_number,1); //lba
idr->name_len=1;
idr->name=0;
memset(&isd->volume_set_id,0,128);
memcpy(&isd->volume_set_id, wstring, len_string * 2);
memset(&isd->publisher_id,0,128);
memset(&isd->preparer_id,0,128);
memset(&isd->application_id,0,128);
memset(&isd->copyright_file_id,0,37);
memset(&isd->abstract_file_id,0,37);
memset(&isd->bibliographic_file_id,0,37);
memcpy(&isd->creation_date, fecha,16);
memcpy(&isd->modification_date,"0000000000000000",16);
memcpy(&isd->expiration_date,"0000000000000000",16);
memcpy(&isd->effective_date,"0000000000000000",16);
isd->file_structure_version=1;
isd = (void *) §ors[0x9000];
isd->type = 255;
memcpy(&isd->id,"CD001",5);
FILE *fp2 = fopen(output_name, "wb");
if(fp2) {
fwrite((void *) sectors, 1, (int) flba2 * 2048, fp2);
flba = flba2;
if(!verbose) printf("\rPercent done: %u%% \r", 0);
int ret = build_file_iso(fp2, path1, path2, 0);
if(ret!= -777) {
if(fp2) fclose(fp2); fp2 = NULL;
}
if(ret < 0 ) {
if(!verbose) printf("\n");
switch(ret) {
case -1:
printf("Out of Memory (build_file_iso())\n");
goto err;
case -555:
printf("File Name Too Long (build_file_iso())\n");
goto err;
case -669:
printf("Error Input File Not Exists (build_file_iso())\n");
case -666:
printf("Error Opening Input File (build_file_iso())\n");
goto err;
case -667:
printf("Error Writing Output File (build_file_iso())\n");
goto err;
case -668:
printf("Error Reading Input File (build_file_iso())\n");
goto err;
case -777:
printf("Error Creating Split file (build_file_iso())\n");
goto err;
}
} else if(!verbose) printf("\rPercent done: %u%% \n", 100);
} else {
printf("Error Creating ISO file %s\n", output_name);
goto err;
}
int n;
for(n = 0; n < cur_isop; n++)
if(directory_iso[n].name) {free(directory_iso[n].name); directory_iso[n].name = NULL;}
free(directory_iso);
free(sectors);
t_finish = clock();
if(verbose) printf("Finish!\n\nISO TOC: %i\n\n", toc);
if(verbose) printf("Total Time (HH:MM:SS): %2.2u:%2.2u:%2.2u.%u\n\n", (u32) ((t_finish - t_start)/(CLOCKS_PER_SEC * 3600)),
(u32) (((t_finish - t_start)/(CLOCKS_PER_SEC * 60)) % 60), (u32) (((t_finish - t_start)/(CLOCKS_PER_SEC)) % 60),
(u32) (((t_finish - t_start)/(CLOCKS_PER_SEC/100)) % 100));
if(argc < 2) {
printf("\nPress ENTER key to exit\n");
get_input_char();
}
return 0;
err:
if(directory_iso) {
int n;
for(n = 0; n < cur_isop; n++)
if(directory_iso[n].name) {free(directory_iso[n].name); directory_iso[n].name = NULL;}
free(directory_iso);
}
if(sectors) free(sectors);
printf("\nPress ENTER key to exit\n");
get_input_char();
return -1;
}
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 464828
Url: https://administrator.de/contentid/464828
Ausgedruckt am: 22.11.2024 um 17:11 Uhr
4 Kommentare
Neuester Kommentar
Zitat von @Rotnasenkater:
Vielleicht hat es mit der Zeile 30 zu tun ("#define NOPS3_UPDATE 1") und es würde schon reichen, wenn man aus der 1 eine 0 (Null) machen würde und dann kompilieren
Vielleicht hat es mit der Zeile 30 zu tun ("#define NOPS3_UPDATE 1") und es würde schon reichen, wenn man aus der 1 eine 0 (Null) machen würde und dann kompilieren
Nein. Wenn dann die gesamte Zeile auskommentiern, den im Code wird mit #ifdef geprüft ob das Macro definiert ist. Versuch macht klug.
Steffen