• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  **/
show_partition_information(struct driveinfo * drive_info,struct part_entry * ptab,int partition_offset,int nb_partitions_seen)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 
main_show_disk(int argc,char ** argv,struct s_hardware * hardware)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 
main_show_disks(int argc __unused,char ** argv __unused,struct s_hardware * hardware)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 
disks_summary(int argc __unused,char ** argv __unused,struct s_hardware * hardware)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