/* Write a directory entry */ static int vmfs_dirent_write(const vmfs_dirent_t *entry,u_char *buf) { write_le32(buf,VMFS_DIRENT_OFS_TYPE,entry->type); write_le32(buf,VMFS_DIRENT_OFS_BLK_ID,entry->block_id); write_le32(buf,VMFS_DIRENT_OFS_REC_ID,entry->record_id); memcpy(buf+VMFS_DIRENT_OFS_NAME,entry->name,VMFS_DIRENT_OFS_NAME_SIZE); return(0); }
/* Write a heartbeat info */ int vmfs_heartbeat_write(const vmfs_heartbeat_t *hb,u_char *buf) { write_le32(buf,VMFS_HB_OFS_MAGIC,hb->magic); write_le64(buf,VMFS_HB_OFS_POS,hb->pos); write_le64(buf,VMFS_HB_OFS_SEQ,hb->seq); write_le64(buf,VMFS_HB_OFS_UPTIME,hb->uptime); write_le32(buf,VMFS_HB_OFS_JOURNAL_BLK,hb->journal_blk); write_uuid(buf,VMFS_HB_OFS_UUID,&hb->uuid); return(0); }
CFilePacker::CFilePacker(u32 version, const char magic[4]) { // put header in our data array. // (its payloadSize_le will be updated on every Pack*() call) FileHeader header; strncpy(header.magic, magic, 4); // not 0-terminated => no _s write_le32(&header.version_le, version); write_le32(&header.payloadSize_le, 0); m_writeBuffer.Append(&header, sizeof(FileHeader)); }
/* Write a metadata header */ int vmfs_metadata_hdr_write(const vmfs_metadata_hdr_t *mdh,u_char *buf) { memset(buf,0,VMFS_METADATA_HDR_SIZE); write_le32(buf,VMFS_MDH_OFS_MAGIC,mdh->magic); write_le64(buf,VMFS_MDH_OFS_POS,mdh->pos); write_le64(buf,VMFS_MDH_OFS_HB_POS,mdh->hb_pos); write_le64(buf,VMFS_MDH_OFS_HB_SEQ,mdh->hb_seq); write_le64(buf,VMFS_MDH_OFS_OBJ_SEQ,mdh->obj_seq); write_le32(buf,VMFS_MDH_OFS_HB_LOCK,mdh->hb_lock); write_le64(buf,VMFS_MDH_OFS_MTIME,mdh->mtime); write_uuid(buf,VMFS_MDH_OFS_HB_UUID,&mdh->hb_uuid); return(0); }
static int relocate_patch_table(void *fsp, size_t size, size_t offset, ssize_t adjustment) { struct fsp_patch_table *table; size_t num; size_t num_entries; table = relative_offset(fsp, offset); if ((offset + sizeof(*table) > size) || (read_le16(&table->header_length) + offset) > size) { printk(BIOS_ERR, "FSPP not entirely contained in region.\n"); return -1; } num_entries = read_le32(&table->patch_entry_num); printk(FSP_DBG_LVL, "FSPP relocs: %zx\n", num_entries); for (num = 0; num < num_entries; num++) { uint32_t *reloc; uint32_t reloc_val; reloc = fspp_reloc(fsp, size, read_le32(&table->patch_entries[num])); if (reloc == NULL) { printk(BIOS_ERR, "Ignoring FSPP entry: %x\n", read_le32(&table->patch_entries[num])); continue; } reloc_val = read_le32(reloc); printk(FSP_DBG_LVL, "Adjusting %p %x -> %x\n", reloc, reloc_val, (unsigned int)(reloc_val + adjustment)); write_le32(reloc, reloc_val + adjustment); } return 0; }
int main() { output_file = fopen("output.wav", "wb"); if (!output_file) die_perror("failed to open file"); int samplerate = SAMPLE_RATE; int channels = 2; int bitspersample = 16; int datarate = samplerate * channels * (bitspersample / 8); int blockalign = channels * (bitspersample / 8); // write wav header output_write("RIFF", 4); long riff_len_pos = ftell(output_file); // need to write 36+datalen to riff_len_pos write_le32(0); output_write("WAVE", 4); output_write("fmt ", 4); write_le32(16); write_le16(1); write_le16(channels); write_le32(samplerate); write_le32(datarate); write_le16(blockalign); write_le16(bitspersample); output_write("data", 4); long wav_data_pos = ftell(output_file); // need to write datalen to wav_data_pos write_le32(0); int i; for (i = 0; i < 22050; i++) output_sample(0, 0); // write 500ms of silence write_pulse(1, 4909, 1000000); // command start write_pulse(0, 4320, 1000000); i = 0; unsigned code = 0xe0e040bf; for (i = 0; i < 32; i++) { int bit = (code >> (31 - i)) & 0x1; if (bit) { write_pulse(1, 818, 1000000); // 1 bit write_pulse(0, 1425, 1000000); } else { write_pulse(1, 818, 1000000); // 0 bit write_pulse(0, 325, 1000000); } } write_pulse(1, 717, 1000000); // command stop write_pulse(0, 717, 1000000); for (i = 0; i < 22050; i++) output_sample(0, 0); // write 500ms of silence fseek(output_file, riff_len_pos, SEEK_SET); write_le32(36 + datalen); fseek(output_file, wav_data_pos, SEEK_SET); write_le32(datalen); fclose(output_file); return 0; }
bool RageSurfaceUtils::SaveBMP( RageSurface *surface, RageFile &f ) { /* Convert the surface to 24bpp. */ RageSurface *converted_surface; converted_surface = CreateSurface( surface->w, surface->h, 24, Swap24LE( 0xFF0000 ), Swap24LE( 0x00FF00 ), Swap24LE( 0x0000FF ), 0 ); RageSurfaceUtils::CopySurface( surface, converted_surface ); RString sError; int iFilePitch = converted_surface->pitch; iFilePitch = (iFilePitch+3) & ~3; // round up a multiple of 4 int iDataSize = converted_surface->h * iFilePitch; const int iHeaderSize = 0x36; WriteBytes( f, sError, "BM", 2 ); write_le32( f, sError, iHeaderSize+iDataSize ); // size (offset 0x2) write_le32( f, sError, 0 ); // reserved (offset 0x6) write_le32( f, sError, iHeaderSize ); // bitmap offset (offset 0xA) write_le32( f, sError, 0x28 ); // header size (offset 0xE) write_le32( f, sError, surface->w ); // width (offset 0x14) write_le32( f, sError, surface->h ); // height (offset 0x18) write_le16( f, sError, 1 ); // planes (offset 0x1A) write_le16( f, sError, (uint16_t) converted_surface->fmt.BytesPerPixel*8 ); // bpp (offset 0x1C) write_le32( f, sError, 0 ); // compression (offset 0x1E) write_le32( f, sError, iDataSize ); // bitmap size (offset 0x22) write_le32( f, sError, 0 ); // horiz resolution (offset 0x26) write_le32( f, sError, 0 ); // vert resolution (offset 0x2A) write_le32( f, sError, 0 ); // colors (offset 0x2E) write_le32( f, sError, 0 ); // important colors (offset 0x32) for( int y = converted_surface->h-1; y >= 0; --y ) { const uint8_t *pRow = converted_surface->pixels + converted_surface->pitch*y; WriteBytes( f, sError, pRow, converted_surface->pitch ); /* Pad the row to the pitch. */ uint8_t padding[4] = { 0,0,0,0 }; WriteBytes( f, sError, padding, iFilePitch-converted_surface->pitch ); } delete converted_surface; if( sError.size() != 0 ) return false; if( f.Flush() == -1 ) return false; return true; }
static ssize_t relocate_remaining_items(void *fsp, size_t size, uintptr_t new_addr, size_t fih_offset) { EFI_FFS_FILE_HEADER *ffsfh; EFI_COMMON_SECTION_HEADER *csh; FSP_INFO_HEADER *fih; ssize_t adjustment; size_t offset; printk(FSP_DBG_LVL, "FSP_INFO_HEADER offset is %zx\n", fih_offset); if (fih_offset == 0) { printk(BIOS_ERR, "FSP_INFO_HEADER offset is 0.\n"); return -1; } /* FSP_INFO_HEADER at first file in FV within first RAW section. */ ffsfh = relative_offset(fsp, fih_offset); fih_offset += file_section_offset(ffsfh); csh = relative_offset(fsp, fih_offset); fih_offset += section_data_offset(csh); fih = relative_offset(fsp, fih_offset); if (guid_compare(&ffsfh->Name, &fih_guid)) { printk(BIOS_ERR, "Bad FIH GUID.\n"); return -1; } if (read_le8(&csh->Type) != EFI_SECTION_RAW) { printk(BIOS_ERR, "FIH file should have raw section: %x\n", read_le8(&csh->Type)); return -1; } if (read_le32(&fih->Signature) != FSP_SIG) { printk(BIOS_ERR, "Unexpected FIH signature: %08x\n", read_le32(&fih->Signature)); return -1; } adjustment = (intptr_t)new_addr - read_le32(&fih->ImageBase); /* Update ImageBase to reflect FSP's new home. */ write_le32(&fih->ImageBase, adjustment + read_le32(&fih->ImageBase)); /* Need to find patch table and adjust each entry. The tables * following FSP_INFO_HEADER have a 32-bit signature and header * length. The patch table is denoted as having a 'FSPP' signature; * the table format doesn't follow the other tables. */ offset = fih_offset + read_le32(&fih->HeaderLength); while (offset + 2 * sizeof(uint32_t) <= size) { uint32_t *table_headers; table_headers = relative_offset(fsp, offset); printk(FSP_DBG_LVL, "Checking offset %zx for 'FSPP'\n", offset); if (read_le32(&table_headers[0]) != FSPP_SIG) { offset += read_le32(&table_headers[1]); continue; } if (relocate_patch_table(fsp, size, offset, adjustment)) { printk(BIOS_ERR, "FSPP relocation failed.\n"); return -1; } return fih_offset; } printk(BIOS_ERR, "Could not find the FSP patch table.\n"); return -1; }
static int te_relocate(uintptr_t new_addr, void *te) { EFI_TE_IMAGE_HEADER *teih; EFI_IMAGE_DATA_DIRECTORY *relocd; EFI_IMAGE_BASE_RELOCATION *relocb; uintptr_t image_base; size_t fixup_offset; size_t num_relocs; uint16_t *reloc; size_t relocd_offset; uint8_t *te_base; uint32_t adj; teih = te; if (read_le16(&teih->Signature) != EFI_TE_IMAGE_HEADER_SIGNATURE) { printk(BIOS_ERR, "TE Signature mismatch: %x vs %x\n", read_le16(&teih->Signature), EFI_TE_IMAGE_HEADER_SIGNATURE); return -1; } /* * A TE image is created by converting a PE file. Because of this * the offsets within the headers are off. In order to calculate * the correct releative offets one needs to subtract fixup_offset * from the encoded offets. Similarly, the linked address of the * program is found by adding the fixup_offset to the ImageBase. */ fixup_offset = read_le16(&teih->StrippedSize); fixup_offset -= sizeof(EFI_TE_IMAGE_HEADER); /* Keep track of a base that is correctly adjusted so that offsets * can be used directly. */ te_base = te; te_base -= fixup_offset; image_base = read_le64(&teih->ImageBase); adj = new_addr - (image_base + fixup_offset); printk(FSP_DBG_LVL, "TE Image %p -> %p adjust value: %x\n", (void *)image_base, (void *)new_addr, adj); /* Adjust ImageBase for consistency. */ write_le64(&teih->ImageBase, (uint32_t)(image_base + adj)); relocd = &teih->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC]; relocd_offset = 0; /* Though the field name is VirtualAddress it's actually relative to * the beginning of the image which is linked at ImageBase. */ relocb = relative_offset(te, read_le32(&relocd->VirtualAddress) - fixup_offset); while (relocd_offset < read_le32(&relocd->Size)) { size_t rva_offset = read_le32(&relocb->VirtualAddress); printk(FSP_DBG_LVL, "Relocs for RVA offset %zx\n", rva_offset); num_relocs = read_le32(&relocb->SizeOfBlock) - sizeof(*relocb); num_relocs /= sizeof(uint16_t); reloc = relative_offset(relocb, sizeof(*relocb)); printk(FSP_DBG_LVL, "Num relocs in block: %zx\n", num_relocs); while (num_relocs > 0) { uint16_t reloc_val = read_le16(reloc); int type = reloc_type(reloc_val); size_t offset = reloc_offset(reloc_val); printk(FSP_DBG_LVL, "reloc type %x offset %zx\n", type, offset); if (type == EFI_IMAGE_REL_BASED_HIGHLOW) { uint32_t *reloc_addr; uint32_t val; offset += rva_offset; reloc_addr = (void *)&te_base[offset]; val = read_le32(reloc_addr); printk(FSP_DBG_LVL, "Adjusting %p %x -> %x\n", reloc_addr, val, val + adj); write_le32(reloc_addr, val + adj); } else if (type != EFI_IMAGE_REL_BASED_ABSOLUTE) { printk(BIOS_ERR, "Unknown reloc type: %x\n", type); return -1; } num_relocs--; reloc++; } /* Track consumption of relocation directory contents. */ relocd_offset += read_le32(&relocb->SizeOfBlock); /* Get next relocation block to process. */ relocb = relative_offset(relocb, read_le32(&relocb->SizeOfBlock)); } return 0; }
unsigned long fw_cfg_acpi_tables(unsigned long start) { BiosLinkerLoaderEntry *s; unsigned long *addrs, current; uint8_t *ptr; int rc, i, j, src, dst, max; rc = fw_cfg_check_file("etc/table-loader"); if (rc < 0) return 0; printk(BIOS_DEBUG, "QEMU: found ACPI tables in fw_cfg.\n"); max = rc / sizeof(*s); s = malloc(rc); addrs = malloc(max * sizeof(*addrs)); fw_cfg_load_file("etc/table-loader", s); current = start; for (i = 0; i < max && s[i].command != 0; i++) { void *cksum_data; uint32_t cksum; uint32_t addr4; uint64_t addr8; switch (s[i].command) { case BIOS_LINKER_LOADER_COMMAND_ALLOCATE: current = ALIGN(current, s[i].alloc.align); rc = fw_cfg_check_file(s[i].alloc.file); if (rc < 0) goto err; printk(BIOS_DEBUG, "QEMU: loading \"%s\" to 0x%lx (len %d)\n", s[i].alloc.file, current, rc); fw_cfg_load_file(s[i].alloc.file, (void*)current); addrs[i] = current; current += rc; break; case BIOS_LINKER_LOADER_COMMAND_ADD_POINTER: src = -1; dst = -1; for (j = 0; j < i; j++) { if (s[j].command != BIOS_LINKER_LOADER_COMMAND_ALLOCATE) continue; if (strcmp(s[j].alloc.file, s[i].pointer.dest_file) == 0) dst = j; if (strcmp(s[j].alloc.file, s[i].pointer.src_file) == 0) src = j; } if (src == -1 || dst == -1) goto err; switch (s[i].pointer.size) { case 4: ptr = (uint8_t *)addrs[dst]; ptr += s[i].pointer.offset; addr4 = read_le32(ptr); addr4 += addrs[src]; write_le32(ptr, addr4); break; case 8: ptr = (uint8_t *)addrs[dst]; ptr += s[i].pointer.offset; addr8 = read_le64(ptr); addr8 += addrs[src]; write_le64(ptr, addr8); break; default: /* * Should not happen. ACPI knows 1 and 2 byte ptrs * too, but we are operating with 32bit offsets which * would simply not fit in there ... */ printk(BIOS_DEBUG, "QEMU: acpi: unimplemented ptr size %d\n", s[i].pointer.size); goto err; } break; case BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM: dst = -1; for (j = 0; j < i; j++) { if (s[j].command != BIOS_LINKER_LOADER_COMMAND_ALLOCATE) continue; if (strcmp(s[j].alloc.file, s[i].cksum.file) == 0) dst = j; } if (dst == -1) goto err; ptr = (uint8_t *)(addrs[dst] + s[i].cksum.offset); cksum_data = (void *)(addrs[dst] + s[i].cksum.start); cksum = acpi_checksum(cksum_data, s[i].cksum.length); write_le8(ptr, cksum); break; default: printk(BIOS_DEBUG, "QEMU: acpi: unknown script cmd 0x%x @ %p\n", s[i].command, s+i); goto err; }; } printk(BIOS_DEBUG, "QEMU: loaded ACPI tables from fw_cfg.\n"); free(s); free(addrs); return ALIGN(current, 16); err: printk(BIOS_DEBUG, "QEMU: loading ACPI tables from fw_cfg failed.\n"); free(s); free(addrs); return 0; }
static int cmd_remove(vmfs_fs_t *fs,int argc,char *argv[]) { /* Dangerous */ vmfs_lvm_t *lvm = (vmfs_lvm_t *)fs->dev; vmfs_volume_t *extent; DECL_ALIGNED_BUFFER(buf,512); vmfs_bitmap_entry_t entry; uint32_t i, blocks_per_segment, items_per_area, items_in_last_entry, old_area_count; fprintf(stderr, "Extents removal is experimental ! Use at your own risk !\n"); while (1) { char *answer = local_readline("Are you sure you want to go further? [y/N] "); char a = answer[0]; char null = answer[1]; free(answer); if ((a == 0) || ((tolower(a) == 'n') && (null == 0))) return(2); if ((tolower(a) == 'y') && (null == 0)) break; } if (lvm->lvm_info.num_extents == 1) { fprintf(stderr, "Can't remove an extent when there is only one\n"); return(1); } /* Get last extent */ extent = lvm->extents[lvm->loaded_extents - 1]; /* Check whether data blocks are used on the last extents */ blocks_per_segment = VMFS_LVM_SEGMENT_SIZE / vmfs_fs_get_blocksize(fs); for (i = extent->vol_info.first_segment * blocks_per_segment; i < extent->vol_info.last_segment * blocks_per_segment; i++) if (vmfs_block_get_status(fs, VMFS_BLK_FB_BUILD(i, 0))) { fprintf(stderr, "There is data on the last extent ; can't remove it\n"); return(1); } /* At filesystem level, only the FBB needs to be downsized */ fs->fbb->bmh.total_items -= extent->vol_info.num_segments * blocks_per_segment; items_per_area = fs->fbb->bmh.items_per_bitmap_entry * fs->fbb->bmh.bmp_entries_per_area; old_area_count = fs->fbb->bmh.area_count; fs->fbb->bmh.area_count = (fs->fbb->bmh.total_items + items_per_area - 1) / items_per_area; memset(buf, 0, buf_len); vmfs_bmh_write(&fs->fbb->bmh, buf); /* TODO: Error handling */ vmfs_file_pwrite(fs->fbb->f, buf, buf_len, 0); /* Adjust new last entry */ if ((items_in_last_entry = fs->fbb->bmh.total_items % fs->fbb->bmh.items_per_bitmap_entry)) { vmfs_bitmap_get_entry(fs->fbb, 0, fs->fbb->bmh.total_items, &entry); entry.free -= entry.total - items_in_last_entry; entry.total = items_in_last_entry; if (entry.ffree > entry.total) entry.ffree = 0; /* Adjust bitmap in last entry */ if (items_in_last_entry % 8) entry.bitmap[items_in_last_entry / 8] &= 0xff << (8 - (items_in_last_entry % 8)); memset(&entry.bitmap[(items_in_last_entry + 7) / 8], 0, (fs->fbb->bmh.items_per_bitmap_entry - items_in_last_entry - 7) / 8); vmfs_bme_update(fs, &entry); } /* Truncate the fbb file depending on the new area count */ if (old_area_count != fs->fbb->bmh.area_count) vmfs_file_truncate(fs->fbb->f, fs->fbb->bmh.hdr_size + fs->fbb->bmh.area_count * fs->fbb->bmh.area_size); /* Adjust entries after the new last one */ for (i = fs->fbb->bmh.total_items + (items_in_last_entry ? (fs->fbb->bmh.items_per_bitmap_entry - items_in_last_entry) : 0); i < fs->fbb->bmh.area_count * items_per_area; i += fs->fbb->bmh.items_per_bitmap_entry) { uint64_t pos; vmfs_bitmap_get_entry(fs->fbb, 0, i, &entry); pos = entry.mdh.pos; memset(&entry, 0, sizeof(entry)); vmfs_device_write(fs->dev, pos, (u_char *)&entry, sizeof(entry)); } /* At LVM level, all extents need to have the LVM information updated */ for (i = 0; i < lvm->loaded_extents - 1; i++) { lvm->extents[i]->vol_info.blocks -= extent->vol_info.num_segments + 1; lvm->extents[i]->vol_info.num_extents--; lvm->extents[i]->vol_info.lvm_size = (lvm->extents[i]->vol_info.blocks - lvm->extents[i]->vol_info.num_extents) * VMFS_LVM_SEGMENT_SIZE; /* Until there is an API for that, do it by hand */ m_pread(lvm->extents[i]->fd,buf,buf_len, lvm->extents[i]->vmfs_base + VMFS_LVMINFO_OFFSET); write_le64(buf, VMFS_LVMINFO_OFS_SIZE - VMFS_LVMINFO_OFFSET, lvm->extents[i]->vol_info.lvm_size); write_le64(buf, VMFS_LVMINFO_OFS_BLKS - VMFS_LVMINFO_OFFSET, lvm->extents[i]->vol_info.blocks); write_le32(buf, VMFS_LVMINFO_OFS_NUM_EXTENTS - VMFS_LVMINFO_OFFSET, lvm->extents[i]->vol_info.num_extents); m_pwrite(lvm->extents[i]->fd,buf,buf_len, lvm->extents[i]->vmfs_base + VMFS_LVMINFO_OFFSET); } return(0); }