uae_u32 zfile_crc32 (struct zfile *f) { uae_u8 *p; int pos, size; uae_u32 crc; if (!f) return 0; if (f->data) return get_crc32 (f->data, f->size); pos = zfile_ftell (f); zfile_fseek (f, 0, SEEK_END); size = zfile_ftell (f); p = xmalloc (size); if (!p) return 0; memset (p, 0, size); zfile_fseek (f, 0, SEEK_SET); zfile_fread (p, 1, size, f); zfile_fseek (f, pos, SEEK_SET); crc = get_crc32 (p, size); free (p); return crc; }
u8 *translateTree(AST *tree) { FILE *fp = NULL; u16 i, j, k; u8 *bin = NULL; u32 binlen; fp = tmpfile(); if (fp == NULL) return NULL; put_u32(0, fp); put_u32(0, fp); for (i = 0; i < tree->ngames; i++) { putFireStr(toFireStr(tree->games[i].s), fp); put_u16(tree->games[i].ncheats, fp); for (j = 0; j < tree->games[i].ncheats; j++) { putFireStr(toFireStr(tree->games[i].cheats[j].s), fp); put_u16(tree->games[i].cheats[j].ncodes, fp); for (k = 0; k < tree->games[i].cheats[j].ncodes; k++) { put_u32(tree->games[i].cheats[j].codes[2 * k], fp); put_u32(tree->games[i].cheats[j].codes[(2 * k) + 1], fp); } } } put_u32(BIN_MKR_EOF, fp); binlen = ftell(fp); bin = (u8*) readFromFile(fp, 0, binlen); if (bin == NULL) return NULL; fclose(fp); // Delete temporary file *(u32*) &bin[0] = binlen - 8; *(u32*) &bin[4] = get_crc32(bin + 8, binlen - 8); return bin; }
static uint32_t ut_do_crc32(void *data, uint32_t length) { uint32_t crc = 0; crc = get_crc32(crc, (char*)data, length); return crc; }
list_part_t *read_part_gpt(disk_t *disk_car, const int verbose, const int saveheader) { struct gpt_hdr *gpt; struct gpt_ent* gpt_entries; list_part_t *new_list_part=NULL; unsigned int i; uint32_t gpt_entries_size; uint64_t gpt_entries_offset; gpt=(struct gpt_hdr*)MALLOC(disk_car->sector_size); screen_buffer_reset(); if((unsigned)disk_car->pread(disk_car, gpt, disk_car->sector_size, disk_car->sector_size) != disk_car->sector_size) { free(gpt); return NULL; } if(memcmp(gpt->hdr_sig, GPT_HDR_SIG, 8)!=0) { screen_buffer_add("Bad GPT partition, invalid signature.\n"); free(gpt); return NULL; } if(verbose>0) { log_info("hdr_size=%llu\n", (long long unsigned)le32(gpt->hdr_size)); log_info("hdr_lba_self=%llu\n", (long long unsigned)le64(gpt->hdr_lba_self)); log_info("hdr_lba_alt=%llu (expected %llu)\n", (long long unsigned)le64(gpt->hdr_lba_alt), (long long unsigned)((disk_car->disk_size-1)/disk_car->sector_size)); log_info("hdr_lba_start=%llu\n", (long long unsigned)le64(gpt->hdr_lba_start)); log_info("hdr_lba_end=%llu\n", (long long unsigned)le64(gpt->hdr_lba_end)); log_info("hdr_lba_table=%llu\n", (long long unsigned)le64(gpt->hdr_lba_table)); log_info("hdr_entries=%llu\n", (long long unsigned)le32(gpt->hdr_entries)); log_info("hdr_entsz=%llu\n", (long long unsigned)le32(gpt->hdr_entsz)); } /* Check header size */ if(le32(gpt->hdr_size)<92 || le32(gpt->hdr_size) > disk_car->sector_size) { screen_buffer_add("GPT: invalid header size.\n"); free(gpt); return NULL; } { /* CRC check */ uint32_t crc; uint32_t origcrc; origcrc=le32(gpt->hdr_crc_self); gpt->hdr_crc_self=le32(0); crc=get_crc32(gpt, le32(gpt->hdr_size), 0xFFFFFFFF)^0xFFFFFFFF; if(crc!=origcrc) { screen_buffer_add("Bad GPT partition, invalid header checksum.\n"); free(gpt); return NULL; } gpt->hdr_crc_self=le32(origcrc); } if(le64(gpt->hdr_lba_self)!=1) { screen_buffer_add("Bad GPT partition, invalid LBA self location.\n"); free(gpt); return NULL; } if(le64(gpt->hdr_lba_start) >= le64(gpt->hdr_lba_end)) { screen_buffer_add("Bad GPT partition, invalid LBA start/end location.\n"); free(gpt); return NULL; } if(le32(gpt->hdr_revision)!=GPT_HDR_REVISION) { screen_buffer_add("GPT: Warning - not revision 1.0\n"); } if(le32(gpt->__reserved)!=0) { screen_buffer_add("GPT: Warning - __reserved!=0\n"); } if(le32(gpt->hdr_entries)==0 || le32(gpt->hdr_entries)>4096) { screen_buffer_add("GPT: invalid number (%u) of partition entries.\n", (unsigned int)le32(gpt->hdr_entries)); free(gpt); return NULL; } /* le32(gpt->hdr_entsz)==128 */ if(le32(gpt->hdr_entsz)%8!=0 || le32(gpt->hdr_entsz)<128 || le32(gpt->hdr_entsz)>4096) { screen_buffer_add("GPT: invalid partition entry size.\n"); free(gpt); return NULL; } gpt_entries_size=le32(gpt->hdr_entries) * le32(gpt->hdr_entsz); if(gpt_entries_size<16384) { screen_buffer_add("GPT: A minimum of 16,384 bytes of space must be reserved for the GUID Partition Entry array.\n"); free(gpt); return NULL; } gpt_entries_offset=(uint64_t)le64(gpt->hdr_lba_table) * disk_car->sector_size; if((uint64_t) le64(gpt->hdr_lba_self) + le32(gpt->hdr_size) - 1 >= gpt_entries_offset || gpt_entries_offset >= le64(gpt->hdr_lba_start) * disk_car->sector_size) { screen_buffer_add( "GPT: The primary GUID Partition Entry array must be located after the primary GUID Partition Table Header and end before the FirstUsableLBA.\n"); free(gpt); return NULL; } gpt_entries=(struct gpt_ent*)MALLOC(gpt_entries_size); if((unsigned)disk_car->pread(disk_car, gpt_entries, gpt_entries_size, gpt_entries_offset) != gpt_entries_size) { free(gpt_entries); free(gpt); return new_list_part; } { /* CRC check */ uint32_t crc; crc=get_crc32(gpt_entries, gpt_entries_size, 0xFFFFFFFF)^0xFFFFFFFF; if(crc!=le32(gpt->hdr_crc_table)) { screen_buffer_add("Bad GPT partition entries, invalid checksum.\n"); free(gpt_entries); free(gpt); return NULL; } } for(i=0;i<le32(gpt->hdr_entries);i++) { const struct gpt_ent* gpt_entry; gpt_entry=(const struct gpt_ent*)((const char*)gpt_entries + (unsigned long)i*le32(gpt->hdr_entsz)); if(guid_cmp(gpt_entry->ent_type, GPT_ENT_TYPE_UNUSED)!=0 && le64(gpt_entry->ent_lba_start) < le64(gpt_entry->ent_lba_end)) { int insert_error=0; partition_t *new_partition=partition_new(&arch_gpt); new_partition->order=i+1; guid_cpy(&new_partition->part_uuid, &gpt_entry->ent_uuid); guid_cpy(&new_partition->part_type_gpt, &gpt_entry->ent_type); new_partition->part_offset=(uint64_t)le64(gpt_entry->ent_lba_start)*disk_car->sector_size; new_partition->part_size=(uint64_t)(le64(gpt_entry->ent_lba_end) - le64(gpt_entry->ent_lba_start)+1) * disk_car->sector_size; new_partition->status=STATUS_PRIM; UCSle2str(new_partition->partname, (const uint16_t *)&gpt_entry->ent_name, sizeof(gpt_entry->ent_name)/2); new_partition->arch->check_part(disk_car,verbose,new_partition,saveheader); /* log_debug("%u ent_attr %08llx\n", new_partition->order, (long long unsigned)le64(gpt_entry->ent_attr)); */ aff_part_buffer(AFF_PART_ORDER|AFF_PART_STATUS,disk_car,new_partition); new_list_part=insert_new_partition(new_list_part, new_partition, 0, &insert_error); if(insert_error>0) free(new_partition); } } /* TODO: The backup GUID Partition Entry array must be located after the LastUsableLBA and end before the backup GUID Partition Table Header. */ free(gpt_entries); free(gpt); return new_list_part; }
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; }
int write_part_gpt(disk_t *disk_car, const list_part_t *list_part, const int ro, const int verbose) { struct gpt_hdr *gpt; struct gpt_ent* gpt_entries; const list_part_t *element; const unsigned int hdr_entries=128; const unsigned int gpt_entries_size=hdr_entries*sizeof(struct gpt_ent); if(ro>0) return 0; gpt_entries=(struct gpt_ent*)MALLOC(gpt_entries_size); for(element=list_part;element!=NULL;element=element->next) { if(element->part->order > 0 && element->part->order <= hdr_entries) { partition_generate_gpt_entry(&gpt_entries[element->part->order-1], element->part, disk_car); } } gpt=(struct gpt_hdr*)MALLOC(disk_car->sector_size); memcpy(gpt->hdr_sig, GPT_HDR_SIG, 8); gpt->hdr_revision=le32(GPT_HDR_REVISION); gpt->hdr_size=le32(92); gpt->hdr_entries=le32(hdr_entries); gpt->hdr_entsz=le32(sizeof(struct gpt_ent)); gpt->__reserved=le32(0); gpt->hdr_lba_start=le64(1 + gpt_entries_size/disk_car->sector_size + 1); gpt->hdr_lba_end=le64((disk_car->disk_size-1 - gpt_entries_size)/disk_car->sector_size - 1); efi_generate_uuid(&gpt->hdr_guid); gpt->hdr_crc_table=le32(get_crc32(gpt_entries, gpt_entries_size, 0xFFFFFFFF)^0xFFFFFFFF); gpt->hdr_lba_self=le64(1); gpt->hdr_lba_alt=le64((disk_car->disk_size-1)/disk_car->sector_size); gpt->hdr_lba_table=le64(1+1); gpt->hdr_crc_self=le32(0); gpt->hdr_crc_self=le32(get_crc32(gpt, le32(gpt->hdr_size), 0xFFFFFFFF)^0xFFFFFFFF); if((unsigned)disk_car->pwrite(disk_car, gpt_entries, gpt_entries_size, le64(gpt->hdr_lba_table) * disk_car->sector_size) != gpt_entries_size) { free(gpt); free(gpt_entries); return 1; } if((unsigned)disk_car->pwrite(disk_car, gpt, disk_car->sector_size, le64(gpt->hdr_lba_self) * disk_car->sector_size) != disk_car->sector_size) { free(gpt); free(gpt_entries); return 1; } gpt->hdr_lba_self=le64((disk_car->disk_size-1)/disk_car->sector_size); gpt->hdr_lba_alt=le64(1); gpt->hdr_lba_table=le64((disk_car->disk_size-1 - gpt_entries_size)/disk_car->sector_size); gpt->hdr_crc_self=le32(0); gpt->hdr_crc_self=le32(get_crc32(gpt, le32(gpt->hdr_size), 0xFFFFFFFF)^0xFFFFFFFF); if((unsigned)disk_car->pwrite(disk_car, gpt_entries, gpt_entries_size, le64(gpt->hdr_lba_table) * disk_car->sector_size) != gpt_entries_size) { free(gpt); free(gpt_entries); return 1; } if((unsigned)disk_car->pwrite(disk_car, gpt, disk_car->sector_size, le64(gpt->hdr_lba_self) * disk_car->sector_size) != disk_car->sector_size) { free(gpt); free(gpt_entries); return 1; } free(gpt); free(gpt_entries); write_part_gpt_i386(disk_car, list_part); disk_car->sync(disk_car); return 0; }