X-Git-Url: https://glassweightruler.freedombox.rocks/gitweb/Ventoy.git/blobdiff_plain/ef40780f20635da1ad36b13960521bfa3100949f..HEAD:/VtoyTool/vtoydump.c diff --git a/VtoyTool/vtoydump.c b/VtoyTool/vtoydump.c index 1c620d3..25c288b 100644 --- a/VtoyTool/vtoydump.c +++ b/VtoyTool/vtoydump.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -31,99 +32,7 @@ #include #include #include - -#define IS_DIGIT(x) ((x) >= '0' && (x) <= '9') - -#ifndef USE_DIET_C -typedef unsigned long long uint64_t; -typedef unsigned int uint32_t; -typedef unsigned short uint16_t; -typedef unsigned char uint8_t; -#endif - -#define VENTOY_GUID { 0x77772020, 0x2e77, 0x6576, { 0x6e, 0x74, 0x6f, 0x79, 0x2e, 0x6e, 0x65, 0x74 }} - -typedef enum ventoy_fs_type -{ - ventoy_fs_exfat = 0, /* 0: exfat */ - ventoy_fs_ntfs, /* 1: NTFS */ - ventoy_fs_ext, /* 2: ext2/ext3/ext4 */ - ventoy_fs_xfs, /* 3: XFS */ - ventoy_fs_udf, /* 4: UDF */ - ventoy_fs_fat, /* 5: FAT */ - - ventoy_fs_max -}ventoy_fs_type; - -#pragma pack(1) - -typedef struct ventoy_guid -{ - uint32_t data1; - uint16_t data2; - uint16_t data3; - uint8_t data4[8]; -}ventoy_guid; - - -typedef struct ventoy_image_disk_region -{ - uint32_t image_sector_count; /* image sectors contained in this region */ - uint32_t image_start_sector; /* image sector start */ - uint64_t disk_start_sector; /* disk sector start */ -}ventoy_image_disk_region; - -typedef struct ventoy_image_location -{ - ventoy_guid guid; - - /* image sector size, currently this value is always 2048 */ - uint32_t image_sector_size; - - /* disk sector size, normally the value is 512 */ - uint32_t disk_sector_size; - - uint32_t region_count; - - /* - * disk region data - * If the image file has more than one fragments in disk, - * there will be more than one region data here. - * You can calculate the region count by - */ - ventoy_image_disk_region regions[1]; - - /* ventoy_image_disk_region regions[2~region_count-1] */ -}ventoy_image_location; - -typedef struct ventoy_os_param -{ - ventoy_guid guid; // VENTOY_GUID - uint8_t chksum; // checksum - - uint8_t vtoy_disk_guid[16]; - uint64_t vtoy_disk_size; // disk size in bytes - uint16_t vtoy_disk_part_id; // begin with 1 - uint16_t vtoy_disk_part_type; // 0:exfat 1:ntfs other: reserved - char vtoy_img_path[384]; // It seems to be enough, utf-8 format - uint64_t vtoy_img_size; // image file size in bytes - - /* - * Ventoy will write a copy of ventoy_image_location data into runtime memory - * this is the physically address and length of that memory. - * Address 0 means no such data exist. - * Address will be aligned by 4KB. - * - */ - uint64_t vtoy_img_location_addr; - uint32_t vtoy_img_location_len; - - uint64_t vtoy_reserved[4]; // Internal use by ventoy - - uint8_t reserved[31]; -}ventoy_os_param; - -#pragma pack() +#include "vtoytool.h" #ifndef O_BINARY #define O_BINARY 0 @@ -155,6 +64,16 @@ static int vtoy_check_os_param(ventoy_os_param *param) if (memcmp(¶m->guid, &vtoy_guid, sizeof(ventoy_guid))) { + uint8_t *data1 = (uint8_t *)(¶m->guid); + uint8_t *data2 = (uint8_t *)(&vtoy_guid); + + for (i = 0; i < 16; i++) + { + if (data1[i] != data2[i]) + { + debug("guid not equal i = %u, 0x%02x, 0x%02x\n", i, data1[i], data2[i]); + } + } return 1; } @@ -208,6 +127,11 @@ static void vtoy_dump_os_param(ventoy_os_param *param) printf("param->vtoy_disk_guid = %02x %02x %02x %02x\n", param->vtoy_disk_guid[0], param->vtoy_disk_guid[1], param->vtoy_disk_guid[2], param->vtoy_disk_guid[3]); + + printf("param->vtoy_disk_signature = %02x %02x %02x %02x\n", + param->vtoy_disk_signature[0], param->vtoy_disk_signature[1], + param->vtoy_disk_signature[2], param->vtoy_disk_signature[3]); + printf("param->vtoy_disk_size = %llu\n", (unsigned long long)param->vtoy_disk_size); printf("param->vtoy_disk_part_id = %u\n", param->vtoy_disk_part_id); printf("param->vtoy_disk_part_type = %u\n", param->vtoy_disk_part_type); @@ -215,13 +139,21 @@ static void vtoy_dump_os_param(ventoy_os_param *param) printf("param->vtoy_img_size = <%llu>\n", (unsigned long long)param->vtoy_img_size); printf("param->vtoy_img_location_addr = <0x%llx>\n", (unsigned long long)param->vtoy_img_location_addr); printf("param->vtoy_img_location_len = <%u>\n", param->vtoy_img_location_len); - printf("param->vtoy_reserved[0] = 0x%llx\n", (unsigned long long)param->vtoy_reserved[0]); - printf("param->vtoy_reserved[1] = 0x%llx\n", (unsigned long long)param->vtoy_reserved[1]); + printf("param->vtoy_reserved = %02x %02x %02x %02x %02x %02x %02x %02x\n", + param->vtoy_reserved[0], + param->vtoy_reserved[1], + param->vtoy_reserved[2], + param->vtoy_reserved[3], + param->vtoy_reserved[4], + param->vtoy_reserved[5], + param->vtoy_reserved[6], + param->vtoy_reserved[7] + ); printf("\n"); } -static int vtoy_get_disk_guid(const char *diskname, uint8_t *vtguid) +static int vtoy_get_disk_guid(const char *diskname, uint8_t *vtguid, uint8_t *vtsig) { int i = 0; int fd = 0; @@ -234,6 +166,9 @@ static int vtoy_get_disk_guid(const char *diskname, uint8_t *vtguid) { lseek(fd, 0x180, SEEK_SET); read(fd, vtguid, 16); + + lseek(fd, 0x1b8, SEEK_SET); + read(fd, vtsig, 4); close(fd); debug("GUID for %s: <", devdisk); @@ -370,13 +305,14 @@ static int vtoy_find_disk_by_size(unsigned long long size, char *diskname) return rc; } -static int vtoy_find_disk_by_guid(uint8_t *guid, char *diskname) +int vtoy_find_disk_by_guid(ventoy_os_param *param, char *diskname) { int rc = 0; int count = 0; DIR* dir = NULL; struct dirent* p = NULL; uint8_t vtguid[16]; + uint8_t vtsig[16]; dir = opendir("/sys/block"); if (!dir) @@ -393,8 +329,47 @@ static int vtoy_find_disk_by_guid(uint8_t *guid, char *diskname) } memset(vtguid, 0, sizeof(vtguid)); - rc = vtoy_get_disk_guid(p->d_name, vtguid); - if (rc == 0 && memcmp(vtguid, guid, 16) == 0) + memset(vtsig, 0, sizeof(vtsig)); + rc = vtoy_get_disk_guid(p->d_name, vtguid, vtsig); + if (rc == 0 && memcmp(vtguid, param->vtoy_disk_guid, 16) == 0 && + memcmp(vtsig, param->vtoy_disk_signature, 4) == 0) + { + sprintf(diskname, "%s", p->d_name); + count++; + } + } + closedir(dir); + + return count; +} + +static int vtoy_find_disk_by_sig(uint8_t *sig, char *diskname) +{ + int rc = 0; + int count = 0; + DIR* dir = NULL; + struct dirent* p = NULL; + uint8_t vtguid[16]; + uint8_t vtsig[16]; + + dir = opendir("/sys/block"); + if (!dir) + { + return 0; + } + + while ((p = readdir(dir)) != NULL) + { + if (!vtoy_is_possible_blkdev(p->d_name)) + { + debug("disk %s is filted by name\n", p->d_name); + continue; + } + + memset(vtguid, 0, sizeof(vtguid)); + memset(vtsig, 0, sizeof(vtsig)); + rc = vtoy_get_disk_guid(p->d_name, vtguid, vtsig); + if (rc == 0 && memcmp(vtsig, sig, 4) == 0) { sprintf(diskname, "%s", p->d_name); count++; @@ -411,58 +386,104 @@ static int vtoy_printf_iso_path(ventoy_os_param *param) return 0; } -static int vtoy_print_os_param(ventoy_os_param *param, char *diskname) +static int vtoy_printf_fs(ventoy_os_param *param) { - int cnt = 0; - char *path = param->vtoy_img_path; - const char *fs; - - cnt = vtoy_find_disk_by_size(param->vtoy_disk_size, diskname); - if (cnt > 1) + const char *fs[] = { - cnt = vtoy_find_disk_by_guid(param->vtoy_disk_guid, diskname); - } - else if (cnt == 0) - { - cnt = vtoy_find_disk_by_guid(param->vtoy_disk_guid, diskname); - debug("find 0 disk by size, try with guid cnt=%d...\n", cnt); - } + "exfat", "ntfs", "ext", "xfs", "udf", "fat" + }; - if (param->vtoy_disk_part_type < ventoy_fs_max) + if (param->vtoy_disk_part_type < 6) { - fs = g_ventoy_fs[param->vtoy_disk_part_type]; + printf("%s\n", fs[param->vtoy_disk_part_type]); } else { - fs = "unknown"; + printf("unknown\n"); } + return 0; +} - if (1 == cnt) +static int vtoy_vlnk_printf(ventoy_os_param *param, char *diskname) +{ + int cnt = 0; + uint8_t disk_sig[4]; + uint8_t mbr[512]; + int fd = -1; + char diskpath[128]; + uint8_t check[8] = { 0x56, 0x54, 0x00, 0x47, 0x65, 0x00, 0x48, 0x44 }; + + memcpy(disk_sig, param->vtoy_reserved + 7, 4); + + debug("vlnk disk sig: %02x %02x %02x %02x \n", disk_sig[0], disk_sig[1], disk_sig[2], disk_sig[3]); + + cnt = vtoy_find_disk_by_sig(disk_sig, diskname); + if (cnt == 1) { - printf("/dev/%s#%s#%s\n", diskname, fs, path); - return 0; + snprintf(diskpath, sizeof(diskpath), "/dev/%s", diskname); + fd = open(diskpath, O_RDONLY | O_BINARY); + if (fd >= 0) + { + memset(mbr, 0, sizeof(mbr)); + read(fd, mbr, sizeof(mbr)); + close(fd); + + if (memcmp(mbr + 0x190, check, 8) == 0) + { + printf("/dev/%s", diskname); + return 0; + } + else + { + debug("check data failed /dev/%s\n", diskname); + } + } } - else + + debug("find count=%d\n", cnt); + printf("unknown"); + return 1; +} + +static int vtoy_check_iso_path_alpnum(ventoy_os_param *param) +{ + char c; + int i = 0; + + while (param->vtoy_img_path[i]) { - return 1; + c = param->vtoy_img_path[i]; + + if (isalnum(c) || c == '_' || c == '-') + { + + } + else + { + return 1; + } + i++; } + + return 0; } static int vtoy_check_device(ventoy_os_param *param, const char *device) { unsigned long long size; uint8_t vtguid[16] = {0}; + uint8_t vtsig[4] = {0}; debug("vtoy_check_device for <%s>\n", device); size = vtoy_get_disk_size_in_byte(device); - vtoy_get_disk_guid(device, vtguid); + vtoy_get_disk_guid(device, vtguid, vtsig); debug("param->vtoy_disk_size=%llu size=%llu\n", (unsigned long long)param->vtoy_disk_size, (unsigned long long)size); - if ((param->vtoy_disk_size == size || param->vtoy_disk_size == size + 512) && - memcmp(vtguid, param->vtoy_disk_guid, 16) == 0) + if (memcmp(vtguid, param->vtoy_disk_guid, 16) == 0 && + memcmp(vtsig, param->vtoy_disk_signature, 4) == 0) { debug("<%s> is right ventoy disk\n", device); return 0; @@ -474,6 +495,81 @@ static int vtoy_check_device(ventoy_os_param *param, const char *device) } } +static int vtoy_print_os_param(ventoy_os_param *param, char *diskname) +{ + int fd, size; + int cnt = 0; + char *path = param->vtoy_img_path; + const char *fs; + char diskpath[256] = {0}; + char sizebuf[64] = {0}; + + cnt = vtoy_find_disk_by_size(param->vtoy_disk_size, diskname); + debug("find disk by size %llu, cnt=%d...\n", (unsigned long long)param->vtoy_disk_size, cnt); + if (1 == cnt) + { + if (vtoy_check_device(param, diskname) != 0) + { + cnt = 0; + } + } + else + { + cnt = vtoy_find_disk_by_guid(param, diskname); + debug("find disk by guid cnt=%d...\n", cnt); + } + + if (param->vtoy_disk_part_type < ventoy_fs_max) + { + fs = g_ventoy_fs[param->vtoy_disk_part_type]; + } + else + { + fs = "unknown"; + } + + if (1 == cnt) + { + if (strstr(diskname, "nvme") || strstr(diskname, "mmc") || strstr(diskname, "nbd")) + { + snprintf(diskpath, sizeof(diskpath) - 1, "/sys/class/block/%sp2/size", diskname); + } + else + { + snprintf(diskpath, sizeof(diskpath) - 1, "/sys/class/block/%s2/size", diskname); + } + + if (param->vtoy_reserved[6] == 0 && access(diskpath, F_OK) >= 0) + { + debug("get part size from sysfs for %s\n", diskpath); + + fd = open(diskpath, O_RDONLY | O_BINARY); + if (fd >= 0) + { + read(fd, sizebuf, sizeof(sizebuf)); + size = (int)strtoull(sizebuf, NULL, 10); + close(fd); + if ((size != (64 * 1024)) && (size != (8 * 1024))) + { + debug("sizebuf=<%s> size=%d\n", sizebuf, size); + return 1; + } + } + } + else + { + debug("%s not exist \n", diskpath); + } + + printf("/dev/%s#%s#%s\n", diskname, fs, path); + return 0; + } + else + { + return 1; + } +} + /* * Find disk and image path from ventoy runtime data. * By default data is read from phymem(legacy bios) or efivar(UEFI), if -f is input, data is read from file. @@ -488,12 +584,15 @@ int vtoydump_main(int argc, char **argv) int rc; int ch; int print_path = 0; + int check_ascii = 0; + int print_fs = 0; + int vlnk_print = 0; char filename[256] = {0}; char diskname[256] = {0}; char device[64] = {0}; ventoy_os_param *param = NULL; - while ((ch = getopt(argc, argv, "c:f:p:v::")) != -1) + while ((ch = getopt(argc, argv, "a:c:f:p:t:s:v::")) != -1) { if (ch == 'f') { @@ -512,6 +611,21 @@ int vtoydump_main(int argc, char **argv) print_path = 1; strncpy(filename, optarg, sizeof(filename) - 1); } + else if (ch == 'a') + { + check_ascii = 1; + strncpy(filename, optarg, sizeof(filename) - 1); + } + else if (ch == 't') + { + vlnk_print = 1; + strncpy(filename, optarg, sizeof(filename) - 1); + } + else if (ch == 's') + { + print_fs = 1; + strncpy(filename, optarg, sizeof(filename) - 1); + } else { fprintf(stderr, "Usage: %s -f datafile [ -v ] \n", argv[0]); @@ -539,8 +653,20 @@ int vtoydump_main(int argc, char **argv) rc = vtoy_os_param_from_file(filename, param); if (rc) { - debug("ventoy os param not found %d\n", rc); - goto end; + debug("ventoy os param not found %d %d\n", rc, ENOENT); + if (ENOENT == rc) + { + debug("now try with file %s\n", "/ventoy/ventoy_os_param"); + rc = vtoy_os_param_from_file("/ventoy/ventoy_os_param", param); + if (rc) + { + goto end; + } + } + else + { + goto end; + } } if (verbose) @@ -552,10 +678,22 @@ int vtoydump_main(int argc, char **argv) { rc = vtoy_printf_iso_path(param); } + else if (print_fs) + { + rc = vtoy_printf_fs(param); + } + else if (vlnk_print) + { + rc = vtoy_vlnk_printf(param, diskname); + } else if (device[0]) { rc = vtoy_check_device(param, device); } + else if (check_ascii) + { + rc = vtoy_check_iso_path_alpnum(param); + } else { // print os param, you can change the output format in the function