Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
dadigang
Ventoy
Commits
43e8ec57
"app/src/app.tsx" did not exist on "2f4aa42d2ee0a0a1763dd6779dc3353ee6fb8f7f"
Commit
43e8ec57
authored
Feb 26, 2021
by
longpanda
Browse files
Experimental Linux GUI based on web browser
parent
7279ba9b
Changes
158
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
4148 additions
and
0 deletions
+4148
-0
INSTALL/README
INSTALL/README
+4
-0
INSTALL/VentoyWeb.sh
INSTALL/VentoyWeb.sh
+182
-0
INSTALL/ventoy_pack.sh
INSTALL/ventoy_pack.sh
+12
-0
LinuxGUI/Ventoy2Disk/Core/ventoy_crc32.c
LinuxGUI/Ventoy2Disk/Core/ventoy_crc32.c
+299
-0
LinuxGUI/Ventoy2Disk/Core/ventoy_define.h
LinuxGUI/Ventoy2Disk/Core/ventoy_define.h
+192
-0
LinuxGUI/Ventoy2Disk/Core/ventoy_disk.c
LinuxGUI/Ventoy2Disk/Core/ventoy_disk.c
+735
-0
LinuxGUI/Ventoy2Disk/Core/ventoy_disk.h
LinuxGUI/Ventoy2Disk/Core/ventoy_disk.h
+145
-0
LinuxGUI/Ventoy2Disk/Core/ventoy_json.c
LinuxGUI/Ventoy2Disk/Core/ventoy_json.c
+716
-0
LinuxGUI/Ventoy2Disk/Core/ventoy_json.h
LinuxGUI/Ventoy2Disk/Core/ventoy_json.h
+267
-0
LinuxGUI/Ventoy2Disk/Core/ventoy_log.c
LinuxGUI/Ventoy2Disk/Core/ventoy_log.c
+115
-0
LinuxGUI/Ventoy2Disk/Core/ventoy_md5.c
LinuxGUI/Ventoy2Disk/Core/ventoy_md5.c
+167
-0
LinuxGUI/Ventoy2Disk/Core/ventoy_util.c
LinuxGUI/Ventoy2Disk/Core/ventoy_util.c
+541
-0
LinuxGUI/Ventoy2Disk/Core/ventoy_util.h
LinuxGUI/Ventoy2Disk/Core/ventoy_util.h
+52
-0
LinuxGUI/Ventoy2Disk/Include/Ventoy2Disk.h
LinuxGUI/Ventoy2Disk/Include/Ventoy2Disk.h
+26
-0
LinuxGUI/Ventoy2Disk/Lib/exfat/buidexfat.sh
LinuxGUI/Ventoy2Disk/Lib/exfat/buidexfat.sh
+30
-0
LinuxGUI/Ventoy2Disk/Lib/exfat/exfat-1.3.0.zip
LinuxGUI/Ventoy2Disk/Lib/exfat/exfat-1.3.0.zip
+0
-0
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h
+68
-0
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/cluster.c
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/cluster.c
+491
-0
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h
+66
-0
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/config.h
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/config.h
+40
-0
No files found.
INSTALL/README
View file @
43e8ec57
...
...
@@ -17,6 +17,10 @@ Ventoy2Disk.sh CMD [ OPTION ] /dev/sdX
Please refer https://www.ventoy.net/en/doc_start.html for details.
========== VentoyWeb.sh ===============
sudo sh VentoyWeb.sh
Normally, it will popup a web browser window.
If not you can open your browser and visit http://127.0.0.1:24680
...
...
INSTALL/VentoyWeb.sh
0 → 100644
View file @
43e8ec57
#!/bin/sh
print_usage
()
{
echo
'Usage: VentoyWeb.sh [ OPTION ]'
echo
' OPTION: (optional)'
echo
' -H x.x.x.x http server IP address (default is 127.0.0.1)'
echo
' -p PORT http server PORT (default is 24680)'
echo
" -n don't start web browser"
echo
' -h print this help'
echo
''
}
print_err
()
{
echo
""
echo
"
$*
"
echo
""
}
check_option
()
{
app
=
"
$1
"
$app
--help
2>&1 |
grep
-q
"
$2
"
}
get_user
()
{
name
=
$(
logname
)
if
[
-n
"
$name
"
-a
"
$name
"
!=
"root"
]
;
then
echo
$name
;
return
fi
name
=
${
HOME
#/home/
}
if
[
-n
"
$name
"
-a
"
$name
"
!=
"root"
]
;
then
echo
$name
;
return
fi
}
chromium_proc
()
{
app
=
"
$1
"
url
=
"http://
${
HOST
}
:
${
PORT
}
/index.html"
if
check_option
"
$app
"
'[-][-]app='
;
then
su
$VUSER
-c
"
$app
--app=
$url
>>
$LOGFILE
2>&1"
elif
check_option
"
$app
"
'[-][-]new[-]window='
;
then
su
$VUSER
-c
"
$app
--new-window
$url
>>
$LOGFILE
2>&1"
else
su
$VUSER
-c
"
$app
$url
>>
$LOGFILE
2>&1"
fi
}
uid
=
$(
id
-u
)
if
[
$uid
-ne
0
]
;
then
print_err
"Please use sudo or run the script as root."
exit
1
fi
OLDDIR
=
$(
pwd
)
if
uname
-a
| egrep
-q
'aarch64|arm64'
;
then
TOOLDIR
=
aarch64
elif
uname
-a
| egrep
-q
'x86_64|amd64'
;
then
TOOLDIR
=
x86_64
else
TOOLDIR
=
i386
fi
if
[
!
-f
./tool/
$TOOLDIR
/V2DServer
]
;
then
if
[
-f
${
0
%VentoyWeb.sh
}
/tool/
$TOOLDIR
/V2DServer
]
;
then
cd
${
0
%VentoyWeb.sh
}
fi
fi
PATH
=
./tool/
$TOOLDIR
:
$PATH
if
[
!
-f
./boot/boot.img
]
;
then
if
[
-d
./grub
]
;
then
echo
"Don't run VentoyWeb.sh here, please download the released install package, and run the script in it."
else
echo
"Please run under the correct directory!"
fi
exit
1
fi
HOST
=
"127.0.0.1"
PORT
=
24680
while
[
-n
"
$1
"
]
;
do
if
[
"
$1
"
=
"-h"
]
||
[
"
$1
"
=
"--help"
]
;
then
print_usage
exit
0
elif
[
"
$1
"
=
"-n"
]
;
then
NOWEB
=
1
elif
[
"
$1
"
=
"-H"
]
;
then
shift
if
echo
$1
|
grep
-q
'[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*'
;
then
HOST
=
"
$1
"
else
print_err
"Invalid host
$1
"
exit
1
fi
elif
[
"
$1
"
=
"-p"
]
;
then
shift
if
[
$1
-gt
0
-a
$1
-le
65535
]
;
then
PORT
=
"
$1
"
else
print_err
"Invalid port
$1
"
exit
1
fi
fi
shift
done
if
ps
-ef
|
grep
"V2DServer.*
$HOST
.*
$PORT
"
|
grep
-q
-v
grep
;
then
print_err
"Another ventoy server is running now, please close it first."
exit
1
fi
VUSER
=
$(
get_user
)
LOGFILE
=
log.txt
#delete the log.txt if it's more than 8MB
if
[
-f
$LOGFILE
]
;
then
logsize
=
$(
stat
-c
'%s'
$LOGFILE
)
if
[
$logsize
-gt
8388608
]
;
then
rm
-f
$LOGFILE
su
$VUSER
-c
"touch
$LOGFILE
"
fi
else
su
$VUSER
-c
"touch
$LOGFILE
"
fi
if
[
-f
./tool/
$TOOLDIR
/V2DServer.xz
]
;
then
xz
-d
./tool/
$TOOLDIR
/V2DServer.xz
chmod
+x ./tool/
$TOOLDIR
/V2DServer
fi
V2DServer
"
$HOST
"
"
$PORT
"
&
vtVer
=
$(
cat
ventoy/version
)
echo
""
echo
"=================================================================="
echo
" Ventoy Server
$vtVer
is running at http://
${
HOST
}
:
${
PORT
}
..."
echo
"=================================================================="
echo
""
echo
"################ Press Ctrl + C to exit ######################"
echo
""
if
[
"
$NOWEB
"
=
"1"
]
;
then
echo
"Please open your web browser and visit http://
${
HOST
}
:
${
PORT
}
"
else
if
which
-a
google-chrome-stable
>>
$LOGFILE
2>&1
;
then
chromium_proc google-chrome-stable
elif
which
-a
google-chrome
>>
$LOGFILE
2>&1
;
then
chromium_proc google-chrome
elif
which
-a
chrome
>>
$LOGFILE
2>&1
;
then
chromium_proc chrome
elif
which
-a
browser
>>
$LOGFILE
2>&1
;
then
chromium_proc browser
elif
which
-a
firefox
>>
$LOGFILE
2>&1
;
then
su
$VUSER
-c
"firefox --no-remote
\"
http://
${
HOST
}
:
${
PORT
}
/index.html
\"
"
else
echo
"Please open your web browser and visit http://
${
HOST
}
:
${
PORT
}
"
fi
fi
if
ps
-ef
|
grep
"V2DServer.*
$HOST
.*
$PORT
"
|
grep
-q
-v
grep
;
then
echo
""
else
print_err
"Ventoy Server Error! Please check log.txt."
fi
wait
$!
if
[
-n
"
$OLDDIR
"
]
;
then
CURDIR
=
$(
pwd
)
if
[
"
$CURDIR
"
!=
"
$OLDDIR
"
]
;
then
cd
"
$OLDDIR
"
fi
fi
INSTALL/ventoy_pack.sh
View file @
43e8ec57
...
...
@@ -25,6 +25,11 @@ sh mkcpio.sh
sh mkloopex.sh
cd
-
cd
../LinuxGUI
sh language.sh
||
exit
1
sh build.sh
cd
-
LOOP
=
$(
losetup
-f
)
...
...
@@ -88,12 +93,17 @@ xz --check=crc32 $tmpdir/boot/core.img
cp
$OPT
./tool
$tmpdir
/
rm
-f
$tmpdir
/ENROLL_THIS_KEY_IN_MOKMANAGER.cer
cp
$OPT
Ventoy2Disk.sh
$tmpdir
/
cp
$OPT
VentoyWeb.sh
$tmpdir
/
cp
$OPT
README
$tmpdir
/
cp
$OPT
plugin
$tmpdir
/
cp
$OPT
CreatePersistentImg.sh
$tmpdir
/
dos2unix
-q
$tmpdir
/Ventoy2Disk.sh
dos2unix
-q
$tmpdir
/VentoyWeb.sh
dos2unix
-q
$tmpdir
/CreatePersistentImg.sh
cp
$OPT
../LinuxGUI/WebUI
$tmpdir
/
sed
's/.*SCRIPT_DEL_THIS \(.*\)/\1/g'
-i
$tmpdir
/WebUI/index.html
#32MB disk img
dd
status
=
none
if
=
$LOOP
of
=
$tmpdir
/ventoy/ventoy.disk.img
bs
=
512
count
=
$VENTOY_SECTOR_NUM
skip
=
$part2_start_sector
xz
--check
=
crc32
$tmpdir
/ventoy/ventoy.disk.img
...
...
@@ -119,6 +129,7 @@ done
find
$tmpdir
/
-type
d
-exec
chmod
755
"{}"
+
find
$tmpdir
/
-type
f
-exec
chmod
644
"{}"
+
chmod
+x
$tmpdir
/Ventoy2Disk.sh
chmod
+x
$tmpdir
/VentoyWeb.sh
chmod
+x
$tmpdir
/CreatePersistentImg.sh
tar
-czvf
ventoy-
${
curver
}
-linux
.tar.gz
$tmpdir
...
...
@@ -130,6 +141,7 @@ cp $OPT Ventoy2Disk*.exe $tmpdir/
cp
$OPT
$LANG_DIR
/languages.ini
$tmpdir
/ventoy/
rm
-rf
$tmpdir
/tool
rm
-f
$tmpdir
/
*
.sh
rm
-rf
$tmpdir
/WebUI
rm
-f
$tmpdir
/README
...
...
LinuxGUI/Ventoy2Disk/Core/ventoy_crc32.c
0 → 100644
View file @
43e8ec57
/******************************************************************************
* crc32.c ---- ventoy crc32
*
* Copyright (c) 2021, longpanda <admin@ventoy.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
static
uint32_t
g_crc_table
[
256
]
=
{
0x00000000
,
0x77073096
,
0xEE0E612C
,
0x990951BA
,
0x076DC419
,
0x706AF48F
,
0xE963A535
,
0x9E6495A3
,
0x0EDB8832
,
0x79DCB8A4
,
0xE0D5E91E
,
0x97D2D988
,
0x09B64C2B
,
0x7EB17CBD
,
0xE7B82D07
,
0x90BF1D91
,
0x1DB71064
,
0x6AB020F2
,
0xF3B97148
,
0x84BE41DE
,
0x1ADAD47D
,
0x6DDDE4EB
,
0xF4D4B551
,
0x83D385C7
,
0x136C9856
,
0x646BA8C0
,
0xFD62F97A
,
0x8A65C9EC
,
0x14015C4F
,
0x63066CD9
,
0xFA0F3D63
,
0x8D080DF5
,
0x3B6E20C8
,
0x4C69105E
,
0xD56041E4
,
0xA2677172
,
0x3C03E4D1
,
0x4B04D447
,
0xD20D85FD
,
0xA50AB56B
,
0x35B5A8FA
,
0x42B2986C
,
0xDBBBC9D6
,
0xACBCF940
,
0x32D86CE3
,
0x45DF5C75
,
0xDCD60DCF
,
0xABD13D59
,
0x26D930AC
,
0x51DE003A
,
0xC8D75180
,
0xBFD06116
,
0x21B4F4B5
,
0x56B3C423
,
0xCFBA9599
,
0xB8BDA50F
,
0x2802B89E
,
0x5F058808
,
0xC60CD9B2
,
0xB10BE924
,
0x2F6F7C87
,
0x58684C11
,
0xC1611DAB
,
0xB6662D3D
,
0x76DC4190
,
0x01DB7106
,
0x98D220BC
,
0xEFD5102A
,
0x71B18589
,
0x06B6B51F
,
0x9FBFE4A5
,
0xE8B8D433
,
0x7807C9A2
,
0x0F00F934
,
0x9609A88E
,
0xE10E9818
,
0x7F6A0DBB
,
0x086D3D2D
,
0x91646C97
,
0xE6635C01
,
0x6B6B51F4
,
0x1C6C6162
,
0x856530D8
,
0xF262004E
,
0x6C0695ED
,
0x1B01A57B
,
0x8208F4C1
,
0xF50FC457
,
0x65B0D9C6
,
0x12B7E950
,
0x8BBEB8EA
,
0xFCB9887C
,
0x62DD1DDF
,
0x15DA2D49
,
0x8CD37CF3
,
0xFBD44C65
,
0x4DB26158
,
0x3AB551CE
,
0xA3BC0074
,
0xD4BB30E2
,
0x4ADFA541
,
0x3DD895D7
,
0xA4D1C46D
,
0xD3D6F4FB
,
0x4369E96A
,
0x346ED9FC
,
0xAD678846
,
0xDA60B8D0
,
0x44042D73
,
0x33031DE5
,
0xAA0A4C5F
,
0xDD0D7CC9
,
0x5005713C
,
0x270241AA
,
0xBE0B1010
,
0xC90C2086
,
0x5768B525
,
0x206F85B3
,
0xB966D409
,
0xCE61E49F
,
0x5EDEF90E
,
0x29D9C998
,
0xB0D09822
,
0xC7D7A8B4
,
0x59B33D17
,
0x2EB40D81
,
0xB7BD5C3B
,
0xC0BA6CAD
,
0xEDB88320
,
0x9ABFB3B6
,
0x03B6E20C
,
0x74B1D29A
,
0xEAD54739
,
0x9DD277AF
,
0x04DB2615
,
0x73DC1683
,
0xE3630B12
,
0x94643B84
,
0x0D6D6A3E
,
0x7A6A5AA8
,
0xE40ECF0B
,
0x9309FF9D
,
0x0A00AE27
,
0x7D079EB1
,
0xF00F9344
,
0x8708A3D2
,
0x1E01F268
,
0x6906C2FE
,
0xF762575D
,
0x806567CB
,
0x196C3671
,
0x6E6B06E7
,
0xFED41B76
,
0x89D32BE0
,
0x10DA7A5A
,
0x67DD4ACC
,
0xF9B9DF6F
,
0x8EBEEFF9
,
0x17B7BE43
,
0x60B08ED5
,
0xD6D6A3E8
,
0xA1D1937E
,
0x38D8C2C4
,
0x4FDFF252
,
0xD1BB67F1
,
0xA6BC5767
,
0x3FB506DD
,
0x48B2364B
,
0xD80D2BDA
,
0xAF0A1B4C
,
0x36034AF6
,
0x41047A60
,
0xDF60EFC3
,
0xA867DF55
,
0x316E8EEF
,
0x4669BE79
,
0xCB61B38C
,
0xBC66831A
,
0x256FD2A0
,
0x5268E236
,
0xCC0C7795
,
0xBB0B4703
,
0x220216B9
,
0x5505262F
,
0xC5BA3BBE
,
0xB2BD0B28
,
0x2BB45A92
,
0x5CB36A04
,
0xC2D7FFA7
,
0xB5D0CF31
,
0x2CD99E8B
,
0x5BDEAE1D
,
0x9B64C2B0
,
0xEC63F226
,
0x756AA39C
,
0x026D930A
,
0x9C0906A9
,
0xEB0E363F
,
0x72076785
,
0x05005713
,
0x95BF4A82
,
0xE2B87A14
,
0x7BB12BAE
,
0x0CB61B38
,
0x92D28E9B
,
0xE5D5BE0D
,
0x7CDCEFB7
,
0x0BDBDF21
,
0x86D3D2D4
,
0xF1D4E242
,
0x68DDB3F8
,
0x1FDA836E
,
0x81BE16CD
,
0xF6B9265B
,
0x6FB077E1
,
0x18B74777
,
0x88085AE6
,
0xFF0F6A70
,
0x66063BCA
,
0x11010B5C
,
0x8F659EFF
,
0xF862AE69
,
0x616BFFD3
,
0x166CCF45
,
0xA00AE278
,
0xD70DD2EE
,
0x4E048354
,
0x3903B3C2
,
0xA7672661
,
0xD06016F7
,
0x4969474D
,
0x3E6E77DB
,
0xAED16A4A
,
0xD9D65ADC
,
0x40DF0B66
,
0x37D83BF0
,
0xA9BCAE53
,
0xDEBB9EC5
,
0x47B2CF7F
,
0x30B5FFE9
,
0xBDBDF21C
,
0xCABAC28A
,
0x53B39330
,
0x24B4A3A6
,
0xBAD03605
,
0xCDD70693
,
0x54DE5729
,
0x23D967BF
,
0xB3667A2E
,
0xC4614AB8
,
0x5D681B02
,
0x2A6F2B94
,
0xB40BBE37
,
0xC30C8EA1
,
0x5A05DF1B
,
0x2D02EF8D
};
uint32_t
ventoy_crc32
(
void
*
Buffer
,
uint32_t
Length
)
{
uint32_t
i
;
uint8_t
*
Ptr
=
Buffer
;
uint32_t
Crc
=
0xFFFFFFFF
;
for
(
i
=
0
;
i
<
Length
;
i
++
,
Ptr
++
)
{
Crc
=
(
Crc
>>
8
)
^
g_crc_table
[(
uint8_t
)
Crc
^
*
Ptr
];
}
return
Crc
^
0xffffffff
;
}
LinuxGUI/Ventoy2Disk/Core/ventoy_define.h
0 → 100644
View file @
43e8ec57
/******************************************************************************
* ventoy_define.h
*
* Copyright (c) 2021, longpanda <admin@ventoy.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __VENTOY_DEFINE_H__
#define __VENTOY_DEFINE_H__
#define MAX_DISK_NUM 256
#define SIZE_1MB 1048576
#define SIZE_1GB 1073741824
#define VTOYIMG_PART_START_BYTES (1024 * 1024)
#define VTOYIMG_PART_START_SECTOR 2048
#define VTOYEFI_PART_BYTES (32 * 1024 * 1024)
#define VTOYEFI_PART_SECTORS 65536
#define VTOY_LOG_FILE "log.txt"
#pragma pack(1)
typedef
struct
vtoy_guid
{
uint32_t
data1
;
uint16_t
data2
;
uint16_t
data3
;
uint8_t
data4
[
8
];
}
vtoy_guid
;
typedef
struct
PART_TABLE
{
uint8_t
Active
;
// 0x00 0x80
uint8_t
StartHead
;
uint16_t
StartSector
:
6
;
uint16_t
StartCylinder
:
10
;
uint8_t
FsFlag
;
uint8_t
EndHead
;
uint16_t
EndSector
:
6
;
uint16_t
EndCylinder
:
10
;
uint32_t
StartSectorId
;
uint32_t
SectorCount
;
}
PART_TABLE
;
typedef
struct
MBR_HEAD
{
uint8_t
BootCode
[
446
];
PART_TABLE
PartTbl
[
4
];
uint8_t
Byte55
;
uint8_t
ByteAA
;
}
MBR_HEAD
;
typedef
struct
VTOY_GPT_HDR
{
char
Signature
[
8
];
/* EFI PART */
uint8_t
Version
[
4
];
uint32_t
Length
;
uint32_t
Crc
;
uint8_t
Reserved1
[
4
];
uint64_t
EfiStartLBA
;
uint64_t
EfiBackupLBA
;
uint64_t
PartAreaStartLBA
;
uint64_t
PartAreaEndLBA
;
vtoy_guid
DiskGuid
;
uint64_t
PartTblStartLBA
;
uint32_t
PartTblTotNum
;
uint32_t
PartTblEntryLen
;
uint32_t
PartTblCrc
;
uint8_t
Reserved2
[
420
];
}
VTOY_GPT_HDR
;
typedef
struct
VTOY_GPT_PART_TBL
{
vtoy_guid
PartType
;
vtoy_guid
PartGuid
;
uint64_t
StartLBA
;
uint64_t
LastLBA
;
uint64_t
Attr
;
uint16_t
Name
[
36
];
}
VTOY_GPT_PART_TBL
;
typedef
struct
VTOY_GPT_INFO
{
MBR_HEAD
MBR
;
VTOY_GPT_HDR
Head
;
VTOY_GPT_PART_TBL
PartTbl
[
128
];
}
VTOY_GPT_INFO
;
#pragma pack()
#define MBR_PART_STYLE 0
#define GPT_PART_STYLE 1
typedef
struct
disk_ventoy_data
{
int
ventoy_valid
;
char
ventoy_ver
[
32
];
// 1.0.33 ...
int
secure_boot_flag
;
uint64_t
preserved_space
;
uint64_t
part2_start_sector
;
int
partition_style
;
// MBR_PART_STYLE/GPT_PART_STYLE
VTOY_GPT_INFO
gptinfo
;
uint8_t
rsvdata
[
4096
];
}
disk_ventoy_data
;
typedef
struct
ventoy_disk
{
char
disk_name
[
32
];
// sda
char
disk_path
[
64
];
// /dev/sda
char
part1_name
[
32
];
// sda1
char
part1_path
[
64
];
// /dev/sda1
char
part2_name
[
32
];
// sda2
char
part2_path
[
64
];
// /dev/sda2
char
disk_model
[
256
];
// Sandisk/Kingston ...
char
human_readable_size
[
32
];
int
major
;
int
minor
;
int
type
;
int
partstyle
;
uint64_t
size_in_byte
;
disk_ventoy_data
vtoydata
;
}
ventoy_disk
;
#pragma pack(1)
typedef
struct
ventoy_guid
{
uint32_t
data1
;
uint16_t
data2
;
uint16_t
data3
;
uint8_t
data4
[
8
];
}
ventoy_guid
;
#pragma pack()
#ifndef O_BINARY
#define O_BINARY 0
#endif
#define VLOG_LOG 1
#define VLOG_DEBUG 2
#define ulong unsigned long
#define _ll long long
#define _ull unsigned long long
#define strlcpy(dst, src) strncpy(dst, src, sizeof(dst) - 1)
#define scnprintf(dst, fmt, args...) snprintf(dst, sizeof(dst) - 1, fmt, ##args)
#define vlog(fmt, args...) ventoy_syslog(VLOG_LOG, fmt, ##args)
#define vdebug(fmt, args...) ventoy_syslog(VLOG_DEBUG, fmt, ##args)
void
ventoy_syslog
(
int
level
,
const
char
*
Fmt
,
...);
void
ventoy_set_loglevel
(
int
level
);
uint32_t
ventoy_crc32
(
void
*
Buffer
,
uint32_t
Length
);
static
inline
void
*
zalloc
(
size_t
n
)
{
void
*
p
=
malloc
(
n
);
if
(
p
)
memset
(
p
,
0
,
n
);
return
p
;
}
#endif
/* __VENTOY_DEFINE_H__ */
LinuxGUI/Ventoy2Disk/Core/ventoy_disk.c
0 → 100644
View file @
43e8ec57
/******************************************************************************
* ventoy_disk.c ---- ventoy disk
* Copyright (c) 2021, longpanda <admin@ventoy.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <linux/fs.h>
#include <dirent.h>
#include <time.h>
#include <ventoy_define.h>
#include <ventoy_disk.h>
#include <ventoy_util.h>
#include <fat_filelib.h>
int
g_disk_num
=
0
;
static
int
g_fatlib_media_fd
=
0
;
static
uint64_t
g_fatlib_media_offset
=
0
;
ventoy_disk
*
g_disk_list
=
NULL
;
static
const
char
*
g_ventoy_dev_type_str
[
VTOY_DEVICE_END
]
=
{
"unknown"
,
"scsi"
,
"USB"
,
"ide"
,
"dac960"
,
"cpqarray"
,
"file"
,
"ataraid"
,
"i2o"
,
"ubd"
,
"dasd"
,
"viodasd"
,
"sx8"
,
"dm"
,
"xvd"
,
"sd/mmc"
,
"virtblk"
,
"aoe"
,
"md"
,
"loopback"
,
"nvme"
,
"brd"
,
"pmem"
};
static
const
char
*
ventoy_get_dev_type_name
(
ventoy_dev_type
type
)
{
return
(
type
<
VTOY_DEVICE_END
)
?
g_ventoy_dev_type_str
[
type
]
:
"unknown"
;
}
static
int
ventoy_check_blk_major
(
int
major
,
const
char
*
type
)
{
int
flag
=
0
;
int
valid
=
0
;
int
devnum
=
0
;
int
len
=
0
;
char
line
[
64
];
char
*
pos
=
NULL
;
FILE
*
fp
=
NULL
;
fp
=
fopen
(
"/proc/devices"
,
"r"
);
if
(
!
fp
)
{
return
0
;
}
len
=
(
int
)
strlen
(
type
);
while
(
fgets
(
line
,
sizeof
(
line
),
fp
))
{
if
(
flag
)
{
pos
=
strchr
(
line
,
' '
);
if
(
pos
)
{
devnum
=
(
int
)
strtol
(
line
,
NULL
,
10
);
if
(
devnum
==
major
)
{
if
(
strncmp
(
pos
+
1
,
type
,
len
)
==
0
)
{
valid
=
1
;
}
break
;
}
}
}
else
if
(
strncmp
(
line
,
"Block devices:"
,
14
)
==
0
)
{
flag
=
1
;
}
}
fclose
(
fp
);
return
valid
;
}
static
int
ventoy_get_disk_devnum
(
const
char
*
name
,
int
*
major
,
int
*
minor
)
{
int
rc
;
char
*
pos
;
char
devnum
[
16
]
=
{
0
};
rc
=
ventoy_get_sys_file_line
(
devnum
,
sizeof
(
devnum
),
"/sys/block/%s/dev"
,
name
);
if
(
rc
)
{
return
1
;
}
pos
=
strstr
(
devnum
,
":"
);
if
(
!
pos
)
{
return
1
;
}
*
major
=
(
int
)
strtol
(
devnum
,
NULL
,
10
);
*
minor
=
(
int
)
strtol
(
pos
+
1
,
NULL
,
10
);
return
0
;
}
static
ventoy_dev_type
ventoy_get_dev_type
(
const
char
*
name
,
int
major
,
int
minor
)
{
int
rc
;
char
syspath
[
128
];
char
dstpath
[
256
];
memset
(
syspath
,
0
,
sizeof
(
syspath
));
memset
(
dstpath
,
0
,
sizeof
(
dstpath
));
scnprintf
(
syspath
,
"/sys/block/%s"
,
name
);
rc
=
readlink
(
syspath
,
dstpath
,
sizeof
(
dstpath
)
-
1
);
if
(
rc
>
0
&&
strstr
(
dstpath
,
"/usb"
))
{
return
VTOY_DEVICE_USB
;
}
if
(
SCSI_BLK_MAJOR
(
major
)
&&
(
minor
%
0x10
==
0
))
{
return
VTOY_DEVICE_SCSI
;
}
else
if
(
IDE_BLK_MAJOR
(
major
)
&&
(
minor
%
0x40
==
0
))
{
return
VTOY_DEVICE_IDE
;
}
else
if
(
major
==
DAC960_MAJOR
&&
(
minor
%
0x8
==
0
))
{
return
VTOY_DEVICE_DAC960
;
}
else
if
(
major
==
ATARAID_MAJOR
&&
(
minor
%
0x10
==
0
))
{
return
VTOY_DEVICE_ATARAID
;
}
else
if
(
major
==
AOE_MAJOR
&&
(
minor
%
0x10
==
0
))
{
return
VTOY_DEVICE_AOE
;
}
else
if
(
major
==
DASD_MAJOR
&&
(
minor
%
0x4
==
0
))
{
return
VTOY_DEVICE_DASD
;
}
else
if
(
major
==
VIODASD_MAJOR
&&
(
minor
%
0x8
==
0
))
{
return
VTOY_DEVICE_VIODASD
;
}
else
if
(
SX8_BLK_MAJOR
(
major
)
&&
(
minor
%
0x20
==
0
))
{
return
VTOY_DEVICE_SX8
;
}
else
if
(
I2O_BLK_MAJOR
(
major
)
&&
(
minor
%
0x10
==
0
))
{
return
VTOY_DEVICE_I2O
;
}
else
if
(
CPQARRAY_BLK_MAJOR
(
major
)
&&
(
minor
%
0x10
==
0
))
{
return
VTOY_DEVICE_CPQARRAY
;
}
else
if
(
UBD_MAJOR
==
major
&&
(
minor
%
0x10
==
0
))
{
return
VTOY_DEVICE_UBD
;
}
else
if
(
XVD_MAJOR
==
major
&&
(
minor
%
0x10
==
0
))
{
return
VTOY_DEVICE_XVD
;
}
else
if
(
SDMMC_MAJOR
==
major
&&
(
minor
%
0x8
==
0
))
{
return
VTOY_DEVICE_SDMMC
;
}
else
if
(
ventoy_check_blk_major
(
major
,
"virtblk"
))
{
return
VTOY_DEVICE_VIRTBLK
;
}
else
if
(
major
==
LOOP_MAJOR
)
{
return
VTOY_DEVICE_LOOP
;
}
else
if
(
major
==
MD_MAJOR
)
{
return
VTOY_DEVICE_MD
;
}
else
if
(
major
==
RAM_MAJOR
)
{
return
VTOY_DEVICE_RAM
;
}
else
if
(
strstr
(
name
,
"nvme"
)
&&
ventoy_check_blk_major
(
major
,
"blkext"
))
{
return
VTOY_DEVICE_NVME
;
}
else
if
(
strstr
(
name
,
"pmem"
)
&&
ventoy_check_blk_major
(
major
,
"blkext"
))
{
return
VTOY_DEVICE_PMEM
;
}
return
VTOY_DEVICE_END
;
}
static
int
ventoy_is_possible_blkdev
(
const
char
*
name
)
{
if
(
name
[
0
]
==
'.'
)
{
return
0
;
}
/* /dev/ramX */
if
(
name
[
0
]
==
'r'
&&
name
[
1
]
==
'a'
&&
name
[
2
]
==
'm'
)
{
return
0
;
}
/* /dev/loopX */
if
(
name
[
0
]
==
'l'
&&
name
[
1
]
==
'o'
&&
name
[
2
]
==
'o'
&&
name
[
3
]
==
'p'
)
{
return
0
;
}
/* /dev/dm-X */
if
(
name
[
0
]
==
'd'
&&
name
[
1
]
==
'm'
&&
name
[
2
]
==
'-'
&&
isdigit
(
name
[
3
]))
{
return
0
;
}
/* /dev/srX */
if
(
name
[
0
]
==
's'
&&
name
[
1
]
==
'r'
&&
isdigit
(
name
[
2
]))
{
return
0
;
}
return
1
;
}
uint64_t
ventoy_get_disk_size_in_byte
(
const
char
*
disk
)
{
int
fd
;
int
rc
;
unsigned
long
long
size
=
0
;
char
diskpath
[
256
]
=
{
0
};
char
sizebuf
[
64
]
=
{
0
};
// Try 1: get size from sysfs
snprintf
(
diskpath
,
sizeof
(
diskpath
)
-
1
,
"/sys/block/%s/size"
,
disk
);
if
(
access
(
diskpath
,
F_OK
)
>=
0
)
{
vdebug
(
"get disk size from sysfs for %s
\n
"
,
disk
);
fd
=
open
(
diskpath
,
O_RDONLY
|
O_BINARY
);
if
(
fd
>=
0
)
{
read
(
fd
,
sizebuf
,
sizeof
(
sizebuf
));
size
=
strtoull
(
sizebuf
,
NULL
,
10
);
close
(
fd
);
return
(
uint64_t
)(
size
*
512
);
}
}
else
{
vdebug
(
"%s not exist
\n
"
,
diskpath
);
}
// Try 2: get size from ioctl
snprintf
(
diskpath
,
sizeof
(
diskpath
)
-
1
,
"/dev/%s"
,
disk
);
fd
=
open
(
diskpath
,
O_RDONLY
);
if
(
fd
>=
0
)
{
vdebug
(
"get disk size from ioctl for %s
\n
"
,
disk
);
rc
=
ioctl
(
fd
,
BLKGETSIZE64
,
&
size
);
if
(
rc
==
-
1
)
{
size
=
0
;
vdebug
(
"failed to ioctl %d
\n
"
,
rc
);
}
close
(
fd
);
}
else
{
vdebug
(
"failed to open %s %d
\n
"
,
diskpath
,
errno
);
}
vdebug
(
"disk %s size %llu bytes
\n
"
,
disk
,
size
);
return
size
;
}
int
ventoy_get_disk_vendor
(
const
char
*
name
,
char
*
vendorbuf
,
int
bufsize
)
{
return
ventoy_get_sys_file_line
(
vendorbuf
,
bufsize
,
"/sys/block/%s/device/vendor"
,
name
);
}
int
ventoy_get_disk_model
(
const
char
*
name
,
char
*
modelbuf
,
int
bufsize
)
{
return
ventoy_get_sys_file_line
(
modelbuf
,
bufsize
,
"/sys/block/%s/device/model"
,
name
);
}
static
int
fatlib_media_sector_read
(
uint32
sector
,
uint8
*
buffer
,
uint32
sector_count
)
{
lseek
(
g_fatlib_media_fd
,
(
sector
+
g_fatlib_media_offset
)
*
512ULL
,
SEEK_SET
);
read
(
g_fatlib_media_fd
,
buffer
,
sector_count
*
512
);
return
1
;
}
static
int
fatlib_is_secure_boot_enable
(
void
)
{
void
*
flfile
=
NULL
;
flfile
=
fl_fopen
(
"/EFI/BOOT/grubx64_real.efi"
,
"rb"
);
if
(
flfile
)
{
fl_fclose
(
flfile
);
return
1
;
}
else
{
vlog
(
"/EFI/BOOT/grubx64_real.efi not exist
\n
"
);
}
return
0
;
}
static
int
fatlib_get_ventoy_version
(
char
*
verbuf
,
int
bufsize
)
{
int
rc
=
1
;
int
size
=
0
;
char
*
buf
=
NULL
;
char
*
pos
=
NULL
;
char
*
end
=
NULL
;
void
*
flfile
=
NULL
;
flfile
=
fl_fopen
(
"/grub/grub.cfg"
,
"rb"
);
if
(
flfile
)
{
fl_fseek
(
flfile
,
0
,
SEEK_END
);
size
=
(
int
)
fl_ftell
(
flfile
);
fl_fseek
(
flfile
,
0
,
SEEK_SET
);
buf
=
malloc
(
size
+
1
);
if
(
buf
)
{
fl_fread
(
buf
,
1
,
size
,
flfile
);
buf
[
size
]
=
0
;
pos
=
strstr
(
buf
,
"VENTOY_VERSION="
);
if
(
pos
)
{
pos
+=
strlen
(
"VENTOY_VERSION="
);
if
(
*
pos
==
'"'
)
{
pos
++
;
}
end
=
pos
;
while
(
*
end
!=
0
&&
*
end
!=
'"'
&&
*
end
!=
'\r'
&&
*
end
!=
'\n'
)
{
end
++
;
}
*
end
=
0
;
snprintf
(
verbuf
,
bufsize
-
1
,
"%s"
,
pos
);
rc
=
0
;
}
free
(
buf
);
}
fl_fclose
(
flfile
);
}
else
{
vdebug
(
"No grub.cfg found
\n
"
);
}
return
rc
;
}
int
ventoy_get_vtoy_data
(
ventoy_disk
*
info
,
int
*
ppartstyle
)
{
int
i
;
int
fd
;
int
len
;
int
rc
=
1
;
int
ret
=
1
;
int
part_style
;
uint64_t
part1_start_sector
;
uint64_t
part1_sector_count
;
uint64_t
part2_start_sector
;
uint64_t
part2_sector_count
;
uint64_t
preserved_space
;
char
name
[
64
]
=
{
0
};
disk_ventoy_data
*
vtoy
=
NULL
;
VTOY_GPT_INFO
*
gpt
=
NULL
;
vtoy
=
&
(
info
->
vtoydata
);
gpt
=
&
(
vtoy
->
gptinfo
);
memset
(
vtoy
,
0
,
sizeof
(
disk_ventoy_data
));
vdebug
(
"ventoy_get_vtoy_data %s
\n
"
,
info
->
disk_path
);
if
(
info
->
size_in_byte
<
(
2
*
VTOYEFI_PART_BYTES
))
{
vdebug
(
"disk %s is too small %llu
\n
"
,
info
->
disk_path
,
(
_ull
)
info
->
size_in_byte
);
return
1
;
}
fd
=
open
(
info
->
disk_path
,
O_RDONLY
|
O_BINARY
);
if
(
fd
<
0
)
{
vdebug
(
"failed to open %s %d
\n
"
,
info
->
disk_path
,
errno
);
return
1
;
}
len
=
(
int
)
read
(
fd
,
&
(
vtoy
->
gptinfo
),
sizeof
(
VTOY_GPT_INFO
));
if
(
len
!=
sizeof
(
VTOY_GPT_INFO
))
{
vdebug
(
"failed to read %s %d
\n
"
,
info
->
disk_path
,
errno
);
goto
end
;
}
if
(
gpt
->
MBR
.
Byte55
!=
0x55
||
gpt
->
MBR
.
ByteAA
!=
0xAA
)
{
vdebug
(
"Invalid mbr magic 0x%x 0x%x
\n
"
,
gpt
->
MBR
.
Byte55
,
gpt
->
MBR
.
ByteAA
);
goto
end
;
}
if
(
gpt
->
MBR
.
PartTbl
[
0
].
FsFlag
==
0xEE
&&
strncmp
(
gpt
->
Head
.
Signature
,
"EFI PART"
,
8
)
==
0
)
{
part_style
=
GPT_PART_STYLE
;
if
(
ppartstyle
)
{
*
ppartstyle
=
part_style
;
}
if
(
gpt
->
PartTbl
[
0
].
StartLBA
==
0
||
gpt
->
PartTbl
[
1
].
StartLBA
==
0
)
{
vdebug
(
"NO ventoy efi part layout <%llu %llu>
\n
"
,
(
_ull
)
gpt
->
PartTbl
[
0
].
StartLBA
,
(
_ull
)
gpt
->
PartTbl
[
1
].
StartLBA
);
goto
end
;
}
for
(
i
=
0
;
i
<
36
;
i
++
)
{
name
[
i
]
=
(
char
)(
gpt
->
PartTbl
[
1
].
Name
[
i
]);
}
if
(
strcmp
(
name
,
"VTOYEFI"
))
{
vdebug
(
"Invalid efi part2 name <%s>
\n
"
,
name
);
goto
end
;
}
part1_start_sector
=
gpt
->
PartTbl
[
0
].
StartLBA
;
part1_sector_count
=
gpt
->
PartTbl
[
0
].
LastLBA
-
part1_start_sector
+
1
;
part2_start_sector
=
gpt
->
PartTbl
[
1
].
StartLBA
;
part2_sector_count
=
gpt
->
PartTbl
[
1
].
LastLBA
-
part2_start_sector
+
1
;
preserved_space
=
info
->
size_in_byte
-
(
part2_start_sector
+
part2_sector_count
+
33
)
*
512
;
}
else
{
part_style
=
MBR_PART_STYLE
;
if
(
ppartstyle
)
{
*
ppartstyle
=
part_style
;
}
part1_start_sector
=
gpt
->
MBR
.
PartTbl
[
0
].
StartSectorId
;
part1_sector_count
=
gpt
->
MBR
.
PartTbl
[
0
].
SectorCount
;
part2_start_sector
=
gpt
->
MBR
.
PartTbl
[
1
].
StartSectorId
;
part2_sector_count
=
gpt
->
MBR
.
PartTbl
[
1
].
SectorCount
;
preserved_space
=
info
->
size_in_byte
-
(
part2_start_sector
+
part2_sector_count
)
*
512
;
}
if
(
part1_start_sector
!=
VTOYIMG_PART_START_SECTOR
||
part2_sector_count
!=
VTOYEFI_PART_SECTORS
||
(
part1_start_sector
+
part1_sector_count
)
!=
part2_start_sector
)
{
vdebug
(
"Not valid ventoy partition layout [%llu %llu] [%llu %llu]
\n
"
,
part1_start_sector
,
part1_sector_count
,
part2_start_sector
,
part2_sector_count
);
goto
end
;
}
vdebug
(
"now check secure boot ...
\n
"
);
g_fatlib_media_fd
=
fd
;
g_fatlib_media_offset
=
part2_start_sector
;
fl_init
();
if
(
0
==
fl_attach_media
(
fatlib_media_sector_read
,
NULL
))
{
ret
=
fatlib_get_ventoy_version
(
vtoy
->
ventoy_ver
,
sizeof
(
vtoy
->
ventoy_ver
));
if
(
ret
==
0
&&
vtoy
->
ventoy_ver
[
0
])
{
vtoy
->
secure_boot_flag
=
fatlib_is_secure_boot_enable
();
vtoy
->
ventoy_valid
=
1
;
}
else
{
vdebug
(
"fatlib_get_ventoy_version failed %d
\n
"
,
ret
);
}
}
else
{
vdebug
(
"fl_attach_media failed
\n
"
);
}
fl_shutdown
();
g_fatlib_media_fd
=
-
1
;
g_fatlib_media_offset
=
0
;
if
(
0
==
vtoy
->
ventoy_valid
)
{
goto
end
;
}
lseek
(
fd
,
2040
*
512
,
SEEK_SET
);
read
(
fd
,
vtoy
->
rsvdata
,
sizeof
(
vtoy
->
rsvdata
));
vtoy
->
preserved_space
=
preserved_space
;
vtoy
->
partition_style
=
part_style
;
vtoy
->
part2_start_sector
=
part2_start_sector
;
rc
=
0
;
end:
close
(
fd
);
return
rc
;
}
int
ventoy_get_disk_info
(
const
char
*
name
,
ventoy_disk
*
info
)
{
char
vendor
[
64
]
=
{
0
};
char
model
[
128
]
=
{
0
};
vdebug
(
"get disk info %s
\n
"
,
name
);
strlcpy
(
info
->
disk_name
,
name
);
scnprintf
(
info
->
disk_path
,
"/dev/%s"
,
name
);
if
(
strstr
(
name
,
"nvme"
)
||
strstr
(
name
,
"mmc"
)
||
strstr
(
name
,
"nbd"
))
{
scnprintf
(
info
->
part1_name
,
"%sp1"
,
name
);
scnprintf
(
info
->
part1_path
,
"/dev/%sp1"
,
name
);
scnprintf
(
info
->
part2_name
,
"%sp2"
,
name
);
scnprintf
(
info
->
part2_path
,
"/dev/%sp2"
,
name
);
}
else
{
scnprintf
(
info
->
part1_name
,
"%s1"
,
name
);
scnprintf
(
info
->
part1_path
,
"/dev/%s1"
,
name
);
scnprintf
(
info
->
part2_name
,
"%s2"
,
name
);
scnprintf
(
info
->
part2_path
,
"/dev/%s2"
,
name
);
}
info
->
size_in_byte
=
ventoy_get_disk_size_in_byte
(
name
);
ventoy_get_disk_devnum
(
name
,
&
info
->
major
,
&
info
->
minor
);
info
->
type
=
ventoy_get_dev_type
(
name
,
info
->
major
,
info
->
minor
);
ventoy_get_disk_vendor
(
name
,
vendor
,
sizeof
(
vendor
));
ventoy_get_disk_model
(
name
,
model
,
sizeof
(
model
));
scnprintf
(
info
->
human_readable_size
,
"%llu GB"
,
(
_ull
)
ventoy_get_human_readable_gb
(
info
->
size_in_byte
));
scnprintf
(
info
->
disk_model
,
"%s %s (%s)"
,
vendor
,
model
,
ventoy_get_dev_type_name
(
info
->
type
));
ventoy_get_vtoy_data
(
info
,
&
(
info
->
partstyle
));
vdebug
(
"disk:<%s %d:%d> model:<%s> size:%llu (%s)
\n
"
,
info
->
disk_path
,
info
->
major
,
info
->
minor
,
info
->
disk_model
,
info
->
size_in_byte
,
info
->
human_readable_size
);
if
(
info
->
vtoydata
.
ventoy_valid
)
{
vdebug
(
"%s Ventoy:<%s> %s secureboot:%d preserve:%llu
\n
"
,
info
->
disk_path
,
info
->
vtoydata
.
ventoy_ver
,
info
->
vtoydata
.
partition_style
==
MBR_PART_STYLE
?
"MBR"
:
"GPT"
,
info
->
vtoydata
.
secure_boot_flag
,
(
_ull
)(
info
->
vtoydata
.
preserved_space
));
}
else
{
vdebug
(
"%s NO Ventoy detected
\n
"
,
info
->
disk_path
);
}
return
0
;
}
static
int
ventoy_disk_compare
(
const
ventoy_disk
*
disk1
,
const
ventoy_disk
*
disk2
)
{
if
(
disk1
->
type
==
VTOY_DEVICE_USB
&&
disk2
->
type
==
VTOY_DEVICE_USB
)
{
return
strcmp
(
disk1
->
disk_name
,
disk2
->
disk_name
);
}
else
if
(
disk1
->
type
==
VTOY_DEVICE_USB
)
{
return
-
1
;
}
else
if
(
disk2
->
type
==
VTOY_DEVICE_USB
)
{
return
1
;
}
else
{
return
strcmp
(
disk1
->
disk_name
,
disk2
->
disk_name
);
}
}
static
int
ventoy_disk_sort
(
void
)
{
int
i
,
j
;
ventoy_disk
*
tmp
;
tmp
=
malloc
(
sizeof
(
ventoy_disk
));
if
(
!
tmp
)
{
return
1
;
}
for
(
i
=
0
;
i
<
g_disk_num
;
i
++
)
for
(
j
=
i
+
1
;
j
<
g_disk_num
;
j
++
)
{
if
(
ventoy_disk_compare
(
g_disk_list
+
i
,
g_disk_list
+
j
)
>
0
)
{
memcpy
(
tmp
,
g_disk_list
+
i
,
sizeof
(
ventoy_disk
));
memcpy
(
g_disk_list
+
i
,
g_disk_list
+
j
,
sizeof
(
ventoy_disk
));
memcpy
(
g_disk_list
+
j
,
tmp
,
sizeof
(
ventoy_disk
));
}
}
free
(
tmp
);
return
0
;
}
int
ventoy_disk_enumerate_all
(
void
)
{
int
rc
=
0
;
DIR
*
dir
=
NULL
;
struct
dirent
*
p
=
NULL
;
vdebug
(
"ventoy_disk_enumerate_all
\n
"
);
dir
=
opendir
(
"/sys/block"
);
if
(
!
dir
)
{
vlog
(
"Failed to open /sys/block %d
\n
"
,
errno
);
return
1
;
}
while
(((
p
=
readdir
(
dir
))
!=
NULL
)
&&
(
g_disk_num
<
MAX_DISK_NUM
))
{
if
(
ventoy_is_possible_blkdev
(
p
->
d_name
))
{
memset
(
g_disk_list
+
g_disk_num
,
0
,
sizeof
(
ventoy_disk
));
if
(
0
==
ventoy_get_disk_info
(
p
->
d_name
,
g_disk_list
+
g_disk_num
))
{
g_disk_num
++
;
}
}
}
closedir
(
dir
);
ventoy_disk_sort
();
return
rc
;
}
void
ventoy_disk_dump
(
ventoy_disk
*
cur
)
{
if
(
cur
->
vtoydata
.
ventoy_valid
)
{
vdebug
(
"%s [%s] %s
\t
Ventoy: %s %s secureboot:%d preserve:%llu
\n
"
,
cur
->
disk_path
,
cur
->
human_readable_size
,
cur
->
disk_model
,
cur
->
vtoydata
.
ventoy_ver
,
cur
->
vtoydata
.
partition_style
==
MBR_PART_STYLE
?
"MBR"
:
"GPT"
,
cur
->
vtoydata
.
secure_boot_flag
,
(
_ull
)(
cur
->
vtoydata
.
preserved_space
));
}
else
{
vdebug
(
"%s [%s] %s
\t
Ventoy: NA
\n
"
,
cur
->
disk_path
,
cur
->
human_readable_size
,
cur
->
disk_model
);
}
}
void
ventoy_disk_dump_all
(
void
)
{
int
i
;
vdebug
(
"============= DISK DUMP ============
\n
"
);
for
(
i
=
0
;
i
<
g_disk_num
;
i
++
)
{
ventoy_disk_dump
(
g_disk_list
+
i
);
}
}
int
ventoy_disk_install
(
ventoy_disk
*
disk
,
void
*
efipartimg
)
{
return
0
;
}
int
ventoy_disk_init
(
void
)
{
g_disk_list
=
malloc
(
sizeof
(
ventoy_disk
)
*
MAX_DISK_NUM
);
ventoy_disk_enumerate_all
();
ventoy_disk_dump_all
();
return
0
;
}
void
ventoy_disk_exit
(
void
)
{
check_free
(
g_disk_list
);
g_disk_list
=
NULL
;
g_disk_num
=
0
;
}
LinuxGUI/Ventoy2Disk/Core/ventoy_disk.h
0 → 100644
View file @
43e8ec57
/******************************************************************************
* ventoy_disk.h
*
* Copyright (c) 2021, longpanda <admin@ventoy.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __VENTOY_DISK_H__
#define __VENTOY_DISK_H__
typedef
enum
{
VTOY_DEVICE_UNKNOWN
=
0
,
VTOY_DEVICE_SCSI
,
VTOY_DEVICE_USB
,
VTOY_DEVICE_IDE
,
VTOY_DEVICE_DAC960
,
VTOY_DEVICE_CPQARRAY
,
VTOY_DEVICE_FILE
,
VTOY_DEVICE_ATARAID
,
VTOY_DEVICE_I2O
,
VTOY_DEVICE_UBD
,
VTOY_DEVICE_DASD
,
VTOY_DEVICE_VIODASD
,
VTOY_DEVICE_SX8
,
VTOY_DEVICE_DM
,
VTOY_DEVICE_XVD
,
VTOY_DEVICE_SDMMC
,
VTOY_DEVICE_VIRTBLK
,
VTOY_DEVICE_AOE
,
VTOY_DEVICE_MD
,
VTOY_DEVICE_LOOP
,
VTOY_DEVICE_NVME
,
VTOY_DEVICE_RAM
,
VTOY_DEVICE_PMEM
,
VTOY_DEVICE_END
}
ventoy_dev_type
;
/* from <linux/major.h> */
#define IDE0_MAJOR 3
#define IDE1_MAJOR 22
#define IDE2_MAJOR 33
#define IDE3_MAJOR 34
#define IDE4_MAJOR 56
#define IDE5_MAJOR 57
#define SCSI_CDROM_MAJOR 11
#define SCSI_DISK0_MAJOR 8
#define SCSI_DISK1_MAJOR 65
#define SCSI_DISK2_MAJOR 66
#define SCSI_DISK3_MAJOR 67
#define SCSI_DISK4_MAJOR 68
#define SCSI_DISK5_MAJOR 69
#define SCSI_DISK6_MAJOR 70
#define SCSI_DISK7_MAJOR 71
#define SCSI_DISK8_MAJOR 128
#define SCSI_DISK9_MAJOR 129
#define SCSI_DISK10_MAJOR 130
#define SCSI_DISK11_MAJOR 131
#define SCSI_DISK12_MAJOR 132
#define SCSI_DISK13_MAJOR 133
#define SCSI_DISK14_MAJOR 134
#define SCSI_DISK15_MAJOR 135
#define COMPAQ_SMART2_MAJOR 72
#define COMPAQ_SMART2_MAJOR1 73
#define COMPAQ_SMART2_MAJOR2 74
#define COMPAQ_SMART2_MAJOR3 75
#define COMPAQ_SMART2_MAJOR4 76
#define COMPAQ_SMART2_MAJOR5 77
#define COMPAQ_SMART2_MAJOR6 78
#define COMPAQ_SMART2_MAJOR7 79
#define COMPAQ_SMART_MAJOR 104
#define COMPAQ_SMART_MAJOR1 105
#define COMPAQ_SMART_MAJOR2 106
#define COMPAQ_SMART_MAJOR3 107
#define COMPAQ_SMART_MAJOR4 108
#define COMPAQ_SMART_MAJOR5 109
#define COMPAQ_SMART_MAJOR6 110
#define COMPAQ_SMART_MAJOR7 111
#define DAC960_MAJOR 48
#define ATARAID_MAJOR 114
#define I2O_MAJOR1 80
#define I2O_MAJOR2 81
#define I2O_MAJOR3 82
#define I2O_MAJOR4 83
#define I2O_MAJOR5 84
#define I2O_MAJOR6 85
#define I2O_MAJOR7 86
#define I2O_MAJOR8 87
#define UBD_MAJOR 98
#define DASD_MAJOR 94
#define VIODASD_MAJOR 112
#define AOE_MAJOR 152
#define SX8_MAJOR1 160
#define SX8_MAJOR2 161
#define XVD_MAJOR 202
#define SDMMC_MAJOR 179
#define LOOP_MAJOR 7
#define MD_MAJOR 9
#define BLKEXT_MAJOR 259
#define RAM_MAJOR 1
#define SCSI_BLK_MAJOR(M) ( \
(M) == SCSI_DISK0_MAJOR \
|| (M) == SCSI_CDROM_MAJOR \
|| ((M) >= SCSI_DISK1_MAJOR && (M) <= SCSI_DISK7_MAJOR) \
|| ((M) >= SCSI_DISK8_MAJOR && (M) <= SCSI_DISK15_MAJOR))
#define IDE_BLK_MAJOR(M) \
((M) == IDE0_MAJOR || \
(M) == IDE1_MAJOR || \
(M) == IDE2_MAJOR || \
(M) == IDE3_MAJOR || \
(M) == IDE4_MAJOR || \
(M) == IDE5_MAJOR)
#define SX8_BLK_MAJOR(M) ((M) >= SX8_MAJOR1 && (M) <= SX8_MAJOR2)
#define I2O_BLK_MAJOR(M) ((M) >= I2O_MAJOR1 && (M) <= I2O_MAJOR8)
#define CPQARRAY_BLK_MAJOR(M) \
(((M) >= COMPAQ_SMART2_MAJOR && (M) <= COMPAQ_SMART2_MAJOR7) || \
(COMPAQ_SMART_MAJOR <= (M) && (M) <= COMPAQ_SMART_MAJOR7))
#define VENTOY_FILE_STG1_IMG "boot/core.img.xz"
#define VENTOY_FILE_DISK_IMG "ventoy/ventoy.disk.img.xz"
extern
int
g_disk_num
;
extern
ventoy_disk
*
g_disk_list
;
int
ventoy_disk_enumerate_all
(
void
);
int
ventoy_disk_init
(
void
);
void
ventoy_disk_exit
(
void
);
#endif
/* __VENTOY_DISK_H__ */
LinuxGUI/Ventoy2Disk/Core/ventoy_json.c
0 → 100644
View file @
43e8ec57
/******************************************************************************
* ventoy_json.c
*
* Copyright (c) 2021, longpanda <admin@ventoy.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <ventoy_define.h>
#include <ventoy_util.h>
#include <ventoy_json.h>
static
void
vtoy_json_free
(
VTOY_JSON
*
pstJsonHead
)
{
VTOY_JSON
*
pstNext
=
NULL
;
while
(
NULL
!=
pstJsonHead
)
{
pstNext
=
pstJsonHead
->
pstNext
;
if
((
pstJsonHead
->
enDataType
<
JSON_TYPE_BUTT
)
&&
(
NULL
!=
pstJsonHead
->
pstChild
))
{
vtoy_json_free
(
pstJsonHead
->
pstChild
);
}
free
(
pstJsonHead
);
pstJsonHead
=
pstNext
;
}
return
;
}
static
char
*
vtoy_json_skip
(
const
char
*
pcData
)
{
while
((
NULL
!=
pcData
)
&&
(
'\0'
!=
*
pcData
)
&&
(
*
pcData
<=
32
))
{
pcData
++
;
}
return
(
char
*
)
pcData
;
}
VTOY_JSON
*
vtoy_json_find_item
(
VTOY_JSON
*
pstJson
,
JSON_TYPE
enDataType
,
const
char
*
szKey
)
{
while
(
NULL
!=
pstJson
)
{
if
((
enDataType
==
pstJson
->
enDataType
)
&&
(
0
==
strcmp
(
szKey
,
pstJson
->
pcName
)))
{
return
pstJson
;
}
pstJson
=
pstJson
->
pstNext
;
}
return
NULL
;
}
static
int
vtoy_json_parse_number
(
VTOY_JSON
*
pstJson
,
const
char
*
pcData
,
const
char
**
ppcEnd
)
{
unsigned
long
Value
;
Value
=
strtoul
(
pcData
,
(
char
**
)
ppcEnd
,
10
);
if
(
*
ppcEnd
==
pcData
)
{
vdebug
(
"Failed to parse json number %s.
\n
"
,
pcData
);
return
JSON_FAILED
;
}
pstJson
->
enDataType
=
JSON_TYPE_NUMBER
;
pstJson
->
unData
.
lValue
=
Value
;
return
JSON_SUCCESS
;
}
static
int
vtoy_json_parse_string
(
char
*
pcNewStart
,
char
*
pcRawStart
,
VTOY_JSON
*
pstJson
,
const
char
*
pcData
,
const
char
**
ppcEnd
)
{
uint32_t
uiLen
=
0
;
const
char
*
pcPos
=
NULL
;
const
char
*
pcTmp
=
pcData
+
1
;
*
ppcEnd
=
pcData
;
if
(
'\"'
!=
*
pcData
)
{
return
JSON_FAILED
;
}
pcPos
=
strchr
(
pcTmp
,
'\"'
);
if
((
NULL
==
pcPos
)
||
(
pcPos
<
pcTmp
))
{
vdebug
(
"Invalid string %s.
\n
"
,
pcData
);
return
JSON_FAILED
;
}
*
ppcEnd
=
pcPos
+
1
;
uiLen
=
(
uint32_t
)(
unsigned
long
)(
pcPos
-
pcTmp
);
pstJson
->
enDataType
=
JSON_TYPE_STRING
;
pstJson
->
unData
.
pcStrVal
=
pcNewStart
+
(
pcTmp
-
pcRawStart
);
pstJson
->
unData
.
pcStrVal
[
uiLen
]
=
'\0'
;
return
JSON_SUCCESS
;
}
static
int
vtoy_json_parse_array
(
char
*
pcNewStart
,
char
*
pcRawStart
,
VTOY_JSON
*
pstJson
,
const
char
*
pcData
,
const
char
**
ppcEnd
)
{
int
Ret
=
JSON_SUCCESS
;
VTOY_JSON
*
pstJsonChild
=
NULL
;
VTOY_JSON
*
pstJsonItem
=
NULL
;
const
char
*
pcTmp
=
pcData
+
1
;
*
ppcEnd
=
pcData
;
pstJson
->
enDataType
=
JSON_TYPE_ARRAY
;
if
(
'['
!=
*
pcData
)
{
return
JSON_FAILED
;
}
pcTmp
=
vtoy_json_skip
(
pcTmp
);
if
(
']'
==
*
pcTmp
)
{
*
ppcEnd
=
pcTmp
+
1
;
return
JSON_SUCCESS
;
}
JSON_NEW_ITEM
(
pstJson
->
pstChild
,
JSON_FAILED
);
Ret
=
vtoy_json_parse_value
(
pcNewStart
,
pcRawStart
,
pstJson
->
pstChild
,
pcTmp
,
ppcEnd
);
if
(
JSON_SUCCESS
!=
Ret
)
{
vdebug
(
"Failed to parse array child.
\n
"
);
return
JSON_FAILED
;
}
pstJsonChild
=
pstJson
->
pstChild
;
pcTmp
=
vtoy_json_skip
(
*
ppcEnd
);
while
((
NULL
!=
pcTmp
)
&&
(
','
==
*
pcTmp
))
{
JSON_NEW_ITEM
(
pstJsonItem
,
JSON_FAILED
);
pstJsonChild
->
pstNext
=
pstJsonItem
;
pstJsonItem
->
pstPrev
=
pstJsonChild
;
pstJsonChild
=
pstJsonItem
;
Ret
=
vtoy_json_parse_value
(
pcNewStart
,
pcRawStart
,
pstJsonChild
,
vtoy_json_skip
(
pcTmp
+
1
),
ppcEnd
);
if
(
JSON_SUCCESS
!=
Ret
)
{
vdebug
(
"Failed to parse array child.
\n
"
);
return
JSON_FAILED
;
}
pcTmp
=
vtoy_json_skip
(
*
ppcEnd
);
}
if
((
NULL
!=
pcTmp
)
&&
(
']'
==
*
pcTmp
))
{
*
ppcEnd
=
pcTmp
+
1
;
return
JSON_SUCCESS
;
}
else
{
*
ppcEnd
=
pcTmp
;
return
JSON_FAILED
;
}
}
static
int
vtoy_json_parse_object
(
char
*
pcNewStart
,
char
*
pcRawStart
,
VTOY_JSON
*
pstJson
,
const
char
*
pcData
,
const
char
**
ppcEnd
)
{
int
Ret
=
JSON_SUCCESS
;
VTOY_JSON
*
pstJsonChild
=
NULL
;
VTOY_JSON
*
pstJsonItem
=
NULL
;
const
char
*
pcTmp
=
pcData
+
1
;
*
ppcEnd
=
pcData
;
pstJson
->
enDataType
=
JSON_TYPE_OBJECT
;
if
(
'{'
!=
*
pcData
)
{
return
JSON_FAILED
;
}
pcTmp
=
vtoy_json_skip
(
pcTmp
);
if
(
'}'
==
*
pcTmp
)
{
*
ppcEnd
=
pcTmp
+
1
;
return
JSON_SUCCESS
;
}
JSON_NEW_ITEM
(
pstJson
->
pstChild
,
JSON_FAILED
);
Ret
=
vtoy_json_parse_string
(
pcNewStart
,
pcRawStart
,
pstJson
->
pstChild
,
pcTmp
,
ppcEnd
);
if
(
JSON_SUCCESS
!=
Ret
)
{
vdebug
(
"Failed to parse array child.
\n
"
);
return
JSON_FAILED
;
}
pstJsonChild
=
pstJson
->
pstChild
;
pstJsonChild
->
pcName
=
pstJsonChild
->
unData
.
pcStrVal
;
pstJsonChild
->
unData
.
pcStrVal
=
NULL
;
pcTmp
=
vtoy_json_skip
(
*
ppcEnd
);
if
((
NULL
==
pcTmp
)
||
(
':'
!=
*
pcTmp
))
{
*
ppcEnd
=
pcTmp
;
return
JSON_FAILED
;
}
Ret
=
vtoy_json_parse_value
(
pcNewStart
,
pcRawStart
,
pstJsonChild
,
vtoy_json_skip
(
pcTmp
+
1
),
ppcEnd
);
if
(
JSON_SUCCESS
!=
Ret
)
{
vdebug
(
"Failed to parse array child.
\n
"
);
return
JSON_FAILED
;
}
pcTmp
=
vtoy_json_skip
(
*
ppcEnd
);
while
((
NULL
!=
pcTmp
)
&&
(
','
==
*
pcTmp
))
{
JSON_NEW_ITEM
(
pstJsonItem
,
JSON_FAILED
);
pstJsonChild
->
pstNext
=
pstJsonItem
;
pstJsonItem
->
pstPrev
=
pstJsonChild
;
pstJsonChild
=
pstJsonItem
;
Ret
=
vtoy_json_parse_string
(
pcNewStart
,
pcRawStart
,
pstJsonChild
,
vtoy_json_skip
(
pcTmp
+
1
),
ppcEnd
);
if
(
JSON_SUCCESS
!=
Ret
)
{
vdebug
(
"Failed to parse array child.
\n
"
);
return
JSON_FAILED
;
}
pcTmp
=
vtoy_json_skip
(
*
ppcEnd
);
pstJsonChild
->
pcName
=
pstJsonChild
->
unData
.
pcStrVal
;
pstJsonChild
->
unData
.
pcStrVal
=
NULL
;
if
((
NULL
==
pcTmp
)
||
(
':'
!=
*
pcTmp
))
{
*
ppcEnd
=
pcTmp
;
return
JSON_FAILED
;
}
Ret
=
vtoy_json_parse_value
(
pcNewStart
,
pcRawStart
,
pstJsonChild
,
vtoy_json_skip
(
pcTmp
+
1
),
ppcEnd
);
if
(
JSON_SUCCESS
!=
Ret
)
{
vdebug
(
"Failed to parse array child.
\n
"
);
return
JSON_FAILED
;
}
pcTmp
=
vtoy_json_skip
(
*
ppcEnd
);
}
if
((
NULL
!=
pcTmp
)
&&
(
'}'
==
*
pcTmp
))
{
*
ppcEnd
=
pcTmp
+
1
;
return
JSON_SUCCESS
;
}
else
{
*
ppcEnd
=
pcTmp
;
return
JSON_FAILED
;
}
}
int
vtoy_json_parse_value
(
char
*
pcNewStart
,
char
*
pcRawStart
,
VTOY_JSON
*
pstJson
,
const
char
*
pcData
,
const
char
**
ppcEnd
)
{
pcData
=
vtoy_json_skip
(
pcData
);
switch
(
*
pcData
)
{
case
'n'
:
{
if
(
0
==
strncmp
(
pcData
,
"null"
,
4
))
{
pstJson
->
enDataType
=
JSON_TYPE_NULL
;
*
ppcEnd
=
pcData
+
4
;
return
JSON_SUCCESS
;
}
break
;
}
case
'f'
:
{
if
(
0
==
strncmp
(
pcData
,
"false"
,
5
))
{
pstJson
->
enDataType
=
JSON_TYPE_BOOL
;
pstJson
->
unData
.
lValue
=
0
;
*
ppcEnd
=
pcData
+
5
;
return
JSON_SUCCESS
;
}
break
;
}
case
't'
:
{
if
(
0
==
strncmp
(
pcData
,
"true"
,
4
))
{
pstJson
->
enDataType
=
JSON_TYPE_BOOL
;
pstJson
->
unData
.
lValue
=
1
;
*
ppcEnd
=
pcData
+
4
;
return
JSON_SUCCESS
;
}
break
;
}
case
'\"'
:
{
return
vtoy_json_parse_string
(
pcNewStart
,
pcRawStart
,
pstJson
,
pcData
,
ppcEnd
);
}
case
'['
:
{
return
vtoy_json_parse_array
(
pcNewStart
,
pcRawStart
,
pstJson
,
pcData
,
ppcEnd
);
}
case
'{'
:
{
return
vtoy_json_parse_object
(
pcNewStart
,
pcRawStart
,
pstJson
,
pcData
,
ppcEnd
);
}
case
'-'
:
{
return
vtoy_json_parse_number
(
pstJson
,
pcData
,
ppcEnd
);
}
default
:
{
if
(
*
pcData
>=
'0'
&&
*
pcData
<=
'9'
)
{
return
vtoy_json_parse_number
(
pstJson
,
pcData
,
ppcEnd
);
}
}
}
*
ppcEnd
=
pcData
;
vdebug
(
"Invalid json data %u.
\n
"
,
(
uint8_t
)(
*
pcData
));
return
JSON_FAILED
;
}
VTOY_JSON
*
vtoy_json_create
(
void
)
{
VTOY_JSON
*
pstJson
=
NULL
;
pstJson
=
(
VTOY_JSON
*
)
zalloc
(
sizeof
(
VTOY_JSON
));
if
(
NULL
==
pstJson
)
{
return
NULL
;
}
return
pstJson
;
}
int
vtoy_json_parse
(
VTOY_JSON
*
pstJson
,
const
char
*
szJsonData
)
{
uint32_t
uiMemSize
=
0
;
int
Ret
=
JSON_SUCCESS
;
char
*
pcNewBuf
=
NULL
;
const
char
*
pcEnd
=
NULL
;
uiMemSize
=
strlen
(
szJsonData
)
+
1
;
pcNewBuf
=
(
char
*
)
malloc
(
uiMemSize
);
if
(
NULL
==
pcNewBuf
)
{
vdebug
(
"Failed to alloc new buf.
\n
"
);
return
JSON_FAILED
;
}
memcpy
(
pcNewBuf
,
szJsonData
,
uiMemSize
);
pcNewBuf
[
uiMemSize
-
1
]
=
0
;
Ret
=
vtoy_json_parse_value
(
pcNewBuf
,
(
char
*
)
szJsonData
,
pstJson
,
szJsonData
,
&
pcEnd
);
if
(
JSON_SUCCESS
!=
Ret
)
{
vdebug
(
"Failed to parse json data %s start=%p, end=%p:%s.
\n
"
,
szJsonData
,
szJsonData
,
pcEnd
,
pcEnd
);
return
JSON_FAILED
;
}
return
JSON_SUCCESS
;
}
int
vtoy_json_scan_parse
(
const
VTOY_JSON
*
pstJson
,
uint32_t
uiParseNum
,
VTOY_JSON_PARSE_S
*
pstJsonParse
)
{
uint32_t
i
=
0
;
const
VTOY_JSON
*
pstJsonCur
=
NULL
;
VTOY_JSON_PARSE_S
*
pstCurParse
=
NULL
;
for
(
pstJsonCur
=
pstJson
;
NULL
!=
pstJsonCur
;
pstJsonCur
=
pstJsonCur
->
pstNext
)
{
if
((
JSON_TYPE_OBJECT
==
pstJsonCur
->
enDataType
)
||
(
JSON_TYPE_ARRAY
==
pstJsonCur
->
enDataType
))
{
continue
;
}
for
(
i
=
0
,
pstCurParse
=
NULL
;
i
<
uiParseNum
;
i
++
)
{
if
(
0
==
strcmp
(
pstJsonParse
[
i
].
pcKey
,
pstJsonCur
->
pcName
))
{
pstCurParse
=
pstJsonParse
+
i
;
break
;
}
}
if
(
NULL
==
pstCurParse
)
{
continue
;
}
switch
(
pstJsonCur
->
enDataType
)
{
case
JSON_TYPE_NUMBER
:
{
if
(
sizeof
(
uint32_t
)
==
pstCurParse
->
uiBufSize
)
{
*
(
uint32_t
*
)(
pstCurParse
->
pDataBuf
)
=
(
uint32_t
)
pstJsonCur
->
unData
.
lValue
;
}
else
if
(
sizeof
(
uint16_t
)
==
pstCurParse
->
uiBufSize
)
{
*
(
uint16_t
*
)(
pstCurParse
->
pDataBuf
)
=
(
uint16_t
)
pstJsonCur
->
unData
.
lValue
;
}
else
if
(
sizeof
(
uint8_t
)
==
pstCurParse
->
uiBufSize
)
{
*
(
uint8_t
*
)(
pstCurParse
->
pDataBuf
)
=
(
uint8_t
)
pstJsonCur
->
unData
.
lValue
;
}
else
if
((
pstCurParse
->
uiBufSize
>
sizeof
(
uint64_t
)))
{
snprintf
((
char
*
)
pstCurParse
->
pDataBuf
,
pstCurParse
->
uiBufSize
,
"%llu"
,
(
unsigned
long
long
)(
pstJsonCur
->
unData
.
lValue
));
}
else
{
vdebug
(
"Invalid number data buf size %u.
\n
"
,
pstCurParse
->
uiBufSize
);
}
break
;
}
case
JSON_TYPE_STRING
:
{
strncpy
((
char
*
)
pstCurParse
->
pDataBuf
,
pstJsonCur
->
unData
.
pcStrVal
,
pstCurParse
->
uiBufSize
);
break
;
}
case
JSON_TYPE_BOOL
:
{
*
(
uint8_t
*
)(
pstCurParse
->
pDataBuf
)
=
(
pstJsonCur
->
unData
.
lValue
)
>
0
?
1
:
0
;
break
;
}
default
:
{
break
;
}
}
}
return
JSON_SUCCESS
;
}
int
vtoy_json_scan_array
(
VTOY_JSON
*
pstJson
,
const
char
*
szKey
,
VTOY_JSON
**
ppstArrayItem
)
{
VTOY_JSON
*
pstJsonItem
=
NULL
;
pstJsonItem
=
vtoy_json_find_item
(
pstJson
,
JSON_TYPE_ARRAY
,
szKey
);
if
(
NULL
==
pstJsonItem
)
{
vdebug
(
"Key %s is not found in json data.
\n
"
,
szKey
);
return
JSON_NOT_FOUND
;
}
*
ppstArrayItem
=
pstJsonItem
;
return
JSON_SUCCESS
;
}
int
vtoy_json_scan_array_ex
(
VTOY_JSON
*
pstJson
,
const
char
*
szKey
,
VTOY_JSON
**
ppstArrayItem
)
{
VTOY_JSON
*
pstJsonItem
=
NULL
;
pstJsonItem
=
vtoy_json_find_item
(
pstJson
,
JSON_TYPE_ARRAY
,
szKey
);
if
(
NULL
==
pstJsonItem
)
{
vdebug
(
"Key %s is not found in json data.
\n
"
,
szKey
);
return
JSON_NOT_FOUND
;
}
*
ppstArrayItem
=
pstJsonItem
->
pstChild
;
return
JSON_SUCCESS
;
}
int
vtoy_json_scan_object
(
VTOY_JSON
*
pstJson
,
const
char
*
szKey
,
VTOY_JSON
**
ppstObjectItem
)
{
VTOY_JSON
*
pstJsonItem
=
NULL
;
pstJsonItem
=
vtoy_json_find_item
(
pstJson
,
JSON_TYPE_OBJECT
,
szKey
);
if
(
NULL
==
pstJsonItem
)
{
vdebug
(
"Key %s is not found in json data.
\n
"
,
szKey
);
return
JSON_NOT_FOUND
;
}
*
ppstObjectItem
=
pstJsonItem
;
return
JSON_SUCCESS
;
}
int
vtoy_json_get_int
(
VTOY_JSON
*
pstJson
,
const
char
*
szKey
,
int
*
piValue
)
{
VTOY_JSON
*
pstJsonItem
=
NULL
;
pstJsonItem
=
vtoy_json_find_item
(
pstJson
,
JSON_TYPE_NUMBER
,
szKey
);
if
(
NULL
==
pstJsonItem
)
{
vdebug
(
"Key %s is not found in json data.
\n
"
,
szKey
);
return
JSON_NOT_FOUND
;
}
*
piValue
=
(
int
)
pstJsonItem
->
unData
.
lValue
;
return
JSON_SUCCESS
;
}
int
vtoy_json_get_uint
(
VTOY_JSON
*
pstJson
,
const
char
*
szKey
,
uint32_t
*
puiValue
)
{
VTOY_JSON
*
pstJsonItem
=
NULL
;
pstJsonItem
=
vtoy_json_find_item
(
pstJson
,
JSON_TYPE_NUMBER
,
szKey
);
if
(
NULL
==
pstJsonItem
)
{
vdebug
(
"Key %s is not found in json data.
\n
"
,
szKey
);
return
JSON_NOT_FOUND
;
}
*
puiValue
=
(
uint32_t
)
pstJsonItem
->
unData
.
lValue
;
return
JSON_SUCCESS
;
}
int
vtoy_json_get_uint64
(
VTOY_JSON
*
pstJson
,
const
char
*
szKey
,
uint64_t
*
pui64Value
)
{
VTOY_JSON
*
pstJsonItem
=
NULL
;
pstJsonItem
=
vtoy_json_find_item
(
pstJson
,
JSON_TYPE_NUMBER
,
szKey
);
if
(
NULL
==
pstJsonItem
)
{
vdebug
(
"Key %s is not found in json data.
\n
"
,
szKey
);
return
JSON_NOT_FOUND
;
}
*
pui64Value
=
(
uint64_t
)
pstJsonItem
->
unData
.
lValue
;
return
JSON_SUCCESS
;
}
int
vtoy_json_get_bool
(
VTOY_JSON
*
pstJson
,
const
char
*
szKey
,
uint8_t
*
pbValue
)
{
VTOY_JSON
*
pstJsonItem
=
NULL
;
pstJsonItem
=
vtoy_json_find_item
(
pstJson
,
JSON_TYPE_BOOL
,
szKey
);
if
(
NULL
==
pstJsonItem
)
{
vdebug
(
"Key %s is not found in json data.
\n
"
,
szKey
);
return
JSON_NOT_FOUND
;
}
*
pbValue
=
pstJsonItem
->
unData
.
lValue
>
0
?
1
:
0
;
return
JSON_SUCCESS
;
}
int
vtoy_json_get_string
(
VTOY_JSON
*
pstJson
,
const
char
*
szKey
,
uint32_t
uiBufLen
,
char
*
pcBuf
)
{
VTOY_JSON
*
pstJsonItem
=
NULL
;
pstJsonItem
=
vtoy_json_find_item
(
pstJson
,
JSON_TYPE_STRING
,
szKey
);
if
(
NULL
==
pstJsonItem
)
{
vdebug
(
"Key %s is not found in json data.
\n
"
,
szKey
);
return
JSON_NOT_FOUND
;
}
strncpy
(
pcBuf
,
pstJsonItem
->
unData
.
pcStrVal
,
uiBufLen
);
return
JSON_SUCCESS
;
}
const
char
*
vtoy_json_get_string_ex
(
VTOY_JSON
*
pstJson
,
const
char
*
szKey
)
{
VTOY_JSON
*
pstJsonItem
=
NULL
;
if
((
NULL
==
pstJson
)
||
(
NULL
==
szKey
))
{
return
NULL
;
}
pstJsonItem
=
vtoy_json_find_item
(
pstJson
,
JSON_TYPE_STRING
,
szKey
);
if
(
NULL
==
pstJsonItem
)
{
vdebug
(
"Key %s is not found in json data.
\n
"
,
szKey
);
return
NULL
;
}
return
pstJsonItem
->
unData
.
pcStrVal
;
}
int
vtoy_json_destroy
(
VTOY_JSON
*
pstJson
)
{
if
(
NULL
==
pstJson
)
{
return
JSON_SUCCESS
;
}
if
(
NULL
!=
pstJson
->
pstChild
)
{
vtoy_json_free
(
pstJson
->
pstChild
);
}
if
(
NULL
!=
pstJson
->
pstNext
)
{
vtoy_json_free
(
pstJson
->
pstNext
);
}
free
(
pstJson
);
return
JSON_SUCCESS
;
}
LinuxGUI/Ventoy2Disk/Core/ventoy_json.h
0 → 100644
View file @
43e8ec57
/******************************************************************************
* ventoy_json.h
*
* Copyright (c) 2021, longpanda <admin@ventoy.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __VENTOY_JSON_H__
#define __VENTOY_JSON_H__
#define JSON_NEW_ITEM(pstJson, ret) \
{ \
(pstJson) = (VTOY_JSON *)zalloc(sizeof(VTOY_JSON)); \
if (NULL == (pstJson)) \
{ \
vdebug("Failed to alloc memory for json."); \
return (ret); \
} \
}
#define ssprintf(curpos, buf, len, fmt, args...) \
curpos += snprintf(buf + curpos, len - curpos, fmt, ##args)
#define VTOY_JSON_IS_SKIPABLE(c) (((c) <= 32) ? 1 : 0)
#define VTOY_JSON_PRINT_PREFIX(uiDepth, args...) \
{ \
uint32_t _uiLoop = 0; \
for (_uiLoop = 0; _uiLoop < (uiDepth); _uiLoop++) \
{ \
ssprintf(uiCurPos, pcBuf, uiBufLen, " "); \
} \
ssprintf(uiCurPos, pcBuf, uiBufLen, ##args); \
}
#define VTOY_JSON_SUCCESS_RET "{ \"result\" : \"success\" }"
#define VTOY_JSON_FAILED_RET "{ \"result\" : \"failed\" }"
#define VTOY_JSON_INVALID_RET "{ \"result\" : \"invalidfmt\" }"
#define VTOY_JSON_TOKEN_ERR_RET "{ \"result\" : \"tokenerror\" }"
#define VTOY_JSON_EXIST_RET "{ \"result\" : \"exist\" }"
#define VTOY_JSON_TIMEOUT_RET "{ \"result\" : \"timeout\" }"
#define VTOY_JSON_BUSY_RET "{ \"result\" : \"busy\" }"
#define VTOY_JSON_INUSE_RET "{ \"result\" : \"inuse\" }"
#define VTOY_JSON_NOTFOUND_RET "{ \"result\" : \"notfound\" }"
#define VTOY_JSON_NOTRUNNING_RET "{ \"result\" : \"notrunning\" }"
#define VTOY_JSON_NOT_READY_RET "{ \"result\" : \"notready\" }"
#define VTOY_JSON_NOT_SUPPORT_RET "{ \"result\" : \"notsupport\" }"
#define VTOY_JSON_MBR_2TB_RET "{ \"result\" : \"mbr2tb\" }"
#define VTOY_JSON_INVALID_RSV_RET "{ \"result\" : \"reserve_invalid\" }"
#define VTOY_JSON_FILE_NOT_FOUND_RET "{ \"result\" : \"file_not_found\" }"
typedef
enum
tagJSON_TYPE
{
JSON_TYPE_NUMBER
=
0
,
JSON_TYPE_STRING
,
JSON_TYPE_BOOL
,
JSON_TYPE_ARRAY
,
JSON_TYPE_OBJECT
,
JSON_TYPE_NULL
,
JSON_TYPE_BUTT
}
JSON_TYPE
;
typedef
struct
tagVTOY_JSON
{
struct
tagVTOY_JSON
*
pstPrev
;
struct
tagVTOY_JSON
*
pstNext
;
struct
tagVTOY_JSON
*
pstChild
;
JSON_TYPE
enDataType
;
union
{
char
*
pcStrVal
;
int
iNumVal
;
uint64_t
lValue
;
}
unData
;
char
*
pcName
;
}
VTOY_JSON
;
#define VTOY_JSON_FMT_BEGIN(uiCurPos, pcBuf, uiBufLen) \
{\
uint32_t __uiCurPos = (uiCurPos);\
uint32_t __uiBufLen = (uiBufLen);\
char *__pcBuf = (pcBuf);
#define VTOY_JSON_FMT_END(uiCurPos) \
(uiCurPos) = __uiCurPos;\
}
#define VTOY_JSON_FMT_OBJ_BEGIN() ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "{")
#define VTOY_JSON_FMT_OBJ_END() \
{\
if (',' == *(__pcBuf + (__uiCurPos - 1)))\
{\
__uiCurPos -= 1;\
}\
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "}");\
}
#define VTOY_JSON_FMT_OBJ_ENDEX() \
{\
if (',' == *(__pcBuf + (__uiCurPos - 1)))\
{\
__uiCurPos -= 1;\
}\
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "},");\
}
#define VTOY_JSON_FMT_KEY(Key) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":", (Key))
#define VTOY_JSON_FMT_ITEM(Item) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\",", (Item))
#define VTOY_JSON_FMT_COMA() ssprintf(__uiCurPos, __pcBuf, __uiBufLen, ",");
#define VTOY_JSON_FMT_APPEND_BEGIN() \
{ \
if ('}' == *(__pcBuf + (__uiCurPos - 1)))\
{\
__uiCurPos -= 1;\
}\
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, ",");\
}
#define VTOY_JSON_FMT_APPEND_END() \
{ \
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "}");\
}
#define VTOY_JSON_FMT_ARY_BEGIN() ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "[")
#define VTOY_JSON_FMT_ARY_END() \
{\
if (',' == *(__pcBuf + (__uiCurPos - 1)))\
{\
__uiCurPos -= 1;\
}\
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "]");\
}
#define VTOY_JSON_FMT_ARY_ENDEX() \
{\
if (',' == *(__pcBuf + (__uiCurPos - 1)))\
{\
__uiCurPos -= 1;\
}\
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "],");\
}
#define VTOY_JSON_FMT_UINT64(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":%llu,", Key, (_ull)Val)
#define VTOY_JSON_FMT_ULONG(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":%lu,", Key, Val)
#define VTOY_JSON_FMT_LONG(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":%ld,", Key, Val)
#define VTOY_JSON_FMT_UINT(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":%u,", Key, Val)
#define VTOY_JSON_FMT_STRINT(Key, Val) \
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":\"%u\",", Key, Val)
#define VTOY_JSON_FMT_STRINT64(Key, Val) \
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":\"%llu\",", Key, Val)
#define VTOY_JSON_FMT_SINT(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":%d,", Key, Val)
#define VTOY_JSON_FMT_DUBL(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":%.1lf,", Key, Val)
#define VTOY_JSON_FMT_DUBL2(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":%10.02lf,", Key, Val)
#define VTOY_JSON_FMT_STRN(Key, Val) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":\"%s\",", Key, Val)
#define VTOY_JSON_FMT_NULL(Key) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":null,", Key)
#define VTOY_JSON_FMT_TRUE(Key) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":true,", (Key))
#define VTOY_JSON_FMT_FALSE(Key) ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":false,", (Key))
#define VTOY_JSON_FMT_BOOL(Key, Val) \
{\
if (0 == (Val))\
{\
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":false,", (Key));\
}\
else \
{\
ssprintf(__uiCurPos, __pcBuf, __uiBufLen, "\"%s\":true,", (Key));\
}\
}
typedef
struct
tagVTOY_JSON_PARSE
{
char
*
pcKey
;
void
*
pDataBuf
;
uint32_t
uiBufSize
;
}
VTOY_JSON_PARSE_S
;
#define JSON_SUCCESS 0
#define JSON_FAILED 1
#define JSON_NOT_FOUND 2
int
vtoy_json_parse_value
(
char
*
pcNewStart
,
char
*
pcRawStart
,
VTOY_JSON
*
pstJson
,
const
char
*
pcData
,
const
char
**
ppcEnd
);
VTOY_JSON
*
vtoy_json_create
(
void
);
int
vtoy_json_parse
(
VTOY_JSON
*
pstJson
,
const
char
*
szJsonData
);
int
vtoy_json_destroy
(
VTOY_JSON
*
pstJson
);
VTOY_JSON
*
vtoy_json_find_item
(
VTOY_JSON
*
pstJson
,
JSON_TYPE
enDataType
,
const
char
*
szKey
);
int
vtoy_json_scan_parse
(
const
VTOY_JSON
*
pstJson
,
uint32_t
uiParseNum
,
VTOY_JSON_PARSE_S
*
pstJsonParse
);
int
vtoy_json_get_int
(
VTOY_JSON
*
pstJson
,
const
char
*
szKey
,
int
*
piValue
);
int
vtoy_json_get_uint
(
VTOY_JSON
*
pstJson
,
const
char
*
szKey
,
uint32_t
*
puiValue
);
int
vtoy_json_get_uint64
(
VTOY_JSON
*
pstJson
,
const
char
*
szKey
,
uint64_t
*
pui64Value
);
int
vtoy_json_get_bool
(
VTOY_JSON
*
pstJson
,
const
char
*
szKey
,
uint8_t
*
pbValue
);
int
vtoy_json_get_string
(
VTOY_JSON
*
pstJson
,
const
char
*
szKey
,
uint32_t
uiBufLen
,
char
*
pcBuf
);
const
char
*
vtoy_json_get_string_ex
(
VTOY_JSON
*
pstJson
,
const
char
*
szKey
);
#endif
/* __VENTOY_JSON_H__ */
LinuxGUI/Ventoy2Disk/Core/ventoy_log.c
0 → 100644
View file @
43e8ec57
/******************************************************************************
* ventoy_log.c ---- ventoy log
*
* Copyright (c) 2021, longpanda <admin@ventoy.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <ventoy_define.h>
static
int
g_ventoy_log_level
=
VLOG_DEBUG
;
static
pthread_mutex_t
g_log_mutex
;
int
ventoy_log_init
(
void
)
{
pthread_mutex_init
(
&
g_log_mutex
,
NULL
);
return
0
;
}
void
ventoy_log_exit
(
void
)
{
pthread_mutex_destroy
(
&
g_log_mutex
);
}
void
ventoy_set_loglevel
(
int
level
)
{
g_ventoy_log_level
=
level
;
}
void
ventoy_syslog_newline
(
int
level
,
const
char
*
Fmt
,
...)
{
char
log
[
512
];
va_list
arg
;
time_t
stamp
;
struct
tm
ttm
;
FILE
*
fp
;
if
(
level
>
g_ventoy_log_level
)
{
return
;
}
time
(
&
stamp
);
localtime_r
(
&
stamp
,
&
ttm
);
va_start
(
arg
,
Fmt
);
vsnprintf
(
log
,
512
,
Fmt
,
arg
);
va_end
(
arg
);
pthread_mutex_lock
(
&
g_log_mutex
);
fp
=
fopen
(
VTOY_LOG_FILE
,
"a+"
);
if
(
fp
)
{
fprintf
(
fp
,
"[%04u/%02u/%02u %02u:%02u:%02u] %s
\n
"
,
ttm
.
tm_year
,
ttm
.
tm_mon
,
ttm
.
tm_mday
,
ttm
.
tm_hour
,
ttm
.
tm_min
,
ttm
.
tm_sec
,
log
);
fclose
(
fp
);
}
pthread_mutex_unlock
(
&
g_log_mutex
);
}
void
ventoy_syslog
(
int
level
,
const
char
*
Fmt
,
...)
{
char
log
[
512
];
va_list
arg
;
time_t
stamp
;
struct
tm
ttm
;
FILE
*
fp
;
if
(
level
>
g_ventoy_log_level
)
{
return
;
}
time
(
&
stamp
);
localtime_r
(
&
stamp
,
&
ttm
);
va_start
(
arg
,
Fmt
);
vsnprintf
(
log
,
512
,
Fmt
,
arg
);
va_end
(
arg
);
pthread_mutex_lock
(
&
g_log_mutex
);
fp
=
fopen
(
VTOY_LOG_FILE
,
"a+"
);
if
(
fp
)
{
fprintf
(
fp
,
"[%04u/%02u/%02u %02u:%02u:%02u] %s"
,
ttm
.
tm_year
,
ttm
.
tm_mon
,
ttm
.
tm_mday
,
ttm
.
tm_hour
,
ttm
.
tm_min
,
ttm
.
tm_sec
,
log
);
fclose
(
fp
);
}
pthread_mutex_unlock
(
&
g_log_mutex
);
}
LinuxGUI/Ventoy2Disk/Core/ventoy_md5.c
0 → 100644
View file @
43e8ec57
/******************************************************************************
* ventoy_md5.c ---- ventoy md5
*
* Copyright (c) 2021, longpanda <admin@ventoy.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
const
static
uint32_t
k
[
64
]
=
{
0xd76aa478
,
0xe8c7b756
,
0x242070db
,
0xc1bdceee
,
0xf57c0faf
,
0x4787c62a
,
0xa8304613
,
0xfd469501
,
0x698098d8
,
0x8b44f7af
,
0xffff5bb1
,
0x895cd7be
,
0x6b901122
,
0xfd987193
,
0xa679438e
,
0x49b40821
,
0xf61e2562
,
0xc040b340
,
0x265e5a51
,
0xe9b6c7aa
,
0xd62f105d
,
0x02441453
,
0xd8a1e681
,
0xe7d3fbc8
,
0x21e1cde6
,
0xc33707d6
,
0xf4d50d87
,
0x455a14ed
,
0xa9e3e905
,
0xfcefa3f8
,
0x676f02d9
,
0x8d2a4c8a
,
0xfffa3942
,
0x8771f681
,
0x6d9d6122
,
0xfde5380c
,
0xa4beea44
,
0x4bdecfa9
,
0xf6bb4b60
,
0xbebfbc70
,
0x289b7ec6
,
0xeaa127fa
,
0xd4ef3085
,
0x04881d05
,
0xd9d4d039
,
0xe6db99e5
,
0x1fa27cf8
,
0xc4ac5665
,
0xf4292244
,
0x432aff97
,
0xab9423a7
,
0xfc93a039
,
0x655b59c3
,
0x8f0ccc92
,
0xffeff47d
,
0x85845dd1
,
0x6fa87e4f
,
0xfe2ce6e0
,
0xa3014314
,
0x4e0811a1
,
0xf7537e82
,
0xbd3af235
,
0x2ad7d2bb
,
0xeb86d391
};
const
static
uint32_t
r
[]
=
{
7
,
12
,
17
,
22
,
7
,
12
,
17
,
22
,
7
,
12
,
17
,
22
,
7
,
12
,
17
,
22
,
5
,
9
,
14
,
20
,
5
,
9
,
14
,
20
,
5
,
9
,
14
,
20
,
5
,
9
,
14
,
20
,
4
,
11
,
16
,
23
,
4
,
11
,
16
,
23
,
4
,
11
,
16
,
23
,
4
,
11
,
16
,
23
,
6
,
10
,
15
,
21
,
6
,
10
,
15
,
21
,
6
,
10
,
15
,
21
,
6
,
10
,
15
,
21
};
#define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
#define to_bytes(val, bytes) *((uint32_t *)(bytes)) = (val)
#define ROTATE_CALC() \
{\
temp = d; \
d = c; \
c = b; \
b = b + LEFTROTATE((a + f + k[i] + w[g]), r[i]); \
a = temp; \
}
void
ventoy_md5
(
const
void
*
data
,
uint32_t
len
,
uint8_t
*
md5
)
{
uint32_t
h0
,
h1
,
h2
,
h3
;
uint32_t
w
[
16
];
uint32_t
a
,
b
,
c
,
d
,
i
,
f
,
g
,
temp
;
uint32_t
offset
,
mod
,
delta
;
uint8_t
postbuf
[
128
]
=
{
0
};
// Initialize variables - simple count in nibbles:
h0
=
0x67452301
;
h1
=
0xefcdab89
;
h2
=
0x98badcfe
;
h3
=
0x10325476
;
//Pre-processing:
//append "1" bit to message
//append "0" bits until message length in bits ≡ 448 (mod 512)
//append length mod (2^64) to message
mod
=
len
%
64
;
if
(
mod
)
{
memcpy
(
postbuf
,
(
const
uint8_t
*
)
data
+
len
-
mod
,
mod
);
}
postbuf
[
mod
]
=
0x80
;
if
(
mod
<
56
)
{
to_bytes
(
len
*
8
,
postbuf
+
56
);
to_bytes
(
len
>>
29
,
postbuf
+
60
);
delta
=
64
;
}
else
{
to_bytes
(
len
*
8
,
postbuf
+
120
);
to_bytes
(
len
>>
29
,
postbuf
+
124
);
delta
=
128
;
}
len
-=
mod
;
for
(
offset
=
0
;
offset
<
len
+
delta
;
offset
+=
64
)
{
if
(
offset
<
len
)
{
memcpy
(
w
,
(
const
uint8_t
*
)
data
+
offset
,
64
);
}
else
{
memcpy
(
w
,
postbuf
+
offset
-
len
,
64
);
}
// Initialize hash value for this chunk:
a
=
h0
;
b
=
h1
;
c
=
h2
;
d
=
h3
;
// Main loop:
for
(
i
=
0
;
i
<
16
;
i
++
)
{
f
=
(
b
&
c
)
|
((
~
b
)
&
d
);
g
=
i
;
ROTATE_CALC
();
}
for
(
i
=
16
;
i
<
32
;
i
++
)
{
f
=
(
d
&
b
)
|
((
~
d
)
&
c
);
g
=
(
5
*
i
+
1
)
%
16
;
ROTATE_CALC
();
}
for
(
i
=
32
;
i
<
48
;
i
++
)
{
f
=
b
^
c
^
d
;
g
=
(
3
*
i
+
5
)
%
16
;
ROTATE_CALC
();
}
for
(
i
=
48
;
i
<
64
;
i
++
)
{
f
=
c
^
(
b
|
(
~
d
));
g
=
(
7
*
i
)
%
16
;
ROTATE_CALC
();
}
// Add this chunk's hash to result so far:
h0
+=
a
;
h1
+=
b
;
h2
+=
c
;
h3
+=
d
;
}
//var char md5[16] := h0 append h1 append h2 append h3 //(Output is in little-endian)
to_bytes
(
h0
,
md5
);
to_bytes
(
h1
,
md5
+
4
);
to_bytes
(
h2
,
md5
+
8
);
to_bytes
(
h3
,
md5
+
12
);
}
LinuxGUI/Ventoy2Disk/Core/ventoy_util.c
0 → 100644
View file @
43e8ec57
/******************************************************************************
* ventoy_util.c ---- ventoy util
* Copyright (c) 2021, longpanda <admin@ventoy.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mount.h>
#include <linux/fs.h>
#include <dirent.h>
#include <time.h>
#include <ventoy_define.h>
#include <ventoy_util.h>
uint8_t
g_mbr_template
[
512
];
void
ventoy_gen_preudo_uuid
(
void
*
uuid
)
{
int
i
;
int
fd
;
fd
=
open
(
"/dev/urandom"
,
O_RDONLY
|
O_BINARY
);
if
(
fd
<
0
)
{
srand
(
time
(
NULL
));
for
(
i
=
0
;
i
<
8
;
i
++
)
{
*
((
uint16_t
*
)
uuid
+
i
)
=
(
uint16_t
)(
rand
()
&
0xFFFF
);
}
}
else
{
read
(
fd
,
uuid
,
16
);
close
(
fd
);
}
}
uint64_t
ventoy_get_human_readable_gb
(
uint64_t
SizeBytes
)
{
int
i
;
int
Pow2
=
1
;
double
Delta
;
double
GB
=
SizeBytes
*
1
.
0
/
1000
/
1000
/
1000
;
if
((
SizeBytes
%
SIZE_1GB
)
==
0
)
{
return
(
uint64_t
)(
SizeBytes
/
SIZE_1GB
);
}
for
(
i
=
0
;
i
<
12
;
i
++
)
{
if
(
Pow2
>
GB
)
{
Delta
=
(
Pow2
-
GB
)
/
Pow2
;
}
else
{
Delta
=
(
GB
-
Pow2
)
/
Pow2
;
}
if
(
Delta
<
0
.
05
)
{
return
Pow2
;
}
Pow2
<<=
1
;
}
return
(
uint64_t
)
GB
;
}
int
ventoy_get_sys_file_line
(
char
*
buffer
,
int
buflen
,
const
char
*
fmt
,
...)
{
int
len
;
char
c
;
char
path
[
256
];
va_list
arg
;
va_start
(
arg
,
fmt
);
vsnprintf
(
path
,
256
,
fmt
,
arg
);
va_end
(
arg
);
if
(
access
(
path
,
F_OK
)
>=
0
)
{
FILE
*
fp
=
fopen
(
path
,
"r"
);
memset
(
buffer
,
0
,
buflen
);
len
=
(
int
)
fread
(
buffer
,
1
,
buflen
-
1
,
fp
);
fclose
(
fp
);
while
(
len
>
0
)
{
c
=
buffer
[
len
-
1
];
if
(
c
==
'\r'
||
c
==
'\n'
||
c
==
' '
||
c
==
'\t'
)
{
buffer
[
len
-
1
]
=
0
;
len
--
;
}
else
{
break
;
}
}
return
0
;
}
else
{
vdebug
(
"%s not exist
\n
"
,
path
);
return
1
;
}
}
int
ventoy_is_disk_mounted
(
const
char
*
devpath
)
{
int
len
;
int
mount
=
0
;
char
line
[
512
];
FILE
*
fp
=
NULL
;
fp
=
fopen
(
"/proc/mounts"
,
"r"
);
if
(
!
fp
)
{
return
0
;
}
len
=
(
int
)
strlen
(
devpath
);
while
(
fgets
(
line
,
sizeof
(
line
),
fp
))
{
if
(
strncmp
(
line
,
devpath
,
len
)
==
0
)
{
mount
=
1
;
vdebug
(
"%s mounted <%s>
\n
"
,
devpath
,
line
);
goto
end
;
}
}
end:
fclose
(
fp
);
return
mount
;
}
int
ventoy_try_umount_disk
(
const
char
*
devpath
)
{
int
rc
;
int
len
;
char
line
[
512
];
char
*
pos1
=
NULL
;
char
*
pos2
=
NULL
;
FILE
*
fp
=
NULL
;
fp
=
fopen
(
"/proc/mounts"
,
"r"
);
if
(
!
fp
)
{
return
0
;
}
len
=
(
int
)
strlen
(
devpath
);
while
(
fgets
(
line
,
sizeof
(
line
),
fp
))
{
if
(
strncmp
(
line
,
devpath
,
len
)
==
0
)
{
pos1
=
strchr
(
line
,
' '
);
if
(
pos1
)
{
pos2
=
strchr
(
pos1
+
1
,
' '
);
if
(
pos2
)
{
*
pos2
=
0
;
}
rc
=
umount
(
pos1
+
1
);
if
(
rc
)
{
vdebug
(
"umount %s %s [ failed ] error:%d
\n
"
,
devpath
,
pos1
+
1
,
errno
);
}
else
{
vdebug
(
"umount %s %s [ success ]
\n
"
,
devpath
,
pos1
+
1
);
}
}
}
}
fclose
(
fp
);
return
0
;
}
int
ventoy_read_file_to_buf
(
const
char
*
FileName
,
int
ExtLen
,
void
**
Bufer
,
int
*
BufLen
)
{
int
FileSize
;
FILE
*
fp
=
NULL
;
void
*
Data
=
NULL
;
fp
=
fopen
(
FileName
,
"rb"
);
if
(
fp
==
NULL
)
{
vlog
(
"Failed to open file %s"
,
FileName
);
return
1
;
}
fseek
(
fp
,
0
,
SEEK_END
);
FileSize
=
(
int
)
ftell
(
fp
);
Data
=
malloc
(
FileSize
+
ExtLen
);
if
(
!
Data
)
{
fclose
(
fp
);
return
1
;
}
fseek
(
fp
,
0
,
SEEK_SET
);
fread
(
Data
,
1
,
FileSize
,
fp
);
fclose
(
fp
);
*
Bufer
=
Data
;
*
BufLen
=
FileSize
;
return
0
;
}
const
char
*
ventoy_get_local_version
(
void
)
{
int
rc
;
int
FileSize
;
char
*
Pos
=
NULL
;
char
*
Buf
=
NULL
;
static
char
LocalVersion
[
64
]
=
{
0
};
if
(
LocalVersion
[
0
]
==
0
)
{
rc
=
ventoy_read_file_to_buf
(
"ventoy/version"
,
1
,
(
void
**
)
&
Buf
,
&
FileSize
);
if
(
rc
)
{
return
""
;
}
Buf
[
FileSize
]
=
0
;
for
(
Pos
=
Buf
;
*
Pos
;
Pos
++
)
{
if
(
*
Pos
==
'\r'
||
*
Pos
==
'\n'
)
{
*
Pos
=
0
;
break
;
}
}
scnprintf
(
LocalVersion
,
"%s"
,
Buf
);
free
(
Buf
);
}
return
LocalVersion
;
}
int
VentoyGetLocalBootImg
(
MBR_HEAD
*
pMBR
)
{
memcpy
(
pMBR
,
g_mbr_template
,
512
);
return
0
;
}
static
int
VentoyFillProtectMBR
(
uint64_t
DiskSizeBytes
,
MBR_HEAD
*
pMBR
)
{
ventoy_guid
Guid
;
uint32_t
DiskSignature
;
uint64_t
DiskSectorCount
;
VentoyGetLocalBootImg
(
pMBR
);
ventoy_gen_preudo_uuid
(
&
Guid
);
memcpy
(
&
DiskSignature
,
&
Guid
,
sizeof
(
uint32_t
));
vdebug
(
"Disk signature: 0x%08x
\n
"
,
DiskSignature
);
memcpy
(
pMBR
->
BootCode
+
0x1B8
,
&
DiskSignature
,
4
);
DiskSectorCount
=
DiskSizeBytes
/
512
-
1
;
if
(
DiskSectorCount
>
0xFFFFFFFF
)
{
DiskSectorCount
=
0xFFFFFFFF
;
}
memset
(
pMBR
->
PartTbl
,
0
,
sizeof
(
pMBR
->
PartTbl
));
pMBR
->
PartTbl
[
0
].
Active
=
0x00
;
pMBR
->
PartTbl
[
0
].
FsFlag
=
0xee
;
// EE
pMBR
->
PartTbl
[
0
].
StartHead
=
0
;
pMBR
->
PartTbl
[
0
].
StartSector
=
1
;
pMBR
->
PartTbl
[
0
].
StartCylinder
=
0
;
pMBR
->
PartTbl
[
0
].
EndHead
=
254
;
pMBR
->
PartTbl
[
0
].
EndSector
=
63
;
pMBR
->
PartTbl
[
0
].
EndCylinder
=
1023
;
pMBR
->
PartTbl
[
0
].
StartSectorId
=
1
;
pMBR
->
PartTbl
[
0
].
SectorCount
=
(
uint32_t
)
DiskSectorCount
;
pMBR
->
Byte55
=
0x55
;
pMBR
->
ByteAA
=
0xAA
;
pMBR
->
BootCode
[
92
]
=
0x22
;
return
0
;
}
static
int
ventoy_fill_gpt_partname
(
uint16_t
Name
[
36
],
const
char
*
asciiName
)
{
int
i
;
int
len
;
memset
(
Name
,
0
,
36
*
sizeof
(
uint16_t
));
len
=
(
int
)
strlen
(
asciiName
);
for
(
i
=
0
;
i
<
36
&&
i
<
len
;
i
++
)
{
Name
[
i
]
=
asciiName
[
i
];
}
return
0
;
}
int
ventoy_fill_gpt
(
uint64_t
size
,
uint64_t
reserve
,
int
align4k
,
VTOY_GPT_INFO
*
gpt
)
{
uint64_t
ReservedSector
=
33
;
uint64_t
Part1SectorCount
=
0
;
uint64_t
DiskSectorCount
=
size
/
512
;
VTOY_GPT_HDR
*
Head
=
&
gpt
->
Head
;
VTOY_GPT_PART_TBL
*
Table
=
gpt
->
PartTbl
;
ventoy_guid
WindowsDataPartType
=
{
0xebd0a0a2
,
0xb9e5
,
0x4433
,
{
0x87
,
0xc0
,
0x68
,
0xb6
,
0xb7
,
0x26
,
0x99
,
0xc7
}
};
//ventoy_guid EspPartType = { 0xc12a7328, 0xf81f, 0x11d2, { 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } };
//ventoy_guid BiosGrubPartType = { 0x21686148, 0x6449, 0x6e6f, { 0x74, 0x4e, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49 } };
VentoyFillProtectMBR
(
size
,
&
gpt
->
MBR
);
if
(
reserve
>
0
)
{
ReservedSector
+=
reserve
/
512
;
}
// check aligned with 4KB
if
(
align4k
)
{
if
(
DiskSectorCount
%
8
)
{
vdebug
(
"Disk need to align with 4KB %u
\n
"
,
(
uint32_t
)(
DiskSectorCount
%
8
));
ReservedSector
+=
(
DiskSectorCount
%
8
);
}
}
Part1SectorCount
=
DiskSectorCount
-
ReservedSector
-
(
VTOYEFI_PART_BYTES
/
512
)
-
2048
;
memcpy
(
Head
->
Signature
,
"EFI PART"
,
8
);
Head
->
Version
[
2
]
=
0x01
;
Head
->
Length
=
92
;
Head
->
Crc
=
0
;
Head
->
EfiStartLBA
=
1
;
Head
->
EfiBackupLBA
=
DiskSectorCount
-
1
;
Head
->
PartAreaStartLBA
=
34
;
Head
->
PartAreaEndLBA
=
DiskSectorCount
-
34
;
ventoy_gen_preudo_uuid
(
&
Head
->
DiskGuid
);
Head
->
PartTblStartLBA
=
2
;
Head
->
PartTblTotNum
=
128
;
Head
->
PartTblEntryLen
=
128
;
memcpy
(
&
(
Table
[
0
].
PartType
),
&
WindowsDataPartType
,
sizeof
(
ventoy_guid
));
ventoy_gen_preudo_uuid
(
&
(
Table
[
0
].
PartGuid
));
Table
[
0
].
StartLBA
=
2048
;
Table
[
0
].
LastLBA
=
2048
+
Part1SectorCount
-
1
;
Table
[
0
].
Attr
=
0
;
ventoy_fill_gpt_partname
(
Table
[
0
].
Name
,
"Ventoy"
);
// to fix windows issue
//memcpy(&(Table[1].PartType), &EspPartType, sizeof(GUID));
memcpy
(
&
(
Table
[
1
].
PartType
),
&
WindowsDataPartType
,
sizeof
(
ventoy_guid
));
ventoy_gen_preudo_uuid
(
&
(
Table
[
1
].
PartGuid
));
Table
[
1
].
StartLBA
=
Table
[
0
].
LastLBA
+
1
;
Table
[
1
].
LastLBA
=
Table
[
1
].
StartLBA
+
VTOYEFI_PART_BYTES
/
512
-
1
;
Table
[
1
].
Attr
=
0x8000000000000001ULL
;
ventoy_fill_gpt_partname
(
Table
[
1
].
Name
,
"VTOYEFI"
);
#if 0
memcpy(&(Table[2].PartType), &BiosGrubPartType, sizeof(ventoy_guid));
ventoy_gen_preudo_uuid(&(Table[2].PartGuid));
Table[2].StartLBA = 34;
Table[2].LastLBA = 2047;
Table[2].Attr = 0;
#endif
//Update CRC
Head
->
PartTblCrc
=
ventoy_crc32
(
Table
,
sizeof
(
gpt
->
PartTbl
));
Head
->
Crc
=
ventoy_crc32
(
Head
,
Head
->
Length
);
return
0
;
}
int
VentoyFillMBRLocation
(
uint64_t
DiskSizeInBytes
,
uint32_t
StartSectorId
,
uint32_t
SectorCount
,
PART_TABLE
*
Table
)
{
uint8_t
Head
;
uint8_t
Sector
;
uint8_t
nSector
=
63
;
uint8_t
nHead
=
8
;
uint32_t
Cylinder
;
uint32_t
EndSectorId
;
while
(
nHead
!=
0
&&
(
DiskSizeInBytes
/
512
/
nSector
/
nHead
)
>
1024
)
{
nHead
=
(
uint8_t
)
nHead
*
2
;
}
if
(
nHead
==
0
)
{
nHead
=
255
;
}
Cylinder
=
StartSectorId
/
nSector
/
nHead
;
Head
=
StartSectorId
/
nSector
%
nHead
;
Sector
=
StartSectorId
%
nSector
+
1
;
Table
->
StartHead
=
Head
;
Table
->
StartSector
=
Sector
;
Table
->
StartCylinder
=
Cylinder
;
EndSectorId
=
StartSectorId
+
SectorCount
-
1
;
Cylinder
=
EndSectorId
/
nSector
/
nHead
;
Head
=
EndSectorId
/
nSector
%
nHead
;
Sector
=
EndSectorId
%
nSector
+
1
;
Table
->
EndHead
=
Head
;
Table
->
EndSector
=
Sector
;
Table
->
EndCylinder
=
Cylinder
;
Table
->
StartSectorId
=
StartSectorId
;
Table
->
SectorCount
=
SectorCount
;
return
0
;
}
int
ventoy_fill_mbr
(
uint64_t
size
,
uint64_t
reserve
,
int
align4k
,
int
PartStyle
,
MBR_HEAD
*
pMBR
)
{
ventoy_guid
Guid
;
uint32_t
DiskSignature
;
uint32_t
DiskSectorCount
;
uint32_t
PartSectorCount
;
uint32_t
PartStartSector
;
uint32_t
ReservedSector
;
VentoyGetLocalBootImg
(
pMBR
);
ventoy_gen_preudo_uuid
(
&
Guid
);
memcpy
(
&
DiskSignature
,
&
Guid
,
sizeof
(
uint32_t
));
vdebug
(
"Disk signature: 0x%08x
\n
"
,
DiskSignature
);
memcpy
(
pMBR
->
BootCode
+
0x1B8
,
&
DiskSignature
,
4
);
if
(
size
/
512
>
0xFFFFFFFF
)
{
DiskSectorCount
=
0xFFFFFFFF
;
}
else
{
DiskSectorCount
=
(
uint32_t
)(
size
/
512
);
}
if
(
reserve
<=
0
)
{
ReservedSector
=
0
;
}
else
{
ReservedSector
=
(
uint32_t
)(
reserve
/
512
);
}
if
(
PartStyle
)
{
ReservedSector
+=
33
;
// backup GPT part table
}
// check aligned with 4KB
if
(
align4k
)
{
uint64_t
sectors
=
size
/
512
;
if
(
sectors
%
8
)
{
vlog
(
"Disk need to align with 4KB %u
\n
"
,
(
uint32_t
)(
sectors
%
8
));
ReservedSector
+=
(
uint32_t
)(
sectors
%
8
);
}
}
vlog
(
"ReservedSector: %u
\n
"
,
ReservedSector
);
//Part1
PartStartSector
=
VTOYIMG_PART_START_SECTOR
;
PartSectorCount
=
DiskSectorCount
-
ReservedSector
-
VTOYEFI_PART_BYTES
/
512
-
PartStartSector
;
VentoyFillMBRLocation
(
size
,
PartStartSector
,
PartSectorCount
,
pMBR
->
PartTbl
);
pMBR
->
PartTbl
[
0
].
Active
=
0x80
;
// bootable
pMBR
->
PartTbl
[
0
].
FsFlag
=
0x07
;
// exFAT/NTFS/HPFS
//Part2
PartStartSector
+=
PartSectorCount
;
PartSectorCount
=
VTOYEFI_PART_BYTES
/
512
;
VentoyFillMBRLocation
(
size
,
PartStartSector
,
PartSectorCount
,
pMBR
->
PartTbl
+
1
);
pMBR
->
PartTbl
[
1
].
Active
=
0x00
;
pMBR
->
PartTbl
[
1
].
FsFlag
=
0xEF
;
// EFI System Partition
pMBR
->
Byte55
=
0x55
;
pMBR
->
ByteAA
=
0xAA
;
return
0
;
}
LinuxGUI/Ventoy2Disk/Core/ventoy_util.h
0 → 100644
View file @
43e8ec57
/******************************************************************************
* ventoy_util.h
*
* Copyright (c) 2021, longpanda <admin@ventoy.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __VENTOY_UTIL_H__
#define __VENTOY_UTIL_H__
#define check_free(p) if (p) free(p)
#define vtoy_safe_close_fd(fd) \
{\
if ((fd) >= 0) \
{ \
close(fd); \
(fd) = -1; \
}\
}
extern
uint8_t
g_mbr_template
[
512
];
void
ventoy_gen_preudo_uuid
(
void
*
uuid
);
int
ventoy_get_disk_part_name
(
const
char
*
dev
,
int
part
,
char
*
partbuf
,
int
bufsize
);
int
ventoy_get_sys_file_line
(
char
*
buffer
,
int
buflen
,
const
char
*
fmt
,
...);
uint64_t
ventoy_get_human_readable_gb
(
uint64_t
SizeBytes
);
void
ventoy_md5
(
const
void
*
data
,
uint32_t
len
,
uint8_t
*
md5
);
int
ventoy_is_disk_mounted
(
const
char
*
devpath
);
int
ventoy_try_umount_disk
(
const
char
*
devpath
);
int
unxz
(
unsigned
char
*
in
,
int
in_size
,
int
(
*
fill
)(
void
*
dest
,
unsigned
int
size
),
int
(
*
flush
)(
void
*
src
,
unsigned
int
size
),
unsigned
char
*
out
,
int
*
in_used
,
void
(
*
error
)(
char
*
x
));
int
ventoy_read_file_to_buf
(
const
char
*
FileName
,
int
ExtLen
,
void
**
Bufer
,
int
*
BufLen
);
const
char
*
ventoy_get_local_version
(
void
);
int
ventoy_fill_gpt
(
uint64_t
size
,
uint64_t
reserve
,
int
align4k
,
VTOY_GPT_INFO
*
gpt
);
int
ventoy_fill_mbr
(
uint64_t
size
,
uint64_t
reserve
,
int
align4k
,
int
PartStyle
,
MBR_HEAD
*
pMBR
);
#endif
/* __VENTOY_UTIL_H__ */
LinuxGUI/Ventoy2Disk/Include/Ventoy2Disk.h
0 → 100644
View file @
43e8ec57
/******************************************************************************
* Ventoy2Disk.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 __VENTOY2DISK_H__
#define __VENTOY2DISK_H__
#endif
/* __VENTOY2DISK_H__ */
LinuxGUI/Ventoy2Disk/Lib/exfat/buidexfat.sh
0 → 100644
View file @
43e8ec57
#!/bin/sh
CUR
=
"
$PWD
"
rm
-rf
src
mkdir
-p
src/libexfat
mkdir
-p
src/mkfs
rm
-rf
exfat-1.3.0
unzip exfat-1.3.0.zip
cd
exfat-1.3.0
autoreconf
--install
./configure
--prefix
=
"
$CUR
"
CFLAGS
=
'-O2 -D_FILE_OFFSET_BITS=64'
make
cp
-a
libexfat/
*
.c ../src/libexfat/
cp
-a
libexfat/
*
.h ../src/libexfat/
cp
-a
mkfs/
*
.c ../src/mkfs/
cp
-a
mkfs/
*
.h ../src/mkfs/
rm
-f
../src/libexfat/log.c
cd
..
rm
-rf
exfat-1.3.0
mv
src/mkfs/main.c src/mkfs/mkexfat_main.c
sed
's/<exfat.h>/"exfat.h"/g'
-i
src/mkfs/mkexfat_main.c
sed
's/<exfat.h>/"exfat.h"/g'
-i
src/mkfs/mkexfat.h
sed
's/int main/int mkexfat_main/g'
-i
src/mkfs/mkexfat_main.c
LinuxGUI/Ventoy2Disk/Lib/exfat/exfat-1.3.0.zip
0 → 100644
View file @
43e8ec57
File added
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h
0 → 100644
View file @
43e8ec57
/*
byteorder.h (12.01.10)
Endianness stuff. exFAT uses little-endian byte order.
Free exFAT implementation.
Copyright (C) 2010-2018 Andrew Nayenko
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 2 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, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef BYTEORDER_H_INCLUDED
#define BYTEORDER_H_INCLUDED
#include "platform.h"
#include <stdint.h>
#include <stddef.h>
typedef
struct
{
uint16_t
__u16
;
}
le16_t
;
typedef
struct
{
uint32_t
__u32
;
}
le32_t
;
typedef
struct
{
uint64_t
__u64
;
}
le64_t
;
#if EXFAT_BYTE_ORDER == EXFAT_LITTLE_ENDIAN
static
inline
uint16_t
le16_to_cpu
(
le16_t
v
)
{
return
v
.
__u16
;
}
static
inline
uint32_t
le32_to_cpu
(
le32_t
v
)
{
return
v
.
__u32
;
}
static
inline
uint64_t
le64_to_cpu
(
le64_t
v
)
{
return
v
.
__u64
;
}
static
inline
le16_t
cpu_to_le16
(
uint16_t
v
)
{
le16_t
t
=
{
v
};
return
t
;
}
static
inline
le32_t
cpu_to_le32
(
uint32_t
v
)
{
le32_t
t
=
{
v
};
return
t
;
}
static
inline
le64_t
cpu_to_le64
(
uint64_t
v
)
{
le64_t
t
=
{
v
};
return
t
;
}
typedef
size_t
bitmap_t
;
#elif EXFAT_BYTE_ORDER == EXFAT_BIG_ENDIAN
static
inline
uint16_t
le16_to_cpu
(
le16_t
v
)
{
return
exfat_bswap16
(
v
.
__u16
);
}
static
inline
uint32_t
le32_to_cpu
(
le32_t
v
)
{
return
exfat_bswap32
(
v
.
__u32
);
}
static
inline
uint64_t
le64_to_cpu
(
le64_t
v
)
{
return
exfat_bswap64
(
v
.
__u64
);
}
static
inline
le16_t
cpu_to_le16
(
uint16_t
v
)
{
le16_t
t
=
{
exfat_bswap16
(
v
)};
return
t
;
}
static
inline
le32_t
cpu_to_le32
(
uint32_t
v
)
{
le32_t
t
=
{
exfat_bswap32
(
v
)};
return
t
;
}
static
inline
le64_t
cpu_to_le64
(
uint64_t
v
)
{
le64_t
t
=
{
exfat_bswap64
(
v
)};
return
t
;
}
typedef
unsigned
char
bitmap_t
;
#else
#error Wow! You have a PDP machine?!
#endif
#endif
/* ifndef BYTEORDER_H_INCLUDED */
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/cluster.c
0 → 100644
View file @
43e8ec57
/*
cluster.c (03.09.09)
exFAT file system implementation library.
Free exFAT implementation.
Copyright (C) 2010-2018 Andrew Nayenko
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 2 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, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "exfat.h"
#include <errno.h>
#include <string.h>
#include <inttypes.h>
/*
* Sector to absolute offset.
*/
static
off_t
s2o
(
const
struct
exfat
*
ef
,
off_t
sector
)
{
return
sector
<<
ef
->
sb
->
sector_bits
;
}
/*
* Cluster to sector.
*/
static
off_t
c2s
(
const
struct
exfat
*
ef
,
cluster_t
cluster
)
{
if
(
cluster
<
EXFAT_FIRST_DATA_CLUSTER
)
exfat_bug
(
"invalid cluster number %u"
,
cluster
);
return
le32_to_cpu
(
ef
->
sb
->
cluster_sector_start
)
+
((
off_t
)
(
cluster
-
EXFAT_FIRST_DATA_CLUSTER
)
<<
ef
->
sb
->
spc_bits
);
}
/*
* Cluster to absolute offset.
*/
off_t
exfat_c2o
(
const
struct
exfat
*
ef
,
cluster_t
cluster
)
{
return
s2o
(
ef
,
c2s
(
ef
,
cluster
));
}
/*
* Sector to cluster.
*/
static
cluster_t
s2c
(
const
struct
exfat
*
ef
,
off_t
sector
)
{
return
((
sector
-
le32_to_cpu
(
ef
->
sb
->
cluster_sector_start
))
>>
ef
->
sb
->
spc_bits
)
+
EXFAT_FIRST_DATA_CLUSTER
;
}
/*
* Size in bytes to size in clusters (rounded upwards).
*/
static
uint32_t
bytes2clusters
(
const
struct
exfat
*
ef
,
uint64_t
bytes
)
{
uint64_t
cluster_size
=
CLUSTER_SIZE
(
*
ef
->
sb
);
return
DIV_ROUND_UP
(
bytes
,
cluster_size
);
}
cluster_t
exfat_next_cluster
(
const
struct
exfat
*
ef
,
const
struct
exfat_node
*
node
,
cluster_t
cluster
)
{
le32_t
next
;
off_t
fat_offset
;
if
(
cluster
<
EXFAT_FIRST_DATA_CLUSTER
)
exfat_bug
(
"bad cluster 0x%x"
,
cluster
);
if
(
node
->
is_contiguous
)
return
cluster
+
1
;
fat_offset
=
s2o
(
ef
,
le32_to_cpu
(
ef
->
sb
->
fat_sector_start
))
+
cluster
*
sizeof
(
cluster_t
);
if
(
exfat_pread
(
ef
->
dev
,
&
next
,
sizeof
(
next
),
fat_offset
)
<
0
)
return
EXFAT_CLUSTER_BAD
;
/* the caller should handle this and print
appropriate error message */
return
le32_to_cpu
(
next
);
}
cluster_t
exfat_advance_cluster
(
const
struct
exfat
*
ef
,
struct
exfat_node
*
node
,
uint32_t
count
)
{
uint32_t
i
;
if
(
node
->
fptr_index
>
count
)
{
node
->
fptr_index
=
0
;
node
->
fptr_cluster
=
node
->
start_cluster
;
}
for
(
i
=
node
->
fptr_index
;
i
<
count
;
i
++
)
{
node
->
fptr_cluster
=
exfat_next_cluster
(
ef
,
node
,
node
->
fptr_cluster
);
if
(
CLUSTER_INVALID
(
*
ef
->
sb
,
node
->
fptr_cluster
))
break
;
/* the caller should handle this and print appropriate
error message */
}
node
->
fptr_index
=
count
;
return
node
->
fptr_cluster
;
}
static
cluster_t
find_bit_and_set
(
bitmap_t
*
bitmap
,
size_t
start
,
size_t
end
)
{
const
size_t
start_index
=
start
/
sizeof
(
bitmap_t
)
/
8
;
const
size_t
end_index
=
DIV_ROUND_UP
(
end
,
sizeof
(
bitmap_t
)
*
8
);
size_t
i
;
size_t
start_bitindex
;
size_t
end_bitindex
;
size_t
c
;
for
(
i
=
start_index
;
i
<
end_index
;
i
++
)
{
if
(
bitmap
[
i
]
==
~
((
bitmap_t
)
0
))
continue
;
start_bitindex
=
MAX
(
i
*
sizeof
(
bitmap_t
)
*
8
,
start
);
end_bitindex
=
MIN
((
i
+
1
)
*
sizeof
(
bitmap_t
)
*
8
,
end
);
for
(
c
=
start_bitindex
;
c
<
end_bitindex
;
c
++
)
if
(
BMAP_GET
(
bitmap
,
c
)
==
0
)
{
BMAP_SET
(
bitmap
,
c
);
return
c
+
EXFAT_FIRST_DATA_CLUSTER
;
}
}
return
EXFAT_CLUSTER_END
;
}
static
int
flush_nodes
(
struct
exfat
*
ef
,
struct
exfat_node
*
node
)
{
struct
exfat_node
*
p
;
for
(
p
=
node
->
child
;
p
!=
NULL
;
p
=
p
->
next
)
{
int
rc
=
flush_nodes
(
ef
,
p
);
if
(
rc
!=
0
)
return
rc
;
}
return
exfat_flush_node
(
ef
,
node
);
}
int
exfat_flush_nodes
(
struct
exfat
*
ef
)
{
return
flush_nodes
(
ef
,
ef
->
root
);
}
int
exfat_flush
(
struct
exfat
*
ef
)
{
if
(
ef
->
cmap
.
dirty
)
{
if
(
exfat_pwrite
(
ef
->
dev
,
ef
->
cmap
.
chunk
,
BMAP_SIZE
(
ef
->
cmap
.
chunk_size
),
exfat_c2o
(
ef
,
ef
->
cmap
.
start_cluster
))
<
0
)
{
exfat_error
(
"failed to write clusters bitmap"
);
return
-
EIO
;
}
ef
->
cmap
.
dirty
=
false
;
}
return
0
;
}
static
bool
set_next_cluster
(
const
struct
exfat
*
ef
,
bool
contiguous
,
cluster_t
current
,
cluster_t
next
)
{
off_t
fat_offset
;
le32_t
next_le32
;
if
(
contiguous
)
return
true
;
fat_offset
=
s2o
(
ef
,
le32_to_cpu
(
ef
->
sb
->
fat_sector_start
))
+
current
*
sizeof
(
cluster_t
);
next_le32
=
cpu_to_le32
(
next
);
if
(
exfat_pwrite
(
ef
->
dev
,
&
next_le32
,
sizeof
(
next_le32
),
fat_offset
)
<
0
)
{
exfat_error
(
"failed to write the next cluster %#x after %#x"
,
next
,
current
);
return
false
;
}
return
true
;
}
static
cluster_t
allocate_cluster
(
struct
exfat
*
ef
,
cluster_t
hint
)
{
cluster_t
cluster
;
hint
-=
EXFAT_FIRST_DATA_CLUSTER
;
if
(
hint
>=
ef
->
cmap
.
chunk_size
)
hint
=
0
;
cluster
=
find_bit_and_set
(
ef
->
cmap
.
chunk
,
hint
,
ef
->
cmap
.
chunk_size
);
if
(
cluster
==
EXFAT_CLUSTER_END
)
cluster
=
find_bit_and_set
(
ef
->
cmap
.
chunk
,
0
,
hint
);
if
(
cluster
==
EXFAT_CLUSTER_END
)
{
exfat_error
(
"no free space left"
);
return
EXFAT_CLUSTER_END
;
}
ef
->
cmap
.
dirty
=
true
;
return
cluster
;
}
static
void
free_cluster
(
struct
exfat
*
ef
,
cluster_t
cluster
)
{
if
(
cluster
-
EXFAT_FIRST_DATA_CLUSTER
>=
ef
->
cmap
.
size
)
exfat_bug
(
"caller must check cluster validity (%#x, %#x)"
,
cluster
,
ef
->
cmap
.
size
);
BMAP_CLR
(
ef
->
cmap
.
chunk
,
cluster
-
EXFAT_FIRST_DATA_CLUSTER
);
ef
->
cmap
.
dirty
=
true
;
}
static
bool
make_noncontiguous
(
const
struct
exfat
*
ef
,
cluster_t
first
,
cluster_t
last
)
{
cluster_t
c
;
for
(
c
=
first
;
c
<
last
;
c
++
)
if
(
!
set_next_cluster
(
ef
,
false
,
c
,
c
+
1
))
return
false
;
return
true
;
}
static
int
shrink_file
(
struct
exfat
*
ef
,
struct
exfat_node
*
node
,
uint32_t
current
,
uint32_t
difference
);
static
int
grow_file
(
struct
exfat
*
ef
,
struct
exfat_node
*
node
,
uint32_t
current
,
uint32_t
difference
)
{
cluster_t
previous
;
cluster_t
next
;
uint32_t
allocated
=
0
;
if
(
difference
==
0
)
exfat_bug
(
"zero clusters count passed"
);
if
(
node
->
start_cluster
!=
EXFAT_CLUSTER_FREE
)
{
/* get the last cluster of the file */
previous
=
exfat_advance_cluster
(
ef
,
node
,
current
-
1
);
if
(
CLUSTER_INVALID
(
*
ef
->
sb
,
previous
))
{
exfat_error
(
"invalid cluster 0x%x while growing"
,
previous
);
return
-
EIO
;
}
}
else
{
if
(
node
->
fptr_index
!=
0
)
exfat_bug
(
"non-zero pointer index (%u)"
,
node
->
fptr_index
);
/* file does not have clusters (i.e. is empty), allocate
the first one for it */
previous
=
allocate_cluster
(
ef
,
0
);
if
(
CLUSTER_INVALID
(
*
ef
->
sb
,
previous
))
return
-
ENOSPC
;
node
->
fptr_cluster
=
node
->
start_cluster
=
previous
;
allocated
=
1
;
/* file consists of only one cluster, so it's contiguous */
node
->
is_contiguous
=
true
;
}
while
(
allocated
<
difference
)
{
next
=
allocate_cluster
(
ef
,
previous
+
1
);
if
(
CLUSTER_INVALID
(
*
ef
->
sb
,
next
))
{
if
(
allocated
!=
0
)
shrink_file
(
ef
,
node
,
current
+
allocated
,
allocated
);
return
-
ENOSPC
;
}
if
(
next
!=
previous
-
1
&&
node
->
is_contiguous
)
{
/* it's a pity, but we are not able to keep the file contiguous
anymore */
if
(
!
make_noncontiguous
(
ef
,
node
->
start_cluster
,
previous
))
return
-
EIO
;
node
->
is_contiguous
=
false
;
node
->
is_dirty
=
true
;
}
if
(
!
set_next_cluster
(
ef
,
node
->
is_contiguous
,
previous
,
next
))
return
-
EIO
;
previous
=
next
;
allocated
++
;
}
if
(
!
set_next_cluster
(
ef
,
node
->
is_contiguous
,
previous
,
EXFAT_CLUSTER_END
))
return
-
EIO
;
return
0
;
}
static
int
shrink_file
(
struct
exfat
*
ef
,
struct
exfat_node
*
node
,
uint32_t
current
,
uint32_t
difference
)
{
cluster_t
previous
;
cluster_t
next
;
if
(
difference
==
0
)
exfat_bug
(
"zero difference passed"
);
if
(
node
->
start_cluster
==
EXFAT_CLUSTER_FREE
)
exfat_bug
(
"unable to shrink empty file (%u clusters)"
,
current
);
if
(
current
<
difference
)
exfat_bug
(
"file underflow (%u < %u)"
,
current
,
difference
);
/* crop the file */
if
(
current
>
difference
)
{
cluster_t
last
=
exfat_advance_cluster
(
ef
,
node
,
current
-
difference
-
1
);
if
(
CLUSTER_INVALID
(
*
ef
->
sb
,
last
))
{
exfat_error
(
"invalid cluster 0x%x while shrinking"
,
last
);
return
-
EIO
;
}
previous
=
exfat_next_cluster
(
ef
,
node
,
last
);
if
(
!
set_next_cluster
(
ef
,
node
->
is_contiguous
,
last
,
EXFAT_CLUSTER_END
))
return
-
EIO
;
}
else
{
previous
=
node
->
start_cluster
;
node
->
start_cluster
=
EXFAT_CLUSTER_FREE
;
node
->
is_dirty
=
true
;
}
node
->
fptr_index
=
0
;
node
->
fptr_cluster
=
node
->
start_cluster
;
/* free remaining clusters */
while
(
difference
--
)
{
if
(
CLUSTER_INVALID
(
*
ef
->
sb
,
previous
))
{
exfat_error
(
"invalid cluster 0x%x while freeing after shrink"
,
previous
);
return
-
EIO
;
}
next
=
exfat_next_cluster
(
ef
,
node
,
previous
);
if
(
!
set_next_cluster
(
ef
,
node
->
is_contiguous
,
previous
,
EXFAT_CLUSTER_FREE
))
return
-
EIO
;
free_cluster
(
ef
,
previous
);
previous
=
next
;
}
return
0
;
}
static
bool
erase_raw
(
struct
exfat
*
ef
,
size_t
size
,
off_t
offset
)
{
if
(
exfat_pwrite
(
ef
->
dev
,
ef
->
zero_cluster
,
size
,
offset
)
<
0
)
{
exfat_error
(
"failed to erase %zu bytes at %"
PRId64
,
size
,
offset
);
return
false
;
}
return
true
;
}
static
int
erase_range
(
struct
exfat
*
ef
,
struct
exfat_node
*
node
,
uint64_t
begin
,
uint64_t
end
)
{
uint64_t
cluster_boundary
;
cluster_t
cluster
;
if
(
begin
>=
end
)
return
0
;
cluster_boundary
=
(
begin
|
(
CLUSTER_SIZE
(
*
ef
->
sb
)
-
1
))
+
1
;
cluster
=
exfat_advance_cluster
(
ef
,
node
,
begin
/
CLUSTER_SIZE
(
*
ef
->
sb
));
if
(
CLUSTER_INVALID
(
*
ef
->
sb
,
cluster
))
{
exfat_error
(
"invalid cluster 0x%x while erasing"
,
cluster
);
return
-
EIO
;
}
/* erase from the beginning to the closest cluster boundary */
if
(
!
erase_raw
(
ef
,
MIN
(
cluster_boundary
,
end
)
-
begin
,
exfat_c2o
(
ef
,
cluster
)
+
begin
%
CLUSTER_SIZE
(
*
ef
->
sb
)))
return
-
EIO
;
/* erase whole clusters */
while
(
cluster_boundary
<
end
)
{
cluster
=
exfat_next_cluster
(
ef
,
node
,
cluster
);
/* the cluster cannot be invalid because we have just allocated it */
if
(
CLUSTER_INVALID
(
*
ef
->
sb
,
cluster
))
exfat_bug
(
"invalid cluster 0x%x after allocation"
,
cluster
);
if
(
!
erase_raw
(
ef
,
CLUSTER_SIZE
(
*
ef
->
sb
),
exfat_c2o
(
ef
,
cluster
)))
return
-
EIO
;
cluster_boundary
+=
CLUSTER_SIZE
(
*
ef
->
sb
);
}
return
0
;
}
int
exfat_truncate
(
struct
exfat
*
ef
,
struct
exfat_node
*
node
,
uint64_t
size
,
bool
erase
)
{
uint32_t
c1
=
bytes2clusters
(
ef
,
node
->
size
);
uint32_t
c2
=
bytes2clusters
(
ef
,
size
);
int
rc
=
0
;
if
(
node
->
references
==
0
&&
node
->
parent
)
exfat_bug
(
"no references, node changes can be lost"
);
if
(
node
->
size
==
size
)
return
0
;
if
(
c1
<
c2
)
rc
=
grow_file
(
ef
,
node
,
c1
,
c2
-
c1
);
else
if
(
c1
>
c2
)
rc
=
shrink_file
(
ef
,
node
,
c1
,
c1
-
c2
);
if
(
rc
!=
0
)
return
rc
;
if
(
erase
)
{
rc
=
erase_range
(
ef
,
node
,
node
->
size
,
size
);
if
(
rc
!=
0
)
return
rc
;
}
exfat_update_mtime
(
node
);
node
->
size
=
size
;
node
->
is_dirty
=
true
;
return
0
;
}
uint32_t
exfat_count_free_clusters
(
const
struct
exfat
*
ef
)
{
uint32_t
free_clusters
=
0
;
uint32_t
i
;
for
(
i
=
0
;
i
<
ef
->
cmap
.
size
;
i
++
)
if
(
BMAP_GET
(
ef
->
cmap
.
chunk
,
i
)
==
0
)
free_clusters
++
;
return
free_clusters
;
}
static
int
find_used_clusters
(
const
struct
exfat
*
ef
,
cluster_t
*
a
,
cluster_t
*
b
)
{
const
cluster_t
end
=
le32_to_cpu
(
ef
->
sb
->
cluster_count
);
/* find first used cluster */
for
(
*
a
=
*
b
+
1
;
*
a
<
end
;
(
*
a
)
++
)
if
(
BMAP_GET
(
ef
->
cmap
.
chunk
,
*
a
-
EXFAT_FIRST_DATA_CLUSTER
))
break
;
if
(
*
a
>=
end
)
return
1
;
/* find last contiguous used cluster */
for
(
*
b
=
*
a
;
*
b
<
end
;
(
*
b
)
++
)
if
(
BMAP_GET
(
ef
->
cmap
.
chunk
,
*
b
-
EXFAT_FIRST_DATA_CLUSTER
)
==
0
)
{
(
*
b
)
--
;
break
;
}
return
0
;
}
int
exfat_find_used_sectors
(
const
struct
exfat
*
ef
,
off_t
*
a
,
off_t
*
b
)
{
cluster_t
ca
,
cb
;
if
(
*
a
==
0
&&
*
b
==
0
)
ca
=
cb
=
EXFAT_FIRST_DATA_CLUSTER
-
1
;
else
{
ca
=
s2c
(
ef
,
*
a
);
cb
=
s2c
(
ef
,
*
b
);
}
if
(
find_used_clusters
(
ef
,
&
ca
,
&
cb
)
!=
0
)
return
1
;
if
(
*
a
!=
0
||
*
b
!=
0
)
*
a
=
c2s
(
ef
,
ca
);
*
b
=
c2s
(
ef
,
cb
)
+
(
CLUSTER_SIZE
(
*
ef
->
sb
)
-
1
)
/
SECTOR_SIZE
(
*
ef
->
sb
);
return
0
;
}
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h
0 → 100644
View file @
43e8ec57
/*
compiler.h (09.06.13)
Compiler-specific definitions. Note that unknown compiler is not a
showstopper.
Free exFAT implementation.
Copyright (C) 2010-2018 Andrew Nayenko
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 2 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, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef COMPILER_H_INCLUDED
#define COMPILER_H_INCLUDED
#if __STDC_VERSION__ < 199901L
#error C99-compliant compiler is required
#endif
#if defined(__clang__)
#define PRINTF __attribute__((format(printf, 1, 2)))
#define NORETURN __attribute__((noreturn))
#define PACKED __attribute__((packed))
#if __has_extension(c_static_assert)
#define USE_C11_STATIC_ASSERT
#endif
#elif defined(__GNUC__)
#define PRINTF __attribute__((format(printf, 1, 2)))
#define NORETURN __attribute__((noreturn))
#define PACKED __attribute__((packed))
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#define USE_C11_STATIC_ASSERT
#endif
#else
#define PRINTF
#define NORETURN
#define PACKED
#endif
#ifdef USE_C11_STATIC_ASSERT
#define STATIC_ASSERT(cond) _Static_assert(cond, #cond)
#else
#define CONCAT2(a, b) a ## b
#define CONCAT1(a, b) CONCAT2(a, b)
#define STATIC_ASSERT(cond) \
extern void CONCAT1(static_assert, __LINE__)(int x[(cond) ? 1 : -1])
#endif
#endif
/* ifndef COMPILER_H_INCLUDED */
LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/config.h
0 → 100644
View file @
43e8ec57
/* libexfat/config.h. Generated from config.h.in by configure. */
/* libexfat/config.h.in. Generated from configure.ac by autoheader. */
/* Name of package */
#define PACKAGE "exfat"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "relan@users.noreply.github.com"
/* Define to the full name of this package. */
#define PACKAGE_NAME "Free exFAT implementation"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "Free exFAT implementation 1.3.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "exfat"
/* Define to the home page for this package. */
#define PACKAGE_URL "https://github.com/relan/exfat"
/* Define to the version of this package. */
#define PACKAGE_VERSION "1.3.0"
/* Define if block devices are not supported. */
/* #undef USE_UBLIO */
/* Version number of package */
#define VERSION "1.3.0"
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
/* #undef _FILE_OFFSET_BITS */
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */
Prev
1
2
3
4
5
…
8
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment