mirror of
https://github.com/ventoy/Ventoy.git
synced 2025-08-27 16:01:14 +00:00
1.0.66 release
This commit is contained in:
271
Vlnk/VentoyVlnk.sh
Normal file
271
Vlnk/VentoyVlnk.sh
Normal file
@@ -0,0 +1,271 @@
|
||||
#!/bin/sh
|
||||
|
||||
print_usage() {
|
||||
echo 'Usage: sudo sh VentoyVlnk.sh CMD FILE'
|
||||
echo ' CMD:'
|
||||
echo ' -c FILE create vlnk for FILE'
|
||||
echo ' -l VLNK parse vlnk file'
|
||||
echo ' -v print verbose info'
|
||||
echo ' -h print this help'
|
||||
echo ''
|
||||
}
|
||||
|
||||
verbose_flag=0
|
||||
|
||||
vlog() {
|
||||
if [ $verbose_flag -eq 1 ]; then
|
||||
echo "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
vlnk_suffix() {
|
||||
echo $1 | egrep -q '.*(.vlnk.iso|.vlnk.img|.vlnk.wim|.vlnk.vhd|.vlnk.vhdx|.vlnk.efi|.vlnk.vtoy|.vlnk.dat)$'
|
||||
}
|
||||
|
||||
|
||||
uid=$(id -u)
|
||||
if [ $uid -ne 0 ]; then
|
||||
echo "Please use sudo or run the script as root."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#check system tools used bellow
|
||||
for t in 'mountpoint' 'readlink' 'xzcat'; do
|
||||
if ! which "$t" > /dev/null 2>&1; then
|
||||
echo "$t command not found in current system!"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
machine=$(uname -m)
|
||||
if echo $machine | egrep -q 'aarch64|arm64'; then
|
||||
TOOLDIR=aarch64
|
||||
elif echo $machine | egrep -q 'x86_64|amd64'; then
|
||||
TOOLDIR=x86_64
|
||||
elif echo $machine | egrep -q 'mips64'; then
|
||||
TOOLDIR=mips64el
|
||||
elif echo $machine | egrep -q 'i[3-6]86'; then
|
||||
TOOLDIR=i386
|
||||
else
|
||||
echo "Unsupported machine type $machine"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
fullsh=$(readlink -f "$0")
|
||||
vtoydir=${fullsh%/*}
|
||||
|
||||
if [ -f "$vtoydir/tool/$TOOLDIR/vlnk.xz" ]; then
|
||||
xzcat "$vtoydir/tool/$TOOLDIR/vlnk.xz" > "$vtoydir/tool/$TOOLDIR/vlnk"
|
||||
rm -f "$vtoydir/tool/$TOOLDIR/vlnk.xz"
|
||||
fi
|
||||
|
||||
if [ -f "$vtoydir/tool/$TOOLDIR/vlnk" ]; then
|
||||
chmod +x "$vtoydir/tool/$TOOLDIR/vlnk"
|
||||
else
|
||||
echo "$vtoydir/tool/$TOOLDIR/vlnk does not exist! "
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PATH="$vtoydir/tool/$TOOLDIR":$PATH
|
||||
|
||||
VLNKCMD=vlnk
|
||||
while [ -n "$1" ]; do
|
||||
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
|
||||
print_usage
|
||||
exit 0
|
||||
elif [ "$1" = "-c" ]; then
|
||||
shift
|
||||
CMD='c'
|
||||
IMG="$1"
|
||||
elif [ "$1" = "-o" ]; then
|
||||
shift
|
||||
OUT="$1"
|
||||
elif [ "$1" = "-l" ]; then
|
||||
shift
|
||||
CMD='l'
|
||||
VLNK="$1"
|
||||
elif [ "$1" = "-v" ]; then
|
||||
verbose_flag=1
|
||||
VLNKCMD="vlnk -v"
|
||||
else
|
||||
echo "invalid option $1"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
shift
|
||||
done
|
||||
|
||||
if [ "$CMD" = "c" ]; then
|
||||
vlog "Create vlnk for $IMG"
|
||||
|
||||
if [ ! -f "$IMG" ]; then
|
||||
echo "$IMG does not exist!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if echo $IMG | egrep -q -i '.*(.iso|.img|.wim|.vhd|.vhdx|.efi|.vtoy|.dat)$'; then
|
||||
:
|
||||
else
|
||||
echo "This file is not supported for vlnk!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if vlnk_suffix "$IMG"; then
|
||||
echo "This is already a vlnk file!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if $VLNKCMD -t "$IMG"; then
|
||||
echo "This is already a vlnk file!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
FULLIMG=$(readlink -f "$IMG")
|
||||
if [ ! -f "$FULLIMG" ]; then
|
||||
echo "$FULLIMG does not exist!"
|
||||
exit 1
|
||||
fi
|
||||
vlog "Full file path is $FULLIMG"
|
||||
|
||||
|
||||
#check img file position is a valid mountpoint
|
||||
FULLDIR=${FULLIMG%/*}
|
||||
while [ -n "${FULLDIR}" ]; do
|
||||
if mountpoint -q "${FULLDIR}"; then
|
||||
break
|
||||
fi
|
||||
FULLDIR="${FULLDIR%/*}"
|
||||
done
|
||||
|
||||
if [ -z "${FULLDIR}" ]; then
|
||||
FULLDIR=/
|
||||
IMGPATH="${FULLIMG}"
|
||||
else
|
||||
IMGPATH="${FULLIMG#$FULLDIR}"
|
||||
fi
|
||||
|
||||
IMGFILE=$(basename "$IMGPATH")
|
||||
vlog "IMGPATH=$IMGPATH IMGFILE=$IMGFILE"
|
||||
|
||||
|
||||
mntdev=$(mountpoint -d "${FULLDIR}")
|
||||
vlog "mountpoint is ${FULLDIR} dev $mntdev"
|
||||
|
||||
#check fs
|
||||
if grep -q " ${FULLDIR} " /proc/mounts; then
|
||||
FS=$(grep " ${FULLDIR} " /proc/mounts | awk '{print $3}')
|
||||
vlog "File system is $FS"
|
||||
|
||||
if echo $FS | egrep -q "ext2|ext3|ext4|exfat|vfat|fat32|fat16|fat12|ntfs|xfs|udf"; then
|
||||
vlog "FS OK"
|
||||
else
|
||||
echo "$FS is not supported!"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "${FULLDIR} not found in /proc/mounts"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
Major=$(echo $mntdev | awk -F: '{print $1}')
|
||||
Minor=$(echo $mntdev | awk -F: '{print $2}')
|
||||
vlog "Major=$Major Minor=$Minor"
|
||||
|
||||
IMGPARTITION=""
|
||||
while read line; do
|
||||
M1=$(echo $line | awk '{print $1}')
|
||||
M2=$(echo $line | awk '{print $2}')
|
||||
if [ "$Major" = "$M1" -a "$Minor" = "$M2" ]; then
|
||||
IMGPARTITION=$(echo $line | awk '{print $4}')
|
||||
vlog "disk partition is $IMGPARTITION"
|
||||
break
|
||||
fi
|
||||
done < /proc/partitions
|
||||
|
||||
if [ -z "$IMGPARTITION" ]; then
|
||||
echo "Disk partition not found for $FULLDIR"
|
||||
grep " $FULLDIR " /proc/mounts
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f "/sys/class/block/$IMGPARTITION/start" ]; then
|
||||
PARTSTART=$(cat "/sys/class/block/$IMGPARTITION/start")
|
||||
if echo $IMGPARTITION | egrep -q 'mmc|nbd|nvme'; then
|
||||
DISK=$(echo /dev/$IMGPARTITION | sed "s/^\(.*\)p[0-9][0-9]*$/\1/")
|
||||
else
|
||||
DISK=$(echo /dev/$IMGPARTITION | sed "s/^\(.*[^0-9]\)[0-9][0-9]*$/\1/")
|
||||
fi
|
||||
|
||||
if [ ! -b $DISK ]; then
|
||||
echo "Device $DISK not exist!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
vlog "PARTSTART=$PARTSTART DISK=$DISK"
|
||||
else
|
||||
if echo $IMGPARTITION | grep -q '^dm-[0-9][0-9]*'; then
|
||||
echo "LVM/DM is not supported!"
|
||||
fi
|
||||
echo "/sys/class/block/$IMGPARTITION/start not exist!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
if [ -n "$OUT" ]; then
|
||||
lowersuffix=$(echo ${IMG##*.} | tr 'A-Z' 'a-z')
|
||||
OUT="${OUT}.vlnk.${lowersuffix}"
|
||||
else
|
||||
name=${IMGFILE%.*}
|
||||
lowersuffix=$(echo ${IMGFILE##*.} | tr 'A-Z' 'a-z')
|
||||
OUT="${name}.vlnk.${lowersuffix}"
|
||||
fi
|
||||
|
||||
echo "Output VLNK file is $OUT"
|
||||
[ -f "${OUT}" ] && rm -f "${OUT}"
|
||||
|
||||
touch "${OUT}"
|
||||
if [ -f "${OUT}" ]; then
|
||||
rm -f "${OUT}"
|
||||
else
|
||||
echo "Failed to create ${OUT}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if $VLNKCMD -c "$IMGPATH" -d $DISK -p $PARTSTART -o "${OUT}"; then
|
||||
echo "====== Vlnk file create success ========="
|
||||
echo ""
|
||||
else
|
||||
echo "====== Vlnk file create failed ========="
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
elif [ "$CMD" = "l" ]; then
|
||||
vlog "Parse vlnk for $VLNK"
|
||||
|
||||
if [ ! -f "$VLNK" ]; then
|
||||
echo "$VLNK does not exist!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if vlnk_suffix "$VLNK"; then
|
||||
:
|
||||
else
|
||||
echo "Invalid vlnk file suffix!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if $VLNKCMD -t "$VLNK"; then
|
||||
vlog "Vlnk data check OK"
|
||||
else
|
||||
echo "This is not a valid vlnk file!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
$VLNKCMD -l "$VLNK"
|
||||
echo ""
|
||||
else
|
||||
echo "invalid cmd"
|
||||
print_usage
|
||||
exit 1
|
||||
fi
|
32
Vlnk/build.sh
Normal file
32
Vlnk/build.sh
Normal file
@@ -0,0 +1,32 @@
|
||||
#!/bin/sh
|
||||
|
||||
rm -f vlnk_64
|
||||
rm -f vlnk_32
|
||||
rm -f vlnk_aa64
|
||||
rm -f vlnk_m64e
|
||||
|
||||
SRCS="src/crc32.c src/main_linux.c src/vlnk.c"
|
||||
|
||||
gcc -specs "/usr/local/musl/lib/musl-gcc.specs" -Os -static -D_FILE_OFFSET_BITS=64 $SRCS -Isrc -o vlnk_64
|
||||
|
||||
/opt/diet32/bin/diet -Os gcc -D_FILE_OFFSET_BITS=64 -m32 -static $SRCS -Isrc -o vlnk_32
|
||||
|
||||
aarch64-buildroot-linux-uclibc-gcc -static -O2 -D_FILE_OFFSET_BITS=64 $SRCS -Isrc -o vlnk_aa64
|
||||
mips64el-linux-musl-gcc -mips64r2 -mabi=64 -static -O2 -D_FILE_OFFSET_BITS=64 $SRCS -Isrc -o vlnk_m64e
|
||||
|
||||
if [ -e vlnk_64 ] && [ -e vlnk_32 ] && [ -e vlnk_aa64 ] && [ -e vlnk_m64e ]; then
|
||||
echo -e "\n===== success =======\n"
|
||||
|
||||
strip --strip-all vlnk_32
|
||||
strip --strip-all vlnk_64
|
||||
aarch64-buildroot-linux-uclibc-strip --strip-all vlnk_aa64
|
||||
mips64el-linux-musl-strip --strip-all vlnk_m64e
|
||||
|
||||
[ -d ../INSTALL/tool/i386/ ] && mv vlnk_32 ../INSTALL/tool/i386/vlnk
|
||||
[ -d ../INSTALL/tool/x86_64/ ] && mv vlnk_64 ../INSTALL/tool/x86_64/vlnk
|
||||
[ -d ../INSTALL/tool/aarch64/ ] && mv vlnk_aa64 ../INSTALL/tool/aarch64/vlnk
|
||||
[ -d ../INSTALL/tool/mips64el/ ] && mv vlnk_m64e ../INSTALL/tool/mips64el/vlnk
|
||||
else
|
||||
echo -e "\n===== failed =======\n"
|
||||
exit 1
|
||||
fi
|
7
Vlnk/pack.sh
Normal file
7
Vlnk/pack.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
rm -f ../INSTALL/VentoyVlnk.sh
|
||||
cp -a ./VentoyVlnk.sh ../INSTALL/VentoyVlnk.sh
|
||||
|
||||
rm -f ../INSTALL/VentoyVlnk.exe
|
||||
cp -a ./vs/VentoyVlnk/Release/VentoyVlnk.exe ../INSTALL/VentoyVlnk.exe
|
77
Vlnk/src/crc32.c
Normal file
77
Vlnk/src/crc32.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/******************************************************************************
|
||||
* crc32.c ----
|
||||
*
|
||||
* Copyright (c) 2022, 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 "vlnk.h"
|
||||
|
||||
static uint32_t crc32c_table [256];
|
||||
|
||||
/* Helper for init_crc32c_table. */
|
||||
static uint32_t reflect (uint32_t ref, int len)
|
||||
{
|
||||
uint32_t result = 0;
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= len; i++)
|
||||
{
|
||||
if (ref & 1)
|
||||
result |= 1 << (len - i);
|
||||
ref >>= 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void init_crc32c_table (void)
|
||||
{
|
||||
uint32_t polynomial = 0x1edc6f41;
|
||||
int i, j;
|
||||
|
||||
for(i = 0; i < 256; i++)
|
||||
{
|
||||
crc32c_table[i] = reflect(i, 8) << 24;
|
||||
for (j = 0; j < 8; j++)
|
||||
crc32c_table[i] = (crc32c_table[i] << 1) ^
|
||||
(crc32c_table[i] & (1 << 31) ? polynomial : 0);
|
||||
crc32c_table[i] = reflect(crc32c_table[i], 32);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ventoy_getcrc32c (uint32_t crc, const void *buf, int size)
|
||||
{
|
||||
int i;
|
||||
const uint8_t *data = buf;
|
||||
|
||||
if (! crc32c_table[1])
|
||||
init_crc32c_table ();
|
||||
|
||||
crc^= 0xffffffff;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
crc = (crc >> 8) ^ crc32c_table[(crc & 0xFF) ^ *data];
|
||||
data++;
|
||||
}
|
||||
|
||||
return crc ^ 0xffffffff;
|
||||
}
|
||||
|
457
Vlnk/src/main_linux.c
Normal file
457
Vlnk/src/main_linux.c
Normal file
@@ -0,0 +1,457 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/statfs.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "vlnk.h"
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 4096
|
||||
#endif
|
||||
|
||||
#define IS_DIGIT(x) ((x) >= '0' && (x) <= '9')
|
||||
|
||||
static int verbose = 0;
|
||||
#define debug(fmt, args...) if(verbose) printf(fmt, ##args)
|
||||
|
||||
static uint8_t g_vlnk_buf[VLNK_FILE_LEN];
|
||||
|
||||
static int64_t get_file_size(char *file)
|
||||
{
|
||||
struct stat stStat;
|
||||
|
||||
if (stat(file, &stStat) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int64_t)(stStat.st_size);
|
||||
}
|
||||
|
||||
static int get_disk_sig(char *diskname, uint32_t *sig)
|
||||
{
|
||||
int fd;
|
||||
uint8_t buf[512] = {0};
|
||||
|
||||
fd = open(diskname, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
printf("Failed to open %s\n", diskname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
read(fd, buf, 512);
|
||||
close(fd);
|
||||
|
||||
memcpy(sig, buf + 0x1b8, 4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vtoy_get_disk_guid(const char *diskname, uint8_t *vtguid, uint8_t *vtsig)
|
||||
{
|
||||
int i = 0;
|
||||
int fd = 0;
|
||||
char devdisk[128] = {0};
|
||||
|
||||
snprintf(devdisk, sizeof(devdisk) - 1, "/dev/%s", diskname);
|
||||
|
||||
fd = open(devdisk, O_RDONLY);
|
||||
if (fd >= 0)
|
||||
{
|
||||
lseek(fd, 0x180, SEEK_SET);
|
||||
read(fd, vtguid, 16);
|
||||
|
||||
lseek(fd, 0x1b8, SEEK_SET);
|
||||
read(fd, vtsig, 4);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
debug("failed to open %s %d\n", devdisk, errno);
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
|
||||
static int vtoy_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] == '-' && IS_DIGIT(name[3]))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* /dev/srX */
|
||||
if (name[0] == 's' && name[1] == 'r' && IS_DIGIT(name[2]))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int find_disk_by_sig(uint8_t *sig, char *diskname)
|
||||
{
|
||||
int rc = 0;
|
||||
int count = 0;
|
||||
DIR* dir = NULL;
|
||||
struct dirent* p = NULL;
|
||||
uint8_t vtguid[16];
|
||||
uint8_t vtsig[16];
|
||||
|
||||
dir = opendir("/sys/block");
|
||||
if (!dir)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
while ((p = readdir(dir)) != NULL)
|
||||
{
|
||||
if (!vtoy_is_possible_blkdev(p->d_name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = vtoy_get_disk_guid(p->d_name, vtguid, vtsig);
|
||||
if (rc == 0 && memcmp(vtsig, sig, 4) == 0)
|
||||
{
|
||||
sprintf(diskname, "%s", p->d_name);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static uint64_t get_part_offset(char *partname)
|
||||
{
|
||||
int fd;
|
||||
uint64_t offset;
|
||||
char buf[32] = {0};
|
||||
char path[PATH_MAX];
|
||||
|
||||
snprintf(path, PATH_MAX - 1, "/sys/class/block/%s/start", partname);
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
read(fd, buf, sizeof(buf));
|
||||
close(fd);
|
||||
|
||||
offset = (uint64_t)strtoull(buf, NULL, 10);
|
||||
offset *= 512;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int create_vlnk(char *infile, char *diskname, uint64_t partoff, char *outfile)
|
||||
{
|
||||
FILE *fp;
|
||||
int len;
|
||||
uint32_t sig = 0;
|
||||
|
||||
debug("create vlnk\n");
|
||||
|
||||
if (infile[0] == 0 || outfile[0] == 0 || diskname[0] == 0 || partoff == 0)
|
||||
{
|
||||
debug("Invalid parameters: %d %d %d %llu\n", infile[0], outfile[0], diskname[0], (unsigned long long)partoff);
|
||||
return 1;
|
||||
}
|
||||
|
||||
len = (int)strlen(infile);
|
||||
if (len >= VLNK_NAME_MAX)
|
||||
{
|
||||
printf("File name length %d is too long for vlnk!\n", len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (get_disk_sig(diskname, &sig))
|
||||
{
|
||||
printf("Failed to read disk sig\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
fp = fopen(outfile, "wb+");
|
||||
if (!fp)
|
||||
{
|
||||
printf("Failed to create file %s\n", outfile);
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(g_vlnk_buf, 0, sizeof(g_vlnk_buf));
|
||||
ventoy_create_vlnk(sig, partoff, infile, (ventoy_vlnk *)g_vlnk_buf);
|
||||
fwrite(g_vlnk_buf, 1, VLNK_FILE_LEN, fp);
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_mount_point(char *partname, char *mntpoint)
|
||||
{
|
||||
int i;
|
||||
int len;
|
||||
int rc = 1;
|
||||
FILE *fp = NULL;
|
||||
char line[PATH_MAX];
|
||||
|
||||
fp = fopen("/proc/mounts", "r");
|
||||
if (!fp)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
len = (int)strlen(partname);
|
||||
while (fgets(line, sizeof(line), fp))
|
||||
{
|
||||
if (strncmp(line, partname, len) == 0)
|
||||
{
|
||||
for (i = len; i < PATH_MAX && line[i]; i++)
|
||||
{
|
||||
if (line[i] == ' ')
|
||||
{
|
||||
line[i] = 0;
|
||||
rc = 0;
|
||||
strncpy(mntpoint, line + len, PATH_MAX - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int parse_vlnk(char *infile)
|
||||
{
|
||||
int i;
|
||||
int fd;
|
||||
int cnt;
|
||||
int pflag = 0;
|
||||
char diskname[128] = {0};
|
||||
char partname[128] = {0};
|
||||
char partpath[256] = {0};
|
||||
char mntpoint[PATH_MAX];
|
||||
ventoy_vlnk vlnk;
|
||||
|
||||
debug("parse vlnk\n");
|
||||
|
||||
if (infile[0] == 0)
|
||||
{
|
||||
debug("input file null\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
fd = open(infile, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
printf("Failed to open file %s error %d\n", infile, errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(&vlnk, 0, sizeof(vlnk));
|
||||
read(fd, &vlnk, sizeof(vlnk));
|
||||
close(fd);
|
||||
|
||||
debug("disk_signature:%08X\n", vlnk.disk_signature);
|
||||
debug("file path:<%s>\n", vlnk.filepath);
|
||||
debug("part offset: %llu\n", (unsigned long long)vlnk.part_offset);
|
||||
|
||||
cnt = find_disk_by_sig((uint8_t *)&(vlnk.disk_signature), diskname);
|
||||
if (cnt != 1)
|
||||
{
|
||||
printf("Disk in vlnk not found!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
debug("Disk is <%s>\n", diskname);
|
||||
|
||||
if (strstr(diskname, "nvme") || strstr(diskname, "mmc") || strstr(diskname, "nbd"))
|
||||
{
|
||||
pflag = 1;
|
||||
}
|
||||
|
||||
for (i = 1; i <= 128; i++)
|
||||
{
|
||||
if (pflag)
|
||||
{
|
||||
snprintf(partname, sizeof(partname) - 1, "%sp%d", diskname, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(partname, sizeof(partname) - 1, "%s%d", diskname, i);
|
||||
}
|
||||
|
||||
if (get_part_offset(partname) == vlnk.part_offset)
|
||||
{
|
||||
debug("Find correct partition </dev/%s>\n", partname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i > 128)
|
||||
{
|
||||
printf("Partition in vlnk not found!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
snprintf(partpath, sizeof(partpath), "/dev/%s ", partname);
|
||||
if (get_mount_point(partpath, mntpoint))
|
||||
{
|
||||
printf("Mountpoint of %s is not found!\n", partpath);
|
||||
return 1;
|
||||
}
|
||||
debug("moutpoint of %s is <%s>\n", partpath, mntpoint);
|
||||
|
||||
strcat(mntpoint, vlnk.filepath);
|
||||
printf("Vlnk Point: %s\n", mntpoint);
|
||||
if (access(mntpoint, F_OK) >= 0)
|
||||
{
|
||||
printf("File Exist: YES\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("File Exist: NO\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_vlnk(char *infile)
|
||||
{
|
||||
int fd;
|
||||
int64_t size;
|
||||
ventoy_vlnk vlnk;
|
||||
|
||||
debug("check vlnk\n");
|
||||
|
||||
if (infile[0] == 0)
|
||||
{
|
||||
debug("input file null\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
size = get_file_size(infile);
|
||||
if (size != VLNK_FILE_LEN)
|
||||
{
|
||||
debug("file size %lld is not a vlnk file size\n", (long long)size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fd = open(infile, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
debug("Failed to open file %s error %d\n", infile, errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(&vlnk, 0, sizeof(vlnk));
|
||||
read(fd, &vlnk, sizeof(vlnk));
|
||||
close(fd);
|
||||
|
||||
if (CheckVlnkData(&vlnk))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ch = 0;
|
||||
int cmd = 0;
|
||||
uint64_t partoff = 0;
|
||||
char infile[PATH_MAX] = {0};
|
||||
char outfile[PATH_MAX] = {0};
|
||||
char diskname[256] = {0};
|
||||
|
||||
while ((ch = getopt(argc, argv, "c:t:l:d:p:o:v::")) != -1)
|
||||
{
|
||||
if (ch == 'c')
|
||||
{
|
||||
cmd = 1;
|
||||
strncpy(infile, optarg, sizeof(infile) - 1);
|
||||
}
|
||||
else if (ch == 'o')
|
||||
{
|
||||
strncpy(outfile, optarg, sizeof(outfile) - 1);
|
||||
}
|
||||
else if (ch == 'l')
|
||||
{
|
||||
cmd = 2;
|
||||
strncpy(infile, optarg, sizeof(infile) - 1);
|
||||
}
|
||||
else if (ch == 't')
|
||||
{
|
||||
cmd = 3;
|
||||
strncpy(infile, optarg, sizeof(infile) - 1);
|
||||
}
|
||||
else if (ch == 'd')
|
||||
{
|
||||
strncpy(diskname, optarg, sizeof(diskname) - 1);
|
||||
}
|
||||
else if (ch == 'p')
|
||||
{
|
||||
partoff = (uint64_t)strtoull(optarg, NULL, 10);
|
||||
partoff *= 512;
|
||||
}
|
||||
else if (ch == 'v')
|
||||
{
|
||||
verbose = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd == 1)
|
||||
{
|
||||
return create_vlnk(infile, diskname, partoff, outfile);
|
||||
}
|
||||
else if (cmd == 2)
|
||||
{
|
||||
return parse_vlnk(infile);
|
||||
}
|
||||
else if (cmd == 3)
|
||||
{
|
||||
return check_vlnk(infile);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Invalid command %d\n", cmd);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
711
Vlnk/src/main_windows.c
Normal file
711
Vlnk/src/main_windows.c
Normal file
@@ -0,0 +1,711 @@
|
||||
#include <Windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include <resource.h>
|
||||
#include <vlnk.h>
|
||||
|
||||
static WCHAR g_CurDirW[MAX_PATH];
|
||||
static CHAR g_CurDirA[MAX_PATH];
|
||||
static CHAR g_LogFile[MAX_PATH];
|
||||
static HWND g_create_button;
|
||||
static HWND g_parse_button;
|
||||
|
||||
typedef enum MSGID
|
||||
{
|
||||
MSGID_ERROR = 0,
|
||||
MSGID_INFO,
|
||||
MSGID_BTN_CREATE,
|
||||
MSGID_BTN_PARSE,
|
||||
MSGID_SRC_UNSUPPORTED,
|
||||
MSGID_FS_UNSUPPORTED,
|
||||
MSGID_SUFFIX_UNSUPPORTED,
|
||||
MSGID_DISK_INFO_ERR,
|
||||
MSGID_VLNK_SUCCESS,
|
||||
MSGID_RUNNING_TIP,
|
||||
MSGID_CREATE_FILE_ERR,
|
||||
MSGID_ALREADY_VLNK,
|
||||
MSGID_INVALID_VLNK,
|
||||
MSGID_VLNK_POINT_TO,
|
||||
MSGID_VLNK_NO_DST,
|
||||
MSGID_FILE_NAME_TOO_LONG,
|
||||
|
||||
MSGID_BUTT
|
||||
}MSGID;
|
||||
|
||||
|
||||
const WCHAR *g_msg_cn[MSGID_BUTT] =
|
||||
{
|
||||
L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
|
||||
L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
|
||||
L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
|
||||
L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
|
||||
L"<EFBFBD><EFBFBD>֧<EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>vlnk",
|
||||
L"<EFBFBD><EFBFBD>֧<EFBFBD>ֵ<EFBFBD><EFBFBD>ļ<EFBFBD>ϵͳ",
|
||||
L"<EFBFBD><EFBFBD>֧<EFBFBD>ֵ<EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
|
||||
L"<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
|
||||
L"Vlnk <20>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD>",
|
||||
L"<EFBFBD><EFBFBD><EFBFBD>ȹر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD> VentoyVlnk <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
|
||||
L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>ʧ<EFBFBD><EFBFBD>",
|
||||
L"<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD>Ѿ<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>vlnk<EFBFBD>ļ<EFBFBD><EFBFBD>ˣ<EFBFBD>",
|
||||
L"<EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD>vlnk<EFBFBD>ļ<EFBFBD>!",
|
||||
L"<EFBFBD><EFBFBD> vlnk <20>ļ<EFBFBD>ָ<EFBFBD><D6B8> ",
|
||||
L"<EFBFBD><EFBFBD> vlnk ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD>",
|
||||
L"<EFBFBD>ļ<EFBFBD>·<EFBFBD><EFBFBD>̫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
|
||||
};
|
||||
const WCHAR *g_msg_en[MSGID_BUTT] =
|
||||
{
|
||||
L"Error",
|
||||
L"Info",
|
||||
L"Create",
|
||||
L"Parse",
|
||||
L"This file is not supported for vlnk",
|
||||
L"Unsupported file system!",
|
||||
L"Unsupported file suffix!",
|
||||
L"Error when getting disk info",
|
||||
L"Vlnk file successfully created!",
|
||||
L"Please close another running VentoyVlnk instance!",
|
||||
L"Failed to create file!",
|
||||
L"This file is already a vlnk file!",
|
||||
L"Invalid vlnk file!",
|
||||
L"The vlnk file point to ",
|
||||
L"The file pointed by the vlnk does NOT exist!",
|
||||
L"The file full path is too long!",
|
||||
};
|
||||
|
||||
const WCHAR **g_msg_lang = NULL;
|
||||
|
||||
HINSTANCE g_hInst;
|
||||
|
||||
static void Log2File(const char *log)
|
||||
{
|
||||
time_t stamp;
|
||||
struct tm ttm;
|
||||
FILE *fp;
|
||||
|
||||
time(&stamp);
|
||||
localtime_s(&ttm, &stamp);
|
||||
|
||||
fopen_s(&fp, g_LogFile, "a+");
|
||||
if (fp)
|
||||
{
|
||||
fprintf_s(fp, "[%04u/%02u/%02u %02u:%02u:%02u] %s",
|
||||
ttm.tm_year + 1900, ttm.tm_mon + 1, ttm.tm_mday,
|
||||
ttm.tm_hour, ttm.tm_min, ttm.tm_sec, log);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
void LogW(const WCHAR *Fmt, ...)
|
||||
{
|
||||
WCHAR log[512];
|
||||
CHAR alog[2048];
|
||||
va_list arg;
|
||||
|
||||
if (g_LogFile[0] == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
va_start(arg, Fmt);
|
||||
vswprintf_s(log, 512, Fmt, arg);
|
||||
va_end(arg);
|
||||
|
||||
WideCharToMultiByte(CP_UTF8, 0, log, -1, alog, 2048, 0, 0);
|
||||
|
||||
Log2File(alog);
|
||||
}
|
||||
|
||||
|
||||
void LogA(const CHAR *Fmt, ...)
|
||||
{
|
||||
CHAR log[512];
|
||||
va_list arg;
|
||||
|
||||
if (g_LogFile[0] == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
va_start(arg, Fmt);
|
||||
vsprintf_s(log, 512, Fmt, arg);
|
||||
va_end(arg);
|
||||
|
||||
Log2File(log);
|
||||
}
|
||||
|
||||
static int Utf8ToUtf16(const char* src, WCHAR * dst)
|
||||
{
|
||||
int size = MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, 0);
|
||||
return MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, size + 1);
|
||||
}
|
||||
|
||||
static BOOL OnDestroyDialog()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static BOOL InitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
HICON hIcon;
|
||||
|
||||
g_create_button = GetDlgItem(hWnd, IDC_BUTTON1);
|
||||
g_parse_button = GetDlgItem(hWnd, IDC_BUTTON2);
|
||||
|
||||
hIcon = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_ICON1));
|
||||
SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
|
||||
SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
|
||||
|
||||
SetWindowTextW(g_create_button, g_msg_lang[MSGID_BTN_CREATE]);
|
||||
SetWindowTextW(g_parse_button, g_msg_lang[MSGID_BTN_PARSE]);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int GetPhyDiskInfo(const char LogicalDrive, UINT32 *DiskSig, DISK_EXTENT *DiskExtent)
|
||||
{
|
||||
BOOL Ret;
|
||||
DWORD dwSize;
|
||||
HANDLE Handle;
|
||||
VOLUME_DISK_EXTENTS DiskExtents;
|
||||
CHAR PhyPath[128];
|
||||
UINT8 SectorBuf[512];
|
||||
|
||||
LogA("GetPhyDiskInfo %C\n", LogicalDrive);
|
||||
|
||||
sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\%C:", LogicalDrive);
|
||||
Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
|
||||
if (Handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
LogA("Could not open the disk %C: error:%u\n", LogicalDrive, GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
Ret = DeviceIoControl(Handle,
|
||||
IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
|
||||
NULL,
|
||||
0,
|
||||
&DiskExtents,
|
||||
(DWORD)(sizeof(DiskExtents)),
|
||||
(LPDWORD)&dwSize,
|
||||
NULL);
|
||||
if (!Ret || DiskExtents.NumberOfDiskExtents == 0)
|
||||
{
|
||||
LogA("DeviceIoControl IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS failed, error:%u\n", GetLastError());
|
||||
CloseHandle(Handle);
|
||||
return 1;
|
||||
}
|
||||
CloseHandle(Handle);
|
||||
|
||||
memcpy(DiskExtent, DiskExtents.Extents, sizeof(DISK_EXTENT));
|
||||
LogA("%C: is in PhysicalDrive%d Offset:%llu\n", LogicalDrive, DiskExtents.Extents[0].DiskNumber,
|
||||
(ULONGLONG)(DiskExtents.Extents[0].StartingOffset.QuadPart));
|
||||
|
||||
sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\PhysicalDrive%d", DiskExtents.Extents[0].DiskNumber);
|
||||
Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
|
||||
if (Handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
LogA("Could not open the disk<PhysicalDrive%d>, error:%u\n", DiskExtents.Extents[0].DiskNumber, GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!ReadFile(Handle, SectorBuf, sizeof(SectorBuf), &dwSize, NULL))
|
||||
{
|
||||
LogA("ReadFile failed, dwSize:%u error:%u\n", dwSize, GetLastError());
|
||||
CloseHandle(Handle);
|
||||
return 1;
|
||||
}
|
||||
|
||||
memcpy(DiskSig, SectorBuf + 0x1B8, 4);
|
||||
|
||||
CloseHandle(Handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int SaveBuffer2File(const WCHAR *Fullpath, void *Buffer, DWORD Length)
|
||||
{
|
||||
int rc = 1;
|
||||
DWORD dwSize;
|
||||
HANDLE Handle;
|
||||
|
||||
LogW(L"SaveBuffer2File <%ls> len:%u\n", Fullpath, Length);
|
||||
|
||||
Handle = CreateFileW(Fullpath, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0, 0);
|
||||
if (Handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
LogA("Could not create new file, error:%u\n", GetLastError());
|
||||
goto End;
|
||||
}
|
||||
|
||||
WriteFile(Handle, Buffer, Length, &dwSize, NULL);
|
||||
|
||||
rc = 0;
|
||||
|
||||
End:
|
||||
|
||||
if (Handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle(Handle);
|
||||
}
|
||||
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int DefaultVlnkDstFullPath(WCHAR *Src, WCHAR *Dir, WCHAR *Dst)
|
||||
{
|
||||
int i, j;
|
||||
int len;
|
||||
int wrlen;
|
||||
WCHAR C;
|
||||
|
||||
len = (int)lstrlen(Src);
|
||||
for (i = len - 1; i >= 0; i--)
|
||||
{
|
||||
if (Src[i] == '.')
|
||||
{
|
||||
C = Src[i];
|
||||
Src[i] = 0;
|
||||
wrlen = swprintf_s(Dst, MAX_PATH, L"%ls\\%ls.vlnk.%ls", Dir, Src, Src + i + 1);
|
||||
Src[i] = C;
|
||||
|
||||
for (j = wrlen - (len - i); j < wrlen; j++)
|
||||
{
|
||||
if (Dst[j] >= 'A' && Dst[j] <= 'Z')
|
||||
{
|
||||
Dst[j] = 'a' + (Dst[j] - 'A');
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static BOOL IsVlnkFile(WCHAR *path, ventoy_vlnk *outvlnk)
|
||||
{
|
||||
BOOL bRet;
|
||||
BOOL bVlnk = FALSE;
|
||||
DWORD dwSize;
|
||||
LARGE_INTEGER FileSize;
|
||||
HANDLE Handle;
|
||||
ventoy_vlnk vlnk;
|
||||
|
||||
Handle = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
|
||||
if (Handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
LogA("Could not open this file, error:%u\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!GetFileSizeEx(Handle, &FileSize))
|
||||
{
|
||||
LogA("Failed to get vlnk file size\n");
|
||||
goto End;
|
||||
}
|
||||
|
||||
if (FileSize.QuadPart != VLNK_FILE_LEN)
|
||||
{
|
||||
LogA("Invalid vlnk file length %llu\n", (unsigned long long)FileSize.QuadPart);
|
||||
goto End;
|
||||
}
|
||||
|
||||
memset(&vlnk, 0, sizeof(vlnk));
|
||||
bRet = ReadFile(Handle, &vlnk, sizeof(vlnk), &dwSize, NULL);
|
||||
if (bRet && CheckVlnkData(&vlnk))
|
||||
{
|
||||
if (outvlnk)
|
||||
{
|
||||
memcpy(outvlnk, &vlnk, sizeof(vlnk));
|
||||
}
|
||||
|
||||
bVlnk = TRUE;
|
||||
}
|
||||
|
||||
End:
|
||||
|
||||
if (Handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle(Handle);
|
||||
}
|
||||
|
||||
return bVlnk;
|
||||
}
|
||||
|
||||
|
||||
static int CreateVlnk(HWND hWnd, WCHAR *Dir)
|
||||
{
|
||||
int i;
|
||||
int end;
|
||||
int len;
|
||||
UINT32 DiskSig;
|
||||
DISK_EXTENT DiskExtend;
|
||||
OPENFILENAME ofn = { 0 };
|
||||
CHAR UTF8Path[MAX_PATH];
|
||||
WCHAR DstFullPath[MAX_PATH];
|
||||
WCHAR szFile[MAX_PATH] = { 0 };
|
||||
CHAR suffix[8] = { 0 };
|
||||
CHAR Drive[8] = { 0 };
|
||||
CHAR FsName[64] = { 0 };
|
||||
CHAR *Buf = NULL;
|
||||
WCHAR *Pos = NULL;
|
||||
ventoy_vlnk *vlnk = NULL;
|
||||
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = hWnd;
|
||||
ofn.lpstrFile = szFile;
|
||||
ofn.nMaxFile = sizeof(szFile);
|
||||
ofn.lpstrFilter = L"Vlnk Source File\0*.iso;*.img;*.wim;*.vhd;*.vhdx;*.vtoy;*.efi;*.dat\0";
|
||||
ofn.nFilterIndex = 1;
|
||||
ofn.lpstrFileTitle = NULL;
|
||||
ofn.nMaxFileTitle = 0;
|
||||
ofn.lpstrInitialDir = NULL;
|
||||
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
|
||||
|
||||
if (GetOpenFileName(&ofn) != TRUE)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
LogW(L"Create vlnk for <%ls>\n", szFile);
|
||||
|
||||
len = lstrlen(szFile);
|
||||
|
||||
if (len < 5 || szFile[0] == '.' || szFile[1] != ':')
|
||||
{
|
||||
MessageBox(hWnd, g_msg_lang[MSGID_SRC_UNSUPPORTED], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Drive[0] = (CHAR)szFile[0];
|
||||
Drive[1] = ':';
|
||||
Drive[2] = '\\';
|
||||
if (0 == GetVolumeInformationA(Drive, NULL, 0, NULL, NULL, NULL, FsName, sizeof(FsName) - 1))
|
||||
{
|
||||
LogA("GetVolumeInformationA failed %u\n", GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
LogA("Partition filesystem of <%s> is <%s>\n", Drive, FsName);
|
||||
if (_stricmp(FsName, "NTFS") == 0 ||
|
||||
_stricmp(FsName, "exFAT") == 0 ||
|
||||
_stricmp(FsName, "FAT") == 0 ||
|
||||
_stricmp(FsName, "FAT32") == 0 ||
|
||||
_stricmp(FsName, "FAT16") == 0 ||
|
||||
_stricmp(FsName, "FAT12") == 0 ||
|
||||
_stricmp(FsName, "UDF") == 0)
|
||||
{
|
||||
LogA("FS Check OK\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox(hWnd, g_msg_lang[MSGID_FS_UNSUPPORTED], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
end = (szFile[len - 5] == '.') ? 5 : 4;
|
||||
for (i = 0; i < end; i++)
|
||||
{
|
||||
suffix[i] = (CHAR)szFile[len - (end - i)];
|
||||
}
|
||||
|
||||
if (!IsSupportedImgSuffix(suffix))
|
||||
{
|
||||
MessageBox(hWnd, g_msg_lang[MSGID_SUFFIX_UNSUPPORTED], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (IsVlnkFile(szFile, NULL))
|
||||
{
|
||||
MessageBox(hWnd, g_msg_lang[MSGID_ALREADY_VLNK], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_PATH && szFile[i]; i++)
|
||||
{
|
||||
if (szFile[i] == '\\' || szFile[i] == '/')
|
||||
{
|
||||
Pos = szFile + i;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Pos)
|
||||
{
|
||||
LogA("name part not found\n");
|
||||
return 1;
|
||||
}
|
||||
LogW(L"File Name is <%ls>\n", Pos + 1);
|
||||
|
||||
memset(UTF8Path, 0, sizeof(UTF8Path));
|
||||
WideCharToMultiByte(CP_UTF8, 0, szFile + 2, -1, UTF8Path, MAX_PATH, NULL, 0);
|
||||
|
||||
for (i = 0; i < MAX_PATH && UTF8Path[i]; i++)
|
||||
{
|
||||
if (UTF8Path[i] == '\\')
|
||||
{
|
||||
UTF8Path[i] = '/';
|
||||
}
|
||||
}
|
||||
|
||||
len = (int)strlen(UTF8Path);
|
||||
if (len >= VLNK_NAME_MAX)
|
||||
{
|
||||
LogA("File name length %d overflow\n", len);
|
||||
MessageBox(hWnd, g_msg_lang[MSGID_FILE_NAME_TOO_LONG], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
DiskExtend.StartingOffset.QuadPart = 0;
|
||||
if (GetPhyDiskInfo((char)szFile[0], &DiskSig, &DiskExtend))
|
||||
{
|
||||
MessageBox(hWnd, g_msg_lang[MSGID_DISK_INFO_ERR], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Buf = malloc(VLNK_FILE_LEN);
|
||||
if (Buf)
|
||||
{
|
||||
memset(Buf, 0, VLNK_FILE_LEN);
|
||||
vlnk = (ventoy_vlnk *)Buf;
|
||||
ventoy_create_vlnk(DiskSig, (uint64_t)DiskExtend.StartingOffset.QuadPart, UTF8Path, vlnk);
|
||||
|
||||
DefaultVlnkDstFullPath(Pos + 1, Dir, DstFullPath);
|
||||
LogW(L"vlnk output file path is <%ls>\n", DstFullPath);
|
||||
|
||||
if (SaveBuffer2File(DstFullPath, Buf, VLNK_FILE_LEN) == 0)
|
||||
{
|
||||
WCHAR Msg[1024];
|
||||
|
||||
swprintf_s(Msg, 1024, L"%ls\r\n\r\n%ls", g_msg_lang[MSGID_VLNK_SUCCESS], DstFullPath + lstrlen(Dir) + 1);
|
||||
|
||||
LogW(L"Vlnk file create success <%ls>\n", DstFullPath);
|
||||
MessageBox(hWnd, Msg, g_msg_lang[MSGID_INFO], MB_OK | MB_ICONINFORMATION);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogA("Vlnk file save failed\n");
|
||||
MessageBox(hWnd, g_msg_lang[MSGID_CREATE_FILE_ERR], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
|
||||
}
|
||||
|
||||
free(Buf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static CHAR GetDriveLetter(UINT32 disksig, UINT64 PartOffset)
|
||||
{
|
||||
CHAR Letter;
|
||||
DWORD Drives;
|
||||
UINT32 Sig;
|
||||
DISK_EXTENT DiskExtent;
|
||||
|
||||
Letter = 'A';
|
||||
Drives = GetLogicalDrives();
|
||||
LogA("Logic Drives: 0x%x", Drives);
|
||||
|
||||
while (Drives)
|
||||
{
|
||||
if (Drives & 0x01)
|
||||
{
|
||||
Sig = 0;
|
||||
DiskExtent.StartingOffset.QuadPart = 0;
|
||||
if (GetPhyDiskInfo(Letter, &Sig, &DiskExtent) == 0)
|
||||
{
|
||||
if (Sig == disksig && DiskExtent.StartingOffset.QuadPart == PartOffset)
|
||||
{
|
||||
return Letter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Drives >>= 1;
|
||||
Letter++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ParseVlnk(HWND hWnd)
|
||||
{
|
||||
int i;
|
||||
CHAR Letter;
|
||||
ventoy_vlnk vlnk;
|
||||
OPENFILENAME ofn = { 0 };
|
||||
WCHAR szFile[MAX_PATH] = { 0 };
|
||||
WCHAR szDst[MAX_PATH + 2] = { 0 };
|
||||
WCHAR Msg[1024];
|
||||
CHAR *suffix = NULL;
|
||||
HANDLE hFile;
|
||||
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = hWnd;
|
||||
ofn.lpstrFile = szFile;
|
||||
ofn.nMaxFile = sizeof(szFile);
|
||||
ofn.lpstrFilter = L"Vlnk File\0*.vlnk.iso;*.vlnk.img;*.vlnk.wim;*.vlnk.efi;*.vlnk.vhd;*.vlnk.vhdx;*.vlnk.vtoy;*.vlnk.dat\0";
|
||||
ofn.nFilterIndex = 1;
|
||||
ofn.lpstrFileTitle = NULL;
|
||||
ofn.nMaxFileTitle = 0;
|
||||
ofn.lpstrInitialDir = NULL;
|
||||
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
|
||||
|
||||
if (GetOpenFileName(&ofn) != TRUE)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
LogW(L"Parse vlnk for <%ls>\n", szFile);
|
||||
|
||||
if (!IsVlnkFile(szFile, &vlnk))
|
||||
{
|
||||
MessageBox(hWnd, g_msg_lang[MSGID_INVALID_VLNK], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(vlnk.filepath) && vlnk.filepath[i]; i++)
|
||||
{
|
||||
if (vlnk.filepath[i] == '.')
|
||||
{
|
||||
suffix = vlnk.filepath + i;
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsSupportedImgSuffix(suffix))
|
||||
{
|
||||
MessageBox(hWnd, g_msg_lang[MSGID_SUFFIX_UNSUPPORTED], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Utf8ToUtf16(vlnk.filepath, szDst + 2);
|
||||
for (i = 2; i < MAX_PATH && szDst[i]; i++)
|
||||
{
|
||||
if (szDst[i] == '/')
|
||||
{
|
||||
szDst[i] = '\\';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Letter = GetDriveLetter(vlnk.disk_signature, vlnk.part_offset);
|
||||
if (Letter == 0)
|
||||
{
|
||||
MessageBox(hWnd, g_msg_lang[MSGID_VLNK_NO_DST], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
szDst[0] = toupper(Letter);
|
||||
szDst[1] = ':';
|
||||
LogW(L"vlnk dst is %ls\n", szDst);
|
||||
|
||||
hFile = CreateFileW(szDst, FILE_READ_EA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
|
||||
if (INVALID_HANDLE_VALUE == hFile)
|
||||
{
|
||||
MessageBox(hWnd, g_msg_lang[MSGID_VLNK_NO_DST], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
|
||||
return 1;
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
|
||||
swprintf_s(Msg, 1024, L"%ls %ls", g_msg_lang[MSGID_VLNK_POINT_TO], szDst);
|
||||
MessageBox(hWnd, Msg, g_msg_lang[MSGID_INFO], MB_OK | MB_ICONINFORMATION);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK DialogProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
WORD NotifyCode;
|
||||
WORD CtrlID;
|
||||
|
||||
switch (Message)
|
||||
{
|
||||
case WM_COMMAND:
|
||||
{
|
||||
NotifyCode = HIWORD(wParam);
|
||||
CtrlID = LOWORD(wParam);
|
||||
|
||||
if (NotifyCode == BN_CLICKED)
|
||||
{
|
||||
if (CtrlID == IDC_BUTTON1)
|
||||
{
|
||||
EnableWindow(g_create_button, FALSE);
|
||||
CreateVlnk(hWnd, g_CurDirW);
|
||||
EnableWindow(g_create_button, TRUE);
|
||||
}
|
||||
else if (CtrlID == IDC_BUTTON2)
|
||||
{
|
||||
EnableWindow(g_parse_button, FALSE);
|
||||
ParseVlnk(hWnd);
|
||||
EnableWindow(g_parse_button, TRUE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
InitDialog(hWnd, wParam, lParam);
|
||||
break;
|
||||
}
|
||||
case WM_CLOSE:
|
||||
{
|
||||
OnDestroyDialog();
|
||||
EndDialog(hWnd, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow)
|
||||
{
|
||||
int i;
|
||||
HANDLE hMutex;
|
||||
|
||||
UNREFERENCED_PARAMETER(hPrevInstance);
|
||||
|
||||
if (GetUserDefaultUILanguage() == 0x0804)
|
||||
{
|
||||
g_msg_lang = g_msg_cn;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_msg_lang = g_msg_en;
|
||||
}
|
||||
|
||||
hMutex = CreateMutexA(NULL, TRUE, "VtoyVlnkMUTEX");
|
||||
if ((hMutex != NULL) && (GetLastError() == ERROR_ALREADY_EXISTS))
|
||||
{
|
||||
MessageBoxW(NULL, g_msg_lang[MSGID_RUNNING_TIP], g_msg_lang[MSGID_ERROR], MB_OK | MB_ICONERROR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
GetCurrentDirectoryA(MAX_PATH, g_CurDirA);
|
||||
GetCurrentDirectoryW(MAX_PATH, g_CurDirW);
|
||||
sprintf_s(g_LogFile, sizeof(g_LogFile), "%s\\VentoyVlnk.log", g_CurDirA);
|
||||
|
||||
for (i = 0; i < __argc; i++)
|
||||
{
|
||||
if (strncmp(__argv[i], "-Q", 2) == 0 ||
|
||||
strncmp(__argv[i], "-q", 2) == 0)
|
||||
{
|
||||
g_LogFile[0] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LogA("========= VentoyVlnk =========\n");
|
||||
|
||||
g_hInst = hInstance;
|
||||
DialogBoxA(hInstance, MAKEINTRESOURCEA(IDD_DIALOG1), NULL, DialogProc);
|
||||
|
||||
return 0;
|
||||
}
|
80
Vlnk/src/vlnk.c
Normal file
80
Vlnk/src/vlnk.c
Normal file
@@ -0,0 +1,80 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "vlnk.h"
|
||||
|
||||
int ventoy_create_vlnk(uint32_t disksig, uint64_t partoffset, const char *path, ventoy_vlnk *vlnk)
|
||||
{
|
||||
uint32_t crc;
|
||||
ventoy_guid guid = VENTOY_GUID;
|
||||
|
||||
memcpy(&(vlnk->guid), &guid, sizeof(ventoy_guid));
|
||||
vlnk->disk_signature = disksig;
|
||||
vlnk->part_offset = partoffset;
|
||||
|
||||
#ifdef WIN32
|
||||
strcpy_s(vlnk->filepath, sizeof(vlnk->filepath) - 1, path);
|
||||
#else
|
||||
strncpy(vlnk->filepath, path, sizeof(vlnk->filepath) - 1);
|
||||
#endif
|
||||
|
||||
crc = ventoy_getcrc32c(0, vlnk, sizeof(ventoy_vlnk));
|
||||
vlnk->crc32 = crc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CheckVlnkData(ventoy_vlnk *vlnk)
|
||||
{
|
||||
uint32_t readcrc, calccrc;
|
||||
ventoy_guid guid = VENTOY_GUID;
|
||||
|
||||
if (memcmp(&vlnk->guid, &guid, sizeof(guid)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
readcrc = vlnk->crc32;
|
||||
vlnk->crc32 = 0;
|
||||
calccrc = ventoy_getcrc32c(0, vlnk, sizeof(ventoy_vlnk));
|
||||
|
||||
if (readcrc != calccrc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int IsSupportedImgSuffix(char *suffix)
|
||||
{
|
||||
int i = 0;
|
||||
const char *suffixs[] =
|
||||
{
|
||||
".iso", ".img", ".wim", ".efi", ".vhd", ".vhdx", ".dat", ".vtoy", NULL
|
||||
};
|
||||
|
||||
if (!suffix)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (suffixs[i])
|
||||
{
|
||||
|
||||
#ifdef WIN32
|
||||
if (_stricmp(suffixs[i], suffix) == 0)
|
||||
#else
|
||||
if (strcasecmp(suffixs[i], suffix) == 0)
|
||||
#endif
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
38
Vlnk/src/vlnk.h
Normal file
38
Vlnk/src/vlnk.h
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
#ifndef __VLNK_H__
|
||||
#define __VLNK_H__
|
||||
|
||||
#define VLNK_FILE_LEN 32768
|
||||
|
||||
#define VLNK_NAME_MAX 384
|
||||
|
||||
#define VENTOY_GUID { 0x77772020, 0x2e77, 0x6576, { 0x6e, 0x74, 0x6f, 0x79, 0x2e, 0x6e, 0x65, 0x74 }}
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct ventoy_guid
|
||||
{
|
||||
uint32_t data1;
|
||||
uint16_t data2;
|
||||
uint16_t data3;
|
||||
uint8_t data4[8];
|
||||
}ventoy_guid;
|
||||
|
||||
typedef struct ventoy_vlnk
|
||||
{
|
||||
ventoy_guid guid; // VENTOY_GUID
|
||||
uint32_t crc32; // crc32
|
||||
uint32_t disk_signature;
|
||||
uint64_t part_offset; // in bytes
|
||||
char filepath[VLNK_NAME_MAX];
|
||||
uint8_t reserverd[96];
|
||||
}ventoy_vlnk;
|
||||
#pragma pack()
|
||||
|
||||
uint32_t ventoy_getcrc32c (uint32_t crc, const void *buf, int size);
|
||||
int ventoy_create_vlnk(uint32_t disksig, uint64_t partoffset, const char *path, ventoy_vlnk *vlnk);
|
||||
int CheckVlnkData(ventoy_vlnk *vlnk);
|
||||
int IsSupportedImgSuffix(char *suffix);
|
||||
|
||||
#endif
|
||||
|
BIN
Vlnk/vs/VentoyVlnk/Release/VentoyVlnk.exe
Normal file
BIN
Vlnk/vs/VentoyVlnk/Release/VentoyVlnk.exe
Normal file
Binary file not shown.
22
Vlnk/vs/VentoyVlnk/VentoyVlnk.sln
Normal file
22
Vlnk/vs/VentoyVlnk/VentoyVlnk.sln
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.21005.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VentoyVlnk", "VentoyVlnk\VentoyVlnk.vcxproj", "{9987D9FE-1A40-4C5F-835C-D66B0FEADA26}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{9987D9FE-1A40-4C5F-835C-D66B0FEADA26}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{9987D9FE-1A40-4C5F-835C-D66B0FEADA26}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{9987D9FE-1A40-4C5F-835C-D66B0FEADA26}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{9987D9FE-1A40-4C5F-835C-D66B0FEADA26}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
37
Vlnk/vs/VentoyVlnk/VentoyVlnk/Res/Vlnk32.manifest
Normal file
37
Vlnk/vs/VentoyVlnk/VentoyVlnk/Res/Vlnk32.manifest
Normal file
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="x86"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
|
||||
<!-- Windows 8.1 -->
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
||||
<!-- Windows 8 -->
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
|
||||
<!-- Windows 7 -->
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
|
||||
<!-- Windows Vista -->
|
||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
|
||||
</application>
|
||||
</compatibility>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"></requestedExecutionLevel>
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
</assembly>
|
31
Vlnk/vs/VentoyVlnk/VentoyVlnk/Res/Vlnk64.manifest
Normal file
31
Vlnk/vs/VentoyVlnk/VentoyVlnk/Res/Vlnk64.manifest
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="amd64"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
|
||||
<!-- Windows 8.1 -->
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
||||
<!-- Windows 8 -->
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
|
||||
<!-- Windows 7 -->
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
|
||||
<!-- Windows Vista -->
|
||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
|
||||
</application>
|
||||
</compatibility>
|
||||
|
||||
</assembly>
|
31
Vlnk/vs/VentoyVlnk/VentoyVlnk/Res/VlnkArm.manifest
Normal file
31
Vlnk/vs/VentoyVlnk/VentoyVlnk/Res/VlnkArm.manifest
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="arm"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
|
||||
<!-- Windows 8.1 -->
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
||||
<!-- Windows 8 -->
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
|
||||
<!-- Windows 7 -->
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
|
||||
<!-- Windows Vista -->
|
||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
|
||||
</application>
|
||||
</compatibility>
|
||||
|
||||
</assembly>
|
31
Vlnk/vs/VentoyVlnk/VentoyVlnk/Res/VlnkArm64.manifest
Normal file
31
Vlnk/vs/VentoyVlnk/VentoyVlnk/Res/VlnkArm64.manifest
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="arm64"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
|
||||
<!-- Windows 8.1 -->
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
||||
<!-- Windows 8 -->
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
|
||||
<!-- Windows 7 -->
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
|
||||
<!-- Windows Vista -->
|
||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
|
||||
</application>
|
||||
</compatibility>
|
||||
|
||||
</assembly>
|
BIN
Vlnk/vs/VentoyVlnk/VentoyVlnk/Res/vlnk.ico
Normal file
BIN
Vlnk/vs/VentoyVlnk/VentoyVlnk/Res/vlnk.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
BIN
Vlnk/vs/VentoyVlnk/VentoyVlnk/VentoyVlnk.aps
Normal file
BIN
Vlnk/vs/VentoyVlnk/VentoyVlnk/VentoyVlnk.aps
Normal file
Binary file not shown.
BIN
Vlnk/vs/VentoyVlnk/VentoyVlnk/VentoyVlnk.rc
Normal file
BIN
Vlnk/vs/VentoyVlnk/VentoyVlnk/VentoyVlnk.rc
Normal file
Binary file not shown.
110
Vlnk/vs/VentoyVlnk/VentoyVlnk/VentoyVlnk.vcxproj
Normal file
110
Vlnk/vs/VentoyVlnk/VentoyVlnk/VentoyVlnk.vcxproj
Normal file
@@ -0,0 +1,110 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{9987D9FE-1A40-4C5F-835C-D66B0FEADA26}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>VentoyVlnk</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(ProjectDir);$(SolutionDir)/../../src;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(SolutionDir)/../../src;$(ProjectDir);$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<AdditionalManifestFiles>$(ProjectDir)\Res\Vlnk32.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>
|
||||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<AdditionalManifestFiles>$(ProjectDir)\Res\Vlnk32.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>
|
||||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\src\vlnk.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="VentoyVlnk.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\src\crc32.c" />
|
||||
<ClCompile Include="..\..\..\src\main_windows.c" />
|
||||
<ClCompile Include="..\..\..\src\vlnk.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="Res\vlnk.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
46
Vlnk/vs/VentoyVlnk/VentoyVlnk/VentoyVlnk.vcxproj.filters
Normal file
46
Vlnk/vs/VentoyVlnk/VentoyVlnk/VentoyVlnk.vcxproj.filters
Normal file
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="源文件">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="头文件">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="资源文件">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\vlnk.h">
|
||||
<Filter>源文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="VentoyVlnk.rc">
|
||||
<Filter>资源文件</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\src\crc32.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\main_windows.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\vlnk.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="Res\vlnk.ico">
|
||||
<Filter>资源文件</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
</Project>
|
7
Vlnk/vs/VentoyVlnk/VentoyVlnk/VentoyVlnk.vcxproj.user
Normal file
7
Vlnk/vs/VentoyVlnk/VentoyVlnk/VentoyVlnk.vcxproj.user
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LocalDebuggerWorkingDirectory>K:\test\ventoy\ventoy-1.0.57</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
</Project>
|
BIN
Vlnk/vs/VentoyVlnk/VentoyVlnk/resource.h
Normal file
BIN
Vlnk/vs/VentoyVlnk/VentoyVlnk/resource.h
Normal file
Binary file not shown.
Reference in New Issue
Block a user