static int mvl_open(const char *filename, int forWriting, void **fh, PHYSFS_uint32 *count) { PHYSFS_uint8 buf[4]; *fh = NULL; BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, 0); *fh = __PHYSFS_platformOpenRead(filename); BAIL_IF_MACRO(*fh == NULL, NULL, 0); if (__PHYSFS_platformRead(*fh, buf, 4, 1) != 1) goto openMvl_failed; if (memcmp(buf, "DMVL", 4) != 0) { __PHYSFS_setError(ERR_UNSUPPORTED_ARCHIVE); goto openMvl_failed; } /* if */ if (__PHYSFS_platformRead(*fh, count, sizeof (PHYSFS_uint32), 1) != 1) goto openMvl_failed; *count = PHYSFS_swapULE32(*count); return 1; openMvl_failed: if (*fh != NULL) __PHYSFS_platformClose(*fh); *count = -1; *fh = NULL; return 0; } /* mvl_open */
static int hog_open(const char *filename, int forWriting, void **fh, PHYSFS_uint32 *count) { PHYSFS_uint8 buf[13]; PHYSFS_uint32 size; PHYSFS_sint64 pos; *count = 0; *fh = NULL; BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, 0); *fh = __PHYSFS_platformOpenRead(filename); BAIL_IF_MACRO(*fh == NULL, NULL, 0); if (__PHYSFS_platformRead(*fh, buf, 3, 1) != 1) goto openHog_failed; if (memcmp(buf, "DHF", 3) != 0) { __PHYSFS_setError(ERR_UNSUPPORTED_ARCHIVE); goto openHog_failed; } /* if */ while( 1 ) { if (__PHYSFS_platformRead(*fh, buf, 13, 1) != 1) break; //eof here is ok if (__PHYSFS_platformRead(*fh, &size, 4, 1) != 1) goto openHog_failed; size = PHYSFS_swapULE32(size); (*count)++; // Skip over entry pos = __PHYSFS_platformTell(*fh); if (pos == -1) goto openHog_failed; if (!__PHYSFS_platformSeek(*fh, pos + size)) goto openHog_failed; } // Rewind to start of entries if (!__PHYSFS_platformSeek(*fh, 3)) goto openHog_failed; return(1); openHog_failed: if (*fh != NULL) __PHYSFS_platformClose(*fh); *count = -1; *fh = NULL; return(0); } /* hog_open */
static int wad_load_entries(const char *name, int forWriting, WADinfo *info) { void *fh = NULL; PHYSFS_uint32 fileCount; PHYSFS_uint32 directoryOffset; WADentry *entry; char lastDirectory[9]; lastDirectory[8] = 0; /* Make sure lastDirectory stays null-terminated. */ BAIL_IF_MACRO(!wad_open(name, forWriting, &fh, &fileCount,&directoryOffset), NULL, 0); info->entryCount = fileCount; info->entries = (WADentry *) allocator.Malloc(sizeof(WADentry)*fileCount); if (info->entries == NULL) { __PHYSFS_platformClose(fh); BAIL_MACRO(ERR_OUT_OF_MEMORY, 0); } /* if */ __PHYSFS_platformSeek(fh,directoryOffset); for (entry = info->entries; fileCount > 0; fileCount--, entry++) { if (__PHYSFS_platformRead(fh, &entry->startPos, 4, 1) != 1) { __PHYSFS_platformClose(fh); return 0; } /* if */ if (__PHYSFS_platformRead(fh, &entry->size, 4, 1) != 1) { __PHYSFS_platformClose(fh); return 0; } /* if */ if (__PHYSFS_platformRead(fh, &entry->name, 8, 1) != 1) { __PHYSFS_platformClose(fh); return 0; } /* if */ entry->name[8] = '\0'; /* name might not be null-terminated in file. */ entry->size = PHYSFS_swapULE32(entry->size); entry->startPos = PHYSFS_swapULE32(entry->startPos); } /* for */ __PHYSFS_platformClose(fh); __PHYSFS_sort(info->entries, info->entryCount, wad_entry_cmp, wad_entry_swap); return 1; } /* wad_load_entries */
static int hog_load_entries(const char *name, int forWriting, HOGinfo *info) { void *fh = NULL; PHYSFS_uint32 fileCount; HOGentry *entry; BAIL_IF_MACRO(!hog_open(name, forWriting, &fh, &fileCount), NULL, 0); info->entryCount = fileCount; info->entries = (HOGentry *) malloc(sizeof (HOGentry) * fileCount); if (info->entries == NULL) { __PHYSFS_platformClose(fh); BAIL_MACRO(ERR_OUT_OF_MEMORY, 0); } /* if */ for (entry = info->entries; fileCount > 0; fileCount--, entry++) { if (__PHYSFS_platformRead(fh, &entry->name, 13, 1) != 1) { __PHYSFS_platformClose(fh); return(0); } /* if */ if (__PHYSFS_platformRead(fh, &entry->size, 4, 1) != 1) { __PHYSFS_platformClose(fh); return(0); } /* if */ entry->size = PHYSFS_swapULE32(entry->size); entry->startPos = __PHYSFS_platformTell(fh); if (entry->startPos == -1) { __PHYSFS_platformClose(fh); return(0); } // Skip over entry if (!__PHYSFS_platformSeek(fh, entry->startPos + entry->size)) { __PHYSFS_platformClose(fh); return(0); } } /* for */ __PHYSFS_platformClose(fh); __PHYSFS_sort(info->entries, info->entryCount, hog_entry_cmp, hog_entry_swap); return(1); } /* hog_load_entries */
static int HHA_load_entries(const char *name, int forWriting, HHAinfo *info) { void *fh = NULL; PHYSFS_uint32 fileNameSize; PHYSFS_uint32 fileCount; HHAentry *entry; PHYSFS_uint32 buf[6]; BAIL_IF_MACRO(!hha_open(name, forWriting, &fh, &fileNameSize, &fileCount), NULL, 0); info->entryCount = fileCount; info->filenames = (char *) allocator.Malloc(fileNameSize); if (info->filenames == NULL) { __PHYSFS_platformClose(fh); BAIL_MACRO(ERR_OUT_OF_MEMORY, 0); } /* if */ info->entries = (HHAentry *) allocator.Malloc(sizeof(HHAentry)*fileCount); if (info->entries == NULL) { __PHYSFS_platformClose(fh); BAIL_MACRO(ERR_OUT_OF_MEMORY, 0); } /* if */ if (__PHYSFS_platformRead(fh, info->filenames, 1, fileNameSize) != fileNameSize) { __PHYSFS_platformClose(fh); return(0); } for (entry = info->entries; fileCount > 0; fileCount--, entry++) { if (__PHYSFS_platformRead(fh, buf, sizeof(PHYSFS_uint32), 6) != 6) { __PHYSFS_platformClose(fh); return(0); } /* if */ entry->dir = info->filenames + PHYSFS_swapULE32(buf[0]); entry->name = info->filenames + PHYSFS_swapULE32(buf[1]); entry->compress = PHYSFS_swapULE32(buf[2]); entry->offset = PHYSFS_swapULE32(buf[3]); entry->uncompressed_size = PHYSFS_swapULE32(buf[4]); entry->compressed_size = PHYSFS_swapULE32(buf[5]); } /* for */ __PHYSFS_platformClose(fh); __PHYSFS_sort(info->entries, info->entryCount, HHA_entry_cmp, HHA_entry_swap); return(1); } /* HHA_load_entries */
static PHYSFS_sint64 DIR_read(fvoid *opaque, void *buffer, PHYSFS_uint32 objSize, PHYSFS_uint32 objCount) { PHYSFS_sint64 retval; retval = __PHYSFS_platformRead(opaque, buffer, objSize, objCount); return(retval); } /* DIR_read */
/* * Read an unsigned 8-bit int and swap to native byte order. */ static int readui8(void *in, PHYSFS_uint8 *val) { PHYSFS_uint8 v; BAIL_IF_MACRO(__PHYSFS_platformRead(in, &v, sizeof (v), 1) != 1, NULL, 0); *val = v; return(1); } /* readui8*/
/* * Read an unsigned 16-bit int and swap to native byte order. */ static int readui16(void *in, PHYSFS_uint16 *val) { PHYSFS_uint16 v; BAIL_IF_MACRO(__PHYSFS_platformRead(in, &v, sizeof (v), 1) != 1, NULL, 0); *val = PHYSFS_swapULE16(v); return(1); } /* readui16 */
SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size, size_t *processedSize) { CFileInStream *s = (CFileInStream *)object; size_t processedSizeLoc = __PHYSFS_platformRead(s->File, buffer, 1, size); if (processedSize != 0) *processedSize = processedSizeLoc; return SZ_OK; } /* SzFileReadImp */
static int mvl_load_entries(const char *name, int forWriting, MVLinfo *info) { void *fh = NULL; PHYSFS_uint32 fileCount; PHYSFS_uint32 location = 8; /* sizeof sig. */ MVLentry *entry; BAIL_IF_MACRO(!mvl_open(name, forWriting, &fh, &fileCount), NULL, 0); info->entryCount = fileCount; info->entries = (MVLentry *) allocator.Malloc(sizeof(MVLentry)*fileCount); if (info->entries == NULL) { __PHYSFS_platformClose(fh); BAIL_MACRO(ERR_OUT_OF_MEMORY, 0); } /* if */ location += (17 * fileCount); for (entry = info->entries; fileCount > 0; fileCount--, entry++) { if (__PHYSFS_platformRead(fh, &entry->name, 13, 1) != 1) { __PHYSFS_platformClose(fh); return 0; } /* if */ if (__PHYSFS_platformRead(fh, &entry->size, 4, 1) != 1) { __PHYSFS_platformClose(fh); return 0; } /* if */ entry->size = PHYSFS_swapULE32(entry->size); entry->startPos = location; location += entry->size; } /* for */ __PHYSFS_platformClose(fh); __PHYSFS_sort(info->entries, info->entryCount, mvl_entry_cmp, mvl_entry_swap); return 1; } /* mvl_load_entries */
static int hha_open(const char *filename, int forWriting, void **fh, PHYSFS_uint32 *filenameSize, PHYSFS_uint32 *count) { PHYSFS_uint32 magic[2]; *fh = NULL; BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, 0); *fh = __PHYSFS_platformOpenRead(filename); BAIL_IF_MACRO(*fh == NULL, NULL, 0); if (__PHYSFS_platformRead(*fh, magic, sizeof(PHYSFS_uint32), 2) != 2) goto openHHA_failed; magic[0] = PHYSFS_swapULE32(magic[0]); magic[1] = PHYSFS_swapULE32(magic[1]); if (!(magic[0] == HHA_FILE_MAGIC && magic[1] == HHA_FILE_VERSION)) { __PHYSFS_setError(ERR_UNSUPPORTED_ARCHIVE); goto openHHA_failed; } /* if */ if (__PHYSFS_platformRead(*fh, filenameSize, sizeof (PHYSFS_uint32), 1) != 1) goto openHHA_failed; *filenameSize = PHYSFS_swapULE32(*filenameSize); if (__PHYSFS_platformRead(*fh, count, sizeof (PHYSFS_uint32), 1) != 1) goto openHHA_failed; *count = PHYSFS_swapULE32(*count); return(1); openHHA_failed: if (*fh != NULL) __PHYSFS_platformClose(*fh); *filenameSize = -1; *count = -1; *fh = NULL; return(0); } /* HHA_open */
SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxReqSize, size_t *processedSize) { CFileInStream *s = (CFileInStream *)object; PHYSFS_sint64 processedSizeLoc; if (maxReqSize > kBufferSize) maxReqSize = kBufferSize; processedSizeLoc = __PHYSFS_platformRead(s->File, g_Buffer, 1, maxReqSize); *buffer = g_Buffer; if (processedSize != NULL) *processedSize = (size_t) processedSizeLoc; return SZ_OK; } /* SzFileReadImp */
static PHYSFS_sint64 HOG_read(FileHandle *handle, void *buffer, PHYSFS_uint32 objSize, PHYSFS_uint32 objCount) { HOGfileinfo *finfo = (HOGfileinfo *) (handle->opaque); HOGentry *entry = finfo->entry; PHYSFS_uint32 bytesLeft = entry->size - finfo->curPos; PHYSFS_uint32 objsLeft = (bytesLeft / objSize); PHYSFS_sint64 rc; if (objsLeft < objCount) objCount = objsLeft; rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount); if (rc > 0) finfo->curPos += (PHYSFS_uint32) (rc * objSize); return(rc); } /* HOG_read */
static PHYSFS_sint64 WAD_read(fvoid *opaque, void *buffer, PHYSFS_uint32 objSize, PHYSFS_uint32 objCount) { WADfileinfo *finfo = (WADfileinfo *) opaque; WADentry *entry = finfo->entry; PHYSFS_uint32 bytesLeft = entry->size - finfo->curPos; PHYSFS_uint32 objsLeft = (bytesLeft / objSize); PHYSFS_sint64 rc; if (objsLeft < objCount) objCount = objsLeft; rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount); if (rc > 0) finfo->curPos += (PHYSFS_uint32) (rc * objSize); return rc; } /* WAD_read */
static int LZMA_isArchive(const char *filename, int forWriting) { PHYSFS_uint8 sig[k7zSignatureSize]; PHYSFS_uint8 res; void *in; BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, 0); in = __PHYSFS_platformOpenRead(filename); BAIL_IF_MACRO(in == NULL, NULL, 0); if (__PHYSFS_platformRead(in, sig, k7zSignatureSize, 1) != 1) BAIL_MACRO(NULL, 0); /* Test whether sig is the 7z signature */ res = TestSignatureCandidate(sig); __PHYSFS_platformClose(in); return res; } /* LZMA_isArchive */
static PHYSFS_sint64 HHA_read(fvoid *opaque, void *buffer, PHYSFS_uint32 objSize, PHYSFS_uint32 objCount) { HHAfileinfo *finfo = (HHAfileinfo *) opaque; HHAentry *entry = finfo->entry; PHYSFS_sint64 retval = 0; PHYSFS_sint64 maxread = ((PHYSFS_sint64) objSize) * objCount; PHYSFS_sint64 avail = entry->uncompressed_size - finfo->uncompressed_position; BAIL_IF_MACRO(maxread == 0, NULL, 0); /* quick rejection. */ if (avail < maxread) { maxread = avail - (avail % objSize); objCount = (PHYSFS_uint32) (maxread / objSize); BAIL_IF_MACRO(objCount == 0, ERR_PAST_EOF, 0); /* quick rejection. */ __PHYSFS_setError(ERR_PAST_EOF); /* this is always true here. */ } /* if */ if (entry->compress == HHA_COMPRESS_NONE) { retval = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount); } else if (entry->compress == HHA_COMPRESS_ZLIB) { finfo->zlib_stream.next_out = buffer; finfo->zlib_stream.avail_out = objSize * objCount; while (retval < maxread) { PHYSFS_uint32 before = finfo->zlib_stream.total_out; int rc; if (finfo->zlib_stream.avail_in == 0) { PHYSFS_sint64 br; br = entry->compressed_size - finfo->compressed_position; if (br > 0) { if (br > ZIP_READBUFSIZE) br = ZIP_READBUFSIZE; br = __PHYSFS_platformRead(finfo->handle, finfo->buffer, 1, (PHYSFS_uint32) br); if (br <= 0) break; finfo->compressed_position += (PHYSFS_uint32) br; finfo->zlib_stream.next_in = finfo->buffer; finfo->zlib_stream.avail_in = (PHYSFS_uint32) br; } /* if */ } /* if */ rc = zlib_err(inflate(&finfo->zlib_stream, Z_SYNC_FLUSH)); retval += (finfo->zlib_stream.total_out - before); if (rc != Z_OK) break; } /* while */ retval /= objSize; } if (retval > 0) finfo->uncompressed_position += (PHYSFS_uint32) (retval * objSize); return(retval); } /* HHA_read */
static PHYSFS_sint64 zip_find_end_of_central_dir(void *in, PHYSFS_sint64 *len) { PHYSFS_uint8 buf[256]; PHYSFS_sint32 i = 0; PHYSFS_sint64 filelen; PHYSFS_sint64 filepos; PHYSFS_sint32 maxread; PHYSFS_sint32 totalread = 0; int found = 0; PHYSFS_uint32 extra = 0; filelen = __PHYSFS_platformFileLength(in); BAIL_IF_MACRO(filelen == -1, NULL, 0); /* !!! FIXME: unlocalized string */ BAIL_IF_MACRO(filelen > 0xFFFFFFFF, "ZIP bigger than 2 gigs?!", 0); /* * Jump to the end of the file and start reading backwards. * The last thing in the file is the zipfile comment, which is variable * length, and the field that specifies its size is before it in the * file (argh!)...this means that we need to scan backwards until we * hit the end-of-central-dir signature. We can then sanity check that * the comment was as big as it should be to make sure we're in the * right place. The comment length field is 16 bits, so we can stop * searching for that signature after a little more than 64k at most, * and call it a corrupted zipfile. */ if (sizeof (buf) < filelen) { filepos = filelen - sizeof (buf); maxread = sizeof (buf); } /* if */ else { filepos = 0; maxread = (PHYSFS_uint32) filelen; } /* else */ while ((totalread < filelen) && (totalread < 65557)) { BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, filepos), NULL, -1); /* make sure we catch a signature between buffers. */ if (totalread != 0) { if (__PHYSFS_platformRead(in, buf, maxread - 4, 1) != 1) return(-1); *((PHYSFS_uint32 *) (&buf[maxread - 4])) = extra; totalread += maxread - 4; } /* if */ else { if (__PHYSFS_platformRead(in, buf, maxread, 1) != 1) return(-1); totalread += maxread; } /* else */ extra = *((PHYSFS_uint32 *) (&buf[0])); for (i = maxread - 4; i > 0; i--) { if ((buf[i + 0] == 0x50) && (buf[i + 1] == 0x4B) && (buf[i + 2] == 0x05) && (buf[i + 3] == 0x06) ) { found = 1; /* that's the signature! */ break; } /* if */ } /* for */ if (found) break; filepos -= (maxread - 4); } /* while */ BAIL_IF_MACRO(!found, ERR_NOT_AN_ARCHIVE, -1); if (len != NULL) *len = filelen; return(filepos + i); } /* zip_find_end_of_central_dir */
static PHYSFS_sint64 ZIP_read(fvoid *opaque, void *buf, PHYSFS_uint32 objSize, PHYSFS_uint32 objCount) { int total, i = 0; ZIPfileinfo *finfo = (ZIPfileinfo *) opaque; ZIPentry *entry = finfo->entry; PHYSFS_sint64 retval = 0; PHYSFS_sint64 maxread = ((PHYSFS_sint64) objSize) * objCount; PHYSFS_sint64 avail = entry->uncompressed_size - finfo->uncompressed_position; BAIL_IF_MACRO(maxread == 0, NULL, 0); /* quick rejection. */ if (avail < maxread) { maxread = avail - (avail % objSize); objCount = (PHYSFS_uint32) (maxread / objSize); BAIL_IF_MACRO(objCount == 0, ERR_PAST_EOF, 0); /* quick rejection. */ __PHYSFS_setError(ERR_PAST_EOF); /* this is always true here. */ } /* if */ if (entry->compression_method == COMPMETH_NONE) { if (entry->encrypted == AES_ENCRYPTED) { retval = __PHYSFS_platformRead(finfo->handle, buf, objSize, objCount); total = maxread; while (total > 16) { fcrypt_decrypt(((char*)buf) + i, 16, &finfo->zctx); i += 16; total -= 16; } if (total > 0) { fcrypt_decrypt(((char*)buf) + i, total, &finfo->zctx); } } else { retval = __PHYSFS_platformRead(finfo->handle, buf, objSize, objCount); } } /* if */ else { finfo->stream.next_out = buf; finfo->stream.avail_out = objSize * objCount; while (retval < maxread) { PHYSFS_uint32 before = finfo->stream.total_out; int rc; if (finfo->stream.avail_in == 0) { PHYSFS_sint64 br; br = entry->compressed_size - finfo->compressed_position; if (br > 0) { if (br > ZIP_READBUFSIZE) br = ZIP_READBUFSIZE; br = __PHYSFS_platformRead(finfo->handle, finfo->buffer, 1, (PHYSFS_uint32) br); if (br <= 0) { break; } if (entry->encrypted == AES_ENCRYPTED) { total = br; i = 0; while (total > 16) { fcrypt_decrypt(finfo->buffer + i, 16, &finfo->zctx); i += 16; total -= 16; } if (total > 0) { fcrypt_decrypt(finfo->buffer + i, total, &finfo->zctx); } } finfo->compressed_position += (PHYSFS_uint32) br; finfo->stream.next_in = finfo->buffer; finfo->stream.avail_in = (PHYSFS_uint32) br; } /* if */ } /* if */ rc = zlib_err(inflate(&finfo->stream, Z_SYNC_FLUSH)); retval += (finfo->stream.total_out - before); if (rc != Z_OK) break; } /* while */ retval /= objSize; } /* else */ if (retval > 0) finfo->uncompressed_position += (PHYSFS_uint32) (retval * objSize); return(retval); } /* ZIP_read */