int get_block_n(int n) { partition_map * entry; int rtn_value; if (the_map != NULL) { entry = find_entry_by_disk_address(n, the_map); if (entry != 0) { mb = entry->data; rtn_value = 1; } else { rtn_value = 0; } } else { if (read_media(the_media, ((long long) n) * g, PBLOCK_SIZE, (void *)buffer) == 0) { rtn_value = 0; } else { mb = (DPME *) buffer; convert_dpme(mb, 1); rtn_value = 1; } } return rtn_value; }
int read_block(partition_map_header *map, unsigned long num, char *buf) { //printf("read block %d\n", num); return read_media(map->m, ((long long) num) * map->logical_block, PBLOCK_SIZE, (void *)buf); }
int read_block(partition_map_header *map, unsigned long num, char *buf, int quiet) { int f; f = map->logical_block / PBLOCK_SIZE; return read_media(map->fd, num*f, buf, quiet); }
// // Routines // int get_block_zero(void) { int rtn_value; if (the_map != NULL) { b0 = the_map->misc; rtn_value = 1; } else { if (read_media(the_media, (long long) 0, PBLOCK_SIZE, buffer) == 0) { rtn_value = 0; } else { b0 = (Block0 *) buffer; convert_block0(b0, 1); rtn_value = 1; } } return rtn_value; }
int read_partition_block(partition_map *entry, unsigned long num, char *buf) { DPME *data; partition_map_header * map; u32 base; u64 offset; map = entry->the_map; data = entry->data; base = data->dpme_pblock_start; if (num >= data->dpme_pblocks) { return 0; } offset = ((long long) base) * map->logical_block + num * 512; return read_media(map->m, offset, 512, (void *)buf); }
long write_deblock_media(MEDIA m, long long offset, unsigned long count, void *address) { DEBLOCK_MEDIA a; long rtn_value; unsigned long next_size; unsigned long partial_offset; unsigned long partial_count; long long cur_offset; unsigned long remainder; unsigned char *addr; a = (DEBLOCK_MEDIA) m; rtn_value = 0; if (a == 0) { /* no media */ } else if (a->m.kind != deblock_info.kind) { /* wrong kind - XXX need to error here - this is an internal problem */ } else if (count <= 0 || count % a->m.grain != 0) { /* can't handle size */ } else if (offset < 0 || offset % a->m.grain != 0) { /* can't handle offset */ } else if (a->need_filtering == 0) { rtn_value = write_media(a->next_media, offset, count, address); } else { next_size = a->next_block_size; addr = address; cur_offset = offset; remainder = count; rtn_value = 1; /* write partial */ partial_offset = cur_offset % next_size; if (partial_offset != 0) { partial_count = next_size - partial_offset; if (partial_count > remainder) { partial_count = remainder; } rtn_value = read_media(a->next_media, cur_offset - partial_offset, next_size, a->buffer); if (rtn_value != 0) { memcpy (a->buffer + partial_offset, addr, partial_count); rtn_value = write_media(a->next_media, cur_offset - partial_offset, next_size, a->buffer); addr += partial_count; cur_offset += partial_count; remainder -= partial_count; } } /* write fulls as long as needed */ if (rtn_value != 0 && remainder > next_size) { partial_count = remainder - (remainder % next_size); rtn_value = write_media(a->next_media, cur_offset, partial_count, addr); addr += partial_count; cur_offset += partial_count; remainder -= partial_count; } /* write partial */ if (rtn_value != 0 && remainder > 0) { partial_count = remainder; rtn_value = read_media(a->next_media, cur_offset, next_size, a->buffer); if (rtn_value != 0) { memcpy (a->buffer, addr, partial_count); rtn_value = write_media(a->next_media, cur_offset, next_size, a->buffer); } } } /* recompute size to handle file media */ a->m.size_in_bytes = media_total_size(a->next_media); return rtn_value; }
void display_patches(partition_map *entry) { long long offset; MEDIA m; static uint8_t *patch_block; PatchListPtr p; PatchDescriptorPtr q; uint8_t *next; uint8_t *s; int i; offset = entry->data->dpme_pblock_start; m = entry->the_map->m; offset = ((long long) entry->data->dpme_pblock_start) * entry->the_map->logical_block; if (patch_block == NULL) { patch_block = (uint8_t *) malloc(PBLOCK_SIZE); if (patch_block == NULL) { error(errno, "can't allocate memory for patch block buffer"); return; } } if (read_media(m, (long long)offset, PBLOCK_SIZE, (char *)patch_block) == 0) { error(errno, "Can't read patch block"); return; } p = (PatchListPtr) patch_block; if (p->numPatchBlocks != 1) { i = p->numPatchBlocks; free(patch_block); patch_block = (uint8_t *) malloc(PBLOCK_SIZE*i); if (patch_block == NULL) { error(errno, "can't allocate memory for patch blocks buffer"); return; } s = patch_block + PBLOCK_SIZE*i; while (i > 0) { s -= PBLOCK_SIZE; i -= 1; if (read_media(m, offset+i, PBLOCK_SIZE, (char *)s) == 0) { error(errno, "Can't read patch block %d", i); return; } } p = (PatchListPtr) patch_block; } printf("Patch list (%d entries)\n", p->numPatches); q = p->thePatch; for (i = 0; i < p->numPatches; i++) { printf("%2d signature: '%.4s'\n", i+1, (char *)&q->patchSig); printf(" version: %d.%d\n", q->majorVers, q->minorVers); printf(" flags: 0x%"PRIx32"\n", q->flags); printf(" offset: %"PRId32"\n", q->patchOffset); printf(" size: %"PRId32"\n", q->patchSize); printf(" CRC: 0x%"PRIx32"\n", q->patchCRC); printf(" name: '%.*s'\n", q->patchName[0], &q->patchName[1]); printf(" vendor: '%.*s'\n", q->patchVendor[0], &q->patchVendor[1]); next = ((uint8_t *)q) + q->patchDescriptorLen; s = &q->patchVendor[q->patchVendor[0]+1]; if (next > s) { printf("remainder of entry -"); dump_block(s, next-s); } q = (PatchDescriptorPtr)next; } }
// // Routines // partition_map_header * open_partition_map(char *name, int *valid_file, int ask_logical_size) { media *fd; partition_map_header * map; int writeable; #ifdef __linux__ struct stat info; #endif int size; fd = open_media(name, (rflag)?O_RDONLY:O_RDWR); if (fd == 0) { fd = open_media(name, O_RDONLY); if (fd == 0) { error(errno, "can't open file '%s'", name); *valid_file = 0; return NULL; } else { writeable = 0; } } else { writeable = 1; } *valid_file = 1; map = (partition_map_header *) malloc(sizeof(partition_map_header)); if (map == NULL) { error(errno, "can't allocate memory for open partition map"); close_media(fd); return NULL; } map->fd = fd; map->name = name; map->writeable = (rflag)?0:writeable; map->changed = 0; map->disk_order = NULL; map->base_order = NULL; map->physical_block = fd->block_size; /* preflight */ map->misc = (Block0 *) malloc(PBLOCK_SIZE); if (map->misc == NULL) { error(errno, "can't allocate memory for block zero buffer"); close_media(map->fd); free(map); return NULL; } else if (read_media(map->fd, 0, (char *)map->misc, 0) == 0 || convert_block0(map->misc, 1) || coerce_block0(map)) { // if I can't read block 0 I might as well give up close_partition_map(map); return NULL; } map->physical_block = map->misc->sbBlkSize; // printf("physical block size is %d\n", map->physical_block); if (ask_logical_size && interactive) { size = PBLOCK_SIZE; printf("A logical block is %d bytes: ", size); flush_to_newline(0); get_number_argument("what should be the logical block size? ", (long *)&size, size); map->logical_block = (size / PBLOCK_SIZE) * PBLOCK_SIZE; } else { map->logical_block = PBLOCK_SIZE; } if (map->logical_block > MAXIOSIZE) { map->logical_block = MAXIOSIZE; } if (map->logical_block > map->physical_block) { map->physical_block = map->logical_block; } map->blocks_in_map = 0; map->maximum_in_map = -1; map->media_size = compute_device_size(map, map); sync_device_size(map); #ifdef __linux__ if (fstat(fd, &info) < 0) { error(errno, "can't stat file '%s'", name); map->regular_file = 0; } else { map->regular_file = S_ISREG(info.st_mode); } #else map->regular_file = 0; #endif if (read_partition_map(map) < 0) { // some sort of failure reading the map } else { // got it! ; return map; } close_partition_map(map); return NULL; }
void do_display_block(partition_map_header *map, char *alt_name) { MEDIA m; long number; char *name; static unsigned char *display_block; static int display_g; int g; static long next_number = -1; if (map != NULL) { name = 0; m = map->m; g = map->logical_block; } else { if (alt_name == 0) { if (get_string_argument("Name of device: ", &name, 1) == 0) { bad_input("Bad name"); return; } } else { name = strdup(alt_name); } m = open_pathname_as_media(name, O_RDONLY); if (m == 0) { error(errno, "can't open file '%s'", name); free(name); return; } g = media_granularity(m); if (g < PBLOCK_SIZE) { g = PBLOCK_SIZE; } } if (get_number_argument("Block number: ", &number, next_number) == 0) { bad_input("Bad block number"); goto xit; } if (display_block == NULL || display_g < g) { if (display_block != NULL) { free(display_block); display_g = 0; } display_block = (unsigned char *) malloc(g); if (display_block == NULL) { error(errno, "can't allocate memory for display block buffer"); goto xit; } display_g = g; } if (read_media(m, ((long long)number) * g, g, (char *)display_block) != 0) { printf("block %ld -", number); dump_block((unsigned char*) display_block, g); next_number = number + 1; } xit: if (name) { close_media(m); free(name); } return; }
// // Routines // partition_map_header * open_partition_map(char *name, int *valid_file, int ask_logical_size, int oflag) { MEDIA m; partition_map_header * map; int writable; long size; m = open_pathname_as_media(name, oflag); if (m == 0) { m = open_pathname_as_media(name, O_RDONLY); if (m == 0) { error(errno, "can't open file '%s'", name); *valid_file = 0; return NULL; } else { writable = 0; } } else { writable = 1; } *valid_file = 1; map = (partition_map_header *) malloc(sizeof(partition_map_header)); if (map == NULL) { error(errno, "can't allocate memory for open partition map"); close_media(m); return NULL; } map->name = name; map->writable = (oflag == O_RDONLY)?0:writable; map->changed = 0; map->written = 0; map->disk_order = NULL; map->base_order = NULL; map->physical_block = media_granularity(m); /* preflight */ m = open_deblock_media(PBLOCK_SIZE, m); map->m = m; map->misc = (Block0 *) malloc(PBLOCK_SIZE); if (map->misc == NULL) { error(errno, "can't allocate memory for block zero buffer"); close_media(map->m); free(map); return NULL; } else if (read_media(map->m, (long long) 0, PBLOCK_SIZE, (char *)map->misc) == 0 || convert_block0(map->misc, 1) || coerce_block0(map)) { // if I can't read block 0 I might as well give up error(-1, "Can't read block 0 from '%s'", name); close_partition_map(map); return NULL; } map->physical_block = map->misc->sbBlkSize; //printf("physical block size is %d\n", map->physical_block); if (ask_logical_size && interactive) { size = PBLOCK_SIZE; printf("A logical block is %ld bytes: ", size); flush_to_newline(0); get_number_argument("what should be the logical block size? ", &size, size); size = (size / PBLOCK_SIZE) * PBLOCK_SIZE; if (size < PBLOCK_SIZE) { size = PBLOCK_SIZE; } map->logical_block = size; } else { map->logical_block = PBLOCK_SIZE; } if (map->logical_block > MAXIOSIZE) { map->logical_block = MAXIOSIZE; } if (map->logical_block > map->physical_block) { map->physical_block = map->logical_block; } map->blocks_in_map = 0; map->maximum_in_map = -1; map->media_size = compute_device_size(map, map); if (read_partition_map(map) < 0) { // some sort of failure reading the map } else { // got it! ; return map; } close_partition_map(map); return NULL; }