/* we want to delete temporary files as early as possible */ static struct zfile *updateoutputfile (struct zfile *z) { struct zfile *z2 = 0; int size; FILE *f = fopen (z->name, "rb"); for (;;) { if (!f) break; fseek (f, 0, SEEK_END); size = ftell (f); fseek (f, 0, SEEK_SET); if (!size) break; z2 = zfile_fopen_empty (z->name, size); if (!z2) break; fread (z2->data, size, 1, f); fclose (f); zfile_fclose (z); return z2; } if (f) fclose (f); zfile_fclose (z); zfile_fclose (z2); return 0; }
static struct zfile *dms (struct zfile *z) { int ret; struct zfile *zo; zo = zfile_fopen_empty ("zipped.dms", 1760 * 512); if (!zo) return z; ret = DMS_Process_File (z, zo, CMD_UNPACK, OPT_VERBOSE, 0, 0); if (ret == NO_PROBLEM || ret == DMS_FILE_END) { zfile_fclose (z); return zo; } return z; }
static void addextra(TCHAR *name, struct zfile **extra, uae_u8 *p, int size) { int i; struct zfile *zf = NULL; if (!extra) return; for (i = 0; i < DMS_EXTRA_SIZE; i++) { if (!extra[i]) break; } if (i == DMS_EXTRA_SIZE) return; zf = zfile_fopen_empty (NULL, name, size); if (!zf) return; zfile_fwrite (p, size, 1, zf); zfile_fseek (zf, 0, SEEK_SET); extra[i] = zf; }
struct zfile *read_rom_name (const TCHAR *filename) { int i; struct zfile *f; for (i = 0; i < romlist_cnt; i++) { if (!_tcsicmp (filename, rl[i].path)) { struct romdata *rd = rl[i].rd; f = read_rom (&rd); if (f) return f; } } f = rom_fopen (filename, L"rb", ZFD_NORMAL); if (f) { uae_u8 tmp[11]; zfile_fread (tmp, sizeof tmp, 1, f); if (!memcmp (tmp, "AMIROMTYPE1", sizeof tmp)) { struct zfile *df; int size; uae_u8 *buf; addkeydir (filename); zfile_fseek (f, 0, SEEK_END); size = zfile_ftell (f) - sizeof tmp; zfile_fseek (f, sizeof tmp, SEEK_SET); buf = xmalloc (uae_u8, size); zfile_fread (buf, size, 1, f); df = zfile_fopen_empty (f, L"tmp.rom", size); decode_cloanto_rom_do (buf, size, size); zfile_fwrite (buf, size, 1, df); zfile_fclose (f); xfree (buf); zfile_fseek (df, 0, SEEK_SET); f = df; } else { zfile_fseek (f, -((int)sizeof tmp), SEEK_CUR); } } return f; }
struct zfile *archive_access_lha (struct znode *zn) { struct zfile *zf = zn->volume->archive; struct zfile *out = zfile_fopen_empty (zf, zn->name, zn->size); struct interfacing lhinterface; zfile_fseek(zf, zn->offset, SEEK_SET); lhinterface.method = zn->method; lhinterface.dicbit = 13; /* method + 8; -lh5- */ lhinterface.infile = zf; lhinterface.outfile = out; lhinterface.original = zn->size; lhinterface.packed = zn->packedsize; switch (zn->method) { case LZHUFF0_METHOD_NUM: case LARC4_METHOD_NUM: zfile_fread(out->data, zn->size, 1, zf); break; case LARC_METHOD_NUM: /* -lzs- */ lhinterface.dicbit = 11; decode(&lhinterface); break; case LZHUFF1_METHOD_NUM: /* -lh1- */ case LZHUFF4_METHOD_NUM: /* -lh4- */ case LARC5_METHOD_NUM: /* -lz5- */ lhinterface.dicbit = 12; decode(&lhinterface); break; case LZHUFF6_METHOD_NUM: /* -lh6- */ /* Added N.Watazaki (^_^) */ case LZHUFF7_METHOD_NUM: /* -lh7- */ lhinterface.dicbit = (zn->method - LZHUFF6_METHOD_NUM) + 15; default: decode(&lhinterface); } return out; }
static struct zfile *unzip (struct zfile *z) { unzFile uz; unz_file_info file_info; char filename_inzip[2048]; struct zfile *zf; unsigned int err, zipcnt, i, we_have_file = 0; int select; char tmphist[MAX_DPATH]; int first = 1; if (!zlib_test ()) return z; zf = 0; uz = unzOpen (z); if (!uz) return z; if (unzGoToFirstFile (uz) != UNZ_OK) return z; zipcnt = 1; tmphist[0] = 0; for (;;) { err = unzGetCurrentFileInfo(uz,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0); if (err != UNZ_OK) return z; if (file_info.uncompressed_size > 0) { i = 0; while (ignoreextensions[i]) { if (strlen(filename_inzip) > strlen (ignoreextensions[i]) && !strcasecmp (ignoreextensions[i], filename_inzip + strlen (filename_inzip) - strlen (ignoreextensions[i]))) break; i++; } if (!ignoreextensions[i]) { if (tmphist[0]) { DISK_history_add (tmphist, -1); tmphist[0] = 0; first = 0; } if (first) { if (isdiskimage (filename_inzip)) sprintf (tmphist,"%s/%s", z->name, filename_inzip); } else { sprintf (tmphist,"%s/%s", z->name, filename_inzip); DISK_history_add (tmphist, -1); tmphist[0] = 0; } select = 0; if (!z->zipname) select = 1; if (z->zipname && !strcasecmp (z->zipname, filename_inzip)) select = -1; if (z->zipname && z->zipname[0] == '#' && atol (z->zipname + 1) == (int)zipcnt) select = -1; if (select && !we_have_file) { unsigned int err = unzOpenCurrentFile (uz); if (err == UNZ_OK) { zf = zfile_fopen_empty (filename_inzip, file_info.uncompressed_size); if (zf) { err = unzReadCurrentFile (uz, zf->data, file_info.uncompressed_size); unzCloseCurrentFile (uz); if (err == 0 || err == file_info.uncompressed_size) { zf = zuncompress (zf); if (select < 0 || zfile_gettype (zf)) { we_have_file = 1; } } } if (!we_have_file) { zfile_fclose (zf); zf = 0; } } } } } zipcnt++; err = unzGoToNextFile (uz); if (err != UNZ_OK) break; } if (zf) { zfile_fclose (z); z = zf; } return z; }
static struct zfile *gunzip (struct zfile *z) { uae_u8 header[2 + 1 + 1 + 4 + 1 + 1]; z_stream zs; int i, size, ret, first; uae_u8 flags; long offset; char name[MAX_DPATH]; uae_u8 buffer[8192]; struct zfile *z2; uae_u8 b; if (!zlib_test ()) return z; strcpy (name, z->name); memset (&zs, 0, sizeof (zs)); memset (header, 0, sizeof (header)); zfile_fread (header, sizeof (header), 1, z); flags = header[3]; if (header[0] != 0x1f && header[1] != 0x8b) return z; if (flags & 2) /* multipart not supported */ return z; if (flags & 32) /* encryption not supported */ return z; if (flags & 4) { /* skip extra field */ zfile_fread (&b, 1, 1, z); size = b; zfile_fread (&b, 1, 1, z); size |= b << 8; zfile_fseek (z, size + 2, SEEK_CUR); } if (flags & 8) { /* get original file name */ i = 0; do { zfile_fread (name + i, 1, 1, z); } while (name[i++]); } if (flags & 16) { /* skip comment */ i = 0; do { zfile_fread (&b, 1, 1, z); } while (b); } offset = zfile_ftell (z); zfile_fseek (z, -4, SEEK_END); zfile_fread (&b, 1, 1, z); size = b; zfile_fread (&b, 1, 1, z); size |= b << 8; zfile_fread (&b, 1, 1, z); size |= b << 16; zfile_fread (&b, 1, 1, z); size |= b << 24; if (size < 8 || size > 10000000) /* safety check */ return z; zfile_fseek (z, offset, SEEK_SET); z2 = zfile_fopen_empty (name, size); if (!z2) return z; zs.next_out = z2->data; zs.avail_out = size; first = 1; do { zs.next_in = buffer; zs.avail_in = sizeof (buffer); zfile_fread (buffer, sizeof (buffer), 1, z); if (first) { if (inflateInit2 (&zs, -MAX_WBITS) != Z_OK) break; first = 0; } ret = inflate (&zs, 0); } while (ret == Z_OK); inflateEnd (&zs); if (ret != Z_STREAM_END || first != 0) { zfile_fclose (z2); return z; } zfile_fclose (z); return z2; }
struct zfile *read_rom (struct romdata **prd) { struct romdata *rd2 = *prd; struct romdata *rd = *prd; TCHAR *name; int id = rd->id; uae_u32 crc32; int size; uae_u8 *buf, *buf2; /* find parent node */ for (;;) { if (rd2 == &roms[0]) break; if (rd2[-1].id != id) break; rd2--; } *prd = rd2; size = rd2->size; crc32 = rd2->crc32; name = rd->name; buf = xmalloc (uae_u8, size * 2); memset (buf, 0xff, size * 2); if (!buf) return NULL; buf2 = buf + size; while (rd->id == id) { int i, j, add; int ok = 0; uae_u32 flags = rd->type; int odd = (flags & ROMTYPE_ODD) ? 1 : 0; add = 0; for (i = 0; i < 2; i++) { memset (buf, 0, size); if (!(flags & (ROMTYPE_EVEN | ROMTYPE_ODD))) { read_rom_file (buf, rd); if (flags & ROMTYPE_CD32) { memcpy (buf2, buf, size); mergecd32 (buf, buf2, size); } add = 1; i++; } else { int romsize = size / 2; if (i) odd = !odd; if (flags & ROMTYPE_8BIT) { read_rom_file (buf2, rd); if (flags & ROMTYPE_BYTESWAP) byteswap (buf2, romsize); if (flags & ROMTYPE_SCRAMBLED) descramble (rd, buf2, romsize, odd); for (j = 0; j < size; j += 2) buf[j + odd] = buf2[j / 2]; read_rom_file (buf2, rd + 1); if (flags & ROMTYPE_BYTESWAP) byteswap (buf2, romsize); if (flags & ROMTYPE_SCRAMBLED) descramble (rd + 1, buf2, romsize, !odd); for (j = 0; j < size; j += 2) buf[j + (1 - odd)] = buf2[j / 2]; } else { read_rom_file (buf2, rd); if (flags & ROMTYPE_BYTESWAP) byteswap (buf2, romsize); if (flags & ROMTYPE_SCRAMBLED) descramble (rd, buf2, romsize, odd); for (j = 0; j < size; j += 4) { buf[j + 2 * odd + 0] = buf2[j / 2 + 0]; buf[j + 2 * odd + 1] = buf2[j / 2 + 1]; } read_rom_file (buf2, rd + 1); if (flags & ROMTYPE_BYTESWAP) byteswap (buf2, romsize); if (flags & ROMTYPE_SCRAMBLED) descramble (rd + 1, buf2, romsize, !odd); for (j = 0; j < size; j += 4) { buf[j + 2 * (1 - odd) + 0] = buf2[j / 2 + 0]; buf[j + 2 * (1 - odd) + 1] = buf2[j / 2 + 1]; } } add = 2; } if (get_crc32 (buf, size) == crc32) { ok = 1; } if (!ok && (rd->type & ROMTYPE_AR)) { uae_u8 tmp[2]; tmp[0] = buf[0]; tmp[1] = buf[1]; buf[0] = buf[1] = 0; if (get_crc32 (buf, size) == crc32) ok = 1; buf[0] = tmp[0]; buf[1] = tmp[1]; } if (!ok) { /* perhaps it is byteswapped without byteswap entry? */ byteswap (buf, size); if (get_crc32 (buf, size) == crc32) ok = 1; } if (ok) { struct zfile *zf = zfile_fopen_empty (NULL, name, size); if (zf) { zfile_fwrite (buf, size, 1, zf); zfile_fseek (zf, 0, SEEK_SET); } xfree (buf); return zf; } } rd += add; } xfree (buf); return NULL; }