mirror of
https://github.com/ventoy/Ventoy.git
synced 2025-08-28 16:31:14 +00:00
VentoyPlugson ---- A GUI ventoy.json configurator
This commit is contained in:
304
Plugson/src/Core/ventoy_crc32.c
Normal file
304
Plugson/src/Core/ventoy_crc32.c
Normal file
@@ -0,0 +1,304 @@
|
||||
/******************************************************************************
|
||||
* 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>
|
||||
#if defined(_MSC_VER) || defined(WIN32)
|
||||
#include <Windows.h>
|
||||
#define uint32_t UINT32
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
|
207
Plugson/src/Core/ventoy_define.h
Normal file
207
Plugson/src/Core/ventoy_define.h
Normal file
@@ -0,0 +1,207 @@
|
||||
/******************************************************************************
|
||||
* 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__
|
||||
|
||||
#if defined(_MSC_VER) || defined(WIN32)
|
||||
#include <windows.h>
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include <linux/limits.h>
|
||||
#endif
|
||||
|
||||
#define LOG_FILE "VentoyPlugson.log"
|
||||
|
||||
#define SIZE_1MB 1048576
|
||||
#define SIZE_1GB 1073741824
|
||||
#define JSON_BUF_MAX (8 * SIZE_1MB)
|
||||
#define TAR_BUF_MAX (8 * SIZE_1MB)
|
||||
|
||||
#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
|
||||
|
||||
|
||||
#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
|
||||
|
||||
#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
|
||||
|
||||
#if defined(_MSC_VER) || defined(WIN32)
|
||||
#define strlcpy(dst, src) strcpy_s(dst, sizeof(dst), src)
|
||||
#define scnprintf(dst, len, fmt, ...) sprintf_s(dst, len, fmt, ##__VA_ARGS__)
|
||||
|
||||
#define vlog(fmt, ...) ventoy_syslog(VLOG_LOG, fmt, ##__VA_ARGS__)
|
||||
#define vdebug(fmt, ...) ventoy_syslog(VLOG_DEBUG, fmt, ##__VA_ARGS__)
|
||||
|
||||
#define localtime_r(a,b) localtime_s(b,a)
|
||||
|
||||
#define LASTERR GetLastError()
|
||||
|
||||
#define CHECK_CLOSE_HANDLE(Handle) \
|
||||
{\
|
||||
if (Handle != INVALID_HANDLE_VALUE) \
|
||||
{\
|
||||
CloseHandle(Handle); \
|
||||
Handle = INVALID_HANDLE_VALUE; \
|
||||
}\
|
||||
}
|
||||
|
||||
#else
|
||||
#define strlcpy(dst, src) strncpy(dst, src, sizeof(dst) - 1)
|
||||
#define scnprintf(dst, len, fmt, args...) snprintf(dst, len, fmt, ##args)
|
||||
|
||||
#define vlog(fmt, args...) ventoy_syslog(VLOG_LOG, fmt, ##args)
|
||||
#define vdebug(fmt, args...) ventoy_syslog(VLOG_DEBUG, fmt, ##args)
|
||||
|
||||
#define MAX_PATH PATH_MAX
|
||||
|
||||
#endif
|
||||
|
||||
#define CHECK_FREE(p) \
|
||||
{\
|
||||
if (p)\
|
||||
{\
|
||||
free(p); \
|
||||
(p) = NULL; \
|
||||
}\
|
||||
}
|
||||
|
||||
void ventoy_syslog(int level, const char *Fmt, ...);
|
||||
void ventoy_set_loglevel(int level);
|
||||
uint32_t ventoy_crc32(void *Buffer, uint32_t Length);
|
||||
|
||||
|
||||
#if defined(_MSC_VER) || defined(WIN32)
|
||||
static __inline void * zalloc(size_t n)
|
||||
#else
|
||||
static inline void * zalloc(size_t n)
|
||||
#endif
|
||||
{
|
||||
void *p = malloc(n);
|
||||
if (p) memset(p, 0, n);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
#endif /* __VENTOY_DEFINE_H__ */
|
||||
|
24
Plugson/src/Core/ventoy_disk.c
Normal file
24
Plugson/src/Core/ventoy_disk.c
Normal file
@@ -0,0 +1,24 @@
|
||||
/******************************************************************************
|
||||
* 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>
|
||||
|
||||
|
166
Plugson/src/Core/ventoy_disk.h
Normal file
166
Plugson/src/Core/ventoy_disk.h
Normal file
@@ -0,0 +1,166 @@
|
||||
/******************************************************************************
|
||||
* 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__
|
||||
|
||||
#define MAX_DISK 256
|
||||
typedef struct ventoy_disk
|
||||
{
|
||||
char devname[64];
|
||||
|
||||
int pathcase;
|
||||
char cur_fsname[64];
|
||||
char cur_capacity[64];
|
||||
char cur_model[256];
|
||||
char cur_ventoy_ver[64];
|
||||
int cur_secureboot;
|
||||
int cur_part_style;
|
||||
|
||||
}ventoy_disk;
|
||||
|
||||
#if defined(_MSC_VER) || defined(WIN32)
|
||||
|
||||
|
||||
|
||||
#else
|
||||
|
||||
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))
|
||||
|
||||
#endif
|
||||
|
||||
int ventoy_disk_init(void);
|
||||
void ventoy_disk_exit(void);
|
||||
int ventoy_get_disk_info(char **argv);
|
||||
const ventoy_disk * ventoy_get_disk_list(int *num);
|
||||
const ventoy_disk * ventoy_get_disk_node(int id);
|
||||
int CheckRuntimeEnvironment(char Letter, ventoy_disk *disk);
|
||||
|
||||
#endif /* __VENTOY_DISK_H__ */
|
||||
|
607
Plugson/src/Core/ventoy_disk_linux.c
Normal file
607
Plugson/src/Core/ventoy_disk_linux.c
Normal file
@@ -0,0 +1,607 @@
|
||||
/******************************************************************************
|
||||
* 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>
|
||||
|
||||
static int g_fatlib_media_fd = 0;
|
||||
static uint64_t g_fatlib_media_offset = 0;
|
||||
|
||||
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, sizeof(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/zramX */
|
||||
if (name[0] == 'z' && name[1] == 'r' && name[2] == 'a' && name[3] == '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
|
||||
scnprintf(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
|
||||
scnprintf(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)
|
||||
{
|
||||
vlog("/EFI/BOOT/grubx64_real.efi find, secure boot in enabled\n");
|
||||
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;
|
||||
|
||||
scnprintf(verbuf, bufsize - 1, "%s", pos);
|
||||
rc = 0;
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
|
||||
fl_fclose(flfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
vdebug("No grub.cfg found\n");
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* <BEGIN>: Deleted by longpanda, 20211028 PN:XX LABEL:XX */
|
||||
#if 0
|
||||
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("ventoy partition layout check OK: [%llu %llu] [%llu %llu]\n",
|
||||
part1_start_sector, part1_sector_count, part2_start_sector, part2_sector_count);
|
||||
|
||||
vtoy->ventoy_valid = 1;
|
||||
|
||||
vdebug("now check secure boot for %s ...\n", info->disk_path);
|
||||
|
||||
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();
|
||||
}
|
||||
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 (vtoy->ventoy_ver[0] == 0)
|
||||
{
|
||||
vtoy->ventoy_ver[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:
|
||||
vtoy_safe_close_fd(fd);
|
||||
return rc;
|
||||
}
|
||||
#endif /* #if 0 */
|
||||
/* <END> : Deleted by longpanda, 20211028 PN:XX LABEL:XX */
|
||||
|
||||
|
||||
int ventoy_get_disk_info(char **argv)
|
||||
{
|
||||
uint64_t size;
|
||||
char vendor[128];
|
||||
char model[128];
|
||||
char *disk = argv[4];
|
||||
|
||||
if (strncmp(argv[4], "/dev/", 4) == 0)
|
||||
{
|
||||
disk += 4;
|
||||
}
|
||||
ventoy_get_disk_vendor(disk, vendor, sizeof(vendor));
|
||||
ventoy_get_disk_model(disk, model, sizeof(model));
|
||||
|
||||
scnprintf(g_sysinfo.cur_model, sizeof(g_sysinfo.cur_model), "%s %s [%s]", vendor, model, argv[4]);
|
||||
strlcpy(g_sysinfo.cur_ventoy_ver, argv[5]);
|
||||
strlcpy(g_sysinfo.cur_fsname, argv[6]);
|
||||
g_sysinfo.cur_part_style = (int)strtol(argv[7], NULL, 10);
|
||||
g_sysinfo.cur_secureboot = (int)strtol(argv[8], NULL, 10);
|
||||
|
||||
size = ventoy_get_disk_size_in_byte(disk);
|
||||
scnprintf(g_sysinfo.cur_capacity, sizeof(g_sysinfo.cur_capacity), "%dGB", (int)ventoy_get_human_readable_gb(size));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ventoy_disk_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ventoy_disk_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
88
Plugson/src/Core/ventoy_disk_windows.c
Normal file
88
Plugson/src/Core/ventoy_disk_windows.c
Normal file
@@ -0,0 +1,88 @@
|
||||
/******************************************************************************
|
||||
* 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 <windows.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include <ventoy_define.h>
|
||||
#include <ventoy_disk.h>
|
||||
#include <ventoy_util.h>
|
||||
#include <fat_filelib.h>
|
||||
|
||||
static int g_disk_num = 0;
|
||||
ventoy_disk *g_disk_list = NULL;
|
||||
|
||||
int ventoy_disk_init(void)
|
||||
{
|
||||
char Letter = 'A';
|
||||
DWORD Drives = GetLogicalDrives();
|
||||
|
||||
vlog("ventoy disk init ...\n");
|
||||
|
||||
g_disk_list = zalloc(sizeof(ventoy_disk) * MAX_DISK);
|
||||
|
||||
while (Drives)
|
||||
{
|
||||
if (Drives & 0x01)
|
||||
{
|
||||
if (CheckRuntimeEnvironment(Letter, g_disk_list + g_disk_num) == 0)
|
||||
{
|
||||
g_disk_list[g_disk_num].devname[0] = Letter;
|
||||
g_disk_num++;
|
||||
vlog("%C: is ventoy disk\n", Letter);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(g_disk_list + g_disk_num, 0, sizeof(ventoy_disk));
|
||||
vlog("%C: is NOT ventoy disk\n", Letter);
|
||||
}
|
||||
}
|
||||
|
||||
Letter++;
|
||||
Drives >>= 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ventoy_disk_exit(void)
|
||||
{
|
||||
vlog("ventoy disk exit ...\n");
|
||||
|
||||
check_free(g_disk_list);
|
||||
g_disk_list = NULL;
|
||||
g_disk_num = 0;
|
||||
}
|
||||
|
||||
const ventoy_disk * ventoy_get_disk_list(int *num)
|
||||
{
|
||||
*num = g_disk_num;
|
||||
return g_disk_list;
|
||||
}
|
||||
|
||||
const ventoy_disk * ventoy_get_disk_node(int id)
|
||||
{
|
||||
if (id >= 0 && id < g_disk_num)
|
||||
{
|
||||
return g_disk_list + id;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
803
Plugson/src/Core/ventoy_json.c
Normal file
803
Plugson/src/Core/ventoy_json.c
Normal file
@@ -0,0 +1,803 @@
|
||||
/******************************************************************************
|
||||
* 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>
|
||||
#if defined(_MSC_VER) || defined(WIN32)
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/limits.h>
|
||||
#endif
|
||||
#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;
|
||||
}
|
||||
|
||||
if (*(pcPos - 1) == '\\')
|
||||
{
|
||||
for (pcPos++; *pcPos; pcPos++)
|
||||
{
|
||||
if (*pcPos == '"' && *(pcPos - 1) != '\\')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (*pcPos == 0 || pcPos < pcTmp)
|
||||
{
|
||||
vdebug("Invalid quotes string %s.", 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 start=%p, end=%p.\n", szJsonData, pcEnd);
|
||||
return JSON_FAILED;
|
||||
}
|
||||
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
|
||||
int vtoy_json_parse_ex(VTOY_JSON *pstJson, const char *szJsonData, int szLen)
|
||||
{
|
||||
uint32_t uiMemSize = 0;
|
||||
int Ret = JSON_SUCCESS;
|
||||
char *pcNewBuf = NULL;
|
||||
const char *pcEnd = NULL;
|
||||
|
||||
uiMemSize = (uint32_t)szLen;
|
||||
pcNewBuf = (char *)malloc(uiMemSize + 1);
|
||||
if (NULL == pcNewBuf)
|
||||
{
|
||||
vdebug("Failed to alloc new buf.\n");
|
||||
return JSON_FAILED;
|
||||
}
|
||||
memcpy(pcNewBuf, szJsonData, szLen);
|
||||
pcNewBuf[uiMemSize] = 0;
|
||||
|
||||
Ret = vtoy_json_parse_value(pcNewBuf, (char *)szJsonData, pstJson, szJsonData, &pcEnd);
|
||||
if (JSON_SUCCESS != Ret)
|
||||
{
|
||||
vdebug("Failed to parse json data start=%p, end=%p\n", szJsonData, 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)))
|
||||
{
|
||||
scnprintf((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:
|
||||
{
|
||||
scnprintf((char *)pstCurParse->pDataBuf, pstCurParse->uiBufSize, "%s", pstJsonCur->unData.pcStrVal);
|
||||
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;
|
||||
}
|
||||
|
||||
scnprintf(pcBuf, uiBufLen, "%s", pstJsonItem->unData.pcStrVal);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int vtoy_json_escape_string(char *buf, int buflen, const char *str, int newline)
|
||||
{
|
||||
char last = 0;
|
||||
int count = 0;
|
||||
|
||||
*buf++ = '"';
|
||||
count++;
|
||||
|
||||
while (*str)
|
||||
{
|
||||
if (*str == '"' && last != '\\')
|
||||
{
|
||||
*buf = '\\';
|
||||
count++;
|
||||
buf++;
|
||||
}
|
||||
|
||||
*buf = *str;
|
||||
count++;
|
||||
buf++;
|
||||
|
||||
last = *str;
|
||||
str++;
|
||||
}
|
||||
|
||||
*buf++ = '"';
|
||||
count++;
|
||||
|
||||
*buf++ = ',';
|
||||
count++;
|
||||
|
||||
if (newline)
|
||||
{
|
||||
*buf++ = '\n';
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
436
Plugson/src/Core/ventoy_json.h
Normal file
436
Plugson/src/Core/ventoy_json.h
Normal file
@@ -0,0 +1,436 @@
|
||||
/******************************************************************************
|
||||
* 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); \
|
||||
} \
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER) || defined(WIN32)
|
||||
#define ssprintf(curpos, buf, len, fmt, ...) \
|
||||
curpos += scnprintf(buf + curpos, len - curpos, fmt, ##__VA_ARGS__)
|
||||
|
||||
#define VTOY_JSON_IS_SKIPABLE(c) (((c) <= 32) ? 1 : 0)
|
||||
|
||||
#define VTOY_JSON_PRINT_PREFIX(uiDepth, ...) \
|
||||
{ \
|
||||
uint32_t _uiLoop = 0; \
|
||||
for (_uiLoop = 0; _uiLoop < (uiDepth); _uiLoop++) \
|
||||
{ \
|
||||
ssprintf(uiCurPos, pcBuf, uiBufLen, " "); \
|
||||
} \
|
||||
ssprintf(uiCurPos, pcBuf, uiBufLen, ##__VA_ARGS__); \
|
||||
}
|
||||
#else
|
||||
|
||||
#define ssprintf(curpos, buf, len, fmt, args...) \
|
||||
curpos += scnprintf(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); \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#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_BEGIN_L(P) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s{", P)
|
||||
#define VTOY_JSON_FMT_OBJ_BEGIN_N() ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "{\n")
|
||||
#define VTOY_JSON_FMT_OBJ_BEGIN_LN(P) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s{\n", P)
|
||||
|
||||
#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_KEY_L(P, Key) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s\"%s\":", P, (Key))
|
||||
|
||||
|
||||
#define VTOY_JSON_FMT_ITEM(Item) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\",", (Item))
|
||||
#define VTOY_JSON_FMT_ITEM_L(P, Item) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s\"%s\",", P, (Item))
|
||||
#define VTOY_JSON_FMT_ITEM_LN(P, Item) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s\"%s\",\n", P, (Item))
|
||||
#define VTOY_JSON_FMT_ITEM_PATH_LN(P, Item) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s\"%s\",\n", P, ventoy_real_path(Item))
|
||||
|
||||
#define VTOY_JSON_FMT_COMA() ssprintf(__uiCurPos, __pcBuf, __uiBufLen, ",")
|
||||
#define VTOY_JSON_FMT_COMA_N(cnt) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, ",\n")
|
||||
#define VTOY_JSON_FMT_COMA_N_CNT(cnt) if ((cnt) > 0) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, ",\n")
|
||||
|
||||
|
||||
#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_BEGIN_N() ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "[\n")
|
||||
|
||||
#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_OBJ_END_L(P) \
|
||||
{\
|
||||
if ('\n' == *(__pcBuf + (__uiCurPos - 1)) && ',' == *(__pcBuf + (__uiCurPos - 2)))\
|
||||
{\
|
||||
*(__pcBuf + (__uiCurPos - 2)) = '\n';\
|
||||
__uiCurPos -= 1;\
|
||||
}\
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s}%s", P);\
|
||||
}
|
||||
#define VTOY_JSON_FMT_OBJ_ENDEX_L(P) \
|
||||
{\
|
||||
if ('\n' == *(__pcBuf + (__uiCurPos - 1)) && ',' == *(__pcBuf + (__uiCurPos - 2)))\
|
||||
{\
|
||||
*(__pcBuf + (__uiCurPos - 2)) = '\n';\
|
||||
__uiCurPos -= 1;\
|
||||
}\
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s},%s", P);\
|
||||
}
|
||||
|
||||
#define VTOY_JSON_FMT_OBJ_END_LN(P) \
|
||||
{\
|
||||
if ('\n' == *(__pcBuf + (__uiCurPos - 1)) && ',' == *(__pcBuf + (__uiCurPos - 2)))\
|
||||
{\
|
||||
*(__pcBuf + (__uiCurPos - 2)) = '\n';\
|
||||
__uiCurPos -= 1;\
|
||||
}\
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s}\n", P);\
|
||||
}
|
||||
#define VTOY_JSON_FMT_OBJ_ENDEX_LN(P) \
|
||||
{\
|
||||
if ('\n' == *(__pcBuf + (__uiCurPos - 1)) && ',' == *(__pcBuf + (__uiCurPos - 2)))\
|
||||
{\
|
||||
*(__pcBuf + (__uiCurPos - 2)) = '\n';\
|
||||
__uiCurPos -= 1;\
|
||||
}\
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s},\n", P);\
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#define VTOY_JSON_FMT_ARY_END_L(P) \
|
||||
{\
|
||||
if ('\n' == *(__pcBuf + (__uiCurPos - 1)) && ',' == *(__pcBuf + (__uiCurPos - 2)))\
|
||||
{\
|
||||
*(__pcBuf + (__uiCurPos - 2)) = '\n';\
|
||||
__uiCurPos -= 1;\
|
||||
}\
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s]", P);\
|
||||
}
|
||||
|
||||
#define VTOY_JSON_FMT_ARY_END_LN(P) \
|
||||
{\
|
||||
if ('\n' == *(__pcBuf + (__uiCurPos - 1)) && ',' == *(__pcBuf + (__uiCurPos - 2)))\
|
||||
{\
|
||||
*(__pcBuf + (__uiCurPos - 2)) = '\n';\
|
||||
__uiCurPos -= 1;\
|
||||
}\
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s]\n", P);\
|
||||
}
|
||||
|
||||
#define VTOY_JSON_FMT_ARY_ENDEX_L(P) \
|
||||
{\
|
||||
if ('\n' == *(__pcBuf + (__uiCurPos - 1)) && ',' == *(__pcBuf + (__uiCurPos - 2)))\
|
||||
{\
|
||||
*(__pcBuf + (__uiCurPos - 2)) = '\n';\
|
||||
__uiCurPos -= 1;\
|
||||
}\
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s],", P);\
|
||||
}
|
||||
|
||||
|
||||
#define VTOY_JSON_FMT_ARY_ENDEX_LN(P) \
|
||||
{\
|
||||
if ('\n' == *(__pcBuf + (__uiCurPos - 1)) && ',' == *(__pcBuf + (__uiCurPos - 2)))\
|
||||
{\
|
||||
*(__pcBuf + (__uiCurPos - 2)) = '\n';\
|
||||
__uiCurPos -= 1;\
|
||||
}\
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s],\n", P);\
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#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_UINT_N(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\": %u,\n", Key, Val)
|
||||
#define VTOY_JSON_FMT_UINT_L(P, Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s\"%s\": %u,", P, Key, Val)
|
||||
#define VTOY_JSON_FMT_UINT_LN(P, Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s\"%s\": %u,\n", P, Key, Val)
|
||||
|
||||
|
||||
#define VTOY_JSON_FMT_STRUINT(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\": \"%u\",", Key, Val)
|
||||
#define VTOY_JSON_FMT_STRUINT_N(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\": \"%u\",\n", Key, Val)
|
||||
#define VTOY_JSON_FMT_STRUINT_L(P, Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s\"%s\": \"%u\",", P, Key, Val)
|
||||
#define VTOY_JSON_FMT_STRUINT_LN(P, Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s\"%s\": \"%u\",\n", P, Key, Val)
|
||||
|
||||
#define VTOY_JSON_FMT_STRSINT(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\": \"%d\",", Key, Val)
|
||||
#define VTOY_JSON_FMT_STRSINT_N(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\": \"%d\",\n", Key, Val)
|
||||
#define VTOY_JSON_FMT_STRSINT_L(P, Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s\"%s\": \"%d\",", P, Key, Val)
|
||||
#define VTOY_JSON_FMT_STRSINT_LN(P, Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s\"%s\": \"%d\",\n", P, Key, Val)
|
||||
|
||||
#define VTOY_JSON_FMT_CTRL_INT(Prefix, Key, Field) \
|
||||
if (def->Field != data->Field) \
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s{ \"%s\": \"%d\" },\n", Prefix, Key, data->Field)
|
||||
|
||||
#define VTOY_JSON_FMT_CTRL_STRN(P, Key, Field) \
|
||||
if (strcmp(def->Field, data->Field)) \
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s{ \"%s\": \"%s\" },\n", P, Key, data->Field)
|
||||
|
||||
#define VTOY_JSON_FMT_CTRL_STRN_STR(P, Key, ptr) \
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s{ \"%s\": \"%s\" },\n", P, Key, ptr)
|
||||
|
||||
#define VTOY_JSON_FMT_CTRL_PUB_STRN(P, Key, Field) \
|
||||
if (strcmp(def->Field, g_pub_path)) \
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s{ \"%s\": \"%s\" },\n", P, Key, g_pub_path)
|
||||
|
||||
|
||||
#define VTOY_JSON_FMT_DIFF_STRN(P, Key, Field) \
|
||||
if (strcmp(def->Field, data->Field)) \
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s\"%s\": \"%s\",\n", P, Key, data->Field)
|
||||
|
||||
|
||||
#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_SINT_N(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\": %d,\n", Key, Val)
|
||||
#define VTOY_JSON_FMT_SINT_L(P, Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s\"%s\": %d,", P, Key, Val)
|
||||
#define VTOY_JSON_FMT_SINT_LN(P, Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s\"%s\": %d,\n", P, 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_STRN_N(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\": \"%s\",\n", Key, Val)
|
||||
#define VTOY_JSON_FMT_STRN_L(P, Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s\"%s\": \"%s\",", P, Key, Val)
|
||||
#define VTOY_JSON_FMT_STRN_LN(P, Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s\"%s\": \"%s\",\n", P, Key, Val)
|
||||
#define VTOY_JSON_FMT_STRN_PATH_LN(P, Key, Val) \
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s\"%s\": \"%s\",\n", P, Key, ventoy_real_path(Val))
|
||||
|
||||
int vtoy_json_escape_string(char *buf, int buflen, const char *str, int newline);
|
||||
|
||||
#define VTOY_JSON_FMT_STRN_EX_LN(P, Key, Val) \
|
||||
{\
|
||||
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "%s\"%s\": ", P, Key);\
|
||||
__uiCurPos += vtoy_json_escape_string(__pcBuf + __uiCurPos, __uiBufLen - __uiCurPos, Val, 1);\
|
||||
}
|
||||
|
||||
|
||||
#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_parse_ex(VTOY_JSON *pstJson, const char *szJsonData, int szLen);
|
||||
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__ */
|
||||
|
151
Plugson/src/Core/ventoy_log.c
Normal file
151
Plugson/src/Core/ventoy_log.c
Normal file
@@ -0,0 +1,151 @@
|
||||
/******************************************************************************
|
||||
* 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 <string.h>
|
||||
#include <time.h>
|
||||
#include <ventoy_define.h>
|
||||
#include <ventoy_util.h>
|
||||
|
||||
extern char g_log_file[MAX_PATH];
|
||||
static int g_ventoy_log_level = VLOG_DEBUG;
|
||||
static pthread_mutex_t g_log_mutex;
|
||||
|
||||
int ventoy_log_init(void)
|
||||
{
|
||||
if (ventoy_get_file_size(g_log_file) >= SIZE_1MB)
|
||||
{
|
||||
#if defined(_MSC_VER) || defined(WIN32)
|
||||
DeleteFileA(g_log_file);
|
||||
#else
|
||||
remove(g_log_file);
|
||||
#endif
|
||||
}
|
||||
|
||||
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_printf(const char *Fmt, ...)
|
||||
{
|
||||
char log[512];
|
||||
va_list arg;
|
||||
time_t stamp;
|
||||
struct tm ttm;
|
||||
FILE *fp;
|
||||
|
||||
time(&stamp);
|
||||
localtime_r(&stamp, &ttm);
|
||||
|
||||
va_start(arg, Fmt);
|
||||
#if defined(_MSC_VER) || defined(WIN32)
|
||||
vsnprintf_s(log, 512, _TRUNCATE, Fmt, arg);
|
||||
#else
|
||||
vsnprintf(log, 512, Fmt, arg);
|
||||
#endif
|
||||
va_end(arg);
|
||||
|
||||
pthread_mutex_lock(&g_log_mutex);
|
||||
|
||||
#if defined(_MSC_VER) || defined(WIN32)
|
||||
fopen_s(&fp, g_log_file, "a+");
|
||||
#else
|
||||
fp = fopen(g_log_file, "a+");
|
||||
#endif
|
||||
|
||||
if (fp)
|
||||
{
|
||||
fprintf(fp, "[%04u/%02u/%02u %02u:%02u:%02u] %s",
|
||||
ttm.tm_year, ttm.tm_mon + 1, ttm.tm_mday,
|
||||
ttm.tm_hour, ttm.tm_min, ttm.tm_sec,
|
||||
log);
|
||||
fclose(fp);
|
||||
|
||||
#ifdef VENTOY_SIM
|
||||
printf("[%04u/%02u/%02u %02u:%02u:%02u] %s",
|
||||
ttm.tm_year, ttm.tm_mon + 1, ttm.tm_mday,
|
||||
ttm.tm_hour, ttm.tm_min, ttm.tm_sec,
|
||||
log);
|
||||
#endif
|
||||
}
|
||||
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);
|
||||
#if defined(_MSC_VER) || defined(WIN32)
|
||||
vsnprintf_s(log, 512, _TRUNCATE, Fmt, arg);
|
||||
#else
|
||||
vsnprintf(log, 512, Fmt, arg);
|
||||
#endif
|
||||
va_end(arg);
|
||||
|
||||
pthread_mutex_lock(&g_log_mutex);
|
||||
#if defined(_MSC_VER) || defined(WIN32)
|
||||
fopen_s(&fp, g_log_file, "a+");
|
||||
#else
|
||||
fp = fopen(g_log_file, "a+");
|
||||
#endif
|
||||
if (fp)
|
||||
{
|
||||
fprintf(fp, "[%04u/%02u/%02u %02u:%02u:%02u] %s",
|
||||
ttm.tm_year + 1900, ttm.tm_mon + 1, ttm.tm_mday,
|
||||
ttm.tm_hour, ttm.tm_min, ttm.tm_sec,
|
||||
log);
|
||||
fclose(fp);
|
||||
|
||||
#ifdef VENTOY_SIM
|
||||
printf("[%04u/%02u/%02u %02u:%02u:%02u] %s",
|
||||
ttm.tm_year + 1900, ttm.tm_mon + 1, ttm.tm_mday,
|
||||
ttm.tm_hour, ttm.tm_min, ttm.tm_sec,
|
||||
log);
|
||||
#endif
|
||||
}
|
||||
pthread_mutex_unlock(&g_log_mutex);
|
||||
}
|
||||
|
166
Plugson/src/Core/ventoy_md5.c
Normal file
166
Plugson/src/Core/ventoy_md5.c
Normal file
@@ -0,0 +1,166 @@
|
||||
/******************************************************************************
|
||||
* 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>
|
||||
|
||||
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 <20><> 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);
|
||||
}
|
||||
|
255
Plugson/src/Core/ventoy_util.c
Normal file
255
Plugson/src/Core/ventoy_util.c
Normal file
@@ -0,0 +1,255 @@
|
||||
/******************************************************************************
|
||||
* 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 <sys/stat.h>
|
||||
#include <ventoy_define.h>
|
||||
#include <ventoy_util.h>
|
||||
|
||||
|
||||
static int g_tar_filenum = 0;
|
||||
static char *g_tar_buffer = NULL;
|
||||
static ventoy_file *g_tar_filelist = NULL;
|
||||
|
||||
SYSINFO g_sysinfo;
|
||||
|
||||
unsigned char *g_unxz_buffer = NULL;
|
||||
int g_unxz_len = 0;
|
||||
|
||||
void unxz_error(char *x)
|
||||
{
|
||||
vlog("%s\n", x);
|
||||
}
|
||||
|
||||
int unxz_flush(void *src, unsigned int size)
|
||||
{
|
||||
memcpy(g_unxz_buffer + g_unxz_len, src, size);
|
||||
g_unxz_len += (int)size;
|
||||
|
||||
return (int)size;
|
||||
}
|
||||
|
||||
|
||||
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_read_file_to_buf(const char *FileName, int ExtLen, void **Bufer, int *BufLen)
|
||||
{
|
||||
int FileSize;
|
||||
FILE *fp = NULL;
|
||||
void *Data = NULL;
|
||||
|
||||
#if defined(_MSC_VER) || defined(WIN32)
|
||||
fopen_s(&fp, FileName, "rb");
|
||||
#else
|
||||
fp = fopen(FileName, "rb");
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
|
||||
ventoy_file * ventoy_tar_find_file(const char *path)
|
||||
{
|
||||
int i;
|
||||
int len;
|
||||
ventoy_file *node = g_tar_filelist;
|
||||
|
||||
len = (int)strlen(path);
|
||||
|
||||
for (i = 0; i < g_tar_filenum; i++, node++)
|
||||
{
|
||||
if (node->pathlen == len && memcmp(node->path, path, len) == 0)
|
||||
{
|
||||
return node;
|
||||
}
|
||||
|
||||
if (node->pathlen > len)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int ventoy_www_init(void)
|
||||
{
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int size = 0;
|
||||
int tarsize = 0;
|
||||
int offset = 0;
|
||||
ventoy_file *node = NULL;
|
||||
ventoy_file *node2 = NULL;
|
||||
VENTOY_TAR_HEAD *pHead = NULL;
|
||||
ventoy_file tmpnode;
|
||||
|
||||
if (!g_tar_filelist)
|
||||
{
|
||||
g_tar_filelist = malloc(VENTOY_FILE_MAX * sizeof(ventoy_file));
|
||||
g_tar_buffer = malloc(TAR_BUF_MAX);
|
||||
g_tar_filenum = 0;
|
||||
}
|
||||
|
||||
if ((!g_tar_filelist) || (!g_tar_buffer))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ventoy_decompress_tar(g_tar_buffer, TAR_BUF_MAX, &tarsize))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
pHead = (VENTOY_TAR_HEAD *)g_tar_buffer;
|
||||
node = g_tar_filelist;
|
||||
|
||||
while (g_tar_filenum < VENTOY_FILE_MAX && size < tarsize && memcmp(pHead->magic, TMAGIC, 5) == 0)
|
||||
{
|
||||
if (pHead->typeflag == REGTYPE)
|
||||
{
|
||||
node->size = (int)strtol(pHead->size, NULL, 8);
|
||||
node->pathlen = (int)scnprintf(node->path, MAX_PATH, "%s", pHead->name);
|
||||
node->addr = pHead + 1;
|
||||
|
||||
if (node->pathlen == 13 && strcmp(pHead->name, "www/buildtime") == 0)
|
||||
{
|
||||
scnprintf(g_sysinfo.buildtime, sizeof(g_sysinfo.buildtime), "%s", (char *)node->addr);
|
||||
vlog("Plugson buildtime %s\n", g_sysinfo.buildtime);
|
||||
}
|
||||
|
||||
offset = 512 + VENTOY_UP_ALIGN(node->size, 512);
|
||||
|
||||
node++;
|
||||
g_tar_filenum++;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = 512;
|
||||
}
|
||||
|
||||
pHead = (VENTOY_TAR_HEAD *)((char *)pHead + offset);
|
||||
size += offset;
|
||||
}
|
||||
|
||||
|
||||
//sort
|
||||
for (i = 0; i < g_tar_filenum; i++)
|
||||
for (j = i + 1; j < g_tar_filenum; j++)
|
||||
{
|
||||
node = g_tar_filelist + i;
|
||||
node2 = g_tar_filelist + j;
|
||||
|
||||
if (node->pathlen > node2->pathlen)
|
||||
{
|
||||
memcpy(&tmpnode, node, sizeof(ventoy_file));
|
||||
memcpy(node, node2, sizeof(ventoy_file));
|
||||
memcpy(node2, &tmpnode, sizeof(ventoy_file));
|
||||
}
|
||||
}
|
||||
|
||||
vlog("Total extract %d files from tar file.\n", g_tar_filenum);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ventoy_www_exit(void)
|
||||
{
|
||||
check_free(g_tar_filelist);
|
||||
check_free(g_tar_buffer);
|
||||
g_tar_filelist = NULL;
|
||||
g_tar_buffer = NULL;
|
||||
g_tar_filenum = 0;
|
||||
}
|
||||
|
||||
|
||||
void ventoy_get_json_path(char *path, char *backup)
|
||||
{
|
||||
#if defined(_MSC_VER) || defined(WIN32)
|
||||
scnprintf(path, 64, "%C:\\ventoy\\ventoy.json", g_cur_dir[0]);
|
||||
if (backup)
|
||||
{
|
||||
scnprintf(backup, 64, "%C:\\ventoy\\ventoy_backup.json", g_cur_dir[0]);
|
||||
}
|
||||
#else
|
||||
scnprintf(path, 64, "%s/ventoy/ventoy.json", g_cur_dir);
|
||||
if (backup)
|
||||
{
|
||||
scnprintf(backup, 64, "%s/ventoy/ventoy_backup.json", g_cur_dir);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
210
Plugson/src/Core/ventoy_util.h
Normal file
210
Plugson/src/Core/ventoy_util.h
Normal file
@@ -0,0 +1,210 @@
|
||||
/******************************************************************************
|
||||
* 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 char g_cur_dir[MAX_PATH];
|
||||
extern char g_ventoy_dir[MAX_PATH];
|
||||
|
||||
#if defined(_MSC_VER) || defined(WIN32)
|
||||
|
||||
typedef HANDLE pthread_mutex_t;
|
||||
|
||||
static __inline int pthread_mutex_init(pthread_mutex_t *mutex, void *unused)
|
||||
{
|
||||
(void)unused;
|
||||
*mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
return *mutex == NULL ? -1 : 0;
|
||||
}
|
||||
|
||||
static __inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
|
||||
{
|
||||
return CloseHandle(*mutex) == 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
static __inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
|
||||
{
|
||||
return ReleaseMutex(*mutex) == 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
static __inline int pthread_mutex_lock(pthread_mutex_t *mutex)
|
||||
{
|
||||
return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0 ? 0 : -1;
|
||||
}
|
||||
|
||||
int ventoy_path_case(char *path, int slash);
|
||||
|
||||
#else
|
||||
int ventoy_get_sys_file_line(char *buffer, int buflen, const char *fmt, ...);
|
||||
|
||||
#define UINT8 uint8_t
|
||||
#define UINT16 uint16_t
|
||||
#define UINT32 uint32_t
|
||||
#define UINT64 uint64_t
|
||||
|
||||
static inline int ventoy_path_case(char *path, int slash)
|
||||
{
|
||||
(void)path;
|
||||
(void)slash;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#define LANGUAGE_EN 0
|
||||
#define LANGUAGE_CN 1
|
||||
|
||||
typedef struct SYSINFO
|
||||
{
|
||||
char buildtime[128];
|
||||
int syntax_error;
|
||||
|
||||
int language;
|
||||
int pathcase;
|
||||
char cur_fsname[64];
|
||||
char cur_capacity[64];
|
||||
char cur_model[256];
|
||||
char cur_ventoy_ver[64];
|
||||
int cur_secureboot;
|
||||
int cur_part_style;
|
||||
|
||||
char ip[32];
|
||||
char port[16];
|
||||
}SYSINFO;
|
||||
|
||||
extern SYSINFO g_sysinfo;
|
||||
|
||||
|
||||
|
||||
|
||||
#define TMAGIC "ustar"
|
||||
|
||||
#define REGTYPE '0'
|
||||
#define AREGTYPE '\0'
|
||||
#define LNKTYPE '1'
|
||||
#define CHRTYPE '3'
|
||||
#define BLKTYPE '4'
|
||||
#define DIRTYPE '5'
|
||||
#define FIFOTYPE '6'
|
||||
#define CONTTYPE '7'
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct tag_tar_head
|
||||
{
|
||||
char name[100];
|
||||
char mode[8];
|
||||
char uid[8];
|
||||
char gid[8];
|
||||
char size[12];
|
||||
char mtime[12];
|
||||
char chksum[8];
|
||||
char typeflag;
|
||||
char linkname[100];
|
||||
char magic[6];
|
||||
char version[2];
|
||||
char uname[32];
|
||||
char gname[32];
|
||||
char devmajor[8];
|
||||
char devminor[8];
|
||||
char prefix[155];
|
||||
char padding[12];
|
||||
}VENTOY_TAR_HEAD;
|
||||
|
||||
|
||||
|
||||
typedef struct VENTOY_MAGIC
|
||||
{
|
||||
uint32_t magic1; // 0x51 0x52 0x53 0x54
|
||||
uint32_t xzlen; //
|
||||
uint32_t magic2; // 0xa1 0xa2 0xa3 0xa4
|
||||
}VENTOY_MAGIC;
|
||||
|
||||
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#define VENTOY_UP_ALIGN(N, align) (((N) + ((align) - 1)) / (align) * (align))
|
||||
#define VENTOY_FILE_MAX 2048
|
||||
|
||||
|
||||
#if defined(_MSC_VER) || defined(WIN32)
|
||||
#define million_sleep(a) Sleep(a)
|
||||
#else
|
||||
#define million_sleep(a) usleep((a) * 1000)
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct ventoy_file
|
||||
{
|
||||
int size;
|
||||
char path[MAX_PATH];
|
||||
int pathlen;
|
||||
void *addr;
|
||||
}ventoy_file;
|
||||
|
||||
|
||||
|
||||
int ventoy_is_file_exist(const char *fmt, ...);
|
||||
int ventoy_is_directory_exist(const char *fmt, ...);
|
||||
void ventoy_gen_preudo_uuid(void *uuid);
|
||||
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 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);
|
||||
int ventoy_write_buf_to_file(const char *FileName, void *Bufer, int BufLen);
|
||||
const char * ventoy_get_os_language(void);
|
||||
int ventoy_get_file_size(const char *file);
|
||||
int ventoy_www_init(void);
|
||||
void ventoy_www_exit(void);
|
||||
int ventoy_decompress_tar(char *tarbuf, int buflen, int *tarsize);
|
||||
ventoy_file * ventoy_tar_find_file(const char *path);
|
||||
void ventoy_get_json_path(char *path, char *backup);
|
||||
int ventoy_copy_file(const char *a, const char *b);
|
||||
|
||||
typedef int (*ventoy_http_writeback_pf)(void);
|
||||
|
||||
int ventoy_start_writeback_thread(ventoy_http_writeback_pf callback);
|
||||
void ventoy_stop_writeback_thread(void);
|
||||
void ventoy_set_writeback_event(void);
|
||||
|
||||
|
||||
extern unsigned char *g_unxz_buffer;
|
||||
extern int g_unxz_len;
|
||||
void unxz_error(char *x);
|
||||
int unxz_flush(void *src, unsigned int size);
|
||||
|
||||
#endif /* __VENTOY_UTIL_H__ */
|
||||
|
344
Plugson/src/Core/ventoy_util_linux.c
Normal file
344
Plugson/src/Core/ventoy_util_linux.c
Normal file
@@ -0,0 +1,344 @@
|
||||
/******************************************************************************
|
||||
* ventoy_util_linux.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>
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
const char * ventoy_get_os_language(void)
|
||||
{
|
||||
const char *env = getenv("LANG");
|
||||
|
||||
if (env && strncasecmp(env, "zh_CN", 5) == 0)
|
||||
{
|
||||
return "cn";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "en";
|
||||
}
|
||||
}
|
||||
|
||||
int ventoy_is_file_exist(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
struct stat sb;
|
||||
char fullpath[MAX_PATH];
|
||||
|
||||
va_start (ap, fmt);
|
||||
vsnprintf(fullpath, MAX_PATH, fmt, ap);
|
||||
va_end (ap);
|
||||
|
||||
if (stat(fullpath, &sb))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (S_ISREG(sb.st_mode))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ventoy_is_directory_exist(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
struct stat sb;
|
||||
char fullpath[MAX_PATH];
|
||||
|
||||
va_start (ap, fmt);
|
||||
vsnprintf(fullpath, MAX_PATH, fmt, ap);
|
||||
va_end (ap);
|
||||
|
||||
if (stat(fullpath, &sb))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (S_ISDIR(sb.st_mode))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ventoy_get_file_size(const char *file)
|
||||
{
|
||||
int Size = -1;
|
||||
struct stat stStat;
|
||||
|
||||
if (stat(file, &stStat) >= 0)
|
||||
{
|
||||
Size = (int)(stStat.st_size);
|
||||
}
|
||||
|
||||
return Size;
|
||||
}
|
||||
|
||||
|
||||
int ventoy_write_buf_to_file(const char *FileName, void *Bufer, int BufLen)
|
||||
{
|
||||
int fd;
|
||||
int rc;
|
||||
ssize_t size;
|
||||
|
||||
fd = open(FileName, O_CREAT | O_RDWR | O_TRUNC, 0755);
|
||||
if (fd < 0)
|
||||
{
|
||||
vlog("Failed to open file %s %d\n", FileName, errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
rc = fchmod(fd, 0755);
|
||||
if (rc)
|
||||
{
|
||||
vlog("Failed to chmod <%s> %d\n", FileName, errno);
|
||||
}
|
||||
|
||||
size = write(fd, Bufer, BufLen);
|
||||
if ((int)size != BufLen)
|
||||
{
|
||||
close(fd);
|
||||
vlog("write file %s failed %d err:%d\n", FileName, (int)size, errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fsync(fd);
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ventoy_decompress_tar(char *tarbuf, int buflen, int *tarsize)
|
||||
{
|
||||
int rc = 1;
|
||||
int inused = 0;
|
||||
int BufLen = 0;
|
||||
unsigned char *buffer = NULL;
|
||||
char tarxz[MAX_PATH];
|
||||
|
||||
scnprintf(tarxz, sizeof(tarxz), "%s/tool/plugson.tar.xz", g_ventoy_dir);
|
||||
if (ventoy_read_file_to_buf(tarxz, 0, (void **)&buffer, &BufLen))
|
||||
{
|
||||
vlog("Failed to read file <%s>\n", tarxz);
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_unxz_buffer = (unsigned char *)tarbuf;
|
||||
g_unxz_len = 0;
|
||||
|
||||
unxz(buffer, BufLen, NULL, unxz_flush, NULL, &inused, unxz_error);
|
||||
vlog("xzlen:%u rawdata size:%d\n", BufLen, g_unxz_len);
|
||||
|
||||
if (inused != BufLen)
|
||||
{
|
||||
vlog("Failed to unxz data %d %d\n", inused, BufLen);
|
||||
rc = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*tarsize = g_unxz_len;
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static volatile int g_thread_stop = 0;
|
||||
static pthread_t g_writeback_thread;
|
||||
static pthread_mutex_t g_writeback_mutex;
|
||||
static pthread_cond_t g_writeback_cond;
|
||||
static void * ventoy_local_thread_run(void* data)
|
||||
{
|
||||
ventoy_http_writeback_pf callback = (ventoy_http_writeback_pf)data;
|
||||
|
||||
while (1)
|
||||
{
|
||||
pthread_mutex_lock(&g_writeback_mutex);
|
||||
pthread_cond_wait(&g_writeback_cond, &g_writeback_mutex);
|
||||
|
||||
if (g_thread_stop)
|
||||
{
|
||||
pthread_mutex_unlock(&g_writeback_mutex);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
callback();
|
||||
pthread_mutex_unlock(&g_writeback_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ventoy_set_writeback_event(void)
|
||||
{
|
||||
pthread_cond_signal(&g_writeback_cond);
|
||||
}
|
||||
|
||||
int ventoy_start_writeback_thread(ventoy_http_writeback_pf callback)
|
||||
{
|
||||
g_thread_stop = 0;
|
||||
pthread_mutex_init(&g_writeback_mutex, NULL);
|
||||
pthread_cond_init(&g_writeback_cond, NULL);
|
||||
|
||||
pthread_create(&g_writeback_thread, NULL, ventoy_local_thread_run, callback);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ventoy_stop_writeback_thread(void)
|
||||
{
|
||||
g_thread_stop = 1;
|
||||
pthread_cond_signal(&g_writeback_cond);
|
||||
|
||||
pthread_join(g_writeback_thread, NULL);
|
||||
|
||||
|
||||
pthread_cond_destroy(&g_writeback_cond);
|
||||
pthread_mutex_destroy(&g_writeback_mutex);
|
||||
}
|
||||
|
||||
|
||||
int ventoy_copy_file(const char *a, const char *b)
|
||||
{
|
||||
int len = 0;
|
||||
char *buf = NULL;
|
||||
|
||||
if (0 == ventoy_read_file_to_buf(a, 0, (void **)&buf, &len))
|
||||
{
|
||||
ventoy_write_buf_to_file(b, buf, len);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
813
Plugson/src/Core/ventoy_util_windows.c
Normal file
813
Plugson/src/Core/ventoy_util_windows.c
Normal file
@@ -0,0 +1,813 @@
|
||||
/******************************************************************************
|
||||
* 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 <ventoy_define.h>
|
||||
#include <ventoy_util.h>
|
||||
#include <ventoy_disk.h>
|
||||
#include "fat_filelib.h"
|
||||
|
||||
static void TrimString(CHAR *String)
|
||||
{
|
||||
CHAR *Pos1 = String;
|
||||
CHAR *Pos2 = String;
|
||||
size_t Len = strlen(String);
|
||||
|
||||
while (Len > 0)
|
||||
{
|
||||
if (String[Len - 1] != ' ' && String[Len - 1] != '\t')
|
||||
{
|
||||
break;
|
||||
}
|
||||
String[Len - 1] = 0;
|
||||
Len--;
|
||||
}
|
||||
|
||||
while (*Pos1 == ' ' || *Pos1 == '\t')
|
||||
{
|
||||
Pos1++;
|
||||
}
|
||||
|
||||
while (*Pos1)
|
||||
{
|
||||
*Pos2++ = *Pos1++;
|
||||
}
|
||||
*Pos2++ = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ventoy_gen_preudo_uuid(void *uuid)
|
||||
{
|
||||
CoCreateGuid((GUID *)uuid);
|
||||
}
|
||||
|
||||
static int IsUTF8Encode(const char *src)
|
||||
{
|
||||
int i;
|
||||
const UCHAR *Byte = (const UCHAR *)src;
|
||||
|
||||
for (i = 0; i < MAX_PATH && Byte[i]; i++)
|
||||
{
|
||||
if (Byte[i] > 127)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Utf8ToUtf16(const char* src, WCHAR * dst)
|
||||
{
|
||||
return MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, MAX_PATH * sizeof(WCHAR));
|
||||
}
|
||||
|
||||
static int Utf16ToUtf8(const WCHAR* src, CHAR * dst)
|
||||
{
|
||||
int size = WideCharToMultiByte(CP_UTF8, 0, src, -1, dst, MAX_PATH, NULL, 0);
|
||||
dst[size] = 0;
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
int ventoy_path_case(char *path, int slash)
|
||||
{
|
||||
int i;
|
||||
int j = 0;
|
||||
int count = 0;
|
||||
int isUTF8 = 0;
|
||||
BOOL bRet;
|
||||
HANDLE handle = INVALID_HANDLE_VALUE;
|
||||
WCHAR Buffer[MAX_PATH + 16];
|
||||
WCHAR FilePathW[MAX_PATH];
|
||||
CHAR FilePathA[MAX_PATH];
|
||||
FILE_NAME_INFO *pInfo = NULL;
|
||||
|
||||
if (g_sysinfo.pathcase == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (path == NULL || path[0] == '/' || path[0] == '\\')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
isUTF8 = IsUTF8Encode(path);
|
||||
if (isUTF8)
|
||||
{
|
||||
Utf8ToUtf16(path, FilePathW);
|
||||
handle = CreateFileW(FilePathW, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
handle = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
||||
}
|
||||
|
||||
if (handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
bRet = GetFileInformationByHandleEx(handle, FileNameInfo, Buffer, sizeof(Buffer));
|
||||
if (bRet)
|
||||
{
|
||||
pInfo = (FILE_NAME_INFO *)Buffer;
|
||||
|
||||
if (slash)
|
||||
{
|
||||
for (i = 0; i < (int)(pInfo->FileNameLength / sizeof(WCHAR)); i++)
|
||||
{
|
||||
if (pInfo->FileName[i] == L'\\')
|
||||
{
|
||||
pInfo->FileName[i] = L'/';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pInfo->FileName[(pInfo->FileNameLength / sizeof(WCHAR))] = 0;
|
||||
|
||||
memset(FilePathA, 0, sizeof(FilePathA));
|
||||
Utf16ToUtf8(pInfo->FileName, FilePathA);
|
||||
|
||||
if (FilePathA[1] == ':')
|
||||
{
|
||||
j = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
j = 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_PATH && j < MAX_PATH; i++, j++)
|
||||
{
|
||||
if (FilePathA[j] == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (path[i] != FilePathA[j])
|
||||
{
|
||||
path[i] = FilePathA[j];
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_CLOSE_HANDLE(handle);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ventoy_is_directory_exist(const char *Fmt, ...)
|
||||
{
|
||||
va_list Arg;
|
||||
DWORD Attr;
|
||||
int UTF8 = 0;
|
||||
CHAR FilePathA[MAX_PATH];
|
||||
WCHAR FilePathW[MAX_PATH];
|
||||
|
||||
va_start(Arg, Fmt);
|
||||
vsnprintf_s(FilePathA, sizeof(FilePathA), sizeof(FilePathA), Fmt, Arg);
|
||||
va_end(Arg);
|
||||
|
||||
UTF8 = IsUTF8Encode(FilePathA);
|
||||
|
||||
if (UTF8)
|
||||
{
|
||||
Utf8ToUtf16(FilePathA, FilePathW);
|
||||
Attr = GetFileAttributesW(FilePathW);
|
||||
}
|
||||
else
|
||||
{
|
||||
Attr = GetFileAttributesA(FilePathA);
|
||||
}
|
||||
|
||||
if (Attr != INVALID_FILE_ATTRIBUTES && (Attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int ventoy_is_file_exist(const char *Fmt, ...)
|
||||
{
|
||||
va_list Arg;
|
||||
HANDLE hFile;
|
||||
DWORD Attr;
|
||||
int UTF8 = 0;
|
||||
CHAR FilePathA[MAX_PATH];
|
||||
WCHAR FilePathW[MAX_PATH];
|
||||
|
||||
va_start(Arg, Fmt);
|
||||
vsnprintf_s(FilePathA, sizeof(FilePathA), sizeof(FilePathA), Fmt, Arg);
|
||||
va_end(Arg);
|
||||
|
||||
UTF8 = IsUTF8Encode(FilePathA);
|
||||
if (UTF8)
|
||||
{
|
||||
Utf8ToUtf16(FilePathA, FilePathW);
|
||||
hFile = CreateFileW(FilePathW, FILE_READ_EA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
|
||||
Attr = GetFileAttributesW(FilePathW);
|
||||
}
|
||||
else
|
||||
{
|
||||
hFile = CreateFileA(FilePathA, FILE_READ_EA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
|
||||
Attr = GetFileAttributesA(FilePathA);
|
||||
}
|
||||
|
||||
if (INVALID_HANDLE_VALUE == hFile)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
|
||||
if (Attr & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char * ventoy_get_os_language(void)
|
||||
{
|
||||
if (GetUserDefaultUILanguage() == 0x0804)
|
||||
{
|
||||
return "cn";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "en";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int GetPhyDriveByLogicalDrive(int DriveLetter, UINT64 *Offset)
|
||||
{
|
||||
BOOL Ret;
|
||||
DWORD dwSize;
|
||||
HANDLE Handle;
|
||||
VOLUME_DISK_EXTENTS DiskExtents;
|
||||
CHAR PhyPath[128];
|
||||
|
||||
scnprintf(PhyPath, sizeof(PhyPath), "\\\\.\\%C:", (CHAR)DriveLetter);
|
||||
|
||||
Handle = CreateFileA(PhyPath, 0, 0, 0, OPEN_EXISTING, 0, 0);
|
||||
if (Handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
vlog("CreateFileA %s failed %u\n", PhyPath, LASTERR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Ret = DeviceIoControl(Handle,
|
||||
IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
|
||||
NULL,
|
||||
0,
|
||||
&DiskExtents,
|
||||
(DWORD)(sizeof(DiskExtents)),
|
||||
(LPDWORD)&dwSize,
|
||||
NULL);
|
||||
|
||||
if (!Ret || DiskExtents.NumberOfDiskExtents == 0)
|
||||
{
|
||||
vlog("IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTSfailed %u\n", LASTERR);
|
||||
CHECK_CLOSE_HANDLE(Handle);
|
||||
return -1;
|
||||
}
|
||||
CHECK_CLOSE_HANDLE(Handle);
|
||||
|
||||
if (Offset)
|
||||
{
|
||||
*Offset = (UINT64)(DiskExtents.Extents[0].StartingOffset.QuadPart);
|
||||
}
|
||||
|
||||
return (int)DiskExtents.Extents[0].DiskNumber;
|
||||
}
|
||||
|
||||
int GetPhyDriveInfo(int PhyDrive, UINT64 *Size, CHAR *Vendor, CHAR *Product)
|
||||
{
|
||||
int ret = 1;
|
||||
BOOL bRet;
|
||||
DWORD dwBytes;
|
||||
CHAR Drive[64];
|
||||
HANDLE Handle = INVALID_HANDLE_VALUE;
|
||||
GET_LENGTH_INFORMATION LengthInfo;
|
||||
STORAGE_PROPERTY_QUERY Query;
|
||||
STORAGE_DESCRIPTOR_HEADER DevDescHeader;
|
||||
STORAGE_DEVICE_DESCRIPTOR *pDevDesc = NULL;
|
||||
|
||||
sprintf_s(Drive, sizeof(Drive), "\\\\.\\PhysicalDrive%d", PhyDrive);
|
||||
Handle = CreateFileA(Drive, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (Handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
vlog("CreateFileA %s failed %u\n", Drive, LASTERR);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
bRet = DeviceIoControl(Handle,
|
||||
IOCTL_DISK_GET_LENGTH_INFO, NULL,
|
||||
0,
|
||||
&LengthInfo,
|
||||
sizeof(LengthInfo),
|
||||
&dwBytes,
|
||||
NULL);
|
||||
if (!bRet)
|
||||
{
|
||||
vlog("IOCTL_DISK_GET_LENGTH_INFO failed %u\n", LASTERR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (Size)
|
||||
{
|
||||
*Size = (UINT64)LengthInfo.Length.QuadPart;
|
||||
}
|
||||
|
||||
Query.PropertyId = StorageDeviceProperty;
|
||||
Query.QueryType = PropertyStandardQuery;
|
||||
|
||||
bRet = DeviceIoControl(Handle,
|
||||
IOCTL_STORAGE_QUERY_PROPERTY,
|
||||
&Query,
|
||||
sizeof(Query),
|
||||
&DevDescHeader,
|
||||
sizeof(STORAGE_DESCRIPTOR_HEADER),
|
||||
&dwBytes,
|
||||
NULL);
|
||||
if (!bRet)
|
||||
{
|
||||
vlog("IOCTL_STORAGE_QUERY_PROPERTY failed %u\n", LASTERR);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (DevDescHeader.Size < sizeof(STORAGE_DEVICE_DESCRIPTOR))
|
||||
{
|
||||
vlog("DevDescHeader.size invalid %u\n", DevDescHeader.Size);
|
||||
goto out;
|
||||
}
|
||||
|
||||
pDevDesc = (STORAGE_DEVICE_DESCRIPTOR *)malloc(DevDescHeader.Size);
|
||||
if (!pDevDesc)
|
||||
{
|
||||
vlog("malloc failed\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
bRet = DeviceIoControl(Handle,
|
||||
IOCTL_STORAGE_QUERY_PROPERTY,
|
||||
&Query,
|
||||
sizeof(Query),
|
||||
pDevDesc,
|
||||
DevDescHeader.Size,
|
||||
&dwBytes,
|
||||
NULL);
|
||||
if (!bRet)
|
||||
{
|
||||
vlog("IOCTL_STORAGE_QUERY_PROPERTY failed %u\n", LASTERR);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (pDevDesc->VendorIdOffset && Vendor)
|
||||
{
|
||||
strcpy_s(Vendor, 128, (char *)pDevDesc + pDevDesc->VendorIdOffset);
|
||||
TrimString(Vendor);
|
||||
}
|
||||
|
||||
if (pDevDesc->ProductIdOffset && Product)
|
||||
{
|
||||
strcpy_s(Product, 128, (char *)pDevDesc + pDevDesc->ProductIdOffset);
|
||||
TrimString(Product);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
CHECK_FREE(pDevDesc);
|
||||
CHECK_CLOSE_HANDLE(Handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int ventoy_get_file_size(const char *file)
|
||||
{
|
||||
int Size = -1;
|
||||
HANDLE hFile;
|
||||
|
||||
hFile = CreateFileA(file, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
Size = (int)GetFileSize(hFile, NULL);
|
||||
CHECK_CLOSE_HANDLE(hFile);
|
||||
}
|
||||
|
||||
return Size;
|
||||
}
|
||||
|
||||
|
||||
static HANDLE g_FatPhyDrive;
|
||||
static UINT64 g_Part2StartSec;
|
||||
|
||||
const CHAR* ParseVentoyVersionFromString(CHAR *Buf)
|
||||
{
|
||||
CHAR *Pos = NULL;
|
||||
CHAR *End = NULL;
|
||||
static CHAR LocalVersion[64] = { 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;
|
||||
|
||||
sprintf_s(LocalVersion, sizeof(LocalVersion), "%s", Pos);
|
||||
return LocalVersion;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
static int GetVentoyVersionFromFatFile(CHAR *VerBuf, size_t BufLen)
|
||||
{
|
||||
int rc = 1;
|
||||
int size = 0;
|
||||
char *buf = 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 = (char *)malloc(size + 1);
|
||||
if (buf)
|
||||
{
|
||||
fl_fread(buf, 1, size, flfile);
|
||||
buf[size] = 0;
|
||||
|
||||
rc = 0;
|
||||
sprintf_s(VerBuf, BufLen, "%s", ParseVentoyVersionFromString(buf));
|
||||
free(buf);
|
||||
}
|
||||
|
||||
fl_fclose(flfile);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int VentoyFatDiskRead(uint32 Sector, uint8 *Buffer, uint32 SectorCount)
|
||||
{
|
||||
DWORD dwSize;
|
||||
BOOL bRet;
|
||||
DWORD ReadSize;
|
||||
LARGE_INTEGER liCurrentPosition;
|
||||
|
||||
liCurrentPosition.QuadPart = Sector + g_Part2StartSec;
|
||||
liCurrentPosition.QuadPart *= 512;
|
||||
SetFilePointerEx(g_FatPhyDrive, liCurrentPosition, &liCurrentPosition, FILE_BEGIN);
|
||||
|
||||
ReadSize = (DWORD)(SectorCount * 512);
|
||||
|
||||
bRet = ReadFile(g_FatPhyDrive, Buffer, ReadSize, &dwSize, NULL);
|
||||
if (bRet == FALSE || dwSize != ReadSize)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int GetVentoyVersion(int PhyDrive, ventoy_disk *disk)
|
||||
{
|
||||
int ret = 1;
|
||||
BOOL bRet;
|
||||
DWORD dwBytes;
|
||||
UINT64 Part2Offset;
|
||||
HANDLE Handle = INVALID_HANDLE_VALUE;
|
||||
VTOY_GPT_INFO *pGPT = NULL;
|
||||
CHAR Drive[64];
|
||||
void *flfile = NULL;
|
||||
UCHAR MbrData[] =
|
||||
{
|
||||
0xEB, 0x63, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x56, 0x54, 0x00, 0x47, 0x65, 0x00, 0x48, 0x44, 0x00, 0x52, 0x64, 0x00, 0x20, 0x45, 0x72, 0x0D,
|
||||
};
|
||||
|
||||
sprintf_s(Drive, sizeof(Drive), "\\\\.\\PhysicalDrive%d", PhyDrive);
|
||||
Handle = CreateFileA(Drive, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (Handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
vlog("CreateFileA %s failed %u\n", Drive, LASTERR);
|
||||
goto out;
|
||||
}
|
||||
|
||||
pGPT = zalloc(sizeof(VTOY_GPT_INFO));
|
||||
if (!pGPT)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
bRet = ReadFile(Handle, pGPT, sizeof(VTOY_GPT_INFO), &dwBytes, NULL);
|
||||
if (!bRet || dwBytes != sizeof(VTOY_GPT_INFO))
|
||||
{
|
||||
vlog("ReadFile failed %u\n", LASTERR);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (memcmp(pGPT->MBR.BootCode, MbrData, 0x30) || memcmp(pGPT->MBR.BootCode + 0x190, MbrData + 0x30, 0x10))
|
||||
{
|
||||
vlog("Invalid MBR Code %u\n", LASTERR);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (pGPT->MBR.PartTbl[0].FsFlag == 0xEE)
|
||||
{
|
||||
if (memcmp(pGPT->Head.Signature, "EFI PART", 8))
|
||||
{
|
||||
vlog("Invalid GPT Signature\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
Part2Offset = pGPT->PartTbl[1].StartLBA;
|
||||
disk->cur_part_style = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Part2Offset = pGPT->MBR.PartTbl[1].StartSectorId;
|
||||
disk->cur_part_style = 0;
|
||||
}
|
||||
|
||||
|
||||
g_FatPhyDrive = Handle;
|
||||
g_Part2StartSec = Part2Offset;
|
||||
|
||||
fl_init();
|
||||
|
||||
if (0 == fl_attach_media(VentoyFatDiskRead, NULL))
|
||||
{
|
||||
ret = GetVentoyVersionFromFatFile(disk->cur_ventoy_ver, sizeof(disk->cur_ventoy_ver));
|
||||
if (ret == 0)
|
||||
{
|
||||
flfile = fl_fopen("/EFI/BOOT/grubx64_real.efi", "rb");
|
||||
if (flfile)
|
||||
{
|
||||
disk->cur_secureboot = 1;
|
||||
fl_fclose(flfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fl_shutdown();
|
||||
|
||||
out:
|
||||
CHECK_FREE(pGPT);
|
||||
CHECK_CLOSE_HANDLE(Handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CheckRuntimeEnvironment(char Letter, ventoy_disk *disk)
|
||||
{
|
||||
int PhyDrive;
|
||||
UINT64 Offset = 0;
|
||||
char Drive[32];
|
||||
DWORD FsFlag;
|
||||
CHAR Vendor[128] = { 0 };
|
||||
CHAR Product[128] = { 0 };
|
||||
CHAR FsName[MAX_PATH];
|
||||
|
||||
PhyDrive = GetPhyDriveByLogicalDrive(Letter, &Offset);
|
||||
if (PhyDrive < 0)
|
||||
{
|
||||
vlog("GetPhyDriveByLogicalDrive failed %d %llu\n", PhyDrive, (ULONGLONG)Offset);
|
||||
return 1;
|
||||
}
|
||||
if (Offset != 1048576)
|
||||
{
|
||||
vlog("Partition offset is NOT 1MB. This is NOT ventoy image partition (%llu)\n", (ULONGLONG)Offset);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (GetPhyDriveInfo(PhyDrive, &Offset, Vendor, Product) != 0)
|
||||
{
|
||||
vlog("GetPhyDriveInfo failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
sprintf_s(disk->cur_capacity, sizeof(disk->cur_capacity), "%dGB", (int)ventoy_get_human_readable_gb(Offset));
|
||||
sprintf_s(disk->cur_model, sizeof(disk->cur_model), "%s %s", Vendor, Product);
|
||||
|
||||
scnprintf(Drive, sizeof(Drive), "%C:\\", Letter);
|
||||
if (0 == GetVolumeInformationA(Drive, NULL, 0, NULL, NULL, &FsFlag, FsName, MAX_PATH))
|
||||
{
|
||||
vlog("GetVolumeInformationA failed %u\n", LASTERR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (_stricmp(FsName, "NTFS") == 0)
|
||||
{
|
||||
disk->pathcase = 1;
|
||||
}
|
||||
|
||||
strlcpy(disk->cur_fsname, FsName);
|
||||
|
||||
if (GetVentoyVersion(PhyDrive, disk) != 0)
|
||||
{
|
||||
vlog("GetVentoyVersion failed %u\n", LASTERR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ventoy_write_buf_to_file(const char *FileName, void *Bufer, int BufLen)
|
||||
{
|
||||
BOOL bRet;
|
||||
DWORD dwBytes;
|
||||
HANDLE hFile;
|
||||
|
||||
hFile = CreateFileA(FileName, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
vlog("CreateFile %s failed %u\n", FileName, LASTERR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
bRet = WriteFile(hFile, Bufer, (DWORD)BufLen, &dwBytes, NULL);
|
||||
|
||||
if ((!bRet) || ((DWORD)BufLen != dwBytes))
|
||||
{
|
||||
vlog("Failed to write file <%s> %u err:%u", FileName, dwBytes, LASTERR);
|
||||
CloseHandle(hFile);
|
||||
return 1;
|
||||
}
|
||||
|
||||
FlushFileBuffers(hFile);
|
||||
CloseHandle(hFile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ventoy_decompress_tar(char *tarbuf, int buflen, int *tarsize)
|
||||
{
|
||||
int rc = 1;
|
||||
int inused;
|
||||
HANDLE hFile;
|
||||
DWORD dwSize;
|
||||
DWORD dwRead;
|
||||
WCHAR FullPath[MAX_PATH];
|
||||
BYTE *buffer;
|
||||
VENTOY_MAGIC Magic;
|
||||
|
||||
GetModuleFileNameW(NULL, FullPath, MAX_PATH);
|
||||
hFile = CreateFileW(FullPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
vlog("Failed to open self %u\n", LASTERR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
dwSize = GetFileSize(hFile, NULL);
|
||||
if (dwSize == INVALID_FILE_SIZE)
|
||||
{
|
||||
vlog("Invalid self exe size %u\n", LASTERR);
|
||||
CHECK_CLOSE_HANDLE(hFile);
|
||||
return 1;
|
||||
}
|
||||
|
||||
buffer = malloc(dwSize);
|
||||
if (!buffer)
|
||||
{
|
||||
vlog("Failed to malloc %u\n", dwSize);
|
||||
CHECK_CLOSE_HANDLE(hFile);
|
||||
return 1;
|
||||
}
|
||||
ReadFile(hFile, buffer, dwSize, &dwRead, NULL);
|
||||
|
||||
memcpy(&Magic, buffer + dwSize - sizeof(Magic), sizeof(Magic));
|
||||
if (Magic.magic1 == 0x54535251 && Magic.magic2 == 0xa4a3a2a1)
|
||||
{
|
||||
g_unxz_buffer = (UCHAR *)tarbuf;
|
||||
g_unxz_len = 0;
|
||||
|
||||
unxz(buffer + dwSize - Magic.xzlen - sizeof(Magic), Magic.xzlen, NULL, unxz_flush, NULL, &inused, unxz_error);
|
||||
vlog("bigexe:%u xzlen:%u rawdata size:%d\n", dwSize, Magic.xzlen, g_unxz_len);
|
||||
|
||||
if (inused != Magic.xzlen)
|
||||
{
|
||||
vlog("Failed to unxz www %d\n", inused);
|
||||
rc = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*tarsize = g_unxz_len;
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vlog("Invalid magic 0x%x 0x%x\n", Magic.magic1, Magic.magic2);
|
||||
rc = 1;
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
CHECK_CLOSE_HANDLE(hFile);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static volatile int g_thread_stop = 0;
|
||||
static HANDLE g_writeback_thread;
|
||||
static HANDLE g_writeback_event;
|
||||
|
||||
DWORD WINAPI ventoy_local_thread_run(LPVOID lpParameter)
|
||||
{
|
||||
ventoy_http_writeback_pf callback = (ventoy_http_writeback_pf)lpParameter;
|
||||
|
||||
while (1)
|
||||
{
|
||||
WaitForSingleObject(g_writeback_event, INFINITE);
|
||||
if (g_thread_stop)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void ventoy_set_writeback_event(void)
|
||||
{
|
||||
SetEvent(g_writeback_event);
|
||||
}
|
||||
|
||||
|
||||
int ventoy_start_writeback_thread(ventoy_http_writeback_pf callback)
|
||||
{
|
||||
g_thread_stop = 0;
|
||||
g_writeback_event = CreateEventA(NULL, FALSE, FALSE, "VTOYWRBK");
|
||||
g_writeback_thread = CreateThread(NULL, 0, ventoy_local_thread_run, callback, 0, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void ventoy_stop_writeback_thread(void)
|
||||
{
|
||||
g_thread_stop = 1;
|
||||
ventoy_set_writeback_event();
|
||||
|
||||
WaitForSingleObject(g_writeback_thread, INFINITE);
|
||||
|
||||
CHECK_CLOSE_HANDLE(g_writeback_thread);
|
||||
CHECK_CLOSE_HANDLE(g_writeback_event);
|
||||
}
|
||||
|
||||
|
||||
int ventoy_copy_file(const char *a, const char *b)
|
||||
{
|
||||
CopyFileA(a, b, FALSE);
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user