1#include <stdio.h>
2#include <string.h>
3#include <fcntl.h>
4#include <sys/ioctl.h>
5#include <Drivers.h>
6#include <StorageDefs.h>
7
8static void dump_dev_size(int dev)
9{
10	size_t sz;
11	if (ioctl(dev, B_GET_DEVICE_SIZE, &sz, sizeof(sz)) < 0) {
12		perror("ioctl(B_GET_DEVICE_SIZE)");
13		return;
14	}
15	printf("size: %" B_PRIuSIZE " bytes\n", sz);
16}
17
18static void dump_bios_id(int dev)
19{
20	uint8 id;
21	if (ioctl(dev, B_GET_BIOS_DRIVE_ID, &id, sizeof(id)) < 0) {
22		perror("ioctl(B_GET_BIOS_DRIVE_ID)");
23		return;
24	}
25	printf("bios id: %d, 0x%x\n", id, id);
26}
27
28static void dump_media_status(int dev)
29{
30	uint32 st;
31	if (ioctl(dev, B_GET_MEDIA_STATUS, &st, sizeof(st)) < 0) {
32		perror("ioctl(B_GET_MEDIA_STATUS)");
33		return;
34	}
35	printf("media status: %s\n", strerror(st));
36}
37
38static const char *device_type(uint32 type)
39{
40	if (type == B_DISK) return "disk";
41	if (type == B_TAPE) return "tape";
42	if (type == B_PRINTER) return "printer";
43	if (type == B_CPU) return "cpu";
44	if (type == B_WORM) return "worm";
45	if (type == B_CD) return "cd";
46	if (type == B_SCANNER) return "scanner";
47	if (type == B_OPTICAL) return "optical";
48	if (type == B_JUKEBOX) return "jukebox";
49	if (type == B_NETWORK) return "network";
50	return "<unknown>";
51}
52
53static void dump_geom(int dev, bool bios)
54{
55	device_geometry geom;
56
57	if (ioctl(dev, bios?B_GET_BIOS_GEOMETRY:B_GET_GEOMETRY, &geom, sizeof(geom)) < 0) {
58		perror(bios ? "ioctl(B_GET_BIOS_GEOMETRY)" : "ioctl(B_GET_GEOMETRY)");
59		return;
60	}
61	printf("%sgeometry:\n", bios?"bios ":"");
62	printf("bytes_per_sector:\t%" B_PRIu32 "\n", geom.bytes_per_sector);
63	printf("sectors_per_track:\t%" B_PRIu32 "\n", geom.sectors_per_track);
64	printf("cylinder_count:\t%" B_PRIu32 "\n", geom.cylinder_count);
65	printf("head_count:\t%" B_PRIu32 "\n", geom.head_count);
66	printf("device_type:\t%d, %s\n", geom.device_type, device_type(geom.device_type));
67	printf("%sremovable.\n", geom.removable?"":"not ");
68	printf("%sread_only.\n", geom.read_only?"":"not ");
69	printf("%swrite_once.\n", geom.write_once?"":"not ");
70}
71
72static void dump_partition(int dev)
73{
74	partition_info partition;
75
76	if (ioctl(dev, B_GET_PARTITION_INFO, &partition, sizeof(partition)) < 0) {
77		perror("ioctl(B_GET_PARTITION_INFO)");
78		return;
79	}
80	printf("partition:\n");
81	printf("offset:\t%" B_PRIdOFF "\n", partition.offset);
82	printf("size:\t%" B_PRIdOFF "\n", partition.size);
83	printf("logical_block_size:\t%" B_PRId32 "\n", partition.logical_block_size);
84	printf("session:\t%" B_PRId32 "\n", partition.session);
85	printf("partition:\t%" B_PRId32 "\n", partition.partition);
86	printf("device:\t%s\n", partition.device);
87}
88
89static void dump_misc(int dev)
90{
91	char path[B_PATH_NAME_LENGTH];
92	if (ioctl(dev, B_GET_DRIVER_FOR_DEVICE, path, sizeof(path)) < 0) {
93		perror("ioctl(B_GET_DRIVER_FOR_DEVICE)");
94	} else {
95		printf("driver:\t%s\n", path);
96	}
97#ifdef __HAIKU__
98	if (ioctl(dev, B_GET_PATH_FOR_DEVICE, path, sizeof(path)) < 0) {
99		perror("ioctl(B_GET_PATH_FOR_DEVICE)");
100	} else {
101		printf("device path:\t%s\n", path);
102	}
103#endif
104}
105
106int main(int argc, char **argv)
107{
108	int dev;
109	if (argc < 2) {
110		printf("%s device\n", argv[0]);
111		return 1;
112	}
113	dev = open(argv[1], O_RDONLY);
114	if (dev < 0) {
115		perror("open");
116		return 1;
117	}
118	dump_dev_size(dev);
119	puts("");
120	dump_bios_id(dev);
121	puts("");
122	dump_media_status(dev);
123	puts("");
124	dump_geom(dev, false);
125	puts("");
126	dump_geom(dev, true);
127	puts("");
128	dump_partition(dev);
129	puts("");
130	dump_misc(dev);
131	puts("");
132	return 0;
133}
134