gdtool: better command line, stdin lists, cleanup

Also, imgread const filenames and such
This commit is contained in:
Stefanos Kornilios Mitsis Poiitidis 2014-06-13 18:41:48 +03:00
parent 2bd1c4c976
commit d59197f843
10 changed files with 294 additions and 124 deletions

View File

@ -6,7 +6,7 @@
#include "deps/chdpsr/cdipsr.h"
Disc* cdi_parse(wchar* file)
Disc* cdi_parse(const wchar* file)
{
FILE* fsource=fopen(file,"rb");

View File

@ -17,7 +17,7 @@ struct CHDDisc : Disc
hunk_mem=0;
}
bool TryOpen(wchar* file);
bool TryOpen(const wchar* file);
~CHDDisc()
{
@ -64,7 +64,7 @@ struct CHDTrack : TrackFile
}
};
bool CHDDisc::TryOpen(wchar* file)
bool CHDDisc::TryOpen(const wchar* file)
{
chd_error err=chd_open(file,CHD_OPEN_READ,0,&chd);
@ -153,7 +153,7 @@ bool CHDDisc::TryOpen(wchar* file)
}
Disc* chd_parse(wchar* file)
Disc* chd_parse(const wchar* file)
{
CHDDisc* rv = new CHDDisc();

View File

@ -1,16 +1,16 @@
#include "common.h"
Disc* chd_parse(wchar* file);
Disc* gdi_parse(wchar* file);
Disc* cdi_parse(wchar* file);
Disc* chd_parse(const wchar* file);
Disc* gdi_parse(const wchar* file);
Disc* cdi_parse(const wchar* file);
#if HOST_OS==OS_WINDOWS
Disc* ioctl_parse(wchar* file);
Disc* ioctl_parse(const wchar* file);
#endif
u32 NullDriveDiscType;
Disc* disc;
Disc*(*drivers[])(wchar* path)=
Disc*(*drivers[])(const wchar* path)=
{
chd_parse,
gdi_parse,
@ -129,7 +129,7 @@ bool ConvertSector(u8* in_buff , u8* out_buff , int from , int to,int sector)
return true;
}
Disc* OpenDisc(wchar* fn)
Disc* OpenDisc(const wchar* fn)
{
Disc* rv;

View File

@ -257,7 +257,7 @@ struct Disc
extern Disc* disc;
Disc* OpenDisc(wchar* fn);
Disc* OpenDisc(const wchar* fn);
struct RawTrackFile : TrackFile
{

View File

@ -1,7 +1,7 @@
#include "common.h"
#include <ctype.h>
Disc* load_gdi(char* file)
Disc* load_gdi(const char* file)
{
u32 iso_tc;
Disc* disc = new Disc();
@ -75,7 +75,7 @@ Disc* load_gdi(char* file)
}
Disc* gdi_parse(char* file)
Disc* gdi_parse(const char* file)
{
size_t len=strlen(file);
if (len>4)

View File

@ -363,7 +363,7 @@ void PhysicalTrack::Read(u32 FAD,u8* dst,SectorFormat* sector_type,u8* subcode,S
}
Disc* ioctl_parse(wchar* file)
Disc* ioctl_parse(const wchar* file)
{
if (strlen(file)==3 && GetDriveType(file)==DRIVE_CDROM)

View File

@ -1087,7 +1087,7 @@ void OSD_DRAW()
glUseProgram(gl.OSD_SHADER.program);
//reset rendering scale
/*
float dc_width=640;
float dc_height=480;
@ -1101,7 +1101,7 @@ void OSD_DRAW()
ShaderUniforms.scale_coefs[3]=-1;
glUniform4fv( gl.OSD_SHADER.scale, 1, ShaderUniforms.scale_coefs);
*/
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
@ -1136,6 +1136,8 @@ void OSD_DRAW()
glBindTexture(GL_TEXTURE_2D,osd_font);
glUseProgram(gl.OSD_SHADER.program);
/*
//-1 -> too much to left
ShaderUniforms.scale_coefs[0]=2.0f/(screen_width/dc2s_scale_h);
ShaderUniforms.scale_coefs[1]=-2/dc_height;
@ -1143,7 +1145,7 @@ void OSD_DRAW()
ShaderUniforms.scale_coefs[3]=-1;
glUniform4fv( gl.OSD_SHADER.scale, 1, ShaderUniforms.scale_coefs);
*/
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);

View File

@ -185,9 +185,9 @@ union voldesc {
};
char *iso_astring(char *, int len);
char *cdrom_time(struct cdromtime *, int);
void printdirent(struct directent *, struct fs *);
void printdirents(struct directent *, struct fs *);
double cdrom_time(struct cdromtime *, int);
void printdirent(FILE* w, struct directent *, struct fs *, bool&);
void printdirents(FILE* w, struct directent *, struct fs *);
void printdirentheader(char *p);
int searchdirent(struct directent *, struct directent *, struct directent *,
struct fs *);
@ -353,10 +353,11 @@ printdirentheader(char *path) {
}
/* Print all entries in the directory. */
void
printdirents(struct directent *dp, struct fs *fs) {
printdirents(FILE* w, struct directent *dp, struct fs *fs) {
struct directent *ldp;
long filesize = ISO_WD(FDV(dp, size, fs->type)),
lbn = 0, cnt;
bool first = true;
char *buffer = (char *) malloc(fs->lbs);
while (getblkdirent(dp, buffer, lbn, fs)) {
long entlen, namelen;
@ -367,7 +368,7 @@ printdirents(struct directent *dp, struct fs *fs) {
namelen = ISO_BY(FDV(ldp, name_len, fs->type));
/* have we a record to match? */
while (cnt > sizeof (union fsdir) && entlen && namelen) {
printdirent(ldp, fs);
printdirent(w, ldp, fs, first);
/* next entry? */
cnt -= entlen;
ldp = (struct directent *) (((char *) ldp) + entlen);
@ -380,61 +381,70 @@ printdirents(struct directent *dp, struct fs *fs) {
free(buffer);
}
char __212[32];
/* print CDROM file modes */
void prmodes(int f) {
char* prmodes(int f) {
memset(__212, 0, sizeof(__212));
char* p = __212;
int i;
for(i=0; i < 8; i++) {
if(CD_FLAGBITS[i] == ' ')
continue;
if(f & (1<<i))
putchar(CD_FLAGBITS[i]);
else
putchar('-');
*p++=(CD_FLAGBITS[i]);
/*else
*p++=('-');*/
}
putchar(' ');
return __212;
}
/* Print a directent on output, formatted. */
#define HN(name, val, lst) fprintf(w, "%s\"%s\":%0.f", !lst?", " : "", name, (double)(val))
#define HS(name, val, lst) fprintf(w, "%s\"%s\":\"%s\"", !lst?", " : " ", name, val)
void
printdirent(struct directent *dp, struct fs *fs) {
printdirent(FILE* w, struct directent *dp, struct fs *fs, bool& first) {
unsigned extattlen;
unsigned fbname, name_len, entlen, enttaken;
/* mode flags */
prmodes(ISO_BY(FDV(dp, flags, fs->type)));
/* Note: this feature of HSF is not used because of lack of semantic def. */
#ifdef whybother
extattlen = ISO_BY(FDV(dp, ext_attr_length, fs->type));
if (extattlen)
printf(" E%3d", extattlen);
else
printf(" ");
#endif
/* size */
printf("\t%6d", ISO_WD(FDV(dp, size, fs->type)));
/* time */
printf(" %s",
cdrom_time((struct cdromtime *) FDV(dp, date, fs->type),fs->type));
/* compensate for reserved field used to word align directory entry */
entlen = ISO_BY(FDV(dp, length, fs->type));
entlen = ISO_BY(FDV(dp, length, fs->type));
name_len = ISO_BY(FDV(dp, name_len, fs->type));
enttaken = sizeof(union fsdir) + name_len;
if (enttaken & 1)
if (enttaken & 1)
enttaken++;
fbname = ISO_BY(FDV(dp, name(), fs->type));
entlen -= enttaken;
/* print size of CDROM Extensions field if present */
if (entlen)
printf(" %3d", entlen);
else
printf(" ");
/* finally print name. compensate for unprintable names */
if (name_len == 1 && fbname <= 1) {
printf("\t%s\n", (fbname == 0) ? "." : "..");
} else
printf("\t%s\n",
iso_astring(FDV(dp, name(), fs->type), name_len));
};
/* attempt to print a CDROM file's creation time */
char *
if (name_len == 1 && fbname <= 1)
return;
fprintf(w, "%s\n\t{", first ? "" : ",");
{
first = false;
HS("name", iso_astring(FDV(dp, name(), fs->type), name_len), true);
//modes
HS("modes", prmodes(ISO_BY(FDV(dp, flags, fs->type))), false);
// size
HN("size", ISO_WD(FDV(dp, size, fs->type)), false);
//lba
HN("startFAD", 150 + ISO_WD(FDV(dp, extent, fs->type)), false);
//time
HN("time", cdrom_time((struct cdromtime *) FDV(dp, date, fs->type),fs->type), false);
}
fprintf(w, " }");
}
//cdrom_time to js timestamp
double
cdrom_time(struct cdromtime *crt, int type) {
struct tm tm;
static char buf[32];
@ -457,10 +467,8 @@ cdrom_time(struct cdromtime *crt, int type) {
fmt = "%b %e %H:%M:%S %Z %Y";
} else
#endif
fmt = "%b %d %H:%M:%S %Y";
/* step 2. use ANSI C standard function to format time properly */
(void)strftime(buf, sizeof(buf), fmt, &tm);
return (buf);
return 1000.0*mktime(&tm);
}
static char __strbuf[200];
/* turn a blank padded character field into the null terminated strings
@ -533,14 +541,18 @@ mainy(int argc, char *argv[])
#endif
void find(directent* rootent, fs* fsd, char* pathname) {
void find(FILE* w, directent* rootent, fs* fsd, char* pathname) {
struct directent openfile;
if (lookup(rootent, &openfile, pathname, fsd)) {
/* if a directory, format and list it */
if (ISO_BY(FDV(&openfile, flags, fsd->type)) & CD_DIRECTORY) {
/*
printdirentheader(pathname);
printdirents(&openfile, fsd);
*/
fprintf(w, "[");
printdirents(w, &openfile, fsd);
fprintf(w, "\n]\n");
}
/* if a file, print it on standard output */
else
@ -551,7 +563,7 @@ void find(directent* rootent, fs* fsd, char* pathname) {
}
void parse_cdfs(cdimage* cdio, int offs) {
bool parse_cdfs(FILE* w, cdimage* cdio, const char* name, int offs, bool first) {
//im
fs fsd;
directent rootent;
@ -564,10 +576,14 @@ void parse_cdfs(cdimage* cdio, int offs) {
/* is there a filesystem we can understand here? */
if (iscdromfs(&rootent, &fsd, offs) ) {
/* print the contents of the root directory to give user a start */
printf("Root Directory Listing:\n");
printdirentheader("/");
printdirents(&rootent, &fsd);
//printdirentheader("/");
fprintf(w, "%s\"%s\": [", first? "\n":",\n", name);
printdirents(w, &rootent, &fsd);
fprintf(w, "\n]");
return true;
}
else
return false;
}

View File

@ -22,4 +22,4 @@ struct cdimage {
};
void parse_cdfs(cdimage* cdio, int offs);
bool parse_cdfs(FILE* w, cdimage* cdio, const char* prefix, int offs, bool first);

View File

@ -13,11 +13,11 @@ int msgboxf(const wchar* text,unsigned int type,...) {
void data_head() {
printf("---\nrv=\n");
printf("\n---\nrv=\n");
}
void data_tail() {
printf("===\n");
printf("\n===\n");
}
void data_string(const char* s) {
@ -26,42 +26,39 @@ void data_string(const char* s) {
data_tail();
}
void data_kvp(const char* k, const char* v) {
printf("\t\"%s\":\"%s\",\n", k, v);
void data_kvp(FILE* w, const char* k, const char* v, bool first) {
fprintf(w, "%s\t\"%s\":\"%s\"", first?"\n":",\n", k, v);
}
void parse_ip_meta(u8* ip_meta)
void parse_ip_meta(FILE* w, u8* ip_meta, bool first)
{
char temp[256];
const char* chm = (const char*)ip_meta;
#define HH(ofs, len, name) { strncpy(temp, chm+ofs, len); temp[len]=0; for (int i=len-1; i>=0; i--) if(temp[i]==' ') temp[i]=0; else break; data_kvp(#name, temp); }
data_head();
printf("{\n");
#define HH(ofs, len, name, first) { strncpy(temp, chm+ofs, len); temp[len]=0; for (int i=len-1; i>=0; i--) if(temp[i]==' ') temp[i]=0; else break; data_kvp(w, #name, temp, first); }
data_kvp("type", "\"meta-info\"");
HH(0x00, 16, hardwareId);
HH(0x10, 16, makerId);
fprintf(w, "%s\"meta-info\": {\n", first?"\n":",\n");
HH(0x80, 128, productName);
HH(0x4A, 6, productVersion);
HH(0x50, 16, releaseDate);
HH(0x40, 10, productId);
HH(0x20, 16, discId);
//data_kvp("type", "\"meta-info\"");
HH(0x00, 16, hardwareId, true);
HH(0x10, 16, makerId, false);
HH(0x80, 128, productName, false);
HH(0x4A, 6, productVersion, false);
HH(0x50, 16, releaseDate, false);
HH(0x40, 10, productId, false);
HH(0x20, 16, discId, false);
HH(0x30, 8, areas);
HH(0x38, 8, peripherals);
HH(0x30, 8, areas, false);
HH(0x38, 8, peripherals, false);
HH(0x60, 16, bootfile);
HH(0x70, 16, publisher);
HH(0x60, 16, bootfile, false);
HH(0x70, 16, publisher, false);
printf("}\n");
data_tail();
fprintf(w, "\n}");
}
@ -104,53 +101,208 @@ struct gdio : cdimage {
};
int main(int argc, char** argv)
{
for (int i=1; i<argc; i++) {
bool extract_info(FILE* w, bool first, Disc* d) {
Disc* d = OpenDisc(argv[i]);
int start_fad = -1;
if (d->type == GdRom) {
printf("This is a gdrom image\n");
start_fad = d->tracks[2].StartFAD;
}
else {
printf("This is a cdrom image\n");
if (!d) {
printf("Invalid image\n");
//data_string("-1");
continue;
if (d->sessions.size() < 2) {
printf("Not a selfboot cd\n");
return false;
}
start_fad = d->sessions[1].StartFAD;
}
int start_fad = -1;
u8 ip_meta[2048];
d->ReadSectors(start_fad,1,ip_meta,2048);
data_head();
fprintf(w, first?"\n{":",\n{");
{
data_kvp(w, "type",d->type == GdRom? "gdrom" : "cdrom", true);
parse_ip_meta(w, ip_meta, false);
if (d->type == GdRom) {
printf("This is a gdrom image\n");
start_fad = d->tracks[2].StartFAD;
verify(d->sessions.size() == 2);
}
else {
printf("This is a cdrom image\n");
if (d->sessions.size() < 2) {
printf("Not a selfboot cd\n");
//data_string("-2");
continue;
fprintf(w,",\n\"tracks\": [");
{
for (int i=0; i<d->tracks.size(); i++) {
fprintf(w, "%s{ \"startFAD\":%d, \"endFAD\":%d, \"ctrl\":%d, \"addr\":%d }", i ==0 ? "\n":",\n", d->tracks[i].StartFAD, d->tracks[i].EndFAD, d->tracks[i].CTRL, d->tracks[i].ADDR);
}
start_fad = d->sessions[1].StartFAD;
}
fprintf(w,"\n]");
u8 ip_meta[2048];
d->ReadSectors(start_fad,1,ip_meta,2048);
//d->Dump(argv[1]);
parse_ip_meta(ip_meta);
fprintf(w,",\n\"sessions\": [");
{
for (int i=0; i<d->sessions.size(); i++) {
fprintf(w, "%s{ \"firstTrack\":%d, \"startFAD\":%d }", i ==0 ? "\n":",\n", d->sessions[i].FirstTrack, d->sessions[i].StartFAD);
}
}
fprintf(w,"\n]");
//im
gdio* image = new gdio(d);
if (d->type == GdRom) {
parse_cdfs(image, d->tracks[0].StartFAD-image->offs);
parse_cdfs(w, image, "gdfs", d->tracks[0].StartFAD-image->offs, false);
}
parse_cdfs(image, start_fad-image->offs);
parse_cdfs(w, image, "cdfs", start_fad-image->offs, false);
delete image;
}
fprintf(w, "\n}");
data_tail();
}
void extract_data(FILE* w, bool first, Disc* d, int start_fad, int size) {
u8 temp[2048];
delete d;
int current = start_fad;
while(size>0) {
d->ReadSectors(current++, 1, temp, 2048);
int step = min(2048, size);
fwrite(temp, 1, step, w);
size-=step;
}
}
bool jsarray;
vector<string> cmds;
vector<string> files;
void exec_cmd(FILE* w, bool first, Disc* d) {
for (auto i=cmds.begin();i!=cmds.end();i++)
{
switch((*i)[0])
{
case 'g':
{
int start_fad = atoi((++i)->c_str());
int size = atoi((++i)->c_str());
extract_data(w, first, d, start_fad, size);
}
break;
case 'i':
extract_info(w, first, d);
break;
}
}
}
bool process_image(FILE* w, bool& first, const string& image) {
Disc* d = OpenDisc(image.c_str());
if (!d) {
printf("Invalid image, %s\n", image.c_str());
return false;
}
exec_cmd(w, first, d);
delete d;
first = false;
return true;
}
void parse_args(int argc, char** argv) {
int i = 1;
int rem = argc - i -1;
while(i < argc) {
char** p= argv + i;
if (p[0][0] == '-')
{
i++;
switch(p[0][1]) {
case 'G':
case 'g':
cmds.push_back("g");
cmds.push_back(p[1]);
cmds.push_back(p[2]);
i+=2;
break;
case 'I':
case 'i':
cmds.push_back("i");
break;
default:
printf("Unknown option %c\n",*p[1]);
}
}
else
files.push_back(p[0]);
i++;
}
if (cmds.size() == 0)
cmds.push_back("i");
}
#include <iostream>
#include <string>
int main(int argc, char** argv)
{
FILE* w=stderr;
bool first = true;
parse_args(argc, argv);
if (files.size() !=1 )
jsarray = true;
if (jsarray) {
fprintf(w, "\n[\n");
}
if (files.size() > 0) {
for(auto i = files.begin(); i!= files.end(); i++) {
process_image(w, first, *i);
}
}
else {
while (!cin.eof()) {
string f;
getline(cin, f);
process_image(w, first, f);
}
}
if (jsarray) {
fprintf(w, "\n]\n");
}
}