Пример #1
0
void update(FILE *infile, long old_length, long new_length)
{
    unsigned char buf[4];
    size_t bytes_read;
    size_t bytes_written;

    CHECK_ERROR(
            !(new_length >= old_length && (new_length-old_length)%4 == 0),
            "internal error (bad size for update)");

    /* check old RIFF length */
    CHECK_ERRNO(fseek(infile, 0x04, SEEK_SET) != 0, "fseek");

    bytes_read = fread(buf, 1, 4, infile);
    CHECK_FILE(bytes_read != 4, infile, "fread");

    CHECK_ERROR(read_32_le(buf)+8 != old_length, "RIFF size doesn't check out (extra chunks?)\n");

    /* check old data length */
    CHECK_ERRNO(fseek(infile, 0x28, SEEK_SET) != 0, "fseek");

    bytes_read = fread(buf, 1, 4, infile);
    CHECK_FILE(bytes_read != 4, infile, "fread");
    CHECK_ERROR(read_32_le(buf)+0x2c != old_length, "data size doesn't check out (extra chunks?)\n");


    /* update RIFF length */
    CHECK_ERRNO(fseek(infile, 0x04, SEEK_SET) != 0, "fseek");

    write_32_le(buf, new_length-8);
    bytes_written = fwrite(buf, 1, 4, infile);
    CHECK_FILE(bytes_written != 4, infile, "fwrite");

    /* update data length */
    CHECK_ERRNO(fseek(infile, 0x28, SEEK_SET) != 0, "fseek");

    write_32_le(buf, new_length-0x2c);
    bytes_written = fwrite(buf, 1, 4, infile);
    CHECK_FILE(bytes_written != 4, infile, "fwrite");

    /* append silence */
    long offset = old_length;

    write_16_le(buf, 0);
    write_16_le(buf+2, 0);

    CHECK_ERRNO(fseek(infile, offset, SEEK_SET) != 0, "fseek");

    while (offset < new_length)
    {
        bytes_written = fwrite(buf, 1, 4, infile);
        CHECK_FILE(bytes_written != 4, infile, "fwrite");

        offset += 4;
    }
}
Пример #2
0
uint32_t get_32_le(FILE *infile)
{
    unsigned char buf[4];
    size_t bytes_read = fread(buf, 1, 4, infile);
    CHECK_FILE(bytes_read != 4, infile, "fread");

    return read_32_le(buf);
}
Пример #3
0
int JVlibForm::read_id(void) {
    return read_32_le();
}
Пример #4
0
void analyze(FILE *infile, long file_length)
{
    unsigned char buf[4];

    /* read header */
    size_t bytes_read = fread(buf, 1, 4, infile);
    CHECK_FILE(bytes_read != 4, infile, "fread");

    /* check header */
    const char LARC_signature[4] = "LARC"; /* intentionally unterminated */
    CHECK_ERROR(memcmp(buf, LARC_signature, sizeof(LARC_signature)),"Missing LARC signature");

    /* get file count */
    bytes_read = fread(buf, 1, 4, infile);
    CHECK_FILE(bytes_read != 4, infile, "fread");
    uint32_t file_count = read_32_le(buf);
    
    printf("%d files\n", file_count);

    /* read file info */
    struct {
        char *name;
        uint32_t size;
        uint32_t offset;
    } *file_info = malloc(sizeof(file_info[0]) * file_count);
    CHECK_ERRNO(file_info == NULL, "malloc");
    for (int i=0; i<file_count; i++)
    {
        /* file name length */
        bytes_read = fread(buf, 1, 2, infile);
        CHECK_FILE(bytes_read != 2, infile, "fread");
        uint16_t name_length = read_16_le(buf);

        /* allocate for name */
        file_info[i].name = malloc(name_length + 1);
        CHECK_ERRNO(file_info[i].name == NULL, "malloc");

        /* load name */
        bytes_read = fread(file_info[i].name, 1, name_length, infile);
        CHECK_FILE(bytes_read != name_length, infile, "fread");
        file_info[i].name[name_length] = '\0';

        /* load size */
        bytes_read = fread(buf, 1, 4, infile);
        CHECK_FILE(bytes_read != 4, infile, "fread");
        file_info[i].size = read_32_le(buf);

        /* load offset */
        bytes_read = fread(buf, 1, 4, infile);
        CHECK_FILE(bytes_read != 4, infile, "fread");
        file_info[i].offset = read_32_le(buf);

    }

    long data_offset = ftell(infile);
    CHECK_ERRNO(data_offset == -1, "ftell");

    /* dump files */
    for (int i=0; i<file_count; i++)
    {
        long file_offset = data_offset + file_info[i].offset;
        printf("%02d: 0x%08" PRIx32 " 0x%08" PRIx32 " %s\n",
                i, (uint32_t)file_offset,
                file_info[i].size, file_info[i].name);
        
        FILE *outfile = fopen(file_info[i].name, "wb");
        CHECK_ERRNO(outfile == NULL, "fopen");

        dump(infile, outfile, file_offset, file_info[i].size);

        CHECK_ERRNO(fclose(outfile) == EOF, "fclose");
    }
}
Пример #5
0
int main(int argc, char ** argv) {
    if (argc != 3)
    {
        fprintf(stderr, "usage: hpi_hpb MORI5.HPI MORI5.HPB\n");
        return -1;
    }

    FILE * indexfile = fopen(argv[1], "rb");
    FILE * datafile  = fopen(argv[2], "rb");

    char * index_basename = copy_string(strip_path(argv[1]));
    {
        char * index_basename_ext = strrchr(index_basename, '.');
        CHECK_ERROR(index_basename_ext == NULL, "no extension on index?");
        *index_basename_ext = '\0';
    }

    CHECK_ERROR(get_32_be_seek(0, indexfile) != UINT32_C(0x48504948), "HPIH header missing");

    long index_file_size;
    uint8_t * const index_buf = get_whole_file(indexfile, &index_file_size);
    fclose(indexfile);
    indexfile = NULL;

    EXPECT_32_BE(index_buf+0x00, 0x48504948, "HPIH");
    EXPECT_32_LE(index_buf+0x04, 0,        "0 at 0x04");
    EXPECT_32_LE(index_buf+0x08, 0x10,     "0x10 at 0x08");
    EXPECT_32_LE(index_buf+0x0C, 0,        "0 at 0x0C");
    EXPECT_16_LE(index_buf+0x10, 0,        "0 at 0x10");
    EXPECT_16_LE(index_buf+0x12, 0x1000,   "0x1000 at 0x12");
    const uint32_t index_entries = read_16_le(index_buf + 0x12);
    const uint32_t index_size = index_entries * 4;
    const uint32_t entries = read_32_le(index_buf + 0x14);

    const uint32_t index_offset   = 0x18;
    const uint32_t entry_offset   = index_offset + index_size;
    const uint32_t strings_offset = entry_offset + entries * 0x10;

    CHECK_ERROR(strings_offset > index_file_size, "file is too small");

    //printf("Index:   %8"PRIx32"\n", index_offset);
    printf("Entries: %8"PRIx32"\n", entry_offset);
    printf("Strings: %8"PRIx32"\n", strings_offset);

    printf("  id    offset     size    type?    name\n");
    printf("----------------------------------------\n");
#if 0
    for (uint16_t ei = 0; ei < index_entries; ei ++)
    {
        const uint8_t * index_entry = index_buf + index_offset + ei*4;
        const uint16_t first_entry = read_16_le(index_entry + 0);
        const uint16_t last_entry =
            first_entry + read_16_le(index_entry + 4) - 1;

        CHECK_ERROR(last_entry >= entries, "entry out of range");

        printf("group %u\n", (unsigned int)ei);
#endif

        for (uint16_t j = 0; j < entries; j++)
        {
            const uint8_t * entry = index_buf + entry_offset + j*0x10;
            const uint32_t file_name_offset = strings_offset + read_32_le(entry+0x0);
            CHECK_ERROR(file_name_offset >= index_file_size, "string idx out of range"); 
            const uint8_t * file_name = index_buf + file_name_offset;
            const uint32_t hpb_offset = read_32_le(entry+0x4);
            const uint32_t hpb_size   = read_32_le(entry+0x8);
            const uint32_t hpb_type   = read_32_le(entry+0xc);

            printf("%4"PRIx16": %8"PRIx32" %8"PRIx32" %8"PRIx32"    %.*s\n",
                j, hpb_offset, hpb_size, hpb_type,
                (int)(index_file_size-file_name_offset), file_name);

            
            char * name_copy = copy_string((char*)file_name);
            char * dir_name = name_copy;
            char * file_name_base = strrchr(name_copy, '/');
            if (file_name_base == NULL)
            {
                file_name_base = name_copy;
                dir_name = "";
            }
            else
            {
                file_name_base[0] = '\0';
                file_name_base ++;
            }
            FILE * outfile = open_file_in_directory(index_basename, dir_name, '/', file_name_base, "wb");

            free(name_copy);

            dump(datafile, outfile, hpb_offset, hpb_size);

            CHECK_ERRNO(fclose(outfile) == EOF, "fclose output");
        }

#if 0
        printf("\n");
    }
#endif

    free(index_basename);

    fclose(datafile);
}