Esempio n. 1
0
int extract_fastfile(char * infilename, char * outfilename) {
    FILE *fd,
         *fdo  = NULL;

    uint32_t inlen,
             outlen;
    int i,
        files;

    char *file_input,
         *file_output,
         *file_offset;

    setbuf(stdout, NULL);
    setbuf(stderr, NULL);
    file_input  = infilename;
    file_output = outfilename;
    file_offset = "0x15";

    printf("Extracting fastfile: %s\n", file_input);
    fd = fopen(file_input, "rb");
    if(!fd) std_err();

    if(minzip > INSZ) minzip = INSZ;
    if(minzip < 1)    minzip = 1;

    in       = malloc(INSZ);
    out      = malloc(OUTSZ);
    filebuff = malloc(FBUFFSZ);
    if(!in || !out || !filebuff) std_err();

    offset = get_num(file_offset);  // do not skip, needed for buffseek
    buffseek(fd, offset, SEEK_SET);

    z.zalloc = (alloc_func)0;
    z.zfree  = (free_func)0;
    z.opaque = (voidpf)0;
    if(inflateInit2(&z, zipwbits) != Z_OK) zlib_err(Z_INIT_ERROR);

    fdo = save_file(file_output);
    unzip(fd, &fdo, &inlen, &outlen);
    FCLOSE(fdo)

    printf("\n"
        "%u bytes compressed\n"
        "%u bytes extracted\n",
        inlen, outlen);

    FCLOSE(fdo)
    FCLOSE(fd)
    inflateEnd(&z);
    free(in);
    free(out);
    free(filebuff);
    return(0);
}
Esempio n. 2
0
static int HHA_seek(fvoid *opaque, PHYSFS_uint64 offset)
{
    HHAfileinfo *finfo = (HHAfileinfo *) opaque;
    HHAentry *entry = finfo->entry;
    void *in = finfo->handle;

    BAIL_IF_MACRO(offset < 0, ERR_INVALID_ARGUMENT, 0);
    BAIL_IF_MACRO(offset >= entry->uncompressed_size, ERR_PAST_EOF, 0);
    if (entry->compress == HHA_COMPRESS_NONE)
    {
        PHYSFS_sint64 newpos = offset + entry->offset;
        BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, newpos), NULL, 0);
        finfo->uncompressed_position = (PHYSFS_uint32) offset;
    }
    else if (entry->compress == HHA_COMPRESS_ZLIB)
    {
        /*
         * If seeking backwards, we need to redecode the file
         *  from the start and throw away the compressed bits until we hit
         *  the offset we need. If seeking forward, we still need to
         *  decode, but we don't rewind first.
         */
        if (offset < finfo->uncompressed_position)
        {
            /* we do a copy so state is sane if inflateInit2() fails. */
            z_stream str;
            initializeZStream(&str);
            if (zlib_err(inflateInit2(&str, -MAX_WBITS)) != Z_OK)
                return(0);

            if (!__PHYSFS_platformSeek(in, entry->offset))
                return(0);

            inflateEnd(&finfo->zlib_stream);
            memcpy(&finfo->zlib_stream, &str, sizeof (z_stream));
            finfo->uncompressed_position = finfo->compressed_position = 0;
        } /* if */

        while (finfo->uncompressed_position != offset)
        {
            PHYSFS_uint8 buf[512];
            PHYSFS_uint32 maxread;

            maxread = (PHYSFS_uint32) (offset - finfo->uncompressed_position);
            if (maxread > sizeof (buf))
                maxread = sizeof (buf);

            if (HHA_read(finfo, buf, maxread, 1) != 1)
                return(0);
        } /* while */
    } /* else */
    else
        printf("LZMA file: %s/%s\n", entry->dir, entry->name);
    return(1);
} /* HHA_seek */
Esempio n. 3
0
static int ZIP_seek(fvoid *opaque, PHYSFS_uint64 offset)
{
    ZIPfileinfo *finfo = (ZIPfileinfo *) opaque;
    ZIPentry *entry = finfo->entry;
    void *in = finfo->handle;

    BAIL_IF_MACRO(offset > entry->uncompressed_size, ERR_PAST_EOF, 0);

    if (entry->compression_method == COMPMETH_NONE)
    {
        PHYSFS_sint64 newpos = offset + entry->offset;
        BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, newpos), NULL, 0);
        finfo->uncompressed_position = (PHYSFS_uint32) offset;
    } /* if */

    else
    {
        /*
         * If seeking backwards, we need to redecode the file
         *  from the start and throw away the compressed bits until we hit
         *  the offset we need. If seeking forward, we still need to
         *  decode, but we don't rewind first.
         */
        if (offset < finfo->uncompressed_position)
        {
            /* we do a copy so state is sane if inflateInit2() fails. */
            z_stream str;
            initializeZStream(&str);
            if (zlib_err(inflateInit2(&str, -MAX_WBITS)) != Z_OK)
                return(0);

            if (!__PHYSFS_platformSeek(in, entry->offset))
                return(0);

            inflateEnd(&finfo->stream);
            memcpy(&finfo->stream, &str, sizeof (z_stream));
            finfo->uncompressed_position = finfo->compressed_position = 0;
        } /* if */

        while (finfo->uncompressed_position != offset)
        {
            PHYSFS_uint8 buf[512];
            PHYSFS_uint32 maxread;

            maxread = (PHYSFS_uint32) (offset - finfo->uncompressed_position);
            if (maxread > sizeof (buf))
                maxread = sizeof (buf);

            if (ZIP_read(finfo, buf, maxread, 1) != 1)
                return(0);
        } /* while */
    } /* else */

    return(1);
} /* ZIP_seek */
Esempio n. 4
0
int unzip(FILE *fd, FILE **fdo, uint32_t *inlen, uint32_t *outlen) {
    uint32_t     oldsz = 0,
            oldoff,
            len;
    int     ret   = -1,
            zerr  = Z_OK;

    oldoff = offset;
    inflateReset(&z);
    for(; (len = buffread(fd, in, INSZ)); buffinc(len)) {
        z.next_in   = in;
        z.avail_in  = len;
        do {
            z.next_out  = out;
            z.avail_out = OUTSZ;
            zerr = inflate(&z, Z_SYNC_FLUSH);
			myfw(out, z.total_out - oldsz, *fdo);
			oldsz = z.total_out;

            if(zerr != Z_OK) {      // inflate() return value MUST be handled now
                if(zerr == Z_STREAM_END) {
                    ret = 0;
                } else {
                    zlib_err(zerr);
                }
                break;
            }
            ret = 0;    // it's better to return 0 even if the z stream is incomplete... or not?
        } while(z.avail_in);

        if(zerr != Z_OK) break;     // Z_STREAM_END included, for avoiding "goto"
    }

    *inlen  = z.total_in;
    *outlen = z.total_out;
    if(!ret) {
        oldoff += z.total_in;
    } else {
        oldoff++;
    }
    buffseek(fd, oldoff, SEEK_SET);
    return(ret);
}
Esempio n. 5
0
static fvoid *HHA_openRead(dvoid *opaque, const char *fnm, int *fileExists)
{
    HHAinfo *info = (HHAinfo *) opaque;
    HHAfileinfo *finfo;
    HHAentry *entry;

    entry = HHA_find_entry(info, fnm);
    *fileExists = (entry != NULL);
    BAIL_IF_MACRO(entry == NULL, NULL, NULL);

    finfo = (HHAfileinfo *) allocator.Malloc(sizeof (HHAfileinfo));
    BAIL_IF_MACRO(finfo == NULL, ERR_OUT_OF_MEMORY, NULL);
    memset(finfo, '\0', sizeof (HHAfileinfo));
    finfo->handle = __PHYSFS_platformOpenRead(info->filename);
    if ( (finfo->handle == NULL) ||
         (!__PHYSFS_platformSeek(finfo->handle, entry->offset)) )
    {
        allocator.Free(finfo);
        return(NULL);
    } /* if */
    
    finfo->entry = entry;
    
    if (finfo->entry->compress == HHA_COMPRESS_ZLIB)
    {
        initializeZStream(&finfo->zlib_stream);
        if (zlib_err(inflateInit2(&finfo->zlib_stream, -MAX_WBITS)) != Z_OK)
        {
            HHA_fileClose(finfo);
            return(NULL);
        } /* if */

        finfo->buffer = (PHYSFS_uint8 *) allocator.Malloc(ZIP_READBUFSIZE);
        if (finfo->buffer == NULL)
        {
            HHA_fileClose(finfo);
            BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
        } /* if */
    } /* if */
    
    return(finfo);
} /* HHA_openRead */
Esempio n. 6
0
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 */
Esempio n. 7
0
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 */