mirror of
https://github.com/ventoy/Ventoy.git
synced 2025-06-03 08:28:50 -04:00
Experimental Linux GUI based on web browser
This commit is contained in:
parent
7279ba9bc8
commit
43e8ec5785
158 changed files with 43670 additions and 0 deletions
299
LinuxGUI/Ventoy2Disk/Core/ventoy_crc32.c
Normal file
299
LinuxGUI/Ventoy2Disk/Core/ventoy_crc32.c
Normal file
|
@ -0,0 +1,299 @@
|
|||
/******************************************************************************
|
||||
* crc32.c ---- ventoy crc32
|
||||
*
|
||||
* Copyright (c) 2021, longpanda <admin@ventoy.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static uint32_t g_crc_table[256] = {
|
||||
0x00000000,
|
||||
0x77073096,
|
||||
0xEE0E612C,
|
||||
0x990951BA,
|
||||
0x076DC419,
|
||||
0x706AF48F,
|
||||
0xE963A535,
|
||||
0x9E6495A3,
|
||||
0x0EDB8832,
|
||||
0x79DCB8A4,
|
||||
0xE0D5E91E,
|
||||
0x97D2D988,
|
||||
0x09B64C2B,
|
||||
0x7EB17CBD,
|
||||
0xE7B82D07,
|
||||
0x90BF1D91,
|
||||
0x1DB71064,
|
||||
0x6AB020F2,
|
||||
0xF3B97148,
|
||||
0x84BE41DE,
|
||||
0x1ADAD47D,
|
||||
0x6DDDE4EB,
|
||||
0xF4D4B551,
|
||||
0x83D385C7,
|
||||
0x136C9856,
|
||||
0x646BA8C0,
|
||||
0xFD62F97A,
|
||||
0x8A65C9EC,
|
||||
0x14015C4F,
|
||||
0x63066CD9,
|
||||
0xFA0F3D63,
|
||||
0x8D080DF5,
|
||||
0x3B6E20C8,
|
||||
0x4C69105E,
|
||||
0xD56041E4,
|
||||
0xA2677172,
|
||||
0x3C03E4D1,
|
||||
0x4B04D447,
|
||||
0xD20D85FD,
|
||||
0xA50AB56B,
|
||||
0x35B5A8FA,
|
||||
0x42B2986C,
|
||||
0xDBBBC9D6,
|
||||
0xACBCF940,
|
||||
0x32D86CE3,
|
||||
0x45DF5C75,
|
||||
0xDCD60DCF,
|
||||
0xABD13D59,
|
||||
0x26D930AC,
|
||||
0x51DE003A,
|
||||
0xC8D75180,
|
||||
0xBFD06116,
|
||||
0x21B4F4B5,
|
||||
0x56B3C423,
|
||||
0xCFBA9599,
|
||||
0xB8BDA50F,
|
||||
0x2802B89E,
|
||||
0x5F058808,
|
||||
0xC60CD9B2,
|
||||
0xB10BE924,
|
||||
0x2F6F7C87,
|
||||
0x58684C11,
|
||||
0xC1611DAB,
|
||||
0xB6662D3D,
|
||||
0x76DC4190,
|
||||
0x01DB7106,
|
||||
0x98D220BC,
|
||||
0xEFD5102A,
|
||||
0x71B18589,
|
||||
0x06B6B51F,
|
||||
0x9FBFE4A5,
|
||||
0xE8B8D433,
|
||||
0x7807C9A2,
|
||||
0x0F00F934,
|
||||
0x9609A88E,
|
||||
0xE10E9818,
|
||||
0x7F6A0DBB,
|
||||
0x086D3D2D,
|
||||
0x91646C97,
|
||||
0xE6635C01,
|
||||
0x6B6B51F4,
|
||||
0x1C6C6162,
|
||||
0x856530D8,
|
||||
0xF262004E,
|
||||
0x6C0695ED,
|
||||
0x1B01A57B,
|
||||
0x8208F4C1,
|
||||
0xF50FC457,
|
||||
0x65B0D9C6,
|
||||
0x12B7E950,
|
||||
0x8BBEB8EA,
|
||||
0xFCB9887C,
|
||||
0x62DD1DDF,
|
||||
0x15DA2D49,
|
||||
0x8CD37CF3,
|
||||
0xFBD44C65,
|
||||
0x4DB26158,
|
||||
0x3AB551CE,
|
||||
0xA3BC0074,
|
||||
0xD4BB30E2,
|
||||
0x4ADFA541,
|
||||
0x3DD895D7,
|
||||
0xA4D1C46D,
|
||||
0xD3D6F4FB,
|
||||
0x4369E96A,
|
||||
0x346ED9FC,
|
||||
0xAD678846,
|
||||
0xDA60B8D0,
|
||||
0x44042D73,
|
||||
0x33031DE5,
|
||||
0xAA0A4C5F,
|
||||
0xDD0D7CC9,
|
||||
0x5005713C,
|
||||
0x270241AA,
|
||||
0xBE0B1010,
|
||||
0xC90C2086,
|
||||
0x5768B525,
|
||||
0x206F85B3,
|
||||
0xB966D409,
|
||||
0xCE61E49F,
|
||||
0x5EDEF90E,
|
||||
0x29D9C998,
|
||||
0xB0D09822,
|
||||
0xC7D7A8B4,
|
||||
0x59B33D17,
|
||||
0x2EB40D81,
|
||||
0xB7BD5C3B,
|
||||
0xC0BA6CAD,
|
||||
0xEDB88320,
|
||||
0x9ABFB3B6,
|
||||
0x03B6E20C,
|
||||
0x74B1D29A,
|
||||
0xEAD54739,
|
||||
0x9DD277AF,
|
||||
0x04DB2615,
|
||||
0x73DC1683,
|
||||
0xE3630B12,
|
||||
0x94643B84,
|
||||
0x0D6D6A3E,
|
||||
0x7A6A5AA8,
|
||||
0xE40ECF0B,
|
||||
0x9309FF9D,
|
||||
0x0A00AE27,
|
||||
0x7D079EB1,
|
||||
0xF00F9344,
|
||||
0x8708A3D2,
|
||||
0x1E01F268,
|
||||
0x6906C2FE,
|
||||
0xF762575D,
|
||||
0x806567CB,
|
||||
0x196C3671,
|
||||
0x6E6B06E7,
|
||||
0xFED41B76,
|
||||
0x89D32BE0,
|
||||
0x10DA7A5A,
|
||||
0x67DD4ACC,
|
||||
0xF9B9DF6F,
|
||||
0x8EBEEFF9,
|
||||
0x17B7BE43,
|
||||
0x60B08ED5,
|
||||
0xD6D6A3E8,
|
||||
0xA1D1937E,
|
||||
0x38D8C2C4,
|
||||
0x4FDFF252,
|
||||
0xD1BB67F1,
|
||||
0xA6BC5767,
|
||||
0x3FB506DD,
|
||||
0x48B2364B,
|
||||
0xD80D2BDA,
|
||||
0xAF0A1B4C,
|
||||
0x36034AF6,
|
||||
0x41047A60,
|
||||
0xDF60EFC3,
|
||||
0xA867DF55,
|
||||
0x316E8EEF,
|
||||
0x4669BE79,
|
||||
0xCB61B38C,
|
||||
0xBC66831A,
|
||||
0x256FD2A0,
|
||||
0x5268E236,
|
||||
0xCC0C7795,
|
||||
0xBB0B4703,
|
||||
0x220216B9,
|
||||
0x5505262F,
|
||||
0xC5BA3BBE,
|
||||
0xB2BD0B28,
|
||||
0x2BB45A92,
|
||||
0x5CB36A04,
|
||||
0xC2D7FFA7,
|
||||
0xB5D0CF31,
|
||||
0x2CD99E8B,
|
||||
0x5BDEAE1D,
|
||||
0x9B64C2B0,
|
||||
0xEC63F226,
|
||||
0x756AA39C,
|
||||
0x026D930A,
|
||||
0x9C0906A9,
|
||||
0xEB0E363F,
|
||||
0x72076785,
|
||||
0x05005713,
|
||||
0x95BF4A82,
|
||||
0xE2B87A14,
|
||||
0x7BB12BAE,
|
||||
0x0CB61B38,
|
||||
0x92D28E9B,
|
||||
0xE5D5BE0D,
|
||||
0x7CDCEFB7,
|
||||
0x0BDBDF21,
|
||||
0x86D3D2D4,
|
||||
0xF1D4E242,
|
||||
0x68DDB3F8,
|
||||
0x1FDA836E,
|
||||
0x81BE16CD,
|
||||
0xF6B9265B,
|
||||
0x6FB077E1,
|
||||
0x18B74777,
|
||||
0x88085AE6,
|
||||
0xFF0F6A70,
|
||||
0x66063BCA,
|
||||
0x11010B5C,
|
||||
0x8F659EFF,
|
||||
0xF862AE69,
|
||||
0x616BFFD3,
|
||||
0x166CCF45,
|
||||
0xA00AE278,
|
||||
0xD70DD2EE,
|
||||
0x4E048354,
|
||||
0x3903B3C2,
|
||||
0xA7672661,
|
||||
0xD06016F7,
|
||||
0x4969474D,
|
||||
0x3E6E77DB,
|
||||
0xAED16A4A,
|
||||
0xD9D65ADC,
|
||||
0x40DF0B66,
|
||||
0x37D83BF0,
|
||||
0xA9BCAE53,
|
||||
0xDEBB9EC5,
|
||||
0x47B2CF7F,
|
||||
0x30B5FFE9,
|
||||
0xBDBDF21C,
|
||||
0xCABAC28A,
|
||||
0x53B39330,
|
||||
0x24B4A3A6,
|
||||
0xBAD03605,
|
||||
0xCDD70693,
|
||||
0x54DE5729,
|
||||
0x23D967BF,
|
||||
0xB3667A2E,
|
||||
0xC4614AB8,
|
||||
0x5D681B02,
|
||||
0x2A6F2B94,
|
||||
0xB40BBE37,
|
||||
0xC30C8EA1,
|
||||
0x5A05DF1B,
|
||||
0x2D02EF8D
|
||||
};
|
||||
|
||||
uint32_t ventoy_crc32(void *Buffer, uint32_t Length)
|
||||
{
|
||||
uint32_t i;
|
||||
uint8_t *Ptr = Buffer;
|
||||
uint32_t Crc = 0xFFFFFFFF;
|
||||
|
||||
for (i = 0; i < Length; i++, Ptr++)
|
||||
{
|
||||
Crc = (Crc >> 8) ^ g_crc_table[(uint8_t) Crc ^ *Ptr];
|
||||
}
|
||||
|
||||
return Crc ^ 0xffffffff;
|
||||
}
|
||||
|
192
LinuxGUI/Ventoy2Disk/Core/ventoy_define.h
Normal file
192
LinuxGUI/Ventoy2Disk/Core/ventoy_define.h
Normal file
|
@ -0,0 +1,192 @@
|
|||
/******************************************************************************
|
||||
* ventoy_define.h
|
||||
*
|
||||
* Copyright (c) 2021, longpanda <admin@ventoy.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifndef __VENTOY_DEFINE_H__
|
||||
#define __VENTOY_DEFINE_H__
|
||||
|
||||
#define MAX_DISK_NUM 256
|
||||
|
||||
#define SIZE_1MB 1048576
|
||||
#define SIZE_1GB 1073741824
|
||||
|
||||
#define VTOYIMG_PART_START_BYTES (1024 * 1024)
|
||||
#define VTOYIMG_PART_START_SECTOR 2048
|
||||
|
||||
#define VTOYEFI_PART_BYTES (32 * 1024 * 1024)
|
||||
#define VTOYEFI_PART_SECTORS 65536
|
||||
|
||||
#define VTOY_LOG_FILE "log.txt"
|
||||
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct vtoy_guid
|
||||
{
|
||||
uint32_t data1;
|
||||
uint16_t data2;
|
||||
uint16_t data3;
|
||||
uint8_t data4[8];
|
||||
}vtoy_guid;
|
||||
|
||||
typedef struct PART_TABLE
|
||||
{
|
||||
uint8_t Active; // 0x00 0x80
|
||||
|
||||
uint8_t StartHead;
|
||||
uint16_t StartSector : 6;
|
||||
uint16_t StartCylinder : 10;
|
||||
|
||||
uint8_t FsFlag;
|
||||
|
||||
uint8_t EndHead;
|
||||
uint16_t EndSector : 6;
|
||||
uint16_t EndCylinder : 10;
|
||||
|
||||
uint32_t StartSectorId;
|
||||
uint32_t SectorCount;
|
||||
}PART_TABLE;
|
||||
|
||||
typedef struct MBR_HEAD
|
||||
{
|
||||
uint8_t BootCode[446];
|
||||
PART_TABLE PartTbl[4];
|
||||
uint8_t Byte55;
|
||||
uint8_t ByteAA;
|
||||
}MBR_HEAD;
|
||||
|
||||
typedef struct VTOY_GPT_HDR
|
||||
{
|
||||
char Signature[8]; /* EFI PART */
|
||||
uint8_t Version[4];
|
||||
uint32_t Length;
|
||||
uint32_t Crc;
|
||||
uint8_t Reserved1[4];
|
||||
uint64_t EfiStartLBA;
|
||||
uint64_t EfiBackupLBA;
|
||||
uint64_t PartAreaStartLBA;
|
||||
uint64_t PartAreaEndLBA;
|
||||
vtoy_guid DiskGuid;
|
||||
uint64_t PartTblStartLBA;
|
||||
uint32_t PartTblTotNum;
|
||||
uint32_t PartTblEntryLen;
|
||||
uint32_t PartTblCrc;
|
||||
uint8_t Reserved2[420];
|
||||
}VTOY_GPT_HDR;
|
||||
|
||||
typedef struct VTOY_GPT_PART_TBL
|
||||
{
|
||||
vtoy_guid PartType;
|
||||
vtoy_guid PartGuid;
|
||||
uint64_t StartLBA;
|
||||
uint64_t LastLBA;
|
||||
uint64_t Attr;
|
||||
uint16_t Name[36];
|
||||
}VTOY_GPT_PART_TBL;
|
||||
|
||||
typedef struct VTOY_GPT_INFO
|
||||
{
|
||||
MBR_HEAD MBR;
|
||||
VTOY_GPT_HDR Head;
|
||||
VTOY_GPT_PART_TBL PartTbl[128];
|
||||
}VTOY_GPT_INFO;
|
||||
#pragma pack()
|
||||
|
||||
|
||||
#define MBR_PART_STYLE 0
|
||||
#define GPT_PART_STYLE 1
|
||||
|
||||
typedef struct disk_ventoy_data
|
||||
{
|
||||
int ventoy_valid;
|
||||
|
||||
char ventoy_ver[32]; // 1.0.33 ...
|
||||
int secure_boot_flag;
|
||||
uint64_t preserved_space;
|
||||
|
||||
uint64_t part2_start_sector;
|
||||
|
||||
int partition_style; // MBR_PART_STYLE/GPT_PART_STYLE
|
||||
VTOY_GPT_INFO gptinfo;
|
||||
uint8_t rsvdata[4096];
|
||||
}disk_ventoy_data;
|
||||
|
||||
|
||||
typedef struct ventoy_disk
|
||||
{
|
||||
char disk_name[32]; // sda
|
||||
char disk_path[64]; // /dev/sda
|
||||
|
||||
char part1_name[32]; // sda1
|
||||
char part1_path[64]; // /dev/sda1
|
||||
char part2_name[32]; // sda2
|
||||
char part2_path[64]; // /dev/sda2
|
||||
|
||||
char disk_model[256]; // Sandisk/Kingston ...
|
||||
char human_readable_size[32];
|
||||
|
||||
int major;
|
||||
int minor;
|
||||
int type;
|
||||
int partstyle;
|
||||
uint64_t size_in_byte;
|
||||
|
||||
disk_ventoy_data vtoydata;
|
||||
}ventoy_disk;
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct ventoy_guid
|
||||
{
|
||||
uint32_t data1;
|
||||
uint16_t data2;
|
||||
uint16_t data3;
|
||||
uint8_t data4[8];
|
||||
}ventoy_guid;
|
||||
#pragma pack()
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#define VLOG_LOG 1
|
||||
#define VLOG_DEBUG 2
|
||||
|
||||
#define ulong unsigned long
|
||||
#define _ll long long
|
||||
#define _ull unsigned long long
|
||||
#define strlcpy(dst, src) strncpy(dst, src, sizeof(dst) - 1)
|
||||
#define scnprintf(dst, fmt, args...) snprintf(dst, sizeof(dst) - 1, fmt, ##args)
|
||||
|
||||
#define vlog(fmt, args...) ventoy_syslog(VLOG_LOG, fmt, ##args)
|
||||
#define vdebug(fmt, args...) ventoy_syslog(VLOG_DEBUG, fmt, ##args)
|
||||
|
||||
void ventoy_syslog(int level, const char *Fmt, ...);
|
||||
void ventoy_set_loglevel(int level);
|
||||
uint32_t ventoy_crc32(void *Buffer, uint32_t Length);
|
||||
|
||||
|
||||
static inline void * zalloc(size_t n)
|
||||
{
|
||||
void *p = malloc(n);
|
||||
if (p) memset(p, 0, n);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
#endif /* __VENTOY_DEFINE_H__ */
|
||||
|
735
LinuxGUI/Ventoy2Disk/Core/ventoy_disk.c
Normal file
735
LinuxGUI/Ventoy2Disk/Core/ventoy_disk.c
Normal file
|
@ -0,0 +1,735 @@
|
|||
/******************************************************************************
|
||||
* ventoy_disk.c ---- ventoy disk
|
||||
* Copyright (c) 2021, longpanda <admin@ventoy.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/fs.h>
|
||||
#include <dirent.h>
|
||||
#include <time.h>
|
||||
#include <ventoy_define.h>
|
||||
#include <ventoy_disk.h>
|
||||
#include <ventoy_util.h>
|
||||
#include <fat_filelib.h>
|
||||
|
||||
int g_disk_num = 0;
|
||||
static int g_fatlib_media_fd = 0;
|
||||
static uint64_t g_fatlib_media_offset = 0;
|
||||
ventoy_disk *g_disk_list = NULL;
|
||||
|
||||
static const char *g_ventoy_dev_type_str[VTOY_DEVICE_END] =
|
||||
{
|
||||
"unknown", "scsi", "USB", "ide", "dac960",
|
||||
"cpqarray", "file", "ataraid", "i2o",
|
||||
"ubd", "dasd", "viodasd", "sx8", "dm",
|
||||
"xvd", "sd/mmc", "virtblk", "aoe",
|
||||
"md", "loopback", "nvme", "brd", "pmem"
|
||||
};
|
||||
|
||||
static const char * ventoy_get_dev_type_name(ventoy_dev_type type)
|
||||
{
|
||||
return (type < VTOY_DEVICE_END) ? g_ventoy_dev_type_str[type] : "unknown";
|
||||
}
|
||||
|
||||
static int ventoy_check_blk_major(int major, const char *type)
|
||||
{
|
||||
int flag = 0;
|
||||
int valid = 0;
|
||||
int devnum = 0;
|
||||
int len = 0;
|
||||
char line[64];
|
||||
char *pos = NULL;
|
||||
FILE *fp = NULL;
|
||||
|
||||
fp = fopen("/proc/devices", "r");
|
||||
if (!fp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = (int)strlen(type);
|
||||
while (fgets(line, sizeof(line), fp))
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
pos = strchr(line, ' ');
|
||||
if (pos)
|
||||
{
|
||||
devnum = (int)strtol(line, NULL, 10);
|
||||
if (devnum == major)
|
||||
{
|
||||
if (strncmp(pos + 1, type, len) == 0)
|
||||
{
|
||||
valid = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strncmp(line, "Block devices:", 14) == 0)
|
||||
{
|
||||
flag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return valid;
|
||||
}
|
||||
|
||||
static int ventoy_get_disk_devnum(const char *name, int *major, int* minor)
|
||||
{
|
||||
int rc;
|
||||
char *pos;
|
||||
char devnum[16] = {0};
|
||||
|
||||
rc = ventoy_get_sys_file_line(devnum, sizeof(devnum), "/sys/block/%s/dev", name);
|
||||
if (rc)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
pos = strstr(devnum, ":");
|
||||
if (!pos)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
*major = (int)strtol(devnum, NULL, 10);
|
||||
*minor = (int)strtol(pos + 1, NULL, 10);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ventoy_dev_type ventoy_get_dev_type(const char *name, int major, int minor)
|
||||
{
|
||||
int rc;
|
||||
char syspath[128];
|
||||
char dstpath[256];
|
||||
|
||||
memset(syspath, 0, sizeof(syspath));
|
||||
memset(dstpath, 0, sizeof(dstpath));
|
||||
|
||||
scnprintf(syspath, "/sys/block/%s", name);
|
||||
rc = readlink(syspath, dstpath, sizeof(dstpath) - 1);
|
||||
if (rc > 0 && strstr(dstpath, "/usb"))
|
||||
{
|
||||
return VTOY_DEVICE_USB;
|
||||
}
|
||||
|
||||
if (SCSI_BLK_MAJOR(major) && (minor % 0x10 == 0))
|
||||
{
|
||||
return VTOY_DEVICE_SCSI;
|
||||
}
|
||||
else if (IDE_BLK_MAJOR(major) && (minor % 0x40 == 0))
|
||||
{
|
||||
return VTOY_DEVICE_IDE;
|
||||
}
|
||||
else if (major == DAC960_MAJOR && (minor % 0x8 == 0))
|
||||
{
|
||||
return VTOY_DEVICE_DAC960;
|
||||
}
|
||||
else if (major == ATARAID_MAJOR && (minor % 0x10 == 0))
|
||||
{
|
||||
return VTOY_DEVICE_ATARAID;
|
||||
}
|
||||
else if (major == AOE_MAJOR && (minor % 0x10 == 0))
|
||||
{
|
||||
return VTOY_DEVICE_AOE;
|
||||
}
|
||||
else if (major == DASD_MAJOR && (minor % 0x4 == 0))
|
||||
{
|
||||
return VTOY_DEVICE_DASD;
|
||||
}
|
||||
else if (major == VIODASD_MAJOR && (minor % 0x8 == 0))
|
||||
{
|
||||
return VTOY_DEVICE_VIODASD;
|
||||
}
|
||||
else if (SX8_BLK_MAJOR(major) && (minor % 0x20 == 0))
|
||||
{
|
||||
return VTOY_DEVICE_SX8;
|
||||
}
|
||||
else if (I2O_BLK_MAJOR(major) && (minor % 0x10 == 0))
|
||||
{
|
||||
return VTOY_DEVICE_I2O;
|
||||
}
|
||||
else if (CPQARRAY_BLK_MAJOR(major) && (minor % 0x10 == 0))
|
||||
{
|
||||
return VTOY_DEVICE_CPQARRAY;
|
||||
}
|
||||
else if (UBD_MAJOR == major && (minor % 0x10 == 0))
|
||||
{
|
||||
return VTOY_DEVICE_UBD;
|
||||
}
|
||||
else if (XVD_MAJOR == major && (minor % 0x10 == 0))
|
||||
{
|
||||
return VTOY_DEVICE_XVD;
|
||||
}
|
||||
else if (SDMMC_MAJOR == major && (minor % 0x8 == 0))
|
||||
{
|
||||
return VTOY_DEVICE_SDMMC;
|
||||
}
|
||||
else if (ventoy_check_blk_major(major, "virtblk"))
|
||||
{
|
||||
return VTOY_DEVICE_VIRTBLK;
|
||||
}
|
||||
else if (major == LOOP_MAJOR)
|
||||
{
|
||||
return VTOY_DEVICE_LOOP;
|
||||
}
|
||||
else if (major == MD_MAJOR)
|
||||
{
|
||||
return VTOY_DEVICE_MD;
|
||||
}
|
||||
else if (major == RAM_MAJOR)
|
||||
{
|
||||
return VTOY_DEVICE_RAM;
|
||||
}
|
||||
else if (strstr(name, "nvme") && ventoy_check_blk_major(major, "blkext"))
|
||||
{
|
||||
return VTOY_DEVICE_NVME;
|
||||
}
|
||||
else if (strstr(name, "pmem") && ventoy_check_blk_major(major, "blkext"))
|
||||
{
|
||||
return VTOY_DEVICE_PMEM;
|
||||
}
|
||||
|
||||
return VTOY_DEVICE_END;
|
||||
}
|
||||
|
||||
static int ventoy_is_possible_blkdev(const char *name)
|
||||
{
|
||||
if (name[0] == '.')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* /dev/ramX */
|
||||
if (name[0] == 'r' && name[1] == 'a' && name[2] == 'm')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* /dev/loopX */
|
||||
if (name[0] == 'l' && name[1] == 'o' && name[2] == 'o' && name[3] == 'p')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* /dev/dm-X */
|
||||
if (name[0] == 'd' && name[1] == 'm' && name[2] == '-' && isdigit(name[3]))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* /dev/srX */
|
||||
if (name[0] == 's' && name[1] == 'r' && isdigit(name[2]))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint64_t ventoy_get_disk_size_in_byte(const char *disk)
|
||||
{
|
||||
int fd;
|
||||
int rc;
|
||||
unsigned long long size = 0;
|
||||
char diskpath[256] = {0};
|
||||
char sizebuf[64] = {0};
|
||||
|
||||
// Try 1: get size from sysfs
|
||||
snprintf(diskpath, sizeof(diskpath) - 1, "/sys/block/%s/size", disk);
|
||||
if (access(diskpath, F_OK) >= 0)
|
||||
{
|
||||
vdebug("get disk size from sysfs for %s\n", disk);
|
||||
|
||||
fd = open(diskpath, O_RDONLY | O_BINARY);
|
||||
if (fd >= 0)
|
||||
{
|
||||
read(fd, sizebuf, sizeof(sizebuf));
|
||||
size = strtoull(sizebuf, NULL, 10);
|
||||
close(fd);
|
||||
return (uint64_t)(size * 512);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vdebug("%s not exist \n", diskpath);
|
||||
}
|
||||
|
||||
// Try 2: get size from ioctl
|
||||
snprintf(diskpath, sizeof(diskpath) - 1, "/dev/%s", disk);
|
||||
fd = open(diskpath, O_RDONLY);
|
||||
if (fd >= 0)
|
||||
{
|
||||
vdebug("get disk size from ioctl for %s\n", disk);
|
||||
rc = ioctl(fd, BLKGETSIZE64, &size);
|
||||
if (rc == -1)
|
||||
{
|
||||
size = 0;
|
||||
vdebug("failed to ioctl %d\n", rc);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
vdebug("failed to open %s %d\n", diskpath, errno);
|
||||
}
|
||||
|
||||
vdebug("disk %s size %llu bytes\n", disk, size);
|
||||
return size;
|
||||
}
|
||||
|
||||
int ventoy_get_disk_vendor(const char *name, char *vendorbuf, int bufsize)
|
||||
{
|
||||
return ventoy_get_sys_file_line(vendorbuf, bufsize, "/sys/block/%s/device/vendor", name);
|
||||
}
|
||||
|
||||
int ventoy_get_disk_model(const char *name, char *modelbuf, int bufsize)
|
||||
{
|
||||
return ventoy_get_sys_file_line(modelbuf, bufsize, "/sys/block/%s/device/model", name);
|
||||
}
|
||||
|
||||
static int fatlib_media_sector_read(uint32 sector, uint8 *buffer, uint32 sector_count)
|
||||
{
|
||||
lseek(g_fatlib_media_fd, (sector + g_fatlib_media_offset) * 512ULL, SEEK_SET);
|
||||
read(g_fatlib_media_fd, buffer, sector_count * 512);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int fatlib_is_secure_boot_enable(void)
|
||||
{
|
||||
void *flfile = NULL;
|
||||
|
||||
flfile = fl_fopen("/EFI/BOOT/grubx64_real.efi", "rb");
|
||||
if (flfile)
|
||||
{
|
||||
fl_fclose(flfile);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
vlog("/EFI/BOOT/grubx64_real.efi not exist\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fatlib_get_ventoy_version(char *verbuf, int bufsize)
|
||||
{
|
||||
int rc = 1;
|
||||
int size = 0;
|
||||
char *buf = NULL;
|
||||
char *pos = NULL;
|
||||
char *end = NULL;
|
||||
void *flfile = NULL;
|
||||
|
||||
flfile = fl_fopen("/grub/grub.cfg", "rb");
|
||||
if (flfile)
|
||||
{
|
||||
fl_fseek(flfile, 0, SEEK_END);
|
||||
size = (int)fl_ftell(flfile);
|
||||
|
||||
fl_fseek(flfile, 0, SEEK_SET);
|
||||
|
||||
buf = malloc(size + 1);
|
||||
if (buf)
|
||||
{
|
||||
fl_fread(buf, 1, size, flfile);
|
||||
buf[size] = 0;
|
||||
|
||||
pos = strstr(buf, "VENTOY_VERSION=");
|
||||
if (pos)
|
||||
{
|
||||
pos += strlen("VENTOY_VERSION=");
|
||||
if (*pos == '"')
|
||||
{
|
||||
pos++;
|
||||
}
|
||||
|
||||
end = pos;
|
||||
while (*end != 0 && *end != '"' && *end != '\r' && *end != '\n')
|
||||
{
|
||||
end++;
|
||||
}
|
||||
|
||||
*end = 0;
|
||||
|
||||
snprintf(verbuf, bufsize - 1, "%s", pos);
|
||||
rc = 0;
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
|
||||
fl_fclose(flfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
vdebug("No grub.cfg found\n");
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int ventoy_get_vtoy_data(ventoy_disk *info, int *ppartstyle)
|
||||
{
|
||||
int i;
|
||||
int fd;
|
||||
int len;
|
||||
int rc = 1;
|
||||
int ret = 1;
|
||||
int part_style;
|
||||
uint64_t part1_start_sector;
|
||||
uint64_t part1_sector_count;
|
||||
uint64_t part2_start_sector;
|
||||
uint64_t part2_sector_count;
|
||||
uint64_t preserved_space;
|
||||
char name[64] = {0};
|
||||
disk_ventoy_data *vtoy = NULL;
|
||||
VTOY_GPT_INFO *gpt = NULL;
|
||||
|
||||
vtoy = &(info->vtoydata);
|
||||
gpt = &(vtoy->gptinfo);
|
||||
memset(vtoy, 0, sizeof(disk_ventoy_data));
|
||||
|
||||
vdebug("ventoy_get_vtoy_data %s\n", info->disk_path);
|
||||
|
||||
if (info->size_in_byte < (2 * VTOYEFI_PART_BYTES))
|
||||
{
|
||||
vdebug("disk %s is too small %llu\n", info->disk_path, (_ull)info->size_in_byte);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fd = open(info->disk_path, O_RDONLY | O_BINARY);
|
||||
if (fd < 0)
|
||||
{
|
||||
vdebug("failed to open %s %d\n", info->disk_path, errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
len = (int)read(fd, &(vtoy->gptinfo), sizeof(VTOY_GPT_INFO));
|
||||
if (len != sizeof(VTOY_GPT_INFO))
|
||||
{
|
||||
vdebug("failed to read %s %d\n", info->disk_path, errno);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (gpt->MBR.Byte55 != 0x55 || gpt->MBR.ByteAA != 0xAA)
|
||||
{
|
||||
vdebug("Invalid mbr magic 0x%x 0x%x\n", gpt->MBR.Byte55, gpt->MBR.ByteAA);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (gpt->MBR.PartTbl[0].FsFlag == 0xEE && strncmp(gpt->Head.Signature, "EFI PART", 8) == 0)
|
||||
{
|
||||
part_style = GPT_PART_STYLE;
|
||||
if (ppartstyle)
|
||||
{
|
||||
*ppartstyle = part_style;
|
||||
}
|
||||
|
||||
if (gpt->PartTbl[0].StartLBA == 0 || gpt->PartTbl[1].StartLBA == 0)
|
||||
{
|
||||
vdebug("NO ventoy efi part layout <%llu %llu>\n",
|
||||
(_ull)gpt->PartTbl[0].StartLBA,
|
||||
(_ull)gpt->PartTbl[1].StartLBA);
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (i = 0; i < 36; i++)
|
||||
{
|
||||
name[i] = (char)(gpt->PartTbl[1].Name[i]);
|
||||
}
|
||||
if (strcmp(name, "VTOYEFI"))
|
||||
{
|
||||
vdebug("Invalid efi part2 name <%s>\n", name);
|
||||
goto end;
|
||||
}
|
||||
|
||||
part1_start_sector = gpt->PartTbl[0].StartLBA;
|
||||
part1_sector_count = gpt->PartTbl[0].LastLBA - part1_start_sector + 1;
|
||||
part2_start_sector = gpt->PartTbl[1].StartLBA;
|
||||
part2_sector_count = gpt->PartTbl[1].LastLBA - part2_start_sector + 1;
|
||||
|
||||
preserved_space = info->size_in_byte - (part2_start_sector + part2_sector_count + 33) * 512;
|
||||
}
|
||||
else
|
||||
{
|
||||
part_style = MBR_PART_STYLE;
|
||||
if (ppartstyle)
|
||||
{
|
||||
*ppartstyle = part_style;
|
||||
}
|
||||
|
||||
part1_start_sector = gpt->MBR.PartTbl[0].StartSectorId;
|
||||
part1_sector_count = gpt->MBR.PartTbl[0].SectorCount;
|
||||
part2_start_sector = gpt->MBR.PartTbl[1].StartSectorId;
|
||||
part2_sector_count = gpt->MBR.PartTbl[1].SectorCount;
|
||||
|
||||
preserved_space = info->size_in_byte - (part2_start_sector + part2_sector_count) * 512;
|
||||
}
|
||||
|
||||
if (part1_start_sector != VTOYIMG_PART_START_SECTOR ||
|
||||
part2_sector_count != VTOYEFI_PART_SECTORS ||
|
||||
(part1_start_sector + part1_sector_count) != part2_start_sector)
|
||||
{
|
||||
vdebug("Not valid ventoy partition layout [%llu %llu] [%llu %llu]\n",
|
||||
part1_start_sector, part1_sector_count, part2_start_sector, part2_sector_count);
|
||||
goto end;
|
||||
}
|
||||
|
||||
vdebug("now check secure boot ...\n");
|
||||
|
||||
g_fatlib_media_fd = fd;
|
||||
g_fatlib_media_offset = part2_start_sector;
|
||||
fl_init();
|
||||
|
||||
if (0 == fl_attach_media(fatlib_media_sector_read, NULL))
|
||||
{
|
||||
ret = fatlib_get_ventoy_version(vtoy->ventoy_ver, sizeof(vtoy->ventoy_ver));
|
||||
if (ret == 0 && vtoy->ventoy_ver[0])
|
||||
{
|
||||
vtoy->secure_boot_flag = fatlib_is_secure_boot_enable();
|
||||
vtoy->ventoy_valid = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
vdebug("fatlib_get_ventoy_version failed %d\n", ret);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vdebug("fl_attach_media failed\n");
|
||||
}
|
||||
|
||||
fl_shutdown();
|
||||
g_fatlib_media_fd = -1;
|
||||
g_fatlib_media_offset = 0;
|
||||
|
||||
if (0 == vtoy->ventoy_valid)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
lseek(fd, 2040 * 512, SEEK_SET);
|
||||
read(fd, vtoy->rsvdata, sizeof(vtoy->rsvdata));
|
||||
|
||||
vtoy->preserved_space = preserved_space;
|
||||
vtoy->partition_style = part_style;
|
||||
vtoy->part2_start_sector = part2_start_sector;
|
||||
|
||||
rc = 0;
|
||||
end:
|
||||
close(fd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int ventoy_get_disk_info(const char *name, ventoy_disk *info)
|
||||
{
|
||||
char vendor[64] = {0};
|
||||
char model[128] = {0};
|
||||
|
||||
vdebug("get disk info %s\n", name);
|
||||
|
||||
strlcpy(info->disk_name, name);
|
||||
scnprintf(info->disk_path, "/dev/%s", name);
|
||||
|
||||
if (strstr(name, "nvme") || strstr(name, "mmc") || strstr(name, "nbd"))
|
||||
{
|
||||
scnprintf(info->part1_name, "%sp1", name);
|
||||
scnprintf(info->part1_path, "/dev/%sp1", name);
|
||||
scnprintf(info->part2_name, "%sp2", name);
|
||||
scnprintf(info->part2_path, "/dev/%sp2", name);
|
||||
}
|
||||
else
|
||||
{
|
||||
scnprintf(info->part1_name, "%s1", name);
|
||||
scnprintf(info->part1_path, "/dev/%s1", name);
|
||||
scnprintf(info->part2_name, "%s2", name);
|
||||
scnprintf(info->part2_path, "/dev/%s2", name);
|
||||
}
|
||||
|
||||
info->size_in_byte = ventoy_get_disk_size_in_byte(name);
|
||||
|
||||
ventoy_get_disk_devnum(name, &info->major, &info->minor);
|
||||
info->type = ventoy_get_dev_type(name, info->major, info->minor);
|
||||
ventoy_get_disk_vendor(name, vendor, sizeof(vendor));
|
||||
ventoy_get_disk_model(name, model, sizeof(model));
|
||||
|
||||
scnprintf(info->human_readable_size, "%llu GB", (_ull)ventoy_get_human_readable_gb(info->size_in_byte));
|
||||
scnprintf(info->disk_model, "%s %s (%s)", vendor, model, ventoy_get_dev_type_name(info->type));
|
||||
|
||||
ventoy_get_vtoy_data(info, &(info->partstyle));
|
||||
|
||||
vdebug("disk:<%s %d:%d> model:<%s> size:%llu (%s)\n",
|
||||
info->disk_path, info->major, info->minor, info->disk_model, info->size_in_byte, info->human_readable_size);
|
||||
|
||||
if (info->vtoydata.ventoy_valid)
|
||||
{
|
||||
vdebug("%s Ventoy:<%s> %s secureboot:%d preserve:%llu\n", info->disk_path, info->vtoydata.ventoy_ver,
|
||||
info->vtoydata.partition_style == MBR_PART_STYLE ? "MBR" : "GPT",
|
||||
info->vtoydata.secure_boot_flag, (_ull)(info->vtoydata.preserved_space));
|
||||
}
|
||||
else
|
||||
{
|
||||
vdebug("%s NO Ventoy detected\n", info->disk_path);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ventoy_disk_compare(const ventoy_disk *disk1, const ventoy_disk *disk2)
|
||||
{
|
||||
if (disk1->type == VTOY_DEVICE_USB && disk2->type == VTOY_DEVICE_USB)
|
||||
{
|
||||
return strcmp(disk1->disk_name, disk2->disk_name);
|
||||
}
|
||||
else if (disk1->type == VTOY_DEVICE_USB)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (disk2->type == VTOY_DEVICE_USB)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return strcmp(disk1->disk_name, disk2->disk_name);
|
||||
}
|
||||
}
|
||||
|
||||
static int ventoy_disk_sort(void)
|
||||
{
|
||||
int i, j;
|
||||
ventoy_disk *tmp;
|
||||
|
||||
tmp = malloc(sizeof(ventoy_disk));
|
||||
if (!tmp)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < g_disk_num; i++)
|
||||
for (j = i + 1; j < g_disk_num; j++)
|
||||
{
|
||||
if (ventoy_disk_compare(g_disk_list + i, g_disk_list + j) > 0)
|
||||
{
|
||||
memcpy(tmp, g_disk_list + i, sizeof(ventoy_disk));
|
||||
memcpy(g_disk_list + i, g_disk_list + j, sizeof(ventoy_disk));
|
||||
memcpy(g_disk_list + j, tmp, sizeof(ventoy_disk));
|
||||
}
|
||||
}
|
||||
|
||||
free(tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ventoy_disk_enumerate_all(void)
|
||||
{
|
||||
int rc = 0;
|
||||
DIR* dir = NULL;
|
||||
struct dirent* p = NULL;
|
||||
|
||||
vdebug("ventoy_disk_enumerate_all\n");
|
||||
|
||||
dir = opendir("/sys/block");
|
||||
if (!dir)
|
||||
{
|
||||
vlog("Failed to open /sys/block %d\n", errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (((p = readdir(dir)) != NULL) && (g_disk_num < MAX_DISK_NUM))
|
||||
{
|
||||
if (ventoy_is_possible_blkdev(p->d_name))
|
||||
{
|
||||
memset(g_disk_list + g_disk_num, 0, sizeof(ventoy_disk));
|
||||
if (0 == ventoy_get_disk_info(p->d_name, g_disk_list + g_disk_num))
|
||||
{
|
||||
g_disk_num++;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
ventoy_disk_sort();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void ventoy_disk_dump(ventoy_disk *cur)
|
||||
{
|
||||
if (cur->vtoydata.ventoy_valid)
|
||||
{
|
||||
vdebug("%s [%s] %s\tVentoy: %s %s secureboot:%d preserve:%llu\n",
|
||||
cur->disk_path, cur->human_readable_size, cur->disk_model,
|
||||
cur->vtoydata.ventoy_ver, cur->vtoydata.partition_style == MBR_PART_STYLE ? "MBR" : "GPT",
|
||||
cur->vtoydata.secure_boot_flag, (_ull)(cur->vtoydata.preserved_space));
|
||||
}
|
||||
else
|
||||
{
|
||||
vdebug("%s [%s] %s\tVentoy: NA\n", cur->disk_path, cur->human_readable_size, cur->disk_model);
|
||||
}
|
||||
}
|
||||
|
||||
void ventoy_disk_dump_all(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
vdebug("============= DISK DUMP ============\n");
|
||||
for (i = 0; i < g_disk_num; i++)
|
||||
{
|
||||
ventoy_disk_dump(g_disk_list + i);
|
||||
}
|
||||
}
|
||||
|
||||
int ventoy_disk_install(ventoy_disk *disk, void *efipartimg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ventoy_disk_init(void)
|
||||
{
|
||||
g_disk_list = malloc(sizeof(ventoy_disk) * MAX_DISK_NUM);
|
||||
|
||||
ventoy_disk_enumerate_all();
|
||||
ventoy_disk_dump_all();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ventoy_disk_exit(void)
|
||||
{
|
||||
check_free(g_disk_list);
|
||||
g_disk_list = NULL;
|
||||
g_disk_num = 0;
|
||||
}
|
||||
|
||||
|
145
LinuxGUI/Ventoy2Disk/Core/ventoy_disk.h
Normal file
145
LinuxGUI/Ventoy2Disk/Core/ventoy_disk.h
Normal file
|
@ -0,0 +1,145 @@
|
|||
/******************************************************************************
|
||||
* ventoy_disk.h
|
||||
*
|
||||
* Copyright (c) 2021, longpanda <admin@ventoy.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifndef __VENTOY_DISK_H__
|
||||
#define __VENTOY_DISK_H__
|
||||
|
||||
typedef enum
|
||||
{
|
||||
VTOY_DEVICE_UNKNOWN = 0,
|
||||
VTOY_DEVICE_SCSI,
|
||||
VTOY_DEVICE_USB,
|
||||
VTOY_DEVICE_IDE,
|
||||
VTOY_DEVICE_DAC960,
|
||||
VTOY_DEVICE_CPQARRAY,
|
||||
VTOY_DEVICE_FILE,
|
||||
VTOY_DEVICE_ATARAID,
|
||||
VTOY_DEVICE_I2O,
|
||||
VTOY_DEVICE_UBD,
|
||||
VTOY_DEVICE_DASD,
|
||||
VTOY_DEVICE_VIODASD,
|
||||
VTOY_DEVICE_SX8,
|
||||
VTOY_DEVICE_DM,
|
||||
VTOY_DEVICE_XVD,
|
||||
VTOY_DEVICE_SDMMC,
|
||||
VTOY_DEVICE_VIRTBLK,
|
||||
VTOY_DEVICE_AOE,
|
||||
VTOY_DEVICE_MD,
|
||||
VTOY_DEVICE_LOOP,
|
||||
VTOY_DEVICE_NVME,
|
||||
VTOY_DEVICE_RAM,
|
||||
VTOY_DEVICE_PMEM,
|
||||
|
||||
VTOY_DEVICE_END
|
||||
}ventoy_dev_type;
|
||||
|
||||
/* from <linux/major.h> */
|
||||
#define IDE0_MAJOR 3
|
||||
#define IDE1_MAJOR 22
|
||||
#define IDE2_MAJOR 33
|
||||
#define IDE3_MAJOR 34
|
||||
#define IDE4_MAJOR 56
|
||||
#define IDE5_MAJOR 57
|
||||
#define SCSI_CDROM_MAJOR 11
|
||||
#define SCSI_DISK0_MAJOR 8
|
||||
#define SCSI_DISK1_MAJOR 65
|
||||
#define SCSI_DISK2_MAJOR 66
|
||||
#define SCSI_DISK3_MAJOR 67
|
||||
#define SCSI_DISK4_MAJOR 68
|
||||
#define SCSI_DISK5_MAJOR 69
|
||||
#define SCSI_DISK6_MAJOR 70
|
||||
#define SCSI_DISK7_MAJOR 71
|
||||
#define SCSI_DISK8_MAJOR 128
|
||||
#define SCSI_DISK9_MAJOR 129
|
||||
#define SCSI_DISK10_MAJOR 130
|
||||
#define SCSI_DISK11_MAJOR 131
|
||||
#define SCSI_DISK12_MAJOR 132
|
||||
#define SCSI_DISK13_MAJOR 133
|
||||
#define SCSI_DISK14_MAJOR 134
|
||||
#define SCSI_DISK15_MAJOR 135
|
||||
#define COMPAQ_SMART2_MAJOR 72
|
||||
#define COMPAQ_SMART2_MAJOR1 73
|
||||
#define COMPAQ_SMART2_MAJOR2 74
|
||||
#define COMPAQ_SMART2_MAJOR3 75
|
||||
#define COMPAQ_SMART2_MAJOR4 76
|
||||
#define COMPAQ_SMART2_MAJOR5 77
|
||||
#define COMPAQ_SMART2_MAJOR6 78
|
||||
#define COMPAQ_SMART2_MAJOR7 79
|
||||
#define COMPAQ_SMART_MAJOR 104
|
||||
#define COMPAQ_SMART_MAJOR1 105
|
||||
#define COMPAQ_SMART_MAJOR2 106
|
||||
#define COMPAQ_SMART_MAJOR3 107
|
||||
#define COMPAQ_SMART_MAJOR4 108
|
||||
#define COMPAQ_SMART_MAJOR5 109
|
||||
#define COMPAQ_SMART_MAJOR6 110
|
||||
#define COMPAQ_SMART_MAJOR7 111
|
||||
#define DAC960_MAJOR 48
|
||||
#define ATARAID_MAJOR 114
|
||||
#define I2O_MAJOR1 80
|
||||
#define I2O_MAJOR2 81
|
||||
#define I2O_MAJOR3 82
|
||||
#define I2O_MAJOR4 83
|
||||
#define I2O_MAJOR5 84
|
||||
#define I2O_MAJOR6 85
|
||||
#define I2O_MAJOR7 86
|
||||
#define I2O_MAJOR8 87
|
||||
#define UBD_MAJOR 98
|
||||
#define DASD_MAJOR 94
|
||||
#define VIODASD_MAJOR 112
|
||||
#define AOE_MAJOR 152
|
||||
#define SX8_MAJOR1 160
|
||||
#define SX8_MAJOR2 161
|
||||
#define XVD_MAJOR 202
|
||||
#define SDMMC_MAJOR 179
|
||||
#define LOOP_MAJOR 7
|
||||
#define MD_MAJOR 9
|
||||
#define BLKEXT_MAJOR 259
|
||||
#define RAM_MAJOR 1
|
||||
|
||||
#define SCSI_BLK_MAJOR(M) ( \
|
||||
(M) == SCSI_DISK0_MAJOR \
|
||||
|| (M) == SCSI_CDROM_MAJOR \
|
||||
|| ((M) >= SCSI_DISK1_MAJOR && (M) <= SCSI_DISK7_MAJOR) \
|
||||
|| ((M) >= SCSI_DISK8_MAJOR && (M) <= SCSI_DISK15_MAJOR))
|
||||
|
||||
#define IDE_BLK_MAJOR(M) \
|
||||
((M) == IDE0_MAJOR || \
|
||||
(M) == IDE1_MAJOR || \
|
||||
(M) == IDE2_MAJOR || \
|
||||
(M) == IDE3_MAJOR || \
|
||||
(M) == IDE4_MAJOR || \
|
||||
(M) == IDE5_MAJOR)
|
||||
|
||||
#define SX8_BLK_MAJOR(M) ((M) >= SX8_MAJOR1 && (M) <= SX8_MAJOR2)
|
||||
#define I2O_BLK_MAJOR(M) ((M) >= I2O_MAJOR1 && (M) <= I2O_MAJOR8)
|
||||
#define CPQARRAY_BLK_MAJOR(M) \
|
||||
(((M) >= COMPAQ_SMART2_MAJOR && (M) <= COMPAQ_SMART2_MAJOR7) || \
|
||||
(COMPAQ_SMART_MAJOR <= (M) && (M) <= COMPAQ_SMART_MAJOR7))
|
||||
|
||||
#define VENTOY_FILE_STG1_IMG "boot/core.img.xz"
|
||||
#define VENTOY_FILE_DISK_IMG "ventoy/ventoy.disk.img.xz"
|
||||
|
||||
extern int g_disk_num;
|
||||
extern ventoy_disk *g_disk_list;
|
||||
int ventoy_disk_enumerate_all(void);
|
||||
int ventoy_disk_init(void);
|
||||
void ventoy_disk_exit(void);
|
||||
|
||||
#endif /* __VENTOY_DISK_H__ */
|
||||
|
716
LinuxGUI/Ventoy2Disk/Core/ventoy_json.c
Normal file
716
LinuxGUI/Ventoy2Disk/Core/ventoy_json.c
Normal file
|
@ -0,0 +1,716 @@
|
|||
/******************************************************************************
|
||||
* ventoy_json.c
|
||||
*
|
||||
* Copyright (c) 2021, longpanda <admin@ventoy.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <ventoy_define.h>
|
||||
#include <ventoy_util.h>
|
||||
#include <ventoy_json.h>
|
||||
|
||||
static void vtoy_json_free(VTOY_JSON *pstJsonHead)
|
||||
{
|
||||
VTOY_JSON *pstNext = NULL;
|
||||
|
||||
while (NULL != pstJsonHead)
|
||||
{
|
||||
pstNext = pstJsonHead->pstNext;
|
||||
if ((pstJsonHead->enDataType < JSON_TYPE_BUTT) && (NULL != pstJsonHead->pstChild))
|
||||
{
|
||||
vtoy_json_free(pstJsonHead->pstChild);
|
||||
}
|
||||
|
||||
free(pstJsonHead);
|
||||
pstJsonHead = pstNext;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static char *vtoy_json_skip(const char *pcData)
|
||||
{
|
||||
while ((NULL != pcData) && ('\0' != *pcData) && (*pcData <= 32))
|
||||
{
|
||||
pcData++;
|
||||
}
|
||||
|
||||
return (char *)pcData;
|
||||
}
|
||||
|
||||
VTOY_JSON *vtoy_json_find_item
|
||||
(
|
||||
VTOY_JSON *pstJson,
|
||||
JSON_TYPE enDataType,
|
||||
const char *szKey
|
||||
)
|
||||
{
|
||||
while (NULL != pstJson)
|
||||
{
|
||||
if ((enDataType == pstJson->enDataType) &&
|
||||
(0 == strcmp(szKey, pstJson->pcName)))
|
||||
{
|
||||
return pstJson;
|
||||
}
|
||||
pstJson = pstJson->pstNext;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int vtoy_json_parse_number
|
||||
(
|
||||
VTOY_JSON *pstJson,
|
||||
const char *pcData,
|
||||
const char **ppcEnd
|
||||
)
|
||||
{
|
||||
unsigned long Value;
|
||||
|
||||
Value = strtoul(pcData, (char **)ppcEnd, 10);
|
||||
if (*ppcEnd == pcData)
|
||||
{
|
||||
vdebug("Failed to parse json number %s.\n", pcData);
|
||||
return JSON_FAILED;
|
||||
}
|
||||
|
||||
pstJson->enDataType = JSON_TYPE_NUMBER;
|
||||
pstJson->unData.lValue = Value;
|
||||
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
|
||||
static int vtoy_json_parse_string
|
||||
(
|
||||
char *pcNewStart,
|
||||
char *pcRawStart,
|
||||
VTOY_JSON *pstJson,
|
||||
const char *pcData,
|
||||
const char **ppcEnd
|
||||
)
|
||||
{
|
||||
uint32_t uiLen = 0;
|
||||
const char *pcPos = NULL;
|
||||
const char *pcTmp = pcData + 1;
|
||||
|
||||
*ppcEnd = pcData;
|
||||
|
||||
if ('\"' != *pcData)
|
||||
{
|
||||
return JSON_FAILED;
|
||||
}
|
||||
|
||||
pcPos = strchr(pcTmp, '\"');
|
||||
if ((NULL == pcPos) || (pcPos < pcTmp))
|
||||
{
|
||||
vdebug("Invalid string %s.\n", pcData);
|
||||
return JSON_FAILED;
|
||||
}
|
||||
|
||||
*ppcEnd = pcPos + 1;
|
||||
uiLen = (uint32_t)(unsigned long)(pcPos - pcTmp);
|
||||
|
||||
pstJson->enDataType = JSON_TYPE_STRING;
|
||||
pstJson->unData.pcStrVal = pcNewStart + (pcTmp - pcRawStart);
|
||||
pstJson->unData.pcStrVal[uiLen] = '\0';
|
||||
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
|
||||
static int vtoy_json_parse_array
|
||||
(
|
||||
char *pcNewStart,
|
||||
char *pcRawStart,
|
||||
VTOY_JSON *pstJson,
|
||||
const char *pcData,
|
||||
const char **ppcEnd
|
||||
)
|
||||
{
|
||||
int Ret = JSON_SUCCESS;
|
||||
VTOY_JSON *pstJsonChild = NULL;
|
||||
VTOY_JSON *pstJsonItem = NULL;
|
||||
const char *pcTmp = pcData + 1;
|
||||
|
||||
*ppcEnd = pcData;
|
||||
pstJson->enDataType = JSON_TYPE_ARRAY;
|
||||
|
||||
if ('[' != *pcData)
|
||||
{
|
||||
return JSON_FAILED;
|
||||
}
|
||||
|
||||
pcTmp = vtoy_json_skip(pcTmp);
|
||||
|
||||
if (']' == *pcTmp)
|
||||
{
|
||||
*ppcEnd = pcTmp + 1;
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
|
||||
JSON_NEW_ITEM(pstJson->pstChild, JSON_FAILED);
|
||||
|
||||
Ret = vtoy_json_parse_value(pcNewStart, pcRawStart, pstJson->pstChild, pcTmp, ppcEnd);
|
||||
if (JSON_SUCCESS != Ret)
|
||||
{
|
||||
vdebug("Failed to parse array child.\n");
|
||||
return JSON_FAILED;
|
||||
}
|
||||
|
||||
pstJsonChild = pstJson->pstChild;
|
||||
pcTmp = vtoy_json_skip(*ppcEnd);
|
||||
while ((NULL != pcTmp) && (',' == *pcTmp))
|
||||
{
|
||||
JSON_NEW_ITEM(pstJsonItem, JSON_FAILED);
|
||||
pstJsonChild->pstNext = pstJsonItem;
|
||||
pstJsonItem->pstPrev = pstJsonChild;
|
||||
pstJsonChild = pstJsonItem;
|
||||
|
||||
Ret = vtoy_json_parse_value(pcNewStart, pcRawStart, pstJsonChild, vtoy_json_skip(pcTmp + 1), ppcEnd);
|
||||
if (JSON_SUCCESS != Ret)
|
||||
{
|
||||
vdebug("Failed to parse array child.\n");
|
||||
return JSON_FAILED;
|
||||
}
|
||||
pcTmp = vtoy_json_skip(*ppcEnd);
|
||||
}
|
||||
|
||||
if ((NULL != pcTmp) && (']' == *pcTmp))
|
||||
{
|
||||
*ppcEnd = pcTmp + 1;
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppcEnd = pcTmp;
|
||||
return JSON_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
static int vtoy_json_parse_object
|
||||
(
|
||||
char *pcNewStart,
|
||||
char *pcRawStart,
|
||||
VTOY_JSON *pstJson,
|
||||
const char *pcData,
|
||||
const char **ppcEnd
|
||||
)
|
||||
{
|
||||
int Ret = JSON_SUCCESS;
|
||||
VTOY_JSON *pstJsonChild = NULL;
|
||||
VTOY_JSON *pstJsonItem = NULL;
|
||||
const char *pcTmp = pcData + 1;
|
||||
|
||||
*ppcEnd = pcData;
|
||||
pstJson->enDataType = JSON_TYPE_OBJECT;
|
||||
|
||||
if ('{' != *pcData)
|
||||
{
|
||||
return JSON_FAILED;
|
||||
}
|
||||
|
||||
pcTmp = vtoy_json_skip(pcTmp);
|
||||
if ('}' == *pcTmp)
|
||||
{
|
||||
*ppcEnd = pcTmp + 1;
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
|
||||
JSON_NEW_ITEM(pstJson->pstChild, JSON_FAILED);
|
||||
|
||||
Ret = vtoy_json_parse_string(pcNewStart, pcRawStart, pstJson->pstChild, pcTmp, ppcEnd);
|
||||
if (JSON_SUCCESS != Ret)
|
||||
{
|
||||
vdebug("Failed to parse array child.\n");
|
||||
return JSON_FAILED;
|
||||
}
|
||||
|
||||
pstJsonChild = pstJson->pstChild;
|
||||
pstJsonChild->pcName = pstJsonChild->unData.pcStrVal;
|
||||
pstJsonChild->unData.pcStrVal = NULL;
|
||||
|
||||
pcTmp = vtoy_json_skip(*ppcEnd);
|
||||
if ((NULL == pcTmp) || (':' != *pcTmp))
|
||||
{
|
||||
*ppcEnd = pcTmp;
|
||||
return JSON_FAILED;
|
||||
}
|
||||
|
||||
Ret = vtoy_json_parse_value(pcNewStart, pcRawStart, pstJsonChild, vtoy_json_skip(pcTmp + 1), ppcEnd);
|
||||
if (JSON_SUCCESS != Ret)
|
||||
{
|
||||
vdebug("Failed to parse array child.\n");
|
||||
return JSON_FAILED;
|
||||
}
|
||||
|
||||
pcTmp = vtoy_json_skip(*ppcEnd);
|
||||
while ((NULL != pcTmp) && (',' == *pcTmp))
|
||||
{
|
||||
JSON_NEW_ITEM(pstJsonItem, JSON_FAILED);
|
||||
pstJsonChild->pstNext = pstJsonItem;
|
||||
pstJsonItem->pstPrev = pstJsonChild;
|
||||
pstJsonChild = pstJsonItem;
|
||||
|
||||
Ret = vtoy_json_parse_string(pcNewStart, pcRawStart, pstJsonChild, vtoy_json_skip(pcTmp + 1), ppcEnd);
|
||||
if (JSON_SUCCESS != Ret)
|
||||
{
|
||||
vdebug("Failed to parse array child.\n");
|
||||
return JSON_FAILED;
|
||||
}
|
||||
|
||||
pcTmp = vtoy_json_skip(*ppcEnd);
|
||||
pstJsonChild->pcName = pstJsonChild->unData.pcStrVal;
|
||||
pstJsonChild->unData.pcStrVal = NULL;
|
||||
if ((NULL == pcTmp) || (':' != *pcTmp))
|
||||
{
|
||||
*ppcEnd = pcTmp;
|
||||
return JSON_FAILED;
|
||||
}
|
||||
|
||||
Ret = vtoy_json_parse_value(pcNewStart, pcRawStart, pstJsonChild, vtoy_json_skip(pcTmp + 1), ppcEnd);
|
||||
if (JSON_SUCCESS != Ret)
|
||||
{
|
||||
vdebug("Failed to parse array child.\n");
|
||||
return JSON_FAILED;
|
||||
}
|
||||
|
||||
pcTmp = vtoy_json_skip(*ppcEnd);
|
||||
}
|
||||
|
||||
if ((NULL != pcTmp) && ('}' == *pcTmp))
|
||||
{
|
||||
*ppcEnd = pcTmp + 1;
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppcEnd = pcTmp;
|
||||
return JSON_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int vtoy_json_parse_value
|
||||
(
|
||||
char *pcNewStart,
|
||||
char *pcRawStart,
|
||||
VTOY_JSON *pstJson,
|
||||
const char *pcData,
|
||||
const char **ppcEnd
|
||||
)
|
||||
{
|
||||
pcData = vtoy_json_skip(pcData);
|
||||
|
||||
switch (*pcData)
|
||||
{
|
||||
case 'n':
|
||||
{
|
||||
if (0 == strncmp(pcData, "null", 4))
|
||||
{
|
||||
pstJson->enDataType = JSON_TYPE_NULL;
|
||||
*ppcEnd = pcData + 4;
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'f':
|
||||
{
|
||||
if (0 == strncmp(pcData, "false", 5))
|
||||
{
|
||||
pstJson->enDataType = JSON_TYPE_BOOL;
|
||||
pstJson->unData.lValue = 0;
|
||||
*ppcEnd = pcData + 5;
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 't':
|
||||
{
|
||||
if (0 == strncmp(pcData, "true", 4))
|
||||
{
|
||||
pstJson->enDataType = JSON_TYPE_BOOL;
|
||||
pstJson->unData.lValue = 1;
|
||||
*ppcEnd = pcData + 4;
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '\"':
|
||||
{
|
||||
return vtoy_json_parse_string(pcNewStart, pcRawStart, pstJson, pcData, ppcEnd);
|
||||
}
|
||||
case '[':
|
||||
{
|
||||
return vtoy_json_parse_array(pcNewStart, pcRawStart, pstJson, pcData, ppcEnd);
|
||||
}
|
||||
case '{':
|
||||
{
|
||||
return vtoy_json_parse_object(pcNewStart, pcRawStart, pstJson, pcData, ppcEnd);
|
||||
}
|
||||
case '-':
|
||||
{
|
||||
return vtoy_json_parse_number(pstJson, pcData, ppcEnd);
|
||||
}
|
||||
default :
|
||||
{
|
||||
if (*pcData >= '0' && *pcData <= '9')
|
||||
{
|
||||
return vtoy_json_parse_number(pstJson, pcData, ppcEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*ppcEnd = pcData;
|
||||
vdebug("Invalid json data %u.\n", (uint8_t)(*pcData));
|
||||
return JSON_FAILED;
|
||||
}
|
||||
|
||||
VTOY_JSON * vtoy_json_create(void)
|
||||
{
|
||||
VTOY_JSON *pstJson = NULL;
|
||||
|
||||
pstJson = (VTOY_JSON *)zalloc(sizeof(VTOY_JSON));
|
||||
if (NULL == pstJson)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pstJson;
|
||||
}
|
||||
|
||||
int vtoy_json_parse(VTOY_JSON *pstJson, const char *szJsonData)
|
||||
{
|
||||
uint32_t uiMemSize = 0;
|
||||
int Ret = JSON_SUCCESS;
|
||||
char *pcNewBuf = NULL;
|
||||
const char *pcEnd = NULL;
|
||||
|
||||
uiMemSize = strlen(szJsonData) + 1;
|
||||
pcNewBuf = (char *)malloc(uiMemSize);
|
||||
if (NULL == pcNewBuf)
|
||||
{
|
||||
vdebug("Failed to alloc new buf.\n");
|
||||
return JSON_FAILED;
|
||||
}
|
||||
memcpy(pcNewBuf, szJsonData, uiMemSize);
|
||||
pcNewBuf[uiMemSize - 1] = 0;
|
||||
|
||||
Ret = vtoy_json_parse_value(pcNewBuf, (char *)szJsonData, pstJson, szJsonData, &pcEnd);
|
||||
if (JSON_SUCCESS != Ret)
|
||||
{
|
||||
vdebug("Failed to parse json data %s start=%p, end=%p:%s.\n",
|
||||
szJsonData, szJsonData, pcEnd, pcEnd);
|
||||
return JSON_FAILED;
|
||||
}
|
||||
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
|
||||
int vtoy_json_scan_parse
|
||||
(
|
||||
const VTOY_JSON *pstJson,
|
||||
uint32_t uiParseNum,
|
||||
VTOY_JSON_PARSE_S *pstJsonParse
|
||||
)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
const VTOY_JSON *pstJsonCur = NULL;
|
||||
VTOY_JSON_PARSE_S *pstCurParse = NULL;
|
||||
|
||||
for (pstJsonCur = pstJson; NULL != pstJsonCur; pstJsonCur = pstJsonCur->pstNext)
|
||||
{
|
||||
if ((JSON_TYPE_OBJECT == pstJsonCur->enDataType) ||
|
||||
(JSON_TYPE_ARRAY == pstJsonCur->enDataType))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0, pstCurParse = NULL; i < uiParseNum; i++)
|
||||
{
|
||||
if (0 == strcmp(pstJsonParse[i].pcKey, pstJsonCur->pcName))
|
||||
{
|
||||
pstCurParse = pstJsonParse + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL == pstCurParse)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (pstJsonCur->enDataType)
|
||||
{
|
||||
case JSON_TYPE_NUMBER:
|
||||
{
|
||||
if (sizeof(uint32_t) == pstCurParse->uiBufSize)
|
||||
{
|
||||
*(uint32_t *)(pstCurParse->pDataBuf) = (uint32_t)pstJsonCur->unData.lValue;
|
||||
}
|
||||
else if (sizeof(uint16_t) == pstCurParse->uiBufSize)
|
||||
{
|
||||
*(uint16_t *)(pstCurParse->pDataBuf) = (uint16_t)pstJsonCur->unData.lValue;
|
||||
}
|
||||
else if (sizeof(uint8_t) == pstCurParse->uiBufSize)
|
||||
{
|
||||
*(uint8_t *)(pstCurParse->pDataBuf) = (uint8_t)pstJsonCur->unData.lValue;
|
||||
}
|
||||
else if ((pstCurParse->uiBufSize > sizeof(uint64_t)))
|
||||
{
|
||||
snprintf((char *)pstCurParse->pDataBuf, pstCurParse->uiBufSize, "%llu",
|
||||
(unsigned long long)(pstJsonCur->unData.lValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
vdebug("Invalid number data buf size %u.\n", pstCurParse->uiBufSize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case JSON_TYPE_STRING:
|
||||
{
|
||||
strncpy((char *)pstCurParse->pDataBuf, pstJsonCur->unData.pcStrVal, pstCurParse->uiBufSize);
|
||||
break;
|
||||
}
|
||||
case JSON_TYPE_BOOL:
|
||||
{
|
||||
*(uint8_t *)(pstCurParse->pDataBuf) = (pstJsonCur->unData.lValue) > 0 ? 1 : 0;
|
||||
break;
|
||||
}
|
||||
default :
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
|
||||
int vtoy_json_scan_array
|
||||
(
|
||||
VTOY_JSON *pstJson,
|
||||
const char *szKey,
|
||||
VTOY_JSON **ppstArrayItem
|
||||
)
|
||||
{
|
||||
VTOY_JSON *pstJsonItem = NULL;
|
||||
|
||||
pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_ARRAY, szKey);
|
||||
if (NULL == pstJsonItem)
|
||||
{
|
||||
vdebug("Key %s is not found in json data.\n", szKey);
|
||||
return JSON_NOT_FOUND;
|
||||
}
|
||||
|
||||
*ppstArrayItem = pstJsonItem;
|
||||
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
|
||||
int vtoy_json_scan_array_ex
|
||||
(
|
||||
VTOY_JSON *pstJson,
|
||||
const char *szKey,
|
||||
VTOY_JSON **ppstArrayItem
|
||||
)
|
||||
{
|
||||
VTOY_JSON *pstJsonItem = NULL;
|
||||
|
||||
pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_ARRAY, szKey);
|
||||
if (NULL == pstJsonItem)
|
||||
{
|
||||
vdebug("Key %s is not found in json data.\n", szKey);
|
||||
return JSON_NOT_FOUND;
|
||||
}
|
||||
|
||||
*ppstArrayItem = pstJsonItem->pstChild;
|
||||
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
|
||||
int vtoy_json_scan_object
|
||||
(
|
||||
VTOY_JSON *pstJson,
|
||||
const char *szKey,
|
||||
VTOY_JSON **ppstObjectItem
|
||||
)
|
||||
{
|
||||
VTOY_JSON *pstJsonItem = NULL;
|
||||
|
||||
pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_OBJECT, szKey);
|
||||
if (NULL == pstJsonItem)
|
||||
{
|
||||
vdebug("Key %s is not found in json data.\n", szKey);
|
||||
return JSON_NOT_FOUND;
|
||||
}
|
||||
|
||||
*ppstObjectItem = pstJsonItem;
|
||||
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
|
||||
int vtoy_json_get_int
|
||||
(
|
||||
VTOY_JSON *pstJson,
|
||||
const char *szKey,
|
||||
int *piValue
|
||||
)
|
||||
{
|
||||
VTOY_JSON *pstJsonItem = NULL;
|
||||
|
||||
pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_NUMBER, szKey);
|
||||
if (NULL == pstJsonItem)
|
||||
{
|
||||
vdebug("Key %s is not found in json data.\n", szKey);
|
||||
return JSON_NOT_FOUND;
|
||||
}
|
||||
|
||||
*piValue = (int)pstJsonItem->unData.lValue;
|
||||
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
|
||||
int vtoy_json_get_uint
|
||||
(
|
||||
VTOY_JSON *pstJson,
|
||||
const char *szKey,
|
||||
uint32_t *puiValue
|
||||
)
|
||||
{
|
||||
VTOY_JSON *pstJsonItem = NULL;
|
||||
|
||||
pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_NUMBER, szKey);
|
||||
if (NULL == pstJsonItem)
|
||||
{
|
||||
vdebug("Key %s is not found in json data.\n", szKey);
|
||||
return JSON_NOT_FOUND;
|
||||
}
|
||||
|
||||
*puiValue = (uint32_t)pstJsonItem->unData.lValue;
|
||||
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
|
||||
int vtoy_json_get_uint64
|
||||
(
|
||||
VTOY_JSON *pstJson,
|
||||
const char *szKey,
|
||||
uint64_t *pui64Value
|
||||
)
|
||||
{
|
||||
VTOY_JSON *pstJsonItem = NULL;
|
||||
|
||||
pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_NUMBER, szKey);
|
||||
if (NULL == pstJsonItem)
|
||||
{
|
||||
vdebug("Key %s is not found in json data.\n", szKey);
|
||||
return JSON_NOT_FOUND;
|
||||
}
|
||||
|
||||
*pui64Value = (uint64_t)pstJsonItem->unData.lValue;
|
||||
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
|
||||
int vtoy_json_get_bool
|
||||
(
|
||||
VTOY_JSON *pstJson,
|
||||
const char *szKey,
|
||||
uint8_t *pbValue
|
||||
)
|
||||
{
|
||||
VTOY_JSON *pstJsonItem = NULL;
|
||||
|
||||
pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_BOOL, szKey);
|
||||
if (NULL == pstJsonItem)
|
||||
{
|
||||
vdebug("Key %s is not found in json data.\n", szKey);
|
||||
return JSON_NOT_FOUND;
|
||||
}
|
||||
|
||||
*pbValue = pstJsonItem->unData.lValue > 0 ? 1 : 0;
|
||||
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
|
||||
int vtoy_json_get_string
|
||||
(
|
||||
VTOY_JSON *pstJson,
|
||||
const char *szKey,
|
||||
uint32_t uiBufLen,
|
||||
char *pcBuf
|
||||
)
|
||||
{
|
||||
VTOY_JSON *pstJsonItem = NULL;
|
||||
|
||||
pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_STRING, szKey);
|
||||
if (NULL == pstJsonItem)
|
||||
{
|
||||
vdebug("Key %s is not found in json data.\n", szKey);
|
||||
return JSON_NOT_FOUND;
|
||||
}
|
||||
|
||||
strncpy(pcBuf, pstJsonItem->unData.pcStrVal, uiBufLen);
|
||||
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
|
||||
const char * vtoy_json_get_string_ex(VTOY_JSON *pstJson, const char *szKey)
|
||||
{
|
||||
VTOY_JSON *pstJsonItem = NULL;
|
||||
|
||||
if ((NULL == pstJson) || (NULL == szKey))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_STRING, szKey);
|
||||
if (NULL == pstJsonItem)
|
||||
{
|
||||
vdebug("Key %s is not found in json data.\n", szKey);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pstJsonItem->unData.pcStrVal;
|
||||
}
|
||||
|
||||
int vtoy_json_destroy(VTOY_JSON *pstJson)
|
||||
{
|
||||
if (NULL == pstJson)
|
||||
{
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
|
||||
if (NULL != pstJson->pstChild)
|
||||
{
|
||||
vtoy_json_free(pstJson->pstChild);
|
||||
}
|
||||
|
||||
if (NULL != pstJson->pstNext)
|
||||
{
|
||||
vtoy_json_free(pstJson->pstNext);
|
||||
}
|
||||
|
||||
free(pstJson);
|
||||
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
|
267
LinuxGUI/Ventoy2Disk/Core/ventoy_json.h
Normal file
267
LinuxGUI/Ventoy2Disk/Core/ventoy_json.h
Normal file
|
@ -0,0 +1,267 @@
|
|||
/******************************************************************************
|
||||
* ventoy_json.h
|
||||
*
|
||||
* Copyright (c) 2021, longpanda <admin@ventoy.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifndef __VENTOY_JSON_H__
|
||||
#define __VENTOY_JSON_H__
|
||||
|
||||
#define JSON_NEW_ITEM(pstJson, ret) \
|
||||
{ \
|
||||
(pstJson) = (VTOY_JSON *)zalloc(sizeof(VTOY_JSON)); \
|
||||
if (NULL == (pstJson)) \
|
||||
{ \
|
||||
vdebug("Failed to alloc memory for json."); \
|
||||
return (ret); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ssprintf(curpos, buf, len, fmt, args...) \
|
||||
curpos += snprintf(buf + curpos, len - curpos, fmt, ##args)
|
||||
|
||||
#define VTOY_JSON_IS_SKIPABLE(c) (((c) <= 32) ? 1 : 0)
|
||||
|
||||
#define VTOY_JSON_PRINT_PREFIX(uiDepth, args...) \
|
||||
{ \
|
||||
uint32_t _uiLoop = 0; \
|
||||
for (_uiLoop = 0; _uiLoop < (uiDepth); _uiLoop++) \
|
||||
{ \
|
||||
ssprintf(uiCurPos, pcBuf, uiBufLen, " "); \
|
||||
} \
|
||||
ssprintf(uiCurPos, pcBuf, uiBufLen, ##args); \
|
||||
}
|
||||
|
||||
#define VTOY_JSON_SUCCESS_RET "{ \"result\" : \"success\" }"
|
||||
#define VTOY_JSON_FAILED_RET "{ \"result\" : \"failed\" }"
|
||||
#define VTOY_JSON_INVALID_RET "{ \"result\" : \"invalidfmt\" }"
|
||||
#define VTOY_JSON_TOKEN_ERR_RET "{ \"result\" : \"tokenerror\" }"
|
||||
#define VTOY_JSON_EXIST_RET "{ \"result\" : \"exist\" }"
|
||||
#define VTOY_JSON_TIMEOUT_RET "{ \"result\" : \"timeout\" }"
|
||||
#define VTOY_JSON_BUSY_RET "{ \"result\" : \"busy\" }"
|
||||
#define VTOY_JSON_INUSE_RET "{ \"result\" : \"inuse\" }"
|
||||
#define VTOY_JSON_NOTFOUND_RET "{ \"result\" : \"notfound\" }"
|
||||
#define VTOY_JSON_NOTRUNNING_RET "{ \"result\" : \"notrunning\" }"
|
||||
#define VTOY_JSON_NOT_READY_RET "{ \"result\" : \"notready\" }"
|
||||
#define VTOY_JSON_NOT_SUPPORT_RET "{ \"result\" : \"notsupport\" }"
|
||||
#define VTOY_JSON_MBR_2TB_RET "{ \"result\" : \"mbr2tb\" }"
|
||||
#define VTOY_JSON_INVALID_RSV_RET "{ \"result\" : \"reserve_invalid\" }"
|
||||
#define VTOY_JSON_FILE_NOT_FOUND_RET "{ \"result\" : \"file_not_found\" }"
|
||||
|
||||
typedef enum tagJSON_TYPE
|
||||
{
|
||||
JSON_TYPE_NUMBER = 0,
|
||||
JSON_TYPE_STRING,
|
||||
JSON_TYPE_BOOL,
|
||||
JSON_TYPE_ARRAY,
|
||||
JSON_TYPE_OBJECT,
|
||||
JSON_TYPE_NULL,
|
||||
JSON_TYPE_BUTT
|
||||
}JSON_TYPE;
|
||||
|
||||
typedef struct tagVTOY_JSON
|
||||
{
|
||||
struct tagVTOY_JSON *pstPrev;
|
||||
struct tagVTOY_JSON *pstNext;
|
||||
struct tagVTOY_JSON *pstChild;
|
||||
|
||||
JSON_TYPE enDataType;
|
||||
union
|
||||
{
|
||||
char *pcStrVal;
|
||||
int iNumVal;
|
||||
uint64_t lValue;
|
||||
}unData;
|
||||
|
||||
char *pcName;
|
||||
}VTOY_JSON;
|
||||
|
||||
#define VTOY_JSON_FMT_BEGIN(uiCurPos, pcBuf, uiBufLen) \
|
||||
{\
|
||||
uint32_t __uiCurPos = (uiCurPos);\
|
||||
uint32_t __uiBufLen = (uiBufLen);\
|
||||
char *__pcBuf = (pcBuf);
|
||||
|
||||
#define VTOY_JSON_FMT_END(uiCurPos) \
|
||||
(uiCurPos) = __uiCurPos;\
|
||||
}
|
||||
|
||||
#define VTOY_JSON_FMT_OBJ_BEGIN() ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "{")
|
||||
|
||||
#define VTOY_JSON_FMT_OBJ_END() \
|
||||
{\
|
||||
if (',' == *(__pcBuf + (__uiCurPos - 1)))\
|
||||
{\
|
||||
__uiCurPos -= 1;\
|
||||
}\
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "}");\
|
||||
}
|
||||
|
||||
#define VTOY_JSON_FMT_OBJ_ENDEX() \
|
||||
{\
|
||||
if (',' == *(__pcBuf + (__uiCurPos - 1)))\
|
||||
{\
|
||||
__uiCurPos -= 1;\
|
||||
}\
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "},");\
|
||||
}
|
||||
|
||||
#define VTOY_JSON_FMT_KEY(Key) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":", (Key))
|
||||
|
||||
#define VTOY_JSON_FMT_ITEM(Item) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\",", (Item))
|
||||
|
||||
#define VTOY_JSON_FMT_COMA() ssprintf(__uiCurPos, __pcBuf, __uiBufLen, ",");
|
||||
|
||||
#define VTOY_JSON_FMT_APPEND_BEGIN() \
|
||||
{ \
|
||||
if ('}' == *(__pcBuf + (__uiCurPos - 1)))\
|
||||
{\
|
||||
__uiCurPos -= 1;\
|
||||
}\
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, ",");\
|
||||
}
|
||||
|
||||
#define VTOY_JSON_FMT_APPEND_END() \
|
||||
{ \
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "}");\
|
||||
}
|
||||
|
||||
#define VTOY_JSON_FMT_ARY_BEGIN() ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "[")
|
||||
|
||||
#define VTOY_JSON_FMT_ARY_END() \
|
||||
{\
|
||||
if (',' == *(__pcBuf + (__uiCurPos - 1)))\
|
||||
{\
|
||||
__uiCurPos -= 1;\
|
||||
}\
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "]");\
|
||||
}
|
||||
|
||||
#define VTOY_JSON_FMT_ARY_ENDEX() \
|
||||
{\
|
||||
if (',' == *(__pcBuf + (__uiCurPos - 1)))\
|
||||
{\
|
||||
__uiCurPos -= 1;\
|
||||
}\
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "],");\
|
||||
}
|
||||
|
||||
#define VTOY_JSON_FMT_UINT64(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":%llu,", Key, (_ull)Val)
|
||||
|
||||
#define VTOY_JSON_FMT_ULONG(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":%lu,", Key, Val)
|
||||
#define VTOY_JSON_FMT_LONG(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":%ld,", Key, Val)
|
||||
|
||||
#define VTOY_JSON_FMT_UINT(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":%u,", Key, Val)
|
||||
|
||||
#define VTOY_JSON_FMT_STRINT(Key, Val) \
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":\"%u\",", Key, Val)
|
||||
|
||||
#define VTOY_JSON_FMT_STRINT64(Key, Val) \
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":\"%llu\",", Key, Val)
|
||||
|
||||
#define VTOY_JSON_FMT_SINT(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":%d,", Key, Val)
|
||||
|
||||
#define VTOY_JSON_FMT_DUBL(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":%.1lf,", Key, Val)
|
||||
#define VTOY_JSON_FMT_DUBL2(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":%10.02lf,", Key, Val)
|
||||
|
||||
#define VTOY_JSON_FMT_STRN(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":\"%s\",", Key, Val)
|
||||
|
||||
#define VTOY_JSON_FMT_NULL(Key) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":null,", Key)
|
||||
|
||||
#define VTOY_JSON_FMT_TRUE(Key) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":true,", (Key))
|
||||
#define VTOY_JSON_FMT_FALSE(Key) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":false,", (Key))
|
||||
|
||||
#define VTOY_JSON_FMT_BOOL(Key, Val) \
|
||||
{\
|
||||
if (0 == (Val))\
|
||||
{\
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":false,", (Key));\
|
||||
}\
|
||||
else \
|
||||
{\
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":true,", (Key));\
|
||||
}\
|
||||
}
|
||||
|
||||
typedef struct tagVTOY_JSON_PARSE
|
||||
{
|
||||
char *pcKey;
|
||||
void *pDataBuf;
|
||||
uint32_t uiBufSize;
|
||||
}VTOY_JSON_PARSE_S;
|
||||
|
||||
#define JSON_SUCCESS 0
|
||||
#define JSON_FAILED 1
|
||||
#define JSON_NOT_FOUND 2
|
||||
|
||||
int vtoy_json_parse_value
|
||||
(
|
||||
char *pcNewStart,
|
||||
char *pcRawStart,
|
||||
VTOY_JSON *pstJson,
|
||||
const char *pcData,
|
||||
const char **ppcEnd
|
||||
);
|
||||
VTOY_JSON * vtoy_json_create(void);
|
||||
int vtoy_json_parse(VTOY_JSON *pstJson, const char *szJsonData);
|
||||
int vtoy_json_destroy(VTOY_JSON *pstJson);
|
||||
VTOY_JSON *vtoy_json_find_item
|
||||
(
|
||||
VTOY_JSON *pstJson,
|
||||
JSON_TYPE enDataType,
|
||||
const char *szKey
|
||||
);
|
||||
int vtoy_json_scan_parse
|
||||
(
|
||||
const VTOY_JSON *pstJson,
|
||||
uint32_t uiParseNum,
|
||||
VTOY_JSON_PARSE_S *pstJsonParse
|
||||
);
|
||||
int vtoy_json_get_int
|
||||
(
|
||||
VTOY_JSON *pstJson,
|
||||
const char *szKey,
|
||||
int *piValue
|
||||
);
|
||||
int vtoy_json_get_uint
|
||||
(
|
||||
VTOY_JSON *pstJson,
|
||||
const char *szKey,
|
||||
uint32_t *puiValue
|
||||
);
|
||||
int vtoy_json_get_uint64
|
||||
(
|
||||
VTOY_JSON *pstJson,
|
||||
const char *szKey,
|
||||
uint64_t *pui64Value
|
||||
);
|
||||
int vtoy_json_get_bool
|
||||
(
|
||||
VTOY_JSON *pstJson,
|
||||
const char *szKey,
|
||||
uint8_t *pbValue
|
||||
);
|
||||
int vtoy_json_get_string
|
||||
(
|
||||
VTOY_JSON *pstJson,
|
||||
const char *szKey,
|
||||
uint32_t uiBufLen,
|
||||
char *pcBuf
|
||||
);
|
||||
const char * vtoy_json_get_string_ex(VTOY_JSON *pstJson, const char *szKey);
|
||||
|
||||
#endif /* __VENTOY_JSON_H__ */
|
||||
|
115
LinuxGUI/Ventoy2Disk/Core/ventoy_log.c
Normal file
115
LinuxGUI/Ventoy2Disk/Core/ventoy_log.c
Normal file
|
@ -0,0 +1,115 @@
|
|||
/******************************************************************************
|
||||
* ventoy_log.c ---- ventoy log
|
||||
*
|
||||
* Copyright (c) 2021, longpanda <admin@ventoy.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include <ventoy_define.h>
|
||||
|
||||
static int g_ventoy_log_level = VLOG_DEBUG;
|
||||
static pthread_mutex_t g_log_mutex;
|
||||
|
||||
int ventoy_log_init(void)
|
||||
{
|
||||
pthread_mutex_init(&g_log_mutex, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ventoy_log_exit(void)
|
||||
{
|
||||
pthread_mutex_destroy(&g_log_mutex);
|
||||
}
|
||||
|
||||
void ventoy_set_loglevel(int level)
|
||||
{
|
||||
g_ventoy_log_level = level;
|
||||
}
|
||||
|
||||
void ventoy_syslog_newline(int level, const char *Fmt, ...)
|
||||
{
|
||||
char log[512];
|
||||
va_list arg;
|
||||
time_t stamp;
|
||||
struct tm ttm;
|
||||
FILE *fp;
|
||||
|
||||
if (level > g_ventoy_log_level)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
time(&stamp);
|
||||
localtime_r(&stamp, &ttm);
|
||||
|
||||
va_start(arg, Fmt);
|
||||
vsnprintf(log, 512, Fmt, arg);
|
||||
va_end(arg);
|
||||
|
||||
pthread_mutex_lock(&g_log_mutex);
|
||||
fp = fopen(VTOY_LOG_FILE, "a+");
|
||||
if (fp)
|
||||
{
|
||||
fprintf(fp, "[%04u/%02u/%02u %02u:%02u:%02u] %s\n",
|
||||
ttm.tm_year, ttm.tm_mon, ttm.tm_mday,
|
||||
ttm.tm_hour, ttm.tm_min, ttm.tm_sec,
|
||||
log);
|
||||
fclose(fp);
|
||||
}
|
||||
pthread_mutex_unlock(&g_log_mutex);
|
||||
}
|
||||
|
||||
void ventoy_syslog(int level, const char *Fmt, ...)
|
||||
{
|
||||
char log[512];
|
||||
va_list arg;
|
||||
time_t stamp;
|
||||
struct tm ttm;
|
||||
FILE *fp;
|
||||
|
||||
if (level > g_ventoy_log_level)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
time(&stamp);
|
||||
localtime_r(&stamp, &ttm);
|
||||
|
||||
va_start(arg, Fmt);
|
||||
vsnprintf(log, 512, Fmt, arg);
|
||||
va_end(arg);
|
||||
|
||||
pthread_mutex_lock(&g_log_mutex);
|
||||
fp = fopen(VTOY_LOG_FILE, "a+");
|
||||
if (fp)
|
||||
{
|
||||
fprintf(fp, "[%04u/%02u/%02u %02u:%02u:%02u] %s",
|
||||
ttm.tm_year, ttm.tm_mon, ttm.tm_mday,
|
||||
ttm.tm_hour, ttm.tm_min, ttm.tm_sec,
|
||||
log);
|
||||
fclose(fp);
|
||||
}
|
||||
pthread_mutex_unlock(&g_log_mutex);
|
||||
}
|
||||
|
167
LinuxGUI/Ventoy2Disk/Core/ventoy_md5.c
Normal file
167
LinuxGUI/Ventoy2Disk/Core/ventoy_md5.c
Normal file
|
@ -0,0 +1,167 @@
|
|||
/******************************************************************************
|
||||
* ventoy_md5.c ---- ventoy md5
|
||||
*
|
||||
* Copyright (c) 2021, longpanda <admin@ventoy.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
const static uint32_t k[64] =
|
||||
{
|
||||
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
|
||||
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
|
||||
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
|
||||
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
|
||||
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
|
||||
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
|
||||
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
|
||||
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
|
||||
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
|
||||
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
|
||||
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
|
||||
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
|
||||
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
|
||||
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
|
||||
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
|
||||
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
|
||||
};
|
||||
|
||||
const static uint32_t r[] =
|
||||
{
|
||||
7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
|
||||
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
|
||||
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
|
||||
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
|
||||
};
|
||||
|
||||
#define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
|
||||
#define to_bytes(val, bytes) *((uint32_t *)(bytes)) = (val)
|
||||
|
||||
#define ROTATE_CALC() \
|
||||
{\
|
||||
temp = d; \
|
||||
d = c; \
|
||||
c = b; \
|
||||
b = b + LEFTROTATE((a + f + k[i] + w[g]), r[i]); \
|
||||
a = temp; \
|
||||
}
|
||||
|
||||
void ventoy_md5(const void *data, uint32_t len, uint8_t *md5)
|
||||
{
|
||||
uint32_t h0, h1, h2, h3;
|
||||
uint32_t w[16];
|
||||
uint32_t a, b, c, d, i, f, g, temp;
|
||||
uint32_t offset, mod, delta;
|
||||
uint8_t postbuf[128] = {0};
|
||||
|
||||
// Initialize variables - simple count in nibbles:
|
||||
h0 = 0x67452301;
|
||||
h1 = 0xefcdab89;
|
||||
h2 = 0x98badcfe;
|
||||
h3 = 0x10325476;
|
||||
|
||||
//Pre-processing:
|
||||
//append "1" bit to message
|
||||
//append "0" bits until message length in bits ≡ 448 (mod 512)
|
||||
//append length mod (2^64) to message
|
||||
|
||||
mod = len % 64;
|
||||
if (mod)
|
||||
{
|
||||
memcpy(postbuf, (const uint8_t *)data + len - mod, mod);
|
||||
}
|
||||
|
||||
postbuf[mod] = 0x80;
|
||||
if (mod < 56)
|
||||
{
|
||||
to_bytes(len * 8, postbuf + 56);
|
||||
to_bytes(len >> 29, postbuf + 60);
|
||||
delta = 64;
|
||||
}
|
||||
else
|
||||
{
|
||||
to_bytes(len * 8, postbuf + 120);
|
||||
to_bytes(len >> 29, postbuf + 124);
|
||||
delta = 128;
|
||||
}
|
||||
|
||||
len -= mod;
|
||||
|
||||
for (offset = 0; offset < len + delta; offset += 64)
|
||||
{
|
||||
if (offset < len)
|
||||
{
|
||||
memcpy(w, (const uint8_t *)data + offset, 64);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(w, postbuf + offset - len, 64);
|
||||
}
|
||||
|
||||
// Initialize hash value for this chunk:
|
||||
a = h0;
|
||||
b = h1;
|
||||
c = h2;
|
||||
d = h3;
|
||||
|
||||
// Main loop:
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
f = (b & c) | ((~b) & d);
|
||||
g = i;
|
||||
ROTATE_CALC();
|
||||
}
|
||||
|
||||
for (i = 16; i < 32; i++)
|
||||
{
|
||||
f = (d & b) | ((~d) & c);
|
||||
g = (5 * i + 1) % 16;
|
||||
ROTATE_CALC();
|
||||
}
|
||||
|
||||
for (i = 32; i < 48; i++)
|
||||
{
|
||||
f = b ^ c ^ d;
|
||||
g = (3 * i + 5) % 16;
|
||||
ROTATE_CALC();
|
||||
}
|
||||
|
||||
for (i = 48; i < 64; i++)
|
||||
{
|
||||
f = c ^ (b | (~d));
|
||||
g = (7 * i) % 16;
|
||||
ROTATE_CALC();
|
||||
}
|
||||
|
||||
// Add this chunk's hash to result so far:
|
||||
h0 += a;
|
||||
h1 += b;
|
||||
h2 += c;
|
||||
h3 += d;
|
||||
}
|
||||
|
||||
//var char md5[16] := h0 append h1 append h2 append h3 //(Output is in little-endian)
|
||||
to_bytes(h0, md5);
|
||||
to_bytes(h1, md5 + 4);
|
||||
to_bytes(h2, md5 + 8);
|
||||
to_bytes(h3, md5 + 12);
|
||||
}
|
||||
|
541
LinuxGUI/Ventoy2Disk/Core/ventoy_util.c
Normal file
541
LinuxGUI/Ventoy2Disk/Core/ventoy_util.c
Normal file
|
@ -0,0 +1,541 @@
|
|||
/******************************************************************************
|
||||
* ventoy_util.c ---- ventoy util
|
||||
* Copyright (c) 2021, longpanda <admin@ventoy.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
#include <linux/fs.h>
|
||||
#include <dirent.h>
|
||||
#include <time.h>
|
||||
#include <ventoy_define.h>
|
||||
#include <ventoy_util.h>
|
||||
|
||||
uint8_t g_mbr_template[512];
|
||||
|
||||
void ventoy_gen_preudo_uuid(void *uuid)
|
||||
{
|
||||
int i;
|
||||
int fd;
|
||||
|
||||
fd = open("/dev/urandom", O_RDONLY | O_BINARY);
|
||||
if (fd < 0)
|
||||
{
|
||||
srand(time(NULL));
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
*((uint16_t *)uuid + i) = (uint16_t)(rand() & 0xFFFF);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
read(fd, uuid, 16);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t ventoy_get_human_readable_gb(uint64_t SizeBytes)
|
||||
{
|
||||
int i;
|
||||
int Pow2 = 1;
|
||||
double Delta;
|
||||
double GB = SizeBytes * 1.0 / 1000 / 1000 / 1000;
|
||||
|
||||
if ((SizeBytes % SIZE_1GB) == 0)
|
||||
{
|
||||
return (uint64_t)(SizeBytes / SIZE_1GB);
|
||||
}
|
||||
|
||||
for (i = 0; i < 12; i++)
|
||||
{
|
||||
if (Pow2 > GB)
|
||||
{
|
||||
Delta = (Pow2 - GB) / Pow2;
|
||||
}
|
||||
else
|
||||
{
|
||||
Delta = (GB - Pow2) / Pow2;
|
||||
}
|
||||
|
||||
if (Delta < 0.05)
|
||||
{
|
||||
return Pow2;
|
||||
}
|
||||
|
||||
Pow2 <<= 1;
|
||||
}
|
||||
|
||||
return (uint64_t)GB;
|
||||
}
|
||||
|
||||
|
||||
int ventoy_get_sys_file_line(char *buffer, int buflen, const char *fmt, ...)
|
||||
{
|
||||
int len;
|
||||
char c;
|
||||
char path[256];
|
||||
va_list arg;
|
||||
|
||||
va_start(arg, fmt);
|
||||
vsnprintf(path, 256, fmt, arg);
|
||||
va_end(arg);
|
||||
|
||||
if (access(path, F_OK) >= 0)
|
||||
{
|
||||
FILE *fp = fopen(path, "r");
|
||||
memset(buffer, 0, buflen);
|
||||
len = (int)fread(buffer, 1, buflen - 1, fp);
|
||||
fclose(fp);
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
c = buffer[len - 1];
|
||||
if (c == '\r' || c == '\n' || c == ' ' || c == '\t')
|
||||
{
|
||||
buffer[len - 1] = 0;
|
||||
len--;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
vdebug("%s not exist \n", path);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int ventoy_is_disk_mounted(const char *devpath)
|
||||
{
|
||||
int len;
|
||||
int mount = 0;
|
||||
char line[512];
|
||||
FILE *fp = NULL;
|
||||
|
||||
fp = fopen("/proc/mounts", "r");
|
||||
if (!fp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = (int)strlen(devpath);
|
||||
while (fgets(line, sizeof(line), fp))
|
||||
{
|
||||
if (strncmp(line, devpath, len) == 0)
|
||||
{
|
||||
mount = 1;
|
||||
vdebug("%s mounted <%s>\n", devpath, line);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
fclose(fp);
|
||||
return mount;
|
||||
}
|
||||
|
||||
int ventoy_try_umount_disk(const char *devpath)
|
||||
{
|
||||
int rc;
|
||||
int len;
|
||||
char line[512];
|
||||
char *pos1 = NULL;
|
||||
char *pos2 = NULL;
|
||||
FILE *fp = NULL;
|
||||
|
||||
fp = fopen("/proc/mounts", "r");
|
||||
if (!fp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = (int)strlen(devpath);
|
||||
while (fgets(line, sizeof(line), fp))
|
||||
{
|
||||
if (strncmp(line, devpath, len) == 0)
|
||||
{
|
||||
pos1 = strchr(line, ' ');
|
||||
if (pos1)
|
||||
{
|
||||
pos2 = strchr(pos1 + 1, ' ');
|
||||
if (pos2)
|
||||
{
|
||||
*pos2 = 0;
|
||||
}
|
||||
|
||||
rc = umount(pos1 + 1);
|
||||
if (rc)
|
||||
{
|
||||
vdebug("umount %s %s [ failed ] error:%d\n", devpath, pos1 + 1, errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
vdebug("umount %s %s [ success ]\n", devpath, pos1 + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ventoy_read_file_to_buf(const char *FileName, int ExtLen, void **Bufer, int *BufLen)
|
||||
{
|
||||
int FileSize;
|
||||
FILE *fp = NULL;
|
||||
void *Data = NULL;
|
||||
|
||||
fp = fopen(FileName, "rb");
|
||||
if (fp == NULL)
|
||||
{
|
||||
vlog("Failed to open file %s", FileName);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
FileSize = (int)ftell(fp);
|
||||
|
||||
Data = malloc(FileSize + ExtLen);
|
||||
if (!Data)
|
||||
{
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
fread(Data, 1, FileSize, fp);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
*Bufer = Data;
|
||||
*BufLen = FileSize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char * ventoy_get_local_version(void)
|
||||
{
|
||||
int rc;
|
||||
int FileSize;
|
||||
char *Pos = NULL;
|
||||
char *Buf = NULL;
|
||||
static char LocalVersion[64] = { 0 };
|
||||
|
||||
if (LocalVersion[0] == 0)
|
||||
{
|
||||
rc = ventoy_read_file_to_buf("ventoy/version", 1, (void **)&Buf, &FileSize);
|
||||
if (rc)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
Buf[FileSize] = 0;
|
||||
|
||||
for (Pos = Buf; *Pos; Pos++)
|
||||
{
|
||||
if (*Pos == '\r' || *Pos == '\n')
|
||||
{
|
||||
*Pos = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
scnprintf(LocalVersion, "%s", Buf);
|
||||
free(Buf);
|
||||
}
|
||||
|
||||
return LocalVersion;
|
||||
}
|
||||
|
||||
int VentoyGetLocalBootImg(MBR_HEAD *pMBR)
|
||||
{
|
||||
memcpy(pMBR, g_mbr_template, 512);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int VentoyFillProtectMBR(uint64_t DiskSizeBytes, MBR_HEAD *pMBR)
|
||||
{
|
||||
ventoy_guid Guid;
|
||||
uint32_t DiskSignature;
|
||||
uint64_t DiskSectorCount;
|
||||
|
||||
VentoyGetLocalBootImg(pMBR);
|
||||
|
||||
ventoy_gen_preudo_uuid(&Guid);
|
||||
|
||||
memcpy(&DiskSignature, &Guid, sizeof(uint32_t));
|
||||
|
||||
vdebug("Disk signature: 0x%08x\n", DiskSignature);
|
||||
|
||||
memcpy(pMBR->BootCode + 0x1B8, &DiskSignature, 4);
|
||||
|
||||
DiskSectorCount = DiskSizeBytes / 512 - 1;
|
||||
if (DiskSectorCount > 0xFFFFFFFF)
|
||||
{
|
||||
DiskSectorCount = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
memset(pMBR->PartTbl, 0, sizeof(pMBR->PartTbl));
|
||||
|
||||
pMBR->PartTbl[0].Active = 0x00;
|
||||
pMBR->PartTbl[0].FsFlag = 0xee; // EE
|
||||
|
||||
pMBR->PartTbl[0].StartHead = 0;
|
||||
pMBR->PartTbl[0].StartSector = 1;
|
||||
pMBR->PartTbl[0].StartCylinder = 0;
|
||||
pMBR->PartTbl[0].EndHead = 254;
|
||||
pMBR->PartTbl[0].EndSector = 63;
|
||||
pMBR->PartTbl[0].EndCylinder = 1023;
|
||||
|
||||
pMBR->PartTbl[0].StartSectorId = 1;
|
||||
pMBR->PartTbl[0].SectorCount = (uint32_t)DiskSectorCount;
|
||||
|
||||
pMBR->Byte55 = 0x55;
|
||||
pMBR->ByteAA = 0xAA;
|
||||
|
||||
pMBR->BootCode[92] = 0x22;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ventoy_fill_gpt_partname(uint16_t Name[36], const char *asciiName)
|
||||
{
|
||||
int i;
|
||||
int len;
|
||||
|
||||
memset(Name, 0, 36 * sizeof(uint16_t));
|
||||
len = (int)strlen(asciiName);
|
||||
for (i = 0; i < 36 && i < len; i++)
|
||||
{
|
||||
Name[i] = asciiName[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ventoy_fill_gpt(uint64_t size, uint64_t reserve, int align4k, VTOY_GPT_INFO *gpt)
|
||||
{
|
||||
uint64_t ReservedSector = 33;
|
||||
uint64_t Part1SectorCount = 0;
|
||||
uint64_t DiskSectorCount = size / 512;
|
||||
VTOY_GPT_HDR *Head = &gpt->Head;
|
||||
VTOY_GPT_PART_TBL *Table = gpt->PartTbl;
|
||||
ventoy_guid WindowsDataPartType = { 0xebd0a0a2, 0xb9e5, 0x4433, { 0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7 } };
|
||||
//ventoy_guid EspPartType = { 0xc12a7328, 0xf81f, 0x11d2, { 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } };
|
||||
//ventoy_guid BiosGrubPartType = { 0x21686148, 0x6449, 0x6e6f, { 0x74, 0x4e, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49 } };
|
||||
|
||||
VentoyFillProtectMBR(size, &gpt->MBR);
|
||||
|
||||
if (reserve > 0)
|
||||
{
|
||||
ReservedSector += reserve / 512;
|
||||
}
|
||||
|
||||
// check aligned with 4KB
|
||||
if (align4k)
|
||||
{
|
||||
if (DiskSectorCount % 8)
|
||||
{
|
||||
vdebug("Disk need to align with 4KB %u\n", (uint32_t)(DiskSectorCount % 8));
|
||||
ReservedSector += (DiskSectorCount % 8);
|
||||
}
|
||||
}
|
||||
|
||||
Part1SectorCount = DiskSectorCount - ReservedSector - (VTOYEFI_PART_BYTES / 512) - 2048;
|
||||
|
||||
memcpy(Head->Signature, "EFI PART", 8);
|
||||
Head->Version[2] = 0x01;
|
||||
Head->Length = 92;
|
||||
Head->Crc = 0;
|
||||
Head->EfiStartLBA = 1;
|
||||
Head->EfiBackupLBA = DiskSectorCount - 1;
|
||||
Head->PartAreaStartLBA = 34;
|
||||
Head->PartAreaEndLBA = DiskSectorCount - 34;
|
||||
ventoy_gen_preudo_uuid(&Head->DiskGuid);
|
||||
Head->PartTblStartLBA = 2;
|
||||
Head->PartTblTotNum = 128;
|
||||
Head->PartTblEntryLen = 128;
|
||||
|
||||
|
||||
memcpy(&(Table[0].PartType), &WindowsDataPartType, sizeof(ventoy_guid));
|
||||
ventoy_gen_preudo_uuid(&(Table[0].PartGuid));
|
||||
Table[0].StartLBA = 2048;
|
||||
Table[0].LastLBA = 2048 + Part1SectorCount - 1;
|
||||
Table[0].Attr = 0;
|
||||
ventoy_fill_gpt_partname(Table[0].Name, "Ventoy");
|
||||
|
||||
// to fix windows issue
|
||||
//memcpy(&(Table[1].PartType), &EspPartType, sizeof(GUID));
|
||||
memcpy(&(Table[1].PartType), &WindowsDataPartType, sizeof(ventoy_guid));
|
||||
ventoy_gen_preudo_uuid(&(Table[1].PartGuid));
|
||||
Table[1].StartLBA = Table[0].LastLBA + 1;
|
||||
Table[1].LastLBA = Table[1].StartLBA + VTOYEFI_PART_BYTES / 512 - 1;
|
||||
Table[1].Attr = 0x8000000000000001ULL;
|
||||
ventoy_fill_gpt_partname(Table[1].Name, "VTOYEFI");
|
||||
|
||||
#if 0
|
||||
memcpy(&(Table[2].PartType), &BiosGrubPartType, sizeof(ventoy_guid));
|
||||
ventoy_gen_preudo_uuid(&(Table[2].PartGuid));
|
||||
Table[2].StartLBA = 34;
|
||||
Table[2].LastLBA = 2047;
|
||||
Table[2].Attr = 0;
|
||||
#endif
|
||||
|
||||
//Update CRC
|
||||
Head->PartTblCrc = ventoy_crc32(Table, sizeof(gpt->PartTbl));
|
||||
Head->Crc = ventoy_crc32(Head, Head->Length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int VentoyFillMBRLocation(uint64_t DiskSizeInBytes, uint32_t StartSectorId, uint32_t SectorCount, PART_TABLE *Table)
|
||||
{
|
||||
uint8_t Head;
|
||||
uint8_t Sector;
|
||||
uint8_t nSector = 63;
|
||||
uint8_t nHead = 8;
|
||||
uint32_t Cylinder;
|
||||
uint32_t EndSectorId;
|
||||
|
||||
while (nHead != 0 && (DiskSizeInBytes / 512 / nSector / nHead) > 1024)
|
||||
{
|
||||
nHead = (uint8_t)nHead * 2;
|
||||
}
|
||||
|
||||
if (nHead == 0)
|
||||
{
|
||||
nHead = 255;
|
||||
}
|
||||
|
||||
Cylinder = StartSectorId / nSector / nHead;
|
||||
Head = StartSectorId / nSector % nHead;
|
||||
Sector = StartSectorId % nSector + 1;
|
||||
|
||||
Table->StartHead = Head;
|
||||
Table->StartSector = Sector;
|
||||
Table->StartCylinder = Cylinder;
|
||||
|
||||
EndSectorId = StartSectorId + SectorCount - 1;
|
||||
Cylinder = EndSectorId / nSector / nHead;
|
||||
Head = EndSectorId / nSector % nHead;
|
||||
Sector = EndSectorId % nSector + 1;
|
||||
|
||||
Table->EndHead = Head;
|
||||
Table->EndSector = Sector;
|
||||
Table->EndCylinder = Cylinder;
|
||||
|
||||
Table->StartSectorId = StartSectorId;
|
||||
Table->SectorCount = SectorCount;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ventoy_fill_mbr(uint64_t size, uint64_t reserve, int align4k, int PartStyle, MBR_HEAD *pMBR)
|
||||
{
|
||||
ventoy_guid Guid;
|
||||
uint32_t DiskSignature;
|
||||
uint32_t DiskSectorCount;
|
||||
uint32_t PartSectorCount;
|
||||
uint32_t PartStartSector;
|
||||
uint32_t ReservedSector;
|
||||
|
||||
VentoyGetLocalBootImg(pMBR);
|
||||
|
||||
ventoy_gen_preudo_uuid(&Guid);
|
||||
|
||||
memcpy(&DiskSignature, &Guid, sizeof(uint32_t));
|
||||
|
||||
vdebug("Disk signature: 0x%08x\n", DiskSignature);
|
||||
|
||||
memcpy(pMBR->BootCode + 0x1B8, &DiskSignature, 4);
|
||||
|
||||
if (size / 512 > 0xFFFFFFFF)
|
||||
{
|
||||
DiskSectorCount = 0xFFFFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
DiskSectorCount = (uint32_t)(size / 512);
|
||||
}
|
||||
|
||||
if (reserve <= 0)
|
||||
{
|
||||
ReservedSector = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ReservedSector = (uint32_t)(reserve / 512);
|
||||
}
|
||||
|
||||
if (PartStyle)
|
||||
{
|
||||
ReservedSector += 33; // backup GPT part table
|
||||
}
|
||||
|
||||
// check aligned with 4KB
|
||||
if (align4k)
|
||||
{
|
||||
uint64_t sectors = size / 512;
|
||||
if (sectors % 8)
|
||||
{
|
||||
vlog("Disk need to align with 4KB %u\n", (uint32_t)(sectors % 8));
|
||||
ReservedSector += (uint32_t)(sectors % 8);
|
||||
}
|
||||
}
|
||||
|
||||
vlog("ReservedSector: %u\n", ReservedSector);
|
||||
|
||||
|
||||
//Part1
|
||||
PartStartSector = VTOYIMG_PART_START_SECTOR;
|
||||
PartSectorCount = DiskSectorCount - ReservedSector - VTOYEFI_PART_BYTES / 512 - PartStartSector;
|
||||
VentoyFillMBRLocation(size, PartStartSector, PartSectorCount, pMBR->PartTbl);
|
||||
|
||||
pMBR->PartTbl[0].Active = 0x80; // bootable
|
||||
pMBR->PartTbl[0].FsFlag = 0x07; // exFAT/NTFS/HPFS
|
||||
|
||||
//Part2
|
||||
PartStartSector += PartSectorCount;
|
||||
PartSectorCount = VTOYEFI_PART_BYTES / 512;
|
||||
VentoyFillMBRLocation(size, PartStartSector, PartSectorCount, pMBR->PartTbl + 1);
|
||||
|
||||
pMBR->PartTbl[1].Active = 0x00;
|
||||
pMBR->PartTbl[1].FsFlag = 0xEF; // EFI System Partition
|
||||
|
||||
pMBR->Byte55 = 0x55;
|
||||
pMBR->ByteAA = 0xAA;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
52
LinuxGUI/Ventoy2Disk/Core/ventoy_util.h
Normal file
52
LinuxGUI/Ventoy2Disk/Core/ventoy_util.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/******************************************************************************
|
||||
* ventoy_util.h
|
||||
*
|
||||
* Copyright (c) 2021, longpanda <admin@ventoy.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifndef __VENTOY_UTIL_H__
|
||||
#define __VENTOY_UTIL_H__
|
||||
|
||||
#define check_free(p) if (p) free(p)
|
||||
#define vtoy_safe_close_fd(fd) \
|
||||
{\
|
||||
if ((fd) >= 0) \
|
||||
{ \
|
||||
close(fd); \
|
||||
(fd) = -1; \
|
||||
}\
|
||||
}
|
||||
|
||||
extern uint8_t g_mbr_template[512];
|
||||
void ventoy_gen_preudo_uuid(void *uuid);
|
||||
int ventoy_get_disk_part_name(const char *dev, int part, char *partbuf, int bufsize);
|
||||
int ventoy_get_sys_file_line(char *buffer, int buflen, const char *fmt, ...);
|
||||
uint64_t ventoy_get_human_readable_gb(uint64_t SizeBytes);
|
||||
void ventoy_md5(const void *data, uint32_t len, uint8_t *md5);
|
||||
int ventoy_is_disk_mounted(const char *devpath);
|
||||
int ventoy_try_umount_disk(const char *devpath);
|
||||
int unxz(unsigned char *in, int in_size,
|
||||
int (*fill)(void *dest, unsigned int size),
|
||||
int (*flush)(void *src, unsigned int size),
|
||||
unsigned char *out, int *in_used,
|
||||
void (*error)(char *x));
|
||||
int ventoy_read_file_to_buf(const char *FileName, int ExtLen, void **Bufer, int *BufLen);
|
||||
const char * ventoy_get_local_version(void);
|
||||
int ventoy_fill_gpt(uint64_t size, uint64_t reserve, int align4k, VTOY_GPT_INFO *gpt);
|
||||
int ventoy_fill_mbr(uint64_t size, uint64_t reserve, int align4k, int PartStyle, MBR_HEAD *pMBR);
|
||||
|
||||
#endif /* __VENTOY_UTIL_H__ */
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue