Home | History | Annotate | Download | only in hdt
      1 /* ----------------------------------------------------------------------- *
      2  *
      3  *   Copyright 2009 Pierre-Alexandre Meyer - All Rights Reserved
      4  *
      5  *   Permission is hereby granted, free of charge, to any person
      6  *   obtaining a copy of this software and associated documentation
      7  *   files (the "Software"), to deal in the Software without
      8  *   restriction, including without limitation the rights to use,
      9  *   copy, modify, merge, publish, distribute, sublicense, and/or
     10  *   sell copies of the Software, and to permit persons to whom
     11  *   the Software is furnished to do so, subject to the following
     12  *   conditions:
     13  *
     14  *   The above copyright notice and this permission notice shall
     15  *   be included in all copies or substantial portions of the Software.
     16  *
     17  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     18  *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
     19  *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     20  *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
     21  *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     22  *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     23  *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     24  *   OTHER DEALINGS IN THE SOFTWARE.
     25  *
     26  * -----------------------------------------------------------------------
     27  */
     28 
     29 #include <stdio.h>
     30 #include <string.h>
     31 #include <stdlib.h>
     32 #include <errno.h>
     33 
     34 #include "hdt-cli.h"
     35 #include "hdt-common.h"
     36 #include "hdt-util.h"
     37 
     38 /**
     39  * show_partition_information - print information about a partition
     40  * @ptab:	part_entry describing the partition
     41  * @i:		Partition number (UI purposes only)
     42  * @ptab_root:	part_entry describing the root partition (extended only)
     43  * @drive_info:	driveinfo struct describing the drive on which the partition
     44  *		is
     45  *
     46  * Note on offsets (from hpa, see chain.c32):
     47  *
     48  *  To make things extra confusing: data partition offsets are relative to where
     49  *  the data partition record is stored, whereas extended partition offsets
     50  *  are relative to the beginning of the extended partition all the way back
     51  *  at the MBR... but still not absolute!
     52  **/
     53 static void show_partition_information(struct driveinfo *drive_info,
     54 				       struct part_entry *ptab,
     55 				       int partition_offset,
     56 				       int nb_partitions_seen)
     57 {
     58     char size[11];
     59     char bootloader_name[9];
     60     char *parttype;
     61     unsigned int start, end;
     62 
     63     int i = nb_partitions_seen;
     64 
     65     reset_more_printf();
     66 
     67     start = partition_offset;
     68     end = start + ptab->length - 1;
     69 
     70     if (ptab->length > 0)
     71 	sectors_to_size(ptab->length, size);
     72     else
     73 	memset(size, 0, sizeof size);
     74 
     75     if (i == 1)
     76 	more_printf(" #  B       Start         End    Size Id Type\n");
     77 
     78     get_label(ptab->ostype, &parttype);
     79     more_printf("%2d  %s %11d %11d %s %02X %s",
     80 		i, (ptab->active_flag == 0x80) ? "x" : " ",
     81 		start, end, size, ptab->ostype, parttype);
     82 
     83     /* Extra info */
     84     if (ptab->ostype == 0x82 && swsusp_check(drive_info, ptab))
     85 	more_printf("%s", " (Swsusp sig. detected)");
     86 
     87     if (get_bootloader_string(drive_info, ptab, bootloader_name, 9) == 0)
     88 	more_printf("%-46s %s %s", " ", "Bootloader:", bootloader_name);
     89 
     90     more_printf("\n");
     91 
     92     free(parttype);
     93 }
     94 
     95 void main_show_disk(int argc, char **argv, struct s_hardware *hardware)
     96 {
     97     if (!argc) {
     98 	more_printf("Which disk?\n");
     99 	return;
    100     }
    101 
    102     int drive = strtol(argv[0], (char **)NULL, 16);
    103 
    104     if (drive < 0x80 || drive >= 0xff) {
    105 	more_printf("Invalid disk: %d.\n", drive);
    106 	return;
    107     }
    108 
    109     int i = drive - 0x80;
    110     struct driveinfo *d = &hardware->disk_info[i];
    111     char disk_size[11];
    112     char mbr_name[50];
    113 
    114     reset_more_printf();
    115 
    116     if (!hardware->disk_info[i].cbios) {
    117 	more_printf("No disk found\n");
    118 	return;			/* Invalid geometry */
    119     }
    120 
    121     get_mbr_string(hardware->mbr_ids[i], &mbr_name, 50);
    122 
    123     if ((int)d->edd_params.sectors > 0)
    124 	sectors_to_size((int)d->edd_params.sectors, disk_size);
    125     else
    126 	memset(disk_size, 0, sizeof disk_size);
    127 
    128     more_printf("DISK 0x%X:\n"
    129 		"  C/H/S: %d cylinders, %d heads, %d sectors/track\n"
    130 		"    EDD: Version: %X\n"
    131 		"         Size: %s, %d bytes/sector, %d sectors/track\n"
    132 		"         Host bus: %s, Interface type: %s\n"
    133 		"    MBR: %s (id 0x%X)\n\n",
    134 		d->disk,
    135 		d->legacy_max_cylinder + 1, d->legacy_max_head + 1,
    136 		d->legacy_sectors_per_track, d->edd_version, disk_size,
    137 		(int)d->edd_params.bytes_per_sector,
    138 		(int)d->edd_params.sectors_per_track,
    139 		remove_spaces((char *)d->edd_params.host_bus_type),
    140 		remove_spaces((char *)d->edd_params.interface_type), mbr_name,
    141 		hardware->mbr_ids[i]);
    142     display_line_nb += 6;
    143 
    144     if (parse_partition_table(d, &show_partition_information)) {
    145 	if (errno_disk) {
    146 	    fprintf(stderr, "I/O error parsing disk 0x%X\n", d->disk);
    147 	    get_error("parse_partition_table");
    148 	} else {
    149 	    fprintf(stderr, "Disk 0x%X: unrecognized partition layout\n",
    150 		    d->disk);
    151 	}
    152 	fprintf(stderr, "\n");
    153     }
    154 
    155     more_printf("\n");
    156 }
    157 
    158 void main_show_disks(int argc __unused, char **argv __unused,
    159 		     struct s_hardware *hardware)
    160 {
    161     bool found = false;
    162     reset_more_printf();
    163 
    164     int first_one = 0;
    165     for (int drive = 0x80; drive < 0xff; drive++) {
    166 	if (hardware->disk_info[drive - 0x80].cbios) {
    167 	    found = true;
    168 	    if (!first_one) {
    169 		first_one = 1;
    170 	    } else {
    171 		pause_printf();
    172 	    }
    173 	    char buf[5] = "";
    174 	    sprintf(buf, "0x%x", drive);
    175 	    char *argv[1] = { buf };
    176 	    main_show_disk(1, argv, hardware);
    177 	}
    178     }
    179 
    180     if (found == false)
    181 	more_printf("No disk found\n");
    182 }
    183 
    184 void disks_summary(int argc __unused, char **argv __unused,
    185 		   struct s_hardware *hardware)
    186 {
    187     int i = -1;
    188     bool found = false;
    189 
    190     reset_more_printf();
    191 
    192     for (int drive = 0x80; drive < 0xff; drive++) {
    193 	i++;
    194 	if (!hardware->disk_info[i].cbios)
    195 	    continue;		/* Invalid geometry */
    196 
    197 	found = true;
    198 	struct driveinfo *d = &hardware->disk_info[i];
    199 	char disk_size[11];
    200 
    201 	if ((int)d->edd_params.sectors > 0)
    202 	    sectors_to_size((int)d->edd_params.sectors, disk_size);
    203 	else
    204 	    memset(disk_size, 0, sizeof disk_size);
    205 
    206 	more_printf("DISK 0x%X:\n", d->disk);
    207 	more_printf("  C/H/S: %d cylinders, %d heads, %d sectors/track\n",
    208 		    d->legacy_max_cylinder + 1, d->legacy_max_head + 1,
    209 		    d->legacy_sectors_per_track);
    210 	more_printf("  EDD:   Version: %X, size: %s\n", d->edd_version,
    211 		    disk_size);
    212 
    213 	/* Do not print Host Bus & Interface if EDD isn't 3.0 or more */
    214 	if (d->edd_version >= 0x30)
    215 	    more_printf("         Host bus: %s, Interface type: %s\n\n",
    216 			remove_spaces((char *)d->edd_params.host_bus_type),
    217 			remove_spaces((char *)d->edd_params.interface_type));
    218     }
    219 
    220     if (found == false)
    221 	more_printf("No disk found\n");
    222 }
    223 
    224 struct cli_callback_descr list_disk_show_modules[] = {
    225     {
    226      .name = "disks",
    227      .exec = main_show_disks,
    228      .nomodule = false,
    229      },
    230     {
    231      .name = "disk",
    232      .exec = main_show_disk,
    233      .nomodule = false,
    234      },
    235     {
    236      .name = NULL,
    237      .exec = NULL,
    238      .nomodule = false,
    239      },
    240 };
    241 
    242 struct cli_module_descr disk_show_modules = {
    243     .modules = list_disk_show_modules,
    244     .default_callback = disks_summary,
    245 };
    246 
    247 struct cli_mode_descr disk_mode = {
    248     .mode = DISK_MODE,
    249     .name = CLI_DISK,
    250     .default_modules = NULL,
    251     .show_modules = &disk_show_modules,
    252     .set_modules = NULL,
    253 };
    254