]>
glassweightruler.freedombox.rocks Git - Ventoy.git/blob - VtoyTool/vtoydump.c
1 /******************************************************************************
2 * vtoydump.c ---- Dump ventoy os parameters
4 * Copyright (c) 2020, longpanda <admin@ventoy.net>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 3 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
28 #include <sys/types.h>
30 #include <sys/ioctl.h>
32 #include <sys/types.h>
40 #if defined(_dragon_fly) || defined(_free_BSD) || defined(_QNX)
41 #define MMAP_FLAGS MAP_SHARED
43 #define MMAP_FLAGS MAP_PRIVATE
46 #define SEARCH_MEM_START 0x80000
47 #define SEARCH_MEM_LEN 0x1c000
49 static int verbose
= 0;
50 #define debug(fmt, ...) if(verbose) printf(fmt, ##__VA_ARGS__)
52 static ventoy_guid vtoy_guid
= VENTOY_GUID
;
54 static const char *g_ventoy_fs
[ventoy_fs_max
] =
56 "exfat", "ntfs", "ext*", "xfs", "udf", "fat"
59 static int vtoy_check_os_param(ventoy_os_param
*param
)
63 uint8_t *buf
= (uint8_t *)param
;
65 if (memcmp(¶m
->guid
, &vtoy_guid
, sizeof(ventoy_guid
)))
67 uint8_t *data1
= (uint8_t *)(¶m
->guid
);
68 uint8_t *data2
= (uint8_t *)(&vtoy_guid
);
70 for (i
= 0; i
< 16; i
++)
72 if (data1
[i
] != data2
[i
])
74 debug("guid not equal i = %u, 0x%02x, 0x%02x\n", i
, data1
[i
], data2
[i
]);
80 for (i
= 0; i
< sizeof(ventoy_os_param
); i
++)
87 debug("Invalid checksum 0x%02x\n", chksum
);
94 static int vtoy_os_param_from_file(const char *filename
, ventoy_os_param
*param
)
99 fd
= open(filename
, O_RDONLY
| O_BINARY
);
102 fprintf(stderr
, "Failed to open file %s error %d\n", filename
, errno
);
106 read(fd
, param
, sizeof(ventoy_os_param
));
108 if (vtoy_check_os_param(param
) == 0)
110 debug("find ventoy os param in file %s\n", filename
);
114 debug("ventoy os pararm NOT found in file %s\n", filename
);
122 static void vtoy_dump_os_param(ventoy_os_param
*param
)
124 printf("################# dump os param ################\n");
126 printf("param->chksum = 0x%x\n", param
->chksum
);
127 printf("param->vtoy_disk_guid = %02x %02x %02x %02x\n",
128 param
->vtoy_disk_guid
[0], param
->vtoy_disk_guid
[1],
129 param
->vtoy_disk_guid
[2], param
->vtoy_disk_guid
[3]);
131 printf("param->vtoy_disk_signature = %02x %02x %02x %02x\n",
132 param
->vtoy_disk_signature
[0], param
->vtoy_disk_signature
[1],
133 param
->vtoy_disk_signature
[2], param
->vtoy_disk_signature
[3]);
135 printf("param->vtoy_disk_size = %llu\n", (unsigned long long)param
->vtoy_disk_size
);
136 printf("param->vtoy_disk_part_id = %u\n", param
->vtoy_disk_part_id
);
137 printf("param->vtoy_disk_part_type = %u\n", param
->vtoy_disk_part_type
);
138 printf("param->vtoy_img_path = <%s>\n", param
->vtoy_img_path
);
139 printf("param->vtoy_img_size = <%llu>\n", (unsigned long long)param
->vtoy_img_size
);
140 printf("param->vtoy_img_location_addr = <0x%llx>\n", (unsigned long long)param
->vtoy_img_location_addr
);
141 printf("param->vtoy_img_location_len = <%u>\n", param
->vtoy_img_location_len
);
142 printf("param->vtoy_reserved = %02x %02x %02x %02x %02x %02x %02x %02x\n",
143 param
->vtoy_reserved
[0],
144 param
->vtoy_reserved
[1],
145 param
->vtoy_reserved
[2],
146 param
->vtoy_reserved
[3],
147 param
->vtoy_reserved
[4],
148 param
->vtoy_reserved
[5],
149 param
->vtoy_reserved
[6],
150 param
->vtoy_reserved
[7]
156 static int vtoy_get_disk_guid(const char *diskname
, uint8_t *vtguid
, uint8_t *vtsig
)
160 char devdisk
[128] = {0};
162 snprintf(devdisk
, sizeof(devdisk
) - 1, "/dev/%s", diskname
);
164 fd
= open(devdisk
, O_RDONLY
| O_BINARY
);
167 lseek(fd
, 0x180, SEEK_SET
);
168 read(fd
, vtguid
, 16);
170 lseek(fd
, 0x1b8, SEEK_SET
);
174 debug("GUID for %s: <", devdisk
);
175 for (i
= 0; i
< 16; i
++)
177 debug("%02x", vtguid
[i
]);
185 debug("failed to open %s %d\n", devdisk
, errno
);
190 static unsigned long long vtoy_get_disk_size_in_byte(const char *disk
)
194 unsigned long long size
= 0;
195 char diskpath
[256] = {0};
196 char sizebuf
[64] = {0};
198 // Try 1: get size from sysfs
199 snprintf(diskpath
, sizeof(diskpath
) - 1, "/sys/block/%s/size", disk
);
200 if (access(diskpath
, F_OK
) >= 0)
202 debug("get disk size from sysfs for %s\n", disk
);
204 fd
= open(diskpath
, O_RDONLY
| O_BINARY
);
207 read(fd
, sizebuf
, sizeof(sizebuf
));
208 size
= strtoull(sizebuf
, NULL
, 10);
215 debug("%s not exist \n", diskpath
);
218 // Try 2: get size from ioctl
219 snprintf(diskpath
, sizeof(diskpath
) - 1, "/dev/%s", disk
);
220 fd
= open(diskpath
, O_RDONLY
);
223 debug("get disk size from ioctl for %s\n", disk
);
224 rc
= ioctl(fd
, BLKGETSIZE64
, &size
);
228 debug("failed to ioctl %d\n", rc
);
234 debug("failed to open %s %d\n", diskpath
, errno
);
237 debug("disk %s size %llu bytes\n", disk
, (unsigned long long)size
);
241 static int vtoy_is_possible_blkdev(const char *name
)
249 if (name
[0] == 'r' && name
[1] == 'a' && name
[2] == 'm')
255 if (name
[0] == 'l' && name
[1] == 'o' && name
[2] == 'o' && name
[3] == 'p')
261 if (name
[0] == 'd' && name
[1] == 'm' && name
[2] == '-' && IS_DIGIT(name
[3]))
267 if (name
[0] == 's' && name
[1] == 'r' && IS_DIGIT(name
[2]))
275 static int vtoy_find_disk_by_size(unsigned long long size
, char *diskname
)
277 unsigned long long cursize
= 0;
279 struct dirent
* p
= NULL
;
282 dir
= opendir("/sys/block");
288 while ((p
= readdir(dir
)) != NULL
)
290 if (!vtoy_is_possible_blkdev(p
->d_name
))
292 debug("disk %s is filted by name\n", p
->d_name
);
296 cursize
= vtoy_get_disk_size_in_byte(p
->d_name
);
297 debug("disk %s size %llu\n", p
->d_name
, (unsigned long long)cursize
);
300 sprintf(diskname
, "%s", p
->d_name
);
308 int vtoy_find_disk_by_guid(ventoy_os_param
*param
, char *diskname
)
313 struct dirent
* p
= NULL
;
317 dir
= opendir("/sys/block");
323 while ((p
= readdir(dir
)) != NULL
)
325 if (!vtoy_is_possible_blkdev(p
->d_name
))
327 debug("disk %s is filted by name\n", p
->d_name
);
331 memset(vtguid
, 0, sizeof(vtguid
));
332 memset(vtsig
, 0, sizeof(vtsig
));
333 rc
= vtoy_get_disk_guid(p
->d_name
, vtguid
, vtsig
);
334 if (rc
== 0 && memcmp(vtguid
, param
->vtoy_disk_guid
, 16) == 0 &&
335 memcmp(vtsig
, param
->vtoy_disk_signature
, 4) == 0)
337 sprintf(diskname
, "%s", p
->d_name
);
346 static int vtoy_find_disk_by_sig(uint8_t *sig
, char *diskname
)
351 struct dirent
* p
= NULL
;
355 dir
= opendir("/sys/block");
361 while ((p
= readdir(dir
)) != NULL
)
363 if (!vtoy_is_possible_blkdev(p
->d_name
))
365 debug("disk %s is filted by name\n", p
->d_name
);
369 memset(vtguid
, 0, sizeof(vtguid
));
370 memset(vtsig
, 0, sizeof(vtsig
));
371 rc
= vtoy_get_disk_guid(p
->d_name
, vtguid
, vtsig
);
372 if (rc
== 0 && memcmp(vtsig
, sig
, 4) == 0)
374 sprintf(diskname
, "%s", p
->d_name
);
383 static int vtoy_printf_iso_path(ventoy_os_param
*param
)
385 printf("%s\n", param
->vtoy_img_path
);
389 static int vtoy_printf_fs(ventoy_os_param
*param
)
393 "exfat", "ntfs", "ext", "xfs", "udf", "fat"
396 if (param
->vtoy_disk_part_type
< 6)
398 printf("%s\n", fs
[param
->vtoy_disk_part_type
]);
407 static int vtoy_vlnk_printf(ventoy_os_param
*param
, char *diskname
)
414 uint8_t check
[8] = { 0x56, 0x54, 0x00, 0x47, 0x65, 0x00, 0x48, 0x44 };
416 memcpy(disk_sig
, param
->vtoy_reserved
+ 7, 4);
418 debug("vlnk disk sig: %02x %02x %02x %02x \n", disk_sig
[0], disk_sig
[1], disk_sig
[2], disk_sig
[3]);
420 cnt
= vtoy_find_disk_by_sig(disk_sig
, diskname
);
423 snprintf(diskpath
, sizeof(diskpath
), "/dev/%s", diskname
);
424 fd
= open(diskpath
, O_RDONLY
| O_BINARY
);
427 memset(mbr
, 0, sizeof(mbr
));
428 read(fd
, mbr
, sizeof(mbr
));
431 if (memcmp(mbr
+ 0x190, check
, 8) == 0)
433 printf("/dev/%s", diskname
);
438 debug("check data failed /dev/%s\n", diskname
);
443 debug("find count=%d\n", cnt
);
448 static int vtoy_check_iso_path_alpnum(ventoy_os_param
*param
)
453 while (param
->vtoy_img_path
[i
])
455 c
= param
->vtoy_img_path
[i
];
457 if (isalnum(c
) || c
== '_' || c
== '-')
471 static int vtoy_check_device(ventoy_os_param
*param
, const char *device
)
473 unsigned long long size
;
474 uint8_t vtguid
[16] = {0};
475 uint8_t vtsig
[4] = {0};
477 debug("vtoy_check_device for <%s>\n", device
);
479 size
= vtoy_get_disk_size_in_byte(device
);
480 vtoy_get_disk_guid(device
, vtguid
, vtsig
);
482 debug("param->vtoy_disk_size=%llu size=%llu\n",
483 (unsigned long long)param
->vtoy_disk_size
, (unsigned long long)size
);
485 if (memcmp(vtguid
, param
->vtoy_disk_guid
, 16) == 0 &&
486 memcmp(vtsig
, param
->vtoy_disk_signature
, 4) == 0)
488 debug("<%s> is right ventoy disk\n", device
);
493 debug("<%s> is NOT right ventoy disk\n", device
);
498 static int vtoy_print_os_param(ventoy_os_param
*param
, char *diskname
)
502 char *path
= param
->vtoy_img_path
;
504 char diskpath
[256] = {0};
505 char sizebuf
[64] = {0};
507 cnt
= vtoy_find_disk_by_size(param
->vtoy_disk_size
, diskname
);
508 debug("find disk by size %llu, cnt=%d...\n", (unsigned long long)param
->vtoy_disk_size
, cnt
);
511 if (vtoy_check_device(param
, diskname
) != 0)
518 cnt
= vtoy_find_disk_by_guid(param
, diskname
);
519 debug("find disk by guid cnt=%d...\n", cnt
);
522 if (param
->vtoy_disk_part_type
< ventoy_fs_max
)
524 fs
= g_ventoy_fs
[param
->vtoy_disk_part_type
];
533 if (strstr(diskname
, "nvme") || strstr(diskname
, "mmc") || strstr(diskname
, "nbd"))
535 snprintf(diskpath
, sizeof(diskpath
) - 1, "/sys/class/block/%sp2/size", diskname
);
539 snprintf(diskpath
, sizeof(diskpath
) - 1, "/sys/class/block/%s2/size", diskname
);
542 if (param
->vtoy_reserved
[6] == 0 && access(diskpath
, F_OK
) >= 0)
544 debug("get part size from sysfs for %s\n", diskpath
);
546 fd
= open(diskpath
, O_RDONLY
| O_BINARY
);
549 read(fd
, sizebuf
, sizeof(sizebuf
));
550 size
= (int)strtoull(sizebuf
, NULL
, 10);
552 if ((size
!= (64 * 1024)) && (size
!= (8 * 1024)))
554 debug("sizebuf=<%s> size=%d\n", sizebuf
, size
);
561 debug("%s not exist \n", diskpath
);
564 printf("/dev/%s#%s#%s\n", diskname
, fs
, path
);
574 * Find disk and image path from ventoy runtime data.
575 * By default data is read from phymem(legacy bios) or efivar(UEFI), if -f is input, data is read from file.
577 * -f datafile os param data file.
578 * -c /dev/xxx check ventoy disk
580 * -l also print image disk location
582 int vtoydump_main(int argc
, char **argv
)
590 char filename
[256] = {0};
591 char diskname
[256] = {0};
592 char device
[64] = {0};
593 ventoy_os_param
*param
= NULL
;
595 while ((ch
= getopt(argc
, argv
, "a:c:f:p:t:s:v::")) != -1)
599 strncpy(filename
, optarg
, sizeof(filename
) - 1);
607 strncpy(device
, optarg
, sizeof(device
) - 1);
612 strncpy(filename
, optarg
, sizeof(filename
) - 1);
617 strncpy(filename
, optarg
, sizeof(filename
) - 1);
622 strncpy(filename
, optarg
, sizeof(filename
) - 1);
627 strncpy(filename
, optarg
, sizeof(filename
) - 1);
631 fprintf(stderr
, "Usage: %s -f datafile [ -v ] \n", argv
[0]);
636 if (filename
[0] == 0)
638 fprintf(stderr
, "Usage: %s -f datafile [ -v ] \n", argv
[0]);
642 param
= malloc(sizeof(ventoy_os_param
));
645 fprintf(stderr
, "failed to alloc memory with size %d error %d\n",
646 (int)sizeof(ventoy_os_param
), errno
);
650 memset(param
, 0, sizeof(ventoy_os_param
));
652 debug("get os pararm from file %s\n", filename
);
653 rc
= vtoy_os_param_from_file(filename
, param
);
656 debug("ventoy os param not found %d %d\n", rc
, ENOENT
);
659 debug("now try with file %s\n", "/ventoy/ventoy_os_param");
660 rc
= vtoy_os_param_from_file("/ventoy/ventoy_os_param", param
);
674 vtoy_dump_os_param(param
);
679 rc
= vtoy_printf_iso_path(param
);
683 rc
= vtoy_printf_fs(param
);
687 rc
= vtoy_vlnk_printf(param
, diskname
);
691 rc
= vtoy_check_device(param
, device
);
693 else if (check_ascii
)
695 rc
= vtoy_check_iso_path_alpnum(param
);
699 // print os param, you can change the output format in the function
700 rc
= vtoy_print_os_param(param
, diskname
);
712 #ifndef BUILD_VTOY_TOOL
713 int main(int argc
, char **argv
)
715 return vtoydump_main(argc
, argv
);