void delete_partition_from_map(partition_map *entry) { partition_map_header *map; DPME *data; if (strncmp(entry->data->dpme_type, kMapType, DPISTRLEN) == 0) { fprintf(stderr, "Can't delete entry for the map itself\n"); return; } if (entry->contains_driver) { printf("This program can't install drivers\n"); if (get_okay("are you sure you want to delete this driver? [n/y]: ", 0) != 1) { return; } } data = create_data(kFreeName, kFreeType, entry->data->dpme_pblock_start, entry->data->dpme_pblocks); if (data == NULL) { return; } if (entry->contains_driver) { remove_driver(entry); // update block0 if necessary } free(entry->data); entry->data = data; combine_entry(entry); map = entry->the_map; renumber_disk_addresses(map); map->changed = 1; }
void delete_partition_from_map(partition_map *entry) { partition_map_header *map; DPME *data; if (istrncmp(entry->data->dpme_type, kMapType, DPISTRLEN) == 0) { printf("Can't delete entry for the map itself\n"); return; } if (entry->contains_driver) { printf("This program can't install drivers\n"); if (get_okay("are you sure you want to delete this driver? [n/y]: ", 0) != 1) { return; } } // if past end of disk, delete it completely if (entry->next_by_base == NULL && entry->data->dpme_pblock_start >= entry->the_map->media_size) { if (entry->contains_driver) { remove_driver(entry); // update block0 if necessary } delete_entry(entry); return; } // If at end of disk, incorporate extra disk space to partition if (entry->next_by_base == NULL) { entry->data->dpme_pblocks = entry->the_map->media_size - entry->data->dpme_pblock_start; } data = create_data(kFreeName, kFreeType, entry->data->dpme_pblock_start, entry->data->dpme_pblocks); if (data == NULL) { return; } if (entry->contains_driver) { remove_driver(entry); // update block0 if necessary } free(entry->data); free(entry->HFS_name); entry->HFS_kind = kHFS_not; entry->HFS_name = 0; entry->data = data; combine_entry(entry); map = entry->the_map; renumber_disk_addresses(map); map->changed = 1; }
void move_entry_in_map(long old_index, long index, partition_map_header *map) { partition_map * cur; cur = find_entry_by_disk_address(old_index, map); if (cur == NULL) { printf("No such partition\n"); } else { remove_from_disk_order(cur); cur->disk_address = index; insert_in_disk_order(cur); renumber_disk_addresses(map); map->changed = 1; } }
int add_partition_to_map(const char *name, const char *dptype, u32 base, u32 length, partition_map_header *map) { partition_map * cur; DPME *data; enum add_action act; int limit; u32 adjusted_base = 0; u32 adjusted_length = 0; u32 new_base = 0; u32 new_length = 0; // find a block that starts includes base and length cur = map->base_order; while (cur != NULL) { if (cur->data->dpme_pblock_start <= base && (base + length) <= (cur->data->dpme_pblock_start + cur->data->dpme_pblocks)) { break; } else { cur = cur->next_by_base; } } // if it is not Extra then punt if (cur == NULL || strncmp(cur->data->dpme_type, kFreeType, DPISTRLEN) != 0) { printf("requested base and length is not " "within an existing free partition\n"); return 0; } // figure out what to do and sizes data = cur->data; if (data->dpme_pblock_start == base) { // replace or add if (data->dpme_pblocks == length) { act = kReplace; } else { act = kAdd; adjusted_base = base + length; adjusted_length = data->dpme_pblocks - length; } } else { // split or add if (data->dpme_pblock_start + data->dpme_pblocks == base + length) { act = kAdd; adjusted_base = data->dpme_pblock_start; adjusted_length = base - adjusted_base; } else { act = kSplit; new_base = data->dpme_pblock_start; new_length = base - new_base; adjusted_base = base + length; adjusted_length = data->dpme_pblocks - (length + new_length); } } // if the map will overflow then punt if (map->maximum_in_map < 0) { limit = map->media_size; } else { limit = map->maximum_in_map; } if (map->blocks_in_map + act > limit) { printf("the map is not big enough\n"); return 0; } data = create_data(name, dptype, base, length); if (data == NULL) { return 0; } if (act == kReplace) { free(cur->data); cur->data = data; } else { // adjust this block's size cur->data->dpme_pblock_start = adjusted_base; cur->data->dpme_pblocks = adjusted_length; cur->data->dpme_lblocks = adjusted_length; // insert new with block address equal to this one if (add_data_to_map(data, cur->disk_address, map) == 0) { free(data); } else if (act == kSplit) { data = create_data(kFreeName, kFreeType, new_base, new_length); if (data != NULL) { // insert new with block address equal to this one if (add_data_to_map(data, cur->disk_address, map) == 0) { free(data); } } } } // renumber disk addresses renumber_disk_addresses(map); // mark changed map->changed = 1; return 1; }