예제 #1
0
파일: hog.c 프로젝트: UIKit0/paragui
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 */
예제 #2
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 */
예제 #3
0
파일: hha.c 프로젝트: C4-sic/codetastrophe
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 */
static fvoid *WAD_openRead(dvoid *opaque, const char *fnm, int *fileExists)
{
    WADinfo *info = ((WADinfo *) opaque);
    WADfileinfo *finfo;
    WADentry *entry;

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

    finfo = (WADfileinfo *) allocator.Malloc(sizeof (WADfileinfo));
    BAIL_IF_MACRO(finfo == NULL, ERR_OUT_OF_MEMORY, NULL);

    finfo->handle = __PHYSFS_platformOpenRead(info->filename);
    if ( (finfo->handle == NULL) ||
         (!__PHYSFS_platformSeek(finfo->handle, entry->startPos)) )
    {
        allocator.Free(finfo);
        return NULL;
    } /* if */

    finfo->curPos = 0;
    finfo->entry = entry;
    return finfo;
} /* WAD_openRead */
예제 #5
0
SZ_RESULT SzFileSeekImp(void *object, CFileSize pos)
{
    CFileInStream *s = (CFileInStream *) object;
    if (__PHYSFS_platformSeek(s->File, (PHYSFS_uint64) pos))
        return SZ_OK;
    return SZE_FAIL;
} /* SzFileSeekImp */
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 */
예제 #7
0
파일: hog.c 프로젝트: UIKit0/paragui
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 */
예제 #8
0
파일: hog.c 프로젝트: UIKit0/paragui
static int HOG_seek(FileHandle *handle, PHYSFS_uint64 offset)
{
    HOGfileinfo *finfo = (HOGfileinfo *) (handle->opaque);
    HOGentry *entry = finfo->entry;
    int rc;

    BAIL_IF_MACRO(offset < 0, ERR_INVALID_ARGUMENT, 0);
    BAIL_IF_MACRO(offset >= entry->size, ERR_PAST_EOF, 0);
    rc = __PHYSFS_platformSeek(finfo->handle, entry->startPos + offset);
    if (rc)
        finfo->curPos = (PHYSFS_uint32) offset;

    return(rc);
} /* HOG_seek */
static int WAD_seek(fvoid *opaque, PHYSFS_uint64 offset)
{
    WADfileinfo *finfo = (WADfileinfo *) opaque;
    WADentry *entry = finfo->entry;
    int rc;

    BAIL_IF_MACRO(offset < 0, ERR_INVALID_ARGUMENT, 0);
    BAIL_IF_MACRO(offset >= entry->size, ERR_PAST_EOF, 0);
    rc = __PHYSFS_platformSeek(finfo->handle, entry->startPos + offset);
    if (rc)
        finfo->curPos = (PHYSFS_uint32) offset;

    return rc;
} /* WAD_seek */
예제 #10
0
파일: hha.c 프로젝트: C4-sic/codetastrophe
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 */
예제 #11
0
파일: hog.c 프로젝트: UIKit0/paragui
static FileHandle *HOG_openRead(DirHandle *h, const char *fnm, int *fileExists)
{
    HOGinfo *info = ((HOGinfo *) h->opaque);
    FileHandle *retval;
    HOGfileinfo *finfo;
    HOGentry *entry;

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

    retval = (FileHandle *) malloc(sizeof (FileHandle));
    BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
    finfo = (HOGfileinfo *) malloc(sizeof (HOGfileinfo));
    if (finfo == NULL)
    {
        free(retval);
        BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
    } /* if */

    finfo->handle = __PHYSFS_platformOpenRead(info->filename);
    if ( (finfo->handle == NULL) ||
         (!__PHYSFS_platformSeek(finfo->handle, entry->startPos)) )
    {
        free(finfo);
        free(retval);
        return(NULL);
    } /* if */

    finfo->curPos = 0;
    finfo->entry = entry;
    retval->opaque = (void *) finfo;
    retval->funcs = &__PHYSFS_FileFunctions_HOG;
    retval->dirHandle = h;
    return(retval);
} /* HOG_openRead */
예제 #12
0
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 */
예제 #13
0
파일: dir.c 프로젝트: leonlee/tome
static int DIR_seek(fvoid *opaque, PHYSFS_uint64 offset)
{
    return(__PHYSFS_platformSeek(opaque, offset));
} /* DIR_seek */
예제 #14
0
파일: dir.c 프로젝트: UIKit0/paragui
static int DIR_seek(FileHandle *handle, PHYSFS_uint64 offset)
{
    return(__PHYSFS_platformSeek(handle->opaque, offset));
} /* DIR_seek */