#define __USE_LARGEFILE64 #define __USE_FILE_OFFSET64 #define _FILE_OFFSET_BITS 64 #ifdef __GNUC__ # ifndef _LARGEFILE_SOURCE # define _LARGEFILE_SOURCE # endif # ifndef _LARGEFILE64_SOURCE # define _LARGEFILE64_SOURCE # endif #endif #ifdef _WIN32 #include #endif #include #include #include #include #include #include #include "zlib.h" #include "bzlib.h" #include "CDVDiso.h" #include "libiso.h" /* some structs from libcdvd by Hiryu & Sjeep (C) 2002 */ #if defined(_WIN32) #pragma pack(1) #endif struct rootDirTocHeader { u16 length; //+00 u32 tocLBA; //+02 u32 tocLBA_bigend; //+06 u32 tocSize; //+0A u32 tocSize_bigend; //+0E u8 dateStamp[8]; //+12 u8 reserved[6]; //+1A u8 reserved2; //+20 u8 reserved3; //+21 #if defined(_WIN32) }; //+22 #else } __attribute__((packed)); #endif struct asciiDate { char year[4]; char month[2]; char day[2]; char hours[2]; char minutes[2]; char seconds[2]; char hundreths[2]; char terminator[1]; #if defined(_WIN32) }; #else } __attribute__((packed)); #endif struct cdVolDesc { u8 filesystemType; // 0x01 = ISO9660, 0x02 = Joliet, 0xFF = NULL u8 volID[5]; // "CD001" u8 reserved2; u8 reserved3; u8 sysIdName[32]; u8 volName[32]; // The ISO9660 Volume Name u8 reserved5[8]; u32 volSize; // Volume Size u32 volSizeBig; // Volume Size Big-Endian u8 reserved6[32]; u32 unknown1; u32 unknown1_bigend; u16 volDescSize; //+80 u16 volDescSize_bigend; //+82 u32 unknown3; //+84 u32 unknown3_bigend; //+88 u32 priDirTableLBA; // LBA of Primary Dir Table //+8C u32 reserved7; //+90 u32 secDirTableLBA; // LBA of Secondary Dir Table //+94 u32 reserved8; //+98 struct rootDirTocHeader rootToc; u8 volSetName[128]; u8 publisherName[128]; u8 preparerName[128]; u8 applicationName[128]; u8 copyrightFileName[37]; u8 abstractFileName[37]; u8 bibliographyFileName[37]; struct asciiDate creationDate; struct asciiDate modificationDate; struct asciiDate effectiveDate; struct asciiDate expirationDate; u8 reserved10; u8 reserved11[1166]; #if defined(_WIN32) }; #else } __attribute__((packed)); #endif #ifdef _WIN32 void *_openfile(const char *filename, int flags) { HANDLE handle; // printf("_openfile %s, %d\n", filename, flags & O_RDONLY); if (flags & O_WRONLY) { int _flags = CREATE_NEW; if (flags & O_CREAT) _flags = CREATE_ALWAYS; handle = CreateFile(filename, GENERIC_WRITE, 0, NULL, _flags, 0, NULL); } else { handle = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); } return handle == INVALID_HANDLE_VALUE ? NULL : handle; } u64 _tellfile(void *handle) { u64 ofs; PLONG _ofs = (LONG*) & ofs; _ofs[1] = 0; _ofs[0] = SetFilePointer(handle, 0, &_ofs[1], FILE_CURRENT); return ofs; } int _seekfile(void *handle, u64 offset, int whence) { u64 ofs = (u64)offset; PLONG _ofs = (LONG*) & ofs; // printf("_seekfile %p, %d_%d\n", handle, _ofs[1], _ofs[0]); if (whence == SEEK_SET) { SetFilePointer(handle, _ofs[0], &_ofs[1], FILE_BEGIN); } else { SetFilePointer(handle, _ofs[0], &_ofs[1], FILE_END); } return 0; } int _readfile(void *handle, void *dst, int size) { DWORD ret; // printf("_readfile %p %d\n", handle, size); ReadFile(handle, dst, size, &ret, NULL); // printf("_readfile ret %d; %d\n", ret, GetLastError()); return ret; } int _writefile(void *handle, const void *src, int size) { DWORD ret; // printf("_writefile %p, %d\n", handle, size); // _seekfile(handle, _tellfile(handle)); WriteFile(handle, src, size, &ret, NULL); // printf("_writefile ret %d\n", ret); return ret; } void _closefile(void *handle) { CloseHandle(handle); } #else void *_openfile(const char *filename, int flags) { printf("_openfile %s %x\n", filename, flags); if (flags & O_WRONLY) return fopen64(filename, "wb"); else return fopen64(filename, "rb"); } #include u64 _tellfile(void *handle) { FILE* fp = (FILE*)handle; s64 cursize = ftell(fp); if (cursize == -1) { // try 64bit cursize = ftello64(fp); if (cursize < -1) { // zero top 32 bits cursize &= 0xffffffff; } } return cursize; } int _seekfile(void *handle, u64 offset, int whence) { int seekerr = fseeko64((FILE*)handle, offset, whence); if (seekerr == -1) printf("failed to seek\n"); return seekerr; } int _readfile(void *handle, void *dst, int size) { return fread(dst, 1, size, (FILE*)handle); } int _writefile(void *handle, const void *src, int size) { return fwrite(src, 1, size, (FILE*)handle); } void _closefile(void *handle) { fclose((FILE*)handle); } #endif int detect(isoFile *iso) { u8 buf[2448]; struct cdVolDesc *volDesc; if (isoReadBlock(iso, buf, 16) == -1) return -1; volDesc = (struct cdVolDesc *)(buf + 24); if (strncmp((char*)volDesc->volID, "CD001", 5)) return 0; if (volDesc->rootToc.tocSize == 2048) iso->type = ISOTYPE_CD; else iso->type = ISOTYPE_DVD; return 1; } int _isoReadZtable(isoFile *iso) { void *handle; char table[256]; int size; sprintf(table, "%s.table", iso->filename); handle = _openfile(table, O_RDONLY); if (handle == NULL) { printf("Error loading %s\n", table); return -1; } _seekfile(handle, 0, SEEK_END); size = _tellfile(handle); iso->Ztable = (char*)malloc(size); if (iso->Ztable == NULL) { return -1; } _seekfile(handle, 0, SEEK_SET); _readfile(handle, iso->Ztable, size); _closefile(handle); iso->blocks = size / 6; return 0; } int _isoReadZ2table(isoFile *iso) { void *handle; char table[256]; u32 *Ztable; int ofs, size, i; sprintf(table, "%s.table", iso->filename); handle = _openfile(table, O_RDONLY); if (handle == NULL) { printf("Error loading %s\n", table); return -1; } _seekfile(handle, 0, SEEK_END); size = _tellfile(handle); Ztable = (u32*)malloc(size); if (Ztable == NULL) { return -1; } _seekfile(handle, 0, SEEK_SET); _readfile(handle, Ztable, size); _closefile(handle); iso->Ztable = (char*)malloc(iso->blocks * 8); if (iso->Ztable == NULL) { return -1; } ofs = 16; for (i = 0; i < iso->blocks; i++) { *(u32*)&iso->Ztable[i*8+0] = ofs; *(u32*)&iso->Ztable[i*8+4] = Ztable[i]; ofs += Ztable[i]; } free(Ztable); return 0; } int _isoReadBZ2table(isoFile *iso) { void *handle; char table[256]; u32 *Ztable; int ofs; int size; int i; sprintf(table, "%s.table", iso->filename); handle = _openfile(table, O_RDONLY); if (handle == NULL) { printf("Error loading %s\n", table); return -1; } _seekfile(handle, 0, SEEK_END); size = _tellfile(handle); Ztable = (u32*)malloc(size); if (Ztable == NULL) return -1; _seekfile(handle, 0, SEEK_SET); _readfile(handle, Ztable, size); _closefile(handle); iso->Ztable = (char*)malloc(iso->blocks * 8); if (iso->Ztable == NULL) return -1; ofs = 16; for (i = 0; i < iso->blocks / 16; i++) { *(u32*)&iso->Ztable[i*8+0] = ofs; *(u32*)&iso->Ztable[i*8+4] = Ztable[i]; ofs += Ztable[i]; } if (iso->blocks & 0xf) { *(u32*)&iso->Ztable[i*8+0] = ofs; *(u32*)&iso->Ztable[i*8+4] = Ztable[i]; ofs += Ztable[i]; } free(Ztable); return 0; } int _isoReadDtable(isoFile *iso) { int ret; int i; _seekfile(iso->handle, 0, SEEK_END); iso->dtablesize = (_tellfile(iso->handle) - 16) / (iso->blocksize + 4); iso->dtable = (u32*)malloc(iso->dtablesize * 4); for (i = 0; i < iso->dtablesize; i++) { _seekfile(iso->handle, 16 + (iso->blocksize + 4)*i, SEEK_SET); ret = _readfile(iso->handle, &iso->dtable[i], 4); if (ret < 4) return -1; } return 0; } int isoDetect(isoFile *iso) // based on florin's CDVDbin detection code :) { char buf[32]; int len; iso->type = ISOTYPE_ILLEGAL; len = strlen(iso->filename); if (len >= 2) { if (!strncmp(iso->filename + (len - 2), ".Z", 2)) { iso->flags = ISOFLAGS_Z; iso->blocksize = 2352; _isoReadZtable(iso); return detect(iso) == 1 ? 0 : -1; } } _seekfile(iso->handle, 0, SEEK_SET); _readfile(iso->handle, buf, 4); if (strncmp(buf, "BDV2", 4) == 0) { iso->flags = ISOFLAGS_BLOCKDUMP; _readfile(iso->handle, &iso->blocksize, 4); _readfile(iso->handle, &iso->blocks, 4); _readfile(iso->handle, &iso->blockofs, 4); _isoReadDtable(iso); return detect(iso) == 1 ? 0 : -1; } else if (strncmp(buf, "Z V2", 4) == 0) { iso->flags = ISOFLAGS_Z2; _readfile(iso->handle, &iso->blocksize, 4); _readfile(iso->handle, &iso->blocks, 4); _readfile(iso->handle, &iso->blockofs, 4); _isoReadZ2table(iso); return detect(iso) == 1 ? 0 : -1; } else if (strncmp(buf, "BZV2", 4) == 0) { iso->flags = ISOFLAGS_BZ2; _readfile(iso->handle, &iso->blocksize, 4); _readfile(iso->handle, &iso->blocks, 4); _readfile(iso->handle, &iso->blockofs, 4); iso->buflsn = -1; iso->buffer = (u8*)malloc(iso->blocksize * 16); if (iso->buffer == NULL) return -1; _isoReadBZ2table(iso); return detect(iso) == 1 ? 0 : -1; } else { iso->blocks = 16; } // ISO 2048 iso->blocksize = 2048; iso->offset = 0; iso->blockofs = 24; if (detect(iso) == 1) return 0; // RAW 2336 iso->blocksize = 2336; iso->offset = 0; iso->blockofs = 16; if (detect(iso) == 1) return 0; // RAW 2352 iso->blocksize = 2352; iso->offset = 0; iso->blockofs = 0; if (detect(iso) == 1) return 0; // RAWQ 2448 iso->blocksize = 2448; iso->offset = 0; iso->blockofs = 0; if (detect(iso) == 1) return 0; // NERO ISO 2048 iso->blocksize = 2048; iso->offset = 150 * 2048; iso->blockofs = 24; if (detect(iso) == 1) return 0; // NERO RAW 2352 iso->blocksize = 2352; iso->offset = 150 * 2048; iso->blockofs = 0; if (detect(iso) == 1) return 0; // NERO RAWQ 2448 iso->blocksize = 2448; iso->offset = 150 * 2048; iso->blockofs = 0; if (detect(iso) == 1) return 0; // ISO 2048 iso->blocksize = 2048; iso->offset = -8; iso->blockofs = 24; if (detect(iso) == 1) return 0; // RAW 2352 iso->blocksize = 2352; iso->offset = -8; iso->blockofs = 0; if (detect(iso) == 1) return 0; // RAWQ 2448 iso->blocksize = 2448; iso->offset = -8; iso->blockofs = 0; if (detect(iso) == 1) return 0; iso->offset = 0; iso->blocksize = 2352; iso->type = ISOTYPE_AUDIO; return 0; return -1; } isoFile *isoOpen(const char *filename) { isoFile *iso; int i; iso = (isoFile*)malloc(sizeof(isoFile)); if (iso == NULL) return NULL; memset(iso, 0, sizeof(isoFile)); strcpy(iso->filename, filename); iso->handle = _openfile(iso->filename, O_RDONLY); if (iso->handle == NULL) { printf("Error loading %s\n", iso->filename); return NULL; } if (isoDetect(iso) == -1) return NULL; printf("detected blocksize = %d\n", iso->blocksize); if (strlen(iso->filename) > 3 && strncmp(iso->filename + (strlen(iso->filename) - 3), "I00", 3) == 0) { _closefile(iso->handle); iso->flags |= ISOFLAGS_MULTI; iso->blocks = 0; for (i = 0; i < 8; i++) { iso->filename[strlen(iso->filename) - 1] = '0' + i; iso->multih[i].handle = _openfile(iso->filename, O_RDONLY); if (iso->multih[i].handle == NULL) { break; } iso->multih[i].slsn = iso->blocks; _seekfile(iso->multih[i].handle, 0, SEEK_END); iso->blocks += (u32)((_tellfile(iso->multih[i].handle) - iso->offset) / (iso->blocksize)); iso->multih[i].elsn = iso->blocks - 1; } if (i == 0) { return NULL; } } if (iso->flags == 0) { _seekfile(iso->handle, 0, SEEK_END); iso->blocks = (u32)((_tellfile(iso->handle) - iso->offset) / (iso->blocksize)); } printf("isoOpen: %s ok\n", iso->filename); printf("offset = %d\n", iso->offset); printf("blockofs = %d\n", iso->blockofs); printf("blocksize = %d\n", iso->blocksize); printf("blocks = %d\n", iso->blocks); printf("type = %d\n", iso->type); return iso; } isoFile *isoCreate(const char *filename, int flags) { isoFile *iso; char Zfile[256]; iso = (isoFile*)malloc(sizeof(isoFile)); if (iso == NULL) return NULL; memset(iso, 0, sizeof(isoFile)); strcpy(iso->filename, filename); iso->flags = flags; iso->offset = 0; iso->blockofs = 24; iso->blocksize = CD_FRAMESIZE_RAW; iso->blocksize = 2048; if (iso->flags & (ISOFLAGS_Z | ISOFLAGS_Z2 | ISOFLAGS_BZ2)) { sprintf(Zfile, "%s.table", iso->filename); iso->htable = _openfile(Zfile, O_WRONLY); if (iso->htable == NULL) { return NULL; } } iso->handle = _openfile(iso->filename, O_WRONLY | O_CREAT); if (iso->handle == NULL) { printf("Error loading %s\n", iso->filename); return NULL; } printf("isoCreate: %s ok\n", iso->filename); printf("offset = %d\n", iso->offset); return iso; } int isoSetFormat(isoFile *iso, int blockofs, int blocksize, int blocks) { iso->blocksize = blocksize; iso->blocks = blocks; iso->blockofs = blockofs; printf("blockofs = %d\n", iso->blockofs); printf("blocksize = %d\n", iso->blocksize); printf("blocks = %d\n", iso->blocks); if (iso->flags & ISOFLAGS_Z2) { if (_writefile(iso->handle, "Z V2", 4) < 4) return -1; if (_writefile(iso->handle, &blocksize, 4) < 4) return -1; if (_writefile(iso->handle, &blocks, 4) < 4) return -1; if (_writefile(iso->handle, &blockofs, 4) < 4) return -1; } if (iso->flags & ISOFLAGS_BZ2) { if (_writefile(iso->handle, "BZV2", 4) < 4) return -1; if (_writefile(iso->handle, &blocksize, 4) < 4) return -1; if (_writefile(iso->handle, &blocks, 4) < 4) return -1; if (_writefile(iso->handle, &blockofs, 4) < 4) return -1; iso->buflsn = -1; iso->buffer = (u8*)malloc(iso->blocksize * 16); if (iso->buffer == NULL) return -1; } if (iso->flags & ISOFLAGS_BLOCKDUMP) { if (_writefile(iso->handle, "BDV2", 4) < 4) return -1; if (_writefile(iso->handle, &blocksize, 4) < 4) return -1; if (_writefile(iso->handle, &blocks, 4) < 4) return -1; if (_writefile(iso->handle, &blockofs, 4) < 4) return -1; } return 0; } s32 MSFtoLSN(u8 *Time) { u32 lsn; lsn = Time[2]; lsn += (Time[1] - 2) * 75; lsn += Time[0] * 75 * 60; return lsn; } void LSNtoMSF(u8 *Time, s32 lsn) { u8 m, s, f; lsn += 150; m = lsn / 4500; // minuten lsn = lsn - m * 4500; // minuten rest s = lsn / 75; // sekunden f = lsn - (s * 75); // sekunden rest Time[0] = itob(m); Time[1] = itob(s); Time[2] = itob(f); } int _isoReadBlock(isoFile *iso, u8 *dst, int lsn) { u64 ofs = (u64)lsn * iso->blocksize + iso->offset; int ret; // printf("_isoReadBlock %d, blocksize=%d, blockofs=%d\n", lsn, iso->blocksize, iso->blockofs); memset(dst, 0, iso->blockofs); _seekfile(iso->handle, ofs, SEEK_SET); ret = _readfile(iso->handle, dst + iso->blockofs, iso->blocksize); if (ret < iso->blocksize) { printf("read error %d\n", ret); return -1; } return 0; } int _isoReadBlockZ(isoFile *iso, u8 *dst, int lsn) { u32 pos, p; uLongf size; u8 Zbuf[CD_FRAMESIZE_RAW*2]; int ret; // printf("_isoReadBlockZ %d, %d\n", lsn, iso->blocksize); pos = *(unsigned long*) & iso->Ztable[lsn * 6]; p = *(unsigned short*) & iso->Ztable[lsn * 6 + 4]; // printf("%d, %d\n", pos, p); _seekfile(iso->handle, pos, SEEK_SET); ret = _readfile(iso->handle, Zbuf, p); if (ret < p) { printf("error reading block!!\n"); return -1; } size = CD_FRAMESIZE_RAW; uncompress(dst, &size, Zbuf, p); return 0; } int _isoReadBlockZ2(isoFile *iso, u8 *dst, int lsn) { u32 pos, p; uLongf size; u8 Zbuf[16*1024]; int ret; // printf("_isoReadBlockZ2 %d, %d\n", lsn, iso->blocksize); pos = *(u32*) & iso->Ztable[lsn*8]; p = *(u32*) & iso->Ztable[lsn*8+4]; // printf("%d, %d\n", pos, p); _seekfile(iso->handle, pos, SEEK_SET); ret = _readfile(iso->handle, Zbuf, p); if (ret < p) { printf("error reading block!!\n"); return -1; } size = iso->blocksize; uncompress(dst + iso->blockofs, &size, Zbuf, p); return 0; } int _isoReadBlockBZ2(isoFile *iso, u8 *dst, int lsn) { u32 pos, p; u32 size; u8 Zbuf[64*1024]; int ret; if ((lsn / 16) == iso->buflsn) { memset(dst, 0, iso->blockofs); memcpy(dst + iso->blockofs, iso->buffer + (iso->blocksize*(lsn&0xf)), iso->blocksize); return 0; } iso->buflsn = lsn / 16; // printf("_isoReadBlockBZ2 %d, %d\n", lsn, iso->blocksize); pos = *(u32*) & iso->Ztable[(lsn/16)*8]; p = *(u32*) & iso->Ztable[(lsn/16)*8+4]; // printf("%d, %d\n", pos, p); _seekfile(iso->handle, pos, SEEK_SET); ret = _readfile(iso->handle, Zbuf, p); if (ret < p) { printf("error reading block!!\n"); return -1; } size = iso->blocksize * 64; ret = BZ2_bzBuffToBuffDecompress((s8*)iso->buffer, &size, (s8*)Zbuf, p, 0, 0); if (ret != BZ_OK) { printf("_isoReadBlockBZ2 %d, %d\n", lsn, iso->blocksize); printf("%d, %d\n", pos, p); printf("error on BZ2: %d\n", ret); } memset(dst, 0, iso->blockofs); memcpy(dst + iso->blockofs, iso->buffer + (iso->blocksize*(lsn&0xf)), iso->blocksize); return 0; } int _isoReadBlockD(isoFile *iso, u8 *dst, int lsn) { int ret; int i; // printf("_isoReadBlockD %d, blocksize=%d, blockofs=%d\n", lsn, iso->blocksize, iso->blockofs); memset(dst, 0, iso->blockofs); for (i = 0; i < iso->dtablesize;i++) { if (iso->dtable[i] != lsn) continue; _seekfile(iso->handle, 16 + i*(iso->blocksize + 4) + 4, SEEK_SET); ret = _readfile(iso->handle, dst + iso->blockofs, iso->blocksize); if (ret < iso->blocksize) return -1; return 0; } printf("block %d not found in dump\n", lsn); return -1; } int _isoReadBlockM(isoFile *iso, u8 *dst, int lsn) { u64 ofs; int ret; int i; for (i = 0; i < 8; i++) { if (lsn >= iso->multih[i].slsn && lsn <= iso->multih[i].elsn) { break; } } if (i == 8) return -1; ofs = (u64)(lsn - iso->multih[i].slsn) * iso->blocksize + iso->offset; // printf("_isoReadBlock %d, blocksize=%d, blockofs=%d\n", lsn, iso->blocksize, iso->blockofs); memset(dst, 0, iso->blockofs); _seekfile(iso->multih[i].handle, ofs, SEEK_SET); ret = _readfile(iso->multih[i].handle, dst + iso->blockofs, iso->blocksize); if (ret < iso->blocksize) { printf("read error %d\n", ret); return -1; } return 0; } int isoReadBlock(isoFile *iso, u8 *dst, int lsn) { int ret; if (lsn > iso->blocks) { printf("isoReadBlock: %d > %d\n", lsn, iso->blocks); return -1; } if (iso->flags & ISOFLAGS_Z) ret = _isoReadBlockZ(iso, dst, lsn); else if (iso->flags & ISOFLAGS_Z2) ret = _isoReadBlockZ2(iso, dst, lsn); else if (iso->flags & ISOFLAGS_BLOCKDUMP) ret = _isoReadBlockD(iso, dst, lsn); else if (iso->flags & ISOFLAGS_MULTI) ret = _isoReadBlockM(iso, dst, lsn); else if (iso->flags & ISOFLAGS_BZ2) ret = _isoReadBlockBZ2(iso, dst, lsn); else ret = _isoReadBlock(iso, dst, lsn); if (ret == -1) return ret; if (iso->type == ISOTYPE_CD) { LSNtoMSF(dst + 12, lsn); dst[15] = 2; } return 0; } int _isoWriteBlock(isoFile *iso, u8 *src, int lsn) { u64 ofs = (u64)lsn * iso->blocksize + iso->offset; int ret; // printf("_isoWriteBlock %d (ofs=%d)\n", iso->blocksize, ofs); _seekfile(iso->handle, ofs, SEEK_SET); ret = _writefile(iso->handle, src + iso->blockofs, iso->blocksize); // printf("_isoWriteBlock %d\n", ret); if (ret < iso->blocksize) return -1; return 0; } int _isoWriteBlockZ(isoFile *iso, u8 *src, int lsn) { u32 pos; uLongf size; u8 Zbuf[CD_FRAMESIZE_RAW]; int ret; // printf("_isoWriteBlockZ %d\n", iso->blocksize); size = 2352; compress(Zbuf, &size, src, 2352); // printf("_isoWriteBlockZ %d\n", size); pos = (u32)_tellfile(iso->handle); ret = _writefile(iso->htable, &pos, 4); if (ret < 4) return -1; ret = _writefile(iso->htable, &size, 2); if (ret < 2) return -1; ret = _writefile(iso->handle, Zbuf, size); // printf("_isoWriteBlockZ %d\n", ret); if (ret < size) { printf("error writing block!!\n"); return -1; } return 0; } int _isoWriteBlockZ2(isoFile *iso, u8 *src, int lsn) { uLongf size; u8 Zbuf[1024*16]; int ret; // printf("_isoWriteBlockZ %d\n", iso->blocksize); size = 1024 * 16; compress(Zbuf, &size, src + iso->blockofs, iso->blocksize); // printf("_isoWriteBlockZ %d\n", size); ret = _writefile(iso->htable, (u8*) & size, 4); if (ret < 4) return -1; ret = _writefile(iso->handle, Zbuf, size); // printf("_isoWriteBlockZ %d\n", ret); if (ret < size) { printf("error writing block!!\n"); return -1; } return 0; } int _isoWriteBlockD(isoFile *iso, u8 *src, int lsn) { int ret; // printf("_isoWriteBlock %d (ofs=%d)\n", iso->blocksize, ofs); ret = _writefile(iso->handle, &lsn, 4); if (ret < 4) return -1; ret = _writefile(iso->handle, src + iso->blockofs, iso->blocksize); // printf("_isoWriteBlock %d\n", ret); if (ret < iso->blocksize) return -1; return 0; } int _isoWriteBlockBZ2(isoFile *iso, u8 *src, int lsn) { u32 size; u8 Zbuf[64*1024]; int blocks; int ret; memcpy(iso->buffer + (iso->blocksize*(lsn&0xf)), src + iso->blockofs, iso->blocksize); if (lsn == (iso->blocks - 1)) { blocks = (lsn & 0xf) + 1; } else { blocks = 16; if ((lsn & 0xf) != 0xf) return 0; } // printf("_isoWriteBlockBZ2 %d\n", iso->blocksize); size = 64 * 1024; ret = BZ2_bzBuffToBuffCompress((s8*)Zbuf, (u32*) & size, (s8*)iso->buffer, iso->blocksize * blocks, 9, 0, 30); if (ret != BZ_OK) { printf("error on BZ2: %d\n", ret); } // printf("_isoWriteBlockBZ2 %d\n", size); ret = _writefile(iso->htable, (u8*) & size, 4); if (ret < 4) return -1; ret = _writefile(iso->handle, Zbuf, size); // printf("_isoWriteBlockZ %d\n", ret); if (ret < size) { printf("error writing block!!\n"); return -1; } return 0; } int isoWriteBlock(isoFile *iso, u8 *src, int lsn) { int ret; if (iso->flags & ISOFLAGS_Z) ret = _isoWriteBlockZ(iso, src, lsn); else if (iso->flags & ISOFLAGS_Z2) ret = _isoWriteBlockZ2(iso, src, lsn); else if (iso->flags & ISOFLAGS_BLOCKDUMP) ret = _isoWriteBlockD(iso, src, lsn); else if (iso->flags & ISOFLAGS_BZ2) ret = _isoWriteBlockBZ2(iso, src, lsn); else ret = _isoWriteBlock(iso, src, lsn); if (ret == -1) return ret; return 0; } void isoClose(isoFile *iso) { if (iso->handle) _closefile(iso->handle); if (iso->htable) _closefile(iso->htable); if (iso->buffer) free(iso->buffer); free(iso); }