int INILoadString(char *file, char *section, char *keyword, char *buffer) { char inname[INIMAXLEN + 1]; int filepos; ACTUALHANDLE infile; int retval; if (file == NULL) return (-1); if (section == NULL) return (-1); if (keyword == NULL) return (-1); if (buffer == NULL) return (-1); #ifdef VERBOSE_FUNCTION_INI PrintLog("CDVDiso ini: LoadString(%s, %s, %s)", file, section, keyword); #endif /* VERBOSE_FUNCTION_INI */ filepos = INIRemoveExt(file, inname); INIAddInExt(inname, filepos); filepos = 0; infile = ActualFileOpenForRead(inname); if (infile == ACTUALHANDLENULL) return (-1); retval = INIFindSection(infile, section); if (retval < 0) { ActualFileClose(infile); infile = ACTUALHANDLENULL; return (-1); } // ENDIF- Didn't find it? Abort. retval = INIFindKeyword(infile, keyword, buffer); if (retval < 0) { ActualFileClose(infile); infile = ACTUALHANDLENULL; return (-1); } // ENDIF- Didn't find it? Abort. ActualFileClose(infile); infile = ACTUALHANDLENULL; return (0); } // END INILoadString()
extern int IsoLoadTOC(struct IsoFile *isofile) { char tocext[] = ".toc\0"; char tocheader[5]; ACTUALHANDLE tochandle; char tocname[256]; int i; int j; int retval; unsigned char cdvdtype; struct tocTN toctn; struct tocTD toctd; if (isofile == NULL) return(-1); i = 0; while ((i < 256) && (isofile->name[i] != 0)) { tocname[i] = isofile->name[i]; i++; } // ENDWHILE- Copying the data name to the toc name j = 0; while ((i < 256) && (tocext[j] != 0)) { tocname[i] = tocext[j]; i++; j++; } // ENDWHILE- Append ".toc" to end of name tocname[i] = 0; // And 0-terminate tochandle = ActualFileOpenForRead(tocname); if (tochandle == ACTUALHANDLENULL) return(-1); retval = ActualFileRead(tochandle, 4, tocheader); if (retval < 4) { ActualFileClose(tochandle); tochandle = ACTUALHANDLENULL; return(-1); } // ENDIF- Trouble reading the 'toc' file? if ((tocheader[0] != 'T') || (tocheader[1] != 'O') || (tocheader[2] != 'C') || (tocheader[3] != '1')) { ActualFileClose(tochandle); tochandle = ACTUALHANDLENULL; return(-1); } // ENDIF- Not a 'toc' file after all? #ifdef VERBOSE_FUNCTION_TOC PrintLog("CDVDiso TOC: IsoLoadTOC(%s)", tocname); #endif /* VERBOSE_FUNCTION_TOC */ retval = ActualFileRead(tochandle, 1, (char *) & cdvdtype); if (retval < 1) { ActualFileClose(tochandle); tochandle = ACTUALHANDLENULL; return(-1); } // ENDIF- Trouble reading the 'toc' file? isofile->cdvdtype = cdvdtype; IsoInitTOC(isofile); if ((cdvdtype != CDVD_TYPE_PS2DVD) && (cdvdtype != CDVD_TYPE_DVDV)) { retval = ActualFileRead(tochandle, sizeof(struct tocTN), (char *) & toctn); if (retval < sizeof(struct tocTN)) { ActualFileClose(tochandle); tochandle = ACTUALHANDLENULL; return(-1); } // ENDIF- Trouble reading the 'toc' file? if ((toctn.strack > 99) || (toctn.etrack > 99)) { ActualFileClose(tochandle); tochandle = ACTUALHANDLENULL; return(-1); } // ENDIF- Track numbers out of range? #ifdef VERBOSE_FUNCTION_TOC PrintLog("CDVDiso TOC: Start Track %u End Track %u", toctn.strack, toctn.etrack); #endif /* VERBOSE_FUNCTION_TOC */ IsoAddTNToTOC(isofile, toctn); retval = ActualFileRead(tochandle, sizeof(struct tocTD), (char *) & toctd); if (retval < sizeof(struct tocTD)) { ActualFileClose(tochandle); tochandle = ACTUALHANDLENULL; return(-1); } // ENDIF- Trouble reading the 'toc' file? if (toctd.type != 0) { ActualFileClose(tochandle); tochandle = ACTUALHANDLENULL; return(-1); } // ENDIF- Track numbers out of range? #ifdef VERBOSE_FUNCTION_TOC PrintLog("CDVDiso TOC: Total Sectors: %lu", toctd.lsn); #endif /* VERBOSE_FUNCTION_TOC */ IsoAddTDToTOC(isofile, 0xAA, toctd); for (i = toctn.strack; i <= toctn.etrack; i++) { retval = ActualFileRead(tochandle, sizeof(struct tocTD), (char *) & toctd); if (retval < sizeof(struct tocTD)) { ActualFileClose(tochandle); tochandle = ACTUALHANDLENULL; return(-1); } // ENDIF- Trouble reading the 'toc' file? #ifdef VERBOSE_FUNCTION_TOC PrintLog("CDVDiso TOC: Track %u Type %u Sector Start: %lu", i, toctd.type, toctd.lsn); #endif /* VERBOSE_FUNCTION_TOC */ IsoAddTDToTOC(isofile, i, toctd); } // NEXT i- read in each track } // ENDIF- Not a DVD? (Then read in CD track data) ActualFileClose(tochandle); tochandle = ACTUALHANDLENULL; return(0); } // END IsoLoadTOC()
// External functions struct IsoFile *IsoFileOpenForRead(const char *filename) { struct IsoFile *newfile; int retval; int i; char tempblock[2448]; struct tocTN toctn; struct tocTD toctd; // union { // struct ECMA119PrimaryVolume vol; // char ch[sizeof(struct ECMA119PrimaryVolume)]; // } *volcheck; union { struct ECMA119PrimaryVolume *vol; char *ch; } volcheck; newfile = NULL; if (filename == NULL) return(NULL); #ifdef VERBOSE_FUNCTION_ISOFILE PrintLog("CDVD isofile: IsoFileOpenForRead(%s)", filename); #endif /* VERBOSE_FUNCTION_ISOFILE */ newfile = (struct IsoFile *) malloc(sizeof(struct IsoFile)); if (newfile == NULL) return(NULL); newfile->sectorpos = 0; newfile->openforread = 1; // Read-only ISO newfile->filebytepos = 0; newfile->filesectorpos = 0; newfile->blocksize = 0; // Flags as non-detected yet (Compress vs. Image) newfile->tabledata = NULL; newfile->namepos = 0; while ((newfile->namepos < 255) && (*(filename + newfile->namepos) != 0)) { newfile->name[newfile->namepos] = *(filename + newfile->namepos); newfile->namepos++; } // ENDWHILE- copying the file name in... newfile->name[newfile->namepos] = 0; // And 0-terminate. IsoNameStripExt(newfile); // Ex: -I00.Z[.bin] // File Compression name detection newfile->compress = IsoNameStripCompress(newfile); // Ex: -I00.bin[.Z] newfile->compresspos = newfile->namepos; // Test File name compression retval = -1; if (newfile->compress > 0) { retval = CompressOpenForRead(newfile); if (retval == -1) CompressClose(newfile); } // ENDIF- Have a compression type hint? Test it out if (retval == -1) { newfile->compress = 5; while ((newfile->compress > 0) && (retval == -1)) { retval = CompressOpenForRead(newfile); if (retval == -1) { CompressClose(newfile); newfile->compress--; } // ENDIF- Failed to open? Close it... and try the next one. } // ENDWHILE- Trying to find a compression scheme that will work... if (newfile->compress == 0) { newfile->handle = ActualFileOpenForRead(newfile->name); if (newfile->handle == ACTUALHANDLENULL) { free(newfile); newfile = NULL; return(NULL); } // ENDIF- Failed to open? Abort. newfile->filebytesize = ActualFileSize(newfile->handle); } // ENDIF- No compression? Open it uncompressed. } // ENDIF- Temp- failed to open? Abort... // Compressed data file with no table? Return prematurely... // Condition detection: compress > 0, tablehandle == ACTUALHANDLENULL if (retval == -2) { #ifdef VERBOSE_FUNCTION_ISOFILE PrintLog("CDVD isofile: Data file with no table!"); #endif /* VERBOSE_FUNCTION_ISOFILE */ return(newfile); } // ENDIF- newfile->imagetype = DetectImageType(newfile); if (newfile->compress == 0) { newfile->filesectorsize = newfile->filebytesize / newfile->blocksize; } // ENDIF- Now that blocksize is known, raw file sectors can be figured out IsoNameStripExt(newfile); // Ex: -I00[.bin].Z IsoNameStripMulti(newfile); // Ex: [-I00].bin.Z #ifdef VERBOSE_DISC_INFO PrintLog("CDVD isofile: Filename: %s", filename); if (newfile->multi > 0) PrintLog("CDVD isofile: Multiple <2GB files."); PrintLog("CDVD isofile: Compression Method: %s", compressdesc[newfile->compress]); PrintLog("CDVD isofile: Image Type: %s", newfile->imagename); PrintLog("CDVD isofile: Block Size: %lli", newfile->blocksize); PrintLog("CDVD isofile: Total Sectors (of first file): %lli", newfile->filesectorsize); #endif /* VERBOSE_DISC_INFO */ // Load a TOC from a .toc file (is there is one) retval = IsoLoadTOC(newfile); if (retval == 0) return(newfile); // Get the volume sector for disc type test retval = IsoFileSeek(newfile, 16); if (retval < 0) { newfile = IsoFileClose(newfile); return(NULL); } // ENDIF- Could not find the directory sector? Abort. retval = IsoFileRead(newfile, tempblock); if (retval < 0) { newfile = IsoFileClose(newfile); return(NULL); } // ENDIF- Could not read the directory sector? Abort. volcheck.ch = tempblock; volcheck.ch += newfile->blockoffset; if (ValidateECMA119PrimaryVolume(volcheck.vol) != 0) { #ifdef VERBOSE_DISC_INFO PrintLog("CDVD isofile: Not an ISO9660 disc! Music CD perhaps?"); #endif /* VERBOSE_DISC_INFO */ newfile->cdvdtype = CDVD_TYPE_CDDA; } else { // Is this a playstation image? i = 0; while ((*(playstationid + i) != 0) && (*(playstationid + i) == tempblock[newfile->blockoffset + 8 + i])) i++; if (*(playstationid + i) != 0) { #ifdef VERBOSE_DISC_INFO PrintLog("CDVD isofile: Not a Playstation Disc!"); #endif /* VERBOSE_DISC_INFO */ newfile->cdvdtype = CDVD_TYPE_DVDV; } else { newfile->cdvdtype = CDVD_TYPE_PS2DVD; } // ENDIF- Is this not a Playstation 1 image? // Sidenote: if the emulator is just playing Playstation 2 images, we could // just invalidate the image file right here. } // ENDIF- Not an ISO9660 disc? Assume Music CD. if (newfile->cdvdtype == CDVD_TYPE_PS2DVD) { // Is this a Playstation CD image? i = 0; while ((*(cdname + i) != 0) && (*(cdname + i) == tempblock[newfile->blockoffset + 1024 + i])) i++; if (*(cdname + i) == 0) { newfile->cdvdtype = CDVD_TYPE_PSCD; #ifdef VERBOSE_DISC_INFO PrintLog("CDVD isofile: Image is a Playstation 1 CD."); #endif /* VERBOSE_DISC_INFO */ } else { if (newfile->blocksize != 2048) { newfile->cdvdtype = CDVD_TYPE_PS2CD; #ifdef VERBOSE_DISC_INFO PrintLog("CDVD isofile: Image is a Playstation 2 CD."); #endif /* VERBOSE_DISC_INFO */ } else { #ifdef VERBOSE_DISC_INFO PrintLog("CDVD isofile: Image is a DVD."); #endif /* VERBOSE_DISC_INFO */ } // ENDIF- Is the blocksize not 2048? CD image then. } // ENDIF- Is this a PS1 CD image? } // ENDIF- Is this a Playstation image? volcheck.ch = NULL; if ((newfile->cdvdtype == CDVD_TYPE_DVDV) && (newfile->blocksize == 2352)) newfile->cdvdtype = CDVD_TYPE_CDDA; // Slap together a TOC based on the above guesswork. IsoInitTOC(newfile); if ((newfile->cdvdtype != CDVD_TYPE_PS2DVD) && (newfile->cdvdtype != CDVD_TYPE_DVDV)) { toctn.strack = 1; toctn.etrack = 1; IsoAddTNToTOC(newfile, toctn); toctd.type = 0; toctd.lsn = newfile->filesectorsize; IsoAddTDToTOC(newfile, 0xAA, toctd); toctd.type = 0; // ? if (newfile->cdvdtype == CDVD_TYPE_CDDA) { toctd.type = CDVD_AUDIO_TRACK; // Music track assumed } else { toctd.type = CDVD_MODE1_TRACK; // Data track assumed } // ENDIF- Is this track a music or data track? toctd.lsn = 0; IsoAddTDToTOC(newfile, 1, toctd); } // ENDIF- Is this a CD? Single track for all sectors return(newfile); } // END IsoFileOpenForRead()
int INIRemove(char *file, char *section, char *keyword) { char inname[INIMAXLEN + 1]; char outname[INIMAXLEN + 1]; int filepos; ACTUALHANDLE infile; ACTUALHANDLE outfile; char templine[INIMAXLEN + 1]; int i; int retval; if (file == NULL) return (-1); if (section == NULL) return (-1); #ifdef VERBOSE_FUNCTION_INI PrintLog("CDVDiso ini: Remove(%s, %s, %s)", file, section, keyword); #endif /* VERBOSE_FUNCTION_INI */ filepos = INIRemoveExt(file, inname); for (i = 0; i <= filepos; i++) outname[i] = inname[i]; INIAddInExt(inname, filepos); INIAddOutExt(outname, filepos); infile = ActualFileOpenForRead(inname); if (infile == ACTUALHANDLENULL) return (-1); retval = INIFindSection(infile, section); if (retval == -1) { ActualFileClose(infile); infile = ACTUALHANDLENULL; return (-1); } // ENDIF- Couldn't even find the section? Abort filepos = retval; if (keyword == NULL) { #ifdef VERBOSE_FUNCTION_INI PrintLog("CDVDiso ini: removing section"); #endif /* VERBOSE_FUNCTION_INI */ outfile = ActualFileOpenForWrite(outname); if (outfile == ACTUALHANDLENULL) { ActualFileClose(infile); infile = ACTUALHANDLENULL; return (-1); } // ENDIF- Couldn't open a temp file? Abort ActualFileSeek(infile, 0); retval = INICopy(infile, outfile, filepos); if (retval > 0) { ActualFileClose(infile); infile = ACTUALHANDLENULL; ActualFileClose(outfile); outfile = ACTUALHANDLENULL; ActualFileDelete(outname); return (-1); } // ENDIF- Trouble writing everything up to the section? Abort. templine[0] = 0; retval = 1; while ((retval > 0) && (templine[0] != '[')) retval = INIReadLine(infile, templine); // ENDWHILE- Read to the start of the next section... or EOF. if (templine[0] == '[') { i = 0; while ((i < INIMAXLEN) && (templine[i] != 0)) i++; retval = ActualFileWrite(outfile, i, templine); if (retval < i) { ActualFileClose(infile); infile = ACTUALHANDLENULL; ActualFileClose(outfile); outfile = ACTUALHANDLENULL; ActualFileDelete(outname); return (-1); } // ENDIF- Trouble writing it out? Abort. } // ENDIF- Are there other sections after this one? Save them then. } else { filepos = retval; ActualFileSeek(infile, filepos); filepos += INIReadLine(infile, templine); // Get section line's byte count retval = INIFindKeyword(infile, keyword, NULL); if (retval == -1) { ActualFileClose(infile); infile = ACTUALHANDLENULL; return (-1); } // ENDIF- Couldn't find the keyword? Abort filepos += retval; #ifdef VERBOSE_FUNCTION_INI PrintLog("CDVDiso ini: removing keyword"); #endif /* VERBOSE_FUNCTION_INI */ outfile = ActualFileOpenForWrite(outname); if (outfile == ACTUALHANDLENULL) { ActualFileClose(infile); infile = ACTUALHANDLENULL; return (-1); } // ENDIF- Couldn't open a temp file? Abort ActualFileSeek(infile, 0); retval = INICopy(infile, outfile, filepos); if (retval > 0) { ActualFileClose(infile); infile = ACTUALHANDLENULL; ActualFileClose(outfile); outfile = ACTUALHANDLENULL; ActualFileDelete(outname); return (-1); } // ENDIF- Trouble writing everything up to keyword? Abort. INIReadLine(infile, templine); // Read (and discard) the keyword line } // ENDIF- Wipe out the whole section? Or just a keyword? INICopy(infile, outfile, 0xFFFFFFF); // Write out rest of file ActualFileClose(infile); infile = ACTUALHANDLENULL; ActualFileClose(outfile); outfile = ACTUALHANDLENULL; ActualFileDelete(inname); ActualFileRename(outname, inname); return (0); } // END INIRemove()
int INISaveString(char *file, char *section, char *keyword, char *value) { char inname[INIMAXLEN + 1]; char outname[INIMAXLEN + 1]; int filepos; ACTUALHANDLE infile; ACTUALHANDLE outfile; int i; int retval; char templine[INIMAXLEN + 1]; if (file == NULL) return (-1); if (section == NULL) return (-1); if (keyword == NULL) return (-1); if (value == NULL) return (-1); #ifdef VERBOSE_FUNCTION_INI PrintLog("CDVDiso ini: SaveString(%s, %s, %s, %s)", file, section, keyword, value); #endif /* VERBOSE_FUNCTION_INI */ filepos = INIRemoveExt(file, inname); for (i = 0; i <= filepos; i++) outname[i] = inname[i]; INIAddInExt(inname, filepos); INIAddOutExt(outname, filepos); filepos = 0; infile = ActualFileOpenForRead(inname); if (infile == ACTUALHANDLENULL) { #ifdef VERBOSE_FUNCTION_INI PrintLog("CDVDiso ini: creating new file"); #endif /* VERBOSE_FUNCTION_INI */ outfile = ActualFileOpenForWrite(inname); if (outfile == ACTUALHANDLENULL) return (-1); // Just a bad name? Abort. sprintf(templine, "[%s]\r\n", section); i = 0; while ((i < INIMAXLEN) && (templine[i] != 0)) i++; retval = ActualFileWrite(outfile, i, templine); if (retval < i) { ActualFileClose(outfile); outfile = ACTUALHANDLENULL; ActualFileDelete(inname); return (-1); } // ENDIF- Trouble writing it out? Abort. sprintf(templine, "%s=%s\r\n", keyword, value); i = 0; while ((i < INIMAXLEN) && (templine[i] != 0)) i++; retval = ActualFileWrite(outfile, i, templine); ActualFileClose(outfile); outfile = ACTUALHANDLENULL; if (retval < i) { ActualFileDelete(inname); return (-1); } // ENDIF- Trouble writing it out? Abort. return (0); } // ENDIF- No input file? Create a brand new .ini file then. retval = INIFindSection(infile, section); if (retval < 0) { #ifdef VERBOSE_FUNCTION_INI PrintLog("CDVDiso ini: creating new section"); #endif /* VERBOSE_FUNCTION_INI */ outfile = ActualFileOpenForWrite(outname); if (outfile == ACTUALHANDLENULL) { ActualFileClose(infile); infile = ACTUALHANDLENULL; return (-1); } // ENDIF- Couldn't open a temp file? Abort ActualFileSeek(infile, 0); // Move ini to beginning of file... INICopy(infile, outfile, 0x0FFFFFFF); // Copy the whole file out... sprintf(templine, "\r\n[%s]\r\n", section); i = 0; while ((i < INIMAXLEN) && (templine[i] != 0)) i++; retval = ActualFileWrite(outfile, i, templine); if (retval < i) { ActualFileClose(infile); infile = ACTUALHANDLENULL; ActualFileClose(outfile); outfile = ACTUALHANDLENULL; ActualFileDelete(outname); return (-1); } // ENDIF- Trouble writing it out? Abort. sprintf(templine, "%s=%s\r\n", keyword, value); i = 0; while ((i < INIMAXLEN) && (templine[i] != 0)) i++; retval = ActualFileWrite(outfile, i, templine); ActualFileClose(infile); infile = ACTUALHANDLENULL; ActualFileClose(outfile); outfile = ACTUALHANDLENULL; if (retval < i) { ActualFileDelete(outname); return (-1); } // ENDIF- Trouble writing it out? Abort. ActualFileDelete(inname); ActualFileRename(outname, inname); return (0); } // ENDIF- Couldn't find the section? Make a new one! filepos = retval; ActualFileSeek(infile, filepos); filepos += INIReadLine(infile, templine); // Get section line's byte count retval = INIFindKeyword(infile, keyword, NULL); if (retval < 0) { #ifdef VERBOSE_FUNCTION_INI PrintLog("CDVDiso ini: creating new keyword"); #endif /* VERBOSE_FUNCTION_INI */ ActualFileSeek(infile, filepos); retval = INIReadLine(infile, templine); i = 0; while ((i < INIMAXLEN) && (templine[i] != 0) && (templine[i] != '=')) i++; while ((retval > 0) && (templine[i] == '=')) { filepos += retval; retval = INIReadLine(infile, templine); i = 0; while ((i < INIMAXLEN) && (templine[i] != 0) && (templine[i] != '=')) i++; } // ENDWHILE- skimming to the bottom of the section outfile = ActualFileOpenForWrite(outname); if (outfile == ACTUALHANDLENULL) { ActualFileClose(infile); infile = ACTUALHANDLENULL; return (-1); } // ENDIF- Couldn't open a temp file? Abort ActualFileSeek(infile, 0); retval = INICopy(infile, outfile, filepos); if (retval > 0) { ActualFileClose(infile); infile = ACTUALHANDLENULL; ActualFileClose(outfile); outfile = ACTUALHANDLENULL; ActualFileDelete(outname); return (-1); } // ENDIF- Trouble writing everything up to keyword? Abort. sprintf(templine, "%s=%s\r\n", keyword, value); i = 0; while ((i < INIMAXLEN) && (templine[i] != 0)) i++; retval = ActualFileWrite(outfile, i, templine); if (retval < i) { ActualFileClose(infile); infile = ACTUALHANDLENULL; ActualFileClose(outfile); outfile = ACTUALHANDLENULL; ActualFileDelete(outname); return (-1); } // ENDIF- Trouble writing it out? Abort. } else { #ifdef VERBOSE_FUNCTION_INI PrintLog("CDVDiso ini: replacing keyword"); #endif /* VERBOSE_FUNCTION_INI */ filepos += retval; // Position just before old version of keyword outfile = ActualFileOpenForWrite(outname); if (outfile == ACTUALHANDLENULL) { ActualFileClose(infile); infile = ACTUALHANDLENULL; return (-1); } // ENDIF- Couldn't open a temp file? Abort ActualFileSeek(infile, 0); retval = INICopy(infile, outfile, filepos); if (retval > 0) { ActualFileClose(infile); infile = ACTUALHANDLENULL; ActualFileClose(outfile); outfile = ACTUALHANDLENULL; ActualFileDelete(outname); return (-1); } // ENDIF- Trouble writing everything up to keyword? Abort. INIReadLine(infile, templine); // Read past old keyword/value... // Replace with new value sprintf(templine, "%s=%s\r\n", keyword, value); i = 0; while ((i < INIMAXLEN) && (templine[i] != 0)) i++; retval = ActualFileWrite(outfile, i, templine); if (retval < i) { ActualFileClose(infile); infile = ACTUALHANDLENULL; ActualFileClose(outfile); outfile = ACTUALHANDLENULL; ActualFileDelete(outname); return (-1); } // ENDIF- Trouble writing it out? Abort. } // ENDIF- Need to add a new keyword? INICopy(infile, outfile, 0xFFFFFFF); // Write out rest of file ActualFileClose(infile); infile = ACTUALHANDLENULL; ActualFileClose(outfile); outfile = ACTUALHANDLENULL; ActualFileDelete(inname); ActualFileRename(outname, inname); return (0); } // END INISaveString()